Pager: add ajaxError callback function. Fixes #992

This commit is contained in:
Mottie 2015-08-15 10:56:42 -05:00
parent bbd55ce144
commit be6999c67a
5 changed files with 195 additions and 78 deletions

View File

@ -25,6 +25,11 @@
// modify the url after all processing has been applied
customAjaxUrl: function(table, url) { return url; },
// ajax error callback from $.tablesorter.showError function
// ajaxError: function( config, xhr, exception ){ return exception; };
// returning false will abort the error message
ajaxError: null,
// modify the $.ajax object to allow complete control over your ajax requests
ajaxObject: {
dataType: 'json'
@ -386,20 +391,13 @@
hl = $table.find('thead th').length;
// Clean up any previous error.
ts.showError(table);
ts.showError( table );
if ( exception ) {
if (c.debug) {
console.error('Pager: >> Ajax Error', xhr, exception);
}
ts.showError(table,
xhr.status === 0 ? 'Not connected, verify Network' :
xhr.status === 404 ? 'Requested page not found [404]' :
xhr.status === 500 ? 'Internal Server Error [500]' :
exception === 'parsererror' ? 'Requested JSON parse failed' :
exception === 'timeout' ? 'Time out error' :
exception === 'abort' ? 'Ajax Request aborted' :
'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']' );
ts.showError( table, xhr, exception );
c.$tbodies.eq(0).children('tr').detach();
p.totalRows = 0;
} else {
@ -1069,31 +1067,73 @@
}() });
// see #486
ts.showError = function(table, message) {
var index, $row, c, errorRow,
ts.showError = function( table, xhr, exception ) {
var $row,
$table = $( table ),
len = $table.length;
for ( index = 0; index < len; index++ ) {
c = $table[ index ].config;
if ( c ) {
errorRow = c.pager && c.pager.cssErrorRow || c.widgetOptions.pager_css && c.widgetOptions.pager_css.errorRow || 'tablesorter-errorRow';
if ( typeof message === 'undefined' ) {
c.$table.find('thead').find(c.selectorRemove).remove();
} else {
$row = ( /tr\>/.test(message) ? $(message) : $('<tr><td colspan="' + c.columns + '">' + message + '</td></tr>') )
.click(function(){
$(this).remove();
})
// add error row to thead instead of tbody, or clicking on the header will result in a parser error
.appendTo( c.$table.find('thead:first') )
.addClass( errorRow + ' ' + c.selectorRemove.slice(1) )
.attr({
role : 'alert',
'aria-live' : 'assertive'
});
}
}
c = $table[0].config,
wo = c && c.widgetOptions,
errorRow = c.pager && c.pager.cssErrorRow || wo.pager_css && wo.pager_css.errorRow || 'tablesorter-errorRow',
typ = typeof xhr,
valid = true,
message = '',
removeRow = function(){
c.$table.find( 'thead' ).find( '.' + errorRow ).remove();
};
if ( !$table.length ) {
console.error('tablesorter showError: no table parameter passed');
return;
}
if ( typ !== 'string' ) {
// ajaxError callback for plugin or widget - see #992
if ( typeof c.pager.ajaxError === 'function' ) {
valid = c.pager.ajaxError( c, xhr, exception );
if ( valid === false ) {
return removeRow();
} else {
message = valid;
}
} else if ( typeof wo.pager_ajaxError === 'function' ) {
valid = wo.pager_ajaxError( c, xhr, exception );
if ( valid === false ) {
return removeRow();
} else {
message = valid;
}
} else {
message =
xhr.status === 0 ? 'Not connected, verify Network' :
xhr.status === 404 ? 'Requested page not found [404]' :
xhr.status === 500 ? 'Internal Server Error [500]' :
exception === 'parsererror' ? 'Requested JSON parse failed' :
exception === 'timeout' ? 'Time out error' :
exception === 'abort' ? 'Ajax Request aborted' :
'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']';
}
} else if ( typ !== 'undefined' ) {
// keep backward compatibility (external usage just passes a message string)
message = xhr;
}
if ( message === '' ) {
// remove all error rows
return removeRow();
}
// allow message to include HTML (must include entire row!)
$row = ( /tr\>/.test(message) ? $(message) : $('<tr><td colspan="' + c.columns + '">' + message + '</td></tr>') )
.click( function() {
$( this ).remove();
})
// add error row to thead instead of tbody, or clicking on the header will result in a parser error
.appendTo( c.$table.find( 'thead:first' ) )
.addClass( errorRow + ' ' + c.selectorRemove.slice(1) )
.attr({
role : 'alert',
'aria-live' : 'assertive'
});
};
// extend plugin scope

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3827,6 +3827,39 @@ $('table').trigger('search', false);</pre></div>
<td><a href="example-pager-ajax.html">Example</a></td>
</tr>
<tr id="pager-ajaxerror">
<td><a href="#" class="permalink">ajaxError</a></td>
<td>Function</td>
<td>null</td>
<td>
This callback allows you to customize the error message displayed in the <code>thead</code> (<span class="version">v2.22.6</span>).
<div class="collapsible">
<br>
When there is an ajax error, the <a href="#function-showError"><code>$.tablesorter.showError</code></a> function is called. In <span class="version">v2.22.6</span>, that function now checks this callback to allow adding a custom error message.<br>
<br>
Use it as follows:
<pre class="prettyprint lang-js">$(function(){
$("table")
.tablesorter()
.tablesorterPager({
ajaxError: function( config, xhr, exception ) {
// returning false will abort the error message
// the code below is the default behavior when this callback is set to `null`
return
xhr.status === 0 ? 'Not connected, verify Network' :
xhr.status === 404 ? 'Requested page not found [404]' :
xhr.status === 500 ? 'Internal Server Error [500]' :
exception === 'parsererror' ? 'Requested JSON parse failed' :
exception === 'timeout' ? 'Time out error' :
exception === 'abort' ? 'Ajax Request aborted' :
'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']' );
}
});
});</pre></div>
</td>
<td></td>
</tr>
<tr id="pager-processajaxoninit">
<td><a href="#" class="permalink">processAjaxOnInit</a></td>
<td>Boolean</td>
@ -6883,24 +6916,29 @@ $.tablesorter.isDigit( &quot;(2,345.67)&quot; );</pre>
<tr id="function-showError">
<td><a href="#" class="permalink">showError</a></td>
<td>This function allows adding/removing a row to the thead, to display any errors (<span class="version">v2.15</span>).
<div class="collapsible"><br>
This function is ONLY included within the <code>widget-pager.js</code> and <code>jquery.tablesorter.pager.js</code> files; in version 3+, I plan to add it as a selectable option in a build.<br>
<br>
<td>This function allows adding/removing a row to the thead, to display any errors (<span class="version">v2.15</span>; <span class="version updated">v2.22.6</span>).
<div class="collapsible">
<p>This function is ONLY included within the <code>widget-pager.js</code> and <code>jquery.tablesorter.pager.js</code> files; in version 3+, I plan to add it as a selectable option in a build.</p>
<p>In <span class="version updated">v2.22.6</span>, this function will accept <code>xhr</code> and <code>exception</code> parameters provided by ajax error messages. To maintain backward compatibility, if <code>xhr</code> is a string, it will be treated as previous <code>message</code> parameter and displayed in the error row without modification.</p>
Use it as follows:
<pre class="prettyprint lang-js">$.tablesorter.showError( table, message );</pre>
<pre class="prettyprint lang-js">$.tablesorter.showError( table, xhr, exception );</pre>
<ul>
<li><code>table</code> - table DOM element (or jQuery object) of table (or tables).</li>
<li><code>message</code> - a plain string, or string of an HTML row.</li>
<li><code>table</code> - table DOM element (or jQuery object) of the table.</li>
<li><code>xhr</code> - a plain string, string of an HTML row, or the XMLHttpRequest (XHR) object from ajax error message.</li>
<li><code>exception</code> - exception string passed from the ajax error message.</li>
</ul>
This function will add a table row to the thead, with a class name from either the pager plugin <code>cssErrorRow</code> option setting, or the pager widget <code>pager_css.errorRow</code> option (the default class name is <code>&quot;tablesorter-errorRow&quot;</code>; and styled within each theme css file).<br>
<br>
When passing this function a message, there are three possibilities:
This function will add a table row to the thead, with a class name from either the pager plugin <code>cssErrorRow</code> option setting, or the pager widget <code>pager_css.errorRow</code> option (the default class name is <code>&quot;tablesorter-errorRow&quot;</code>; and styled within each theme css file).
<p>When passing this function a message string (in the <code>xhr</code> parameter), there are three possibilities:</p>
<ol>
<li>Plain string - <code>&quot;table refuses to cooperate&quot;</code></li>
<li>Plain string (with inline HTML is okay) - <code>&quot;&lt;strong&gt;table refuses to cooperate&lt;/strong&gt;&quot;</code></li>
<li>HTML row string - <code>'&lt;tr&gt;&lt;td colspan=&quot;' + table.config.columns + '&quot;&gt;yeah, instead of showing your data... I am taking a nap&lt;/td&gt;&lt;/tr&gt;'</code> (the <a href="#variable-columns"><code>table.config.columns</code> variable</a> contains the number of table columns; use as needed)</li>
<li>undefined - completely leave out a message parameter <code>$.tablesorter.showError( table );</code> to remove all error rows from the table thead.</li>
</ol>
As of <span class="version updated">v2.22.6</span>,
<ul>
<li><span class="label label-warning">*WARNING*</span> the <code>table</code> parameter no longer accepts multiple tables.</li>
<li>If the <code>xhr</code> parameter is not a string, then the pager <a href="#pager-ajaxerror"><code>ajaxError</code></a> callback is called to allow modification of the displayed message.</li>
</ul>
</div>
</td>
</tr>

