Autocomplete with Ajax strange behaviour when using external url script to call for json data

when using autocomplete without a json file in the url but calling a script that generate the json in return the results items are duplicating itself and showing instead of the searched word it shows all matches of all single letters of the searched word…

using this
url: “assets/request_cities.php”,

instead of
url: “assets/cities.json”,

I have big cities database to look for matches and I cannot use a json file for this but I need to consult the db to return the matching records… this is why I need to use .php script…

any solution for this behaviour ?

https://github.com/framework7io/framework7/blob/master/kitchen-sink/pages/autocomplete.html#L310

here the code

    // Dropdown with ajax data
    self.autocompleteDropdownAjax = app.autocomplete.create({
      openerEl: "#destination-ajax", //link that opens autocomplete
      multiple: false, //allow multiple values
      valueProperty: 'id', //object's "value" property name
      textProperty: 'name', //object's "text" property name



      openIn: "popup", //open in page
      preloader: true, //enable preloader
      /* If we set valueProperty to "id" then input value on select will be set according to this property */
      valueProperty: 'name', //object's "value" property name
      textProperty: 'name', //object's "text" property name
      limit: 20, //limit to 20 results
      dropdownPlaceholderText: 'Try "JavaScript"',
      source: function (query, render) {
        var autocomplete = this;
        var results = [];
        if (query.length === 0) {
          render(results);
          return;
        }
        // Show Preloader
        autocomplete.preloaderShow();
        //alert('');
        // Do Ajax request to Autocomplete data
        app.request({
          url: "assets/request_cities.php",
          method: 'POST',
          dataType: 'json',
          //send "query" to server. Useful in case you generate response dynamically
          data: {
            query: query,
          },
          success: function (data) {
            // Find matched items
            console.log(data);
            for (var i = 0; i < data.length; i++) {
              if (data[i].name.toLowerCase().indexOf(query.toLowerCase()) >= 0) results.push(data[i]);
            }
            // Hide Preoloader
            autocomplete.preloaderHide();
            // Render items by passing array with result items
            render(results);
          }
        });
      }
    });

in the php:

$query = $_POST[‘query’];

$results = $db->rawQuery("SELECT * from t_cities where Name like ‘%$query%’ ");

        foreach ($results as $row) 
        {
            $data []= array(
            "id" => $row['cityID'],        
            "name" => $row['Name']
        );

        }

echo $json = json_encode($data,JSON_PRETTY_PRINT);

I think you need to do a JSON.parse(data) inside of success callback

Or not. Hard to say like that, there shouldn’t be any difference if your script returns correct JSON. Do you have a live example to check?

Yes I can upload the sample code online… I will send you the link soon

here the link to a test page:

http://secure-s110src.tripsbro.com/test/

when entering you will see the page transition and then the swiper slider as the slider…
if you here at already know where to go “click here” it will open a page that I modify the width to look like a modal… inside this page there is:

origin
destination

origin is calculated automatically and it is fed using a json file while destination must be selected from the search… and using a php script in the request…

try then to check in the console what I mean

when typing a city name in the search of destination it will look for that city name and will return the matches the problem is then after typing it, the results are shown only for a few seconds and then the return matches change again and again… and the results at the end are showing wrong matches…

I do not know why this is happening but when I use a .json file as the url in the Ajax request it works fine as in the origin… and no problem but when using the script in the destination field to consult the db and get the json file with the cities this problem is happening without any reason apparently no clue why this is happening if the json generated is fine if I check it… no clue what is causing the problem…

the app.request is GET in this case and send a query containing the name of the city is you look for this cities in the script you will see the resulting json array:

http://secure-s110src.tripsbro.com/test/assets/request_cities.php?query=london
http://secure-s110src.tripsbro.com/test/assets/request_cities.php?query=sydney

but when typing London or Sydney in the destination search box of the autocomplete the problem comes up… check the console when typing the city name… I print the results of the request in the console so you can see what I mean… so weird…

but if you check the script directly it is showing the correct matches

http://secure-s110src.tripsbro.com/test/assets/request_cities.php?query=london

below it is the autocomplete with Ajax I am using:

