Pieter VDE
Pieter VDE

Reputation: 2235

Update text data-bind on select value change using Knockout

I'm trying to create a query block which the user can use to search for a person by age. You can either search for persons with any age, persons younger/older than a certain age, or between two ages.

Here's a fiddle of the current state: JSFiddle

The input fields hide and show as wanted, no problem there.
What I'd like to achieve is that the text in the header (containing the current search query in words, e.g. (current: any/younger than/older than/ between .. and ..)) changes too when I change the value of the select field.

So when the select changes, the text value in the header should automatically reset to (current: any).

Here's my current (simplified) code (full code can be found in the fiddle):

<h2>Age&nbsp;<small>(current: <span data-bind="text: ageRange"></span>)</small></h2>

<select data-bind="value: age">
    <option value="0">Any</option>
    <option value="1">Younger than</option>
    <option value="2">Older than</option>
    <option value="3">Between</option>
</select>
<div data-bind="visible: age() == 1">
    <input type="number" data-bind="value: ageHigh" />
</div>
<div data-bind="visible: age() == 2">
    <input type="number" data-bind="value: ageLow" />
</div>
<div data-bind="visible: age() == 3">
    <div>
        <input type="number" data-bind="value: ageLow" />
    </div>
    <p>and</p>
    <div>
        <input type="number" class="form-control" data-bind="value: ageHigh" />
    </div>
</div>

JS:

function QueryViewModel() {
    var self = this;
    self.ageLow = ko.observable('');
    self.ageHigh = ko.observable('');
    self.age = ko.observable('');

    self.ageRange = ko.computed(function () {
        var range = 'any';
        if (self.ageLow() != '' && self.ageHigh() == '') {
            range = "older than " + self.ageLow();
        } else if (self.ageLow() == '' && self.ageHigh() != '') {
            range = "younger than " + self.ageHigh();
        } else if (self.ageLow() != '' && self.ageHigh() != '') {
            return "between " + self.ageLow() + " and " + self.ageHigh() + " years old";
        }
        return range;
    }, this);
}

$(document).ready(function () {
    var qvm = new QueryViewModel();
    ko.applyBindings(qvm);
});

Any ideas? Much appreciated.

Sidenote: I'm using Twitter Bootstrap for the CSS.

Upvotes: 0

Views: 1538

Answers (1)

nemesv
nemesv

Reputation: 139758

You just need to reset your ageHigh and ageLow properties to their defaults when the age property changes and your ageRange will automatically update your text.

You can use the subscribe function to listen on the changes of the age do to the "reset" in the handler:

self.age.subscribe(function () {
    self.ageLow('');
    self.ageHigh('');
});

Demo JSFiddle.

Upvotes: 1

Related Questions