1

I need some help here: https://jsfiddle.net/vhaurnpw/

I want to do a simple list, which is filterable by the input on top and updates itself..

JS/Knockout:

var viewModel = {
    query: ko.observable(''),
    places: ko.observable(data),

    search: function(value) {
        viewModel.places = [];
        console.log(value)

        for (var i = 0; i < data.length; i++) {

            if(data[i].name.toLowerCase().indexOf(value.toLowerCase()) >= 0) {
                viewModel.places.push(data[i]);
            }
                console.log(viewModel.places);
        }
    }
};

viewModel.query.subscribe(viewModel.search);

ko.applyBindings(viewModel);

HTML:

<form acion="#" data-bind="submit: search">
<input placeholder="Search" type="search" name="q" data-bind="value: query, valueUpdate: 'keyup'" autocomplete="off">
</form>

<ul data-bind="foreach: places">
  <li>
     <span data-bind="text: name"></span>
  </li>
</ul>

List will be rendered, but it when you type something, it doesn't show you the result.

Instead when you lookup the console, you will see the console.log and it updates just fine!

so how do i refresh my HTML? :(

2
  • 1
    You set observables by calling them. This line viewModel.places = []; needs to be viewModel.places([]). Commented Feb 22, 2017 at 16:58
  • thank you! that and the observableArray got it to work! Commented Feb 23, 2017 at 9:41

1 Answer 1

2

There are following issues in your code.

  1. places needs to be an ObservableArray and not an Observable so that you can track the addition/removal from the Observable Array. So, change code From places: ko.observable(data) To places: ko.observableArray(data),
  2. viewModel.places is function, so when you assign another value like viewModel.places = [], it is assigning an empty array to the viewModel.places. In order to modify the value of the viewModel.places, you need to call it as a function like viewModel.places([]);

Note: Your code doesn't add the data back in case the textbox is cleared, I hope you got the solution to the problem and you can resolve this issue as well.

Complete Working Code:

var data = [
			{ name: 'Isartor'},
			{ name: 'Sendlinger Tor'},
			{ name: 'Marienplatz'},
			{ name: 'Stachus'},
			{ name: 'Bayerischer Rundfunk'},
			{ name: 'Google München'},
			{ name: 'Viktualienmarkt'},
			{ name: 'Museumsinsel'},
			{ name: 'Tierpark Hellabrunn'},
			{ name: 'Allianz Arena'},
			{ name: 'Olympia-Park'},
			{ name: 'Flaucher-Insel'}
					];

var viewModel = {
		query: ko.observable(''),
		places: ko.observableArray(data),

		search: function(value) {
			viewModel.places([]);
			console.log(value)

			for (var i = 0; i < data.length; i++) {

				if(data[i].name.toLowerCase().indexOf(value.toLowerCase()) >= 0) {
					viewModel.places.push(data[i]);
				}
					console.log(viewModel.places);
			}
		}
};

viewModel.query.subscribe(viewModel.search);

ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<form acion="#" data-bind="submit: search">
  <input placeholder="Search" type="search" name="q" data-bind="value: query, valueUpdate: 'keyup'" autocomplete="off">
</form>

<ul data-bind="foreach: places">
    <li>
      <span data-bind="text: name">asd</span>
    </li>
</ul>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.