Kaynağa Gözat

新增多级联动下拉示例

RuoYi 4 yıl önce
ebeveyn
işleme
004e5b8af6

Dosya farkı çok büyük olduğundan ihmal edildi
+ 52 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/demo/controller/DemoFormController.java


+ 406 - 0
ruoyi-admin/src/main/resources/static/ajax/libs/cxselect/jquery.cxselect.js

@@ -0,0 +1,406 @@
+/*!
+ * jQuery cxSelect
+ * @name jquery.cxselect.js
+ * @version 1.4.2
+ * @date 2017-09-26
+ * @author ciaoca
+ * @email ciaoca@gmail.com
+ * @site https://github.com/ciaoca/cxSelect
+ * @license Released under the MIT license
+ */
+(function(factory) {
+  if (typeof define === 'function' && define.amd) {
+    define(['jquery'], factory);
+  } else {
+    factory(window.jQuery || window.Zepto || window.$);
+  };
+}(function($) {
+  var cxSelect = function() {
+    var self = this;
+    var dom, settings, callback;
+
+    // 分配参数
+    for (var i = 0, l = arguments.length; i < l; i++) {
+      if (cxSelect.isJquery(arguments[i]) || cxSelect.isZepto(arguments[i])) {
+        dom = arguments[i];
+      } else if (cxSelect.isElement(arguments[i])) {
+        dom = $(arguments[i]);
+      } else if (typeof arguments[i] === 'function') {
+        callback = arguments[i];
+      } else if (typeof arguments[i] === 'object') {
+        settings = arguments[i];
+      };
+    };
+
+    var api = new cxSelect.init(dom, settings);
+
+    if (typeof callback === 'function') {
+      callback(api);
+    };
+
+    return api;
+  };
+
+  cxSelect.isElement = function(o){
+    if (o && (typeof HTMLElement === 'function' || typeof HTMLElement === 'object') && o instanceof HTMLElement) {
+      return true;
+    } else {
+      return (o && o.nodeType && o.nodeType === 1) ? true : false;
+    };
+  };
+
+  cxSelect.isJquery = function(o){
+    return (o && o.length && (typeof jQuery === 'function' || typeof jQuery === 'object') && o instanceof jQuery) ? true : false;
+  };
+
+  cxSelect.isZepto = function(o){
+    return (o && o.length && (typeof Zepto === 'function' || typeof Zepto === 'object') && Zepto.zepto.isZ(o)) ? true : false;
+  };
+
+  cxSelect.getIndex = function(n, required) {
+    return required ? n : n - 1;
+  };
+
+  cxSelect.getData = function(data, space) {
+    if (typeof space === 'string' && space.length) {
+      space = space.split('.');
+      for (var i = 0, l = space.length; i < l; i++) {
+        data = data[space[i]];
+      };
+    };
+    return data;
+  };
+
+  cxSelect.init = function(dom, settings) {
+    var self = this;
+
+    if (!cxSelect.isJquery(dom) && !cxSelect.isZepto(dom)) {return};
+
+    var theSelect = {
+      dom: {
+        box: dom
+      }
+    };
+
+    self.attach = cxSelect.attach.bind(theSelect);
+    self.detach = cxSelect.detach.bind(theSelect);
+    self.setOptions = cxSelect.setOptions.bind(theSelect);
+    self.clear = cxSelect.clear.bind(theSelect);
+
+    theSelect.changeEvent = function() {
+      cxSelect.selectChange.call(theSelect, this.className);
+    };
+
+    theSelect.settings = $.extend({}, $.cxSelect.defaults, settings, {
+      url: theSelect.dom.box.data('url'),
+      emptyStyle: theSelect.dom.box.data('emptyStyle'),
+      required: theSelect.dom.box.data('required'),
+      firstTitle: theSelect.dom.box.data('firstTitle'),
+      firstValue: theSelect.dom.box.data('firstValue'),
+      jsonSpace: theSelect.dom.box.data('jsonSpace'),
+      jsonName: theSelect.dom.box.data('jsonName'),
+      jsonValue: theSelect.dom.box.data('jsonValue'),
+      jsonSub: theSelect.dom.box.data('jsonSub')
+    });
+
+    var _dataSelects = theSelect.dom.box.data('selects');
+
+    if (typeof _dataSelects === 'string' && _dataSelects.length) {
+      theSelect.settings.selects = _dataSelects.split(',');
+    };
+
+    self.setOptions();
+    self.attach();
+
+    // 使用独立接口获取数据
+    if (!theSelect.settings.url && !theSelect.settings.data) {
+      cxSelect.start.apply(theSelect);
+
+    // 设置自定义数据
+    } else if ($.isArray(theSelect.settings.data)) {
+      cxSelect.start.call(theSelect, theSelect.settings.data);
+
+    // 设置 URL,通过 Ajax 获取数据
+    } else if (typeof theSelect.settings.url === 'string' && theSelect.settings.url.length) {
+      $.getJSON(theSelect.settings.url, function(json) {
+        cxSelect.start.call(theSelect, json);
+      });
+    };
+  };
+
+  // 设置参数
+  cxSelect.setOptions = function(opts) {
+    var self = this;
+
+    if (opts) {
+      $.extend(self.settings, opts);
+    };
+
+    // 初次或重设选择器组
+    if (!$.isArray(self.selectArray) || !self.selectArray.length || (opts && opts.selects)) {
+      self.selectArray = [];
+
+      if ($.isArray(self.settings.selects) && self.settings.selects.length) {
+        var _tempSelect;
+
+        for (var i = 0, l = self.settings.selects.length; i < l; i++) {
+          _tempSelect = self.dom.box.find('select.' + self.settings.selects[i]);
+
+          if (!_tempSelect || !_tempSelect.length) {break};
+
+          self.selectArray.push(_tempSelect);
+        };
+      };
+    };
+
+    if (opts) {
+      if (!$.isArray(opts.data) && typeof opts.url === 'string' && opts.url.length) {
+        $.getJSON(self.settings.url, function(json) {
+          cxSelect.start.call(self, json);
+        });
+
+      } else {
+        cxSelect.start.call(self, opts.data);
+      };
+    };
+  };
+
+  // 绑定
+  cxSelect.attach = function() {
+    var self = this;
+
+    if (!self.attachStatus) {
+      self.dom.box.on('change', 'select', self.changeEvent);
+    };
+
+    if (typeof self.attachStatus === 'boolean') {
+      cxSelect.start.call(self);
+    };
+
+    self.attachStatus = true;
+  };
+
+  // 移除绑定
+  cxSelect.detach = function() {
+    var self = this;
+    self.dom.box.off('change', 'select', self.changeEvent);
+    self.attachStatus = false;
+  };
+
+  // 清空选项
+  cxSelect.clear = function(index) {
+    var self = this;
+    var _style = {
+      display: '',
+      visibility: ''
+    };
+
+    index = isNaN(index) ? 0 : index;
+
+    // 清空后面的 select
+    for (var i = index, l = self.selectArray.length; i < l; i++) {
+      self.selectArray[i].empty().prop('disabled', true);
+
+      if (self.settings.emptyStyle === 'none') {
+        _style.display = 'none';
+      } else if (self.settings.emptyStyle === 'hidden') {
+        _style.visibility = 'hidden';
+      };
+
+      self.selectArray[i].css(_style);
+    };
+  };
+
+  cxSelect.start = function(data) {
+    var self = this;
+
+    if ($.isArray(data)) {
+      self.settings.data = cxSelect.getData(data, self.settings.jsonSpace);
+    };
+
+    if (!self.selectArray.length) {return};
+
+    // 保存默认值
+    for (var i = 0, l = self.selectArray.length; i < l; i++) {
+      if (typeof self.selectArray[i].attr('data-value') !== 'string' && self.selectArray[i][0].options.length) {
+        self.selectArray[i].attr('data-value', self.selectArray[i].val());
+      };
+    };
+
+    if (self.settings.data || (typeof self.selectArray[0].data('url') === 'string' && self.selectArray[0].data('url').length)) {
+      cxSelect.getOptionData.call(self, 0);
+    } else if (self.selectArray[0][0].options.length && typeof self.selectArray[0].attr('data-value') === 'string' && self.selectArray[0].attr('data-value').length) {
+      self.selectArray[0].val(self.selectArray[0].attr('data-value'));
+      cxSelect.getOptionData.call(self, 1);
+    } else {
+      self.selectArray[0].prop('disabled', false).css({
+        'display': '',
+        'visibility': ''
+      });
+    };
+  };
+
+  // 获取选项数据
+  cxSelect.getOptionData = function(index) {
+    var self = this;
+
+    if (typeof index !== 'number' || isNaN(index) || index < 0 || index >= self.selectArray.length) {return};
+
+    var _indexPrev = index - 1;
+    var _select = self.selectArray[index];
+    var _selectData;
+    var _valueIndex;
+    var _dataUrl = _select.data('url');
+    var _jsonSpace = typeof _select.data('jsonSpace') === 'undefined' ? self.settings.jsonSpace : _select.data('jsonSpace');
+    var _query = {};
+    var _queryName;
+    var _selectName;
+    var _selectValue;
+
+    cxSelect.clear.call(self, index);
+
+    // 使用独立接口
+    if (typeof _dataUrl === 'string' && _dataUrl.length) {
+      if (index > 0) {
+        for (var i = 0, j = 1; i < index; i++, j++) {
+          _queryName = self.selectArray[j].data('queryName');
+          _selectName = self.selectArray[i].attr('name');
+          _selectValue = self.selectArray[i].val();
+
+          if (typeof _queryName === 'string' && _queryName.length) {
+            _query[_queryName] = _selectValue;
+          } else if (typeof _selectName === 'string' && _selectName.length) {
+            _query[_selectName] = _selectValue;
+          };
+        };
+      };
+
+      $.getJSON(_dataUrl, _query, function(json) {
+        _selectData = cxSelect.getData(json, _jsonSpace);
+
+        cxSelect.buildOption.call(self, index, _selectData);
+      });
+
+    // 使用整合数据
+    } else if (self.settings.data && typeof self.settings.data === 'object') {
+      _selectData = self.settings.data;
+
+      for (var i = 0; i < index; i++) {
+        _valueIndex = cxSelect.getIndex(self.selectArray[i][0].selectedIndex, typeof self.selectArray[i].data('required') === 'boolean' ? self.selectArray[i].data('required') : self.settings.required);
+
+        if (typeof _selectData[_valueIndex] === 'object' && $.isArray(_selectData[_valueIndex][self.settings.jsonSub]) && _selectData[_valueIndex][self.settings.jsonSub].length) {
+          _selectData = _selectData[_valueIndex][self.settings.jsonSub];
+        } else {
+          _selectData = null;
+          break;
+        };
+      };
+
+      cxSelect.buildOption.call(self, index, _selectData);
+    };
+  };
+
+  // 构建选项列表
+  cxSelect.buildOption = function(index, data) {
+    var self = this;
+
+    var _select = self.selectArray[index];
+    var _required = typeof _select.data('required') === 'boolean' ? _select.data('required') : self.settings.required;
+    var _firstTitle = typeof _select.data('firstTitle') === 'undefined' ? self.settings.firstTitle : _select.data('firstTitle');
+    var _firstValue = typeof _select.data('firstValue') === 'undefined' ? self.settings.firstValue : _select.data('firstValue');
+    var _jsonName = typeof _select.data('jsonName') === 'undefined' ? self.settings.jsonName : _select.data('jsonName');
+    var _jsonValue = typeof _select.data('jsonValue') === 'undefined' ? self.settings.jsonValue : _select.data('jsonValue');
+
+    if (!$.isArray(data)) {return};
+
+    var _html = !_required ? '<option value="' + String(_firstValue) + '">' + String(_firstTitle) + '</option>' : '';
+
+    // 区分标题、值的数据
+    if (typeof _jsonName === 'string' && _jsonName.length) {
+      // 无值字段时使用标题作为值
+      if (typeof _jsonValue !== 'string' || !_jsonValue.length) {
+        _jsonValue = _jsonName;
+      };
+
+      for (var i = 0, l = data.length; i < l; i++) {
+        _html += '<option value="' + String(data[i][_jsonValue]) + '">' + String(data[i][_jsonName]) + '</option>';
+      };
+
+    // 数组即为值的数据
+    } else {
+      for (var i = 0, l = data.length; i < l; i++) {
+        _html += '<option value="' + String(data[i]) + '">' + String(data[i]) + '</option>';
+      };
+    };
+
+    _select.html(_html).prop('disabled', false).css({
+      'display': '',
+      'visibility': ''
+    });
+
+    // 初次加载设置默认值
+    if (typeof _select.attr('data-value') === 'string') {
+      _select.val(String(_select.attr('data-value'))).removeAttr('data-value');
+
+      if (_select[0].selectedIndex < 0) {
+        _select[0].options[0].selected = true;
+      };
+    };
+
+    if (_required || _select[0].selectedIndex > 0) {
+      _select.trigger('change');
+    };
+
+  };
+
+  // 改变选择时的处理
+  cxSelect.selectChange = function(name) {
+    var self = this;
+
+    if (typeof name !== 'string' || !name.length) {return};
+
+    var index;
+
+    name = name.replace(/\s+/g, ',');
+    name = ',' + name + ',';
+
+    // 获取当前 select 位置
+    for (var i = 0, l = self.selectArray.length; i < l; i++) {
+      if (name.indexOf(',' + self.settings.selects[i] + ',') > -1) {
+        index = i;
+        break;
+      };
+    };
+
+    if (typeof index === 'number' && index > -1) {
+      index += 1;
+      cxSelect.getOptionData.call(self, index);
+    };
+  };
+
+  $.cxSelect = function() {
+    return cxSelect.apply(this, arguments);
+  };
+
+  // 默认值
+  $.cxSelect.defaults = {
+    selects: [],            // 下拉选框组
+    url: null,              // 列表数据文件路径(URL)或数组数据
+    data: null,             // 自定义数据
+    emptyStyle: null,       // 无数据状态显示方式
+    required: false,        // 是否为必选
+    firstTitle: '请选择',    // 第一个选项的标题
+    firstValue: '',         // 第一个选项的值
+    jsonSpace: '',          // 数据命名空间
+    jsonName: 'n',          // 数据标题字段名称
+    jsonValue: '',          // 数据值字段名称
+    jsonSub: 's'            // 子集数据字段名称
+  };
+
+  $.fn.cxSelect = function(settings, callback) {
+    this.each(function(i) {
+      $.cxSelect(this, settings, callback);
+    });
+    return this;
+  };
+}));

