Muli
Muli

Reputation: 214

Search filter with KnockoutJS

I'm trying to implement the search filter in my web app. I read some good articles and i found some good Jsfiddles.

I want to search by TypeName and show the row with that typename. I implemented it in my model but i get and error when i search: main.js:48 Uncaught TypeError: item.TypeName is not a function also the screen error

My index.html:

<div class="form">
    <div class="form-group">
           <input type="search" class="form-control" data-bind="textInput: query" autocomplete="off" />
      </div>
    </div>

    <div id="tab1" class="col s12">
        <ul class="collapsible" data-collapsible="accordion" data-bind="foreach:brickInfos">
            <li  data-bind="with: value">
              <div class="collapsible-header">
                <i class="material-icons">view_stream</i>
                <p class="blue-text" data-bind="text: TypeName"></p>
              </div>
            </li>
        </ul>
    </div>

My model :

function ViewModel() {
  var self = this;
  self.brickInfos =  ko.observableArray([]);

  db.query("BrickInfos/docs").then(function(result) {
    var data = result;
    console.log(data);
    self.brickInfos(data.rows);
  });

  self.query = ko.observable("");
  self.filteredBrickInfos = ko.computed(function () {
      var filter = self.query().toLowerCase();

      if (!filter) {
          return self.brickInfos();
      } else {
          return ko.utils.arrayFilter(self.brickInfos(), function (item) {
              return item.data.TypeName().toLowerCase().indexOf(filter) !== -1;
          });
      }
  });
}

  var db = new PouchDB('http://localhost:5984/helloworld');
  var vm = new ViewModel();



  ko.applyBindings(vm);

This is how my data looks: Json data on console

Any good advice how i should structure my code is always welcome, cuz i'm new in KnockoutJS. Thank you

I posted the JSON here:

{
    "BrickInfos":  {
                       "BrickInfos":  [
                                          {
                                              "Properties":  {
                                                                 "Properties":  [

                                                                                ]
                                                             },
                                              "Implements":  {
                                                                 "Interfaces":  [
                                                                                    {
                                                                                        "TypeName":  "soemtypename"
                                                                                    },
                                                                                    {
                                                                                        "TypeName":  "soemtypename2"
                                                                                    }
                                                                                ]
                                                             },
                                              "Name":  "AccessBareBoneApp",
                                              "Description":  "",
                                              "TypeName":  "soemtypename",
                                              "AssemblyName":  "string other safasgfas",
                                              "Obsolete":  true
                                          },
                                          {
                                              "Properties":  {
                                                                 "Properties":  [
                                                                                    {
                                                                                        "Name":  "file",
                                                                                        "Description":  "asfasf",
                                                                                        "ValidationType":  12,
                                                                                        "Converter":  12,
                                                                                        "EnumTypeName":  "string1"
                                                                                    }
                                                                                ]
                                                             },
                                              "Implements":  {
                                                                 "Interfaces":  [
                                                                                    {
                                                                                        "TypeName":  "soemtypename"
                                                                                    },
                                                                                    {
                                                                                        "TypeName":  "soemtypename"
                                                                                    }
                                                                                ]
                                                             },
                                              "Name":  "File2",
                                              "Description":  "asfasfas",
                                              "TypeName":  "soemtypename",
                                              "AssemblyName":  "string other safasgfas",
                                              "Obsolete":  false
                                          }
                                          ]
                                        }
                                      }

Upvotes: 0

Views: 1708

Answers (1)

super cool
super cool

Reputation: 6045

You are getting item.TypeName undefined because inside computed you seem to access typeName with () notation which is not observable . Usually we un-wrap a observable using () which basically reads it's content .

viewModel :

 var self = this;
  self.brickInfos = ko.observableArray([]);
  self.brickInfos(json.BrickInfos);

  self.query = ko.observable("");
  self.filteredData = ko.computed(function() {
    var filter = self.query().toLowerCase();

    if (!filter) {
      return ;
    } else {
      return ko.utils.arrayFilter(self.brickInfos(), function(item) {
        return item.TypeName.toLowerCase().indexOf(filter) !== -1;
      });
    }
  });
}
var vm = new ViewModel();
ko.applyBindings(vm);

I have modified few stuff, you can see the working sample

var json = {
  "BrickInfos": [{
    "Properties": {
      "Properties": [

      ]
    },
    "Implements": {
      "Interfaces": [{
        "TypeName": "soemtypename"
      }, {
        "TypeName": "soemtypename2"
      }]
    },
    "Name": "AccessBareBoneApp",
    "Description": "",
    "TypeName": "soemtypename",
    "AssemblyName": "string other safasgfas",
    "Obsolete": true
  }, {
    "Properties": {
      "Properties": [{
        "Name": "file",
        "Description": "asfasf",
        "ValidationType": 12,
        "Converter": 12,
        "EnumTypeName": "string1"
      }]
    },
    "Implements": {
      "Interfaces": [{
        "TypeName": "soemtypename"
      }, {
        "TypeName": "soemtypename"
      }]
    },
    "Name": "File2",
    "Description": "asfasfas",
    "TypeName": "soemtypenameTest",
    "AssemblyName": "string other safasgfas",
    "Obsolete": false
  }]
}

function ViewModel() {
  var self = this;
  self.brickInfos = ko.observableArray([]);
  self.brickInfos(json.BrickInfos);

  self.query = ko.observable("");
  self.filteredData = ko.computed(function() {
    var filter = self.query().toLowerCase();

    if (!filter) {
      return  self.brickInfos();
    } else {
      return ko.utils.arrayFilter(self.brickInfos(), function(item) {
        return item.TypeName.toLowerCase().indexOf(filter) !== -1;
      });
    }
  });
}
var vm = new ViewModel();
ko.applyBindings(vm);
body {
  font-family: arial;
  font-size: 14px;
}

.liveExample {
  padding: 1em;
  background-color: #EEEEDD;
  border: 1px solid #CCC;
  max-width: 655px;
}

.liveExample input {
  font-family: Arial;
}

.liveExample b {
  font-weight: bold;
}

.liveExample p {
  margin-top: 0.9em;
  margin-bottom: 0.9em;
}

.liveExample select[multiple] {
  width: 100%;
  height: 8em;
}

.liveExample h2 {
  margin-top: 0.4em;
  font-weight: bold;
  font-size: 1.2em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="form">
  <div class="form-group">
    <input type="search" class="form-control" data-bind="textInput: query" autocomplete="off" />
  </div>
</div>

<div id="tab1" class="col s12">
  <ul class="collapsible" data-collapsible="accordion" data-bind="foreach:filteredData">
    <li>
      <div class="collapsible-header">
        <i class="material-icons">view_stream</i>
        <p class="blue-text" data-bind="text: TypeName"></p><br>
      </div>
    </li>
  </ul>
</div>

Upvotes: 1

Related Questions