pyseext 2.0.1__tar.gz → 2.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyseext-2.0.1/src/pyseext.egg-info → pyseext-2.0.2}/PKG-INFO +1 -1
- {pyseext-2.0.1 → pyseext-2.0.2}/pyproject.toml +1 -1
- pyseext-2.0.2/src/pyseext/js/PySeExt.ComponentQuery.js +123 -0
- pyseext-2.0.2/src/pyseext/js/PySeExt.Core.js +34 -0
- pyseext-2.0.2/src/pyseext/js/PySeExt.FieldHelper.js +249 -0
- pyseext-2.0.2/src/pyseext/js/PySeExt.GridHelper.js +249 -0
- pyseext-2.0.2/src/pyseext/js/PySeExt.LocalStorageHelper.js +65 -0
- pyseext-2.0.2/src/pyseext/js/PySeExt.ObservableHelper.js +79 -0
- pyseext-2.0.2/src/pyseext/js/PySeExt.StoreHelper.js +171 -0
- pyseext-2.0.2/src/pyseext/js/PySeExt.TreeHelper.js +241 -0
- {pyseext-2.0.1 → pyseext-2.0.2/src/pyseext.egg-info}/PKG-INFO +1 -1
- pyseext-2.0.2/src/pyseext.egg-info/SOURCES.txt +32 -0
- pyseext-2.0.2/src/pyseext.egg-info/top_level.txt +1 -0
- pyseext-2.0.1/src/pyseext.egg-info/SOURCES.txt +0 -24
- pyseext-2.0.1/src/pyseext.egg-info/top_level.txt +0 -1
- {pyseext-2.0.1 → pyseext-2.0.2}/LICENSE +0 -0
- {pyseext-2.0.1 → pyseext-2.0.2}/MANIFEST.in +0 -0
- {pyseext-2.0.1 → pyseext-2.0.2}/README.md +0 -0
- {pyseext-2.0.1 → pyseext-2.0.2}/setup.cfg +0 -0
- {pyseext-2.0.1 → pyseext-2.0.2}/setup.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.2/src/pyseext}/__init__.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.2/src/pyseext}/button_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.2/src/pyseext}/component_query.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.2/src/pyseext}/core.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.2/src/pyseext}/field_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.2/src/pyseext}/form_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.2/src/pyseext}/grid_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.2/src/pyseext}/has_referenced_javascript.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.2/src/pyseext}/input_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.2/src/pyseext}/local_storage_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.2/src/pyseext}/menu_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.2/src/pyseext}/observable_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.2/src/pyseext}/store_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.2/src/pyseext}/tree_helper.py +0 -0
- {pyseext-2.0.1 → pyseext-2.0.2}/src/pyseext.egg-info/dependency_links.txt +0 -0
- {pyseext-2.0.1 → pyseext-2.0.2}/src/pyseext.egg-info/requires.txt +0 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
globalThis.None = null;
|
|
2
|
+
|
|
3
|
+
globalThis.PySeExt = globalThis.PySeExt || {};
|
|
4
|
+
globalThis.PySeExt.ComponentQuery = {
|
|
5
|
+
/**
|
|
6
|
+
* Returns an array of matched element dom objects from within the dom.
|
|
7
|
+
*
|
|
8
|
+
* This wraps Ext.ComponentQuery.query, so see there for more detail.
|
|
9
|
+
* Each component has it's dom object returned however.
|
|
10
|
+
* You should never need this from Ext code. This will likely be useful for automated testing.
|
|
11
|
+
*
|
|
12
|
+
* Only supports the passing in of a single root (so no filtering), and an optional CSS selector,
|
|
13
|
+
* to return a sub-element in the found component.
|
|
14
|
+
*
|
|
15
|
+
* @param {String} selector The selector string to filter returned elements.
|
|
16
|
+
* @param {String} [rootId] The id of the dom element indicating the container within which to perform the query.
|
|
17
|
+
* If omitted, all components within the document are included in the search.
|
|
18
|
+
* @param {String} [cssSelector] An optional CSS selector that can be used to get child elements of a found component, e.g. a trigger on a field.
|
|
19
|
+
* @return {Object[]} The matched dom objects or an empty array if none found.
|
|
20
|
+
*/
|
|
21
|
+
query: function(selector, rootId, cssSelector) {
|
|
22
|
+
var components,
|
|
23
|
+
results = [],
|
|
24
|
+
root,
|
|
25
|
+
len,
|
|
26
|
+
i,
|
|
27
|
+
component,
|
|
28
|
+
el,
|
|
29
|
+
j;
|
|
30
|
+
|
|
31
|
+
// Get component for our root if specified
|
|
32
|
+
if (rootId) {
|
|
33
|
+
root = globalThis.Ext.getCmp(rootId);
|
|
34
|
+
|
|
35
|
+
if (!root) {
|
|
36
|
+
globalThis.Ext.Error.raise("Failed to find root component with id '" + rootId + "'! Are you passing in WebElement.get_attribute('id'), because that's what you need?");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
components = globalThis.Ext.ComponentQuery.query(selector, root);
|
|
41
|
+
len = components && components.length;
|
|
42
|
+
|
|
43
|
+
if (len) {
|
|
44
|
+
for (i = 0; i < len; i += 1) {
|
|
45
|
+
component = components[i];
|
|
46
|
+
|
|
47
|
+
if (component && component.getEl) {
|
|
48
|
+
el = component.getEl();
|
|
49
|
+
|
|
50
|
+
if (el) {
|
|
51
|
+
if (cssSelector) {
|
|
52
|
+
el = el.query(cssSelector);
|
|
53
|
+
|
|
54
|
+
if (el && el.length) {
|
|
55
|
+
for (j = 0; j < el.length; j += 1) {
|
|
56
|
+
if (el[j]) {
|
|
57
|
+
// This will already be a DOM element,
|
|
58
|
+
// since Element.query defaults to that.
|
|
59
|
+
results.push(el[j]);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
results.push(el.dom);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return results;
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Determines whether all components for the specified CQ are an instance of the specified class name.
|
|
76
|
+
*
|
|
77
|
+
* Note, will return True if the components are a subclass of the type too.
|
|
78
|
+
* @param {String} className The name of the class that we want to test for.
|
|
79
|
+
* @param {String} selector The selector string to query for.
|
|
80
|
+
* @param {String} rootId The id of the dom element indicating the container within which to perform the query.
|
|
81
|
+
* If omitted, all components within the document are included in the search.
|
|
82
|
+
* @return {Boolean} True if all components are an instance of the specified class, False if they are not, and
|
|
83
|
+
* undefined if no components are found.
|
|
84
|
+
*/
|
|
85
|
+
isComponentInstanceOf: function(className, selector, rootId) {
|
|
86
|
+
var cls = Ext.ClassManager.get(className),
|
|
87
|
+
components,
|
|
88
|
+
root,
|
|
89
|
+
len,
|
|
90
|
+
i,
|
|
91
|
+
component,
|
|
92
|
+
el,
|
|
93
|
+
isInstance;
|
|
94
|
+
|
|
95
|
+
if (!cls) {
|
|
96
|
+
globalThis.Ext.Error.raise("A class with the name '" + className + "' is not defined!");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Get component for our root if specified
|
|
100
|
+
if (rootId) {
|
|
101
|
+
root = globalThis.Ext.getCmp(rootId);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
components = globalThis.Ext.ComponentQuery.query(selector, root);
|
|
105
|
+
len = components && components.length;
|
|
106
|
+
|
|
107
|
+
if (len) {
|
|
108
|
+
for (i = 0; i < len; i += 1) {
|
|
109
|
+
component = components[i];
|
|
110
|
+
|
|
111
|
+
if (component) {
|
|
112
|
+
isInstance = component instanceof cls;
|
|
113
|
+
|
|
114
|
+
if (!isInstance) {
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return isInstance;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
globalThis.None = null;
|
|
2
|
+
|
|
3
|
+
globalThis.PySeExt = globalThis.PySeExt || {};
|
|
4
|
+
globalThis.PySeExt.Core = {
|
|
5
|
+
/**
|
|
6
|
+
* Retrieves the value of a member from an object.
|
|
7
|
+
*
|
|
8
|
+
* The member can contain periods, to access child objects.
|
|
9
|
+
*
|
|
10
|
+
* @param {Object} object The object from which to retrieve the value.
|
|
11
|
+
* @param {String} member A string identifying the member value to retrieve. Can contain periods to access child objects.
|
|
12
|
+
* @return {Object} The value of the object member, or undefined if it or any part of the path was not found.
|
|
13
|
+
*/
|
|
14
|
+
getObjectMember: function(object, member) {
|
|
15
|
+
var me = this,
|
|
16
|
+
members = member.split('.'),
|
|
17
|
+
value = object[members[0]];
|
|
18
|
+
|
|
19
|
+
if (value && (members.length > 1)) {
|
|
20
|
+
members.shift();
|
|
21
|
+
value = me.getObjectMember(value, members.join('.'));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return value;
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Indicates whether there is currently an Ajax request in progress.
|
|
29
|
+
* @return {Boolean} True if there is a request in progress, false otherwise.
|
|
30
|
+
*/
|
|
31
|
+
isAjaxRequestInProgress: function() {
|
|
32
|
+
return globalThis.Ext.Ajax.isLoading();
|
|
33
|
+
}
|
|
34
|
+
};
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
globalThis.None = null;
|
|
2
|
+
|
|
3
|
+
globalThis.PySeExt = globalThis.PySeExt || {};
|
|
4
|
+
globalThis.PySeExt.FieldHelper = {
|
|
5
|
+
/**
|
|
6
|
+
* Finds the specified field input element on the specified form.
|
|
7
|
+
* @param {String} formCQ The CQ to get to the form panel.
|
|
8
|
+
* @param {String} name The name of the field.
|
|
9
|
+
* @returns The DOM for the field's input element
|
|
10
|
+
*/
|
|
11
|
+
findFieldInputElement: function(formCQ, name) {
|
|
12
|
+
var field = this.__getField(formCQ, name);
|
|
13
|
+
|
|
14
|
+
return field && field.inputEl.dom;
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Finds the specified field on the specified form and returns it's xtype.
|
|
19
|
+
* @param {String} formCQ The CQ to get to the form panel.
|
|
20
|
+
* @param {String} name The name of the field.
|
|
21
|
+
* @returns {String} The xtype of the field, if found.
|
|
22
|
+
*/
|
|
23
|
+
getFieldXType: function(formCQ, name) {
|
|
24
|
+
var field = this.__getField(formCQ, name);
|
|
25
|
+
|
|
26
|
+
return field && field.xtype;
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Finds the specified field on the specified form and returns it's value.
|
|
31
|
+
* @param {String} formCQ The CQ to get to the form panel.
|
|
32
|
+
* @param {String} name The name of the field.
|
|
33
|
+
* @returns {Mixed} The value of the field, if found.
|
|
34
|
+
*/
|
|
35
|
+
getFieldValue: function(formCQ, name) {
|
|
36
|
+
var field = this.__getField(formCQ, name),
|
|
37
|
+
value;
|
|
38
|
+
|
|
39
|
+
if (field) {
|
|
40
|
+
value = field.getValue();
|
|
41
|
+
// Python cannot convert a JS datetime to a Python one, so convert before sending.
|
|
42
|
+
if (Ext.isDate(value)) {
|
|
43
|
+
value = value.toLocaleDateString('en-gb')
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return value;
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Finds the specified field on the specified form and returns it's display value, if it has one.
|
|
52
|
+
* @param {String} formCQ The CQ to get to the form panel.
|
|
53
|
+
* @param {String} name The name of the field.
|
|
54
|
+
* @returns {Mixed} The display value of the field, if found and has a display value.
|
|
55
|
+
*/
|
|
56
|
+
getFieldDisplayValue: function(formCQ, name) {
|
|
57
|
+
var field = this.__getField(formCQ, name);
|
|
58
|
+
|
|
59
|
+
return field && field.getDisplayValue && field.getDisplayValue();
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Finds the specified field on the specified form and returns it's raw value, if it has one.
|
|
64
|
+
* @param {String} formCQ The CQ to get to the form panel.
|
|
65
|
+
* @param {String} name The name of the field.
|
|
66
|
+
* @returns {String} The raw value of the field, if found and has a raw value.
|
|
67
|
+
*/
|
|
68
|
+
getFieldRawValue: function(formCQ, name) {
|
|
69
|
+
var field = this.__getField(formCQ, name);
|
|
70
|
+
|
|
71
|
+
return field && field.getRawValue && field.getRawValue();
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Finds the specified field and sets its value directly.
|
|
76
|
+
*
|
|
77
|
+
* Raises an error if the field was not found.
|
|
78
|
+
* @param {String} formCQ The CQ to get to the form panel.
|
|
79
|
+
* @param {String} name The name of the field.
|
|
80
|
+
* @param {Number} value The value of the field.
|
|
81
|
+
*/
|
|
82
|
+
setFieldValue: function(formCQ, name, value) {
|
|
83
|
+
this.__getField(formCQ, name, true).setValue(value);
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Determines whether the specified field is a remotely filtered combobox.
|
|
88
|
+
* @param {String} formCQ The CQ to get to the form panel.
|
|
89
|
+
* @param {String} name The name of the field.
|
|
90
|
+
* @returns {Boolean} True if the field was found, and is a remotely filtered combobox.
|
|
91
|
+
* False otherwise.
|
|
92
|
+
*/
|
|
93
|
+
isRemotelyFilteredComboBox: function(formCQ, name) {
|
|
94
|
+
var field = this.__getField(formCQ, name),
|
|
95
|
+
isRemotelyFilteredComboBox;
|
|
96
|
+
|
|
97
|
+
isRemotelyFilteredComboBox = field instanceof globalThis.Ext.form.field.ComboBox &&
|
|
98
|
+
field.queryMode === 'remote';
|
|
99
|
+
|
|
100
|
+
return isRemotelyFilteredComboBox;
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Method to focus on a field on a form by (zero-based) index or name.
|
|
105
|
+
*
|
|
106
|
+
* Raises an error if the field was not found.
|
|
107
|
+
* @param {String} formCQ The CQ to get to the form panel.
|
|
108
|
+
* @param {String|Integer} indexOrName The zero-based index or name of the field to focus.
|
|
109
|
+
*/
|
|
110
|
+
focusField: function(formCQ, indexOrName) {
|
|
111
|
+
var me = this;
|
|
112
|
+
|
|
113
|
+
if (globalThis.Ext.isString(indexOrName)) {
|
|
114
|
+
me.__getField(formCQ, indexOrName, true).focus();
|
|
115
|
+
} else {
|
|
116
|
+
me.__getFieldAtIndex(formCQ, indexOrName).focus();
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Determines whether the specified field has focus or not.
|
|
122
|
+
*
|
|
123
|
+
* @param {String} formCQ The CQ to get to the form panel.
|
|
124
|
+
* @param {String|Integer} indexOrName The zero-based index or name of the field to focus.
|
|
125
|
+
* @returns {Boolean} True if the field has focus, false otherwise.
|
|
126
|
+
*/
|
|
127
|
+
doesFieldHaveFocus: function(formCQ, indexOrName) {
|
|
128
|
+
var me = this,
|
|
129
|
+
field;
|
|
130
|
+
|
|
131
|
+
if (globalThis.Ext.isString(indexOrName)) {
|
|
132
|
+
field = me.__getField(formCQ, indexOrName, true);
|
|
133
|
+
} else {
|
|
134
|
+
field = me.__getFieldAtIndex(formCQ, indexOrName);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return field.hasFocus;
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Selects a value on a combobox field by finding a record with the specified data.
|
|
142
|
+
*
|
|
143
|
+
* Ensures that the select event is fired if the record is found and selected.
|
|
144
|
+
* @param {String} formCQ The CQ to get to the form panel.
|
|
145
|
+
* @param {String} name The name of the field.
|
|
146
|
+
* @param {Object} data The data to find in the combobox store and select.
|
|
147
|
+
* @returns {Boolean} Indicates whether a record was found and selected.
|
|
148
|
+
*/
|
|
149
|
+
selectComboBoxValue: function(formCQ, name, data) {
|
|
150
|
+
var me = this,
|
|
151
|
+
field = me.__getField(formCQ, name, true),
|
|
152
|
+
store,
|
|
153
|
+
index,
|
|
154
|
+
record;
|
|
155
|
+
|
|
156
|
+
if (field instanceof globalThis.Ext.form.field.ComboBox) {
|
|
157
|
+
store = field.getStore();
|
|
158
|
+
|
|
159
|
+
if (store.isLoaded()) {
|
|
160
|
+
index = store.getData().findIndexBy(function(record) {
|
|
161
|
+
var prop,
|
|
162
|
+
doAllMembersMatch = true;
|
|
163
|
+
|
|
164
|
+
for (prop in data) {
|
|
165
|
+
if (data.hasOwnProperty(prop)) {
|
|
166
|
+
if (data[prop] !== record.get(prop)) {
|
|
167
|
+
doAllMembersMatch = false;
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return doAllMembersMatch;
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
if (index === -1) {
|
|
177
|
+
// Record was not found
|
|
178
|
+
return false;
|
|
179
|
+
} else {
|
|
180
|
+
record = store.getAt(index);
|
|
181
|
+
|
|
182
|
+
field.select(record);
|
|
183
|
+
field.fireEvent('select', field, record);
|
|
184
|
+
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
} else {
|
|
188
|
+
globalThis.Ext.Error.raise("The combobox store is not loaded!");
|
|
189
|
+
}
|
|
190
|
+
} else {
|
|
191
|
+
globalThis.Ext.Error.raise("Field is not a combobox!");
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Finds a field in a form panel.
|
|
197
|
+
* Optionally raises an error if not found.
|
|
198
|
+
* @param {String} formCQ The CQ to get to the form panel.
|
|
199
|
+
* @param {String} name The name of the field.
|
|
200
|
+
* @param {Boolean} throwIfNotFound Indicates whether to raise an error if not found.
|
|
201
|
+
* If omitted then value is taken to be false.
|
|
202
|
+
* @returns {Ext.form.field.Base} The field instance.
|
|
203
|
+
*/
|
|
204
|
+
__getField: function(formCQ, name, throwIfNotFound) {
|
|
205
|
+
var formPanel = Ext.ComponentQuery.query(formCQ),
|
|
206
|
+
field;
|
|
207
|
+
|
|
208
|
+
if (formPanel && formPanel.length) {
|
|
209
|
+
formPanel = formPanel[0];
|
|
210
|
+
field = formPanel.getForm().findField(name);
|
|
211
|
+
} else if (throwIfNotFound) {
|
|
212
|
+
globalThis.Ext.Error.raise("Form panel could not be found!");
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (!field && throwIfNotFound) {
|
|
216
|
+
globalThis.Ext.Error.raise("Field could not be found!");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return field;
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Gets a field in a form panel by index.
|
|
224
|
+
*
|
|
225
|
+
* Raises an error if the index is outside of the bounds of the fields,
|
|
226
|
+
* or is otherwise invalid.
|
|
227
|
+
* @param {String} formCQ The CQ to get to the form panel.
|
|
228
|
+
* @param {Number} index The index of the field.
|
|
229
|
+
* @returns {Ext.form.field.Base} The field instance.
|
|
230
|
+
*/
|
|
231
|
+
__getFieldAtIndex: function(formCQ, index) {
|
|
232
|
+
var formPanel = Ext.ComponentQuery.query(formCQ),
|
|
233
|
+
field;
|
|
234
|
+
|
|
235
|
+
if (formPanel && formPanel.length) {
|
|
236
|
+
formPanel = formPanel[0];
|
|
237
|
+
field = formPanel.getForm().getFields().getAt(index);
|
|
238
|
+
} else {
|
|
239
|
+
globalThis.Ext.Error.raise("Form panel could not be found!");
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (!field) {
|
|
243
|
+
globalThis.Ext.Error.raise("Field could not be found!");
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return field;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
};
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
globalThis.None = null;
|
|
2
|
+
|
|
3
|
+
globalThis.PySeExt = globalThis.PySeExt || {};
|
|
4
|
+
globalThis.PySeExt.GridHelper = {
|
|
5
|
+
/**
|
|
6
|
+
* Gets the element for a column header on the specified grid, by header text or dataIndex.
|
|
7
|
+
* @param {String} gridSelector The CQ for the grid
|
|
8
|
+
* @param {String} columnTextOrDataIndex The text or dataIndex of the column
|
|
9
|
+
* @returns {Object} The DOM node for the column header
|
|
10
|
+
*/
|
|
11
|
+
getColumnHeader: function(gridSelector, columnTextOrDataIndex) {
|
|
12
|
+
var me = this,
|
|
13
|
+
columnHeader = me.__findColumnHeader(gridSelector, columnTextOrDataIndex);
|
|
14
|
+
|
|
15
|
+
return columnHeader && columnHeader.getEl().dom;
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Gets the element for a column header's trigger on the specified grid, by header text or dataIndex.
|
|
20
|
+
* @param {String} gridSelector The CQ for the grid
|
|
21
|
+
* @param {String} columnTextOrDataIndex The text or dataIndex of the column
|
|
22
|
+
* @returns {Object} The DOM node for the column header's trigger
|
|
23
|
+
*/
|
|
24
|
+
getColumnHeaderTrigger: function(gridSelector, columnTextOrDataIndex) {
|
|
25
|
+
var me = this,
|
|
26
|
+
columnHeader = me.__findColumnHeader(gridSelector, columnTextOrDataIndex),
|
|
27
|
+
columnHeaderTrigger;
|
|
28
|
+
|
|
29
|
+
if (columnHeader) {
|
|
30
|
+
columnHeaderTrigger = columnHeader.getEl().down('.x-column-header-trigger', true);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return columnHeaderTrigger;
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Clears the current selection.
|
|
38
|
+
*
|
|
39
|
+
* Useful if want to quickly refresh a grid without having to process all the events.
|
|
40
|
+
* This will only work if the grid supports deselection.
|
|
41
|
+
*
|
|
42
|
+
* @param {String} gridSelector The selector for the grid.
|
|
43
|
+
* @return {void}
|
|
44
|
+
*/
|
|
45
|
+
clearSelection: function(gridSelector) {
|
|
46
|
+
var grids = globalThis.Ext.ComponentQuery.query(gridSelector);
|
|
47
|
+
|
|
48
|
+
if (grids && grids.length) {
|
|
49
|
+
grids[0].getSelectionModel().deselectAll();
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Gets the row element with the specified data or index in the grid.
|
|
55
|
+
* The row is scrolled into view ready for clicking by the caller.
|
|
56
|
+
*
|
|
57
|
+
* The grid must be visible.
|
|
58
|
+
*
|
|
59
|
+
* @param {String} gridSelector The selector for the grid.
|
|
60
|
+
* @param {Object|Number} rowData The index of or an object containing the row data for the record to be found.
|
|
61
|
+
* @return {Element} The element for the found row.
|
|
62
|
+
*/
|
|
63
|
+
getRow: function(gridSelector, rowData) {
|
|
64
|
+
var me = this,
|
|
65
|
+
grids = globalThis.Ext.ComponentQuery.query(gridSelector),
|
|
66
|
+
grid,
|
|
67
|
+
store,
|
|
68
|
+
rowIndex;
|
|
69
|
+
|
|
70
|
+
if (grids && grids.length) {
|
|
71
|
+
grid = grids[0];
|
|
72
|
+
store = grid.getStore();
|
|
73
|
+
|
|
74
|
+
rowIndex = me.__findRowIndex(rowData, store);
|
|
75
|
+
|
|
76
|
+
if (rowIndex !== -1) {
|
|
77
|
+
return grid.getView().getRow(rowIndex);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return null;
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Gets the row data with the specified data or index in the grid.
|
|
86
|
+
* The row is scrolled into view ready for clicking by the caller.
|
|
87
|
+
*
|
|
88
|
+
* The grid must be visible.
|
|
89
|
+
*
|
|
90
|
+
* @param {String} gridSelector The selector for the grid.
|
|
91
|
+
* @param {Object|Number} rowData The index of or an object containing the row data for the record to be found.
|
|
92
|
+
* @return {Object[]} The data for the found row.
|
|
93
|
+
*/
|
|
94
|
+
getRowData: function(gridSelector, rowData) {
|
|
95
|
+
var me = this,
|
|
96
|
+
grids = globalThis.Ext.ComponentQuery.query(gridSelector),
|
|
97
|
+
grid,
|
|
98
|
+
store,
|
|
99
|
+
rowIndex;
|
|
100
|
+
|
|
101
|
+
if (grids && grids.length) {
|
|
102
|
+
grid = grids[0];
|
|
103
|
+
store = grid.getStore();
|
|
104
|
+
|
|
105
|
+
rowIndex = me.__findRowIndex(rowData, store);
|
|
106
|
+
|
|
107
|
+
if (rowIndex !== -1) {
|
|
108
|
+
var data = store.getAt(rowIndex).getData();
|
|
109
|
+
var converted = {};
|
|
110
|
+
Object.keys(data).forEach(function (key) {
|
|
111
|
+
var value = data[key];
|
|
112
|
+
if (value instanceof Date) {
|
|
113
|
+
// Convert to ISO 8601 string, which Python can parse easily
|
|
114
|
+
converted[key] = value.toLocaleString("en-GB", { timeZone: "Europe/London" });
|
|
115
|
+
} else {
|
|
116
|
+
converted[key] = value;
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
return converted;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return null;
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Trims the specified row data to contain just the required fields.
|
|
129
|
+
*
|
|
130
|
+
* Useful when we have stored some row data, and want to select it again later, but some of the ids of times
|
|
131
|
+
* may be different.
|
|
132
|
+
*
|
|
133
|
+
* @param {Object} rowData The row data to trim.
|
|
134
|
+
* @param {Array} requiredFields An array of string indicating the fields that are required from the row data.
|
|
135
|
+
* @return {Object} A copy of the row data object, with only the required fields included.
|
|
136
|
+
*/
|
|
137
|
+
__trimRowData: function(rowData, requiredFields) {
|
|
138
|
+
var trimmedRowData = {},
|
|
139
|
+
i;
|
|
140
|
+
|
|
141
|
+
for (i = 0; i < requiredFields.length; i += 1) {
|
|
142
|
+
trimmedRowData[requiredFields[i]] = rowData[requiredFields[i]];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return trimmedRowData;
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Retrieves the selection of the specified grid.
|
|
150
|
+
* @private
|
|
151
|
+
* @param {String} gridSelector The selector for the grid.
|
|
152
|
+
* @param {Function} callback The function to call when the done.
|
|
153
|
+
* @param {Array} callback.selection The grids current selection.
|
|
154
|
+
* @return {void}
|
|
155
|
+
*/
|
|
156
|
+
__getSelection: function(gridSelector, callback) {
|
|
157
|
+
var grids = globalThis.Ext.ComponentQuery.query(gridSelector);
|
|
158
|
+
|
|
159
|
+
if (grids && grids.length) {
|
|
160
|
+
globalThis.Ext.callback(callback, this, [grids[0].getSelectionModel().getSelection()]);
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Finds on a column header on a grid.
|
|
166
|
+
* @private
|
|
167
|
+
* @param {String} gridSelector The selector for the grid.
|
|
168
|
+
* @param {String} columnTextOrDataIndex The text or dataIndex of the column to find.
|
|
169
|
+
* @return {Ext.Component} The column header component
|
|
170
|
+
*/
|
|
171
|
+
__findColumnHeader: function(gridSelector, columnTextOrDataIndex) {
|
|
172
|
+
var me = this,
|
|
173
|
+
grid,
|
|
174
|
+
dataColumns,
|
|
175
|
+
i,
|
|
176
|
+
dataColumn,
|
|
177
|
+
columnHeader;
|
|
178
|
+
|
|
179
|
+
components = Ext.ComponentQuery.query(gridSelector);
|
|
180
|
+
if (components && components.length) {
|
|
181
|
+
grid = components[0];
|
|
182
|
+
|
|
183
|
+
dataColumns = grid.headerCt.gridDataColumns
|
|
184
|
+
|
|
185
|
+
// Find column header
|
|
186
|
+
for (i = 0; i < dataColumns.length; i += 1) {
|
|
187
|
+
dataColumn = dataColumns[i];
|
|
188
|
+
|
|
189
|
+
if ((dataColumn.dataIndex === columnTextOrDataIndex) ||
|
|
190
|
+
(dataColumn.text === columnTextOrDataIndex)) {
|
|
191
|
+
|
|
192
|
+
columnHeader = dataColumn;
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return columnHeader;
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Gets the row index with the specified data or index in the grid.
|
|
203
|
+
* The row is scrolled into view ready for clicking by the caller.
|
|
204
|
+
*
|
|
205
|
+
* The grid must be visible.
|
|
206
|
+
*
|
|
207
|
+
* @param {Object|Number} rowData The index of or an object containing the row data for the record to be found.
|
|
208
|
+
* @return {Number} The index for the row record, or -1 if not found
|
|
209
|
+
*/
|
|
210
|
+
__findRowIndex: function(rowData, store) {
|
|
211
|
+
var rowIndex = -1,
|
|
212
|
+
foundIndex,
|
|
213
|
+
prop;
|
|
214
|
+
|
|
215
|
+
if (typeof(rowData) === 'number') {
|
|
216
|
+
foundIndex = rowData;
|
|
217
|
+
|
|
218
|
+
// Verify it's not bollocks
|
|
219
|
+
if (!Ext.isNumber(parseInt(foundIndex)) || foundIndex < 0) {
|
|
220
|
+
globalThis.Ext.raise('If attempting to get a row for a specific index, the index must be an integer greater than or equal to zero.');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Check that found index is within bounds, if so grab the row.
|
|
224
|
+
if (foundIndex < store.getCount()) {
|
|
225
|
+
rowIndex = foundIndex;
|
|
226
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
foundIndex = store.findBy(function(record, id) {
|
|
229
|
+
var hasRecordBeenFound = true;
|
|
230
|
+
|
|
231
|
+
for (prop in rowData) {
|
|
232
|
+
if (rowData.hasOwnProperty(prop)) {
|
|
233
|
+
if (record.get(prop) !== rowData[prop]) {
|
|
234
|
+
hasRecordBeenFound = false;
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return hasRecordBeenFound;
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
// This could be -1, but that's fine since that's the expected "not found" result.
|
|
244
|
+
rowIndex = foundIndex;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return rowIndex;
|
|
248
|
+
}
|
|
249
|
+
};
|