12 Replies Latest reply on Aug 8, 2017 1:43 AM by sanils97665427

    Revert back to original position in cordova phonegap application

    sanils97665427 Level 1

      Hi all,

      I am newbie in phonegap. In my cordova phonegap mobile application, I have a long list of items that are links to the next page. I scroll down halfway, and tap an item. When I press back, the position of the list is set to the top. But I'd like to press back and be taken back to the previous page and previous scroll position.

      Does anyone have idea to how it can be solved ?

      Thank you.

        • 1. Re: Revert back to original position in cordova phonegap application
          ryanskihead Adobe Employee

          It would depend on the framework you're using for view navigation... or if you're just navigating between pages.

           

          This isn't really a Phonegap question, this is more of a web dev question in general, so stackoverflow or somewhere might be a better place to post this.

          • 2. Re: Revert back to original position in cordova phonegap application
            sanils97665427 Level 1

            Sir,

                   You are right. I am using codeignitor frame work. For the above question I have done another method, that is in my list each of item has included in a div element with a div id. When click on an item will show a description page where the clicked item div id taken. On clicking back button I use code like this window.location="./search-list.html#divid". But it is not working. What is happening with this window.location. Please answer.

            • 3. Re: Revert back to original position in cordova phonegap application
              ryanskihead Adobe Employee

              Sounds like an issue with your codeigniter framework. I'd discuss it there.

               

              https://forum.codeigniter.com/

              1 person found this helpful
              • 5. Re: Revert back to original position in cordova phonegap application
                kerrishotts Adobe Employee

                If your framework doesn't have any built-in support for this, you might consider using scrollIntoView: http://caniuse.com/#feat=scrollintoview

                 

                Another option is to save off the scroll position before navigation, and then restore that position when the user returns to the page. See Element.scrollTop - Web APIs | MDN for more info.

                • 6. Re: Revert back to original position in cordova phonegap application
                  sanils97665427 Level 1

                  Hai,

                                Below is the items listing html and its javascript page. Please look at this.

                  search-results.html

                  <!DOCTYPE html>

                  <html lang="en">

                  <head>

                  <meta charset="UTF-8">

                  <title>Maids - Results</title>

                  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

                  <meta http-equiv="Content-Security-Policy" content="img-src * blob: android-webview-video-poster: cdvphotolibrary:  'self' data: ws: wss://*; default-src * blob: 'self' gap: wss: ws: data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; connect-src * http: https: ws: wss://*;">

                    <!--Start New Swipe Menu -->

                      <link rel="stylesheet" href="dist/mocha.min.css">

                      <link rel="stylesheet" href="dist/test.css">

                      <link rel="stylesheet" href="dist/index.css">

                       <!--End New Swipe Menu -->

                  <link rel="stylesheet" href="css/bootstrap.min.css">

                  <link rel="stylesheet" href="css/bootstrap-theme.min.css">

                  <link rel="stylesheet" href="css/style.css">

                  <script src="js/jquery.min.js"></script>

                  <script src="js/bootstrap.min.js"></script>

                  <script src="js/bootstrap-switch.js"></script>

                  <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600itali c,700,700italic,800,800italic' rel='stylesheet' type='text/css'>

                  <link rel="stylesheet" href="css/font-awesome.min.css">

                  <link href="menu/jasny-bootstrap.min.css" rel="stylesheet">

                  <link href="menu/navmenu-reveal.css" rel="stylesheet">

                  <link href="css/bootstrap-switch.css" rel="stylesheet">

                  <style type="text/css">

                  .canvas {

                  background: #FFF; 

                  }

                  </style> 

                      <script type="text/javascript">

                  //$(document).ready(function(){

                        window.onload = function() {

                          document.querySelector('.js-slideout-toggle').addEventListener('click', function() {

                            slideout.toggle();

                          });

                          document.querySelector('.menu').addEventListener('click', function(eve) {

                            if (eve.target.nodeName === 'A') { slideout.close(); }

                          });

                          var runner = mocha.run();

                        };

                      </script>

                      <!--End New Swipe Menu -->

                  </head>

                  <!--Start New Swipe Menu -->

                  <body style="background:#5a0da7;-webkit-overflow-scrolling: auto;">

                       <div class="loader" style="display: none"> <div class="preloader4"></div></div> 

                  <nav id="menu" class="menu">

                       <img src="img/logo-white.svg" style="max-width:80%; margin:15px 0 0 15px">

                          <ul class="menu-section-list">

                          <li class="menu-ic-1"><a href="./search-page.html">Search</a></li>

                          <li class="menu-ic-2"><a href="./booking-management.html">Booking Management</a></li>

                          <li class="menu-ic-3"><a href="./favorites.html">Favourites</a></li>

                          <li class="menu-ic-5" onClick="logout()"><a href="#">Logout</a></li>

                          <li class="menu-ic-6"><a href="#">Push Notification</a>

                  <div class="slideThree">

                  <input type="checkbox" value="None" id="slideThree" name="check" onChange="updatePushStatus(event)" />

                  <label for="slideThree"></label>

                  </div>

                  </li>

                          </ul> 

                      </nav>       

                      <div style="position:absolute; top:0; width:100%">

                      <div class="slideout-wrapper" style=" width:100%; height:100vh; ">

                  <div id="panel" class="panel" style="float:left; background:#5a0da7; height:100vh; width:100% !important;  position:absolute; z-index:5">

                  <header class="panel-header" style="background:#63088b; width:100%; margin:0; height:72px; ">

                  <button class="btn-hamburger js-slideout-toggle"></button> <img src="img/logo-white.svg" style="max-width:176px; position:relative; left:75px; top:8px;" />

                  </header>

                  <div> 

                  <!-- End New Swipe Menu -->

                     <div style="position:fixed; width:100%;z-index:9;">

                        <div id="result_count" class="title-holder"></div>

                        <div class="holder">

                          <a href="./search-page.html"><div class="search-again"><i class="fa fa-search"></i>  Search again</div></a>

                          <a href="./filter-sort.html"><div class="filter-btn"><i class="fa fa-sort-amount-asc"></i>  Filter / Sort</div></a>

                        </div>

                      </div>  

                      <div class="maids-wrapper">

                        <div class="login-bg" style="background:#eeeeee">

                          <div class="maids-inner" style="padding:0;" data-role="page">

                            <ul id="ul_results" class="search-results" style="">

                            </ul>

                          </div>

                        </div>

                      </div>

                     <!--Start New Swipe Menu -->

                       </div>

                        </div>

                        </div>

                        </div>

                        <!-- /.container -->

                       <!--End New Swipe Menu -->

                    <!-- Bootstrap core JavaScript

                      ================================================== -->

                    <!-- Placed at the end of the document so the pages load faster -->

                    <script src="menu/jasny-bootstrap.min.js"></script>

                    <script src="cordova.js"></script>

                    <script src="js/maidko/common.js"></script>

                    <script src="js/maidko/search_result.js"></script>

                    <script type="text/javascript">

                      //alert("initialising");

                      debugger;

                      $('#menu-bar').load("nav-menu.html #menu");

                      search_res_app.initialize();

                      //search_res_app.populateListItems();

                    </script>

                       <!--Start New Swipe Menu -->

                      <script src="dist/mocha.min.js"></script>

                      <script>

                        mocha.setup('bdd');

                        var exports = null;

                        function assert(expr, msg) {

                          if (!expr) throw new Error(msg || 'failed');

                        }

                      </script>

                      <script src="dist/slideout.js"></script>

                      <script src="dist/test.js"></script>

                      <style> 

                      #mocha-error { display:none !important}

                      </style>

                      <!--End New Swipe Menu -->

                  </body>

                  </html>   

                              

                  search_result.js

                              

                  var search_data;

                  var search_res_app = {

                  // Application Constructor

                      initialize: function() {

                          this.bindEvents();

                      },

                      // Bind Event Listeners

                      bindEvents: function() {

                          document.addEventListener('deviceready', this.onDeviceReady, false);

                      },

                      // deviceready Event Handler

                      onDeviceReady: function() {

                  console.log('Received Event: deviceready');

                  //window.open = cordova.InAppBrowser.open;

                  document.addEventListener('backbutton', function(){

                  //alert("Back Clicked");

                  window.location = "./search-page.html";

                  }, false);

                  search_res_app.populateListItems();

                  $("#slideThree").prop("checked", window.localStorage.getItem('push_status')== 0 ? false : true);

                      },

                  rating_handler: function(id_company){

                  event.stopPropagation();

                  $.ajax({

                  url: 'http://www.example.com/index.php/companies/getReviewsByCompany',

                  crossDomain: true,

                  type: 'POST',

                  datatype: 'json',

                  data: {'id_company': id_company, 'output': 'json'},

                  success: function(result){

                  if(result.success){

                  window.localStorage.setObject("review_data", result.data);

                  window.location = "./reviews.html";

                  return true;

                  }

                  else alert("Error in DB! " + result.message);

                  },

                  error: function(result){

                  alert("Error! " + result.responseText);

                  return false;

                  }

                  });

                  },

                  like_unlike: function(){

                  event.stopPropagation();

                  var elementId = $(this).attr("id");

                  var messageID = elementId.split("like")[1];

                  var C = parseInt($("#likeCount" + messageID).html());

                  $(this).css("background-position", "")

                  var D = $(this).attr("rel");

                  if(D === 'like')

                  {     

                  $("#likeCount" + messageID).html(C + 1);

                  $(this).addClass("heartAnimation").attr("rel","unlike");

                  search_res_app.updateFavorites(messageID, 1, $(this).attr("fav_id"));

                  }

                  else

                  {

                  $("#likeCount" + messageID).html(C - 1);

                  $(this).removeClass("heartAnimation").attr("rel","like");

                  $(this).css("background-position","left");

                  search_res_app.updateFavorites(messageID, 0, $(this).attr("fav_id"));

                  }

                  },

                  updateFavorites: function(id_company, fav, fav_id) {

                  $.ajax({

                  url: 'http://www.example.com/index.php/companies/updateFavorites',

                  crossDomain: true,

                  type: 'POST',

                  datatype: 'json',

                  data: {'id_company': id_company, 'fav': fav, 'fav_id': fav_id , 'output': 'json'},

                  success: function(result){

                  if(result.success){

                  return true;

                  }

                  //else alert(result.message);

                  },

                  error: function(result){

                  //alert(result.responseJSON.message);

                  return false;

                  }

                  });

                  },

                  populateListItems : function(){

                  search_data = window.localStorage.getObject("search_data");

                  var len = search_data.length;

                  search_res_app.setResultCount(len);

                  var html_text = "";

                  var heart_id = [];

                  var rating_id = [];

                  for(var i=0; i<len; i++){

                  var is_fav = (search_data[i].is_favorite == 'Yes') ? "unlike" : "like";

                  var fav_class = (search_data[i].is_favorite == 'Yes') ? "favorite" : "";

                  var styleClass = (search_data[i].maids_avail < window.localStorage.getItem("search_maids")) ? ' style = "opacity=0.5" ' : '';

                  var current_rate = search_data[i]['rating'];

                  var full_stars = parseInt(current_rate);

                  var half_stars = current_rate > full_stars ? 1 : 0;

                  var empty_stars = half_stars > 0 ? 5 - (full_stars + 1) : 5 - full_stars;

                  var full_stars_div = '';

                  var half_stars_div = '';

                  var empty_stars_div = '';

                  if (full_stars > 0){

                  for(var fs=0; fs<full_stars; fs++){

                  full_stars_div += '<i class="fa fa-star"></i>';

                  }

                  }

                  if (half_stars > 0){

                  half_stars_div += '<i class="fa fa-star-half-empty"></i>';

                  }

                  if (empty_stars > 0){

                  for(var es=0; es<empty_stars; es++){

                  empty_stars_div += '<i class="fa inactive fa-star"></i>';

                  }

                  }

                  html_text += '<li ' + styleClass + ' onclick="search_res_app.viewCompanyDetails(' + search_data[i].id + ', \'' + search_data[i].location + '\', ' + search_data[i].com_location + ', ' + i + ')" id="div'+i+'" >' +

                  '<h1>' + search_data[i].name + ', ' + search_data[i].location + '</h1>' +

                  '<div class="star-cntr-info">' +

                  full_stars_div + half_stars_div + empty_stars_div +

                  '</div>' +

                  '<div class="listing-img"><img src="' + search_data[i].logo + '" /></div>' +

                  '<div class="listing-txt">' +

                  '<h3>' + search_data[i].num_reviews + ' Customers served</h3>' +

                  '<h2>AED ' + search_data[i].price + ' / Hour</h2>' + 

                  '<h4> (' + search_data[i].maids_avail + ' Maids available)</h4>' +

                  '<div class="heart ' + fav_class +'" id="like' + search_data[i].id + '" rel="' + is_fav +'" fav_id="' + search_data[i].fav_id + '"></div>' +

                  '</div>' +

                  '<div class="mdk-holder">' +

                  '<div class="rating-cntr" id="rating' + search_data[i].id + '" onclick="search_res_app.rating_handler(' + search_data[i].id + ')"><span class="rate">' + search_data[i].rating + '</span>' + search_data[i].rate_status + '</div>' +

                  '</div>' +

                  '</li>';

                  heart_id[i] = "like" + search_data[i].id;

                  }

                  $('#ul_results').empty();

                  $('#ul_results').append(html_text);

                  for(var i=0; i<len; i++){

                  document.getElementById(heart_id[i]).addEventListener("click", search_res_app.like_unlike, false);

                  }

                  },

                  setResultCount: function(len) {

                  $('#result_count').empty();

                          if(len>0){

                  $('#result_count').append(len + " Results Found");

                  }

                  else{

                  $('#result_count').append("No Results Found");

                  }

                  },

                  viewCompanyDetails: function(id_company, location, com_loc, val){

                  $.ajax({

                  url: 'http://www.example.com/index.php/companies/getCompanyById',

                  crossDomain: true,

                  type: 'POST',

                  datatype: 'json',

                  data: {'com_loc': com_loc, 'date': window.localStorage.getItem("search_date"), 'output': 'json'},

                  success: function(result){

                  if(result.success){

                  window.localStorage.setObject("company_details", result.data);

                  window.localStorage.setObject("company_bookings", result.bookings);

                  window.localStorage.setObject("all_services", result.all_services);

                  window.localStorage.setObject("com_services", result.com_ser);

                  window.localStorage.setObject("maids_booked", result.maids_booked);

                  window.location = "./company-info.html";

                  }

                  else alert("Error = " + result.message);

                  },

                  error: function(result){

                  alert("AJAX Error = " + result.responseJSON.message);

                  return false;

                  }

                  });

                  }

                  }

                  /////

                  Clicking on an item will go to company-info.html page. But  when user click back button I have to back at the same clicked item. I have used scrollIntoView() function and scrollTop() function. Both not getting good results. Please suggest what I have to with this problem.

                  • 7. Re: Revert back to original position in cordova phonegap application
                    kerrishotts Adobe Employee

                    First: for long code snippets, please, please (for the sake of our eyeballs) link to a gist or other similar service. It's really hard to tell indentation and such in the above code. I've gone ahead and done it this time: Reformatted code from https://forums.adobe.com/message/9737715#9737715 · GitHub

                     

                    Second:  I see no use of scrollIntoView/scrollTop in the above code. Please share code where you're trying to use that functionality. I would expect to see something that saves which element is at the top of the view when navigating to another page, and then some code after rendering the list that checks to see if there is a saved element and then scrolls to it if there is.

                     

                    Finally, I see some potential concerns with the code as presented (not necessarily related to the issue at hand). Please don't take the following as rude or mean; I intend it only in the vein of constructive criticism and in the hopes that you can use it to make your app even better. Note that I only mention an issue once; but that doesn't mean the issue doesn't appear more than once in the code.

                     

                    • It looks like you're using a multiple page app architecture. This isn't the best choice for several reasons -- you have to persist state somewhere when changing pages, and it's slower (cordova has to reinit on every navigation). You should instead use the single page app architecture. State can remain in memory (save for state that does need to be persisted between app launches), and performance can be much better.
                    • In line 1 of your javascript, you've made search_data a global variable. While global variables aren't always bad, in this case, I think you should reevaluate this choice. This seems like data that should be passed around from function to function, and not stored as a global variable.
                    • In line 25, you're using "http". Don't -- you should always use "https" when possible. (I know that you're using an example domain, but the point still applies.) https://gist.github.com/kerrishotts/0e8c2726498d9cddae021d5db2206aaa#file-search_result-js -L25
                    • In line 35, here's a great example of where using SPA would help. With SPA you wouldn't have to persist the review data so that the reviews page could render it.
                    • In line 50, you don't pass a radix argument. This can lead to odd results, depending on the value being parsed. You should pass a 10 as the radix argument to ensure base 10 parsing.
                    • Also in line 50, you're using a capital single-letter variable name. For maintenance-sake, you should use a more descriptive variable name. You should only use caps if you're declaring a constant. CamelCaseCaps should only be applied to classes or functional components.
                    • In line 51, you're setting a style directly. It would be better to use CSS classes so that your styling is more maintainable.
                    • In line 55, you use $(this) again. Instead, you should cache the value of $(this) (call it $this or something similar).
                    • In line 96, you should use strict equality (===). Also, be consistent with your use of quotes. It's OK to use multiple forms of quotes to avoid escaping a quote, though.
                    • In line 99, you should use dot notation ("rating" is a valid name).
                    • In line 119, you are building your HTML using concatenation. This is a security risk, since a malicious search result could easily inject malicious content. I would suggest using a templating library of some sort here since the code is also very difficult to read.
                    • Also in line 119, you use an inline onclick handler. You should avoid doing so and use a single addEventListener that listens for all clicks on list items instead. For long lists, this will be more performant when scrolling.
                    • In line 140, you're using addEventListener -- that's good. But you only need to add one listener to the list rather than several for each heart. Events will bubble up to their containers, so you can catch those events at a higher level with a single event listener. This will be more performant when scrolling long lists.
                    • In line 20 of your HTML, you download fonts from Google. You should download these separately and bundle them with your app instead. (Think about what might happen if the user has no or flaky Internet access.)
                    • In line 48, you have inline styles. Use CSS stylesheets instead.
                    • In line 58, you are using inline event handlers. Use addEventListener instead.

                     

                    Several of the above would be caught by using a linter on your code. I suggest using ESLint, which is very configurable and has a lot of additional plugins for catching specific issues and such. See ESLint - Pluggable JavaScript linter.

                    • 8. Re: Revert back to original position in cordova phonegap application
                      sanils97665427 Level 1

                      Thanks mam for your great opinions.

                      I have already told you that I am a newbie in Phonegap. The website url of my original site is http://www.maidko.com. There you can see search button and on search will see a lot of items. Clicking a search button will show corresponding description page. When return back to search listed items page, it will be on the item where we clicked for description. I want similar functionality in mobile app also. Clicked from Search-results.html will go to company_info.html and return back has to show the clicked item in the Search-results.html . Here i attached company_info.html and com_info.js file. Yo can see both search-result.html and company_info.html page and I am sure that you can give me a solution.

                      Sanil · GitHub .

                      • 9. Re: Revert back to original position in cordova phonegap application
                        kerrishotts Adobe Employee

                        I understand what you want, but you've not provided code for what you've actually tried to do. You say you've tried to use scrollIntoView/scrollTop, but so far I've not seen what you've tried to do with it. That's critical in me offering any assistance (note: I won't write your code for you; you need to learn how to do this so that you can be self-sufficient).

                         

                        Of course, one of the major reasons you're having this problem in the first place is because you're not using the single-page app architecture. I would personally suggest converting to a SPA before doing anything else. Your website works because (best I can tell) it's relying on good will from the browser -- and PhoneGap isn't a browser. If your app was using SPA, everything would be within the same document, and it would be trivial to return to the same place one left off. MPA-style makes it much more difficult to handle.

                        • 10. Re: Revert back to original position in cordova phonegap application
                          sanils97665427 Level 1

                          Thanks for your response mam.

                          Previously I have send you the original code.

                          This is the gist i have made for scrolling. you can check it. Scroll · GitHub .

                          Also my app contains more functionalities such as seaching , listing, booking etc. So I have done it is based on MPA-Style. SImilar to my website www.maidko.com . Once again thanks for your response mam.

                          • 11. Re: Revert back to original position in cordova phonegap application
                            kerrishotts Adobe Employee

                            Indentation, yikes! Wouldn't hurt to fix that up next time you paste a gist. It's extremely difficult to read that.

                             

                            Why do you have quotes in line 46 (Scroll · GitHub)? Take those out; you want to find the element based on a saved ID, not a literal string.

                            • 12. Re: Revert back to original position in cordova phonegap application
                              sanils97665427 Level 1

                              Hai  madam,

                                                      I have mistakenly add some quotes there. Any how I have found solution. Thanks for your great help and support. Thank you very much. I have added the gist file here.

                              Sani · GitHub

                              Madam you were right. Using the ScrllTop() function we can solve the problem. In order to work ScrolTop() I have to add

                              -webkit-overflow-scrolling: auto;

                              in body tag.

                              Once again thanks for your support.