1
votes

I recently built my first jquery mobile site across separate html files that are linked. As instructed in the jquery mobile documentation I loaded all of my scripts between the head tag on the first page:

<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3.exp&sensor=true&libraries=places"></script><!--needed only on map.htm-->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="js/ladot.js"></script><!--all custom script for pages in same js file-->  
<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.10.0/jquery.validate.min.js"></script><!--needed only on the two pages with forms that are to be validated-->

I also loaded only the scripts needed for each page to function in that head of that page. If I navigate to the first page and then link to other pages all of my javascript functions work; forms are validated and the input fields show/hide based on drop down selections.

The problem is that if I refresh the page or just go directly to that page in the address bar these functions are not working. After reading the jquery mobile I thought that if I include the scripts in the head of each page they would load if a user happens to load that page first via HTTP instead of linking with ajax from the first page.

I understand that I can include the scripts I need in between the data-role="page". Is that the best option? Here is the custom ladot.js script I have which I could break up into separate js files which load the necessary functions in the data-role="page" of the relevant pages.

ladot.js:

  // JavaScript Document
  //-------------Javascript for map.htm -- first page that is loaded------------------------------
function initialize() {
var map = new google.maps.Map(document.getElementById('map_canvas'), {
  zoom: 14,
  //center: new google.maps.LatLng( 34.05221496568917, -118.24334979057312 ),
  mapTypeId: google.maps.MapTypeId.TERRAIN 
});

var bikeLayer = new google.maps.BicyclingLayer();
    bikeLayer.setMap(map);

existingbikewaysMap = new google.maps.FusionTablesLayer({
  query: {
    select: 'geometry',
    from: '5294232'
  }
});
existingbikewaysMap.setMap(map);

//add the bicycle parking fusion table layer
BikeParkingMap = new google.maps.FusionTablesLayer({
  query: {
    select: 'Full Address',
    from: '1A5fsPE8B8eJfV4jwji29sebnY1QiAVjL2pTjzOk'
  }
});
BikeParkingMap.setMap(null);

toggle = function(layer) {
   if (layer == 'Bike') {
     if (existingbikewaysMap.getMap() == null) existingbikewaysMap.setMap(map);
     else existingbikewaysMap.setMap(null);
   } else if (layer == 'Park') {
     if (BikeParkingMap.getMap() == null) BikeParkingMap.setMap(map);
     else BikeParkingMap.setMap(null);
   }
}
    google.maps.event.addDomListener(document.getElementById('Bike'), 'click', function() { toggle('Bike'); });
    google.maps.event.addDomListener(document.getElementById('Park'), 'click', function() { toggle('Park'); });


centerLocation = function( position ) {
    map.setCenter( new google.maps.LatLng( 34.05221496568917, -118.24334979057312 ) );
}

myMarker = 0,
    displayLocation = function( position ) {
        // create a new LatLng object for every position update
        var myLatLng = new google.maps.LatLng( position.coords.latitude, position.coords.longitude );

        // build entire marker first time thru
        if ( !myMarker ) {
            // define our custom marker image
            var image = new google.maps.MarkerImage(
                'img/bluedot_retina.png',
                null, // size
                null, // origin
                new google.maps.Point( 8, 8 ), // anchor (move to center of marker)
                new google.maps.Size( 17, 17 ) // scaled size (required for Retina display icon)
            );
            map.setCenter( myLatLng );

            // then create the new marker
            myMarker = new google.maps.Marker({
                flat: true,
                icon: image,
                map: map,
                optimized: false,
                position: myLatLng,
                title: 'You are here',
                visible: true
            });

        // just change marker position on subsequent passes
        } else {
            myMarker.setPosition( myLatLng );
        }

        // center map view on every pass
        //map.setCenter( myLatLng );
    },
    handleError = function( error ) {
        var errorMessage = [ 
            'Sorry. Permission to find your location has been denied.',
            'Sorry. Your position could not be determined.',
            'Sorry. Timed out.'
        ];

        alert( errorMessage[ error.code ] );
    },
    // cache the userAgent
    //useragent = navigator.userAgent;


// allow browser to track movement
    navigator.geolocation.watchPosition( 
        displayLocation,
        centerLocation,
        handleError, 
        { 
            enableHighAccuracy: true, 
            maximumAge: 30000, 
            timeout: 27000 
        }
    );          


var input = document.getElementById('target');
var searchBox = new google.maps.places.SearchBox(input);
var markers = [];

google.maps.event.addListener(searchBox, 'places_changed', function() {
  var places = searchBox.getPlaces();

  for (var i = 0, marker; marker = markers[i]; i++) {
    marker.setMap(null);
  }

  markers = [];
  var bounds = new google.maps.LatLngBounds();
  for (var i = 0, place; place = places[i]; i++) {
    var image = new google.maps.MarkerImage(
        'img/pin_blue.png',
        new google.maps.Size(15,29),
        new google.maps.Point(0,0),
        new google.maps.Point(8,29)
      );

      var shadow = new google.maps.MarkerImage(
        'img/pin_shadow.png',
        new google.maps.Size(33,29),
        new google.maps.Point(0,0),
        new google.maps.Point(8,29)
      );

      var shape = {
        coord: [11,1,12,2,13,3,14,4,14,5,14,6,14,7,14,8,14,9,14,10,14,11,14,12,13,13,12,14,11,15,8,16,8,17,8,18,8,19,8,20,8,21,8,22,8,23,8,24,11,25,11,26,11,27,3,27,3,26,3,25,6,24,6,23,6,22,6,21,6,20,6,19,6,18,6,17,6,16,3,15,2,14,1,13,0,12,0,11,0,10,0,9,0,8,0,7,0,6,0,5,0,4,1,3,2,2,3,1,11,1],
        type: 'poly'
      };

    var marker = new google.maps.Marker({
      map: map,
      icon: image,
      shadow: shadow,
      shape: shape,
      title: place.name,
      position: place.geometry.location
    });

    markers.push(marker);

    bounds.extend(place.geometry.location);
  }

  map.fitBounds(bounds);
});

  google.maps.event.addListener(map, 'bounds_changed', function() {
  //var bounds = map.getBounds();
  searchBox.bindTo('bounds', map);
});
  }

  //Function that toggles CSS styles so that navbar buttons go on and off
