Sort an HTML table with information dynamically populating it from the server

EDITING 4/16/2012: I fixed the problems and handled the sorts correctly. I also converted the time slots to their single-letter UTC (AZ) codes. The only thing left is to get a formatter to check Summer Savings, but there is a lot on this topic. However, feel free to contribute if you want this to be most welcome. Thanks to everyone for helping me achieve my goal.

EDIT2 4/16/2012: I decided! Due to the fact that the date is already in UTC, I did some unnecessary conversions that created some conflicts / strange results. This question should be considered SOLVED. Thanks to everyone who helped.

I use knockoutjs to create a widget (table in html / javascript) that dynamically outputs information from my server. I went in cycles on sorting methods for this. I have made and downloaded various versions of table sorting methods, but all of them make the original data that is pulled from the server disappear. They process tables as information cannot be edited; therefore, there seems to be a conflict with my table, since I need to make all the information editable.

Right now in my ViewModel.js file I have: Event(column1,column2,column3,...columnN){ var self = this; self.column1 = column1; self.column2 = column2; . . } function ViewModel(){ var self= this; self.rows = ko.observableArray([]); self.addRow = function(){ self.rows.push("","",.......); } //THIS REMOVE FUNCTION DOESN'T WORK self.removeRow = function(row) self.rows.remove(row); } //THIS DOESN'T WORK EITHER, a.column and b.column, the 'column would be column1, //column2, etc. self.SortMethod = function(){ self.items.sort(function(a,b){ return a.column < b.column ? -1 : 1; }); } } //navigate to the server and its info function getEvents(){ $get.JSON("http://......", function(data){ $.each(data.d, function(i,item){handleEvent(item)}) } ); } //this populates the rows/columns in the table with the events(info) from the server //Here, 'Model' is a new ViewModel which is declared further below function handleEvent(item){ var newEvent = new Event(item.Event1, item.Event2,.....); this.Model.rows.push(newEvent); } this.Model = new ViewModel(); this.getEvents(); ko.applyBindings(this.Model); //The HTML code just makes the table, the headers and the style of the table and I then use //data-bind to bind the info in the server into the appropriate block in the table. //And yes, I do use <script src="knockout.js"> and for all other js files I have in the //HTML file. The HTML is basically this: title meta scripts table style table headers <tr><td>Column1Header</td><td>Column2Header</td>.....</tr> table body Example line from table body: <td><input data-bind = "value: column1" /><td> buttons (for adding a row and another button for sorting the array) //I think it would be better to get rid of the sorting button and make it so if you click on //the table headers, you'll sort the table according to that header column information. 

==================================================== ============================= EDIT2:

If the sorting error is fixed, I accidentally forgot to rename one of the copied sorting functions to cause a conflict. I still could not figure out how to return the table to its original order. If someone can look at the sorting function that I did and show me what I need to do or change, it would be very helpful.

I also could not get the delete function to work correctly. This causes a conflict anyway, as when I include it in the table, the data from the server does not fill the table.

EDIT: I was able to figure out a “quick and dirty” way to get sorting for a single column. This happens something like this:

 //After the line: self.rows = ko.observableArray([]); I continued with: self.sortColumn = "Column1"; self.sortAscending = true; self.SortColumn1 = function (){ if(self.sortColumn == "Column1") self.sortAscending = !self.sortAscending; else{ self.sortColumn = "Column1"; self.sortAscending = true; } self.rows.sort(function(a,b){ if(self.sortAscending == true) return a.Column1 < b.Column1 ? -1 : 1; else return a.Column1 > b.Column1 ? -1 : 1; }); } 

However, if I copied this code for all the other columns (changing all columns 1 to columns 2 and 3, etc. for every other copy of the function); some rows are not sorted correctly. However, if I save only one function without any copies in relation to other columns, it works fine.

** I also need the ability to return the table to its original order. Right now I have one function bound to the Column1 header in the table. If I click once, he will put it in descending order, and if I click the title again; he places the table in ascending order (according to the information in column 1, of course). Now the problem is to do this, if I clicked a third time, it will restore the default table (original).

+6
source share
2 answers

I solved it! Due to the fact that the date is already in UTC, I did some unnecessary conversions that created some conflicts / strange results. This question should be considered SOLVED. Thanks to everyone who helped.

0
source

How about implementing something like this ? (click column headings to sort):

 function ViewModel(){ var self = this; self.rows = ko.observableArray([]); self.newOne = { firstName:ko.observable(""), lastName:ko.observable("") }; self.currentSort = ko.observable(""); self.addNew = function() { self.addRow(self.newOne.firstName(), self.newOne.lastName()); self.newOne.firstName(""); self.newOne.lastName(""); } self.addRow = function(firstName, lastName) { self.rows.push( { firstName: firstName.capitalize(), lastName:lastName.capitalize() }); if(self.currentSort() != "") self.sortBy(self.currentSort()); }; self.removeRow = function() { self.rows.remove(this); }; self.sortBy = function(sortField) { sortFunc = self.defaultSorter; self.rows.sort(function(left, right) { return sortFunc(left[sortField], right[sortField]); }); self.currentSort(sortField); }; self.defaultSorter = function(left, right) { if(left > right) return 1; return left < right ? -1 : 0; }; }; String.prototype.capitalize = function() { return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase(); }; this.Model = new ViewModel(); this.Model.addRow("Any", "Coder"); this.Model.addRow("Some", "Another"); this.Model.addRow("Nice", "Guy"); this.Model.addRow("Cool", "One"); ko.applyBindings(this.Model); 
 th, td { border: 1px solid gray; padding: 0px 2px; } .sort-by { cursor: pointer; } button { width: 18px; height: 18px; border: 1px solid lightgray; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.0.0/knockout-min.js"></script> <div> current sorting: <span data-bind="text: currentSort"></span> <table> <thead> <tr> <th class="sort-by" data-bind="click: sortBy.bind($data, 'firstName')">First name</th> <th class="sort-by" data-bind="click: sortBy.bind($data, 'lastName')">Last name</th> </tr> </thead> <tbody data-bind="foreach: rows"> <tr> <td data-bind="text: firstName"></td> <td data-bind="text: lastName"></td> <td><button href='#' data-bind="click: $parent.removeRow">-</button></td> </tr> </tbody> <tfoot> <tr> <td><input data-bind="value: newOne.firstName" /></td> <td><input data-bind="value: newOne.lastName" /></td> <td><button data-bind="click: addNew">+</button></td> </tr> </tfoot> </table> </div> 
0
source

Source: https://habr.com/ru/post/913039/


All Articles