0

I am having a confusing time with my codeigniter app.

I have a view/form(view 1) which when submitted loads another view (view 2). view 1, on initial page load does not load the correct js and css. it instead loads the js and css from view 1. if I then hit refresh on view 2, the correct css and js is loaded.

To prove my point I placed a test js script

<script type='text/javascript'>
alert('test');
</script>

as the first bit of code on both view 1 and view 2. on loading view 1 for the first time, the alert is shown, when I click submit on view 1 and view 2 is loaded the alert is not shown. if I refresh though the alert shows as desired.

So js and css not loading correctly on initial load but on refresh works perfectly.

Any ideas?

View 1

<script type='text/javascript'>
alert('test');
</script>
<html>
   <head>
      <title>
         Capture New Order
      </title>
      <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css" />

   </head>
<body>
   <div  data-role="page"  data-theme="a">
      <div class="wrap-header">
         <div data-role="header" data-mini="true"  data-ajax="false">
            <a data-icon="grid" data-mini="true"  data-theme="a" onclick="window.location.href='/pointer'">Menu</a>
            <h3>New Order Details</h3>
         </div>
      </div>   
   <div data-role="content">
   <form id="sales_order_details" action="/sales/new_blank_order_lines" method="post">
         <label for="customer">Select Customer</label>
      <div id="autocomplete_dropdown">
         <input type="text" id="customer" name="customer" />
      </div>

   <label for="period">Desired Order Period</label>
   <select id="period" name="period"> 
      <option value="0"></option>
        <?php
          for($i = 0; $i <= 365; $i ++){
            $startdate = strtotime("today + $i day");
            $enddate = strtotime("today + " . ($i + 6) . " day");
            if(date('D', $startdate) == 'Mon'){
                echo '<option value="' . date('Y-m-d', $startdate) . '">' .date('d M y', $startdate) . " to " . date('d M y', $enddate) . "</option>";
            }
          } 
        ?> 
   </select>

<label>Choose an order type below and provide requested details</label>

  <div data-role="collapsible-set">
      <div data-role="collapsible">
          <h3>
              Auto Spread Order
          </h3>
          <label for="asuom">Unit of Measure for Order</label>
            <select id="asuom" name="asuom"> 
              <option value="0"></option>
              <option value="Bundles">Bundles</option>
              <option value="Cubes">Cubes</option>
              <option value="Pieces">Pieces</option>
            </select>
          <label>Number of Cubes to Autospread</label>
          <input type="text" name="ascubes" id="ascubes">
          <label>Products over which to spread</label>
          must work on this...
          <input type="submit" name="previous_order" id="previous_order" value="Continue">
      </div>
      <div data-role="collapsible">
          <h3>
              Previous Order
          </h3>
          <label>Select Order to use as template</label>
          <input type="submit" name="previous_order" id="previous_order" value="Continue">

      </div>
      <div data-role="collapsible">
          <h3>
              Blank Order
          </h3>
          <label for="buom">Unit of Measure for Order</label>
            <select id="buom" name="buom"> 
              <option value="0"></option>
              <option value="cubes">Bundles</option>
              <option value="cubes">Cubes</option>
              <option value="pcs">Pieces</option>
            </select>
          <input type="submit" name="blank_order" id="blank_order" value="Continue">

      </div>
  </div>


   </form>
   </div>

</body>
</html>

<!-- script for page start-->
     <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
     <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script> 
      <script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
<script type="text/javascript">
      $(function(){
        $("#customer").autocomplete({
          source: "get_customers",
          messages: {
          noResults: '',
          results: function() {}
      }


        });
      });
</script>

View 2

<script type='text/javascript'>
alert('test');
</script>
<?php 
$newperiod = date('Y-m-d',strtotime($period) + (24*3600*6)); 
?>
<html>
   <head>
      <title>
         Capture blank Order
      </title>

     <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
     <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script> 