Dosya farkı çok büyük olduğundan ihmal edildi
+ 10 - 0
ruoyi-admin/src/main/resources/static/ajax/libs/cxselect/jquery.cxselect.min.js


+ 161 - 0
ruoyi-admin/src/main/resources/templates/demo/form/cxselect.html

@@ -0,0 +1,161 @@
+<!DOCTYPE html>
+<html lang="zh">
+<head>
+	<th:block th:include="include :: header('多级联动下拉')" />
+</head>
+<body class="gray-bg">
+      <div class="wrapper wrapper-content animated fadeInRight">
+        <div class="row">
+            <div class="col-sm-12">
+                <div class="ibox float-e-margins">
+                    <div class="ibox-title">
+                        <h5>多级联动下拉<small>https://github.com/ciaoca/cxSelect</small></h5>
+                    </div>  
+                    <div class="ibox-content">
+                        <p>简单联动示例。</p>
+                        <div id="element" class="row">
+                            <div class="col-sm-2">
+	                            <select class="type form-control m-b" data-first-title="请选择">
+				                  <option value="">请选择</option>
+				                </select>
+			                </div>
+			                <div class="col-sm-2">
+				                <select class="router form-control m-b" data-first-title="请选择">
+				                  <option value="">请选择</option>
+				                </select>
+			                </div>
+                        </div>
+                        <hr>
+                        
+                        <p>国内省市区联动。</p>
+                        <div id="element1" class="row">
+                            <div class="col-sm-2">
+	                            <select class="province form-control m-b" data-first-title="选择省">
+				                  <option value="">请选择</option>
+				                  <option value="广东省" selected>广东省</option>
+				                </select>
+			                </div>
+			                <div class="col-sm-2">
+				                <select class="city form-control m-b" data-first-title="选择市">
+				                  <option value="">请选择</option>
+				                  <option value="深圳市" selected>深圳市</option>
+				                </select>
+			                </div>
+			                <div class="col-sm-2">
+				                <select class="area form-control m-b" data-first-title="选择地区">
+				                  <option value="">请选择</option>
+				                  <option value="南山区" selected>南山区</option>
+				                </select>
+			                </div>
+                        </div>
+                        <hr>
+                        
+                        <p>自定义选项。</p>
+                        <div id="element2" class="row">
+                            <div class="col-sm-2">
+	                            <select class="first form-control m-b"></select>
+			                </div>
+			                <div class="col-sm-2">
+				                <select class="second form-control m-b"></select>
+			                </div>
+			                <div class="col-sm-2">
+				                <select class="third form-control m-b"></select>
+			                </div>
+			                <div class="col-sm-2">
+				                <select class="fourth form-control m-b"></select>
+			                </div>
+			                <div class="col-sm-2">
+			                    <select class="fifth form-control m-b"></select>
+			                </div>
+                        </div>
+                        <hr>
+                        <div class="form-group">
+                            <label class="font-noraml">相关参数详细信息</label>
+                            <div><a href="http://doc.ruoyi.vip/ruoyi/document/zjwd.html#cxselect" target="_blank">http://doc.ruoyi.vip/ruoyi/document/zjwd.html#cxselect</a></div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <th:block th:include="include :: footer" />
+    <th:block th:include="include :: cxselect-js" />
+    <script th:inline="javascript">
+        // 直接返回获取
+   		var data = [[${data}]];
+    	$('#element').cxSelect({
+    	  selects: ['type', 'router'],
+    	  jsonValue: 'v',
+    	  data: data
+    	});
+    	
+    	// 通过默认url获取
+    	var urlChina = 'cityData';
+    	$.cxSelect.defaults.url = urlChina;
+    	$('#element1').cxSelect({
+   		  selects: ['province', 'city', 'area'],
+   		  nodata: 'none'
+   		});
+    	
+    	// 固定值获取
+    	$('#element2').cxSelect({
+   		  selects: ['first', 'second', 'third', 'fourth', 'fifth'],
+   		  required: true,
+   		  jsonValue: 'v',
+   		  data: [
+   			{'v': '1', 'n': '第一级 >', 's': [
+   			  {'v': '2', 'n': '第二级 >', 's': [
+   				{'v': '3', 'n': '第三级 >', 's': [
+   				  {'v': '4', 'n': '第四级 >', 's': [
+   					{'v': '5', 'n': '第五级 >', 's': [
+   					  {'v': '6', 'n': '第六级 >'}
+   					]}
+   				  ]}
+   				]}
+   			  ]}
+   			]},
+   			{'v': 'test number', 'n': '测试数字', 's': [
+   			  {'v': 'text', 'n': '文本类型', 's': [
+   				{'v': '4', 'n': '4'},
+   				{'v': '5', 'n': '5'},
+   				{'v': '6', 'n': '6'},
+   				{'v': '7', 'n': '7'},
+   				{'v': '8', 'n': '8'},
+   				{'v': '9', 'n': '9'},
+   				{'v': '10', 'n': '10'}
+   			  ]},
+   			  {'v': 'number', 'n': '数值类型', 's': [
+   				{'v': 11, 'n': 11},
+   				{'v': 12, 'n': 12},
+   				{'v': 13, 'n': 13},
+   				{'v': 14, 'n': 14},
+   				{'v': 15, 'n': 15},
+   				{'v': 16, 'n': 16},
+   				{'v': 17, 'n': 17}
+   			  ]}
+   			]},
+   			{'v': 'test boolean','n': '测试 Boolean 类型', 's': [
+   			  {'v': true ,'n': true},
+   			  {'v': false ,'n': false}
+   			]},
+   			{v: 'test quotes', n: '测试属性不加引号', s: [
+   			  {v: 'quotes', n: '引号'}
+   			]},
+   			{v: 'test other', n: '测试奇怪的值', s: [
+   			  {v: '[]', n: '数组(空)'},
+   			  {v: [1,2,3], n: '数组(数值)'},
+   			  {v: ['a','b','c'], n: '数组(文字)'},
+   			  {v: new Date(), n: '日期'},
+   			  {v: new RegExp('\\d+'), n: '正则对象'},
+   			  {v: /\d+/, n: '正则直接量'},
+   			  {v: {}, n: '对象'},
+   			  {v: document.getElementById('custom_data'), n: 'DOM'},
+   			  {v: null, n: 'Null'},
+   			  {n: '未设置 value'}
+   			]},
+   			{'v': '' , 'n': '无子级'}
+   		  ]
+   		});
+    </script>
+</body>
+</html>

