Skip to content

Commit

Permalink
feature: multiple choice checkbox in editor
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnyblasta committed Oct 23, 2024
1 parent 12cf2a9 commit 55d9278
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 11 deletions.
30 changes: 28 additions & 2 deletions src/controls/editor/editform.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const createForm = function createForm(obj) {
const disabled = obj.readonly ? ' disabled' : '';
const required = obj.required ? ' required' : '';
const name = obj.name ? obj.name : '';
const options = obj.options || [];
let el;
let firstOption;
let checked;
Expand All @@ -31,8 +32,33 @@ const createForm = function createForm(obj) {
el = `<div class="validate ${cls}"><label>${label}<br><textarea name="textarea${maxLengthText}" id="${id}" rows="3" ${maxLength}${readonly}${required}>${val}</textarea></label></div>`;
break;
case 'checkbox':
checked = (obj.config && obj.config.uncheckedValue ? obj.config.uncheckedValue !== val : val) ? ' checked' : '';
el = `<div class="o-form-checkbox ${cls}"><label for="${id}"><input type="checkbox" id="${id}" value="${val}"${checked}${disabled}/>${label}</label></div>`;
// Check if this is a multi choice checkbox
if (options.length) {
el = `<div class="o-form-checkbox"><label>${label}</label><br />`;
options.forEach((opt, index) => {
const option = opt.split(':')[0];
const subtype = opt.split(':')[1];
let textboxVal;
let disable;

// If this is choice with possibility of adding free text add a text input else only a checkbox
if (subtype === 'textbox') {
checked = val[val.length - 1] && options.indexOf(val[val.length - 1]) === -1 ? ' checked' : '';
textboxVal = checked ? val[val.length - 1] : '';
disable = checked ? '' : ' disabled';
el += `<input id="${id}-${index}" type="checkbox" name="${name}" data-index="${index}" value="${option}"${checked}> ${option}: `;
el += `<input id="${id}-${index}-text" type="text" value="${textboxVal}"${maxLength} style="width: auto; padding:0; margin:0; line-height:1.3rem;" ${disable} autocomplete="off">`;
el += '<br>';
} else {
checked = val.indexOf(option) > -1 ? ' checked' : '';
el += `<input id="${id}-${index}" type="checkbox" name="${name}" data-index="${index}" value="${option}"${checked}> ${option}<br>`;
}
});
el += '<br></div>';
} else {
checked = (obj.config && obj.config.uncheckedValue ? obj.config.uncheckedValue !== val : val) ? ' checked' : '';
el = `<div class="o-form-checkbox ${cls}"><label for="${id}"><input type="checkbox" id="${id}" value="${val}"${checked}${disabled}/>${label}</label></div>`;
}
break;
case 'dropdown':
if (val) {
Expand Down
81 changes: 72 additions & 9 deletions src/controls/editor/edithandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -888,27 +888,53 @@ function onAttributesSave(features, attrs) {
document.getElementById(`o-save-button-${currentLayer}`).addEventListener('click', (e) => {
const editEl = {};
const valid = {};
let checkboxValues = [];
attrs.forEach((attribute) => {
// Get the input container class
const containerClass = `.${attribute.elId}`;
// Get the input attributes
// FIXME: Don't have to get from DOM, the same values are in 'attribute'
// and it would be enough to call getElementId once anyway (called numerous times later on).
const inputType = document.getElementById(attribute.elId).getAttribute('type');
const inputValue = document.getElementById(attribute.elId).value;
const inputName = document.getElementById(attribute.elId).getAttribute('name');
const inputId = document.getElementById(attribute.elId).getAttribute('id');
const inputRequired = document.getElementById(attribute.elId).required;

let inputType = attribute.type ? attribute.type : '';
// Check again for not missing when checkbox is part of multiple choice checkboxes
inputType = document.getElementById(`${attribute.elId}-0`) ? document.getElementById(`${attribute.elId}-0`).getAttribute('type') : inputType;
const inputValue = document.getElementById(attribute.elId) ? document.getElementById(attribute.elId).value : '';
const inputName = attribute.name ? attribute.name : '';
const inputId = attribute.elId ? attribute.elId : '';
const inputRequired = document.getElementById(attribute.elId) ? document.getElementById(attribute.elId).required : '';

// If hidden element it should be excluded
// By sheer luck, this prevents attributes to be changed in batch edit mode when checkbox is not checked.
// If this code is changed, it may be necessary to excplict check if the batch edit checkbox is checked for this attribute.
if (!document.querySelector(containerClass) || document.querySelector(containerClass).classList.contains('o-hidden') === false) {
// Check if checkbox. If checkbox read state.
if (inputType === 'checkbox') {
const checkedValue = (attribute.config && attribute.config.checkedValue) || 1;
const uncheckedValue = (attribute.config && attribute.config.uncheckedValue) || 0;
editEl[attribute.name] = document.getElementById(attribute.elId).checked ? checkedValue : uncheckedValue;
// Check if this is a multi choice checkbox
if (document.getElementById(`${attribute.elId}-0`)) {
if (document.getElementById(`${attribute.elId}-0`).getAttribute('type') === 'checkbox') {
if (attribute.options && attribute.options.length > 0) {
Array.from(document.getElementsByName(attribute.name)).forEach((element) => {
if (element.tagName === 'INPUT' && element.getAttribute("type") === 'checkbox' && element.checked === true) {

Check failure on line 918 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote

Check failure on line 918 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote
// Check if this is a free text checkbox
if (element.nextElementSibling.getAttribute("type") === 'text') {

Check failure on line 920 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote

Check failure on line 920 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote
checkboxValues.push(element.nextElementSibling.value.trim());
} else {
checkboxValues.push(element.getAttribute("value"));

Check failure on line 923 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote

Check failure on line 923 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote
}
}
});

Check failure on line 927 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed

Check failure on line 927 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed
editEl[attribute.name] = checkboxValues.join('; ');
} else {
editEl[attribute.name] = $(attribute.elId).is(':checked') ? 1 : 0;

Check failure on line 930 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

'$' is not defined

Check failure on line 930 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

'$' is not defined
}
}
} else { // Read value from input text, textarea or select
const checkedValue = (attribute.config && attribute.config.checkedValue) || 1;
const uncheckedValue = (attribute.config && attribute.config.uncheckedValue) || 0;
editEl[attribute.name] = document.getElementById(attribute.elId).checked ? checkedValue : uncheckedValue;
}

Check failure on line 937 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed

Check failure on line 937 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed
} else if (attribute.type === 'searchList') {
// SearchList may have its value in another place than the input element itself. Query the "Component" instead.
// Note that inputValue still contains the value of the input element, which is used to validate required.
Expand Down Expand Up @@ -1060,6 +1086,7 @@ function onAttributesSave(features, attrs) {
default:
}
valid.validates = !Object.values(valid).includes(false);
checkboxValues = [];
});

// If valid, continue
Expand Down Expand Up @@ -1097,6 +1124,35 @@ function addListener() {
return fn;
}

/**
* Returns a function that adds an event handler to enable/disable the textbox for a free text checkbox
*

Check failure on line 1129 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed

Check failure on line 1129 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces not allowed
* @function
* @name addCheckboxListener
* @kind function
* @param {any} ): (obj
* @returns {void}
*/
function addCheckboxListener() {
const fn = (obj) => {
Array.from(document.getElementsByName(obj.name)).forEach((element) => {
// Add a listener on the checkbox if it has input text as next element
if (element.tagName === 'INPUT' && element.getAttribute("type") === 'checkbox' && element.nextElementSibling.getAttribute("type") === 'text') {

Check failure on line 1140 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote

Check failure on line 1140 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote

Check failure on line 1140 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote

Check failure on line 1140 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote
element.addEventListener('change', (e) => {

Check failure on line 1141 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

'e' is defined but never used

Check failure on line 1141 in src/controls/editor/edithandler.js

View workflow job for this annotation

GitHub Actions / lint

'e' is defined but never used
if (element.checked === true) {
element.nextElementSibling.disabled = false;
} else {
element.nextElementSibling.value = '';
element.nextElementSibling.disabled = true;
}
});
}
});
};

return fn;
}

/**
* Returns a function that adds an event handler to read an image file when user selects a file.
* */
Expand Down Expand Up @@ -1235,7 +1291,14 @@ function editAttributes(feat) {
} else {
alert('Villkor verkar inte vara rätt formulerat. Villkor formuleras enligt principen change:attribute:value');
}
} else if (obj.type === 'image') {
} else if (obj.type === 'checkbox') {
if (obj.options && obj.options.length > 0 && obj.val) {
obj.val = obj.val.split('; ');
}
obj.isVisible = true;
obj.elId = `input-${obj.name}`;
obj.addListener = addCheckboxListener();
} else if (obj.type === 'image') {
obj.isVisible = true;
obj.elId = `input-${currentLayer}-${obj.name}`;
obj.addListener = addImageListener();
Expand Down

0 comments on commit 55d9278

Please sign in to comment.