$(function() {

  $("#nav1,#nav2,#nav3").off('click').on('click', function() {
    setTimeout(function() {
    $(this).removeClass('');
  }, 500);

    $(this).toggleClass("custom-btn-active");
  });
});

//Function to toggle search div
$(function() {
  $("#Find").click(function(){
    $("#searchfield").slideToggle();
  });
});

  google.maps.event.addDomListener(window, 'load', initialize);


  //-------------Javascript for bss-request.htm--------------------------------------------  
 //Function that controls form validation errors for BSS form
$(document).on("#bss-request", "pagecreate", function() {
    $("#bssForm").validate({

        rules: {
                name: "required",
                phone: {
                    required: false,
                    minlength: 10
                },
                email: {
                    required: true,
                    email: true
                },
                problem: "required",
                description: {
                    required: true,
                    minlength: 15
                },
                location: {
                    required: true,
                    minlength: 15
                }
                },
                messages: {
                name: "Please enter your name",
                phone: {
                    minlength: "Please enter at least 10 digits"
                },
                email: "Please enter a valid email address",
                problem: "Please select a problem",
                description: {
                    required: "Please describe the problem",
                    minlength: "We need a longer description"
                },
                location: {
                    required: "Please tell us where the problem is",
                    minlength: "We need a more detailed location"
                },
            },

        errorPlacement: function(error, element) {
            if (element.attr("name") === "problem") {
                error.insertAfter($("#problem").parent());
            } else {
                error.insertAfter(element);
            }
        }
    });
});

  //-------------Javascript for bike-rack-request.htm--------------------------------------------    
 //Function that controls form validation errors for Bike rack request form
