Hi, everybody. This is my first post here, and I’m quite new in the bpmn.io world.
So, I need to make possible to create a multiple selectBox, since I have the need to create a custom extention that allows user to select one or more values from a list. A select with multiple options seemed to me the most reasonable choice. So I tweaked a little the SelectEntryFactory.js a little. That’s the result:
"use strict";
import _ from "lodash";
import {
domify
} from "min-dom";
import entryFieldDescription from "./EntryFieldDescription";
var isList = function (list) {
return !(!list || Object.prototype.toString.call(list) !== "[object Array]");
};
var addEmptyParameter = function (list) {
return list.concat([{
name: "",
value: ""
}]);
};
var createOption = function (option) {
return '<option value="' + option.value + '">' + option.name + "</option>";
};
/**
* @param {Object} options
* @param {string} options.id
* @param {string} [options.label]
* @param {Array<Object>} options.selectOptions
* @param {string} options.modelProperty
* @param {boolean} options.emptyParameter
* @param {boolean} options.multiple
* @param {function} options.disabled
* @param {function} options.hidden
* @param {Object} defaultParameters
*
* @return {Object}
*/
var selectbox = function (options, defaultParameters) {
var resource = defaultParameters,
label = options.label || resource.id,
selectOptions = options.selectOptions || [{
name: "",
value: ""
}],
modelProperty = options.modelProperty,
emptyParameter = options.emptyParameter,
canBeDisabled = !!options.disabled && typeof options.disabled === "function",
canBeHidden = !!options.hidden && typeof options.hidden === "function",
isMultiple = options.multiple || false,
description = options.description;
if (emptyParameter) {
selectOptions = addEmptyParameter(selectOptions);
}
resource.html =
'<label for="camunda-' +
resource.id +
'">' +
label +
"</label>" +
'<select ' +
(isMultiple ? 'multiple ' : '') +
'id="camunda-' +
resource.id +
'-select" name="' +
modelProperty +
'"' +
(canBeDisabled ? 'data-disable="isDisabled" ' : "") +
(canBeHidden ? 'data-show="isHidden" ' : "") +
" data-value >";
if (isList(selectOptions)) {
_.forEach(selectOptions, function (option) {
resource.html +=
'<option value="' + option.value + '">' + (option.name || "") + "</option>";
});
}
resource.html += "</select>";
// add description below select box entry field
if (description && typeof options.showCustomInput !== "function") {
resource.html += entryFieldDescription(description);
}
/**
* Fill the select box options dynamically.
*
* Calls the defined function #selectOptions in the entry to get the
* values for the options and set the value to the inputNode.
*
* @param {djs.model.Base} element
* @param {HTMLElement} entryNode
* @param {EntryDescriptor} inputNode
* @param {Object} inputName
* @param {Object} newValue
*/
resource.setControlValue = function (element, entryNode, inputNode, inputName, newValue) {
if (typeof selectOptions === "function") {
var options = selectOptions(element, inputNode);
if (options) {
// remove existing options
while (inputNode.firstChild) {
inputNode.removeChild(inputNode.firstChild);
}
// add options
_.forEach(options, function (option) {
var template = domify(createOption(option));
inputNode.appendChild(template);
});
}
}
// set select value
if (newValue !== undefined) {
if (isMultiple) {
_.forEach(newValue, function (value) {
const option = _.find(inputNode, node => node.value === value);
if (option) {
option.selected = true;
}
});
} else {
inputNode.value = newValue;
}
}
};
if (canBeDisabled) {
resource.isDisabled = function () {
return options.disabled.apply(resource, arguments);
};
}
if (canBeHidden) {
resource.isHidden = function () {
return !options.hidden.apply(resource, arguments);
};
}
resource.cssClasses = ["bpp-dropdown"];
return resource;
};
export default selectbox;
I just add a new property in options, called multiple. Then, in setControlValue
, set the property selected
to true
to every option selected via click. Then, I created my SomeTaskProps.js
Then I use this in a custom property panel I’ve created. I created get
and set
custom functions. Seems to work perfectly, adding the extension in the proper place, but I still have a little problem. In case I’ve selected several options, and those get highlighted in my screen, if I click the first selected option (the first one appearing from the top), the set
function do not trigger. Mind that this happens only with the first option. The other trigger the function as fine.
So, I’ve many question. Is this the right approach? And so, what am I doing wrong? Creating a mess changing the selectBox or there’s something in my javascript/html code that goes wrong?
Plus: in a case like this, is there a different property field I might use?
I thank anybody could spend a minute to read this and those willing to help me a little to undestand more of this world.