/* jslint vars: true */ /*jslint indent: 4 */ /* global moment, $, window */ "use strict"; var chill = (function () { /** * Display an alert message when the user wants to leave a page containing a given form * in a given state. * * The action of displaying the form be parametrised as : * - always display the alert message when leaving * - only display the alert message when the form contains some modified fields. * * @param{string} form_id An identification string of the form * @param{string} alert_message The alert message to display * @param{boolean} check_unsaved_data If true display the alert message only when the form * contains some modified fields otherwise always display the alert when leaving * @return nothing */ function _generalDisplayAlertWhenLeavingForm( form_id, alert_message, check_unsaved_data, ) { var form_submitted = false; var unsaved_data = false; $(form_id) .submit(function () { form_submitted = true; }) .on("reset", function () { unsaved_data = false; }); $.each($(form_id).find(":input"), function (i, e) { $(e).change(function () { unsaved_data = true; }); }); $(window).bind("beforeunload", function () { if (!form_submitted && (unsaved_data || !check_unsaved_data)) { return alert_message; } }); } /** * Mark the choices "not specified" as check by default. * * This function apply to `custom field choices` when the `required` * option is false and `expanded` is true (checkboxes or radio buttons). * * @param{string} choice_name the name of the input */ function checkNullValuesInChoices(choice_name) { var choices; choices = $("input[name='" + choice_name + "']:checked"); if (choices.size() === 0) { $.each($("input[name='" + choice_name + "']"), function (i, e) { if (e.value === "") { e.checked = true; } }); } } /** * Display an alert message when the user wants to leave a page containing a given * modified form. * * @param{string} form_id An identification string of the form * @param{string} alert_message The alert message to display * @return nothing */ function displayAlertWhenLeavingModifiedForm(form_id, alert_message) { _generalDisplayAlertWhenLeavingForm(form_id, alert_message, true); } /** * Display an alert message when the user wants to leave a page containing a given * form that was not submitted. * * @param{string} form_id An identification string of the form * @param{string} alert_message The alert message to display * @return nothing */ function displayAlertWhenLeavingUnsubmittedForm(form_id, alert_message) { _generalDisplayAlertWhenLeavingForm(form_id, alert_message, false); } /* Enable the following behavior : when the user change the value of an other field, its checkbox is checked. */ function checkOtherValueOnChange() { $(".input-text-other-value").each(function () { $(this).change(function () { var checkbox = $(this) .parent() .find("input[type=checkbox][value=_other]")[0]; $(checkbox).prop("checked", $(this).val() !== ""); }); }); } /** * Create an interraction between two select element (the parent and the * child) of a given form : each parent option has a category, the * child select only display options that have the same category of the * parent optionn * * The parent must have the class "chill-category-link-parent". * * The children must have the class "chill-category-link-child". Each option * of the parent must have the attribute `data-link-category`, with the value of * the connected option in parent. * * Example : * * ```html * * * * ``` * * TODO ECRIRE LA DOC METTRE LES TESTS DANS git : * tester que init est ok : - quand vide - quand choix * tester que quand sélection - quand vide - quand choix */ function categoryLinkParentChildSelect() { var forms_to_link = $("form:has(select.chill-category-link-parent)"); forms_to_link.each(function (i, form_selector) { var form = $(form_selector), parent_multiple; form.old_category = null; form.link_parent = $(form).find(".chill-category-link-parent"); form.link_child = $(form).find(".chill-category-link-child"); // check if the parent allow multiple or single results parent_multiple = $(form) .find(".chill-category-link-parent") .get(0).multiple; // if we use select2, parent_multiple will be `undefined` if (typeof parent_multiple == "undefined") { // currently, I do not know how to check if multiple using select2. // we suppose that multiple is false (old behaviour) parent_multiple = false; } $(form.link_parent).addClass("select2"); $(form.link_parant).select2({ allowClear: true }); // it is weird: when I fix the typo here, the whole stuff does not work anymore... if (parent_multiple == false) { form.old_category = null; if ($(form.link_parent).select2("data") !== null) { form.old_category = $(form.link_parent).select2( "data", ).element[0].dataset.linkCategory; } $(form.link_child) .find("option") .each(function (i, e) { if ( (!$(e).data("link-category") || $(e).data("link-category") == form.old_category) && (!$(e).data("link-categories") || form.old_category in $(e).data("link-categories").split(",")) ) { $(e).show(); // here, we should handle the optgroup } else { $(e).hide(); // here, we should handle the optgroup } }); form.link_parent.change(function () { var new_category = $(form.link_parent).select2("data").element[0] .dataset.linkCategory; if (new_category != form.old_category) { $(form.link_child) .find("option") .each(function (i, e) { if ( (!$(e).data("link-category") || $(e).data("link-category") == new_category) && (!$(e).data("link-categories") || new_category in $(e).data("link-categories").split(",")) ) { $(e).show(); // here, we should handle the optgroup } else { $(e).hide(); // here, we should handle the opgroup } }); $(form.link_child).find("option")[0].selected = true; form.old_category = new_category; } }); } else { var i = 0, selected_items = $(form.link_parent).find(":selected"); form.old_categories = []; for (i = 0; i < selected_items.length; i++) { form.old_categories.push(selected_items[i].value); } $(form.link_child) .find("option") .each(function (i, e) { var visible; if (form.old_categories.indexOf(e.dataset.linkCategory) != -1) { $(e).show(); if (e.parentNode instanceof HTMLOptGroupElement) { $(e.parentNode).show(); } } else { $(e).hide(); if (e.parentNode instanceof HTMLOptGroupElement) { // we check if the other options are visible. visible = false; for (var l = 0; l < e.parentNode.children.length; l++) { if ( window .getComputedStyle(e.parentNode.children[l]) .getPropertyValue("display") != "none" ) { visible = true; } } // if any options are visible, we hide the optgroup if (visible == false) { $(e.parentNode).hide(); } } } }); form.link_parent.change(function () { var new_categories = [], selected_items = $(form.link_parent).find(":selected"), visible; for (i = 0; i < selected_items.length; i++) { new_categories.push(selected_items[i].value); } if (new_categories != form.old_categories) { $(form.link_child) .find("option") .each(function (i, e) { if (new_categories.indexOf(e.dataset.linkCategory) != -1) { $(e).show(); // if parent is an opgroup, we show it if (e.parentNode instanceof HTMLOptGroupElement) { $(e.parentNode).show(); } } else { $(e).hide(); // we check if the parent is an optgroup if (e.parentNode instanceof HTMLOptGroupElement) { // we check if other options are visible visible = false; for (var l = 0; l < e.parentNode.children.length; l++) { if ( window .getComputedStyle(e.parentNode.children[l]) .getPropertyValue("display") != "none" ) { visible = true; } } // if any options are visible, we hide the optgroup if (visible == false) { $(e.parentNode).hide(); } } } }); //$(form.link_child).find('option')[0].selected = true; form.old_categories = new_categories; } }); } }); } function _displayHideTargetWithCheckbox(checkbox) { var target = checkbox.dataset.displayTarget, hideableElements; hideableElements = document.querySelectorAll( '[data-display-show-hide="' + target + '"]', ); if (checkbox.checked) { for (let i = 0; i < hideableElements.length; i = i + 1) { hideableElements[i].style.display = "unset"; } } else { for (let i = 0; i < hideableElements.length; i = i + 1) { hideableElements[i].style.display = "none"; } } } /** * create an interaction between a checkbox and element to show if the * checkbox is checked, or hide if the checkbox is not checked. * * The checkbox must have the data `data-display-target` with an id, * and the parts to show/hide must have the data `data-display-show-hide` * with the same value. * * Example : * * ``` * * *