Editable: remove widget & dynamic update of no-edit class. Fixes #900

This commit is contained in:
Mottie 2015-05-16 18:19:12 -05:00
parent ef8d85c4d0
commit 4468c1fb87
2 changed files with 54 additions and 20 deletions

View File

@ -1,2 +1,2 @@
/*! Widget: editable - updated 2/9/2015 (v2.19.1) */
!function(a){"use strict";var b=a.tablesorter.editable={editComplete:function(a,b,c,d){c.removeClass("tseditable-last-edited-cell").trigger(b.editable_editComplete,[a]),d&&setTimeout(function(){c.focus()},50)},selectAll:function(a){setTimeout(function(){var b,c;document.body.createTextRange?(b=document.body.createTextRange(),b.moveToElementText(a),b.select()):window.getSelection&&(c=window.getSelection(),b=document.createRange(),b.selectNodeContents(a),c.removeAllRanges(),c.addRange(b))},100)},update:function(b,c){var d,e,f,g=[],h=[];if(!c.editable_columnsArray&&"string"===a.type(c.editable_columns)&&c.editable_columns.indexOf("-")>=0)for(e=c.editable_columns.split(/\s*-\s*/),d=parseInt(e[0],10)||0,e=parseInt(e[1],10)||b.columns-1,e>b.columns&&(e=b.columns-1);e>=d;d++)g.push(d),h.push("td:nth-child("+(d+1)+")");else a.isArray(c.editable_columns)&&a.each(c.editable_columnsArray||c.editable_columns,function(a,c){c<b.columns&&(g.push(c),h.push("td:nth-child("+(c+1)+")"))});c.editable_columnsArray||(c.editable_columnsArray=g,c.editable_columnsArray.sort(function(a,b){return a-b})),e=a("<div>").wrapInner(c.editable_wrapContent).children().length||a.isFunction(c.editable_wrapContent),b.$tbodies.find(h.join(",")).not("."+c.editable_noEdit).each(function(){f=a(this),e&&0===f.children("div, span").length&&f.wrapInner(c.editable_wrapContent),f.children("div, span").length?f.children("div, span").not("."+c.editable_noEdit).each(function(){var b=a(this);c.editable_trimContent&&b.html(function(b,c){return a.trim(c)}),b.prop("contenteditable",!0)}):(c.editable_trimContent&&f.html(function(b,c){return a.trim(c)}),f.prop("contenteditable",!0))})},bindEvents:function(c,d){c.$table.off("updateComplete pagerComplete ".split(" ").join(".tseditable ").replace(/\s+/g," ")).on("updateComplete pagerComplete ".split(" ").join(".tseditable "),function(){b.update(c,c.widgetOptions)}).children("thead").add(a(c.namespace+"_extra_table").children("thead")).off("mouseenter.tseditable").on("mouseenter.tseditable",function(){c.$table.data("contentFocused")&&(c.$table.data("contentFocused",!0),a(":focus").trigger("focusout"))}),c.$tbodies.off("focus blur focusout keydown ".split(" ").join(".tseditable ").replace(/\s+/g," ")).on("focus.tseditable","[contenteditable]",function(e){clearTimeout(a(this).data("timer")),c.$table.data("contentFocused",e.target);var f=a(this),g=d.editable_selectAll,h=f.closest("td").index(),i=f.html();d.editable_trimContent&&(i=a.trim(i)),f.off("keydown.tseditable").on("keydown.tseditable",function(a){d.editable_enterToAccept&&13===a.which&&a.preventDefault()}),f.data({before:i,original:i}),"function"==typeof d.editable_focused&&d.editable_focused(i,h,f),g&&("function"==typeof g?g(i,h,f)&&b.selectAll(f[0]):b.selectAll(f[0]))}).on("blur focusout keydown ".split(" ").join(".tseditable "),"[contenteditable]",function(e){if(c.$table.data("contentFocused")){var f,g,h=!1,i=a(e.target),j=i.html(),k=i.closest("td").index();if(d.editable_trimContent&&(j=a.trim(j)),27===e.which)return i.html(i.data("original")).trigger("blur.tseditable"),c.$table.data("contentFocused",!1),!1;if(f=13===e.which&&(d.editable_enterToAccept||e.altKey)||d.editable_autoAccept&&"keydown"!==e.type,f&&i.data("before")!==j){if(g=d.editable_validate,h=j,"function"==typeof g?h=g(j,i.data("original"),k,i):"function"==typeof(g=a.tablesorter.getColumnData(c.table,g,k))&&(h=g(j,i.data("original"),k,i)),f&&h!==!1)return c.$table.find(".tseditable-last-edited-cell").removeClass("tseditable-last-edited-cell"),i.addClass("tseditable-last-edited-cell").html(h).data("before",h).data("original",h).trigger("change"),c.$table.trigger("updateCell",[i.closest("td"),!1,function(){d.editable_autoResort?setTimeout(function(){c.$table.trigger("sorton",[c.sortList,function(){b.editComplete(c,d,c.$table.find(".tseditable-last-edited-cell"),!0)},!0])},10):b.editComplete(c,d,c.$table.find(".tseditable-last-edited-cell"))}]),!1}else h||"keydown"===e.type||(clearTimeout(i.data("timer")),i.data("timer",setTimeout(function(){a.isFunction(d.editable_blur)&&(j=i.html(),d.editable_blur(d.editable_trimContent?a.trim(j):j,k,i))},100)),i.html(i.data("original")))}})}};a.tablesorter.addWidget({id:"editable",options:{editable_columns:[],editable_enterToAccept:!0,editable_autoAccept:!0,editable_autoResort:!1,editable_wrapContent:"<div>",editable_trimContent:!0,editable_validate:null,editable_focused:null,editable_blur:null,editable_selectAll:!1,editable_noEdit:"no-edit",editable_editComplete:"editComplete"},init:function(a,c,d,e){e.editable_columns.length&&(b.update(d,e),b.bindEvents(d,e))}})}(jQuery);
!function(a){"use strict";var b=a.tablesorter.editable={namespace:".tseditable",lastEdited:"tseditable-last-edited-cell",editComplete:function(a,c,d,e){d.removeClass(b.lastEdited).trigger(c.editable_editComplete,[a]),e&&setTimeout(function(){d.focus()},50)},selectAll:function(a){setTimeout(function(){var b,c;document.body.createTextRange?(b=document.body.createTextRange(),b.moveToElementText(a),b.select()):window.getSelection&&(c=window.getSelection(),b=document.createRange(),b.selectNodeContents(a),c.removeAllRanges(),c.addRange(b))},100)},getColumns:function(b,c){var d,e,f=[],g=[];if(!c.editable_columnsArray&&"string"===a.type(c.editable_columns)&&c.editable_columns.indexOf("-")>=0)for(e=c.editable_columns.split(/\s*-\s*/),d=parseInt(e[0],10)||0,e=parseInt(e[1],10)||b.columns-1,e>b.columns&&(e=b.columns-1);e>=d;d++)f.push(d),g.push("td:nth-child("+(d+1)+")");else a.isArray(c.editable_columns)&&a.each(c.editable_columnsArray||c.editable_columns,function(a,c){c<b.columns&&(f.push(c),g.push("td:nth-child("+(c+1)+")"))});return c.editable_columnsArray||(c.editable_columnsArray=f,c.editable_columnsArray.sort(function(a,b){return a-b})),g},update:function(c,d){var e,f=a("<div>").wrapInner(d.editable_wrapContent).children().length||a.isFunction(d.editable_wrapContent),g=b.getColumns(c,d).join(",");c.$tbodies.find(g).find("[contenteditable]").prop("contenteditable",!1),c.$tbodies.find(g).not("."+d.editable_noEdit).each(function(){e=a(this),f&&0===e.children("div, span").length&&e.wrapInner(d.editable_wrapContent),e.children("div, span").length?e.children("div, span").not("."+d.editable_noEdit).each(function(){var b=a(this);d.editable_trimContent&&b.html(function(b,c){return a.trim(c)}),b.prop("contenteditable",!0)}):(d.editable_trimContent&&e.html(function(b,c){return a.trim(c)}),e.prop("contenteditable",!0))})},bindEvents:function(c,d){var e=b.namespace;c.$table.off("updateComplete pagerComplete ".split(" ").join(e+" ").replace(/\s+/g," ")).on("updateComplete pagerComplete ".split(" ").join(e+" "),function(){b.update(c,c.widgetOptions)}).children("thead").add(a(c.namespace+"_extra_table").children("thead")).off("mouseenter"+e).on("mouseenter"+e,function(){c.$table.data("contentFocused")&&(c.$table.data("contentFocused",!0),a(":focus").trigger("focusout"))}),c.$tbodies.off("focus blur focusout keydown ".split(" ").join(e+" ").replace(/\s+/g," ")).on("focus"+e,"[contenteditable]",function(f){clearTimeout(a(this).data("timer")),c.$table.data("contentFocused",f.target);var g=a(this),h=d.editable_selectAll,i=g.closest("td").index(),j=g.html();d.editable_trimContent&&(j=a.trim(j)),g.off("keydown"+e).on("keydown"+e,function(a){d.editable_enterToAccept&&13===a.which&&a.preventDefault()}),g.data({before:j,original:j}),"function"==typeof d.editable_focused&&d.editable_focused(j,i,g),h&&("function"==typeof h?h(j,i,g)&&b.selectAll(g[0]):b.selectAll(g[0]))}).on("blur focusout keydown ".split(" ").join(e+" "),"[contenteditable]",function(f){if(c.$table.data("contentFocused")){var g,h,i=!1,j=a(f.target),k=j.html(),l=j.closest("td").index();if(d.editable_trimContent&&(k=a.trim(k)),27===f.which)return j.html(j.data("original")).trigger("blur"+e),c.$table.data("contentFocused",!1),!1;if(g=13===f.which&&(d.editable_enterToAccept||f.altKey)||d.editable_autoAccept&&"keydown"!==f.type,g&&j.data("before")!==k){if(h=d.editable_validate,i=k,"function"==typeof h?i=h(k,j.data("original"),l,j):"function"==typeof(h=a.tablesorter.getColumnData(c.table,h,l))&&(i=h(k,j.data("original"),l,j)),g&&i!==!1)return c.$table.find("."+b.lastEdited).removeClass(b.lastEdited),j.addClass(b.lastEdited).html(i).data("before",i).data("original",i).trigger("change"),c.$table.trigger("updateCell",[j.closest("td"),!1,function(){d.editable_autoResort?setTimeout(function(){c.$table.trigger("sorton",[c.sortList,function(){b.editComplete(c,d,c.$table.find("."+b.lastEdited),!0)},!0])},10):b.editComplete(c,d,c.$table.find("."+b.lastEdited))}]),!1}else i||"keydown"===f.type||(clearTimeout(j.data("timer")),j.data("timer",setTimeout(function(){a.isFunction(d.editable_blur)&&(k=j.html(),d.editable_blur(d.editable_trimContent?a.trim(k):k,l,j))},100)),j.html(j.data("original")))}})},destroy:function(a,c){var d=b.namespace,e=b.getColumns(a,c),f="updateComplete pagerComplete ".split(" ").join(d+" ").replace(/\s+/g," ");a.$table.off(f),f="focus blur focusout keydown ".split(" ").join(d+" ").replace(/\s+/g," "),a.$tbodies.off(f).find(e.join(",")).find("[contenteditable]").prop("contenteditable",!1)}};a.tablesorter.addWidget({id:"editable",options:{editable_columns:[],editable_enterToAccept:!0,editable_autoAccept:!0,editable_autoResort:!1,editable_wrapContent:"<div>",editable_trimContent:!0,editable_validate:null,editable_focused:null,editable_blur:null,editable_selectAll:!1,editable_noEdit:"no-edit",editable_editComplete:"editComplete"},init:function(a,c,d,e){e.editable_columns.length&&(b.update(d,e),b.bindEvents(d,e))},remove:function(a,c,d,e){e||b.destroy(c,d)}})}(jQuery);

