I'm developing a tablet application with the jquery.mobile-1.0rc3 version. Previoulsy, I used the jquery.mobile-1.0a4.1 version on another application, and it was possible to refresh a listview by doing myListview.listview( "refresh" ).
I'm having some problems doing the same with the new jquery.mobile-1.0rc3 version. Is it possible to do that with the new jquery.mobile-1.0rc3 version?
Thank you very much.
Here's a bit of the code:
var lists = $( '#posicaoIntegradaActivosList, #posicaoIntegradaPassivosList, #posicaoIntegradaOutrosList' );
lists.empty();
/* Fill the lists with jquery template */
lists.listview( "refresh" );
Error:
uncaught exception: cannot call methods on listview prior to
initialization; attempted to call method 'refresh'
Depending on when your code runs it may be running before the jQuery Mobile initialization process. jsFiddle by default runs code after the load event fires so the DOM is all setup and jQuery Mobile has done its initialization. If you change #Phill Pafford's jsFiddle (http://jsfiddle.net/qSmJq/3/) to run on "no wrap (body)" rather than "onLoad" then you get the same error you are reporting. So I recommend either removing the lists.listview('refresh'); line or putting your code inside either a document.ready or a pageshow/pagecreate event handler:
var lists = $( '#posicaoIntegradaActivosList, #posicaoIntegradaPassivosList, #posicaoIntegradaOutrosList' );
lists.empty();
/* Fill the lists with jquery template */
//lists.listview( "refresh" );
Here's a jsfiddle for running the code as soon as it is parsed by the browser: http://jsfiddle.net/jasper/qSmJq/5/
Or:
$(function () {
var lists = $( '#posicaoIntegradaActivosList, #posicaoIntegradaPassivosList, #posicaoIntegradaOutrosList' );
lists.empty();
/* Fill the lists with jquery template */
lists.listview( "refresh" );
}
Here is a jsfiddle for wrapping your code in a document.ready event handler: http://jsfiddle.net/jasper/qSmJq/4/
Or:
$('#my-page-id').on('pagecreate', function () {
var lists = $( '#posicaoIntegradaActivosList, #posicaoIntegradaPassivosList, #posicaoIntegradaOutrosList' );
lists.empty();
/* Fill the lists with jquery template */
//lists.listview( "refresh" );
}
Here is a jsfiddle for using the pageshow event: http://jsfiddle.net/jasper/qSmJq/6/
And here is a jsfiddle for using the pagecreate event: http://jsfiddle.net/jasper/qSmJq/7/
On a side note: if you want to detect whether or not jQuery Mobile has initialized a certain element you can check for the jQuery Mobile specific classes on the element:
$(function () {
//cache lists
var lists = $( '#posicaoIntegradaActivosList, #posicaoIntegradaPassivosList, #posicaoIntegradaOutrosList' );
//iterate through the lists
lists.each(function (index, value) {
//cache this specific list
var $value = $(value);
/*add rows to this listview here*/
//check if the listview has been initialized by jQuery Mobile by checking for the existence of the `ui-listview` class
if ($value.hasClass('ui-listview')) {
//since the class was found, refresh the already initialized element
$value.listview('refresh');
} else {
//the class was not found, so initialize the widget
$value.trigger('create');
}
});
});
Related
I have the following jQuery code that adjusts the product grid on the Window Load event:
$j(window).load(function(){
// Remove list class if thumbview
if ( $j("ul#products-list").hasClass("thumb_view") ) {
$j("ul#products-list").removeClass("list") };
// Equalize all thumb heights on switch if list view default
var maxHeight = 0;
$j('ul.thumb_view div.product-container').each(function() { maxHeight = Math.max(maxHeight, $j(this).height()); }).height(maxHeight +8);
// Undo equalized heights for list
$j('ul.list div.product-container').css("height","auto");
});
On the page we have a way of filtering the products based on for example price. When the price range is adjusted by the customer an AJAX call takes care of the actual filtering of products. However the jQuery script is not run again and the product grid fails to load correctly. I've done a lot of research and found to solutions that could solve this issue; use an "m-ajax-after" event, or use a jQuery delegate function.
The first option would involve this piece of code:
jQuery(document).bind('m-ajax-after', function (e, selectors, url, action) {
// reinitialize your script
});
Which I haven't managed to get it working. Knowledge on this function is very limited.
In my opinion the second option has the most chance on actual success however I haven't been able to reproduce this into code that actually works. Many topics are to be found I just can combine this with the (window).load function. What would be the right way to do this?
It's hard to say without seeing the complete code, but here's an idea:
function formatGrid() {
// Remove list class if thumbview
if ( $j("ul#products-list").hasClass("thumb_view") ) {
$j("ul#products-list").removeClass("list") };
// Equalize all thumb heights on switch if list view default
var maxHeight = 0;
$j('ul.thumb_view div.product-container').each(function() { maxHeight = Math.max(maxHeight, $j(this).height()); }).height(maxHeight +8);
// Undo equalized heights for list
$j('ul.list div.product-container').css("height","auto");
}
$j(window).load(function(){
formatGrid();
});
And then call this function on Ajax success:
$.ajax({
//your current ajax code
//and then call the formatting function
success: function() {
formatGrid();
}
});
I just recently started working with jQuery Mobile. I ran into a issue that I don't get quite yet.
I got this code. What it does is that it triggers the toggle twice. One for jQuery and the other for jQuery Mobile (works as expected when removing reference to jQM). Any ideas on how to avoid this for use with Mobile? Adding namespace...?
var navigation = $main_nav.find("[data-toggle-id='" + target + "']");
navigation.toggle(200, function() {
console.log('toogle');
});
EDIT
Demo: http://jsfiddle.net/4mpdR/4/
I don't get the same behaviour here but this is basically my setup.
Edit2
$(function () {
$(document).on('click', '.nav__toggle', function () {
var $main_nav = $('.main-nav');
var target = $(this).data('target');
var navigation = $main_nav.find("[data-toggle-id='" + target + "']");
navigation.toggle(200, function() {
console.log('toogle');
});
});
});
Edit3
It's just a <nav>. looking in the console I see that it triggers twice and one time it has the reference to my actual .js file, second is the VM[number], removing jQuery Mobile eliminates the VM.
[nav.main-nav__collapse.clearfix, prevObject: jQuery.fn.jQuery.init[1], context: document, selector: ".main-nav [data-toggle-id='main-nav__collapse']", constructor: function, init: function…]
0: nav.main-nav__collapse.clearfix
context: document
length: 1
prevObject: jQuery.fn.jQuery.init[1]
selector: ".main-nav [data-toggle-id='main-nav__collapse']"
__proto__: Object[0]
First you find out user agent(iphone,android,blackberry,webos) then you can separate the event of different platform
$.browser.device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
now $.browser will return "device" for all above devices
I have a working setup for data-tables and x-editable that allows a user to edit data inline in a table that gets loaded from the database. Once the page loads my code below fires and makes all the editable options editable, except it only seems to work for the first page of results. When you click next, change the number of results or do a search, any items that were not on the first page don't get made editable. I am assuming this is because data-tables hides the data that is not on the current page removing it from the document flow. How can I make sure all my data in the table is editable?
$(document).ready(function () {
$.fn.editable.defaults.mode = 'inline';
$('.LocatorID').editable();
$('.Title').editable();
$('.Latitude').editable();
$('.Longitude').editable();
$('.Website').editable();
$('.Address').editable();
$('.City').editable();
$('.State').editable();
$('.Zip').editable();
$('.Country').editable();
$('.Phone').editable();
});
First, move your x-editable setup into its own function:
function setupXedit() {
$.fn.editable.defaults.mode = 'inline';
$('.LocatorID').editable();
$('.Title').editable();
...
}
Then set so that you call the function on every draw:
$('#example').dataTable({
"fnDrawCallback": function( oSettings ) {
setupXedit();
}
});
Do like this: one $('.edit').editable(); inside Datatable fnDrawCallback and one outside .Datatable function
var table = $('#tbldivdsthietlap').DataTable({
"fnDrawCallback": function( oSettings ) {
$('.edit').editable();
}
});
$('.edit').editable();
So I am trying to keep all my functions in 1 jQuery file. Still learning jQuery btw
However I'm running into problems where a div id doesn't exist on a different page and it throws and error. I use the Pop Easy modal plugin. I call $('.modalLink').modal() to initialize the plugin. It works on my home page, but will raise error on my FAQ page because there is no div with modalLink class.
I don't want to create separate files, so how would you re-write this?
$(document).ready(function () {
// PopEasy on Home Page
$('.modalLink').modal({
trigger: '.modalLink', // id or class of link or button to trigger modal
olay:'div.overlay', // id or class of overlay
modals:'div.modal', // id or class of modal
animationEffect: 'fadeIn', // overlay effect | slideDown or fadeIn |
videoClass:'video', // class of video element(s)
close:'.closeBtn' // id or class of close button
});
/*... other code for other pages go below ....*/
// Register Page
$('.login-window input').on('click focusin', function() {
this.value = '';
});
// FAQ Page
// FAQ sidebar menu
$('#faq-btn-general').click(function() {
$(this).parent().addClass('faq-blue');
$('#img-general-on').show();
$('#img-general-off').hide();
$('#dl-general').fadeToggle("slow", "linear");
});
});
If there is no method .modal(), then that is probably because you don't have the proper library loaded to support the .modal() method.
For a well behaved jQuery method (which I assume .modal() is), there should be no problem with:
$('.modalLink').modal();
if the .modalLink object doesn't exist. The $('.modalLink') jQuery object will be empty and calling .modal() on it will just do nothing (or that's how jQuery methods are supposed to be written anyway). If the .modal() method is not well behaved, then you can protect it yourself with this:
// makes sure the .modalLink object exists and that the `.modal()` method exists
var modalObj = $('.modalLink');
if (modalObj.length && modalObj.modal) {
modalObj.modal(...);
}
I would recommend checking to see if the objects exist before adding events to them
You can do so with this.
if ( $('#myDiv').length ){}
So to replace some of your code it would look like this
if ( $('.login-window input').length ){
$('.login-window input').on('click focusin', function() {
this.value = '';
});
}
You can test is method exists such as
if ($.fn.modal) {
$('.modalLink').modal({
trigger: '.modalLink', // id or class of link or button to trigger modal
olay:'div.overlay', // id or class of overlay
modals:'div.modal', // id or class of modal
animationEffect: 'fadeIn', // overlay effect | slideDown or fadeIn |
videoClass:'video', // class of video element(s)
close:'.closeBtn' // id or class of close button
});
}
But that can be long.... You can also add an ident class on the body that you check in the javascript file.
if ($('body').hasClass('forum-section')) {
// Include code concerning that section only
}
Hope that helped
try something like:
if ( $('.myClass').length > 0){
$('.myClass').modal(....)
}
I'm making a website that uses a Javascript sorter. In addition to the sorter, I also put in some custom javascript, to make certain div's clickable. My reasoning was that using the property just couldn't do all that we wanted it to do, so I stuck with divs, and used javascript to make them function.
Take a look here --
http://www.opohills.com/taipei-rentals.php
You can scroll down to where you see the search bar, and click on one of the apartments. When you go back click (1 bedroom), you'll see that clicking on the apartments doesn't work anymore.
I'm not quite sure what to make of this at all. The javascript for the clickability is at the bottom of the page.
What are your thoughts on this?
Here's my javasscript
<script type='text/javascript'>
$(".box_1").click(function(){
window.location=$(this).find("a").attr("href");
return false;
});
$(".box_2").click(function(){
window.location=$(this).find("a").attr("href");
return false;
});
$(".box_3").click(function(){
window.location=$(this).find("a").attr("href");
return false;
});
$(".apt2").click(function(){
window.location=$(this).find("a").attr("href");
return false;
});
</script>
Thoughts?
UPDATE
In accordance to the suggestions, I've updated the code by moving the javascript for clickability above jquery.quicksand, and initiated it only after the document was ready.
Even with these changes, I'm still having trouble getting it to work.
The latest version of the site can be seen here---
http://www.opohills.com/taipei-rentals.php
Your thoughts greatly appreciated
the script basically works for me (and should for you). your problem is probably that sometimes your dom is not ready:
$(document).ready(function() {
// your code here
});
2 more things.
1.) add "cursor: pointer;" to your css for the clickable boxes (usability)
2.) just trigger the click of your link:
$(".apt2").click(function(){
$(this).find("a").trigger('click');
return false;
});
When I'm using the chorme built in debuger on your website, if I create custome fields like ID on you "li" tags, they are deleted after a filter. I think quicksand is creating a cache during the page loading. You are creating you .click() event only after the initialisation of the quicksand library and it is possible that theses click events are deleted because quicksand replaces your li tags.
Try to initialize your click like
$(function() {
$("#ourHolder li").click(function() { window.location.href=$(this).find('a').attr('href')});
});
You should add an id="ourHolder" to your ul tag to optimize the script speed.
And only after this initialisation start your quicksand object initialisation. Move your
<script src="js/jquery.quicksand.js"></script>
<script src="js/sorter-settings.js"></script>
after the previous click functions.
So you can try to edit our file sorter-settings.js and replace by this code (based on the documentation available here (http://razorjack.net/quicksand/docs-and-demos.html) :
$(document).ready(function() {
// get the action filter option item on page load
var $filterType = $('#filterOptions li.active a').attr('class');
// get and assign the ourHolder element to the
// $holder varible for use later
var $holder = $('ul#ourHolder');
// clone all items within the pre-assigned $holder element
var $data = $holder.clone();
// attempt to call Quicksand when a filter option
// item is clicked
$('#filterOptions li a').click(function(e) {
// reset the active class on all the buttons
$('#filterOptions li').removeClass('active');
// assign the class of the clicked filter option
// element to our $filterType variable
var $filterType = $(this).attr('class');
$(this).parent().addClass('active');
if ($filterType == 'all') {
// assign all li items to the $filteredData var when
// the 'All' filter option is clicked
var $filteredData = $data.find('li');
}
else {
// find all li elements that have our required $filterType
// values for the data-type element
var $filteredData = $data.find('li[data-type=' + $filterType + ']');
}
// call quicksand and assign transition parameters
$holder.quicksand($filteredData, {
duration: 800,
easing: 'easeInOutQuad',
enhancement: function() {
$("#ourHolder li").click(function() { window.location.href=$(this).find('a').attr('href')});
}
}
);
return false;
});
});
Additinaly, I think that this code is useless on your html content.
<!--Begin Sorter-->
<script type='text/javascript'>
$(document).ready(function() {
$('#source').quicksand( $('#destination li') );
});
</script>