Skip to content

Commit

Permalink
Improved form fixed field UI for new Job Composer scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
abujeda committed Nov 2, 2023
1 parent e583601 commit 58ed90e
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 37 deletions.
124 changes: 90 additions & 34 deletions apps/dashboard/app/javascript/script_edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,38 +148,82 @@ function addInProgressField(event) {
enableNewFieldButton();
}

function fixExcludeBasedOnSelect(selectElement) {
const excludeElementId = selectElement.dataset.excludeId;
const selectOptions = Array.from(selectElement.options);
const itemsToExclude = selectOptions.filter(opt => !opt.selected).map(opt => opt.text);
const excludeElement = document.getElementById(excludeElementId);
excludeElement.value = itemsToExclude.join(',');
}

function fixedFieldEnabled(checkbox, dataElement) {
// Disable the element to avoid updates from the user
dataElement.disabled = true;
// As it is disabled, need to add a hidden field with the same name to send the fixed field value to the backend.
const input = $('<input>').attr('type','hidden').attr('name', dataElement.name).attr('value', dataElement.value);
$(checkbox).after(input);

if (dataElement.nodeName == 'SELECT') {
const selectOptions = Array.from(dataElement.options);
const selectedOption = selectOptions.filter(opt => opt.selected)[0];
const selectOptionsConfig = $(dataElement).parents('.editable-form-field').find('li.list-group-item').get();

selectOptionsConfig.forEach(configItemLi => {
const textContent = $(configItemLi).find('[data-select-value]')[0].textContent;
if (selectedOption.text == textContent) {
enableSelectOptionConfig(configItemLi, true);
} else {
disableSelectOptionConfig(configItemLi);
}
});
}
}

function toggleFixedField(event) {
event.target.disabled = true;
const elementId = event.target.dataset.fixedToggler;
const dataElement = document.getElementById(elementId);
const targetId = event.target.dataset.fixedToggler;
const dataElement = document.getElementById(targetId);
if (event.target.checked) {
fixedFieldEnabled(event.target, dataElement)
} else {
dataElement.disabled = false;
// Field enabled, remove the hidden field with the same name needed when disabled.
$(`input[type=hidden][name="${dataElement.name}"]`).remove();

if (dataElement.nodeName == 'SELECT') {
fixExcludeBasedOnSelect(dataElement);
initSelect(dataElement);
}
}

event.target.disabled = false;
}

function disableSelectOptionConfig(liElement, addButtonDisabled = true) {
liElement.classList.add('list-group-item-danger', 'text-strike');
const addButton = $(liElement).find('[data-select-toggler="add"]')[0];
addButton.disabled = addButtonDisabled;
const removeButton = $(liElement).find('[data-select-toggler="remove"]')[0];
removeButton.disabled = true;
}

function enableSelectOptionConfig(liElement, removeButtonDisabled = false) {
liElement.classList.remove('list-group-item-secondary', 'list-group-item-danger', 'text-strike');
const addButton = $(liElement).find('[data-select-toggler="add"]')[0];
addButton.disabled = true;
const removeButton = $(liElement).find('[data-select-toggler="remove"]')[0];
removeButton.disabled = removeButtonDisabled;
}

