bootstrap穿梭框+el表达式+jstl标签库

遇到一个需求,要做一个穿梭框的页面功能,最后选择了bootstrap的穿梭框,这个也是网上找的别人封装好的,原文地址 拿来之后结合项目加上EL表达式和jstl的c:foreach实现了这个功能。

Transfer.js:
/**
 * Created by liwg on 2018/1/19.
 */
(function($, window, document) {
   
   
    var transfer = function(el, options) {
   
   
        this.option = options;
        this.$el = $(el);
        this.selectData = [];
        this.unselectData = [];
        this.init();
    };
    transfer.DEFAULTS = {
   
   
        titles: ['待选列表', '已选列表'],
        search: true, ///是否显示搜索查询
        showRefresh: false, //
        clickToSelect: true,
        pagination: false, //是否支持分页
        autoHeight: false,
        url: '',
        type: "get",
        queryParams: {
   
   },
        contentType: 'application/json',
        paginationDetail: false,
        maxSelect: undefined,
        uniqueId: "", //每行的id
        dataSource: [], //默认数据源为同一个  内部会通过diffKey去区分是待选框的  还是已选框的数据,如果selectdataSource存在  则或解析为待选数据框里的数据
        selectdataSource: undefined,
        diffKey: 'flag',
        selectColumns: [],
        unselectColumns: []

    };
    transfer.prototype = {
   
   
        init: function() {
   
   
            this.initoption();
            this.initContainer();
            this.initBothTable();
            if (this.option.url) {
   
   
                this.initServer();
            } else {
   
   
                this.classifyData();
            }
            this.initEvent();
        },
        /*
         * 渲染穿梭框页面结构*/
        initContainer: function() {
   
   
            var _this = this;
            var containerHtml = ['<div class="col-sm-5 transferBox">',
                '<h3 class="unselectTitle" style="margin: 0;padding: 5px 0 10px 0;">' + this.unselectTitle + '<span style="margin-left: 5px;">(<span id="checkedNum1"></span><span id="unselectTotalNum"></span>)</span></h3>',
                '<table id="transferUnselectTable"></table>',
                '</div>',
                '<div class="col-sm-2 transferBtn" style="height: 100%">',
                '<div class="btnList">',
                '<span class="btn btn-default  forwardBtn" ><i class="glyphicon glyphicon-forward"></i></span>',
                '<span class="btn btn-default  backwardBtn" ><i class="glyphicon glyphicon-backward"></i></span>',
                '</div>',
                '</div>',
                '<div class="col-sm-5 transferBox">',
                '<h3 class="selectTitle" style="margin: 0;padding: 5px 0 10px 0;">' + this.selectTitle + '<span style="margin-left: 5px;">(<span id="checkedNum2"></span><span id="selectTotalNum"></span>)</span></h3>',
                '<table id="transferSelectTable"></table>',
                '</div>'
            ].join('');
            this.$el.html(containerHtml);
            this.$unselectTable = this.$el.find('#transferUnselectTable'); //待选表格
            this.$unselectTotalNum = this.$el.find('#unselectTotalNum'); //存放待选表格内总的数量
            this.$checkedNum1 = this.$el.find('#checkedNum1'); //存放待选表格中已勾选的数量
            this.$forwardBtn = this.$el.find('.forwardBtn'); //向待选表格内添加的按钮

            this.$selectTable = this.$el.find('#transferSelectTable'); //已选表格
            this.$selectTotalNum = this.$el.find('#selectTotalNum'); //存放已选表格内总的数量
            this.$checkedNum2 = this.$el.find('#checkedNum2'); //存放已选表格中已勾选的数量
            this.$backwardBtn = this.$el.find('.backwardBtn'); //向待选表格内添加的按钮
            this.option.height = this.$el.outerHeight() - this.$el.find('h3.unselectTitle').outerHeight() - 8;
        },
        /*
         * 参数处理*/
        initoption: function() {
   
   
            /*
             * 两边标题参数处理*/
            if (typeof this.option.titles == 'string' || (this.option.titles instanceof Array && this.option.titles.length == 1)) {
   
   
                this.selectTitle = this.unselectTitle = this.option.titles + '';
            } else if (this.option.titles instanceof Array && this.option.titles.length > 1) {
   
   
                this.unselectTitle = this.option.titles[0];
                this.selectTitle = this.option.titles[1];
            }
            /*
             * 两个table渲染内容若一样,给任意一个columns即可*/
            if (this.option.selectColumns instanceof Array && this.option.unselectColumns instanceof Array && (!this.option.selectColumns.length && this.option.unselectColumns.length)) {
   
   
                this.option.selectColumns = JSON.parse(JSON.stringify(this.option.unselectColumns));
            } else if (this.option.selectColumns instanceof Array && this.option.unselectColumns instanceof Array && (this.option.selectColumns.length && !this.option.unselectColumns.length)) {
   
   
                this.option.unselectColumns = JSON.parse(JSON.stringify(this.option.selectColumns));
            } else if (!this.option.selectColumns instanceof Array || !this.option.unselectColumns instanceof Array) {
   
   
                console.error('参数selectColumns和unselectColumns必须为数组');
                return false;
            }
            /*
             * 两边table两边渲染选中的field不能一样,此处强制替换了,参数中可不写field*/
            this.option.selectColumns[0].field = this
<think>嗯,用户想用EL表达式JSTL在Web应用中显示商品列表。首先,我需要回忆一下ELJSTL的基本用法。根据引用内容,EL主要用于访问JavaBean属性,而JSTL的标签比如<c:forEach>可以用来遍历集合。用户需要的是示例代码和教程,所以应该从数据准备、JSP页面展示、样式处理一步步来。 首先,后台需要准备商品数据,通常放在request或session作用域里。比如创建一个Product类,有name、price、stock等属性,然后创建一个List<Product>,用request.setAttribute("productList", list)传递到前端。这部分用户可能已经知道,但示例里需要明确写出。 接下来是JSP页面部分。用户需要导入JSTL核心标签库,使用<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>。然后用<c:forEach>遍历productList,每个商品显示其属性。要注意EL表达式如何访问对象的属性,比如${product.name}。表格布局比较常见,可以建议用户用Bootstrap来美化,但示例可能只需要基础表格结构。 然后考虑分页和排序,但用户的问题可能暂时不需要这些高级功能,所以可能作为优化点提到。另外,EL表达式处理空值的情况,比如用默认值${product.price ?: '无库存'},这也是一个细节需要注意。 用户可能遇到的问题包括JSTL标签未正确导入、EL表达式无法解析属性(可能没写getter方法)、集合为空时的处理。所以在注意事项里要强调这些点,比如检查taglib声明,确保Product类有getter,用<c:if>判断空列表。 最后,生成相关问题时要围绕ELJSTL的其他应用,比如条件判断、格式化数字日期,以及如何结合Servlet获取数据。这样用户如果有进一步需求,可以参考这些问题扩展学习。</think>### 分步实现商品列表显示的EL+JSTL解决方案 #### 一、数据准备阶段(Servlet/Controller) ```java // 创建商品类(需符合JavaBean规范) public class Product { private String name; private double price; private int stock; // 必须提供无参构造函数 public Product() {} // Getter/Setter方法(EL表达式依赖这些方法访问属性) public String getName() { return name; } public void setName(String name) { this.name = name; } // 其他属性同理... } // 在Servlet中准备数据 List<Product> products = new ArrayList<>(); products.add(new Product("笔记本", 5999.00, 100)); products.add(new Product("无线鼠标", 199.00, 50)); request.setAttribute("productList", products); ``` #### 二、JSP页面展示层 ```jsp <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!-- 表格结构展示 --> <table class="product-table"> <thead> <tr> <th>商品名称</th> <th>价格</th> <th>库存</th> </tr> </thead> <tbody> <c:forEach items="${productList}" var="product" varStatus="status"> <tr class="${status.index % 2 == 0 ? 'even' : 'odd'}"> <td>${product.name}</td> <td>¥${product.price}</td> <td>${product.stock}件</td> </tr> </c:forEach> </tbody> </table> ``` #### 三、样式增强建议 ```html <!-- 添加Bootstrap支持 --> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.1.3/css/bootstrap.min.css" rel="stylesheet"> <!-- 优化后的表格样式 --> <table class="table table-striped table-hover"> <!-- 表头不变 --> <c:forEach items="${productList}" var="product"> <tr> <td>${product.name}</td> <td><fmt:formatNumber value="${product.price}" type="currency"/></td> <td> <c:choose> <c:when test="${product.stock > 0}">有货(${product.stock}件)</c:when> <c:otherwise>暂时缺货</c:otherwise> </c:choose> </td> </tr> </c:forEach> ``` #### 四、高级功能扩展 1. **分页实现**: ```jsp <c:forEach begin="0" end="${totalPages}" var="page"> <a href="?page=${page}">${page+1}</a> </c:forEach> ``` 2. **排序功能**: ```jsp <a href="?sort=price">按价格排序</a> ``` #### 五、注意事项 1. EL表达式访问原理: - `${product.name}` 实际调用`product.getName()` - 集合索引访问:`${productList[0].name}` - 使用`[]`运算符处理特殊字符:`${requestScope['product.list']}` 2. 常见问题排查: - 检查`<%@ taglib %>`声明是否正确 - 确保JSTL库已添加到WEB-INF/lib - 对象属性必须提供getter方法 - 使用`<c:if test="${empty productList}">`处理空集合
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值