77

All the knockout examples I have found seem to add a new item to the end of an ObservableArray using something like:

viewModel.SomeItems.push(someNewItem);

This of course places the item at the end of the array.

How to I add an item to the ObservableArray at a certain position?

eg. something like:

viewModel.SomeItems.push(someNewItem, indexToInsertItAt);
Mark Robinson
  • 13,128
  • 13
  • 63
  • 81

3 Answers3

84

You should be able to use the native JavaScript splice method -

viewModel.SomeItems.splice(2,0,someNewItem);

Docs here - https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice

Example here (not Knockout specific) - How to insert an item into an array at a specific index?

From the Knockout docs -

For functions that modify the contents of the array, such as push and splice, KO’s methods automatically trigger the dependency tracking mechanism so that all registered listeners are notified of the change, and your UI is automatically updated.

Community
  • 1
  • 1
ipr101
  • 24,096
  • 8
  • 59
  • 61
  • 7
    Thanks. Splice worked. For knockout users, ko.utils.arrayIndexOf is also useful if you want to find the index to insert your new item based on an existing item. – Mark Robinson Sep 06 '11 at 11:26
  • 1
    This won't work with sparse arrays, at least it didn't for me in chrome. See my answer below – Adam Tegen Sep 04 '12 at 05:47
23

For knockout use

viewModel.SomeItems.unshift(someNewItem);

See also: http://knockoutjs.com/documentation/observableArrays.html

Josh Darnell
  • 11,304
  • 9
  • 38
  • 66
  • 15
    This insert the item at the beginning of the array so doesn't help if you want to insert an item seomwhere in the middle. – Mark Robinson Aug 03 '12 at 08:03
  • 1
    I somehow missed the part about inserting it anywhere in the array. Yes this only works if you want to insert into the beginning. Sorry about that. – Travis Cavanaugh Oct 01 '12 at 20:47
12

I made this extension function which worked nicely for me. Splice wasn't working for me if I was adding to the end of a sparse array.

ko.observableArray.fn.setAt = function(index, value) {
    this.valueWillMutate();
    this()[index] = value;
    this.valueHasMutated();
}

This even works with:

var a = ko.observableArray(['a', 'b', 'c']);
a.setAt(42, 'the answer');
Adam Tegen
  • 25,378
  • 33
  • 125
  • 153
  • 2
    And if you want to do insertAt rather than setAt, just switch `this()[index] = value;` to `this.splice(index, 0, value);`. Thanks Adam! – Brian S Sep 22 '12 at 13:47