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


#1

is it possible to go back three or more levels using app.router.back ? I tried many things and always go back one level…

the reason:

I have a selection in one page after clicking go next I go deep one level and from that level to a second level too… until I get to the third level…

from third level I give the chance to go back to first level to start again the selection passing a data that needs to be precompiled in that page…

if I use app.router.back I go back just one level …
if I use app.router.navigate the first selection page is reset all settings…

how can I use then app.router.back telling it that it needs to go back a certain number of levels?

thanks for any ideas!


#2

did you try with stackPages?

stackPages
If enabled then all previous pages in navigation chain will not be removed from DOM when you navigate deeper and deeper. It could be useful, for example, if you have some Form from 5 steps (5 pages) and when you are on last 5th page you need access to form that was on 1st page.

https://framework7.io/docs/view.html#view-parameters


#3

Yes I tired also using going back this way and also stack pages stackpages are enabled but the problem it does not go back more than one level back using app.views, or router.navigate or app.router.back…

var mainView = app.views.create('.view-main', {
url: '/home/',
preloadPreviousPage: false
});

this does not work either

app.router.back({
url: '/home/',
force: false,
swipeBackPage: false,
});

after this if I go back manually the data is compiled in the first page but the router does not back to that page even if it is specified in the url: ‘/home/’ …

it goes back only one level from level 3 to 2 but it does not goes to level 1 where home is…

let us say level one is ‘/home/’ from level 3 I need to go back to home passing a parameter… that is all I need… but it does not goes back to home it goes to level 2 all the time … the parameter I pass it is at the home but the page stay in page 2 all the time…

strange but it is so…


#4

go to http://framework7.io/kitchen-sink/core/
go to “Swiper Slider”
go to “Swiper Horizontal”
open console :

var view=app.views.current;
view.router.back(view.history[0],{force:true});

now you are in “index”


#5

WOW it worked!! finally a shortcut!!! big thanks for the tips!!!


#6

see solution below it works now using

var view=app.views.current;
view.router.back(view.history[0],{force:true});

big thanks for your support as well! :slight_smile:


#7

let “user” decide whether to go back to home or to the prev page

var app = new Framework7({
  touch:{
    tapHold:true
  }
});

Dom7(document).on('taphold','.some-link',function(){
  var view=app.views.current;
  view.router.back(view.history[0],{force:true});
});

#8

great :slight_smile: thanks nice!

it will be great to give the option for staying in the same page as well; now if user clicks that button it goes directly to home… maybe a dialog will help either too :slight_smile:

thanks for the great tips! :+1:


#9

make it simple:

Dom7(document).on('click','.some-link',function(){
  app.dialog.create({
    title:'title',
    buttons:[
      {text:'<a class="back">Back</a>'},
      {text:'Stay'}
    ]
  }).open();
});
Dom7(document).on('taphold','.some-link',function(){
  var view=app.views.current;
  view.router.back(view.history[0],{force:true});
});

#10

Great idea! :wink:

but if you have already those class back buttons and stay buttons inside the dialog what is the reason to have tabhold there as well? I mean I just want to think about the user will be prompted with this dialog options to start again or stay there… but I think I get the idea about your thinking too, that is nice!

:slight_smile:


#11

have you received one message I sent you earlier about autocomplete; I do not know if that is possible but I am trying to make it work… :roll_eyes:

About autocomplete with more options and customize it differently


#12