<script type="text/javascript"> 
 function callAutocomplete(element) 
 { 
 $(element).autocomplete( 
 { 
 source: "get_sku_codes", 
 messages: 
 { 
 noResults: '', 
 results: function() {} 
 }, 
 select: function( event, ui ) 
 { 
 var selectedObj = ui.item; 
 $.post('sales/get_sku_prices', {data:selectedObj.value},function(result) { 
 $(ui).parent('tr').find('input[id^="pricepercube"]').val(result); 
 }); 
 } 
 }); 
 } 

 $(function() 
 { 
 var counter = 1; 
 jQuery("table.authors-list").on('change','input[name^="qty"]',function(event) 
 { 
 event.preventDefault(); 
 counter++; 
 var newRow = jQuery('<tr>'+ 
 ' <td><a class="deleteRow"> <img src="<?php echo base_url() ?>application/assets/images/no.jpg" /></a></td>' + 
 ' <td><input type="text" id="product' + counter + '" name="product' + counter + '"  /></td>' + 
 ' <td><input type="text" id="qty' + counter + '" name="qty' + counter + '"  /></td>'+ 
 ' <td><input type="text" id="price' + counter + '" name="price' + counter + '" /></td>'+ 
 ' <td><input type="text" id="discount' + counter + '" name="discount' + counter + '"  /></td>'+ 
 ' <td valign=top><input type="checkbox" id="treated' + counter + '" name="treated' + counter + '" /></td>'+ 
 ' </tr>'); 
 jQuery('table.authors-list').append(newRow); 
 callAutocomplete("#product"+ counter); 
 }); 

 $("#product").autocomplete( 
 { 
 source: "get_sku_codes", 
 messages: 
 { 
 noResults: '', 
 results: function() {} 
 }, 
 select: function( event, ui ) 
 { 
 var selectedObj = ui.item; 
 $.post('<?=site_url("sales/get_sku_price")?>', {data:value},function(result)

 { 
 $("#price").val(result); 
 }); 
 } 
 }); 

 }); 

 </script>


  </head>
<body >

      <div class="wrap-header">
         <div data-role="header" data-mini="true"  data-ajax="false">
            <a data-icon="grid" data-mini="true"  data-theme="a" onclick="window.location.href='/pointer'">Menu</a>
            <h3>New Blank Order</h3>
         </div>
      </div>   
      <div data-role="content">
         <center>
            <table width=80%><tr><td>
            <input type="text" name="customer" id="customer" value="<?php echo $customer; ?>" disabled>
               </td><td>
            <input type="text" name="period" id="period" value="<?php echo $period." to ".$newperiod; ?>" disabled>
               </td><td>
            <input type="text" name="buom" id="buom" value="<?php echo $buom; ?>" disabled>
               </td></tr></table>
      </center>
      </div>

<table class="authors-list" border=0>
  <tr><td></td><td>Product</td><td>Qty</td><td>Price/Cube</td><td>Discount</td><td>treated</td></tr>
  <tr>
   <td><a class="deleteRow"> <img src="<?php echo base_url() ?>application/assets/images/no.jpg" /></a></td>
   <td><input type="text" id="product" name="product" /></td>
   <td><input type="text" id="qty" name="qty" /></td>
   <td><input type="text" id="price" name="price" /></td>
   <td><input type="text" id="discount" name="discount" /></td>
   <td valign="top" ><input type="checkbox" id="treated" name="treated" /></td>
</tr>
</table>

</body>
</html>

Initial Page Load - no alert or js/css working - only css and js from view 1 enter image description here

Refresh Load - no css or js from view 1, only view 2 css and js loaded. note I have removed all styling from view 2 just to test and get working. So below image is what I desire. alert is shown here. this is load after clsing alert. enter image description here

I have tried this in IE, Firefox and Chrome all with same result.

Any advice is appreciated. thanks

UPDATE

View 1:

<html>
   <head>
      <title>
         Capture New Order
      </title>
      <link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.css" />
      <!-- script for page start-->
           <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
           <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script> 
            <script src="http://code.jquery.com/mobile/1.3.0/jquery.mobile-1.3.0.min.js"></script>
      <script type="text/javascript">
      $(document).on('pageshow', '#pagebody', function(){   
            $(function(){
              $("#customer").autocomplete({
                source: "get_customers",
                messages: {
                noResults: '',
                results: function() {}
            }


              });
            });
          });
      </script>
      <!-- script for page end-->
   </head>
<body>
   <div  data-role="page"  data-theme="a">
      <div class="wrap-header">
         <div data-role="header" data-mini="true"  data-ajax="false">
            <a data-icon="grid" data-mini="true"  data-theme="a" onclick="window.location.href='/pointer'">Menu</a>
            <h3>New Order Details</h3>
         </div>
      </div>   
   <div data-role="content">
   <form id="sales_order_details" action="/sales/new_blank_order_lines" method="post">
         <label for="customer">Select Customer</label>
      <div id="autocomplete_dropdown">
         <input type="text" id="customer" name="customer" />
      </div>

   <label for="period">Desired Order Period</label>
   <select id="period" name="period"> 
      <option value="0"></option>
        <?php
          for($i = 0; $i <= 365; $i ++){
            $startdate = strtotime("today + $i day");
            $enddate = strtotime("today + " . ($i + 6) . " day");
            if(date('D', $startdate) == 'Mon'){
                echo '<option value="' . date('Y-m-d', $startdate) . '">' .date('d M y', $startdate) . " to " . date('d M y', $enddate) . "</option>";
            }
          } 
        ?> 
   </select>