function enableOrDisableSelectOption(event) {
const toggleAction = event.target.dataset.selectToggler;
const li = event.target.parentElement;
event.target.disabled = true;

const inputId = event.target.dataset.target;
const choice = $(li).find('[data-select-value]')[0].textContent;

const select = document.getElementById(event.target.dataset.selectId);
const excludeId = select.dataset.excludeId;
const selectOptions = Array.from(select.options);
const optionToToggle = selectOptions.filter(opt => opt.text == choice)[0];
const selectOptionsEnabled = selectOptions.filter(opt => !opt.disabled);
Expand All @@ -191,16 +235,12 @@ function enableOrDisableSelectOption(event) {
}

if(toggleAction == 'add') {
li.classList.remove('list-group-item-danger', 'text-strike');
const removeButton = $(li).find('[data-select-toggler="remove"]')[0];
removeButton.disabled = false;
removeFromExcludeInput(inputId, choice);
enableSelectOptionConfig(li);
removeFromExcludeInput(excludeId, choice);
optionToToggle.disabled = false;
} else {
li.classList.add('list-group-item-danger', 'text-strike');
const addButton = $(li).find('[data-select-toggler="add"]')[0];
addButton.disabled = false;
addToExcludeInput(inputId, choice);
disableSelectOptionConfig(li);
addToExcludeInput(excludeId, choice);
optionToToggle.disabled = true;
if (optionToToggle.selected) {
optionToToggle.selected = false;
Expand All @@ -210,38 +250,54 @@ function enableOrDisableSelectOption(event) {
}
}

function getExcludeList(excludeElementId) {
const excludeInput = document.getElementById(excludeElementId);
const excludeList = excludeInput.value.split(',').filter(word => word != "");
return { excludeInput, excludeList };
}

function addToExcludeInput(id, item) {
const input = document.getElementById(id);
const list = input.value.split(',').filter(word => word != '');
list.push(item);
const { excludeInput, excludeList } = getExcludeList(id);
excludeList.push(item);

input.value = list.join(',');
excludeInput.value = excludeList.join(',');
}

function removeFromExcludeInput(id, item) {
const input = document.getElementById(id);
const currentList = input.value.split(',').filter(word => word != "");
const newList = currentList.filter(word => word != item);
const { excludeInput, excludeList } = getExcludeList(id);
const newList = excludeList.filter(word => word != item);

input.value = newList.join(',');
excludeInput.value = newList.join(',');
}

function initSelectFields(){
const allButtons = Array.from($('[data-select-toggler]'));

// find all the disabled 'remove' buttons
allButtons.filter((button) => {
return button.disabled && button.dataset.selectToggler == 'remove';

// now map that disabled button to the option it's disabled.
}).map((button) => {
const li = button.parentElement;
const optionText = $(li).find('[data-select-value]')[0].textContent;
const select = document.getElementById(button.dataset.selectId);
const selectOptions = Array.from(select.options);
const optionToToggle = selectOptions.filter(opt => opt.text == optionText)[0];
optionToToggle.disabled = true;
optionToToggle.selected = false;
const selectFields = Array.from($('select[data-exclude]'));

selectFields.forEach(select => {
initSelect(select);
});
}

function initSelect(selectElement) {
const excludeId = selectElement.dataset.excludeId;
const selectOptions = Array.from(selectElement.options);
const selectOptionsConfig = $(selectElement).parents('.editable-form-field').find('li.list-group-item').get();
const { excludeInput, excludeList } = getExcludeList(excludeId);

selectOptions.forEach(option => {
option.disabled = false;
if (excludeList.includes(option.text)) {
option.disabled = true;
option.selected = false;
}
});

selectOptionsConfig.forEach(configItem => {
enableSelectOptionConfig(configItem);
const textContent = $(configItem).find('[data-select-value]')[0].textContent;
if (excludeList.includes(textContent)) {
disableSelectOptionConfig(configItem, false);
}
});
}

Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/app/views/scripts/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<%= link_to 'Back', project_path(params[:project_id]), class: 'btn btn-default my-3', title: 'Return to projects page' %>

<%= bootstrap_form_for(@script, url: save_project_script_path) do |f| %>
<%= bootstrap_form_for(@script, url: save_project_script_path, html: { autocomplete: "off" }) do |f| %>
<% @script.smart_attributes.each do |attrib| %>
<%# TODO generate render_format %>
<%= create_editable_widget(f, attrib, format: nil) %>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
field_id = "#{form.object_name}_#{attrib.id}"
exclude_id = "#{field_id}_exclude"
exclude_name = "#{form.object_name}[#{attrib.id}_exclude]"
attrib.html_options['data-exclude-id'] = exclude_id
-%>

<div class="editable-form-field">
Expand All @@ -24,15 +25,15 @@
<li class="<%= li_classes %>">

<button class="btn btn-info float-left" type="button" id="<%= add_id %>"
data-select-toggler="add" data-target="<%= exclude_id %>" data-select-id="<%= field_id %>"
data-select-toggler="add" data-select-id="<%= field_id %>"
<%= disabled ? nil : 'disabled="true"'.html_safe %> >
<%= t('dashboard.add') %>
</button>

<span data-select-value><%= choice %></span>

<button class="btn btn-warning float-right" type="button" id="<%= remove_id %>"
data-select-toggler="remove" data-target="<%= exclude_id %>" data-select-id="<%= field_id %>"
data-select-toggler="remove" data-select-id="<%= field_id %>"
<%= disabled ? 'disabled="true"'.html_safe : nil %> >
<%= t('dashboard.remove') %>
</button>
Expand Down

0 comments on commit 58ed90e

Please sign in to comment.