FieldSelector.js (5493B)
1 Ext.define('PartKeepr.Components.Widgets.FieldSelector', { 2 extend: 'Ext.tree.Panel', 3 xtype: 'modelFieldSelector', 4 store: { 5 folderSort: true, 6 sorters: [ 7 { 8 property: 'text', 9 direction: 'ASC' 10 } 11 ] 12 }, 13 useArrows: true, 14 model: null, 15 selModel: { 16 mode: 'MULTI' 17 }, 18 19 /** 20 * @var {Array} Contains the nodes which are checked by default 21 */ 22 initiallyChecked: [], 23 24 /** 25 * @var {Boolean} True to recurse into associations, false otherwise. 26 */ 27 recurseSubModels: true, 28 29 /** 30 * @var {Array} An array which excludes the fields listed 31 */ 32 excludeFields: [], 33 34 /** 35 * @var {Array} An array which excludes the models listed 36 */ 37 excludeModels: [], 38 39 useCheckBoxes: true, 40 41 initComponent: function () 42 { 43 this.callParent(arguments); 44 this.visitedModels = []; 45 46 var rootNode = this.getRootNode(); 47 rootNode.set("text", this.sourceModel.getName()); 48 this.treeMaker(rootNode, this.sourceModel, "", undefined, []); 49 rootNode.expand(); 50 }, 51 /** 52 * Builds the field tree recursively. Handles infinite recursions (e.g. in trees). 53 * 54 * @param {Ext.data.NodeInterface} node The current node 55 * @param {Ext.data.Model} model The model 56 * @param {String} prefix The prefix. Omit if first called 57 * @param {Function} callback Te callback, optional 58 * @param {Array} originalVisitedModels The visited models in te subtree. Omit 59 * 60 */ 61 treeMaker: function (node, model, prefix, callback, originalVisitedModels) 62 { 63 var fields = model.getFields(); 64 var checked; 65 var newNode; 66 var j, childNode; 67 var skipSubModel = false, associationAlreadyProcessed; 68 69 var visitedModels = originalVisitedModels.slice(0); 70 visitedModels.push(model.getName()); 71 72 for (var i = 0; i < fields.length; i++) { 73 if (!fields[i]["persist"]) { 74 continue; 75 } 76 77 if (fields[i]["reference"] === null) { 78 79 80 checked = Ext.Array.contains(this.initiallyChecked, prefix + fields[i].name); 81 82 if (!Ext.Array.contains(this.excludeFields, prefix + fields[i].name)) { 83 newNode = { 84 text: fields[i].name, 85 leaf: true, 86 data: { 87 name: prefix + fields[i].name, 88 type: "field" 89 } 90 }; 91 92 if (this.useCheckBoxes) { 93 newNode.checked = checked; 94 } 95 node.appendChild(newNode); 96 } 97 } else { 98 if (this.recurseSubModels) { 99 skipSubModel = false; 100 for (j = 0; j < visitedModels.length; j++) { 101 if (visitedModels[j] === fields[i].reference.cls.getName()) { 102 skipSubModel = true; 103 } 104 } 105 106 for (j = 0; j < this.excludeModels.length; j++) { 107 if (this.excludeModels[j] === fields[i].reference.cls.getName()) { 108 skipSubModel = true; 109 } 110 } 111 112 if (skipSubModel === false) { 113 childNode = node.appendChild({ 114 text: fields[i].name, 115 expanded: false, 116 data: { 117 name: prefix + fields[i].name, 118 type: "manytoone", 119 reference: fields[i].reference.cls, 120 model: fields[i].reference.cls.getName() 121 }, 122 leaf: false 123 }); 124 125 this.treeMaker(childNode, fields[i].reference.cls, prefix + fields[i].name + ".", callback, visitedModels); 126 } 127 } 128 } 129 130 } 131 132 var associations = model.associations; 133 134 135 for (i in associations) { 136 associationAlreadyProcessed = false; 137 if (typeof(associations[i].storeName) !== "undefined" && associations[i].isMany === true) { 138 for (j = 0; j < visitedModels.length; j++) { 139 if (visitedModels[j] === associations[i].type) { 140 associationAlreadyProcessed = true; 141 } 142 } 143 144 if (!associationAlreadyProcessed) { 145 childNode = node.appendChild({ 146 text: associations[i].role, 147 expanded: false, 148 data: { 149 name: prefix + associations[i].role, 150 type: "onetomany", 151 reference: associations[i].cls 152 }, 153 leaf: false 154 }); 155 156 if (callback !== undefined) { 157 childNode.set(callback(associations[i].cls, childNode)); 158 } 159 160 this.treeMaker(childNode, associations[i].cls, prefix + associations[i].role + ".", callback, visitedModels); 161 } 162 } 163 } 164 } 165 });