0

I am using jQuery Mobile's PageShow event to set the width of certain input elements. If I load the page directly (i.e. through the URL) everything works as expected.

If I load the page through the standard ajax navigation system (i.e. an in-app link), I get the 'hello' alert and the correct width of the 'span.add-on', but the 'div.content-padd' element gets a width of zero? The 'div.content-padd' is a container element for all the other elements in the page and gives them some padding etc. All JS is loaded in the of my Rails layout template.

I don't know what is going on here. My code is as per below:

$(document).bind('pageshow', function() {

alert('hello')

    $('.add-on').addClass('ui-corner-all');

    //Set the width of the input following the appends or prepends to the remaining space
    var containerWidth = $('div.content-padd').width();
    console.log('container width:' + containerWidth);

    var appendsAndPrepends = '.input-prepend, .input-append';
    $(appendsAndPrepends).each(function () {
        var remainingSpace = containerWidth - $(this).find('span.add-on').outerWidth();
        console.log('span width' + $(this).find('span.add-on').outerWidth());

        $(this).find('div.ui-input-text').outerWidth(remainingSpace);
    });

});
Lee
  • 8,354
  • 14
  • 55
  • 90

1 Answers1

1

This is a wild guess but you will need to change your logic. From what you have just said I guess you have several pages with same .content-padd div. If this is the case then you need to understand how jQuery Mobile and javascript works. jQuery Mobile uses ajax to load content into the DOM. One or more pages can be loaded.

If you have several pages with a same DIV id, when you try to access it you will access first element found in the DOM that has that id, and it usually is not a DIV you want.

To access correct DIV you will need to use jQuery Mobile selector called active page:

$.mobile.activePage

And without testing your code should look like this:

$(document).bind('pageshow', function() {

    alert('hello')

    $.mobile.activePage.find('.add-on').addClass('ui-corner-all');

    //Set the width of the input following the appends or prepends to the remaining space
    var containerWidth = $.mobile.activePage.find('div.content-padd').width();
    console.log('container width:' + containerWidth);

    var appendsAndPrepends = '.input-prepend, .input-append';
    $.mobile.activePage.find(appendsAndPrepends).each(function () {
        var remainingSpace = containerWidth - $(this).find('span.add-on').outerWidth();
        console.log('span width' + $(this).find('span.add-on').outerWidth());

        $(this).find('div.ui-input-text').outerWidth(remainingSpace);
    });

});

I am not sure this code is working correctly but I think you now should understand the point.

Gajotres
  • 57,309
  • 16
  • 102
  • 130
  • Wow, you are spot on! Thanks a million. what I don't understand here is, so JQM loads the page with Ajax and inserts it into the DOM, but why doesn't it remove the previous page from the DOM? Also, how does the JS get refreshed with the Ajax load if it is already loaded (so that the 'pageshow' event fires)? Does JQM only load the content from the element? – Lee May 31 '13 at 13:06
  • To answer your first question. Cashing can be turned off but by default it is always on. Next 2 questions will be answered by my other answer here: http://stackoverflow.com/questions/15800121/why-i-have-to-put-all-the-script-to-index-html-in-jquery-mobile/15806954#15806954 – Gajotres May 31 '13 at 13:10
  • Aah I see, this answer also explains the JS mystery http://stackoverflow.com/questions/7449402/jquery-mobile-mobile-changepage-not-loading-external-js-files. So if one does things the way I was doing them (i.e all JS in the head of a layout page) then you always need to use $.mobile.activePage.find('.add-on')instead of $('selector')? – Lee May 31 '13 at 13:21
  • FWIW I see the active page has a class 'ui-page-active' that should let one use $('.ui-page-active selector') – Lee May 31 '13 at 13:30