View File

@ -62,6 +62,11 @@
// modify the url after all processing has been applied
pager_customAjaxUrl: function(table, url) { return url; },
// ajax error callback from $.tablesorter.showError function
// pager_ajaxError: function( config, xhr, exception ){ return exception; };
// returning false will abort the error message
pager_ajaxError: null,
// modify the $.ajax object to allow complete control over your ajax requests
pager_ajaxObject: {
dataType: 'json'
@ -653,20 +658,13 @@
hl = $table.find('thead th').length;
// Clean up any previous error.
ts.showError(table);
ts.showError( table );
if ( exception ) {
if (c.debug) {
console.error('Pager: >> Ajax Error', xhr, exception);
}
ts.showError(table,
xhr.status === 0 ? 'Not connected, verify Network' :
xhr.status === 404 ? 'Requested page not found [404]' :
xhr.status === 500 ? 'Internal Server Error [500]' :
exception === 'parsererror' ? 'Requested JSON parse failed' :
exception === 'timeout' ? 'Time out error' :
exception === 'abort' ? 'Ajax Request aborted' :
'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']' );
ts.showError( table, xhr, exception );
c.$tbodies.eq(0).children('tr').detach();
p.totalRows = 0;
} else {
@ -1144,32 +1142,73 @@
};
// see #486
ts.showError = function( table, message ) {
var index, $row, c, wo, errorRow,
ts.showError = function( table, xhr, exception ) {
var $row,
$table = $( table ),
len = $table.length;
for ( index = 0; index < len; index++ ) {
c = $table[ index ].config;
if ( c ) {
wo = c.widgetOptions;
errorRow = c.pager && c.pager.cssErrorRow || wo.pager_css && wo.pager_css.errorRow || 'tablesorter-errorRow';
if ( typeof message === 'undefined' ) {
c.$table.find('thead').find(c.selectorRemove).remove();
} else {
$row = ( /tr\>/.test(message) ? $(message) : $('<tr><td colspan="' + c.columns + '">' + message + '</td></tr>') )
.click(function(){
$(this).remove();
})
// add error row to thead instead of tbody, or clicking on the header will result in a parser error
.appendTo( c.$table.find('thead:first') )
.addClass( errorRow + ' ' + c.selectorRemove.slice(1) )
.attr({
role : 'alert',
'aria-live' : 'assertive'
});
}
}
c = $table[0].config,
wo = c && c.widgetOptions,
errorRow = c.pager && c.pager.cssErrorRow || wo.pager_css && wo.pager_css.errorRow || 'tablesorter-errorRow',
typ = typeof xhr,
valid = true,
message = '',
removeRow = function(){
c.$table.find( 'thead' ).find( '.' + errorRow ).remove();
};
if ( !$table.length ) {
console.error('tablesorter showError: no table parameter passed');
return;
}
if ( typ !== 'string' ) {
// ajaxError callback for plugin or widget - see #992
if ( typeof c.pager.ajaxError === 'function' ) {
valid = c.pager.ajaxError( c, xhr, exception );
if ( valid === false ) {
return removeRow();
} else {
message = valid;
}
} else if ( typeof wo.pager_ajaxError === 'function' ) {
valid = wo.pager_ajaxError( c, xhr, exception );
if ( valid === false ) {
return removeRow();
} else {
message = valid;
}
} else {
message =
xhr.status === 0 ? 'Not connected, verify Network' :
xhr.status === 404 ? 'Requested page not found [404]' :
xhr.status === 500 ? 'Internal Server Error [500]' :
exception === 'parsererror' ? 'Requested JSON parse failed' :
exception === 'timeout' ? 'Time out error' :
exception === 'abort' ? 'Ajax Request aborted' :
'Uncaught error: ' + xhr.statusText + ' [' + xhr.status + ']';
}
} else if ( typ !== 'undefined' ) {
// keep backward compatibility (external usage just passes a message string)
message = xhr;
}
if ( message === '' ) {
// remove all error rows
return removeRow();
}
// allow message to include HTML (must include entire row!)
$row = ( /tr\>/.test(message) ? $(message) : $('<tr><td colspan="' + c.columns + '">' + message + '</td></tr>') )
.click( function() {
$( this ).remove();
})
// add error row to thead instead of tbody, or clicking on the header will result in a parser error
.appendTo( c.$table.find( 'thead:first' ) )
.addClass( errorRow + ' ' + c.selectorRemove.slice(1) )
.attr({
role : 'alert',
'aria-live' : 'assertive'
});
};
})(jQuery);