0

I'm using jquery mobile and run into an issue with blackberry playbook. I have pages that I'm loading dynamically through jquery In jquery mobile with the $.mobile.changePage('/full/url/to/page');

When the page loads, I capture the pageinit event and you can see below what i'm working on...

<div id="Page1">
<select id="selectId">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
</div>
...

$("#Page1").live('pageinit', function () {

  $("#selectId").val("1");
  $("#selectId").selectmenu("refresh", true);
});

This works fine in iOS, chrome, android, etc... except blackberry playbook.

In playbook, after attaching the Web Inspector I get this javascript error which looks like the jquery libraries aren't loading when it's trying to reformat the select object...

TypeError: Result of expression 'span.text( text ).addClass' [undefined] is not a function.
code.jquery.com/mobile/latest/jquery.mobile.js:8107

(as per instructions from: http://jquerymobile.com/demos/1.1.1/docs/api/events.html)

Also, I notice when I try this on my main Index page, and load it into the document pageinit, it works perfectly fine.

$(document).bind("pageinit", function () {
    $("#test").val("2");
    $("#test").selectmenu("refresh", true);
});

If you can shed some light on why my "live" event isn't working, please let me know.

(I'm aware live was deprecated in 1.7, but I haven't found any docs on what else to use for jquery mobile with ajax page calls)

Thanks

sonjz
  • 4,870
  • 3
  • 42
  • 60

2 Answers2

2

What you're looking for are delegated event handlers. $([selector]).live([event], [callback]) is the same as $(document).on([event], [callback]). Basically .live() sets-up a delegated event handler on the document element. Using .on() (jQuery 1.7+) or .delegate() (jQuery 1.4.2+) gives the added benefit that you can choose the root element (the element that must always be present in the DOM) which allows your code to perform faster.

jQuery 1.7+:

$(document).on("pageinit", "#Page1", function () {
    $(this).find("#selectId").val("1").selectmenu("refresh", true);
});

Docs: http://api.jquery.com/on

jQuery 1.4.2+

$(document).delegate("#Page1", "pageinit", function () {
    $(this).find("#selectId").val("1").selectmenu("refresh", true);
});

Docs: http://api.jquery.com/delegate

Side Note: If you are using jQuery 1.7+, .delegate() and .live() are simply shortcuts that utilize the new .on() method.

UPDATE

Here is the code block associated with line 8107 in http://code.jquery.com/mobile/latest/jquery.mobile.js:

...
setButtonText: function() {
    var self = this,
        selected = this.selected(),
        text = this.placeholder,
        span = $( document.createElement( "span" ) );

    this.button.find( ".ui-btn-text" ).html(function() {
        if ( selected.length ) {
            text = selected.map(function() {
                return $( this ).text();
            }).get().join( ", " );
        } else {
            text = self.placeholder;
        }

        // TODO possibly aggregate multiple select option classes
        return span.text( text )
            .addClass( self.select.attr( "class" ) )//line 8107 right here
            .addClass( selected.attr( "class" ) );
    });
},
...
Jasper
  • 75,717
  • 14
  • 151
  • 146
  • Thanks Jasper, I just found the delegate function a couple minutes ago and changed my live statement. No change in behaviour, still receiving the same issue with blackberry playbook and the javascript error. – sonjz Aug 24 '12 at 20:09
  • I've moved all events to "on" as you suggested, being the rest are shortcuts, thanks for the info... but anyone on the playbook javascript only error? – sonjz Aug 24 '12 at 20:20
  • I wonder what the `text` variable is just before the `return ...` line in the code I just posted. That seems important because it's the line after `text` is used that the error occurs. – Jasper Aug 24 '12 at 20:38
  • hmm.. i think you're on to something. prior to calling the refresh i call `$.each(JSON.parse($("#jsonresult").val()), function() { $("#searchDate").append($("").val(this.Value).text(this.Name)); });` i took out the $.each statement just to check, and the error disappeared.. doing some more investigation. – sonjz Aug 24 '12 at 20:51
  • Is `this.name` ever `null` or `undefined`? – Jasper Aug 24 '12 at 21:12
  • i'm thinking when the $.each is appending the options, there may be a timing issue and when i run the selectmenu("refresh", true), the option hasn't been created yet.. i guess there isn't way to "commit" or "flush" the changes prior to this running? – sonjz Aug 24 '12 at 21:15
  • my select has the name defined... ` – sonjz Aug 24 '12 at 21:21
  • I just noticed in the code you pasted a few comments ago that you are using `this.Name`, with a capital `N`. If that's part of your actual code you'll want to change it to `this.name` as I believe that attributes are case-sensitive in JS (they are not in the actual HTML). – Jasper Aug 24 '12 at 21:41
  • Hi Jasper, that's not the issue, you'll see that it's coming from my json result were i defined the object to have Name and Value captialized, it's not trying to access a dom attribute. The issue is definitely to do with timing, or something not being set when using the playbook browser.. – sonjz Aug 27 '12 at 14:29
  • thanks for the help, but i'm not sure if we're going to fix this one... i think it's something to do with jquery.mobile and playbook specifically.. – sonjz Aug 27 '12 at 14:55
  • You've posted very incomplete code, there's no way to tell what you're really doing with what piece of code. I'd recommend taking another whack at creating a question that includes all relevant code. – Jasper Aug 27 '12 at 15:38
0

Figured it out, own fault. In the followwing scenario, imagine you are trying to set a value that doesn't exist in the options...

<div id="Page1">
<select id="selectId">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
</div>
...

$("#Page1").live('pageinit', function () {

$("#selectId").val("notHere");
  $("#selectId").selectmenu("refresh", true);
});

jquery breaks in this scenario. Lesson learnt, always check the whitelist of options prior to running the "refresh".

sonjz
  • 4,870
  • 3
  • 42
  • 60