Skip to content
Browse files

Merge pull request #5854 from jquery/table-refresh-1.3

Table refresh method for 1.3.x. Fixes #5841 and fixes #5842.
  • Loading branch information...
2 parents 2f8cee0 + 4f081ec commit 922c562b5c65f0c689fd216bc2890ffd64d65263 @jaspermdegroot jaspermdegroot committed Apr 4, 2013
Showing with 190 additions and 54 deletions.
  1. +59 −36 js/widgets/table.columntoggle.js
  2. +14 −2 js/widgets/table.js
  3. +6 −3 js/widgets/table.reflow.js
  4. +22 −10 tests/unit/table/index.html
  5. +89 −3 tests/unit/table/table_core.js
View
95 js/widgets/table.columntoggle.js
@@ -34,26 +34,29 @@ $.mobile.table.prototype.options.classes = $.extend(
}
);
-$.mobile.document.delegate( ":jqmData(role='table')", "tablecreate", function() {
-
+$.mobile.document.delegate( ":jqmData(role='table')", "tablecreate refresh", function( e ) {
+
var $table = $( this ),
self = $table.data( "mobile-table" ),
+ event = e.type,
o = self.options,
- ns = $.mobile.ns;
+ ns = $.mobile.ns,
+ id = ( $table.attr( "id" ) || o.classes.popup ) + "-popup"; //TODO BETTER FALLBACK ID HERE
if( o.mode !== "columntoggle" ){
return;
}
- self.element.addClass( o.classes.columnToggleTable );
+ if ( event !== "refresh" ) {
+ self.element.addClass( o.classes.columnToggleTable );
- var id = ( $table.attr( "id" ) || o.classes.popup ) + "-popup", //TODO BETTER FALLBACK ID HERE
- $menuButton = $( "<a href='#" + id + "' class='" + o.classes.columnBtn + "' data-" + ns + "rel='popup' data-" + ns + "mini='true'>" + o.columnBtnText + "</a>" ),
- $popup = $( "<div data-" + ns + "role='popup' data-" + ns + "role='fieldcontain' class='" + o.classes.popup + "' id='" + id + "'></div>"),
- $menu = $("<fieldset data-" + ns + "role='controlgroup'></fieldset>");
+ var $menuButton = $( "<a href='#" + id + "' class='" + o.classes.columnBtn + "' data-" + ns + "rel='popup' data-" + ns + "mini='true'>" + o.columnBtnText + "</a>" ),
+ $popup = $( "<div data-" + ns + "role='popup' data-" + ns + "role='fieldcontain' class='" + o.classes.popup + "' id='" + id + "'></div>"),
+ $menu = $("<fieldset data-" + ns + "role='controlgroup'></fieldset>");
+ }
// create the hide/show toggles
- self.headers.not( "td" ).each(function(){
+ self.headers.not( "td" ).each(function( i ){
var priority = $( this ).jqmData( "priority" ),
$cells = $( this ).add( $( this ).jqmData( "cells" ) );
@@ -62,48 +65,68 @@ $.mobile.document.delegate( ":jqmData(role='table')", "tablecreate", function()
$cells.addClass( o.classes.priorityPrefix + priority );
- $("<label><input type='checkbox' checked />" + $( this ).text() + "</label>" )
- .appendTo( $menu )
- .children( 0 )
- .jqmData( "cells", $cells )
- .checkboxradio({
- theme: o.columnPopupTheme
- });
+ if ( event !== "refresh" ) {
+ $("<label><input type='checkbox' checked />" + $( this ).text() + "</label>" )
+ .appendTo( $menu )
+ .children( 0 )
+ .jqmData( "cells", $cells )
+ .checkboxradio({
+ theme: o.columnPopupTheme
+ });
+ } else {
+ $('#' + id + ' fieldset div:eq(' + i +')').find('input').jqmData("cells", $cells)
+ }
}
});
+ if ( event !== "refresh" ) {
$menu.appendTo( $popup );
+ }
// bind change event listeners to inputs - TODO: move to a private method?
- $menu.on( "change", "input", function( e ){
- if( this.checked ){
- $( this ).jqmData( "cells" ).removeClass( "ui-table-cell-hidden" ).addClass( "ui-table-cell-visible" );
- }
- else {
- $( this ).jqmData( "cells" ).removeClass( "ui-table-cell-visible" ).addClass( "ui-table-cell-hidden" );
- }
- });
+ if ( $menu === undefined ) {
+ $switchboard = $('#' + id + ' fieldset');
+ } else {
+ $switchboard = $menu;
+ }
- $menuButton
- .insertBefore( $table )
- .buttonMarkup({
- theme: o.columnBtnTheme
+ if (event !== "refresh") {
+ $switchboard.on( "change", "input", function( e ){
+ if( this.checked ){
+ $( this ).jqmData( "cells" ).removeClass( "ui-table-cell-hidden" ).addClass( "ui-table-cell-visible" );
+ } else {
+ $( this ).jqmData( "cells" ).removeClass( "ui-table-cell-visible" ).addClass( "ui-table-cell-hidden" );
+ }
});
- $popup
- .insertBefore( $table )
- .popup();
+ $menuButton
+ .insertBefore( $table )
+ .buttonMarkup({
+ theme: o.columnBtnTheme
+ });
+
+ $popup
+ .insertBefore( $table )
+ .popup();
+ }
// refresh method
- self.refresh = function(){
- $menu.find( "input" ).each( function(){
- this.checked = $( this ).jqmData( "cells" ).eq(0).css( "display" ) === "table-cell";
+ self.update = function(){
+ $switchboard.find( "input" ).each( function(){
+ if (this.checked) {
+ this.checked = $( this ).jqmData( "cells" ).eq(0).css( "display" ) === "table-cell";
+ if (event === "refresh") {
+ $( this ).jqmData( "cells" ).addClass('ui-table-cell-visible');
+ }
+ } else {
+ $( this ).jqmData( "cells" ).addClass('ui-table-cell-hidden');
+ }
$( this ).checkboxradio( "refresh" );
});
};
- $.mobile.window.on( "throttledresize", self.refresh );
+ $.mobile.window.on( "throttledresize", self.update );
- self.refresh();
+ self.update();
});
View
16 js/widgets/table.js
@@ -19,11 +19,17 @@ $.widget( "mobile.table", $.mobile.widget, {
},
_create: function() {
+ var self = this;
+ self.refresh( true );
+ },
+ refresh: function (create) {
var self = this,
trs = this.element.find( "thead tr" );
- this.element.addClass( this.options.classes.table );
+ if ( create ) {
+ this.element.addClass( this.options.classes.table );
+ }
// Expose headers and allHeaders properties on the widget
// headers references the THs within the first TR in the table
@@ -40,7 +46,6 @@ $.widget( "mobile.table", $.mobile.widget, {
var span = parseInt( $( this ).attr( "colspan" ), 10 ),
sel = ":nth-child(" + ( coltally + 1 ) + ")";
-
$( this )
.jqmData( "colstart", coltally + 1 );
@@ -51,6 +56,9 @@ $.widget( "mobile.table", $.mobile.widget, {
}
}
+ if ( create === undefined ) {
+ $(this).jqmData("cells", "");
+ }
// Store "cells" data on header as a reference to all cells in the same column as this TH
$( this )
.jqmData( "cells", self.element.find( "tr" ).not( trs.eq(0) ).not( this ).children( sel ) );
@@ -61,6 +69,10 @@ $.widget( "mobile.table", $.mobile.widget, {
});
+ // update table modes
+ if ( create === undefined ) {
+ this.element.trigger( 'refresh' );
+ }
}
});
View
9 js/widgets/table.reflow.js
@@ -19,9 +19,10 @@ $.mobile.table.prototype.options.classes = $.extend(
}
);
-$.mobile.document.delegate( ":jqmData(role='table')", "tablecreate", function() {
+$.mobile.document.delegate( ":jqmData(role='table')", "tablecreate refresh", function( e ) {
var $table = $( this ),
+ event = e.type,
self = $table.data( "mobile-table" ),
o = self.options;
@@ -30,13 +31,15 @@ $.mobile.document.delegate( ":jqmData(role='table')", "tablecreate", function()
return;
}
- self.element.addClass( o.classes.reflowTable );
+ if ( event !== "refresh" ) {
+ self.element.addClass( o.classes.reflowTable );
+ }
// get headers in reverse order so that top-level headers are appended last
var reverseHeaders = $( self.allHeaders.get().reverse() );
// create the hide/show toggles
- reverseHeaders.each(function(i){
+ reverseHeaders.each(function( i ){
var $cells = $( this ).jqmData( "cells" ),
colstart = $( this ).jqmData( "colstart" ),
hierarchyClass = $cells.not( this ).filter( "thead th" ).length && " ui-table-cell-label-top",
View
32 tests/unit/table/index.html
@@ -33,6 +33,18 @@
<link rel="stylesheet" href="../../../external/qunit.css"/>
<script src="../swarminject.js"></script>
+
+ <script type="text/javascript">
+ $(window).on('refresh_test_table', function (e, data) {
+ var tb = $(data).find('tbody'),
+ newRow = '<tr><th data-test="abc">1</th><td>2</td><td>3</td><td data-col="3">4</td><td>5</td></tr>';
+ tb.empty()
+ .append(newRow)
+ .closest('table')
+ .table('refresh');
+ });
+ </script>
+
</head>
<body>
@@ -51,11 +63,11 @@ <h2 id="qunit-userAgent"></h2>
<table data-nstest-role="table" id="movie-table">
<thead>
<tr>
- <th data-priority="1">Rank</th>
- <th data-priority="persist">Movie Title</th>
- <th data-priority="2">Year</th>
- <th data-priority="3"><abbr title="Rotten Tomato Rating">Rating</abbr></th>
- <th data-priority="4">Reviews</th>
+ <th data-nstest-priority="1">Rank</th>
+ <th data-nstest-priority="persist">Movie Title</th>
+ <th data-nstest-priority="2">Year</th>
+ <th data-nstest-priority="3"><abbr title="Rotten Tomato Rating">Rating</abbr></th>
+ <th data-nstest-priority="4">Reviews</th>
</tr>
</thead>
<tbody>
@@ -78,11 +90,11 @@ <h2 id="qunit-userAgent"></h2>
<table data-nstest-role="table" data-nstest-mode="reflow" id="movie-table-reflow">
<thead>
<tr>
- <th data-priority="1">Rank</th>
- <th data-priority="persist">Movie Title</th>
- <th data-priority="2">Year</th>
- <th data-priority="3"><abbr title="Rotten Tomato Rating">Rating</abbr></th>
- <th data-priority="4">Reviews</th>
+ <th data-nstest-priority="1">Rank</th>
+ <th data-nstest-priority="persist">Movie Title</th>
+ <th data-nstest-priority="2">Year</th>
+ <th data-nstest-priority="3"><abbr title="Rotten Tomato Rating">Rating</abbr></th>
+ <th data-nstest-priority="4">Reviews</th>
</tr>
</thead>
<tbody>
View
92 tests/unit/table/table_core.js
@@ -1,4 +1,3 @@
-
/*
* mobile table unit tests
*/
@@ -23,29 +22,58 @@
}
});
asyncTest( "The page should be enhanced correctly" , function(){
+ expect( 1 );
+
setTimeout(function() {
var $table = $('#basic-table-test .ui-table');
+
ok( $table.length, ".ui-table class added to table element" );
start();
}, 800);
});
asyncTest( "Has data object attributed to table" , function(){
+ expect( 1 );
+
setTimeout(function(){
var $table = $('#basic-table-test .ui-table'),
self = $table.data( "mobile-table" );
+
ok( self , "Data object is available" );
start();
}, 800);
});
asyncTest( "Has headers option" , function(){
+ expect( 2 );
+
setTimeout(function() {
var $table = $('#basic-table-test .ui-table'),
self = $table.data( "mobile-table" );
+
ok( self.headers.length , "Header array is not empty");
equal( 5 , self.headers.length , "Number of headers is correct");
start();
}, 800);
});
+ asyncTest("Refresh updates table headers correctly", function () {
+ expect( 4 );
+
+ setTimeout(function () {
+ $(window).trigger("refresh_test_table", ["#basic-table-test"]);
+ var $table = $('#basic-table-test .ui-table'),
+ $firstHeaderCell = $table.find('thead tr th').eq(0),
+ $cellLookUp = $table.find('tbody tr').eq(0).find('th td').eq(0).jqmData("test");
+
+ ok($table.length, "table still enhanced");
+ ok($firstHeaderCell.jqmData("cells").length,
+ "column cells still assigned to header cell");
+ equal($firstHeaderCell.jqmData('cells').eq(0).closest("table").attr('id'),
+ "movie-table",
+ "cell stored is a refreshed cell (currently in the table");
+ equal($cellLookUp, $firstHeaderCell.jqmData('cells').eq(0).jqmData("test"),
+ "referenced cell is in the correct column");
+ start();
+ }, 800);
+ });
module( "Reflow Mode", {
setup: function(){
var hash = "#reflow-table-test";
@@ -64,22 +92,42 @@
}
});
asyncTest( "The page should be enhanced correctly" , function(){
+ expect( 1 );
+
setTimeout(function() {
ok($('#reflow-table-test .ui-table-reflow').length, ".ui-table-reflow class added to table element");
start();
}, 800);
});
asyncTest( "The appropriate label is added" , function(){
+ expect( 2 );
+
setTimeout(function(){
var $table = $( "#reflow-table-test table" ),
$body = $table.find( "tbody" ),
$tds = $body.find( "td" ),
labels = $tds.find( "b.ui-table-cell-label" );
+
ok( labels , "Appropriate label placed" );
equal( $( labels[0] ).text(), "Movie Title" , "Appropriate label placed" );
start();
}, 800);
});
+ asyncTest( "Reflow table refresh" , function(){
+ expect( 2 );
+
+ setTimeout(function () {
+ // refresh table
+ $(window).trigger("refresh_test_table", ["#reflow-table-test"]);
+ var $table = $('#reflow-table-test .ui-table'),
+ $tds = $table.find( "td" ),
+ labels = $tds.find( "b.ui-table-cell-label" );
+
+ ok( $table.length, "table still enhanced");
+ ok( labels = $tds.find( "b.ui-table-cell-label" ), "Labels still there");
+ start();
+ }, 800);
+ });
module( "Column toggle table Mode", {
setup: function(){
var hash = "#column-table-test";
@@ -98,8 +146,11 @@
}
});
asyncTest( "The page should be enhanced correctly" , function(){
+ expect( 6 );
+
setTimeout(function() {
var $popup = $('#column-table-test #movie-table-column-popup-popup');
+
ok($('#column-table-test .ui-table-columntoggle').length, ".ui-table-columntoggle class added to table element");
ok($('#column-table-test .ui-table-columntoggle-btn').length, ".ui-table-columntoggle-btn button added");
equal($('#column-table-test .ui-table-columntoggle-btn').text(), "Columns...", "Column toggle button has correct text");
@@ -109,7 +160,42 @@
start();
}, 800);
});
-
+ asyncTest( "Column toggle table refresh" , function(){
+ expect( 5 );
+
+ var $input;
+
+ $.testHelper.pageSequence([
+ function() {
+ $( ".ui-table-columntoggle-btn" ).click();
+ },
+ function() {
+ $input = $( "#movie-table-column-popup-popup" ).find( "input" ).eq(0);
+ $input.click();
+ },
+ function(){
+ setTimeout(function () {
+ $(window).trigger("refresh_test_table", ["#column-table-test"]);
+
+ var $table = $('#column-table-test .ui-table'),
+ $first_input = $( "#movie-table-column-popup-popup" ).find( "input" ).eq(0),
+ $visibleCells = $table.find("tbody tr:first").find("th, td").not('.ui-table-cell-hidden'),
+ $visibleHeaders = $table.find("thead tr:first").find("th, td").not('.ui-table-cell-hidden');
+
+ ok( $table.length, "table still enhanced");
+ equal( $table.find('tbody tr:first')
+ .find("th, td").eq(2).hasClass('ui-table-cell-hidden'), true, "random cell in hidden column has ui-table-cell-hidden class");
+ ok( $input.is( ":checked" ), false, "input is still not checked after refresh");
+ equal( $first_input.jqmData("cells").eq(1).data("test"), "abc",
+ "cell reference in popup is to cell currently in table");
+ equal( $visibleCells.length, $visibleHeaders.length, "same number of headers and rows visible" );
+ }, 800);
+ },
+ function() {
+ start();
+ }
+ ]);
+ });
asyncTest( "The dialog should become visible when button is clicked" , function(){
expect( 2 );
var $input;
@@ -141,4 +227,4 @@
}
]);
});
-})(jQuery);
+})(jQuery);

1 comment on commit 922c562

@frigon
frigon commented on 922c562 Jul 17, 2013

The refresh method does not update dynamically added columns.

Please sign in to comment.
Something went wrong with that request. Please try again.