+ 34 - 0
ruoyi-admin/src/main/resources/templates/demo/table/search.html

@@ -62,6 +62,29 @@
 				</form>
 			</div>
 			
+			<div class="col-sm-12 search-collapse">
+			    <p class="select-title">多级联动下拉查询</p>
+				<form id="select-form">
+					<div class="select-list">
+						<ul id="element">
+						    <li>
+								商户编号:<input type="text" name="userId"/>
+							</li>
+							<li>
+								充值类型:<select class="type"></select>
+							</li>
+							<li>
+								充值路由:<select class="router"></select>
+							</li>
+							<li>
+								<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a>
+							    <a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset('select-form')"><i class="fa fa-refresh"></i>&nbsp;重置</a>
+							</li>
+						</ul>
+					</div>
+				</form>
+			</div>
+			
 			<div class="col-sm-12 search-collapse">
 			    <p class="select-title">下拉多选条件查询</p>
 				<form id="select-form">
@@ -164,5 +187,16 @@
 	</div>
 	<th:block th:include="include :: footer" />
 	<th:block th:include="include :: bootstrap-select-js" />
+	<th:block th:include="include :: cxselect-js" />
+	
+	<script th:inline="javascript">
+	    // 直接返回获取
+   		var data = [{"v":"taobao","n":"淘宝","s":[{"v":"tm","n":"天猫"},{"v":"jhs","n":"聚划算"}]},{"v":"jd","n":"京东","s":[{"v":"jdcs","n":"京东超市"},{"v":"jdsx","n":"京东生鲜"}]}];
+    	$('#element').cxSelect({
+    	  selects: ['type', 'router'],
+    	  jsonValue: 'v',
+    	  data: data
+    	});
+    </script>
 </body>
 </html>