$(document).delegate("#bike-rack-request", "pagecreate", function() {
    $("#rackForm").validate({

        rules: {
                Business_Name: "required",
                Contact_Name: "required",
                Phone_Number: {
                    required: false,
                    minlength: 10
                },
                email: {
                    required: true,
                    email: true
                },
                Street_Address: {
                    required: true,
                    minlength: 8
                },
                Number_of_Racks: "required",
                description: {
                    required: false,
                },
            },
            messages: {
                Business_Name: "Which business needs a bike rack?",
                Contact_Name: "Please enter your name",
                Phone_Number: {
                    minlength: "Please enter at least 10 digits"
                },
                email: "Please enter a valid email address",
                Street_Address: {
                    required: "Where to install or repair the rack(s)?",
                    minlength: "We need a more detailed location"
                },
                Number_of_Racks: "How many racks you are requesting?"      
            },

        errorPlacement: function(error, element) {
            if (element.attr("name") === "Number_of_Racks") {
                error.insertAfter($("#Number_of_Racks").parent());
            } else {
                error.insertAfter(element);
            }
        }

    });
    //Function that shows/hides form fields
    $('#Number_of_Racks').change(function() {
    var value = $(this).val();
    if (value in {'Seperating from concrete':1,
                  'Missing footing screws':1, 
                  'Rack has been cut':1,
                  'Rack has been smashed':1,
                  'Rack was stolen':1,
                  'Other damage':1}) {
        $('#damage_div').slideDown('');
    }
    else {
        $('#damage_div').slideUp('');
    }
  });
});

//-------------Javascript that runs on all pages--------------------------------------------    
//Function that sets sticky footer
$(document).on( 'pagebeforechange', function() {
  // hide footer
  $('[data-role=footer]').hide();
});
$(document).on( 'pagechange', function() {
  // show footer
  $('[data-role=footer]').show();
});
2
It appears that my main issues is that script in the head is not loading when accessing a page via HTTP. If I refresh a page or type the URL into the address bar and go to it my ladot.js and validate scripts do not appear to work. $(document).delegate("#bike-rack-request", "pagecreate", function() { $("#rackForm").validate({ - Rick
Did you link to all the scripts in the headers of the other pages? - Romain
Romain, yes I have the links in the headers of each page. But I only include the links that are needed to run that page. Should I be loading every script that is used anywhere on the site? - Rick
this is one of the funcitons that is in my JS file. i checked the error console and see that the js is loaded but the function is not working on the site. I am guessing it has something to do with the syntax I used. here is the beginning portion of that function://Function that controls form validation errors for BSS form $(document).on("pageshow", "#bss-request", function() { $("#bssForm").validate({ - Rick

2 Answers

2
votes

When loading a page through AJAX, Jquery mobile will only load the body of the target page. This means that whatever content is in the header will be ignored, including any link to script or style. As a consequence, you will need to either

  1. Link to all scripts and styles you will use on subsequent pages on the first page that is visited. It is important to keep in mind that this will have to be done on every page that the user might access directly (or refresh)
  2. deactivate ajax navigation (which I would not recommend)
0
votes

I'm guessing the issue is that jquery mobile doesnt have access to the window object during/after the ajax load. The problem is with: google.maps.event.addDomListener(window, 'load', initialize);

You Do NOT need this. All this does is load the initialize function.

I'm doing a simple autocomplete and removed the addDomListener and pulled the code from the initialize function. See the removed code below. This works perfectly.

function initialize(){ //Removed

     var input = /** @type {HTMLInputElement} */(document.getElementById('text-basic'));
     var autocomplete = new google.maps.places.Autocomplete(input);

    google.maps.event.addListener(autocomplete, 'place_changed', function() {
        var place = autocomplete.getPlace();
        if (!place.geometry) {
      // Inform the user that the place was not found and return.
        input.className = 'notfound';
        return;
        }
    });

} //Removed

google.maps.event.addDomListener(this.window, 'load', initialize); //Removed