user1104854
user1104854

Reputation: 2167

Populating select in knockout.js

I have a quantity select option in a knockout table but I want to set a max limit on it based on the stock available.

Say I have the following values for an entry

ID = 1
stock = 8

I want to populate the quantity field with numbers 1-stock, in this case 1-8. Quantity will always be less than or equal to stock.

function ItemEntry(ID, stock, quantity) {
    var self = this;
    self.ID= ID;
    self.stock= stock;
    self.quantity = quantity;

}

// viewmodel
function EntryViewModel() {
    var self = this;

    self.itemNumbers = ko.observableArray([
        new ItemEntry("1", 8, QUANTITY HERE!) //initial starting values
    ]);

    self.removeItem = function(item) { self.itemNumbers.remove(item) }
}

//custom binding for dropdown outside of models
ko.bindingHandlers.quantityDropdown = {
        update: function(quantityDropdown, stock, EntryViewModel) {
            var quantity = ko.utils.unwrapObservable(stock());
            for(var i = 0; i < stock(); i++)
            {
               $(quantityDropdown).append('<option value="' + i + '">' + i + '</option>');
            }
        }
    };

ko.applyBindings(new EntryViewModel());

Here's the HTML

  <table border="1">
  <thead><tr>
        <th>ID</th><th>Stock</th><th>Quantity</th><th></th>
    </tr></thead>
    <tbody data-bind="foreach: itemNumbers">
        <tr>
            <td data-bind="text: ID"></td>
            <td data-bind="text: stock"></td>
            <td><select data-bind="quantityDropdown: quantity"></select></td>
            <td><a href="#" data-bind="click: $root.removeItem">Remove</a></td>
        </tr>    
    </tbody>
</table>

Upvotes: 0

Views: 647

Answers (1)

Paul Manzotti
Paul Manzotti

Reputation: 5147

Create a custom binding outside of your view model code:

ko.bindingHandlers.quantityDropdown = {

    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var quantity = ko.utils.unwrapObservable(valueAccessor());
        for(var i = 1; i < quantity + 1; i++)
        {
            // Add each option element to the select here
            $(element).append('<option value="' + i + '">' + i + '</option>');
        }
    }
};

Then change your binding to:

<td><select data-bind="quantityDropdown: stock"></select></td>

Upvotes: 1

Related Questions