使用从服务器动态填充的信息对HTML表进行排序

时间:2012-04-12 13:44:02

标签: javascript html sorting knockout.js

编辑2012年4月16日:我修复了问题并使排序正常运行。我还将时区转换为单字母UTC代码(A-Z)。唯一剩下的就是让格式化程序检查夏令时,但这个主题有很多。但是如果你想要它可以随时贡献,最受欢迎。谢谢大家帮助我实现目标。

EDIT2 4/16/2012:我解决了!!由于日期已经是UTC,我正在进行一些不必要的转换,这些转换会产生一些冲突/奇怪的结果。这个问题应该被视为已解决。谢谢所有帮助过的人。

我正在使用knockoutjs创建一个小部件(html / javascript中的表),从我的服务器动态提取信息。我坚持为此排序方法。我已经制作并下载了不同版本的表格排序方法,但它们都使从服务器中提取的初始数据消失。他们对待表格就像信息无法编辑;所以似乎与我的桌子有冲突,因为我需要让所有信息都可以编辑。

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's 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's column's information.  

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

纠正了排序错误,我意外忘记重命名其中一个复制的排序函数,因此导致了冲突。我仍然无法弄清楚如何让表格恢复原来的顺序。如果有人可以查看我制作的排序功能并告诉我需要做什么或更改它将非常感谢。

我也无法让删除功能正常工作。它以某种方式引起冲突,因为当我将它包含在表中时,来自服务器的数据不会填充表。

编辑: 我设法找出一种“快速而肮脏”的方式来获得单个列的排序。它是这样的:

//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;
    });
}

但是,如果我为所有其他列复制了这个代码(将所有Column1更改为Column2和3,依此类推,为函数的每个不同副本);某些行未正确排序。但是,如果我只保留这一个函数而没有任何副本到其他列,它可以正常工作。

**我还需要能够将表​​格恢复为原始顺序。现在我将这一个函数绑定到表中的Column1标题。如果我单击一次,它会按降序排列,如果我再次单击标题;它将表格按升序排列(当然根据Column1的信息)。现在的问题是,如果我第三次点击它,它会将表恢复为默认(原始)顺序。

2 个答案:

答案 0 :(得分:0)

如何实现this之类的内容? (单击列标题进行排序):

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>

答案 1 :(得分:0)

我解决了!!由于日期已经是UTC,我正在进行一些不必要的转换,这些转换会产生一些冲突/奇怪的结果。这个问题应该被视为已解决。谢谢所有帮助过的人。