jQuery Mobile Popup and ListView, and Knockout.js Data Binding Inside the Popup div - Not Working

2,641 views
Skip to first unread message

gsr...@gmail.com

unread,
Nov 1, 2012, 3:46:53 PM11/1/12
to knock...@googlegroups.com
Hello.  I’m working on a mobile website using jQuery Mobile and knockout.js.  I have a (kind of) complex scenario with jQuery Mobile’s popup and listview and knockout data binding inside the popup div, and I can’t get it working.

I have a nested list of alarms as shown below.  For each day, it creates a list-divider row.  Then inside each day, each alarm has a row.

<ul id="alarmslist" data-bind="foreach: days" data-role="listview">
    <li data-role="list-divider"><span data-bind="text: date"></span></li>
    <!-- ko foreach: alarms1 -->
    <li>
        <a href="#popupBasic" data-rel="popup"><span data-bind="text: alarmName"></span></a>
        <section id="popupBasic" data-role="popup" data-corners="true" data-history="false" data-overlay-theme="a">
            <a href="#" class="ui-btn-right" data-icon="delete" data-iconpos="notext" data-rel="back" data-role="button" data-theme="c">Close</a>
            <ul data-role="listview" data-inset="true">
                <li data-role="divider" data-theme="a">Alarm Options</li>
                <li><section class="alarmDetail"><span data-bind="text: alarmID"></span></section></li>
                <li><a href="#">Go to Data</a></li>
                <li><a href="#">Acknowledge</a></li>
            </ul>
        </section>
    </li>
    <!-- /ko -->
</ul>

I’m needing to attach the popup widget to the alarm row such that when the li row is clicked the popup appears with a list of option for that row.  This should be available for each row.  The options for each row will depend on the alarmID key.

This is where the problem occurs.  I’m trying to data bind the alarmID field (which is part of the alarms1 array) so that the next operation knows what to do with the correct alarm.  However, I get a knockout error because it cannot find the alarmID (<span data-bind="text: alarmID"></span>).  I guess jQuery Mobile is creating the popup section at the bottom of the DOM, well below where my view and viewmodel are defined for the knockout piece.

Anyway, does anyone have any ideas how to “fix” this situation?  Or, know of a work-around?  Or, even some other solution?

Denys Khanzhiyev

unread,
Nov 1, 2012, 6:41:48 PM11/1/12
to knockoutjs
Try to build fiddle demonstrating the problem. I think that would not work anyway - as foreach will produce many popup sections with same id.
So you should generate section IDs dinamically, and also maybe setting data-role="popup" with attribute binding will help, but may produce another problem that your page will be flooded with hidden popup sections as alarms1 will be updated.


2012/11/1 <gsr...@gmail.com>

gsr...@gmail.com

unread,
Nov 1, 2012, 7:07:25 PM11/1/12
to knock...@googlegroups.com
Hi Denis.
Thanks for the info.  Your ideas almost worked.  I'm not getting the binding errors and I'm able to click the "Go to Details" li in the popup section and the app navigates to the correct alarm details page.  Here's my updated code snippet.


<ul id="alarmslist" data-bind="foreach: days" data-role="listview">
    <li data-role="list-divider"><span data-bind="text: date"></span></li>
    <!-- ko foreach: alarms1 -->
    <li>
        <a data-bind="attr: { href: '#popupBasic' + alarmID(), 'data-rel': 'popup' }"><span data-bind="text: alarmID"></span></a>
        <section data-bind="attr: { id: 'popupBasic' + alarmID(), 'data-role': 'popup' }" data-corners="true" data-history="false" data-overlay-theme="a">

            <ul data-role="listview" data-inset="true">
                <li data-role="divider" data-theme="a">Alarm Options</li>
                <li><section class="alarmDetail">Go to Details for <span data-bind="text: alarmID"></span></section></li>

                <li><a href="#">Go to Data</a></li>
                <li><a href="#">Acknowledge</a></li>
            </ul>
        </section>
    </li>
    <!-- /ko -->
</ul>

The only problem is that I lose the actual popup functionality.  That is, all list items and sub-list items are always shown.  The popup section is not hidden until the popup link is clicked, like what would normally happen.

Any further thoughts?

Thanks again for the info.  It's pretty close (I think).

Denys Khanzhiyev

unread,
Nov 1, 2012, 7:48:32 PM11/1/12
to knockoutjs
Try 
 <!-- ko foreach: alarms1, afterRender: alarmsPostProcess  -->

and in viewmodel;
vm.alarmsPostProcess  = function(elements){
  $(elements).filter('section').popup();
}


2012/11/2 <gsr...@gmail.com>

gsr...@gmail.com

unread,
Nov 2, 2012, 12:25:36 PM11/2/12
to knock...@googlegroups.com
Hi again Denis.  Thanks for helping out and providing me with some suggestions.  Unfortunately, it's still not working.  After implementing your latest suggestions, I'm getting the popup sections always displayed and the elements argument in the viewmodel's function is always undefined (so, of course, it never finds any section elements to call the popup method).

I really liked the idea of having users click on an alarm in the list, getting the popup with addition options, and then having the user click on an option on the popup to perform some action (based, of course, on the original alarm selected in the list), but I'm under a pretty strict deadline to get this project wrapped up, so I might have to look at other options now.

Thanks again.  If you have any further ideas, let me know.  I appreciate it.

Denys Khanzhiyev

unread,
Nov 2, 2012, 1:39:51 PM11/2/12
to knockoutjs
I have built fiddle http://jsfiddle.net/xQ9Uu/1/

Popup works but bindings inside popup do not.

Maybe with fiddle somebody will suggest something,

I would try other templating engine - without bindings inside template.


2012/11/2 <gsr...@gmail.com>

Denys Khanzhiyev

unread,
Nov 2, 2012, 2:06:29 PM11/2/12
to knockoutjs
with jq.tmpl - jqmmobile elements styling is lost...
now works http://jsfiddle.net/xQ9Uu/2/ with native engine
but should be carrefully used on real page


2012/11/2 Denys Khanzhiyev <xde...@gmail.com>

Denys Khanzhiyev

unread,
Nov 2, 2012, 2:14:20 PM11/2/12
to knockoutjs
here is correct variant
http://jsfiddle.net/xQ9Uu/3/

conslusion:
1. apply popup in afterRender,
2. apply bindings explicitly to elements to avoid error.


2012/11/2 Denys Khanzhiyev <xde...@gmail.com>

gsr...@gmail.com

unread,
Nov 2, 2012, 3:17:03 PM11/2/12
to knock...@googlegroups.com
Whoa Denis that's awesome!  It works!  I needed to go with your second fiddle (http://jsfiddle.net/xQ9Uu/2/) because I needed the whole alarm object from the alarms1 collection to be bound.  My example of simply binding the alarmID to a span (<span data-bind="text: alarmID"></span>) was just for discussion purposes.  Your viewmodel code:

alarmsPostProcess: function(e,z){
var p = $(e).find('section').eq(0).popup();
p.attr('id','popupBasic'+z.alarmID() );
ko.applyBindings(z,p[0]); 
return true;
}

gets the correct alarm, binds it up, and makes it available to the functionality behind the options in the popup list.

So, wow, that's great!  Thank you so much!  I'll continue on from here and see how it goes.
Reply all
Reply to author
Forward
0 new messages