![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/lib/web/jquery/editableMultiselect/js/ |
/** * @file Jeditable - jQuery in place edit plugin * @home https://github.com/NicolasCARPi/jquery_jeditable * @author Mika Tuupola, Dylan Verheul, Nicolas CARPi * @copyright © 2006 Mika Tuupola, Dylan Verheul, Nicolas CARPi * @licence MIT (see LICENCE file) * @name Jquery-jeditable * @type jQuery * * @param {String|Function} target - URL or Function to send edited content to. Can also be 'disable', 'enable', or 'destroy' * @param {Object} [options] - Additional options * @param {Object} [options.ajaxoptions] - jQuery Ajax options. See https://api.jquery.com/jQuery.ajax/ * @param {Function} [options.before] - Function to be executed before going into edit mode * @param {Function} [options.callback] - function(result, settings, submitdata) Function to run after submitting edited content * @param {String} [options.cancel] - Cancel button value, empty means no button * @param {String} [options.cancelcssclass] - CSS class to apply to cancel button * @param {Number} [options.cols] - Number of columns if using textarea * @param {String} [options.cssclass] - CSS class to apply to input form; use 'inherit' to copy from parent * @param {String} [options.inputcssclass] - CSS class to apply to input. 'inherit' to copy from parent * @param {Function} [options.intercept] - Intercept the returned data so you have a chance to process it before returning it in the page * @param {String|Function} [options.data] - Content loaded in the form * @param {String} [options.event='click'] - jQuery event such as 'click' or 'dblclick'. See https://api.jquery.com/category/events/ * @param {String} [options.formid] - Give an id to the form that is produced * @param {String|Number} [options.height='auto'] - Height of the element in pixels or 'auto' or 'none' * @param {String} [options.id='id'] - POST parameter name of edited div id * @param {String} [options.indicator] - Indicator html to show when saving * @param {String} [options.label] - Label for the form * @param {String} [options.list] - HTML5 attribute for text input. Will suggest from a datalist with id of the list option * @param {String|Function} [options.loaddata] - Extra parameters to pass when fetching content before editing * @param {String} [options.loadtext='Loading…'] - Text to display while loading external content * @param {String} [options.loadtype='GET'] - Request type for loadurl (GET or POST) * @param {String} [options.loadurl] - URL to fetch input content before editing * @param {Number} [options.max] - Maximum value for number type * @param {String} [options.maxlength] - The maximum number of character in the text field * @param {String} [options.method] - Method to use to send edited content (POST or PUT) * @param {Number} [options.min] - Minimum value for number type * @param {Boolean} [options.multiple] - Allow multiple selections in a select input * @param {String} [options.name='value'] - POST parameter name of edited content * @param {String|Function} [options.onblur='cancel'] - Use 'cancel', 'submit', 'ignore' or function. If function returns false, the form is cancelled. * @param {Function} [options.onedit] - function triggered upon edition; will cancel edition if it returns false * @param {Function} [options.onerror] - function(settings, original, xhr) { ... } called on error * @param {Function} [options.onreset] - function(settings, original) { ... } called before reset * @param {Function} [options.onsubmit] - function(settings, original) { ... } called before submit * @param {String} [options.pattern] - HTML5 attribute for text or URL input * @param {String} [options.placeholder='Click to edit'] - Placeholder text or html to insert when element is empty * @param {Number} [options.rows] - number of rows if using textarea * @param {Boolean} [options.select] - When true text is selected * @param {Function} [options.showfn]- Function that can animate the element when switching to edit mode * @param {String} [options.size] - The size of the text field * @param {String} [options.sortselectoptions] - Sort the options of a select form * @param {Number} [options.step] - Step size for number type * @param {String} [options.style] - Style to apply to input form; 'inherit' to copy from parent * @param {String} [options.submit] - submit button value, empty means no button * @param {String} [options.submitcssclass] - CSS class to apply to submit button * @param {Object|Function} [options.submitdata] - Extra parameters to send when submitting edited content. function(revert, settings, submitdata) * @param {String} [options.tooltip] - Tooltip text that appears on hover (via title attribute) * @param {String} [options.type='text'] - text, textarea, select, email, number, url (or any 3rd party input type) * @param {String|Number} [options.width='auto'] - The width of the element in pixels or 'auto' or 'none' * * @example <caption>Simple usage example:</caption> * $(".editable").editable("save.php", { * cancel : 'Cancel', * submit : 'Save', * tooltip : "Click to edit...", * }); */ (function($) { 'use strict'; // Keyboard accessibility/WAI-ARIA - allow users to navigate to an editable element using TAB/Shift+TAB $.fn.editableAriaShim = function () { this.attr({ role: 'button', tabindex: 0 }); return this; // <-- object chaining. }; // EDITABLE function $.fn.editable = function(target, options) { if ('disable' === target) { $(this).data('disabled.editable', true); return; } if ('enable' === target) { $(this).data('disabled.editable', false); return; } if ('destroy' === target) { $(this) .off($(this).data('event.editable')) .removeData('disabled.editable') .removeData('event.editable'); return; } var settings = $.extend({}, $.fn.editable.defaults, {target:target}, options); /* setup some functions */ var plugin = $.editable.types[settings.type].plugin || function() { }; var submit = $.editable.types[settings.type].submit || function() { }; var buttons = $.editable.types[settings.type].buttons || $.editable.types.defaults.buttons; var content = $.editable.types[settings.type].content || $.editable.types.defaults.content; var element = $.editable.types[settings.type].element || $.editable.types.defaults.element; var reset = $.editable.types[settings.type].reset || $.editable.types.defaults.reset; var destroy = $.editable.types[settings.type].destroy || $.editable.types.defaults.destroy; var callback = settings.callback || function() { }; var intercept = settings.intercept || function(s) { return s; }; var onedit = settings.onedit || function() { }; var onsubmit = settings.onsubmit || function() { }; var onreset = settings.onreset || function() { }; var onerror = settings.onerror || reset; var before = settings.before || false; // TOOLTIP if (settings.tooltip) { $(this).attr('title', settings.tooltip); } return this.each(function() { /* Save this to self because this changes when scope changes. */ var self = this; /* Save so it can be later used by $.editable('destroy') */ $(this).data('event.editable', settings.event); /* If element is empty add something clickable (if requested) */ if (!$(this).html().trim()) { $(this).html(settings.placeholder); } if ('destroy' === target) { destroy.apply($(this).find('form'), [settings, self]); return; } // EVENT IS FIRED $(this).on(settings.event, function(e) { /* Abort if element is disabled. */ if (true === $(this).data('disabled.editable')) { return; } // do nothing if user press Tab again, just go to next element, not into edit mode if (e.which === 9) { return; } /* Prevent throwing an exception if edit field is clicked again. */ if (self.editing) { return; } /* Abort if onedit hook returns false. */ if (false === onedit.apply(this, [settings, self, e])) { return; } /* execute the before function if any was specified */ if (settings.before && (typeof settings.before === 'function')) { settings.before(e); } else if (settings.before && !(typeof settings.before === 'function')) { throw "The 'before' option needs to be provided as a function!"; } /* Prevent default action and bubbling. */ e.preventDefault(); e.stopPropagation(); /* Remove tooltip. */ if (settings.tooltip) { $(self).removeAttr('title'); } /* Remove placeholder text, replace is here because of IE. */ if ($(this).html().toLowerCase().replace(/(;|"|\/)/g, '') === settings.placeholder.toLowerCase().replace(/(;|"|\/)/g, '')) { $(this).html(''); } self.editing = true; self.revert = $(self).text(); $(self).html(''); /* Create the form object. */ var form = $('<form />'); /* Apply css or style or both. */ if (settings.cssclass) { if ('inherit' === settings.cssclass) { form.attr('class', $(self).attr('class')); } else { form.attr('class', settings.cssclass); } } if (settings.style) { if ('inherit' === settings.style) { form.attr('style', $(self).attr('style')); /* IE needs the second line or display won't be inherited. */ form.css('display', $(self).css('display')); } else { form.attr('style', settings.style); } } // add a label if it exists if (settings.label) { form.append('<label>' + settings.label + '</label>'); } // add an ID to the form if (settings.formid) { form.attr('id', settings.formid); } /* Add main input element to form and store it in input. */ var input = element.apply(form, [settings, self]); if (settings.inputcssclass) { if ('inherit' === settings.inputcssclass) { input.attr('class', $(self).attr('class')); } else { input.attr('class', settings.inputcssclass); } } /* Set input content via POST, GET, given data or existing value. */ var input_content; // timeout function var t; var isSubmitting = false; if (settings.loadurl) { t = self.setTimeout(function() { input.disabled = true; }, 100); $(self).html(settings.loadtext); var loaddata = {}; loaddata[settings.id] = self.id; if (typeof settings.loaddata === 'function') { $.extend(loaddata, settings.loaddata.apply(self, [self.revert, settings])); } else { $.extend(loaddata, settings.loaddata); } $.ajax({ type : settings.loadtype, url : settings.loadurl, data : loaddata, async: false, cache : false, success: function(result) { self.clearTimeout(t); input_content = result; input.disabled = false; } }); } else if (settings.data) { input_content = settings.data; if (typeof settings.data === 'function') { input_content = settings.data.apply(self, [self.revert, settings]); } } else { input_content = self.revert; } content.apply(form, [input_content, settings, self]); input.attr('name', settings.name); /* adjust the width of the element to account for the margin/padding/border */ if (settings.width !== 'none') { var adj_width = settings.width - (input.outerWidth(true) - settings.width); input.width(adj_width); } /* Add buttons to the form. */ buttons.apply(form, [settings, self]); /* Add created form to self. */ if (settings.showfn && (typeof settings.showfn === 'function')) { form.hide(); } // clear the loadtext that we put here before $(self).html(''); $(self).append(form); // execute the showfn if (settings.showfn && (typeof settings.showfn === 'function')) { settings.showfn(form); } /* Attach 3rd party plugin if requested. */ plugin.apply(form, [settings, self]); /* Focus to first visible form element. */ form.find(':input:visible:enabled:first').trigger('focus'); /* Highlight input contents when requested. */ if (settings.select) { input.trigger('select'); } /* discard changes if pressing esc */ $(this).on('keydown', function(e) { if (e.which === 27) { e.preventDefault(); reset.apply(form, [settings, self]); /* allow shift+enter to submit form (required for textarea) */ } else if (e.which == 13 && e.shiftKey){ e.preventDefault(); form.trigger('submit'); } }); /* Discard, submit or nothing with changes when clicking outside. */ /* Do nothing is usable when navigating with tab. */ if ('cancel' === settings.onblur) { input.on('blur', function(e) { /* Prevent canceling if submit was clicked. */ t = self.setTimeout(function() { reset.apply(form, [settings, self]); }, 500); }); } else if ('submit' === settings.onblur) { input.on('blur', function(e) { /* Prevent double submit if submit was clicked. */ t = self.setTimeout(function() { form.trigger('submit'); }, 200); }); } else if (typeof settings.onblur === 'function') { input.on('blur', function(e) { // reset the form if the onblur function returns false if (false === settings.onblur.apply(self, [input.val(), settings, form])) { reset.apply(form, [settings, self]); } }); } form.on('submit', function(e) { /* Do no submit. */ e.preventDefault(); e.stopPropagation(); if (isSubmitting) { // we are already submitting! Stop right here. return false; } else { isSubmitting = true; } if (t) { self.clearTimeout(t); } /* Call before submit hook. */ /* If it returns false abort submitting. */ isSubmitting = false !== onsubmit.apply(form, [settings, self]); if (isSubmitting) { /* Custom inputs call before submit hook. */ /* If it returns false abort submitting. */ isSubmitting = false !== submit.apply(form, [settings, self]); if (isSubmitting) { /* Check if given target is function */ if (typeof settings.target === 'function') { /* Callback function to handle the target response */ var responseHandler = function(value, complete) { isSubmitting = false; if (false !== complete) { $(self).html(value); self.editing = false; callback.apply(self, [self.innerText, settings]); if (!$(self).html().trim()) { $(self).html(settings.placeholder); } } }; /* Call the user target function */ var userTarget = settings.target.apply(self, [input.val(), settings, responseHandler]); /* Handle the target function return for compatibility */ if (false !== userTarget && undefined !== userTarget) { responseHandler(userTarget, userTarget); } } else { /* Add edited content and id of edited element to POST. */ var submitdata = {}; submitdata[settings.name] = input.val(); submitdata[settings.id] = self.id; /* Add extra data to be POST:ed. */ if (typeof settings.submitdata === 'function') { $.extend(submitdata, settings.submitdata.apply(self, [self.revert, settings, submitdata])); } else { $.extend(submitdata, settings.submitdata); } /* Quick and dirty PUT support. */ if ('PUT' === settings.method) { submitdata._method = 'put'; } // SHOW INDICATOR $(self).html(settings.indicator); /* Defaults for ajaxoptions. */ var ajaxoptions = { type : 'POST', complete: function (xhr, status) { isSubmitting = false; }, data : submitdata, dataType: 'html', url : settings.target, success : function(result, status) { // INTERCEPT result = intercept.apply(self, [result, status]); if (ajaxoptions.dataType === 'html') { $(self).html(result); } self.editing = false; callback.apply(self, [result, settings, submitdata]); if (!$(self).html().trim()) { $(self).html(settings.placeholder); } }, error : function(xhr, status, error) { onerror.apply(form, [settings, self, xhr]); } }; /* Override with what is given in settings.ajaxoptions. */ $.extend(ajaxoptions, settings.ajaxoptions); $.ajax(ajaxoptions); } } } /* Show tooltip again. */ $(self).attr('title', settings.tooltip); return false; }); }); // PRIVILEGED METHODS // RESET self.reset = function(form) { /* Prevent calling reset twice when blurring. */ if (self.editing) { /* Before reset hook, if it returns false abort resetting. */ if (false !== onreset.apply(form, [settings, self])) { $(self).text(self.revert); self.editing = false; if (!$(self).html().trim()) { $(self).html(settings.placeholder); } /* Show tooltip again. */ if (settings.tooltip) { $(self).attr('title', settings.tooltip); } } } }; // DESTROY self.destroy = function(form) { $(self) .off($(self).data('event.editable')) .removeData('disabled.editable') .removeData('event.editable'); self.clearTimeouts(); if (self.editing) { reset.apply(form, [settings, self]); } }; // CLEARTIMEOUT self.clearTimeout = function(t) { var timeouts = $(self).data('timeouts'); clearTimeout(t); if(timeouts) { var i = timeouts.indexOf(t); if(i > -1) { timeouts.splice(i, 1); if(timeouts.length <= 0) { $(self).removeData('timeouts'); } } else { console.warn('jeditable clearTimeout could not find timeout '+t); } } }; // CLEAR ALL TIMEOUTS self.clearTimeouts = function () { var timeouts = $(self).data('timeouts'); if(timeouts) { for(var i = 0, n = timeouts.length; i < n; ++i) { clearTimeout(timeouts[i]); } timeouts.length = 0; $(self).removeData('timeouts'); } }; // SETTIMEOUT self.setTimeout = function(callback, time) { var timeouts = $(self).data('timeouts'); var t = setTimeout(function() { callback(); self.clearTimeout(t); }, time); if(!timeouts) { timeouts = []; $(self).data('timeouts', timeouts); } timeouts.push(t); return t; }; }); }; var _supportInType = function (type) { var i = document.createElement('input'); i.setAttribute('type', type); return i.type !== 'text' ? type : 'text'; }; $.editable = { types: { defaults: { element : function(settings, original) { var input = $('<input type="hidden"></input>'); $(this).append(input); return(input); }, content : function(string, settings, original) { $(this).find(':input:first').val(string); }, reset : function(settings, original) { original.reset(this); }, destroy: function(settings, original) { original.destroy(this); }, buttons : function(settings, original) { var form = this; var submit; if (settings.submit) { /* If given html string use that. */ if (settings.submit.match(/>$/)) { submit = $(settings.submit).on('click', function() { if (submit.attr('type') !== 'submit') { form.trigger('submit'); } }); /* Otherwise use button with given string as text. */ } else { submit = $('<button type="submit" />'); submit.html(settings.submit); if (settings.submitcssclass) { submit.addClass(settings.submitcssclass); } } $(this).append(submit); } if (settings.cancel) { var cancel; /* If given html string use that. */ if (settings.cancel.match(/>$/)) { cancel = $(settings.cancel); /* otherwise use button with given string as text */ } else { cancel = $('<button type="cancel" />'); cancel.html(settings.cancel); if (settings.cancelcssclass) { cancel.addClass(settings.cancelcssclass); } } $(this).append(cancel); $(cancel).on('click', function(event) { var reset; if (typeof $.editable.types[settings.type].reset === 'function') { reset = $.editable.types[settings.type].reset; } else { reset = $.editable.types.defaults.reset; } reset.apply(form, [settings, original]); return false; }); } } }, text: { element : function(settings, original) { var input = $('<input />').attr({ autocomplete: 'off', list: settings.list, maxlength: settings.maxlength, pattern: settings.pattern, placeholder: settings.placeholder, tooltip: settings.tooltip, type: 'text' }); if (settings.width !== 'none') { input.css('width', settings.width); } if (settings.height !== 'none') { input.css('height', settings.height); } if (settings.size) { input.attr('size', settings.size); } if (settings.maxlength) { input.attr('maxlength', settings.maxlength); } $(this).append(input); return(input); } }, // TEXTAREA textarea: { element : function(settings, original) { var textarea = $('<textarea></textarea>'); if (settings.rows) { textarea.attr('rows', settings.rows); } else if (settings.height !== 'none') { textarea.height(settings.height); } if (settings.cols) { textarea.attr('cols', settings.cols); } else if (settings.width !== 'none') { textarea.width(settings.width); } if (settings.maxlength) { textarea.attr('maxlength', settings.maxlength); } $(this).append(textarea); return(textarea); } }, // SELECT select: { element : function(settings, original) { var select = $('<select />'); if (settings.multiple) { select.attr('multiple', 'multiple'); } $(this).append(select); return(select); }, content : function(data, settings, original) { var json; // If it is string assume it is json if (String === data.constructor) { json = JSON.parse(data); } else { // Otherwise assume it is a hash already json = data; } // Create tuples for sorting var tuples = []; var key; if (Array.isArray(json) && json.every(Array.isArray)) { // Process list of tuples tuples = json // JSON already contains list of [key, value] json = {}; tuples.forEach(function(e) { json[e[0]] = e[1]; // Recreate json object to comply with following code }); } else { // Process object for (key in json) { tuples.push([key, json[key]]); // Store: [key, value] } } if (settings.sortselectoptions) { // sort it tuples.sort(function (a, b) { a = a[1]; b = b[1]; return a < b ? -1 : (a > b ? 1 : 0); }); } // now add the options to our select var option; for (var i = 0; i < tuples.length; i++) { key = tuples[i][0]; var value = tuples[i][1]; if (!json.hasOwnProperty(key)) { continue; } if (key !== 'selected') { option = $('<option />').val(key).append(value); // add the selected prop if it's the same as original or if the key is 'selected' if (json.selected === key || key === String.prototype.trim.call(original.revert == null ? "" : original.revert)) { $(option).prop('selected', 'selected'); } $(this).find('select').append(option); } } // submit on change if no submit button defined if (!settings.submit) { var form = this; $(this).find('select').change(function() { form.trigger('submit'); }); } } }, // NUMBER number: { element: function (settings, original) { var input = $('<input />').attr({ maxlength: settings.maxlength, placeholder: settings.placeholder, min : settings.min, max : settings.max, step: settings.step, tooltip: settings.tooltip, type: _supportInType('number') }); if (settings.width !== 'none') { input.css('width', settings.width); } $(this).append(input); return input; } }, // EMAIL email: { element: function (settings, original) { var input = $('<input />').attr({ maxlength: settings.maxlength, placeholder: settings.placeholder, tooltip: settings.tooltip, type: _supportInType('email') }); if (settings.width !== 'none') { input.css('width', settings.width); } $(this).append(input); return input; } }, // URL url: { element: function (settings, original) { var input = $('<input />').attr({ maxlength: settings.maxlength, pattern: settings.pattern, placeholder: settings.placeholder, tooltip: settings.tooltip, type: _supportInType('url') }); if (settings.width !== 'none') { input.css('width', settings.width); } $(this).append(input); return input; } } }, // add new input type addInputType: function(name, input) { $.editable.types[name] = input; } }; /* Publicly accessible defaults. */ $.fn.editable.defaults = { name : 'value', id : 'id', type : 'text', width : 'auto', height : 'auto', // Keyboard accessibility - use mouse click OR press any key to enable editing event : 'click.editable keydown.editable', onblur : 'cancel', tooltip : 'Click to edit', loadtype : 'GET', loadtext : 'Loading...', placeholder: 'Click to edit', sortselectoptions: false, loaddata : {}, submitdata : {}, ajaxoptions: {} }; })(jQuery);