App.router.back go back a certain amount of levels back?

Yes it seems to work without the use of request !!! Amazing it is possible to do this!!

strange behaviour that with request stop working properly but let you know what I find here and there soon…

you are a genius! :slight_smile: :tada:

i got v3.5.2

note that i changed this:

a.$el.once('input','.item-radio input',function(e){

to this:

a.$el.once('input change','.item-radio input',function(e){

maybe the ‘input’ didn’t get fire on your machine

1 Like

Yes didn’t get fired I think you are right! u r genius! :wink::+1:
I am updating my framework7 to the latest update too…

regards and big thanks for your support in finding a good solution to custom the search in such a way it does what it does now!!! big thanks for begin supportive in the forum!!

:tada:

Do you know if it is possible for the framework7 autocompleted also to look up for a different field when searching…

I mean in my case I type Milan and I see all airports of Milan, but if I type an airport of Milan it does not show anything because it is inside Milan…

Let us say I want to type Bergamo not Milan … and retrieve not only a city match with the word Bergamo but also any airport name with that name…

below it is the sample, not bergamo only display if I type Milan…

do you think is it also possible to search hidden fields or name of city and name of airports at the same time?

yes
just change the filter inside “app.request.success” callback

//app.request({method:'GET',dataType:'json',url:'airports.json',
//  success:function(data){
    var data=[{"ID":"MILMIL","locationID":4630,"locationCode":"MIL","latitude":"","longitude":"","cityCode":"MIL","cityName":"Milan","countryCode":"IT","countryName":"Italy","airports":[{"ID":"MILBGY","airportCode":"BGY","name":"Milan Bergamo\/Orio al Serio Airport","latitude":45.6689,"longitude":9.70028,"cityCode":"MIL","cityName":"Milan","countryCode":"IT","countryName":"Italy"},{"ID":"MILLIN","airportCode":"LIN","name":"Milan Linate Airport","latitude":45.4494,"longitude":9.27833,"cityCode":"MIL","cityName":"Milan","countryCode":"IT","countryName":"Italy"},{"ID":"MILMXP","airportCode":"MXP","name":"Milan Malpensa Airport","latitude":45.63,"longitude":8.72306,"cityCode":"MIL","cityName":"Milan","countryCode":"IT","countryName":"Italy"}]},{"ID":"LONLON","locationID":4254,"locationCode":"LON","latitude":"","longitude":"","cityCode":"LON","cityName":"London","countryCode":"GB","countryName":"United Kingdom","airports":[{"ID":"LONLCY","airportCode":"LCY","name":"London City Airport","latitude":51.505,"longitude":0.0541667,"cityCode":"LON","cityName":"London","countryCode":"GB","countryName":"United Kingdom"},{"ID":"LONLGW","airportCode":"LGW","name":"London Gatwick Airport","latitude":51.1481,"longitude":-0.190278,"cityCode":"LON","cityName":"London","countryCode":"GB","countryName":"United Kingdom"},{"ID":"LONLHR","airportCode":"LHR","name":"London Heathrow Airport","latitude":51.4775,"longitude":-0.461389,"cityCode":"LON","cityName":"London","countryCode":"GB","countryName":"United Kingdom"},{"ID":"LONSTN","airportCode":"STN","name":"London Stansted Airport","latitude":51.885,"longitude":0.235,"cityCode":"LON","cityName":"London","countryCode":"GB","countryName":"United Kingdom"}]}];
    results=data.filter(function(itm){
      var parent=itm.cityName.toLowerCase().indexOf(query.toLowerCase()) >= 0;
      if (!parent) {
        var child=itm.airports.filter(function(it){
          return it.name.toLowerCase().indexOf(query.toLowerCase()) >= 0;
        });
        if (child.length) {
          itm.airports=child;
          parent=true;
        }
      }
      return parent;
    });
    autocomplete.preloaderHide();
    render(results);
//  }
//});
1 Like

Ohh I tried to do that in different way with filter too… but it didn’t work properly I guess you have a better coding here as I see it! Big thanks for the tips!

I will try it and let you know soon!
Regards!
:blush:

It worked perfectly you are genius to simplify the code lines! :tada:

I just modify it a little bit too the code you sent me to add more options to search for others fields… like airportCode that some people only remember the code and not the name :relaxed:

for instance if the airport code is BGY can type BGY as well…

    "airportCode": "BGY",

here my modified version of your code to add airportCode…

    results=data.filter(function(itm){
                  var parent=itm.cityName.toLowerCase().indexOf(query.toLowerCase()) >= 0;
                  if (!parent) {
                    var child=itm.airports.filter(function(it){
                      return it.name.toLowerCase().indexOf(query.toLowerCase()) >= 0 ||
                      it.airportCode.toLowerCase().indexOf(query.toLowerCase()) >= 0;
                    });
                    if (child.length) {
                      itm.airports=child;
                      parent=true;
                    }
                  }
                  return parent;
                });

I think this way it is so easy to add lot of extra search fields :slight_smile: big thanks

1 Like

May I ask you something about autocomplete and big JSON files?

do you have experience with large JSON files and the use of autocomplete?

more than 8 megabytes in my case the search starts getting pretty slow… I tried to limit to 10 results when doing the search for this reason and fast response…

But for instance, when you have a big JSON file with all the cities around the world for flight destinations mine it is around 1.200,345 cities that needs to be searched for a destination…

this JSON file is sized in 28 megabytes size… what do you think will be the best practice here? any recommendation?

do you think It is too big for the autocomplete and need to go inside a database? I prefer to put the file locally inside the app than inside a database because it is not critical information and locally I think will be faster… but maybe I am thinking wrong…

what do you think about it? Mysql with api crud seems slow down a lot things… this is why I prefer to keep file locally…

Best regards

local vs server ?
as always the answer is “it depends”
i guess any other answer will be wrong

anyway :

  • 28 megabytes it’s a lot (to me)
  • the “parent-child” structure seems to be heavy

if you use your JSON “locally” (static) :
DO NOT request the JSON in every query
one time (globally) is enough

1 Like

I think you are right! because the structure of autocomplete when making the request it sends the request every time I type something different…

One time globally must be the way… testing that in the browser it is slow … but maybe after compilation will be fast I do not know yet…

I will try many methods for the destination cities selection and let you know if I find a fastest way… I tried also to minimise the name labels in the JSON and so to minimise JSON size…

best regards and thanks again for the ideas!
:blush::+1:

just copy/paste to your console
and post the output (only the average)

var obj={
  cities:1200000, // max cities
  airports:5,     // max airports
  maxTest:10,     // max test
  data:[],
  init:function(){
    var self=this;
    console.log('create data...');
    var start=new Date().getTime();
    for(var i=1;i<=self.cities;i++){
      var city={
        cityName:"name-"+i, /* unique cityName */
        ID:"dummy",locationID:"dummy",locationCode:"dummy",
        latitude:"dummy",longitude:"dummy",cityCode:"dummy",
        countryCode:"dummy",countryName:"dummy",
        airports:[]
      };
      for(var j=1;j<=self.airports;j++){
        city.airports.push({
          name:"name-"+i+"-"+j, /* unique name */
          ID:"dummy",airportCode:"dummy",
          latitude:"dummy",longitude:"dummy",cityCode:"dummy",
          cityName:"dummy",countryCode:"dummy",countryName:"dummy"
        });
      }
      self.data.push(city);
    }
    var time=new Date().getTime()-start;
    console.log('data created in',time+'ms')
  },
  test:function(query){
    var self=this;
    console.log('start test:',query)
    var average=[];
    for(var i=1;i<=self.maxTest;i++){
      var start=new Date().getTime();
      var result=obj.data.filter(function(itm){
        var parent=itm.cityName.toLowerCase().indexOf(query.toLowerCase()) >= 0;
        if (!parent) {
          var child=itm.airports.filter(function(it){
            return it.name.toLowerCase().indexOf(query.toLowerCase()) >= 0;
          });
          if (child.length) { itm.airports=child; parent=true; }
        }
        return parent;
      });
      var time=new Date().getTime()-start;
      average.push(time)
      console.log('test n.',i,time+'ms',result)
    }
    var ave=average.reduce(function(a,b){return a+b})/average.length;
    console.log('end test',query,'average :',ave+'ms')
  }
};
obj.init();

obj.test('name-1200000-5');
obj.test('name-1200000');
obj.test('name-600000-5');
obj.test('name-600000');
obj.test('name-300000-5');
obj.test('name-300000');
obj.test('name-150000-5');
obj.test('name-150000');
obj.test('name-75000-5');
obj.test('name-75000');
1 Like

Yeah, it is better to include it via <script src="path/to/cities.js"> and in this file having something like:

var cities = [
  ... // thousands of cities
];

And then it will be abailable as window.cities

But even better is to use database (if applicable) that can be used via XHR and returning cities matching to query.

1 Like

thanks I will try it and let you know if my big JSON works faster… great idea :slight_smile: :tada:

thanks for ideas… I really need to get to the search and search fast inside a big data file…

thank I am doing that now still a bit slow! but I can handle it…
do you have a sample of code with autocomplete because this is what I am using that can pull the data in some faster way to filter it with the query string input?

I mean the query is a city: London… it searches the database and return back all matches starting with Lon (3 characters at least…) and give me a list of cities…

that is my example! I decided to use Google Maps API to create the city list…

Is this for version 1.x? If so, does it work with dynamic pages? I tried and it doesn’t seem to be working.

post your code here!

Since this is v1, there is only 1 param so I changed it to be like this.

_this.navigationView.router.back({
    url: _this.navigationView.history[0],
    force:true
});

In the history in this case, I have 3 entries [’#main’, ‘#content-1’, ‘#content-2’].

When I invoke the back function, nothing happened.

In my case I use now the latest version so if I logout of my app I just do this:

        $f7.views.main.router.navigate('/', {
          reloadAll: true,
          ignoreCache: true,
          clearPreviousHistory: true
        });

or in your case it will be:

$f7.views.main.router.back(url, options);

I believe that’s for version 2 since version 1.x only has 1 param. If I use what you suggested, I get an error because an object in expected for first param instead of string (url).

Unfortunately, I can’t move to latest version coz it doesn’t support dynamic pages. I’m waiting for a response on a separate thread on how to potentially switch by manipulating the routers list manually.