Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

KnockoutJS: click event invoked on every Option in Select

I want Knockout to call an event whenever the user clicks an option in a SELECT element.

Here's my JavaScript:

function ReservationsViewModel() {
    this.availableMeals = [
        { mealName: "Standard (sandwich)", price: 0 },
        { mealName: "Premium (lobster)", price: 34.95 },
        { mealName: "Ultimate (whole zebra)", price: 290 }
    ];
}

ko.applyBindings(new ReservationsViewModel());

Here's my HTML:

<select data-bind="foreach: availableMeals">
    <option data-bind="text: mealName, click: alert('hello')" />
</select>

But when I run this, the application shows "hello" three times even though none of the options were actually clicked.

What am I doing wrong?

like image 454
user1746507 Avatar asked Oct 15 '12 08:10

user1746507


People also ask

What is KnockoutJS used for?

KnockoutJS is basically a library written in JavaScript, based on MVVM pattern that helps developers build rich and responsive websites.

What is $data in knockout?

The $data variable is a built-in variable used to refer to the current object being bound. In the example this is the one of the elements in the viewModel. folders array.

How do you activate a KnockoutJS model?

To activate Knockout, add the following line to a <script> block: ko. applyBindings(myViewModel); You can either put the script block at the bottom of your HTML document, or you can put it at the top and wrap the contents in a DOM-ready handler such as jQuery's $ function.

What is $root in knockout?

$root. This is the main view model object in the root context, i.e., the topmost parent context. It's usually the object that was passed to ko. applyBindings . It is equivalent to $parents[$parents.


2 Answers

You should use change binding instead of click and optionsText binding instead of option tag and use function in change binding instead of just calling alert:

<select data-bind="options: availableMeals, optionsText: 'mealName', value: selectedMeal, event: {change: onChange}">
</select>

function Meal(name, price){
    var self = this;

    self.mealName = name;
    self.price =  price;    
}

function ReservationsViewModel() {
    var self = this;
    self.availableMeals = ko.observableArray(
        [new Meal("Standard (sandwich)", 0),
         new Meal("Premium (lobster)", 34.95),
         new Meal("Ultimate (whole zebra)", 290)]);


    self.selectedMeal = ko.observable(self.availableMeals()[0]);

    self.onChange = function() {
        alert("Hello");
    };
}

ko.applyBindings(new ReservationsViewModel());

Here is working example: http://jsfiddle.net/Q8QLX/

like image 139
Artem Vyshniakov Avatar answered Oct 01 '22 01:10

Artem Vyshniakov


The "alert" should be embedded in a function:

<select data-bind="foreach: availableMeals, event: {change: function () {   alert('hello'); } }">
    <option data-bind="text: mealName " />
</select>
like image 36
gbs Avatar answered Oct 01 '22 02:10

gbs