Question

Info:

I'm trying to learn web development with Knockout by building a simple gradebook app. It's still very early in development, but I've hit a road block getting my <td>'s in each <tr> to match the columns in the <th> element. So far, I have no issues adding rows or header columns, but when I attempt to update each row such that it has the same number or columns as the table header, I get weird behaviour.

See an example here: http://jsbin.com/fehoq/2/edit

It looks like I'm getting new <td>'s, but my <input> elements are missing, as are their empty string values!

Note: I generated the javascript using typescript. I don't think that should be an issue though.

Relevant Script:

From my Model:

addScore = function(score){
   this.scores.push(score);
}

From my View Model:

updateRows = function(){
    for(var i=1;i<this.students.length;i++){
        while(this.students[i].scores.length<this.assignments.length){
            this.students[i].addScore("");
        }
    }
}

Note that assignments is an observable array of "work" objects, and students is an observable array of student objects. "Scores" is also an observable array belonging to each student object.

Edit:

It looks like my updateRows() method is accomplishing nothing whatsoever. I do not know where to call it.

Was it helpful?

Solution

the foreach should be a parent element, since that is not possible in your case you should use the comment notation: http://jsbin.com/wideyeku/2/edit?html,js,output

<thead>
        <tr>
          <th>Name</th>
          <!-- ko foreach: assignments -->
            <th><input data-bind="value: workName"/></th>
          <!-- /ko -->
        </tr>    
</thead>

UPDATE: http://jsbin.com/wideyeku/4/edit?js,console,output I found out you had some logical mistakes in your code:

first of all, this is variable in javascript, so keep a reference to it in your model:

function StudentsViewModel() {
              var self = this;

then correct your update rows function:

this.updateRows = function () {
                    ko.utils.arrayForEach(this.students(), function(student){
                      while(student.scores().length < self.assignments().length){
                        student.scores.push("");
                      }
                    })
                };

never forget that observableArrays are functions, and need to be invoked.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top