0

I’m working on a project that is using knockout.js and jQuery Mobile. I have an observable array of observable properties. This observable array is getting populated with JSON data via an AJAX call to the server (Web API).

// ViewModel
my.vm = function () {
    var
    alarms = ko.observableArray([]),
    loadAlarmsCallback = function (json) {
        $.each(json.Alarms, function (i, p) {
            alarms.push(new my.Alarm()
                .AlarmID(p.AlarmID)
                .StartTime(my.utilities.formatDate(p.StartTime))
                .EndTime(my.utilities.formatDate(p.EndTime))
                .TimeAcknowledged(my.utilities.formatDate(p.TimeAcknowledged))
                .AcknowledgedBy(p.AcknowledgedBy)
                .AlarmType(p.AlarmType)
                .AlarmCategory(p.AlarmCategory)
                .AlarmPriority(p.AlarmPriority)
                .Message(p.Message));
        }),
    loadAlarms = function () {
        my.dataService.getAllAlarms(my.vm.loadAlarmsCallback);
    },
    ...;
    return {
        alarms: alarms,
        loadAlarmsCallback: loadAlarmsCallback,
        loadAlarms: loadAlarms,
        ...
    };
}();

my.vm.loadAlarms();
ko.applyBindings(my.vm);

As you can see, each row in the array in the viewmodel has a StartTime, which is actually a date and time that is getting formatted to MM/dd/yyyy HH:mm.

In my view (a jQuery Mobile enabled .cshtml file), I have a foreach binding for the array on ul/li tags.

<ul data-bind="foreach: alarms" data-role="listview" data-inset="true" data-theme="c">
    <!-- NEED ONLY ONE list-divider PER DAY -->
    <li data-role="list-divider"><span data-bind="text: StartTime"></span></li>
    <!-- NEED MULTIPLE li TAGS FOR EACH ALARM ON THAT DAY -->
    <li>
        <p><span data-bind="text: AlarmCategory"></span></p>
        ...
    </li>
</ul>

What I need is only one list-divider row per day to be displayed with all the individual alarm rows on that day to be grouped under that list-divider row. When the day changes (based on the StartTime value in the viewmodel’s observable array), a new list-divider row is created and displayed with that day’s alarms underneath it.

Anyway, how can I code this scenario? Any ideas?

Thanks.

lmttag
  • 2,499
  • 4
  • 26
  • 30

1 Answers1

0

One way to do it is making a computed observable alertsPerDay which builds an array where each element corresponds to one day. The element's value is an object containing the date (because you want to show it in the view) and a nested array of alarms which belong to that day. Then in the HTML you can have a nested foreach for each day's alarms. It's not trivial to build but it's not too complex either.

Here's a simple example of how to do that: http://jsfiddle.net/antishok/KXhem/49/

The main idea is that you can represent your data in the way that's most suitable for your views, and then the KO bindings themselves are trivial.

antishok
  • 2,910
  • 16
  • 21
  • That looks great! And should be very helpful. I'll try implementing it in my project right away and see how it goes. Thanks again. – lmttag Oct 02 '12 at 13:38