go to http://framework7.io/kitchen-sink/core/
open console :

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"}]}];
var TMPL=Template7.compile(`
<li>
   <div class="item-content">
      <div class="item-inner">
         <div class="item-title"><strong>{{cityName}}, {{countryName}}</strong></div>
      </div>
   </div>
</li>
<ul>
   {{#airports}}
   <li>
      <label class="item-radio item-content">
         <input type="radio" name="{{inputName}}" value="{{value}}">
         <i class="icon icon-radio"></i>
         <div class="item-inner">
            <div class="item-title">{{name}}</div>
         </div>
      </label>
   </li>
   {{/airports}}
</ul>
`);
app.autocomplete.create({
  openIn:'popup',
  valueProperty:'ID',
  textProperty:'cityName',
  renderItem:function(item,index){
    this.items.map(function(itm){
      if(itm.ID==item.value){
        itm.airports.map(function(it){
          it.parent=itm.ID;
          it.value=it.ID;
        });
        app.utils.extend(item,itm);
      }
    }); 
    return TMPL(item)
  },
  source:function(query,render){
    if (query.length <= 1) {
      return;
    }
    // i guess you will filter the data based on the query
    // but now i'll push all the data
    render(DATA);
  },
  on:{
    open:function(a){
      a.$el.once('input','.item-radio input',function(){
        var val=this.value;
        var value={};
        for(var i=0;i<a.items.length;i++){
          for(var j=0;j<a.items[i]["airports"].length;j++){
            if(a.items[i]["airports"][j]["ID"]==val){
              value=a.items[i]["airports"][j];
              break;
            }
          }
        }
        Dom7('#origin-ajax').find('input').val(value.parent);
        Dom7('#origin-ajax').find('.item-after').text(value.name);
        a.close();
        console.log(value.parent,value.name,value)
      });
    }
  }
}).open();

#13

WOW you are a genius how fast you find some way!

I think you are a big thinker to find solutions…

I will test it tomorrow morning but taking a look at the code I think it is a big approach and solution what you found…

Five stars and more!!!
:blush::+1:


#15