// Standalone With Ajax
self.autocompleteStandaloneAjax = app.autocomplete.create({
openIn: “popup”, //open in page
openerEl: “#destination-ajax”, //link that opens autocomplete
multiple: false, //allow multiple values
closeOnSelect: true, //go back after we select something
valueProperty: “id”, //object’s “value” property name
textProperty: “name”, //object’s “text” property name
limit: 50,
requestSourceOnOpen: false,
preloader: true, //enable preloader
source: function(query, render) {
var data = [
{}
];

      var autocomplete = this;
      var results = [];

      if (query.length === 0) {
        results = data;
        render(results);
        return;
      }
      // Show Preloader
      autocomplete.preloaderShow();
      // Do Ajax request to Autocomplete data
      console.log('query');
      console.log(query);

      app.request({
        url: "assets/request_cities.php",
        method: "GET",
        dataType: "json",
        //send "query" to server. Useful in case you generate response dynamically
        data: {
          query: query
        },
        success: function(data) {
          console.log(data);
          // Find matched items
          for (var i = 0; i < data.length; i++) {
            if (
              data[i].name.toLowerCase().indexOf(query.toLowerCase()) >= 0
            )
              results.push(data[i]);
          }
          // Hide Preoloader
          autocomplete.preloaderHide();
          // Render items by passing array with result items
          render(results);
        }
      });
    },
    on: {
      change: function(value) {
        var itemText = [],
          inputValue = [];
        for (var i = 0; i < value.length; i++) {
          console.log(value[i].id);
          itemText.push(value[i].name);
          inputValue.push(value[i].id);
        }

        // Add item text value to item-after
        $("#destination-ajax")
          .find(".item-after")
          .text(itemText.join(", "));
        // Add item value to input value
        $("#destination-ajax")
          .find("input")
          .val(inputValue.join(", "));
      }
    }
  });

I will appreciate your feedback Vladimir! big thanks
anything let me know…

  1. A second problem I see but it has to do with the swiper it is that when you use the swiper with loop and fade… a problem occurs with the onclick links inside the slide specially when LOOP is true…

in my case it is a gallery of images and each image has a link to mark that as a favorite so every slide has a link with a click to do this… in this case I use a heart shape SVG as a link for onclick action to do this… in my sample I just link it to a method …

the problem is that when the first slide in LOOP mode appears again the links inside this first slide stop working… this happen only in the first slide duplicating it in LOOP mode for the rest the links onclick works fine…

any ideas what is causing this problem with the swiper too?
thanks

this is how it should work
when you search for "london"
you make 6 ajax (async:true)

“l” => 54060 results
"lo" => 6232 results
"lon" => 976 results
"lond" => 21 results
"londo" => 5 results
"london" => 5 results

if you type “london” quickly:
the result of the first ajax will return last
because it take time to your db=>php=>webServer to process 54060 results

  • you can make your ajax async:false (not recommended)
  • or try to design better your db/sql-query (recommended)
  • or set minimum query to 2 char :
//if (query.length === 0) { return; }
if (query.length <= 1) { return; }
1 Like

thanks!

but I have tried this in the query but still the same issue when displaying the records in JSON format from the db…

maybe there is a better to stop this behaviour from coming up… or wait for Vladimir to take a look at… and see if there is another way easier to do this…

I will give a try to 2 chars but same issue… happening…
let us see… :confused:

//var results = [];
app.request({
  url:"assets/request_cities.php",
  success:function(data){
    autocomplete.preloaderHide();
    render(data);
  }
});
2 Likes

I will give a try now with this and see what happens thanks

1 Like

PLPL. big thanks this made the difference and the query is now returning only the last results after finishing typing!

I modified the lines:

if (query.length <= 1) { return; }

and

app.request({
url:“assets/request_cities.php”,
success:function(data){
autocomplete.preloaderHide();
render(data);
}
});

and now you can see it online again that is returning only matching records as it should do with a json file, I did not change the db query I only applied this fix… I think it is a big solution when the search data is coming from a db side…

maybe a good to know for everyone with big db tables … I do not know if this is the best solution for this case but it works :slight_smile: big thanks for the time to reply!!!

in case you want to take a look at the swiper problem with links in LOOP mode still not finding any good solution for the onclick that stop working in the first slide after the first LOOP…

big thanks for the above!
see it in action working now better… and showing only records that match the search…

:blush:
http://secure-s110src.tripsbro.com/test/

1 Like

inspire-me.html is a "componentUrl"
there is no way to apply

@click="openAlert" 

on dynamically added elements (like loop)
really, no way.

your only chance is :

return {
  on:{
    pageInit:function(e,page){
      var pageContainer=page.$pageEl;
      pageContainer.on('click','.my-class',function(e){
        //do something
      });
    }
  }
}
2 Likes

well the methods are working in a component page… no problem but in the case of dynamically added elements like in the LOOP I think must be the problem but I tried also with onclick=“javascript:alert();” to see if there was something from the @click methods but the same issue the first slide in LOOP mode links are broken… the others slides stay the same and fine…

so my last try will be adding this to the pageInit like

pageContainer.on(‘click’,’.my-class’,function(e){…

let you know if I have some good news…
in your sample will you add this to the pageInit in the index.html or in the page itself?

regards

1 Like