定义组件
/** * A Picker field that contains a tree panel on its popup, enabling selection of tree nodes. */ Ext.define('Ext.ux.TreePicker', { extend: 'Ext.form.field.Picker', xtype: 'treepicker', uses: [ 'Ext.tree.Panel' ], triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger', config: { /** * @cfg {Ext.data.TreeStore} store * A tree store that the tree picker will be bound to */ store: null, /** * @cfg {String} displayField * The field inside the model that will be used as the node's text. * Defaults to the default value of {@link Ext.tree.Panel}'s `displayField` configuration. */ displayField: null, valueField: null, /** * @cfg {Array} columns * An optional array of columns for multi-column trees */ columns: null, /** * @cfg {Boolean} selectOnTab * Whether the Tab key should select the currently highlighted item. Defaults to `true`. */ selectOnTab: true, /** * @cfg {Number} maxPickerHeight * The maximum height of the tree dropdown. Defaults to 300. */ maxPickerHeight: 300, /** * @cfg {Number} minPickerHeight * The minimum height of the tree dropdown. Defaults to 100. */ minPickerHeight: 100 }, editable: false, /** * @event select * Fires when a tree node is selected * @param {Ext.ux.TreePicker} picker This tree picker * @param {Ext.data.Model} record The selected record */ initComponent: function() { var me = this; me.callParent(arguments); me.mon(me.store, { scope: me, load: me.onLoad, update: me.onUpdate }); }, /** * Creates and returns the tree panel to be used as this field's picker. */ createPicker: function() { var me = this, picker = new Ext.tree.Panel({ shrinkWrapDock: 2, store: me.store, floating: true, displayField: me.displayField, valueField: me.valueField, rootVisible: false, columns: me.columns, minHeight: me.minPickerHeight, maxHeight: me.maxPickerHeight, manageHeight: false, shadow: false, listeners: { scope: me, itemclick: me.onItemClick }, viewConfig: { listeners: { scope: me, render: me.onViewRender } } }), view = picker.getView(); if (Ext.isIE9 && Ext.isStrict) { // In IE9 strict mode, the tree view grows by the height of the horizontal scroll bar when the items are highlighted or unhighlighted. // Also when items are collapsed or expanded the height of the view is off. Forcing a repaint fixes the problem. view.on({ scope: me, highlightitem: me.repaintPickerView, unhighlightitem: me.repaintPickerView, afteritemexpand: me.repaintPickerView, afteritemcollapse: me.repaintPickerView }); } return picker; }, onViewRender: function(view){ view.getEl().on('keypress', this.onPickerKeypress, this); }, /** * repaints the tree view */ repaintPickerView: function() { var style = this.picker.getView().getEl().dom.style; // can't use Element.repaint because it contains a setTimeout, which results in a flicker effect style.display = style.display; }, /** * Handles a click even on a tree node * @private * @param {Ext.tree.View} view * @param {Ext.data.Model} record * @param {HTMLElement} node * @param {Number} rowIndex * @param {Ext.event.Event} e */ onItemClick: function(view, record, node, rowIndex, e) { this.selectItem(record); }, /** * Handles a keypress event on the picker element * @private * @param {Ext.event.Event} e * @param {HTMLElement} el */ onPickerKeypress: function(e, el) { var key = e.getKey(); if(key === e.ENTER || (key === e.TAB && this.selectOnTab)) { this.selectItem(this.picker.getSelectionModel().getSelection()[0]); } }, /** * Changes the selection to a given record and closes the picker * @private * @param {Ext.data.Model} record */ selectItem: function(record) { var me = this; me.setValue(record ? record.get(me.valueField) : ''); me.setRawValue(record ? record.get(me.displayField) : ''); me.fireEvent('select', me, record); me.collapse(); }, /** * Runs when the picker is expanded. Selects the appropriate tree node based on the value of the input element, * and focuses the picker so that keyboard navigation will work. * @private */ onExpand: function() { var me = this, picker = me.picker, store = picker.store, value = me.value, node; if (value) { node = store.getNodeById(value); } if (!node) { node = store.getRoot(); } picker.selectPath(node.getPath()); }, /** * Sets the specified value into the field * @param {Mixed} value * @return {Ext.ux.TreePicker} this */ setValue: function(value) { var me = this, record; me.value = value; if (me.store.loading) { // Called while the Store is loading. Ensure it is processed by the onLoad method. return me; } // try to find a record in the store that matches the value record = value ? me.store.getNodeById(value) : me.store.getRoot(); if (value === undefined) { record = me.store.getRoot(); me.value = record.getId(); } else { record = me.store.getNodeById(value); } // set the raw value to the record's display field if a record was found me.setRawValue(record ? record.get(me.displayField) : ''); return me; }, getSubmitValue: function(){ return this.value; }, /** * Returns the current data value of the field (the idProperty of the record) * @return {Number} */ getValue: function() { return this.value; }, /** * Handles the store's load event. * @private */ onLoad: function() { var value = this.value; if (value) { this.setValue(value); } }, onUpdate: function(store, rec, type, modifiedFieldNames){ var display = this.displayField; if (type === 'edit' && modifiedFieldNames && Ext.Array.contains(modifiedFieldNames, display) && this.value === rec.getId()) { this.setRawValue(rec.get(display)); } } });
页面调用
<script type="text/javascript" src="<%=path%>/extjs/UserControl/TreePicker.js"></script>
var uDevCatCode = Ext.create('Ext.ux.TreePicker', { fieldLabel: '类别', name: 'id', labelWidth: 40, width: 215, minPickerHeight: 0, displayField: 'text', valueField: 'id', emptyText: '—请选择—', blankText: '-请选择-', labelAlign: 'right', animate: true, autoScroll: true, forceSelection: true,// 只能选择下拉框里面的内容 rootVisible: true, listeners: { 'select': function () { storeUDevInfo.load(); } }, store: Ext.create('Ext.data.TreeStore', { autoLoad: false, fields: [{name: 'id'}, {name: 'text'}], root: { text: '', expanded: true }, proxy: { type: 'ajax', url: 'TUDev/loadTreeCategory', reader: {type: 'json'} } }) });
@RequestMapping("/loadTreeCategory") public void loadTreeCategory(HttpServletResponse response, HttpSession session) { if (!Print.CheckPermisson("", session, response)) return; Print print = new Print(); List<TUDevCategory> allUDevCategorys = tuDevService.loadAllUDevCategory(); List<TUDevCategory> uDevCategorys = allUDevCategorys.stream().filter(x -> x.getFudevcatcode() == null || x.getFudevcatcode().equals("")).collect(Collectors.toList()); List<Map<String, Object>> rightDataTree = getChildren(allUDevCategorys, uDevCategorys); print.WriteJson(response, rightDataTree); } private List<Map<String, Object>> getChildren(List<TUDevCategory> listAll, List<TUDevCategory> pList) { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); for (TUDevCategory uDevCategory : pList) { Map<String, Object> child = new HashMap<String, Object>(); child.put("id", uDevCategory.getUdevcatcode()); child.put("text", uDevCategory.getUdevcatname()); child.put("fid", uDevCategory.getFudevcatcode()); child.put("note", uDevCategory.getNote()); List<TUDevCategory> childList = listAll.stream().filter(x -> x.getFudevcatcode() != null && StringUtils.equals(x.getFudevcatcode(), uDevCategory.getUdevcatcode())).collect(Collectors.toList()); if (childList != null) { child.put("children", getChildren(listAll, childList)); child.put("leaf", false); } else { child.put("leaf", true); } list.add(child); } return list; }