Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EDMTP-281] DependsOn: add fill-select option #282

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,10 @@ public class DependsOnActions {
*/
public static final String UPDATE_OPTIONS = "update-options";

/**
* Refreshes the options set of a Coral3 Select widget with provided values
*/
public static final String FILL_SELECT = "fill-select";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A question is:
Are we always going to fill only selects? No raidoGroups/ buttonGroups / autocompletes? May it be, we would want to give a more generic name, kind of "fill-options"?


private DependsOnActions() {}
}
3 changes: 3 additions & 0 deletions docs/md/depends-on.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ Built-in plug-in actions are:
* `required` - set the required marker of the field from the Query result.
* `validate` - set the validation state of the field from the Query result.
* `disabled` - set the field's disabled state from the Query result.
* `fill-select` - fill select options with values from the Query result. The result object must contain *value* and *text* fields
_Additional parameters:_
* `selected` (optional) - a dependsOn query, whose evaluation result should be a value or an array of selected values

##### Async actions

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @author Natasha Gorshunova
*
* DependsOn Coral 3 Select Action.
*
* A simple action to fill select with options with provided values
*
* Action callback params:
* {Array<{value:string, text:string}>} options
* {string} config.selected - a dependsOn query, whose evaluation result should be a value or an array of selected values
*/
(function (Granite, $, DependsOn) {
'use strict';

const ACTION_NAME = 'fill-select';

DependsOn.ActionRegistry.register(ACTION_NAME, function (options, { selected }) {
if (!options || !options.length) {
return;
}

const $select = this.$el;
const selectedValue = selected ? DependsOn.QueryProcessor.calculateQuery(selected, $select) : '';

DependsOn.SelectUtils.setOptions($select, options, selectedValue);
setTimeout(() => $select.trigger('change.dependsOn'));
});
})(Granite, Granite.$, Granite.DependsOnPlugin);
Original file line number Diff line number Diff line change
Expand Up @@ -94,25 +94,12 @@
// resource (so that a new option can be assigned the "selected" state if its value matches),
// and then replace the option set in DOM
if ($select.attr(STORED_VALUE_ATTRIBUTE)) {
setOptions($select, options, $select.attr(STORED_VALUE_ATTRIBUTE));
DependsOn.SelectUtils.setOptions($select, options, $select.attr(STORED_VALUE_ATTRIBUTE));
} else {
setOptionsAndRestoreSelected($select, options, resourceAddr, valueMember);
}
}

/**
* Set a new option set to the Granite Select component
*
* @param $select - Select widget to set options for
* @param options - new option set, represented by "raw" (non-Granite) entities
* @param selectedValue - the value to mark as selected in the option set
*/
function setOptions($select, options, selectedValue) {
const itemCollection = $select.get(0).items;
itemCollection.clear();
options.map(src => createOption(src, selectedValue)).forEach(option => itemCollection.add(option));
}

/**
* Query for a stored JCR resource to find the currently selected value and assign to the Select widget if found
*
Expand All @@ -126,29 +113,13 @@
.then(resource => {
const storedValue = resource[valueMember];
$select.attr(STORED_VALUE_ATTRIBUTE, storedValue);
setOptions($select, options, storedValue);
DependsOn.SelectUtils.setOptions($select, options, storedValue);
})
.fail(() => {
setOptions($select, options);
DependsOn.SelectUtils.setOptions($select, options);
});
}

/**
* Create a new Granite option
*
* @param src - an object having a {@code text} and a {@code value} attribute
* @param selectedValue - the match value to trigger 'selected' state of the option
*/
function createOption(src, selectedValue) {
return {
value: src.value,
content: {
textContent: src.text
},
selected: (!selectedValue && !src.value) || selectedValue === src.value || (Array.isArray(selectedValue) && selectedValue.includes(src.value))
};
}

/**
* Register {@code update-options} action in DependsOn registry.
* This action performs updating of the option set of the current Select widget
Expand Down Expand Up @@ -183,7 +154,7 @@
processNewOptions($select, newOptions, resourceAddress, valueMember);
})
.fail(() => {
setOptions($select, []);
DependsOn.SelectUtils.setOptions($select, []);
});
});
})(Granite, Granite.$, Granite.DependsOnPlugin);
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@
* */
static get REFERENCE_REGEXP() { return REFERENCE_REGEXP; }

/**
*
* @param {string} query
* @param {JQuery} $el
* @returns current result of the query
*/
static calculateQuery(query, $el) {
return QueryProcessor.evaluateQuery(QueryProcessor.parseQuery(query, $el), $el);
}

/**
* Evaluate the parsed query
* @param {string} query - parsed query
Expand Down Expand Up @@ -66,7 +76,7 @@
ns.GroupReferenceRegistry.register(name, $context) :
ns.ElementReferenceRegistry.register(name, $context);

reference.subscribe(changeHandlerCB);
reference.subscribe(changeHandlerCB); // ignores undefined handler
return `${reference.id}.value`;
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/***
* Coral 3 Select Utils
* */
(function (Granite, $, DependsOn) {
'use strict';

class SelectUtils {
/**
* Creates a new Granite option
*
* @param option - an option object
* @param {string} option.text - text to display
* @param {string} option.value - actual value of an option
* @param selectedValue - value or array of values to trigger 'selected' state of the option
*/
static createOption(option, selectedValue) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update-datasource action is creating Select options as well. May I kindly ask you to look into that action and possibly implement these methods there? So that we have a more unified codebase

return {
value: option.value,
content: {
textContent: option.text
},
selected: (!selectedValue && !option.value) || selectedValue === option.value || (Array.isArray(selectedValue) && selectedValue.includes(option.value))
};
}

/**
* Sets a new option set to the Granite Select component
*
* @param {JQuery} $select - Select widget to set options for
* @param {Array} options - new option set, represented by "raw" (non-Granite) entities
* @param selectedValue - the value to mark as selected in the option set
*/
static setOptions($select, options, selectedValue) {
const itemCollection = $select.get(0).items;
itemCollection.clear();
options.map(option => SelectUtils.createOption(option, selectedValue)).forEach(option => itemCollection.add(option));
}
}

DependsOn.SelectUtils = SelectUtils;
})(Granite, Granite.$, Granite.DependsOnPlugin);