here my complete code modified now the query search works to filter the city name but still have to make either the city name or airport name selectable… :frowning:


  var TMPL=Template7.compile('\
        <li>\
          <label class="item-radio item-content">\
             <input type="radio" name="{{inputName}}" value="{{value}} {{#if selected}}checked="checked"{{/if}}">\
             <i class="icon icon-radio"></i>\
              <div class="item-inner">\
                 <div class="item-title"><strong>{{name}}, {{countryName}}</strong></div>\
              </div>\
           </label>\
        </li>\
        <ul>\
           {{#airports}}\
           <li>\
              <label class="item-radio item-content">\
                 <input type="radio" name="{{../inputName}}" value="{{value}} {{#if selected}}checked="checked"{{/if}}">\
                 <i class="icon icon-radio"></i>\
                 <div class="item-inner">\
                    <div class="item-title">{{name}}</div>\
                 </div>\
              </label>\
           </li>\
           {{/airports}}\
        </ul>\
        ');

        app.autocomplete.create({
          openIn:'popup',
          openerEl: '#origin-ajax',
          multiple: false, //allow multiple values
          closeOnSelect: false, //go back after we select something
          valueProperty:'ID',
          textProperty:'name',
          renderItem:function(item,index){
            this.items.map(function(itm){
              if(itm.ID==item.value){
                itm.airports.map(function(it){
                  it.parent=itm.ID;
                  it.value=it.ID;
                });
                app.utils.extend(item,itm);
              }
            });
            return TMPL(item)
          },
          source:function(query,render){
            var autocomplete = this;
            var results = [];
            if (query.length === 0) {
              render(results);
              return;
            }

            autocomplete.preloaderShow();
            app.request({
              url: 'airports.json',
              method: 'GET',
              dataType: 'json',
              data: {
                query: query
              },
              success: function (data) {
                console.log(data);
                for (var i = 0; i < data.length; i++) {
                  if (data[I].name.toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(data[i]);
                }
                autocomplete.preloaderHide();
                render(results);
              }
            });


          },
          on:{
            open:function(a){

              a.$el.once('input','.item-radio input',function(){
                var val=this.value;
                var value={};
                for(var i=0;i<a.items.length;i++){
                  for(var j=0;j<a.items[i]["airports"].length;j++){
                    if(a.items[i]["airports"][j]["ID"]==val){
                      value=a.items[i]["airports"][j];
                      break;
                    }
                  }
                }
                Dom7('#origin-ajax').find('input').val(value.parent);
                Dom7('#origin-ajax').find('.item-after').text(value.name);
                a.close();
                console.log(value.parent,value.name,value)
              });
            },
            change: function (value) {
              console.log(value);

              var itemText = [],
                  inputValue = [];

              for (var i = 0; i < value.length; i++) {
                itemText.push(value[i].name);
                inputValue.push(value[i].id);
              }
              // Add item text value to item-after
              Dom7('#origin-ajax').find('input').val(value.join(', '));
              Dom7('#origin-ajax').find('.item-after').text(value.join(', '));
            }

          }
        });
    

the airport.json I just modify something on the city I added “name”: , so I can use this for airports and cities…

[{
    "ID": "MILMIL",
    "locationID": 4630,
    "locationCode": "MIL",
    "name": "Milan",
    "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": "MILXIK",

            "airportCode": "XIK",
            "name": "Milano Centrale Railway Station",
            "latitude": 45.4859,
            "longitude": 9.20428,
            "cityCode": "MIL",
            "cityName": "Milan",
            "countryCode": "IT",
            "countryName": "Italy"
        },
        {
          "ID": "MILIMR",

            "airportCode": "IMR",
            "name": "Milano Rogoredo Railway Station",
            "latitude": 45.4336,
            "longitude": 9.23849,
            "cityCode": "MIL",
            "cityName": "Milan",
            "countryCode": "IT",
            "countryName": "Italy"
        }
    ]
},
{
  "ID": "LONLON",

    "locationID": 4254,
    "locationCode": "LON",
    "name": "London",
    "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"
        },
        {
            "airportCode": "LGW",
            "name": "London Gatwick Airport",
            "latitude": 51.1481,
            "longitude": -0.190278,
            "cityCode": "LON",
            "cityName": "London",
            "countryCode": "GB",
            "countryName": "United Kingdom"
        },
        {
            "airportCode": "LHR",
            "name": "London Heathrow Airport",
            "latitude": 51.4775,
            "longitude": -0.461389,
            "cityCode": "LON",
            "cityName": "London",
            "countryCode": "GB",
            "countryName": "United Kingdom"
        },
        {
            "airportCode": "STN",
            "name": "London Stansted Airport",
            "latitude": 51.885,
            "longitude": 0.235,
            "cityCode": "LON",
            "cityName": "London",
            "countryCode": "GB",
            "countryName": "United Kingdom"
        },
        {
            "airportCode": "LTN",
            "name": "London Luton Airport",
            "latitude": 51.8747,
            "longitude": -0.368333,
            "cityCode": "LON",
            "cityName": "London",
            "countryCode": "GB",
            "countryName": "United Kingdom"
        },
        {
            "airportCode": "XQE",
            "name": "Ebbsfleet Kent Station",
            "latitude": 51.5074,
            "longitude": -0.127758,
            "cityCode": "LON",
            "cityName": "London",
            "countryCode": "GB",
            "countryName": "United Kingdom"
        },
        {
            "airportCode": "QQP",
            "name": "Paddington Railway Station",
            "latitude": 51.5154,
            "longitude": -0.175743,
            "cityCode": "LON",
            "cityName": "London",
            "countryCode": "GB",
            "countryName": "United Kingdom"
        },
        {
            "airportCode": "QQK",
            "name": "Kings Cross Railway Station",
            "latitude": 51.5316,
            "longitude": -0.124423,
            "cityCode": "LON",
            "cityName": "London",
            "countryCode": "GB",
            "countryName": "United Kingdom"
        },
        {
            "airportCode": "QQU",
            "name": "Euston Railway Station",
            "latitude": 51.5285,
            "longitude": -0.133844,
            "cityCode": "LON",
            "cityName": "London",
            "countryCode": "GB",
            "countryName": "United Kingdom"
        },
        {
            "airportCode": "ZEP",
            "name": "Victoria Railway Station",
            "latitude": 51.4952,
            "longitude": -0.143898,
            "cityCode": "LON",
            "cityName": "London",
            "countryCode": "GB",
            "countryName": "United Kingdom"
        },
        {
            "airportCode": "QQS",
            "name": "London St. Pancras Railway Station Airport",
            "latitude": 51.885,
            "longitude": 0.235,
            "cityCode": "LON",
            "cityName": "London",
            "countryCode": "GB",
            "countryName": "United Kingdom"
        },
        {
            "airportCode": "SEN",
            "name": "London Southend Airport",
            "latitude": 51.5698,
            "longitude": 0.703737,
            "cityCode": "LON",
            "cityName": "London",
            "countryCode": "GB",
            "countryName": "United Kingdom"
        }
    ]
}
]