View File

@ -8,10 +8,13 @@
'use strict';
var tse = $.tablesorter.editable = {
namespace : '.tseditable',
// last edited class name
lastEdited: 'tseditable-last-edited-cell',
editComplete: function( c, wo, $cell, refocus ) {
$cell
.removeClass( 'tseditable-last-edited-cell' )
.removeClass( tse.lastEdited )
.trigger( wo.editable_editComplete, [ c ] );
// restore focus last cell after updating
if ( refocus ) {
@ -40,8 +43,8 @@ var tse = $.tablesorter.editable = {
}, 100 );
},
update: function( c, wo ) {
var indx, tmp, $t,
getColumns : function( c, wo ) {
var indx, tmp,
colIndex = [],
cols = [];
if ( !wo.editable_columnsArray && $.type( wo.editable_columns ) === 'string' && wo.editable_columns.indexOf( '-' ) >= 0 ) {
@ -68,10 +71,21 @@ var tse = $.tablesorter.editable = {
wo.editable_columnsArray = colIndex;
wo.editable_columnsArray.sort(function(a,b){ return a - b; });
}
tmp = $( '<div>' ).wrapInner( wo.editable_wrapContent ).children().length || $.isFunction( wo.editable_wrapContent );
return cols;
},
update: function( c, wo ) {
var $t,
tmp = $( '<div>' ).wrapInner( wo.editable_wrapContent ).children().length || $.isFunction( wo.editable_wrapContent ),
cols = tse.getColumns( c, wo ).join( ',' );
// turn off contenteditable to allow dynamically setting the wo.editable_noEdit
// class on table cells - see issue #900
c.$tbodies.find( cols ).find( '[contenteditable]' ).prop( 'contenteditable', false );
// 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() {
c.$tbodies.find( cols ).not( '.' + wo.editable_noEdit ).each( function() {
// test for children, if they exist, then make the children editable
$t = $( this );
@ -101,17 +115,18 @@ var tse = $.tablesorter.editable = {
},
bindEvents: function( c, wo ) {
var namespace = tse.namespace;
c.$table
.off( ( 'updateComplete pagerComplete '.split( ' ' ).join( '.tseditable ' ) ).replace( /\s+/g, ' ' ) )
.on( 'updateComplete pagerComplete '.split( ' ' ).join( '.tseditable ' ), function() {
.off( ( 'updateComplete pagerComplete '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' ) )
.on( 'updateComplete pagerComplete '.split( ' ' ).join( namespace + ' ' ), function() {
tse.update( c, c.widgetOptions );
})
// prevent sort initialized by user click on the header from changing the row indexing before
// updateCell can finish processing the change
.children( 'thead' )
.add( $( c.namespace + '_extra_table' ).children( 'thead' ) )
.off( 'mouseenter.tseditable' )
.on( 'mouseenter.tseditable', function() {
.off( 'mouseenter' + namespace )
.on( 'mouseenter' + namespace, function() {
if ( c.$table.data( 'contentFocused' ) ) {
// change to 'true' instead of element to allow focusout to process
c.$table.data( 'contentFocused', true );
@ -120,8 +135,8 @@ var tse = $.tablesorter.editable = {
});
c.$tbodies
.off( ( 'focus blur focusout keydown '.split( ' ' ).join( '.tseditable ' ) ).replace( /\s+/g, ' ' ) )
.on( 'focus.tseditable', '[contenteditable]', function( e ) {
.off( ( 'focus blur focusout keydown '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' ) )
.on( 'focus' + namespace, '[contenteditable]', function( e ) {
clearTimeout( $( this ).data( 'timer' ) );
c.$table.data( 'contentFocused', e.target );
var $this = $( this ),
@ -133,8 +148,8 @@ var tse = $.tablesorter.editable = {
}
// prevent enter from adding into the content
$this
.off( 'keydown.tseditable' )
.on( 'keydown.tseditable', function( e ){
.off( 'keydown' + namespace )
.on( 'keydown' + namespace, function( e ){
if ( wo.editable_enterToAccept && e.which === 13 ) {
e.preventDefault();
}
@ -155,7 +170,7 @@ var tse = $.tablesorter.editable = {
}
}
})
.on( 'blur focusout keydown '.split( ' ' ).join( '.tseditable ' ), '[contenteditable]', function( e ) {
.on( 'blur focusout keydown '.split( ' ' ).join( namespace + ' ' ), '[contenteditable]', function( e ) {
if ( !c.$table.data( 'contentFocused' ) ) { return; }
var t, validate,
valid = false,
@ -167,7 +182,7 @@ var tse = $.tablesorter.editable = {
}
if ( e.which === 27 ) {
// user cancelled
$this.html( $this.data( 'original' ) ).trigger( 'blur.tseditable' );
$this.html( $this.data( 'original' ) ).trigger( 'blur' + namespace );
c.$table.data( 'contentFocused', false );
return false;
}
@ -186,9 +201,9 @@ var tse = $.tablesorter.editable = {
}
if ( t && valid !== false ) {
c.$table.find( '.tseditable-last-edited-cell' ).removeClass( 'tseditable-last-edited-cell' );
c.$table.find( '.' + tse.lastEdited ).removeClass( tse.lastEdited );
$this
.addClass( 'tseditable-last-edited-cell' )
.addClass( tse.lastEdited )
.html( valid )
.data( 'before', valid )
.data( 'original', valid )
@ -197,11 +212,11 @@ var tse = $.tablesorter.editable = {
if ( wo.editable_autoResort ) {
setTimeout( function() {
c.$table.trigger( 'sorton', [ c.sortList, function() {
tse.editComplete( c, wo, c.$table.find( '.tseditable-last-edited-cell' ), true );
tse.editComplete( c, wo, c.$table.find( '.' + tse.lastEdited ), true );
}, true ] );
}, 10 );
} else {
tse.editComplete( c, wo, c.$table.find( '.tseditable-last-edited-cell' ) );
tse.editComplete( c, wo, c.$table.find( '.' + tse.lastEdited ) );
}
} ] );
return false;
@ -218,6 +233,20 @@ var tse = $.tablesorter.editable = {
$this.html( $this.data( 'original' ) );
}
});
},
destroy : function( c, wo ) {
var namespace = tse.namespace,
cols = tse.getColumns( c, wo ),
tmp = ( 'updateComplete pagerComplete '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' );
c.$table.off( tmp );
tmp = ( 'focus blur focusout keydown '.split( ' ' ).join( namespace + ' ' ) ).replace( /\s+/g, ' ' );
c.$tbodies
.off( tmp )
.find( cols.join( ',' ) )
.find( '[contenteditable]' )
.prop( 'contenteditable', false );
}
};
@ -242,6 +271,11 @@ var tse = $.tablesorter.editable = {
if ( !wo.editable_columns.length ) { return; }
tse.update( c, wo );
tse.bindEvents( c, wo );
},
remove : function( table, c, wo, refreshing ) {
if ( !refreshing ) {
tse.destroy( c, wo ) ;
}
}
});