<label>Choose an order type below and provide requested details</label>
<div  data-role="page"  data-theme="a" id="pagebody">
  <div data-role="collapsible-set">
      <div data-role="collapsible">
          <h3>
              Auto Spread Order
          </h3>
          <label for="asuom">Unit of Measure for Order</label>
            <select id="asuom" name="asuom"> 
              <option value="0"></option>
              <option value="Bundles">Bundles</option>
              <option value="Cubes">Cubes</option>
              <option value="Pieces">Pieces</option>
            </select>
          <label>Number of Cubes to Autospread</label>
          <input type="text" name="ascubes" id="ascubes">
          <label>Products over which to spread</label>
          must work on this...
          <input type="submit" name="previous_order" id="previous_order" value="Continue">
      </div>
      <div data-role="collapsible">
          <h3>
              Previous Order
          </h3>
          <label>Select Order to use as template</label>
          <input type="submit" name="previous_order" id="previous_order" value="Continue">

      </div>
      <div data-role="collapsible">
          <h3>
              Blank Order
          </h3>
          <label for="buom">Unit of Measure for Order</label>
            <select id="buom" name="buom"> 
              <option value="0"></option>
              <option value="cubes">Bundles</option>
              <option value="cubes">Cubes</option>
              <option value="pcs">Pieces</option>
            </select>
          <input type="submit" name="blank_order" id="blank_order" value="Continue">

      </div>
  </div>


   </form>
   </div>

</body>
</html>

View 2:

<?php 
$newperiod = date('Y-m-d',strtotime($period) + (24*3600*6)); 
?>
<html>
   <head>
      <title>
         Capture blank Order
      </title>

     <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
     <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script> 

<script type="text/javascript"> 
$(document).on('pageshow', '#pagebody', function(){   

 function callAutocomplete(element) 
 { 
 $(element).autocomplete( 
 { 
 source: "get_sku_codes", 
 messages: 
 { 
 noResults: '', 
 results: function() {} 
 }, 
select: function( event, ui ) 
 { 
 var selectedObj = ui.item; 
 $.post('get_sku_prices', {data:selectedObj.value},function(result) 
 { 
 $(element).parent().parent().find('input[id^="price"]').val(result); 
 }); 
 } 
 }); 
 }

 $(function() 
 { 
 var counter = 1; 
 jQuery("table.authors-list").on('change','input[name^="qty"]',function(event) 
 { 
 event.preventDefault(); 
 counter++; 
 var newRow = jQuery('<tr>'+ 
 ' <td><a class="deleteRow"> <img src="<?php echo base_url() ?>application/assets/images/no.jpg" /></a></td>' + 
 ' <td><input type="text" id="product' + counter + '" name="product' + counter + '"  /></td>' + 
 ' <td><input type="text" id="price' + counter + '" name="price' + counter + '" /></td>'+ 
 ' <td><input type="text" id="qty' + counter + '" name="qty' + counter + '"  class="linetotal" /></td>'+ 
 ' <td><input type="text" id="total' + counter + '" name="total' + counter + '"  /></td>'+ 
 ' <td><input type="text" id="discount' + counter + '" name="discount' + counter + '"  /></td>'+ 
 ' <td valign=top><input type="checkbox" id="treated' + counter + '" name="treated' + counter + '" /></td>'+ 
 ' </tr>'); 
 jQuery('table.authors-list').append(newRow); 
 callAutocomplete("#product"+ counter); 
 }); 


 $("#product").autocomplete( 
 { 
 source: "get_sku_codes", 
 messages: 
 { 
 noResults: '', 
 results: function() {} 
 }, 
 select: function( event, ui ) 
 { 
  var selectedObj = ui.item; 
 $.post('get_sku_prices', {data:selectedObj.value},function(result) { 
 $("#product").parent().parent().find('input[id^="price"]').val(result[0]);
 }); 
 } 
 });

//code to calculate line cost (price*qty)
var total=Number($('input[id^="price"]').val()) + Number($('input[id^="qty"]').val());
$('input[id^="total"]').val(total);

//code to calculate Grand Total of all line costs (sum of all line totals)


 }); 

});
 </script>


  </head>
<body >
  <div  data-role="page"  data-theme="a" id="pagebody">

      <div class="wrap-header">
         <div data-role="header" data-mini="true"  data-ajax="false">
            <a data-icon="grid" data-mini="true"  data-theme="a" onclick="window.location.href='/pointer'">Menu</a>
            <h3>New Blank Order</h3>
         </div>
      </div>   
      <div data-role="content">
         <center>
            <table width=80%><tr><td>
            <input type="text" name="customer" id="customer" value="<?php echo $customer; ?>" disabled>
               </td><td>
            <input type="text" name="period" id="period" value="<?php echo $period." to ".$newperiod; ?>" disabled>
               </td><td>
            <input type="text" name="buom" id="buom" value="<?php echo $buom; ?>" disabled>
               </td></tr></table>
      </center>
      </div>

