jquery mobile in playbook, $(“select”).selectmenu(“refresh”, true) breaks on addClass error
-
28-06-2021 - |
Question
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
Solution 2
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".
OTHER TIPS
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" ) );
});
},
...