mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 06:18:28 +01:00
1 line
24 KiB
Plaintext
1 line
24 KiB
Plaintext
{"version":3,"file":"inplace_editable.min.js","sources":["../src/inplace_editable.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * AJAX helper for the inline editing a value.\n *\n * This script is automatically included from template core/inplace_editable\n * It registers a click-listener on [data-inplaceeditablelink] link (the \"inplace edit\" icon),\n * then replaces the displayed value with an input field. On \"Enter\" it sends a request\n * to web service core_update_inplace_editable, which invokes the specified callback.\n * Any exception thrown by the web service (or callback) is displayed as an error popup.\n *\n * @module core/inplace_editable\n * @copyright 2016 Marina Glancy\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.1\n */\ndefine(\n ['jquery',\n 'core/ajax',\n 'core/templates',\n 'core/notification',\n 'core/str',\n 'core/config',\n 'core/url',\n 'core/form-autocomplete',\n 'core/pending',\n 'core/local/inplace_editable/events',\n ],\n function($, ajax, templates, notification, str, cfg, url, autocomplete, Pending, Events) {\n\n const removeSpinner = function(element) {\n element.removeClass('updating');\n element.find('img.spinner').hide();\n };\n\n /**\n * Update an inplace editable value.\n *\n * @param {Jquery} mainelement the element to update\n * @param {string} value the new value\n * @param {bool} silent if true the change won't alter the current page focus\n * @fires event:core/inplace_editable:updated\n * @fires event:core/inplace_editable:updateFailed\n */\n const updateValue = function(mainelement, value, silent) {\n var pendingId = [\n mainelement.attr('data-itemid'),\n mainelement.attr('data-component'),\n mainelement.attr('data-itemtype'),\n ].join('-');\n var pendingPromise = new Pending(pendingId);\n\n addSpinner(mainelement);\n ajax.call([{\n methodname: 'core_update_inplace_editable',\n args: {\n itemid: mainelement.attr('data-itemid'),\n component: mainelement.attr('data-component'),\n itemtype: mainelement.attr('data-itemtype'),\n value: value,\n },\n }])[0]\n .then(function(data) {\n return templates.render('core/inplace_editable', data)\n .then(function(html, js) {\n var oldvalue = mainelement.attr('data-value');\n var newelement = $(html);\n templates.replaceNode(mainelement, newelement, js);\n if (!silent) {\n newelement.find('[data-inplaceeditablelink]').focus();\n }\n\n // Trigger updated event on the DOM element.\n Events.notifyElementUpdated(newelement.get(0), data, oldvalue);\n\n return;\n });\n })\n .then(function() {\n return pendingPromise.resolve();\n })\n .fail(function(ex) {\n removeSpinner(mainelement);\n M.util.js_complete(pendingId);\n\n // Trigger update failed event on the DOM element.\n let updateFailedEvent = Events.notifyElementUpdateFailed(mainelement.get(0), ex, value);\n if (!updateFailedEvent.defaultPrevented) {\n notification.exception(ex);\n }\n });\n };\n\n const addSpinner = function(element) {\n element.addClass('updating');\n var spinner = element.find('img.spinner');\n if (spinner.length) {\n spinner.show();\n } else {\n spinner = $('<img/>')\n .attr('src', url.imageUrl('i/loading_small'))\n .addClass('spinner').addClass('smallicon')\n ;\n element.append(spinner);\n }\n };\n\n $('body').on('click keypress', '[data-inplaceeditable] [data-inplaceeditablelink]', function(e) {\n if (e.type === 'keypress' && e.keyCode !== 13) {\n return;\n }\n var editingEnabledPromise = new Pending('autocomplete-start-editing');\n e.stopImmediatePropagation();\n e.preventDefault();\n var target = $(this),\n mainelement = target.closest('[data-inplaceeditable]');\n\n var turnEditingOff = function(el) {\n el.find('input').off();\n el.find('select').off();\n el.html(el.attr('data-oldcontent'));\n el.removeAttr('data-oldcontent');\n el.removeClass('inplaceeditingon');\n el.find('[data-inplaceeditablelink]').focus();\n\n // Re-enable any parent draggable attribute.\n el.parents(`[data-inplace-in-draggable=\"true\"]`)\n .attr('draggable', true)\n .attr('data-inplace-in-draggable', false);\n };\n\n var turnEditingOffEverywhere = function() {\n // Re-enable any disabled draggable attribute.\n $(`[data-inplace-in-draggable=\"true\"]`)\n .attr('draggable', true)\n .attr('data-inplace-in-draggable', false);\n\n $('span.inplaceeditable.inplaceeditingon').each(function() {\n turnEditingOff($(this));\n });\n };\n\n var uniqueId = function(prefix, idlength) {\n var uniqid = prefix,\n i;\n for (i = 0; i < idlength; i++) {\n uniqid += String(Math.floor(Math.random() * 10));\n }\n // Make sure this ID is not already taken by an existing element.\n if ($(\"#\" + uniqid).length === 0) {\n return uniqid;\n }\n return uniqueId(prefix, idlength);\n };\n\n var turnEditingOnText = function(el) {\n str.get_string('edittitleinstructions').done(function(s) {\n var instr = $('<span class=\"editinstructions\">' + s + '</span>').\n attr('id', uniqueId('id_editinstructions_', 20)),\n inputelement = $('<input type=\"text\"/>').\n attr('id', uniqueId('id_inplacevalue_', 20)).\n attr('value', el.attr('data-value')).\n attr('aria-describedby', instr.attr('id')).\n addClass('ignoredirty').\n addClass('form-control'),\n lbl = $('<label class=\"accesshide\">' + mainelement.attr('data-editlabel') + '</label>').\n attr('for', inputelement.attr('id'));\n el.html('').append(instr).append(lbl).append(inputelement);\n\n inputelement.focus();\n inputelement.select();\n inputelement.on('keyup keypress focusout', function(e) {\n if (cfg.behatsiterunning && e.type === 'focusout') {\n // Behat triggers focusout too often.\n return;\n }\n if (e.type === 'keypress' && e.keyCode === 13) {\n // We need 'keypress' event for Enter because keyup/keydown would catch Enter that was\n // pressed in other fields.\n var val = inputelement.val();\n turnEditingOff(el);\n updateValue(el, val);\n }\n if ((e.type === 'keyup' && e.keyCode === 27) || e.type === 'focusout') {\n // We need 'keyup' event for Escape because keypress does not work with Escape.\n turnEditingOff(el);\n }\n });\n });\n };\n\n var turnEditingOnToggle = function(el, newvalue) {\n turnEditingOff(el);\n updateValue(el, newvalue);\n };\n\n var turnEditingOnSelect = function(el, options) {\n var i,\n inputelement = $('<select></select>').\n attr('id', uniqueId('id_inplacevalue_', 20)).\n addClass('custom-select'),\n lbl = $('<label class=\"accesshide\">' + mainelement.attr('data-editlabel') + '</label>')\n .attr('for', inputelement.attr('id'));\n for (i in options) {\n inputelement\n .append($('<option>')\n .attr('value', options[i].key)\n .html(options[i].value));\n }\n inputelement.val(el.attr('data-value'));\n\n el.html('')\n .append(lbl)\n .append(inputelement);\n\n inputelement.focus();\n inputelement.select();\n inputelement.on('keyup change focusout', function(e) {\n if (cfg.behatsiterunning && e.type === 'focusout') {\n // Behat triggers focusout too often.\n return;\n }\n if (e.type === 'change') {\n var val = inputelement.val();\n turnEditingOff(el);\n updateValue(el, val);\n }\n if ((e.type === 'keyup' && e.keyCode === 27) || e.type === 'focusout') {\n // We need 'keyup' event for Escape because keypress does not work with Escape.\n turnEditingOff(el);\n }\n });\n };\n\n var turnEditingOnAutocomplete = function(el, args) {\n var i,\n inputelement = $('<select></select>').\n attr('id', uniqueId('id_inplacevalue_', 20)).\n addClass('form-autocomplete-original-select').\n addClass('custom-select'),\n lbl = $('<label class=\"accesshide\">' + mainelement.attr('data-editlabel') + '</label>')\n .attr('for', inputelement.attr('id')),\n options = args.options,\n attributes = args.attributes,\n saveelement = $('<a href=\"#\"></a>'),\n cancelelement = $('<a href=\"#\"></a>');\n\n for (i in options) {\n inputelement\n .append($('<option>')\n .attr('value', options[i].key)\n .html(options[i].value));\n }\n if (attributes.multiple) {\n inputelement.attr('multiple', 'true');\n }\n inputelement.val(JSON.parse(el.attr('data-value')));\n\n str.get_string('savechanges', 'core').then(function(s) {\n return templates.renderPix('e/save', 'core', s);\n }).then(function(html) {\n saveelement.append(html);\n return;\n }).fail(notification.exception);\n\n str.get_string('cancel', 'core').then(function(s) {\n return templates.renderPix('e/cancel', 'core', s);\n }).then(function(html) {\n cancelelement.append(html);\n return;\n }).fail(notification.exception);\n\n el.html('')\n .append(lbl)\n .append(inputelement)\n .append(saveelement)\n .append(cancelelement);\n\n inputelement.focus();\n inputelement.select();\n autocomplete.enhance(inputelement,\n attributes.tags,\n attributes.ajax,\n attributes.placeholder,\n attributes.caseSensitive,\n attributes.showSuggestions,\n attributes.noSelectionString)\n .then(function() {\n // Focus on the enhanced combobox.\n el.find('[role=combobox]').focus();\n // Stop eslint nagging.\n return;\n }).fail(notification.exception);\n\n inputelement.on('keyup', function(e) {\n if ((e.type === 'keyup' && e.keyCode === 27) || e.type === 'focusout') {\n // We need 'keyup' event for Escape because keypress does not work with Escape.\n turnEditingOff(el);\n }\n });\n saveelement.on('click', function(e) {\n var val = JSON.stringify(inputelement.val());\n // We need to empty the node to destroy all event handlers etc.\n inputelement.empty();\n turnEditingOff(el);\n updateValue(el, val);\n e.preventDefault();\n });\n cancelelement.on('click', function(e) {\n // We need to empty the node to destroy all event handlers etc.\n inputelement.empty();\n turnEditingOff(el);\n e.preventDefault();\n });\n };\n\n var turnEditingOn = function(el) {\n el.addClass('inplaceeditingon');\n el.attr('data-oldcontent', el.html());\n\n var type = el.attr('data-type');\n var options = el.attr('data-options');\n\n // Input text inside draggable elements disable text selection in some browsers.\n // To prevent this we temporally disable any parent draggables.\n el.parents('[draggable=\"true\"]')\n .attr('data-inplace-in-draggable', true)\n .attr('draggable', false);\n\n if (type === 'toggle') {\n turnEditingOnToggle(el, options);\n } else if (type === 'select') {\n turnEditingOnSelect(el, $.parseJSON(options));\n } else if (type === 'autocomplete') {\n turnEditingOnAutocomplete(el, $.parseJSON(options));\n } else {\n turnEditingOnText(el);\n }\n };\n\n // Turn editing on for the current element and register handler for Enter/Esc keys.\n turnEditingOffEverywhere();\n turnEditingOn(mainelement);\n editingEnabledPromise.resolve();\n\n });\n\n\n return {\n /**\n * Return an object to interact with the current inplace editables at a frontend level.\n *\n * @param {Element} parent the parent element containing a inplace editable\n * @returns {Object|undefined} an object to interact with the inplace element, or undefined\n * if no inplace editable is found.\n */\n getInplaceEditable: function(parent) {\n const element = parent.querySelector(`[data-inplaceeditable]`);\n if (!element) {\n return undefined;\n }\n // Return an object to interact with the inplace editable.\n return {\n element,\n /**\n * Get the value from the inplace editable.\n *\n * @returns {string} the current inplace value\n */\n getValue: function() {\n return this.element.dataset.value;\n },\n /**\n * Force a value change.\n *\n * @param {string} newvalue the new value\n * @fires event:core/inplace_editable:updated\n * @fires event:core/inplace_editable:updateFailed\n */\n setValue: function(newvalue) {\n updateValue($(this.element), newvalue, true);\n },\n /**\n * Return the inplace editable itemid.\n *\n * @returns {string} the current itemid\n */\n getItemId: function() {\n return this.element.dataset.itemid;\n },\n };\n }\n };\n });\n"],"names":["define","$","ajax","templates","notification","str","cfg","url","autocomplete","Pending","Events","updateValue","mainelement","value","silent","pendingId","attr","join","pendingPromise","addSpinner","call","methodname","args","itemid","component","itemtype","then","data","render","html","js","oldvalue","newelement","replaceNode","find","focus","notifyElementUpdated","get","resolve","fail","ex","element","removeClass","hide","M","util","js_complete","notifyElementUpdateFailed","defaultPrevented","exception","addClass","spinner","length","show","imageUrl","append","on","e","type","keyCode","editingEnabledPromise","stopImmediatePropagation","preventDefault","this","closest","turnEditingOff","el","off","removeAttr","parents","uniqueId","prefix","idlength","i","uniqid","String","Math","floor","random","each","options","newvalue","turnEditingOnToggle","inputelement","lbl","key","val","select","behatsiterunning","turnEditingOnSelect","parseJSON","attributes","saveelement","cancelelement","multiple","JSON","parse","get_string","s","renderPix","enhance","tags","placeholder","caseSensitive","showSuggestions","noSelectionString","stringify","empty","turnEditingOnAutocomplete","done","instr","turnEditingOnText","turnEditingOn","getInplaceEditable","parent","querySelector","getValue","dataset","setValue","getItemId"],"mappings":"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"} |