{"version":3,"file":"inplace_editable.min.js","sources":["https:\/\/www.alsg.org\/home\/lib\/amd\/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 .\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 = $('')\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 = $('' + s + '<\/span>').\n attr('id', uniqueId('id_editinstructions_', 20)),\n inputelement = $('').\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 = $('