tablesorter/js/widgets/widget-editable.js

125 lines
4.4 KiB
JavaScript
Raw Normal View History

2014-08-02 02:31:33 +00:00
/*! tablesorter Editable Content widget - updated 8/1/2014 (core v2.17.6)
2013-04-13 01:39:07 +00:00
* Requires tablesorter v2.8+ and jQuery 1.7+
* by Rob Garrison
*/
2013-04-13 02:15:57 +00:00
/*jshint browser:true, jquery:true, unused:false */
2013-04-13 01:39:07 +00:00
/*global jQuery: false */
;(function($){
"use strict";
$.tablesorter.addWidget({
id: 'editable',
options : {
editable_columns : [],
editable_enterToAccept : true,
editable_autoAccept : true,
2013-04-13 01:39:07 +00:00
editable_autoResort : false,
editable_validate : null, // function(text, originalText){ return text; }
editable_noEdit : 'no-edit',
editable_editComplete : 'editComplete'
2013-04-13 01:39:07 +00:00
},
init: function(table, thisWidget, c, wo){
if ( !wo.editable_columns.length ) { return; }
var indx, tmp, $t,
cols = [],
editComplete = function($cell){
$cell
.removeClass('tseditable-last-edited-cell')
.trigger( wo.editable_editComplete, [c] );
// restore focus last cell after updating
setTimeout(function(){
$cell.focus();
}, 50);
};
if ( $.type(wo.editable_columns) === "string" && wo.editable_columns.indexOf('-') >= 0 ) {
// editable_columns can contain a range string (i.e. "2-4" )
tmp = wo.editable_columns.split('-');
indx = parseInt(tmp[0],10) || 0;
tmp = parseInt(tmp[1],10) || (c.columns - 1);
if ( tmp > c.columns ) { tmp = c.columns - 1; }
for ( ; indx <= tmp; indx++ ) {
cols.push('td:nth-child(' + (indx + 1) + ')');
}
} else if ( $.isArray(wo.editable_columns) ) {
$.each(wo.editable_columns, function(i, col){
if ( col < c.columns ) {
cols.push('td:nth-child(' + (col + 1) + ')');
}
});
}
// IE does not allow making TR/TH/TD cells directly editable (issue #404)
// so add a div or span inside ( it's faster than using wrapInner() )
c.$tbodies.find( cols.join(',') ).not( '.' + wo.editable_noEdit ).each(function(){
// test for children, if they exist, then make the children editable
$t = $(this);
( $t.children().length ? $t.children() : $t ).prop( 'contenteditable', true );
});
2013-04-13 01:39:07 +00:00
c.$tbodies
.on('mouseleave.tseditable', function(){
if ( c.$table.data('contentFocused') ) {
// change to "true" instead of element to allow focusout to process
c.$table.data( 'contentFocused', true );
2013-04-13 01:39:07 +00:00
$(':focus').trigger('blur');
}
})
.on('focus.tseditable', '[contenteditable]', function(e){
c.$table.data( 'contentFocused', e.target );
var $this = $(this),
v = $this.html();
2013-04-13 01:39:07 +00:00
if (wo.editable_enterToAccept) {
// prevent enter from adding into the content
$this.on('keydown.tseditable', function(e){
if ( e.which === 13 ) {
2013-04-13 01:39:07 +00:00
e.preventDefault();
}
});
}
$this.data({ before : v, original: v });
})
.on('blur focusout keydown '.split(' ').join('.tseditable '), '[contenteditable]', function(e){
if ( !c.$table.data('contentFocused') ) { return; }
var t,
valid = false,
$this = $(e.target);
if ( e.which === 27 ) {
2013-04-13 01:39:07 +00:00
// user cancelled
$this.html( $this.data('original') ).trigger('blur.tseditable');
c.$table.data( 'contentFocused', false );
2013-04-13 01:39:07 +00:00
return false;
}
t = e.which === 13 && ( wo.editable_enterToAccept || e.altKey ) || wo.editable_autoAccept && e.type !== 'keydown';
2013-04-13 01:39:07 +00:00
// change if new or user hits enter (if option set)
if ( t && $this.data('before') !== $this.html() ) {
valid = $.isFunction(wo.editable_validate) ? wo.editable_validate( $this.html(), $this.data('original') ) : $this.html();
if ( t && valid !== false ) {
c.$table.find('.tseditable-last-edited-cell').removeClass('tseditable-last-edited-cell');
$this
.addClass('tseditable-last-edited-cell')
.html( valid )
.data('before', valid)
.data('original', valid)
.trigger('change');
c.$table.trigger('updateCell', [ $this.closest('td'), false, function(table){
if (wo.editable_autoResort) {
setTimeout(function(){
c.$table.trigger("sorton", [ c.sortList, function(){
editComplete(c.$table.find('.tseditable-last-edited-cell'));
}, true ]);
}, 10);
} else {
editComplete(c.$table.find('.tseditable-last-edited-cell'));
}
} ]);
return false;
2013-04-13 01:39:07 +00:00
}
} else if ( !valid && e.type !== 'keydown' ) {
// restore original content on blur
$this.html( $this.data('original') );
}
2013-04-13 01:39:07 +00:00
});
}
});
})(jQuery);