0

I have a list of records returned from the server for the last 24 months. There is a select menu where the user can select "Last 18 months", "Last 12 months" or "Last 24 months".

The default is 24 months, so when the user comes to the page for the first time, the full list is retrieved from the server. Now, without using a postback (thus saving a trip to the server), can I filter the data depending upon what the user selects from the select menu?

I am using ASP.NET MVC4 with jQuery mobile and knockout.js.

Table in the view (html):

        <table style="width:100%;">

<tbody data-bind="foreach: TankMixRows">
    <tr>
        <td data-bind="text: ProductName"></td>
        <td data-bind="text: AI"></td>
        <td></td>
        <td data-bind="text: MOAHerbicide"></td>
        <td data-bind="text: MOAInsecticide"></td>
        <td data-bind="text: MOAFungicide"></td>
    </tr>
</tbody>
    </table>

Javascript:

  function MOAViewModel() {
var self = this;

self.TankMixRows = ko.observableArray([]);

self.getTankMixRows = function () {
  $.ajax({
    type: "GET",
    url: '@Url.Action("jsonModeOfAction", "WorkOrders")',
    data: {
      ID: '@Model.RecFieldId'
    },
    success: function (data) {
      self.TankMixRows(data);
    }
  });
}

//Load initial state from server and populate viewmodel
self.getTankMixRows();
  }

  ko.applyBindings(new MOAViewModel());
WhatsInAName
  • 724
  • 2
  • 12
  • 32
  • 3
    The answer is yes - but what have you tried? Code to share? – viperguynaz Aug 17 '13 at 02:58
  • 1
    Code is always important to understand what you are trying to do, if you are looking for a recommendation check out using Computeds on top of your observable arrays for an easy way to do this. – PW Kad Aug 17 '13 at 12:46
  • Have not tried anything since I didn't think it was possible client side. That is why I asked this question. I will add the code if that helps. – WhatsInAName Aug 19 '13 at 21:45
  • Do you have a date field in the data you send to the client? Can you show us the model? – TheGwa Aug 19 '13 at 22:26
  • No, right now I don't retrieve the date field, but I now understand that it is needed, I'll add it to the model. – WhatsInAName Aug 19 '13 at 22:29

1 Answers1

1

Firstly you will need the time in the client side model. Once you have that you will need options for your date filter. Bind this to an observable in the viewModel. Lets call it:

self.filterDateSelection = ko.observable(24);

Then you can make a computed array that filters the data:

self.filteredItems = ko.computed(function() {
    return ko.utils.arrayFilter(self.TankMixRows(), function(row) {
        // Filter logic here;
        // Return true if you want to keep the record
        // Use row.date and self.filterDateSelection()
        return true;

    });    
}

Bind your view to filteredItems instead.

Default DateTime serialization from MVC is likely to fight with you. Have a look at: Converting .NET DateTime to JSON


Update

Have a look at the following fiddle: http://jsfiddle.net/mrfunnel/9eaMY/

I have used Moment.js to help with dealing with javascript Date.

You can use the option binding mentioned above for month filters to keep logic within Knockout and simplify calculation of your filter range.

// Possible options
self.filterMonths = ko.observableArray([12, 18, 24]);
// Selected option
self.chosenFilter = ko.observable(24);

This is bound in the view as follows:

<p>Choose Month Filter:
    <select data-bind="options: filterMonths, value: chosenFilter"></select>
</p>

Now we can calculate the filterDate every time chosenFilter changes:

self.filterDate = ko.computed(function () {
    var d = moment().subtract('months', self.chosenFilter());
    return d;
});

The filteredItems can then be computed as follows:

self.filteredItems = ko.computed(function () {
    return ko.utils.arrayFilter(self.tankMixRows(), function (row) {
        // Filter logic here;
        // Return true if you want to keep the record
        return row.date > self.filterDate();
    });
});
Community
  • 1
  • 1
TheGwa
  • 1,919
  • 27
  • 44
  • Where can I find documentation on ko.utils.arrayFilter? Read http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html, didn't help. Also, why do I need options? Can't I call filteredItems in the "change" event of the select menu? – WhatsInAName Aug 20 '13 at 21:22
  • Sorry I am very new to knockoutjs. – WhatsInAName Aug 20 '13 at 21:46
  • Thanks for taking the time to explain things and for creating the demo. I really appreciate it! – WhatsInAName Aug 21 '13 at 23:16
  • No problem. Knockout is a bit tough to get your head around at first, but is really powerful once you get the hang of it. Good luck. – TheGwa Aug 22 '13 at 08:05
  • Thanks. I keep having so much problem whenever I try to work with jquery mobile and knockout together, and very few people helped me like you did. Thanks again! – WhatsInAName Aug 22 '13 at 20:15