Catalin
Catalin

Reputation: 11731

Jquery Knockout - get element instance inside data-bind attribute

I have a select element where i bind the css class using Jquery Knockout.

I want to access the current element instance directly from data-bind attribute, without creating a property in the ViewModel (because i have many select elements which shares the same functionality)

Is this possible?

<select id="select1" data-bind="css: { 'no-value-selected': $item.val() == '' }">
    <option value="">[Select a value]</option>
    <option value="1">1</option>
    <option value="2">2</option>
</select>

EDIT Using ViewModel to achieve this (what i want to avoid)

function ViewModel() {
    this.select1HasNoValueSelected = ko.computed(function () {
        return $("#select1").val() == '';
    }, this);
};
var viewModel = new ViewModel();
ko.applyBindings(viewModel);

<select id="select1" data-bind="css: { 'no-value-selected': select1HasNoValueSelected }">

Upvotes: 3

Views: 5610

Answers (2)

nemesv
nemesv

Reputation: 139798

You are on the wrong track with the css binding because if you are not using observables it won't update your class if the value of your select is changes.

However you can (miss)use the event binding and subscribe on the change event:

<select id="select1" class="no-value-selected" data-bind="event: { 'change': 
function() { $($element).val() == '' ? 
             $($element).addClass('no-value-selected') : 
             $($element).removeClass('no-value-selected') } }">
    <option value="">[Select a value]</option>
    <option value="1">1</option>
    <option value="2">2</option>
</select>

Demo JSFiddle. (second drop-down)

But the best solution is to not fight against KnockOut and have properties for each select on your view model:

function ViewModel() {    
    this.select1Value = ko.observable()
};

<select id="select1" data-bind="css: { 'no-value-selected': !select1Value() }, 
                                value: select1Value">
    <option value="">[Select a value]</option>
    <option value="1">1</option>
    <option value="2">2</option>
</select>

Demo JSFiddle. (third drop-down)

Or don't use Kncokout for this function at all.

Upvotes: 3

Denis G.
Denis G.

Reputation: 129

You can try to use $element instead of $item:

<select data-bind="css: { 'no-value-selected': $element.val() == '' }">
    <option value="">[Select a value]</option>
    <option value="1">1</option>
    <option value="2">2</option>
</select>

Docs: http://knockoutjs.com/documentation/binding-context.html

Upvotes: 1

Related Questions