<table class="authors-list" border=0>
  <tr><td></td><td>Product</td><td>Price/Cube</td><td>Qty</td><td>Line Total</td><td>Discount</td><td>treated</td></tr>
  <tr>
   <td><a class="deleteRow"> <img src="<?php echo base_url() ?>application/assets/images/no.jpg" /></a></td>
   <td><input type="text" id="product" name="product" /></td>
   <td><input type="text" id="price" name="price" /></td>
   <td><input type="text" id="qty" name="qty" onchange="fill()" /></td>
   <td><input type="text" id="total" name="total" class="linetotal" /></td>
   <td><input type="text" id="discount" name="discount" /></td>
   <td valign="top" ><input type="checkbox" id="treated" name="treated" /></td>
</tr>
</table>
</div>
</body>

Smudger
  • 10,451
  • 29
  • 104
  • 179

1 Answers1

1

First of all you have a big problem in your code. When using jQuery Mobile only proper way of initializing javascript/jquery code is jQuery Mobile page events. If you use document ready or $(function(){ to initialize your code there's a good chance it will fail because:

  • Sometimes javascript used like that will trigger before pages are loaded into the DOM. That is why it works after the refresh, content is already in the DOM.
  • Even if pages are loaded into the DOM jQuery Mobile still needs to enhance them with its own styles and markup.

To prevent this, usage of jQuery Mobile page events is strongly advised. Here's a working jsFiddle example: http://jsfiddle.net/Gajotres/tuJEm/

$(document).on('pageshow', '#index', function(){       
    alert('Page loaded');
});

$(document).on('pagebeforeshow', '#second', function(){       
    alert('Page loaded');
});

To make it work in your case, you will need to give an id to your page container:

<div  data-role="page"  data-theme="a">

If you want to understand this better, take a look at this ARTICLE, or find it HERE.

One more thing, because of jQM page events you no longer need to load scripts at the end of HTML file. No matter what, in case of jQM, your jQm js and css should always be in your html header.

EDIT :

After looking into a jQuery Mobile + Codeigniter problematic. I cant confirm this will work, but you should try it. Apparently codeigniter has a problem with how jQuery Mobile handles page loading through AJAX. So basic advice is to turn it off.

First thing you need to do is move all of yours script and style tags into the HEAD. Each PHP file should have the same set of jQuery, jQuery Mobile js files loaded into the head. This is done because we will prevent page loading into the DOM and every page will stand as a single entity.

Second thing, turn of ajax page load:

<script>
    $(document).bind("mobileinit", function() {
        $.mobile.ajaxEnabled = false;
    });
</script> <!-- Note your script before jqm -->

One more thing, mobilinit event must be initialized after jQuery but before jQuery Mobile, like this:

<script src="jquery.js"></script>
<script>
    $(document).bind("mobileinit", function() {
        $.mobile.ajaxEnabled = false;
    });
</script> <!-- Note your script before jqm -->
<script src="jquery-mobile.js"></script>
Community
  • 1
  • 1
Gajotres
  • 57,309
  • 16
  • 102
  • 130
  • Thanks Gajotres, really appreciate the indepth answer and your knowledge transfer. I will update my questions with my current syntax in the next few minutes. Do I understand you correctly? My CSS and JS is in the HTML header, I have given the top most DIV an id, data role and theme. I then placed all my script inside `$(document).on('pagebeforeshow', '#pagebody', function(){ ` but it still doesn't work. Am I missing the point. Guidance appreciated. Thanks Gajotres... – Smudger Mar 27 '13 at 11:16
  • There's one other thing :) Tell me, you are using several html files? – Gajotres Mar 27 '13 at 11:20
  • Hi Gajotres. not at all. I am using codeigniter framework. my controller is obviously a php page calling one single view. my view is a single html page with no includes or the like. Thanks again for the assistance. – Smudger Mar 27 '13 at 11:24
  • It doesn't matter how you call it, your view is still a page with HEAD and BODY, am I correct? – Gajotres Mar 27 '13 at 11:34
  • 1
    In case you have multiple html files (or view in your case), jQuery Mobile will load everything into the DOM. That means, only HEAD of a first file(view) will be loaded. In other loaded files (views) HEAD will be discareded. You should move a script tag from your VIEW 2 into a VIEW 1 or in this case put it inside a BODY (disregard what I told you in my answer). – Gajotres Mar 27 '13 at 11:36
  • Thanks, is it better to use `$(document).ready()` or `$(document).on('pageshow', '#index', function()`? Will try now and feedback. Thanks. – Smudger Mar 27 '13 at 11:43
  • It is better to use page events, read why in my other anser/article: http://stackoverflow.com/a/14469041/1848600 – Gajotres Mar 27 '13 at 11:57
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/27005/discussion-between-smudger-and-gajotres) – Smudger Mar 27 '13 at 12:09