mirror of
https://github.com/Mottie/tablesorter.git
synced 2024-11-15 23:54:22 +00:00
pager bug & resizable columns widget
This commit is contained in:
parent
336b5654b9
commit
628e0eeee8
@ -28,6 +28,15 @@ Included all original [document pages](http://mottie.github.com/tablesorter/docs
|
||||
|
||||
View the [complete listing here](http://mottie.github.com/tablesorter/changelog.txt).
|
||||
|
||||
#### Version 2.0.23.1 (2011-10-26)
|
||||
|
||||
* Fixed the pager plugin to prevent errors when initialized on an empty table. Fix for [issue #5](https://github.com/Mottie/tablesorter/issues/5).
|
||||
* Added a Resizable Column widget
|
||||
* At this time, this widget allows resizing the column widths from the header.
|
||||
* The column widths are not saved, but if I did consider saving the widths to local storage. I just didn't get around to doing it.
|
||||
* [Demo page](http://mottie.github.com/tablesorter/docs/example-widget-resizable.html) added.
|
||||
* Reorganized the next demo links, located at the bottom of every demo page, to match the order on the main document page.
|
||||
|
||||
#### Version 2.0.23 (2011-10-18)
|
||||
|
||||
* Changed the `dateFormat` option:
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* tablesorter pager plugin
|
||||
* updated 11/13/2011
|
||||
* updated 10/26/2011
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
@ -82,6 +82,7 @@
|
||||
l = rows.length,
|
||||
s = (c.page * c.size),
|
||||
e = (s + c.size);
|
||||
if (l < 1) { return; } // empty table, abort!
|
||||
$(table).trigger('pagerChange', c);
|
||||
if (!c.removeRows) {
|
||||
hideRows(table, c);
|
||||
|
4
addons/pager/jquery.tablesorter.pager.min.js
vendored
4
addons/pager/jquery.tablesorter.pager.min.js
vendored
@ -1,2 +1,2 @@
|
||||
/* tablesorter pager plugin - updated 11/13/2011 */
|
||||
(function(d){d.extend({tablesorterPager:new function(){var j=function(c){var a=c.cssDisabled;c.updateArrows&&(c.container[c.totalRows<c.size?"addClass":"removeClass"](a),d(c.cssFirst+","+c.cssPrev,c.container)[c.page===0?"addClass":"removeClass"](a),d(c.cssNext+","+c.cssLast,c.container)[c.page===c.totalPages-1?"addClass":"removeClass"](a))},p=function(c,a){a.startRow=a.size*a.page+1;a.endRow=Math.min(a.totalRows,a.size*(a.page+1));var b=d(a.cssPageDisplay,a.container),e=a.output.replace(/\{(page|totalPages|startRow|endRow|totalRows)\}/gi, function(b){return{"{page}":a.page+1,"{totalPages}":a.totalPages,"{startRow}":a.startRow,"{endRow}":a.endRow,"{totalRows}":a.totalRows}[b]});b[0].tagName==="INPUT"?b.val(e):b.html(e);j(a);a.container.show();d(c).trigger("pagerComplete",a)},m=function(c,a){var b=d(c);if(!a.pagerPositionSet&&a.positionFixed)b.offset&&a.container.css({top:b.offset().top+b.height()+a.offset+"px",position:"absolute"}),a.pagerPositionSet=true},k=function(c,a){var b,e=d("tr",c.tBodies[0]),g=e.length,f=a.page*a.size,i=f+ a.size;i>g&&(i=g);for(b=0;b<g;b++)e[b].style.display=b>=f&&b<i?"":"none"},n=function(c,a){a.size=parseInt(d(a.cssPageSize,a.container).val(),10);j(a);a.removeRows||(k(c,a),d(c).bind("sortEnd.pager",function(){k(c,a);d(c).trigger("applyWidgets")}))},h=function(c,a,b){var e,g,h,i=d(c.tBodies[0]),j=a.length;e=b.page*b.size;var l=e+b.size;d(c).trigger("pagerChange",b);if(b.removeRows){if(l>a.length)l=a.length;for(d.tablesorter.clearTableBody(c);e<l;e++){h=a[e];j=h.length;for(g=0;g<j;g++)i[0].appendChild(h[g])}}else k(c, b);m(c,i,b);d(c).trigger("applyWidgets");if(b.page>=b.totalPages)b.page=b.totalPages-1,f(c,b);p(c,b)},o=function(c,a){a.lastPage=a.page;a.size=a.totalRows;a.totalPages=1;h(c,a.rowsCopy,a)},f=function(c,a){if(!a.isDisabled){if(a.page<0||a.page>a.totalPages-1)a.page=0;h(c,a.rowsCopy,a)}};this.appender=function(c,a){var b=c.config;b.rowsCopy=a;b.totalRows=a.length;b.totalPages=Math.ceil(b.totalRows/b.size);h(c,a,b)};this.defaults={container:null,output:"{startRow} to {endRow} of {totalRows} rows",updateArrows:true, page:0,size:10,positionFixed:true,offset:0,removeRows:true,cssNext:".next",cssPrev:".prev",cssFirst:".first",cssLast:".last",cssPageDisplay:".pagedisplay",cssPageSize:".pagesize",cssDisabled:"disabled",totalRows:0,totalPages:0,appender:this.appender};this.construct=function(c){return this.each(function(){var a=d.extend(this.config,d.tablesorterPager.defaults,c),b=this,e=a.container;d(this).trigger("appendCache");n(b,a);d(a.cssFirst,e).unbind("click.pager").bind("click.pager",function(){a.page=0;f(b, a);return false});d(a.cssNext,e).unbind("click.pager").bind("click.pager",function(){a.page++;if(a.page>=a.totalPages-1)a.page=a.totalPages-1;f(b,a);return false});d(a.cssPrev,e).unbind("click.pager").bind("click.pager",function(){a.page--;if(a.page<=0)a.page=0;f(b,a);return false});d(a.cssLast,e).unbind("click.pager").bind("click.pager",function(){a.page=a.totalPages-1;f(b,a);return false});d(a.cssPageSize,e).unbind("change.pager").bind("change.pager",function(){var c=parseInt(d(this).val(),10); a.size=c;a.totalPages=Math.ceil(a.totalRows/a.size);a.pagerPositionSet=false;f(b,a);m(b,a);return false});d(this).unbind("disable.pager enable.pager destroy.pager").bind("disable.pager",function(){a.isDisabled=true;o(b,a)}).bind("enable.pager",function(){a.isDisabled=false;d("table").trigger("update");a.page=a.lastPage||0;a.totalPages=Math.ceil(a.totalRows/a.size);n(b,a)}).bind("destroy.pager",function(){o(b,a);a.container.hide();a.appender=null;d(b).unbind("destroy.pager sortEnd.pager enable.pager disable.pager")})})}}}); d.fn.extend({tablesorterPager:d.tablesorterPager.construct})})(jQuery);
|
||||
/* tablesorter pager plugin - updated 10/26/2011 */
|
||||
(function(d){d.extend({tablesorterPager:new function(){var m=function(c){var a=c.cssDisabled;c.updateArrows&&(c.container[c.totalRows<c.size?"addClass":"removeClass"](a),d(c.cssFirst+","+c.cssPrev,c.container)[c.page===0?"addClass":"removeClass"](a),d(c.cssNext+","+c.cssLast,c.container)[c.page===c.totalPages-1?"addClass":"removeClass"](a))},q=function(c,a){a.startRow=a.size*a.page+1;a.endRow=Math.min(a.totalRows,a.size*(a.page+1));var b=d(a.cssPageDisplay,a.container),e=a.output.replace(/\{(page|totalPages|startRow|endRow|totalRows)\}/gi, function(b){return{"{page}":a.page+1,"{totalPages}":a.totalPages,"{startRow}":a.startRow,"{endRow}":a.endRow,"{totalRows}":a.totalRows}[b]});b[0].tagName==="INPUT"?b.val(e):b.html(e);m(a);a.container.show();d(c).trigger("pagerComplete",a)},n=function(c,a){var b=d(c);if(!a.pagerPositionSet&&a.positionFixed)b.offset&&a.container.css({top:b.offset().top+b.height()+a.offset+"px",position:"absolute"}),a.pagerPositionSet=true},j=function(c,a){var b,e=d("tr",c.tBodies[0]),g=e.length,f=a.page*a.size,i=f+ a.size;i>g&&(i=g);for(b=0;b<g;b++)e[b].style.display=b>=f&&b<i?"":"none"},o=function(c,a){a.size=parseInt(d(a.cssPageSize,a.container).val(),10);m(a);a.removeRows||(j(c,a),d(c).bind("sortEnd.pager",function(){j(c,a);d(c).trigger("applyWidgets")}))},h=function(c,a,b){var e,g,h,i=d(c.tBodies[0]),k=a.length;e=b.page*b.size;var l=e+b.size;if(!(k<1)){d(c).trigger("pagerChange",b);if(b.removeRows){if(l>a.length)l=a.length;for(d.tablesorter.clearTableBody(c);e<l;e++){h=a[e];k=h.length;for(g=0;g<k;g++)i[0].appendChild(h[g])}}else j(c, b);n(c,i,b);d(c).trigger("applyWidgets");if(b.page>=b.totalPages)b.page=b.totalPages-1,f(c,b);q(c,b)}},p=function(c,a){a.lastPage=a.page;a.size=a.totalRows;a.totalPages=1;h(c,a.rowsCopy,a)},f=function(c,a){if(!a.isDisabled){if(a.page<0||a.page>a.totalPages-1)a.page=0;h(c,a.rowsCopy,a)}};this.appender=function(c,a){var b=c.config;b.rowsCopy=a;b.totalRows=a.length;b.totalPages=Math.ceil(b.totalRows/b.size);h(c,a,b)};this.defaults={container:null,output:"{startRow} to {endRow} of {totalRows} rows",updateArrows:true, page:0,size:10,positionFixed:true,offset:0,removeRows:true,cssNext:".next",cssPrev:".prev",cssFirst:".first",cssLast:".last",cssPageDisplay:".pagedisplay",cssPageSize:".pagesize",cssDisabled:"disabled",totalRows:0,totalPages:0,appender:this.appender};this.construct=function(c){return this.each(function(){var a=d.extend(this.config,d.tablesorterPager.defaults,c),b=this,e=a.container;d(this).trigger("appendCache");o(b,a);d(a.cssFirst,e).unbind("click.pager").bind("click.pager",function(){a.page=0;f(b, a);return false});d(a.cssNext,e).unbind("click.pager").bind("click.pager",function(){a.page++;if(a.page>=a.totalPages-1)a.page=a.totalPages-1;f(b,a);return false});d(a.cssPrev,e).unbind("click.pager").bind("click.pager",function(){a.page--;if(a.page<=0)a.page=0;f(b,a);return false});d(a.cssLast,e).unbind("click.pager").bind("click.pager",function(){a.page=a.totalPages-1;f(b,a);return false});d(a.cssPageSize,e).unbind("change.pager").bind("change.pager",function(){var c=parseInt(d(this).val(),10); a.size=c;a.totalPages=Math.ceil(a.totalRows/a.size);a.pagerPositionSet=false;f(b,a);n(b,a);return false});d(this).unbind("disable.pager enable.pager destroy.pager").bind("disable.pager",function(){a.isDisabled=true;p(b,a)}).bind("enable.pager",function(){a.isDisabled=false;d("table").trigger("update");a.page=a.lastPage||0;a.totalPages=Math.ceil(a.totalRows/a.size);o(b,a)}).bind("destroy.pager",function(){p(b,a);a.container.hide();a.appender=null;d(b).unbind("destroy.pager sortEnd.pager enable.pager disable.pager")})})}}}); d.fn.extend({tablesorterPager:d.tablesorterPager.construct})})(jQuery);
|
||||
|
@ -1,5 +1,15 @@
|
||||
TableSorter Change Log
|
||||
|
||||
Version 2.0.23.1 (2011-10-26)
|
||||
============================]
|
||||
|
||||
* Fixed the pager plugin to prevent errors when initialized on an empty table. Fix for [issue #5](https://github.com/Mottie/tablesorter/issues/5).
|
||||
* Added a Resizable Column widget
|
||||
* At this time, this widget allows resizing the column widths from the header.
|
||||
* The column widths are not saved, but if I did consider saving the widths to local storage. I just didn't get around to doing it.
|
||||
* [Demo page](http://mottie.github.com/tablesorter/docs/example-widget-resizable.html) added.
|
||||
* Reorganized the next demo links, located at the bottom of every demo page, to match the order on the main document page.
|
||||
|
||||
Version 2.0.23 (2011-10-18)
|
||||
============================
|
||||
|
||||
|
@ -131,7 +131,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-update-cell.html">Advanced: Update the table after cell content has changed ››</a>
|
||||
Next up: <a href="example-update-cell.html">Update the table after cell content has changed ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -125,7 +125,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-add-rows.html">Advanced: Adding a table row ››</a>
|
||||
Next up: <a href="example-add-rows.html">Adding a table row ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -119,7 +119,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-widget-zebra.html">Basic: Applying the zebra stripe widget ››</a>
|
||||
Next up: <a href="example-widget-columns.html">Columns widget ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -416,7 +416,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-option-sort-force.html">Basic: Force a default sorting order ››</a>
|
||||
Next up: <a href="example-option-sort-order.html">Set an initial sorting order direction ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -86,7 +86,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-ajax.html">Advanced: Appending table data with ajax ››</a>
|
||||
Next up: <a href="example-ajax.html">Appending table data with ajax ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -107,7 +107,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-option-debug.html">Advanced: Enabling debug mode ››</a>
|
||||
Next up: <a href="example-option-debug.html">Enabling debug mode ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -108,7 +108,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-meta-parsers.html">Metadata: Setting column parser using metadata ››</a>
|
||||
Next up: <a href="example-meta-parsers.html">Setting column parser using metadata ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -101,7 +101,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-triggers.html">Advanced: Triggers sortEnd and sortStart ››</a>
|
||||
<a href="index.html">Back to documentation</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -104,7 +104,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-meta-headers.html">Metadata: Disable header using metadata ››</a>
|
||||
Next up: <a href="example-meta-headers.html">Disable header using metadata ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -140,7 +140,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-options-headers.html">Basic: Disable header using options ››</a>
|
||||
Next up: <a href="example-parsers.html">Parser, writing your own ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -108,7 +108,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-parsers.html">Advanced: Parser, writing your own ››</a>
|
||||
Next up: <a href="example-meta-sort-list.html">Set a initial sorting order using metadata ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -108,7 +108,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-options-headers-digits-strings.html">Basic: Dealing with text strings in numerical sorts ››</a>
|
||||
Next up: <a href="example-options-headers-digits-strings.html">Dealing with text strings in numerical sorts ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -128,7 +128,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-extending-defaults.html">Advanced: Extending default options ››</a>
|
||||
Next up: <a href="example-triggers.html">Triggers sortEnd and sortStart ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -114,7 +114,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-option-digits.html">Basic: Dealing with digits! ››</a>
|
||||
Next up: <a href="example-child-rows.html">Working with Child Rows ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -112,7 +112,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-option-sort-append.html">Basic: Append a sort to the selected sorting order ››</a>
|
||||
Next up: <a href="example-option-sort-append.html">Append a sort to the selected sorting order ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -107,7 +107,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-meta-sort-list.html">Metadata: Set a initial sorting order using metadata ››</a>
|
||||
Next up: <a href="example-option-digits.html">Dealing with digits! ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -101,7 +101,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-trigger-sort.html">Basic: Sort table using a link outside the table ››</a>
|
||||
Next up: <a href="example-trigger-sort.html">Sort table using a link outside the table ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -101,7 +101,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-apply-widget.html">Basic: Applying Widgets ››</a>
|
||||
Next up: <a href="example-options-headers.html">Disable sort using headers options ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -130,7 +130,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-option-render-header.html">Advanced: Modify how the header is rendered to allow for custom styling ››</a>
|
||||
Next up: <a href="example-apply-widget.html">Applying widgets ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -204,7 +204,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-option-sort-order.html">Basic: Direction of initial sort ››</a>
|
||||
Next up: <a href="example-parsers-class-name.html">Disable or set the column parser using class names ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -115,7 +115,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-options-headers-order.html">Basic: Set initial sort order using header options ››</a>
|
||||
Next up: <a href="example-options-headers-order.html">Set initial sort order using header options ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -114,7 +114,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-option-sort-key.html">Basic: Change the default multi-sorting key ››</a>
|
||||
Next up: <a href="example-option-sort-key.html">Change the default multi-sorting key ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -110,7 +110,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-options-headers-locked.html">Basic: Lock sort order using header options ››</a>
|
||||
Next up: <a href="example-options-headers-locked.html">Lock sort order using header options ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -517,7 +517,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="index.html">Back to Documentation ››</a>
|
||||
Next up: <a href="example-empty-table.html">Initializing tablesorter on a empty table ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -101,7 +101,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-option-date-format.html">Basic: Changing the date format ››</a>
|
||||
Next up: <a href="example-option-date-format.html">Changing the date format ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -116,7 +116,7 @@ $(function() {
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-widgets.html">Advanced: Widgets, writing your own ››</a>
|
||||
Next up: <a href="example-option-text-extraction.html">Dealing with markup inside cells (textExtraction function) ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -109,7 +109,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-child-rows.html">Basic: How to add rows that sort with their parent row ››</a>
|
||||
Next up: <a href="example-option-sort-force.html">Force a default sorting order ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -1098,7 +1098,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-empty-table.html">Advanced: Initializing tablesorter on a empty table ››</a>
|
||||
Next up: <a href="example-extending-defaults.html">Extending default options ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -125,7 +125,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-option-text-extraction.html">Advanced: Dealing with markup inside cells (textExtraction function) ››</a>
|
||||
Next up: <a href="example-option-render-header.html">Modify how the header is rendered to allow for custom styling ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -160,7 +160,7 @@ table.tablesorter tbody tr.even td.tertiary {
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-widget-filter.html">Basic: Applying the filter widget ››</a>
|
||||
Next up: <a href="example-widget-filter.html">Applying the filter widget ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -166,7 +166,7 @@ table.tablesorter thead tr.filters, table.tablesorter thead tr.filters td {
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-widget-sticky-header.html">Basic: Applying the sticky header widget ››</a>
|
||||
Next up: <a href="example-widget-ui-theme.html">jQuery UI theme widget ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
135
docs/example-widget-resizable.html
Normal file
135
docs/example-widget-resizable.html
Normal file
@ -0,0 +1,135 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>jQuery plugin: Tablesorter 2.0 - Resizable Columns Widget</title>
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
|
||||
|
||||
<!-- Demo stuff -->
|
||||
<link rel="stylesheet" href="css/jq.css">
|
||||
<script src="js/chili/jquery.chili-2.2.js"></script>
|
||||
<script src="js/chili/recipes.js"></script>
|
||||
<script src="js/docs.js"></script>
|
||||
|
||||
<!-- Tablesorter: required -->
|
||||
<link rel="stylesheet" href="../css/blue/style.css">
|
||||
<script src="../js/jquery.tablesorter.js"></script>
|
||||
<script src="../js/jquery.tablesorter.widgets.js"></script>
|
||||
|
||||
<!-- Tablesorter: optional -->
|
||||
<!-- <script src="../addons/pager/jquery.tablesorter.pager.js"></script> -->
|
||||
|
||||
<script id="js">$(function() {
|
||||
|
||||
// call the tablesorter plugin
|
||||
$("table").tablesorter({
|
||||
|
||||
// initialize zebra striping and resizable widgets on the table
|
||||
widgets: [ "zebra", "resizable" ]
|
||||
|
||||
});
|
||||
|
||||
});</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="banner">
|
||||
<h1>table<em>sorter</em></h1>
|
||||
<h2>Resizable Columns Widget</h2>
|
||||
<h3>Flexible client-side table sorting</h3>
|
||||
<a href="index.html">Back to documentation</a>
|
||||
</div>
|
||||
<div id="main">
|
||||
|
||||
<p class="tip">
|
||||
<em>NOTE!</em> This widget can be applied to the original plugin.
|
||||
</p>
|
||||
|
||||
<h1>Demo</h1>
|
||||
<div id="demo"><table class="tablesorter">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>First Name</th>
|
||||
<th>Last Name</th>
|
||||
<th>Age</th>
|
||||
<th>Total</th>
|
||||
<th>Discount</th>
|
||||
<th>Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Peter</td>
|
||||
<td>Parker</td>
|
||||
<td>28</td>
|
||||
<td>$9.99</td>
|
||||
<td>20%</td>
|
||||
<td>Jul 6, 2006 8:14 AM</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>John</td>
|
||||
<td>Hood</td>
|
||||
<td>33</td>
|
||||
<td>$19.99</td>
|
||||
<td>25%</td>
|
||||
<td>Dec 10, 2002 5:14 AM</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Clark</td>
|
||||
<td>Kent</td>
|
||||
<td>18</td>
|
||||
<td>$15.89</td>
|
||||
<td>44%</td>
|
||||
<td>Jan 12, 2003 11:14 AM</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Bruce</td>
|
||||
<td>Almighty</td>
|
||||
<td>45</td>
|
||||
<td>$153.19</td>
|
||||
<td>44%</td>
|
||||
<td>Jan 18, 2001 9:12 AM</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Bruce</td>
|
||||
<td>Evans</td>
|
||||
<td>22</td>
|
||||
<td>$13.19</td>
|
||||
<td>11%</td>
|
||||
<td>Jan 18, 2007 9:12 AM</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
|
||||
<h1>Page Header</h1>
|
||||
<div>
|
||||
<pre class="html"><!-- blue theme stylesheet with additional css styles added in v2.0.17 -->
|
||||
<link rel="stylesheet" href="../css/blue/style.css">
|
||||
<!-- tablesorter plugin -->
|
||||
<script src="../js/jquery.tablesorter.js"></script>
|
||||
|
||||
<!-- tablesorter widget file - loaded after the plugin -->
|
||||
<script src="../js/jquery.tablesorter.widgets.js"></script></pre>
|
||||
</div>
|
||||
|
||||
<h1>Javascript</h1>
|
||||
<div id="javascript">
|
||||
<pre class="js"></pre>
|
||||
</div>
|
||||
|
||||
<h1>HTML</h1>
|
||||
<div id="html">
|
||||
<pre class="html"></pre>
|
||||
</div>
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-widget-sticky-header.html">Applying the sticky header widget ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -28,7 +28,7 @@
|
||||
<script id="js">$(function(){
|
||||
|
||||
$("table").tablesorter({
|
||||
widgets: [ 'uitheme', 'zebra', 'stickyHeaders' ]
|
||||
widgets: [ 'zebra', 'stickyHeaders' ]
|
||||
});
|
||||
|
||||
}); </script>
|
||||
@ -148,7 +148,7 @@
|
||||
<div class="spacer"></div>
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-widget-ui-theme.html">Basic: Applying a jQuery UI theme widget ››</a>
|
||||
Next up: <a href="example-widget-zebra.html">Zebra stripe widget ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -201,7 +201,7 @@ table.tablesorter thead tr.filters, table.tablesorter thead tr.filters td {
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-parsers-class-name.html">Basic: Disable or set the column parser using class names ››</a>
|
||||
Next up: <a href="example-widget-resizable.html">Resizable Columns widget ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -18,7 +18,7 @@
|
||||
<script src="../js/jquery.tablesorter.js"></script>
|
||||
|
||||
<!-- Tablesorter: optional -->
|
||||
<script src="../addons/pager/jquery.tablesorter.pager.js"></script>
|
||||
<!-- <script src="../addons/pager/jquery.tablesorter.pager.js"></script> -->
|
||||
|
||||
<style id="css">/* Extra selectors needed to override the default styling */
|
||||
table.tablesorter tbody tr.normal-row td {
|
||||
@ -123,7 +123,7 @@ table.tablesorter tbody tr.alt-row td {
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-widget-columns.html">Basic: Applying the columns widget ››</a>
|
||||
Next up: <a href="example-widgets.html">Widgets, writing your own ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -321,7 +321,7 @@
|
||||
|
||||
<div class="next-up">
|
||||
<hr />
|
||||
Next up: <a href="example-pager.html">Companion Plugins: Pager plugin ››</a>
|
||||
Next up: <a href="example-pager.html">Pager plugin ››</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -36,7 +36,7 @@
|
||||
</div>
|
||||
<p>
|
||||
<strong>Author:</strong> <a class="external" href="http://lovepeacenukes.com">Christian Bach</a><br>
|
||||
<strong>Version:</strong> <a href="http://github.com/Mottie/tablesorter/downloads">2.0.23</a> (forked from <a href="http://tablesorter.com/docs/">version 2.0.5</a>, <a href="../changelog.txt">changelog</a>)<br>
|
||||
<strong>Version:</strong> <a href="http://github.com/Mottie/tablesorter/downloads">2.0.23.1</a> (forked from <a href="http://tablesorter.com/docs/">version 2.0.5</a>, <a href="../changelog.txt">changelog</a>)<br>
|
||||
<strong>Licence:</strong>
|
||||
Dual licensed under <a class="external" href="http://www.opensource.org/licenses/mit-license.php">MIT</a>
|
||||
or <a class="external" href="http://www.opensource.org/licenses/gpl-license.php">GPL</a> licenses.
|
||||
@ -319,6 +319,7 @@
|
||||
<li><a href="example-widget-columns.html">Columns widget</a> <span class="tip"><em>New! v2.0.17</em></span></li>
|
||||
<li><a href="example-widget-filter.html">Filter widget</a> <span class="tip"><em>New! v2.0.18</em></span></li>
|
||||
<li><a href="example-widget-ui-theme.html">jQuery UI theme widget</a> <span class="tip"><em>New! v2.0.9</em></span></li>
|
||||
<li><a href="example-widget-resizable.html">Resizable Columns widget</a> <span class="tip"><em>New! v2.0.23.1</em></span></li>
|
||||
<li><a href="example-widget-sticky-header.html">Sticky header widget</a> <span class="tip"><em>New! v2.0.21.1</em></span></li>
|
||||
<li><a href="example-widget-zebra.html">Zebra stripe widget</a></li>
|
||||
<li><a href="example-widgets.html">Widgets, writing your own</a></li>
|
||||
@ -1147,7 +1148,7 @@ $(table)
|
||||
<li><a class="external" href="http://plugins.jquery.com/files/jquery.metadata.2.1.zip">jQuery Metadata 2.1</a> (3,7kb, required for setting <a href="#Examples">inline options</a>)</li>
|
||||
<li><a href="../js/jquery.tablesorter.js">jquery.tablesorter.js</a> (31kb, for development)</li>
|
||||
<li><a href="../addons/pager/jquery.tablesorter.pager.js">jquery.tablesorter.pager.js</a> (5,6kb, <a href="example-pager.html">tablesorter pagination plugin</a>)</li>
|
||||
<li><a href="../js/jquery.tablesorter.widgets.js">jquery.tablesorter.widgets.js</a> (6,2kb, includes the jQuery UI theme, columns styling widget, filter widget and sticky header widgets. <span class="tip"><em>New!</em></span> in v2.0.21.1.)</li>
|
||||
<li><a href="../js/jquery.tablesorter.widgets.js">jquery.tablesorter.widgets.js</a> (8,1kb, includes the jQuery UI theme, columns styling, resizable columns, filter widget and sticky header widgets. <span class="tip"><em>New!</em></span> in v2.0.21.1.)</li>
|
||||
</ul>
|
||||
|
||||
<strong id="Download-Themes">Themes:</strong>
|
||||
|
@ -1,5 +1,14 @@
|
||||
/* TableSorter 2.0 Widgets */
|
||||
/* TableSorter 2.0 Widgets
|
||||
*
|
||||
* jQuery UI Theme
|
||||
* Column Styles
|
||||
* Column Filters
|
||||
* Sticky Header
|
||||
* Column Resizing
|
||||
*
|
||||
*/
|
||||
(function($){
|
||||
|
||||
// Add jQuery UI theme widget
|
||||
// **************************
|
||||
$.tablesorter.addWidget({
|
||||
@ -81,7 +90,6 @@ $.tablesorter.addWidget({
|
||||
});
|
||||
|
||||
// Add Filter widget
|
||||
// ** This widget doesn't work correctly with the pager plugin =( **
|
||||
// **************************
|
||||
$.tablesorter.addWidget({
|
||||
id: "filter",
|
||||
@ -150,7 +158,8 @@ $.tablesorter.addWidget({
|
||||
position : 'fixed',
|
||||
top : 0,
|
||||
marginLeft : -brdr,
|
||||
visibility : 'hidden'
|
||||
visibility : 'hidden',
|
||||
zIndex : 10
|
||||
}),
|
||||
stkyCells = sticky.children();
|
||||
// update sticky header class names to match real header
|
||||
@ -188,7 +197,7 @@ $.tablesorter.addWidget({
|
||||
sticky.css('visibility', vis);
|
||||
})
|
||||
.resize(function(){
|
||||
sticky.css({ width: header.outerWidth() + brdr * 2 })
|
||||
sticky.css({ width: header.outerWidth() + brdr * 2 });
|
||||
stkyCells.each(function(i){
|
||||
$(this).width( hdrCells.eq(i).width() );
|
||||
});
|
||||
@ -196,4 +205,54 @@ $.tablesorter.addWidget({
|
||||
}
|
||||
});
|
||||
|
||||
// Add Column resizing widget
|
||||
// **************************
|
||||
$.tablesorter.addWidget({
|
||||
id: "resizable",
|
||||
format: function(table) {
|
||||
if (!table.config.resizable) {
|
||||
var i, w, c = table.config,
|
||||
cols = c.headerList,
|
||||
len = cols.length,
|
||||
stopResize = function(){
|
||||
c.resizable_position = 0;
|
||||
c.resizable_target = null;
|
||||
$(window).trigger('resize'); // will update stickyHeaders, just in case
|
||||
};
|
||||
c.resizable_target = null;
|
||||
c.resizable_position = 0;
|
||||
for (i=1; i < len; i++){
|
||||
$(cols[i])
|
||||
.append('<div class="resizer" style="cursor:w-resize;position:absolute;height:100%;width:20px;left:-20px;top:0;z-index:1;"></div>')
|
||||
.wrapInner('<div style="position:relative;height:100%;width:100%"></div>')
|
||||
.find('.resizer')
|
||||
.bind('mousedown', function(e){
|
||||
// save header cell and mouse position
|
||||
c.resizable_target = $(e.target).closest('th');
|
||||
c.resizable_position = e.pageX;
|
||||
}).end()
|
||||
.bind('mousemove', function(e){
|
||||
// ignore mousemove if no mousedown
|
||||
if (c.resizable_position === 0 || typeof(c.resizable_target) === null) { return; }
|
||||
var w = e.pageX - c.resizable_position,
|
||||
n = c.resizable_target.closest('th').prev();
|
||||
// make sure
|
||||
if ( c.resizable_target.width() < -w || ( n && n.width() <= w )) { return; }
|
||||
// resize current column
|
||||
n.width( n.width() + w );
|
||||
c.resizable_position = e.pageX;
|
||||
})
|
||||
.bind('mouseup', function(){
|
||||
stopResize();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
$(table).find('thead').bind('mouseup mouseleave', function(){
|
||||
stopResize();
|
||||
});
|
||||
c.resizable = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
})(jQuery);
|
13
js/jquery.tablesorter.widgets.min.js
vendored
13
js/jquery.tablesorter.widgets.min.js
vendored
@ -1,7 +1,8 @@
|
||||
/* TableSorter 2.0 Widgets */
|
||||
(function(b){
|
||||
b.tablesorter.addWidget({id:"uitheme",format:function(e){var c,f,g,d=e.config,a=["ui-icon-arrowthick-2-n-s","ui-icon-arrowthick-1-s","ui-icon-arrowthick-1-n"];d.widgetUitheme&&d.widgetUitheme.hasOwnProperty("css")&&(a=d.widgetUitheme.css||a);g=a.join(" ");d.debug&&(c=new Date);b(e).is(".ui-theme")||(b(e).addClass("ui-widget ui-widget-content ui-corner-all ui-theme"),b.each(d.headerList,function(){b(this).addClass("ui-widget-header ui-corner-all").append('<span class="ui-icon"/>').hover(function(){b(this).addClass("ui-state-hover")}, function(){b(this).removeClass("ui-state-hover")})}));b.each(d.headerList,function(c){d.headers[c]&&d.headers[c].sorter===false?b(this).find("span.ui-icon").removeClass(g+" ui-icon"):(f=b(this).is("."+d.cssAsc)?a[1]:b(this).is("."+d.cssDesc)?a[2]:b(this).is("."+d.cssHeader)?a[0]:"",b(this)[f===a[0]?"removeClass":"addClass"]("ui-state-active").find("span.ui-icon").removeClass(g).addClass(f))});d.debug&&b.tablesorter.benchmark("Applying uitheme widget",c)}});
|
||||
b.tablesorter.addWidget({id:"columns",format:function(e){var c, f,g,d,a=e.config,i=a.sortList,j=i.length,h=["primary","secondary","tertiary"];a.widgetColumns&&a.widgetColumns.hasOwnProperty("css")&&(h=a.widgetColumns.css||h);g=h.length-1;d=h.join(" ");a.debug&&(f=new Date);i&&i[0]&&b("tr:visible",e.tBodies[0]).each(function(a){c=b(this).children().removeClass(d);c.eq(i[0][0]).addClass(h[0]);if(j>1)for(a=1;a<j;a++)c.eq(i[a][0]).addClass(h[a]||h[g])});a.debug&&b.tablesorter.benchmark("Applying Columns widget",f)}});
|
||||
b.tablesorter.addWidget({id:"filter",format:function(e){if(!e.config.filtering){var c, f,g,d,a=e.config,i=a.headerList.length,j=b(e),e='<tr class="filters">',h;a.debug&&(h=new Date);for(c=0;c<i;c++)e+='<td><input type="text" class="filter" data-col="'+c+'" style="',e+=a.headers[c]&&"filter"in a.headers[c]&&a.headers[c].filter===false||b(a.headerList[c]).is(".filter-false")?"visibility:hidden":"",e+='"></td>';j.find("thead").append(e+="</tr>").find(".filter").bind("keyup",function(){f=j.find(".filter").map(function(){return(b(this).val()||"").toLowerCase()}).get();f.join("")===""?j.find("tr").show(): j.find("tbody").find("tr").each(function(){g=true;d=b(this).find("td");for(c=0;c<i;c++)f[c]!==""&&d.eq(c).text().toLowerCase().indexOf(f[c])>=0?g=g?true:false:f[c]!==""&&(g=false);b(this)[g?"show":"hide"]()});j.trigger("applyWidgets")});a.filtering=true;a.debug&&b.tablesorter.benchmark("Applying Filter widget",h)}}});
|
||||
b.tablesorter.addWidget({id:"stickyHeaders",format:function(e){if(!b(e).find(".stickyHeader").length){var c=b(window),f=b(e).find("thead"),g=f.find("tr").children(),d=f.find("tr").clone().addClass("stickyHeader").css({width:f.width(), position:"fixed",top:0,visibility:"hidden"}),a=d.children();b(e).bind("sortEnd",function(a,c){var d=b(c).find("thead tr"),e=d.filter(".stickyHeader").children();d.filter(":not(.stickyHeader)").children().each(function(a){e.eq(a).attr("class",b(this).attr("class"))})});g.each(function(c){var d=b(this);a.eq(c).width(d.width()).bind("click",function(b){d.trigger(b)}).bind("mousedown",function(){this.onselectstart=function(){return false};return false})});f.prepend(d);c.scroll(function(){var a=b(e),d= a.offset(),f=c.scrollTop(),g=a.find(".stickyHeader"),a=f>d.top&&f<d.top+a.height()?"visible":"hidden";g.css("visibility",a)})}}})
|
||||
})(jQuery);
|
||||
(function(c){
|
||||
c.tablesorter.addWidget({id:"uitheme",format:function(f){var b,a,g,d=f.config,e=["ui-icon-arrowthick-2-n-s","ui-icon-arrowthick-1-s","ui-icon-arrowthick-1-n"];d.widgetUitheme&&d.widgetUitheme.hasOwnProperty("css")&&(e=d.widgetUitheme.css||e);g=e.join(" ");d.debug&&(b=new Date);c(f).is(".ui-theme")||(c(f).addClass("ui-widget ui-widget-content ui-corner-all ui-theme"),c.each(d.headerList,function(){c(this).addClass("ui-widget-header ui-corner-all").append('<span class="ui-icon"/>').hover(function(){c(this).addClass("ui-state-hover")}, function(){c(this).removeClass("ui-state-hover")})}));c.each(d.headerList,function(b){d.headers[b]&&d.headers[b].sorter===false?c(this).find("span.ui-icon").removeClass(g+" ui-icon"):(a=c(this).is("."+d.cssAsc)?e[1]:c(this).is("."+d.cssDesc)?e[2]:c(this).is("."+d.cssHeader)?e[0]:"",c(this)[a===e[0]?"removeClass":"addClass"]("ui-state-active").find("span.ui-icon").removeClass(g).addClass(a))});d.debug&&c.tablesorter.benchmark("Applying uitheme widget",b)}});
|
||||
c.tablesorter.addWidget({id:"columns",format:function(f){var b,a,g,d,e=f.config,h=e.sortList,j=h.length,i=["primary","secondary","tertiary"];e.widgetColumns&&e.widgetColumns.hasOwnProperty("css")&&(i=e.widgetColumns.css||i);g=i.length-1;d=i.join(" ");e.debug&&(a=new Date);h&&h[0]&&c("tr:visible",f.tBodies[0]).each(function(a){b=c(this).children().removeClass(d);b.eq(h[0][0]).addClass(i[0]);if(j>1)for(a=1;a<j;a++)b.eq(h[a][0]).addClass(i[a]||i[g])});e.debug&&c.tablesorter.benchmark("Applying Columns widget",a)}});
|
||||
c.tablesorter.addWidget({id:"filter",format:function(f){if(!f.config.filtering){var b, a,g,d,e=f.config,h=e.headerList.length,j=c(f),f='<tr class="filters">',i;e.debug&&(i=new Date);for(b=0;b<h;b++)f+='<td><input type="text" class="filter" data-col="'+b+'" style="',f+=e.headers[b]&&"filter"in e.headers[b]&&e.headers[b].filter===false||c(e.headerList[b]).is(".filter-false")?"visibility:hidden":"",f+='"></td>';j.find("thead").append(f+="</tr>").find(".filter").bind("keyup",function(){a=j.find(".filter").map(function(){return(c(this).val()||"").toLowerCase()}).get();a.join("")===""?j.find("tr").show(): j.find("tbody").find("tr").each(function(){g=true;d=c(this).find("td");for(b=0;b<h;b++)a[b]!==""&&d.eq(b).text().toLowerCase().indexOf(a[b])>=0?g=g?true:false:a[b]!==""&&(g=false);c(this)[g?"show":"hide"]()});j.trigger("applyWidgets")});e.filtering=true;e.debug&&c.tablesorter.benchmark("Applying Filter widget",i)}}});
|
||||
c.tablesorter.addWidget({id:"stickyHeaders",format:function(f){if(!c(f).find(".stickyHeader").length){var b=c(window),a=c(f).find("thead"),g=a.find("tr").children(),d=parseInt(g.eq(0).css("border-left-width"), 10),e=a.find("tr").clone().addClass("stickyHeader").css({width:a.outerWidth()+d*2,position:"fixed",top:0,marginLeft:-d,visibility:"hidden"}),h=e.children();c(f).bind("sortEnd",function(a,e){var b=c(e).find("thead tr"),f=b.filter(".stickyHeader").children();b.filter(":not(.stickyHeader)").children().each(function(a){f.eq(a).attr("class",c(this).attr("class"))})});g.each(function(a){var b=c(this);h.eq(a).width(b.width()).bind("click",function(a){b.trigger(a)}).bind("mousedown",function(){this.onselectstart= function(){return false};return false})});a.prepend(e);b.scroll(function(){var a=c(f),d=a.offset(),g=b.scrollTop(),a=g>d.top&&g<d.top+a.find("tbody").height()?"visible":"hidden";e.css("visibility",a)}).resize(function(){e.css({width:a.outerWidth()+d*2});h.each(function(a){c(this).width(g.eq(a).width())})})}}});
|
||||
c.tablesorter.addWidget({id:"resizable",format:function(f){if(!f.config.resizable){var b,a=f.config,g=a.headerList,d=g.length;a.resizable_target=null;a.resizable_position=0;for(b=1;b<d;b++)c(g[b]).append('<div style="cursor:w-resize;position:absolute;height:100%;width:20px;left:-20px;top:0;z-index:100;"></div>').wrapInner('<div style="position:relative;height:100%;width:100%"></div>').bind("mousedown", function(b){a.resizable_target=c(b.target);a.resizable_position=b.pageX}).bind("mousemove",function(b){if(!(a.resizable_position===0||typeof a.resizable_target===null)){var c=b.pageX-a.resizable_position,d=a.resizable_target.closest("th").prev();if(!(a.resizable_target.width()<-c||d&&d.width()<=c))d.width(d.width()+c),a.resizable_position=b.pageX}}).bind("mouseup",function(){a.resizable_position=0;a.resizable_target=null;return false});c(f).find("thead").bind("mouseup",function(){a.resizable_position= 0;a.resizable_target=null});a.resizable=true}}})
|
||||
})(jQuery);
|
||||
|
Loading…
Reference in New Issue
Block a user