#17

I found these issues so I corrected above that why radios names were empty for airports… it should be “{{…/inputName}}” and not "{{inputName}} inside an #each… clause and the value stays the same I think “{{value}}”

but even if now the radios has names and values on change function… the selected value is not marked as selected when returning back to the search… or opening up again the search only marked selected the city name not the airport name…

select an airport name is always undefined on change function…

weird… :confused:

I think we are closer to get It work… but missing something…


           {{#airports}}\
           <li>\
              <label class="item-radio item-content">\
                 <input type="radio" name="{{../inputName}}" value="{{value}}" {{#if selected}}checked="checked"{{/if}}>\
                 <i class="icon icon-radio"></i>\
                 <div class="item-inner">\
                    <div class="item-title">{{name}}</div>\
                 </div>\
              </label>\
           </li>\
           {{/airports}}\


#19

now you are more clear

try this:
do not change/add/remove anything
just copy/paste
i changed some default-b, so be carefull

var TMPL=Template7.compile('\
  <li>\
    <label class="item-radio item-content">\
      <input type="radio" value="{{value}}" {{#if selected}}checked="checked"{{/if}}>\
      <i class="icon icon-radio"></i>\
      <div class="item-inner">\
        <div class="item-title"><strong>{{name}}</strong></div>\
      </div>\
    </label>\
  </li>\
  <ul>\
    {{#airports}}\
    <li>\
      <label class="item-radio item-content">\
        <input type="radio" value="{{value}}" data-value="{{ID}}" {{#if selected}}checked="checked"{{/if}}>\
        <i class="icon icon-radio"></i>\
        <div class="item-inner">\
          <div class="item-title">{{name}}</div>\
        </div>\
      </label>\
    </li>\
    {{/airports}}\
  </ul>\
');
app.autocomplete.create({
  openIn:'popup',
  openerEl: '#origin-ajax',
  closeOnSelect: true,
  valueProperty:'ID',
  textProperty:'cityName',
  source:function(query,render){
    var autocomplete = this;
    var results = [];
    if (!query.length) {
      render(results);
      return;
    }
    autocomplete.preloaderShow();
    app.request({method:'GET',dataType:'json',url:'airports.json',
      success:function(data){
        results=data.filter(function(itm){
          return itm.cityName.toLowerCase().indexOf(query.toLowerCase()) >= 0;
        });
        autocomplete.preloaderHide();
        render(results);
      }
    });
  },
  renderItem:function(item,index){
    var self=this;
    var target=self.$openerEl.find('input');
    self.items.map(function(itm){
      if(itm.ID==item.value){
        itm.airports.map(function(it){
          app.utils.extend(it,{
            value:itm.ID,
            selected:(target.attr('data-value')==it.ID)
          });
        });
        itm.name=itm.cityName+', '+itm.countryName;
        itm.selected=(target.attr('data-value')==itm.ID);
        app.utils.extend(item,itm);
      }
    });
    return TMPL(item);
  },
  on:{
    open:function(a){
      a.$el.once('input','.item-radio input',function(e){
        var target=Dom7(this);
        var value=target.attr('data-value');
        for(var i=0;i<a.items.length;i++){
          if(a.items[i]["ID"]==target.val() && value==null){
            a.items[i].value=target.val();
            a.params.on.change(a,a.items[i]);
            break;
          }
          for(var j=0;j<a.items[i]["airports"].length;j++){
            if(a.items[i]["airports"][j]["ID"]==value){
              a.params.on.change(a,a.items[i]["airports"][j]);
              break;
            }
          }
        }
      });
    },    
    change:function(a,value){
      if(!value){return;}
      a.$openerEl.find('input').val(value.value).attr('data-value',value.ID);
      a.$openerEl.find('.item-after').text(value.name);
      console.log('change',value.ID,value);
    }
  }
});

#20

Big thanks again for your attention and dedication to find solutions…
you are really helpful indeed! I will be testing the code tomorrow … and give you my feedback… :blush:


#21

I have tried the code again without adding anything but still the selection it is not possible… not selectable… did you tried on your side and it works?

here I share my code again, I shorted out the JSON a bit for the test…


<template>

<div class="page">
  <div class="page-content">

    <div class="list">

      <div class="border no-hairlines-md">
        <ul>
          <li>
            <a href="#" id="origin-ajax" class="item-link item-content autocomplete-opener">
              <input type="hidden" />
              <div class="item-inner">
                <div class="item-title">From</div>
                <div class="item-after"></div>
              </div>
            </a>
          </li>
        </ul>
      </div>


  </div>
</div>

</template>

<style>
  p {
    margin: 10px 0;
  }

  .md .list .item-inner {
  	border-radius: 5px;
  	font: 100 normal normal 20px/1.3 Helvetica Neue, sans-serif;
  }
  .md .list .item-after {
  	color: #282828;
  	font-size: 20px;
  	padding-left: 8px;
  }

  .md .list input[type="text"] {
  	font: 400 normal normal 17px/1.3 Helvetica Neue, sans-serif;
  	height: none;
  	width: 230px;
  	ffffloat: right;
  	font-size: 20px;
  }

  .md .list .border {
  	background: rgba(221, 221, 221, 0.31);
  	border-radius: 0px;
  	margin: 4px;
  	border: 2px solid #2a333c;
    margin: 0 auto;
  }

  .md .list .item-inner {
  	border-radius: 5px;
  	font: 100 normal normal 20px/1.3 Helvetica Neue, sans-serif;
  }

</style>
<script>
  return {
    // Component Data
    data: function () {
      // Must return an object
      return {
      }
    },
    // Component Methods
    methods: {
    },
    // Page Events
    on: {
      pageInit: function(e, page) {
        //console.log('pageInit', page);
        var self = this;
        var app = self.$app;
        var $ = self.$;

        var TMPL=Template7.compile('\
          <li>\
            <label class="item-radio item-content">\
              <input type="radio" value="{{value}}" {{#if selected}}checked="checked"{{/if}}>\
              <i class="icon icon-radio"></i>\
              <div class="item-inner">\
                <div class="item-title"><strong>{{name}}</strong></div>\
              </div>\
            </label>\
          </li>\
          <ul>\
            {{#airports}}\
            <li>\
              <label class="item-radio item-content">\
                <input type="radio" value="{{value}}" data-value="{{ID}}" {{#if selected}}checked="checked"{{/if}}>\
                <i class="icon icon-radio"></i>\
                <div class="item-inner">\
                  <div class="item-title">{{name}}</div>\
                </div>\
              </label>\
            </li>\
            {{/airports}}\
          </ul>\
        ');



        app.autocomplete.create({
          openIn:'popup',
          openerEl: '#origin-ajax',
          closeOnSelect: true,
          valueProperty:'ID',
          textProperty:'cityName',
          source:function(query,render){
            var autocomplete = this;
            var results = [];
            if (!query.length) {
              render(results);
              return;
            }
            autocomplete.preloaderShow();
            app.request({method:'GET',dataType:'json',url:'airports.json',
              success:function(data){
                results=data.filter(function(itm){
                  return itm.cityName.toLowerCase().indexOf(query.toLowerCase()) >= 0;
                });
                autocomplete.preloaderHide();
                render(results);
              }
            });
          },
          renderItem:function(item,index){
            var self=this;
            var target=self.$openerEl.find('input');
            self.items.map(function(itm){
              if(itm.ID==item.value){
                itm.airports.map(function(it){
                  app.utils.extend(it,{
                    value:itm.ID,
                    selected:(target.attr('data-value')==it.ID)
                  });
                });
                itm.name=itm.cityName+', '+itm.countryName;
                itm.selected=(target.attr('data-value')==itm.ID);
                app.utils.extend(item,itm);
              }
            });
            return TMPL(item);
          },
          on:{
            open:function(a){
              a.$el.once('input','.item-radio input',function(e){
                var target=Dom7(this);
                var value=target.attr('data-value');
                for(var i=0;i<a.items.length;i++){
                  if(a.items[i]["ID"]==target.val() && value==null){
                    a.items[i].value=target.val();
                    a.params.on.change(a,a.items[i]);
                    break;
                  }
                  for(var j=0;j<a.items[i]["airports"].length;j++){
                    if(a.items[i]["airports"][j]["ID"]==value){
                      a.params.on.change(a,a.items[i]["airports"][j]);
                      break;
                    }
                  }
                }
              });
            },
            change:function(a,value){
              console.log(value);
              if(!value){return;}
              a.$openerEl.find('input').val(value.value).attr('data-value',value.ID);
              a.$openerEl.find('.item-after').text(value.name);
              console.log('change',value.ID,value);
            }
          }
        });


      }
    }
  }
</script>


the JSON airports.json

[{
    "ID": "MILMIL",
    "locationID": 4630,
    "locationCode": "MIL",
    "name": "Milan",
    "latitude": "",
    "longitude": "",
    "cityCode": "MIL",
    "cityName": "Milan",
    "countryCode": "IT",
    "countryName": "Italy",
    "airports": [
        {
          "ID": "MILBGY",
            "airportCode": "BGY",
            "name": "Milan Bergamo\/Orio al Serio Airport",
            "countryCode": "IT"
        },
        {
          "ID": "MILLIN",
            "airportCode": "LIN",
            "name": "Milan Linate Airport",
            "countryCode": "IT"
        },
        {
          "ID": "MILMXP",
            "airportCode": "MXP",
            "name": "Milan Malpensa Airport",
            "countryCode": "IT"
        }
    ]
},
{
  "ID": "LONLON",

    "locationID": 4254,
    "locationCode": "LON",
    "name": "London",
    "latitude": "",
    "longitude": "",
    "cityCode": "LON",
    "cityName": "London",
    "countryCode": "GB",
    "countryName": "United Kingdom",
    "airports": [
        {
          "ID": "LONLCY",
            "airportCode": "LCY",
            "name": "London City Airport",
            "countryCode": "GB"
        },
        {
          "ID": "LONLGW",
            "airportCode": "LGW",
            "name": "London Gatwick Airport",
            "countryCode": "GB"
        },
        {
          "ID": "LONLHR",
            "airportCode": "LHR",
            "name": "London Heathrow Airport",
            "countryCode": "GB"
        },
        {
          "ID": "LONSTN",
            "airportCode": "STN",
            "name": "London Stansted Airport",
            "countryCode": "GB"
        }
    ]
}
]

#22

works for me

first try it like this (without request)
then see what is worng

<template>
<div class="page">
  <div class="page-content">
    <div class="list">
      <div class="border no-hairlines-md">
        <ul>
          <li>
            <a href="#" id="origin-ajax" class="item-link item-content autocomplete-opener">
              <input type="hidden" />
              <div class="item-inner">
                <div class="item-title">From</div>
                <div class="item-after"></div>
              </div>
            </a>
          </li>
        </ul>
      </div>
    </div>
  </div>
</div>
</template>

<style>
  p {
    margin: 10px 0;
  }

  .md .list .item-inner {
  	border-radius: 5px;
  	font: 100 normal normal 20px/1.3 Helvetica Neue, sans-serif;
  }
  .md .list .item-after {
  	color: #282828;
  	font-size: 20px;
  	padding-left: 8px;
  }

  .md .list input[type="text"] {
  	font: 400 normal normal 17px/1.3 Helvetica Neue, sans-serif;
  	height: none;
  	width: 230px;
  	ffffloat: right;
  	font-size: 20px;
  }

  .md .list .border {
  	background: rgba(221, 221, 221, 0.31);
  	border-radius: 0px;
  	margin: 4px;
  	border: 2px solid #2a333c;
    margin: 0 auto;
  }

  .md .list .item-inner {
  	border-radius: 5px;
  	font: 100 normal normal 20px/1.3 Helvetica Neue, sans-serif;
  }

</style>
<script>
  return {
    // Component Data
    data: function () {
      // Must return an object
      return {
      }
    },
    // Component Methods
    methods: {
    },
    // Page Events
    on: {
      pageInit: function(e, page) {
        //console.log('pageInit', page);
        var self = this;
        var app = self.$app;
        var $ = self.$;

        var TMPL=Template7.compile('\
          <li>\
            <label class="item-radio item-content">\
              <input type="radio" value="{{value}}" {{#if selected}}checked="checked"{{/if}}>\
              <i class="icon icon-radio"></i>\
              <div class="item-inner">\
                <div class="item-title"><strong>{{name}}</strong></div>\
              </div>\
            </label>\
          </li>\
          <ul>\
            {{#airports}}\
            <li>\
              <label class="item-radio item-content">\
                <input type="radio" value="{{value}}" data-value="{{ID}}" {{#if selected}}checked="checked"{{/if}}>\
                <i class="icon icon-radio"></i>\
                <div class="item-inner">\
                  <div class="item-title">{{name}}</div>\
                </div>\
              </label>\
            </li>\
            {{/airports}}\
          </ul>\
        ');
        app.autocomplete.create({
          openIn:'popup',
          openerEl: '#origin-ajax',
          closeOnSelect: true,
          valueProperty:'ID',
          textProperty:'cityName',
          source:function(query,render){
            var autocomplete = this;
            var results = [];
            if (!query.length) {
              render(results);
              return;
            }
            autocomplete.preloaderShow();
            //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){
                  return itm.cityName.toLowerCase().indexOf(query.toLowerCase()) >= 0;
                });
                autocomplete.preloaderHide();
                render(results);
            //  }
            //});
          },
          renderItem:function(item,index){
            var self=this;
            var target=self.$openerEl.find('input');
            self.items.map(function(itm){
              if(itm.ID==item.value){
                itm.airports.map(function(it){
                  app.utils.extend(it,{
                    value:itm.ID,
                    selected:(target.attr('data-value')==it.ID)
                  });
                });
                itm.name=itm.cityName+', '+itm.countryName;
                itm.selected=(target.attr('data-value')==itm.ID);
                app.utils.extend(item,itm);
              }
            });
            return TMPL(item);
          },
          on:{
            open:function(a){
              a.$el.once('input change','.item-radio input',function(e){
                var target=Dom7(this);
                var value=target.attr('data-value');
                for(var i=0;i<a.items.length;i++){
                  if(a.items[i]["ID"]==target.val() && value==null){
                    a.items[i].value=target.val();
                    a.params.on.change(a,a.items[i]);
                    break;
                  }
                  for(var j=0;j<a.items[i]["airports"].length;j++){
                    if(a.items[i]["airports"][j]["ID"]==value){
                      a.params.on.change(a,a.items[i]["airports"][j]);
                      break;
                    }
                  }
                }
              });
            },
            change:function(a,value){
              console.log(value);
              if(!value){return;}
              a.$openerEl.find('input').val(value.value).attr('data-value',value.ID);
              a.$openerEl.find('.item-after').text(value.name);
              console.log('change',value.ID,value);
            }
          }
        });


      }
    }
  }
</script>

#23

What version of Framework7 do you have installed? just in case the problem it is the framework7 version… and not the code…

trying again … let you know thanks