var txaEdt = false; // Reference to textarea
var ctlAct = false; // Reference to currently edit element
var win; // Reference to window
// Some constants
EVENT_ATTR = 'data-edit-event',
IS_EDITING_ATTR = 'data-is-editing',
// non utilisées
DBL_TAP_EVENT = 'dbltap',
SUPPORTS_TOUCH = 'ontouchend' in window,
TINYMCE_INSTALLED = 'tinyMCE' in window && typeof window.tinyMCE.init == 'function',
// reference to old is function
oldjQueryIs = $.fn.is;
//-----------------------------------------------------------------------------------------------------------------
function Premiere($, window) {
//'use strict';
win = $(window); // Reference to window
/**
* Jquery plugin that makes elments editable
* @param {Object|String} [opts] Either callback function or the string 'destroy' if wanting to remove the editor event
* @return {jQuery|Boolean}
*/
$.fn.editable = function(opts) {
if(typeof opts == 'string') {
if( this.is(':editable') ) {
//console.warn('commande : '+opts);
switch (opts) {
case 'open':
if( !this.is(':editing') ) { this.trigger(this.attr(EVENT_ATTR)); }
break;
case 'close':
if( this.is(':editing') ) { txaEdt.trigger('blur'); }
break;
case 'destroy':
if( this.is(':editing') ) { txaEdt.trigger('blur'); }
this.unbind(this.attr(EVENT_ATTR));
this.removeAttr(EVENT_ATTR);
break;
default:
console.warn('Unknown command "'+opts+'" for jquery.editable');
}
} else {
console.error('Calling .editable() on an element that is not editable, call .editable() first');
}
} else {
if( this.is(':editable') ) {
console.warn('Making an already editable element editable, call .editable("destroy") first');
this.editable('destroy');
}
opts = $.extend({
event : 'click', //dblclick
touch : true,
lineBreaks : true,
closeOnEnter : true,
lgn: 0,
cln: 0
}, opts);
opts.event += '.textEditor';
this.bind(opts.event, opts, editEvent);
this.attr(EVENT_ATTR, opts.event);
}
return this;
};
/**
* Add :editable :editing to $.is()
* @param {Object} statement
* @return {*}
*/
$.fn.is = function(statement) {
if( typeof statement == 'string' && statement.indexOf(':') === 0) {
if( statement == ':editable' ) {
return this.attr(EVENT_ATTR) !== undefined;
} else if( statement == ':editing' ) {
return this.attr(IS_EDITING_ATTR) !== undefined;
}
}
return oldjQueryIs.apply(this, arguments);
};
}
//-----------------------------------------------------------------------------------------------------------------
/**
* Event listener that largens font size
*/
function keyHandler(e) {
var kyc=e.keyCode;
var cel=ctlAct[0];
var i=cel.parentNode.rowIndex,
j=cel.cellIndex,
k=(kyc==40 || kyc==13 || (kyc==9 && !e.shiftKey) ) ? 1 : -1,
rws=cel.parentNode.parentNode.rows,
nr=rws.length,
nc=rws[0].cells.length,
nxc;
switch (kyc) {
case 9:
if (nc==j+k) { i=(i+1)%nr; j=-1; }
if (-1==j+k) { i=(i-1)%nr; if (i<0) { i=i+nr; } ; j=nc; }
nxc=rws[i].cells[j+k];
$(nxc).editable('open');
return false;
case 13:
if (nc==j+1) { i=(i+1)%nr; j=-1; }
nxc=rws[i].cells[j+1];
$(nxc).editable('open');
return false;
/*if( e.data.closeOnEnter ) {
ctlAct.editable('close');
}*/
break;
case 38: case 40:
i=(i+k)%nr ; if (i<0) { i=i+nr; }
nxc=rws[i].cells[j];
$(nxc).editable('open');
return false;
break;
}
};
//-----------------------------------------------------------------------------------------------------------------
/**
* Adjusts the height of the textarea to remove scroll
* @todo This way of doing it does not make the textarea smaller when the number of text lines gets smaller
*/
function adjustTextAreaHeight() {
if( txaEdt[0].scrollHeight !== parseInt(txaEdt.attr('data-scroll'), 10) ) {
txaEdt.css('height', txaEdt[0].scrollHeight +'px');
txaEdt.attr('data-scroll', txaEdt[0].scrollHeight);
}
}
//-----------------------------------------------------------------------------------------------------------------
/**
* @param {jQuery} elt
* @param {String} newText
*/
function resetElement(elt, newText,dta) {
elt.removeAttr('data-is-editing');
elt.html( newText );
txaEdt.remove();
}
//-----------------------------------------------------------------------------------------------------------------
/**
* Event listener
*/
function editEvent (event) {
var $this = $(this);
if( ctlAct !== false ) {
// Not closing the currently open editor before opening a new
// editor makes things go crazy
ctlAct.editable('close');
elementEditor($this, event.data);
} else {
event.data.lgn=this.parentNode.rowIndex;
event.data.cln=this.cellIndex;
elementEditor($this, event.data);
}
return false;
}
//-----------------------------------------------------------------------------------------------------------------
/**
* Function creating editor
*/
function elementEditor(elt, opts) {
if( elt.is(':editing') )
return;
ctlAct = elt;
elt.attr('data-is-editing', '1');
var defaultText = $.trim( elt.html() ),
elementHeight = elt.height(),
textareaStyle = 'width: 96%; padding:0; margin:0; border:0; background:none;'+
'font-family: '+elt.css('font-family')+'; font-size: '+elt.css('font-size')+';'+
'font-weight: '+elt.css('font-weight')+';';
if( opts.lineBreaks ) {
defaultText = defaultText.replace(/
/g, '\n');
}
txaEdt = $('');
elt.text('');
if( navigator.userAgent.match(/webkit/i) !== null ) {
textareaStyle = document.defaultView.getComputedStyle(elt.get(0), "").cssText;
}
// The editor should always be static
textareaStyle += 'position: static';
/*
TEXTAREA EDITOR
*/
if( opts.closeOnEnter ) {
}
win.bind('keydown', opts, keyHandler);
win.bind('keyup', adjustTextAreaHeight);
elt.unbind(elt.attr(EVENT_ATTR),editEvent);
//-----------------------------------------
txaEdt
.val(defaultText)
.blur(function() {
ctlAct = false;
// Get new text and font size
var newText = $.trim( txaEdt.val() );
if( opts.lineBreaks ) {
newText = newText.replace(new RegExp('\n','g'), '
');
}
var bChng=newText == defaultText;
// Update element
evt=elt.attr(EVENT_ATTR);
elt.bind(evt, opts, editEvent);
resetElement(elt, newText,opts);
// remove textarea and size toggles
win.unbind('keydown', keyHandler);
win.unbind('keyup', adjustTextAreaHeight);
// Run callback
if( typeof opts.callback == 'function' ) {
opts.callback({
content : bChng ? false : newText,
elmt : elt[0]
});
}
})
.attr('style', textareaStyle)
.appendTo(elt)
.css({
margin: 0,
padding: 0,
height : elementHeight +'px',
overflow : 'hidden'
})
.focus();
// .get(0).select();
//-----------------------------------------
adjustTextAreaHeight();
elt.trigger('edit', [txaEdt]);
}
//-----------------------------------------------------------------------------------------------------------------
Premiere (jQuery, window);