pyseext 2.0.1__tar.gz → 2.0.3__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/README.md → pyseext-2.0.3/PKG-INFO +11 -5
- pyseext-2.0.3/README.md +23 -0
- {pyseext-2.0.1 → pyseext-2.0.3}/pyproject.toml +1 -1
- {pyseext-2.0.1/src/pseext → pyseext-2.0.3/src/pyseext}/grid_helper.py +31 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.3/src/pyseext}/has_referenced_javascript.py +2 -3
- pyseext-2.0.3/src/pyseext/js/PySeExt.ComponentQuery.js +123 -0
- pyseext-2.0.3/src/pyseext/js/PySeExt.Core.js +34 -0
- pyseext-2.0.3/src/pyseext/js/PySeExt.FieldHelper.js +249 -0
- pyseext-2.0.3/src/pyseext/js/PySeExt.GridHelper.js +249 -0
- pyseext-2.0.3/src/pyseext/js/PySeExt.LocalStorageHelper.js +65 -0
- pyseext-2.0.3/src/pyseext/js/PySeExt.ObservableHelper.js +79 -0
- pyseext-2.0.3/src/pyseext/js/PySeExt.StoreHelper.js +171 -0
- pyseext-2.0.3/src/pyseext/js/PySeExt.TreeHelper.js +241 -0
- {pyseext-2.0.1 → pyseext-2.0.3}/src/pyseext.egg-info/PKG-INFO +2 -12
- pyseext-2.0.3/src/pyseext.egg-info/SOURCES.txt +31 -0
- pyseext-2.0.3/src/pyseext.egg-info/top_level.txt +1 -0
- pyseext-2.0.1/PKG-INFO +0 -43
- pyseext-2.0.1/setup.py +0 -25
- 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.3}/LICENSE +0 -0
- {pyseext-2.0.1 → pyseext-2.0.3}/MANIFEST.in +0 -0
- {pyseext-2.0.1 → pyseext-2.0.3}/setup.cfg +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.3/src/pyseext}/__init__.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.3/src/pyseext}/button_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.3/src/pyseext}/component_query.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.3/src/pyseext}/core.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.3/src/pyseext}/field_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.3/src/pyseext}/form_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.3/src/pyseext}/input_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.3/src/pyseext}/local_storage_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.3/src/pyseext}/menu_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.3/src/pyseext}/observable_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.3/src/pyseext}/store_helper.py +0 -0
- {pyseext-2.0.1/src/pseext → pyseext-2.0.3/src/pyseext}/tree_helper.py +0 -0
- {pyseext-2.0.1 → pyseext-2.0.3}/src/pyseext.egg-info/dependency_links.txt +0 -0
- {pyseext-2.0.1 → pyseext-2.0.3}/src/pyseext.egg-info/requires.txt +0 -0
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyseext
|
|
3
|
+
Version: 2.0.3
|
|
4
|
+
Summary: Aids the testing of ExtJS applications from Python using Selenium.
|
|
5
|
+
Requires-Python: >=3.8
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: selenium
|
|
9
|
+
Dynamic: license-file
|
|
10
|
+
|
|
11
|
+
# PySeExt
|
|
2
12
|
|
|
3
13
|
This project contains a package to aid the testing of ExtJS applications from Python using Selenium.
|
|
4
14
|
|
|
@@ -21,7 +31,3 @@ Instance Variables | `lower_with_under` | `_lower_with_under`
|
|
|
21
31
|
Method Names | `lower_with_under()` | `_lower_with_under()`
|
|
22
32
|
Function/Method Parameters | `lower_with_under` |
|
|
23
33
|
Local Variables | `lower_with_under` |
|
|
24
|
-
|
|
25
|
-
### Additional Notes
|
|
26
|
-
I have also settled on a standard of having a single class per source file (that I now understand are called modules), although inner classes are allowed.
|
|
27
|
-
This is pretty much standard practice in other languages, and makes source control and managing conflicts far easier.
|
pyseext-2.0.3/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# PySeExt
|
|
2
|
+
|
|
3
|
+
This project contains a package to aid the testing of ExtJS applications from Python using Selenium.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
## Naming Standards
|
|
7
|
+
|
|
8
|
+
Full details [here](https://namingconvention.org/python/).
|
|
9
|
+
|
|
10
|
+
### TL;DR
|
|
11
|
+
**Type** | **Public** | **Internal**
|
|
12
|
+
--- | --- | ---
|
|
13
|
+
Packages | `lower_with_under` |
|
|
14
|
+
Modules | `lower_with_under` | `_lower_with_under`
|
|
15
|
+
Classes | `CapWords` | `_CapWords`
|
|
16
|
+
Exceptions | `CapWords` |
|
|
17
|
+
Functions | `lower_with_under()` | `_lower_with_under()`
|
|
18
|
+
Global/Class Constants | `CAPS_WITH_UNDER` | `_CAPS_WITH_UNDER`
|
|
19
|
+
Global/Class Variables | `lower_with_under` | `_lower_with_under`
|
|
20
|
+
Instance Variables | `lower_with_under` | `_lower_with_under`
|
|
21
|
+
Method Names | `lower_with_under()` | `_lower_with_under()`
|
|
22
|
+
Function/Method Parameters | `lower_with_under` |
|
|
23
|
+
Local Variables | `lower_with_under` |
|
|
@@ -335,6 +335,37 @@ class GridHelper(HasReferencedJavaScript):
|
|
|
335
335
|
self._input_helper.type_escape()
|
|
336
336
|
self._input_helper.type_escape()
|
|
337
337
|
|
|
338
|
+
def filter_bool_column(
|
|
339
|
+
self,
|
|
340
|
+
grid_cq: str,
|
|
341
|
+
column_text_or_data_index: str,
|
|
342
|
+
bool_value: str,
|
|
343
|
+
wait_for_store_loaded: bool = True,
|
|
344
|
+
):
|
|
345
|
+
"""Toggles the values on a boolean filtered column on a grid.
|
|
346
|
+
|
|
347
|
+
Args:
|
|
348
|
+
grid_cq (str): The component query for the owning grid.
|
|
349
|
+
column_text_or_data_index (str): The header text or dataIndex of the grid column.
|
|
350
|
+
bool_value (str): The value to set e.g. Yes/No.
|
|
351
|
+
wait_for_store_loaded (bool, optional): Indicates whether to wait for the store to load. Defaults to True.
|
|
352
|
+
"""
|
|
353
|
+
self.click_column_header_trigger(grid_cq, column_text_or_data_index)
|
|
354
|
+
self._menu_helper.move_to_menu_item_by_text("Filters")
|
|
355
|
+
|
|
356
|
+
if wait_for_store_loaded:
|
|
357
|
+
self._store_helper.reset_store_load_count(grid_cq)
|
|
358
|
+
|
|
359
|
+
self._menu_helper.click_menu_item_by_text(bool_value)
|
|
360
|
+
|
|
361
|
+
if wait_for_store_loaded:
|
|
362
|
+
self._store_helper.wait_for_store_loaded(grid_cq)
|
|
363
|
+
|
|
364
|
+
# Close filter and then column menu
|
|
365
|
+
self._input_helper.type_escape()
|
|
366
|
+
self._input_helper.type_escape()
|
|
367
|
+
|
|
368
|
+
|
|
338
369
|
def filter_number_column(
|
|
339
370
|
self,
|
|
340
371
|
grid_cq: str,
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
Module that contains our HasReferencedJavaScript class.
|
|
3
3
|
"""
|
|
4
4
|
from logging import Logger
|
|
5
|
-
from
|
|
6
|
-
import pkg_resources
|
|
5
|
+
from importlib.resources import files
|
|
7
6
|
|
|
8
7
|
from selenium.webdriver.remote.webdriver import WebDriver
|
|
9
8
|
from selenium.webdriver.support.wait import WebDriverWait
|
|
@@ -48,7 +47,7 @@ class HasReferencedJavaScript:
|
|
|
48
47
|
# If our JavaScript has not been loaded then load it now
|
|
49
48
|
if not self._driver.execute_script(self._SCRIPT_LOADED_TEST_TEMPLATE.format(class_name=class_name)):
|
|
50
49
|
# Read JavaScript from package resources
|
|
51
|
-
stream =
|
|
50
|
+
stream = files(__package__).joinpath('js', f'PySeExt.{class_name}.js').open('rb')
|
|
52
51
|
|
|
53
52
|
self._logger.debug("Loading JavaScript from '%s'", stream.name)
|
|
54
53
|
self._driver.execute_script(str(stream.read(), encoding = "utf-8"))
|
|
@@ -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
|
+
};
|