/** * Make a text editable. * * The `.uiTextedit()` method make an element editable on click the element. * * ### Examples * Make all divs with class edit editable and strip HTML tags on edit. * * JavaScript: * * ep('div.edit') * .uiTextedit({ * stripHTML: true * }); * * * @class jQuery.ui.uiTextedit * @extends jQuery.widget * * @uses ep * @uses ep.ajax * @uses ep.ui.input * @uses jQuery.ui.core * @since 6.11.0 */ /** * @event onBeforeOpen This event is triggered before the editable element is displayed. * @member jQuery.ui.uiTextedit * @since 6.12.0 */ /** * @event onAfterOpen This event is triggered when the editable element is displayed. * @member jQuery.ui.uiTextedit * @since 6.12.0 */ /** * @event onAfterClose This event is triggered when the data was written back and the editable element is closed. * @member jQuery.ui.uiTextedit * @since 6.12.0 */ /** * @event formatOnWriteBack This event is triggered before datas write back an before the editable element will be hidden. * @member jQuery.ui.uiTextedit * @since 6.12.0 */ /** * Show the text input. * * @method open * @member jQuery.ui.uiTextedit * * @since 6.15.1 */ /** * @cfg {String} type A input type such as 'input' or 'textarea'. */ /** * @cfg {String} action A url as for save action. */ /** * @cfg {String} action An ObjectID for save action. */ /** * @cfg {String} name A name for the value to save. */ /** * @cfg {Boolean} convertLineBreaks A boolean indication whether to convert line breaks to <br /> tags. */ /** * @cfg {Boolean} stripHTML A boolean indication whether to remove HTML tags from the text. */ /** * @cfg {undefined} validate An object contenting validation options (available options see ep.uiValidate) */ /** * @cfg {undefined} additional An object contenting additional parameters (key/value pairs) for the ajax-request */ /** * @cfg {undefined} rows Number of displayed rows of a textarea. */ /** * @cfg {undefined} width Width of the input or textarea. */ /** * See `jQuery.ui.uiTextedit` for details. * * @param {Object} [options] A map of additional options pass to the method. * @param {String} type A input type such as 'input' or 'textarea'. * @param {String} action A url as for save action. * @param {String} action An ObjectID for save action. * @param {String} name A name for the value to save. * @param {Boolean} convertLineBreaks A boolean indication whether to convert line breaks to <br /> tags. * @param {Boolean} stripHTML A boolean indication whether to remove HTML tags from the text. * @param {undefined} validate An object contenting validation options (available options see ep.uiValidate) * @param {undefined} additional An object contenting additional parameters (key/value pairs) for the ajax-request * @param {undefined} rows Number of displayed rows of a textarea. * @param {undefined} width Width of the input or textarea. * * @fires onBeforeOpen * @fires onAfterOpen * @fires onAfterClose * @fires formatOnWriteBack * * @method uiTextedit * @member jQuery * * @since 6.11.0 */ /* * @copyright © Copyright 2006-2010, epages GmbH, All Rights Reserved. * * @module ep.ui.textedit * * @revision $Revision: 1.12 $ */ define("ep/ui/textedit", [ "jquery", "ep", "util/string", "jquery/ui/core", "ep/ajax", "ep/ui/input" ], function ($, ep, str) { $.widget( "ui.uiTextedit",/* my.parent.widget,*/ { MIN_WIDTH: 50, options: { // validate: undefined, additional: undefined, // additional save parameters (e.g. CurrencyID) type: 'input', // textarea or input rows: undefined, // number of rows which should be displayed in a textarea width: undefined, // width of the input or textarea action: null, // save action objectId: ep.config.objectId !== 0 ? ep.config.objectId : null, // object id for save name: null, // name for save convertLineBreaks: false, // new line to br stripHTML: false, // remove html tags xhrType: 'POST', // request type onAfterClose: null, onBeforeOpen: null, onAfterOpen: null, formatOnWriteBack: null, preventDefaultOnEnter : false // Call *preventDefault()* on event *keypress* with key 'ENTER'; }, _create: function(){ var o = this.options; this.elem = this.element; this.elem .on('click.uiTextedit', $.proxy(this, '_open')); /*.on( 'mouseover.uiTextedit', $.proxy(this, '_onmouseover') ) .on( 'mouseout.uiTextedit', $.proxy(this, '_onmouseout') );*/ }, _build: function(){ var self = this, o = self.options; this.elem .on( 'mouseover.uiTextedit', $.proxy(this, '_onmouseover') ) .on( 'mouseout.uiTextedit', $.proxy(this, '_onmouseout') ); this.uiInput = ep( o.type === 'textarea' ? '<textarea>' : '<input type="text">' ) .hide() .insertAfter( this.elem ); if( o.type === 'textarea' && o.rows ){ this.uiInput.attr('rows', o.rows); } if(o.validate){ this.uiInput.uiValidate(o.validate); }else{ this.uiInput.uiInput(); } this.uiInput //.uiInput() .uiInput('addClass', 'ep-uiTextedit-wrap') .on( 'blur.uiTextedit', $.proxy(this, '_close') ) .on( 'keypress.uiTextedit', $.proxy(this, '_onkeypress') ) .on( 'keyup.uiTextedit', $.proxy(this, '_onkeyup') ); //if we have a action we also need a name to save content to the server if( o.action ){ if( o.name || name ){ this._name = o.name || name; } else{ this._name = this.elem.attr('name'); if( !this._name ){ console.warn('ep.ui.textedit: unable to save: action is defined but no name is defined'); } } } }, _open:function( event ){ // build textedit construct if necessary if(this.uiInput === undefined){ this._build(); } if((this.options.onBeforeOpen!=null) && (typeof this.options.onBeforeOpen=="function")){ this.options.onBeforeOpen(this.uiInput); } this.content = this.elem.html(); var content = this.content; this.uiInput.width( this.options.width || Math.max( this.elem.width(), this.MIN_WIDTH ) ); this.elem.hide(); this.uiInput .show() .css( 'display', (this.elem.data("olddisplay") !== undefined) ? this.elem.data("olddisplay") : 'inline-block' ); if( this.options.convertLineBreaks ){ content = content.replace(/(<br>|<br \/>)/g, '\n'); } this.uiInput .attr({ //'disabled': false, 'value': content }) .focus() .select(); if((this.options.onAfterOpen!=null) && (typeof this.options.onAfterOpen=="function")){ this.options.onAfterOpen(this.uiInput); } }, _close:function(evt){ var o = this.options; if(!this.uiInput.is(':disabled[disabled]') && !this.uiInput.is(':hidden')) { // Otherwise *_close()* has already been called by *_onkeypress()* ('Enter') or // *_writeContentBack()* was called by *_onkeyup* ('ESC'). if(this.uiInput.is(':input:invalid')){ evt.preventDefault(); //this.uiInput.focus(); return; } this._writeContentBack(evt); if (o.action && o.objectId && this._name) { this._saveContent(); } //this.uiInput.attr('disabled', true); if((this.options.onAfterClose != null) && (typeof this.options.onAfterClose == "function")){ this.options.onAfterClose(this.uiInput); } } }, _onkeypress: function( event ){ /*if( event.keyCode === 27 ){ this.uiInput.val(this.content); this._writeContentBack(event); }*/ var o = this.options; if( o.type === 'input' && event.keyCode === 13 ){ if (o.preventDefaultOnEnter) { event.preventDefault(); } this._close(event); } }, _onkeyup: function( event ){ if( event.keyCode === 27 ){ this.uiInput.val(this.content); this._writeContentBack(event); } }, _onmouseover: function(){ this.elem.addClass('ep-uiTextedit-Hover'); }, _onmouseout: function(){ this.elem.removeClass('ep-uiTextedit-Hover'); }, _writeContentBack: function(event){ var o = this.options; this.elem.show(); this.uiInput.hide(); // FIRST if((o.formatOnWriteBack!=null) &&(typeof o.formatOnWriteBack=="function")){ o.formatOnWriteBack(this.uiInput, event); } this.content = this.uiInput.val(); if( o.stripHTML){ this.content = str.stripTags(this.content); } if( o.convertLineBreaks){ this.content = this.content.replace( /(\n)/g, '<br />' ); } /*if((o.formatOnWriteBack!=null) &&(typeof o.formatOnWriteBack=="function")){ o.formatOnWriteBack(this.uiInput, event); }*/ this.elem.html(this.content); }, _saveContent: function(){ var o = this.options, jsonData = { 'ViewAction': 'JSONViewResponse', 'ObjectID': o.objectId, 'ChangeAction': o.action }; jsonData[this._name] = this.content; // add additional parameters (e.g. CurrencyID) if(o.additional!==undefined){ $.extend(jsonData, o.additional); } ep.ajax({ dataType: 'json', data: jsonData, type: o.xhrType, context: this }); }, open: function(){ if(!this.uiInput || (this.uiInput && !this.uiInput.is(':visible'))){ this._open(); } }, destroy: function(){ if(this.uiInput){ this.uiInput.remove(); } this.elem .off('.uiTextedit') .show(); this._superApply(arguments); } }); return ep; });