+ 5 - 0
ruoyi-admin/src/main/resources/templates/include.html

@@ -139,6 +139,11 @@
     <script th:src="@{/ajax/libs/typeahead/bootstrap3-typeahead.min.js}"></script>
 </div>
 
+<!-- 多级联动下拉 -->
+<div th:fragment="cxselect-js">
+    <script th:src="@{/ajax/libs/cxselect/jquery.cxselect.min.js}"></script>
+</div>
+
 <!-- jsonview格式化和语法高亮JSON格式数据查看插件 -->
 <div th:fragment="jsonview-css">
     <link th:href="@{/ajax/libs/jsonview/jquery.jsonview.css}" rel="stylesheet"/>

+ 1 - 0
ruoyi-admin/src/main/resources/templates/index.html

@@ -95,6 +95,7 @@
 								<li><a class="menuItem" th:href="@{/demo/form/summernote}">富文本编辑器</a></li>
 								<li><a class="menuItem" th:href="@{/demo/form/duallistbox}">左右互选组件</a></li>
 								<li><a class="menuItem" th:href="@{/demo/form/autocomplete}">搜索自动补全</a></li>
+								<li><a class="menuItem" th:href="@{/demo/form/cxselect}">多级联动下拉</a></li>
 							</ul>
                         </li>
                         <li> <a>表格<span class="fa arrow"></span></a>

+ 69 - 0
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/CxSelect.java

@@ -0,0 +1,69 @@
+package com.ruoyi.common.core.domain;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * CxSelect树结构实体类
+ * 
+ * @author ruoyi
+ */
+public class CxSelect implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 数据值字段名称
+     */
+    private String v;
+
+    /**
+     * 数据标题字段名称
+     */
+    private String n;
+
+    /**
+     * 子集数据字段名称
+     */
+    private List<CxSelect> s;
+
+    public CxSelect()
+    {
+    }
+
+    public CxSelect(String v, String n)
+    {
+        this.v = v;
+        this.n = n;
+    }
+
+    public List<CxSelect> getS()
+    {
+        return s;
+    }
+
+    public void setN(String n)
+    {
+        this.n = n;
+    }
+
+    public String getN()
+    {
+        return n;
+    }
+
+    public void setS(List<CxSelect> s)
+    {
+        this.s = s;
+    }
+
+    public String getV()
+    {
+        return v;
+    }
+
+    public void setV(String v)
+    {
+        this.v = v;
+    }
+}

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor