materialize icon indicating copy to clipboard operation
materialize copied to clipboard

Autocomplete updateData() with http reqests

Open troncomputers opened this issue 6 years ago • 21 comments

Hi! I have a problem with autocomplete.updateData()

 <div class="input-field" style="padding:0px;margin-top:0em;margin-bottom:0em">
  <input type="text" placeholder="podaj kod towaru" id="pozycje_autocomplete"
     (change)="selectTowar($event)" autocomplete="off" class="autocomplete" name="kodTowaru" [(ngModel)]="kodTowaru"
     (keyup.Enter)="dodajPozycje()" (keyup)="szukajTowary($event)" style="text-align:center;height:2em">
 </div>

It's all about (keyup)="szukajTowaru($event)"

  ngAfterViewInit() {
    const pozycje_autocomplete = document.querySelector('#pozycje_autocomplete');
    M.Autocomplete.init(pozycje_autocomplete, {
      limit: 5
    });
}

  szukajTowary(event:any)
  {
    const pozycje_autocomplete = document.querySelector('#pozycje_autocomplete');
    let instance = M.Autocomplete.getInstance(pozycje_autocomplete);

    this.http.get('http://192.168.0.110:9000/tron/towary/'+event.target.value)
      .subscribe((result: any[]) => {
        let pozycje = [];
        for (var i = 0; i < result.length; i++) {
          pozycje[result[i]] = null;
        }
        console.log(pozycje);
        instance.updateData(pozycje);
      });
  }

Console.log displays data correctly when I type, for example, letter 's'

[IGLAKI_CYPRYS: null, KORA_S80: null, PIŁA_SPALINOWA: null, SEKATOR: null, SKRZYNKA: null, …]
IGLAKI_CYPRYS: null
KORA_S80: null
PIŁA_SPALINOWA: null
SEKATOR: null
SKRZYNKA: null
STOJAK: null
SZPADEL: null
ZESTAW_OGR: null
length: 0
__proto__: Array(0)

It's not showing autocomplete dropdown. Sometimes after couple tries it works but it's messed up with items from request before.

troncomputers avatar Feb 22 '18 09:02 troncomputers

It seems like you are passing in an array. Try passing in an object instead:

let pozycje = {};

acburst avatar Mar 01 '18 23:03 acburst

Same behavior with object. I made a little video to show you: https://youtu.be/sC6X7wwhcEc

Maybe my code is incorrect for this to work

    const pozycje_autocomplete = document.querySelector('#pozycje_autocomplete');
    let instance = M.Autocomplete.getInstance(pozycje_autocomplete);

    this.api.getSzukanyTowar(event.target.value)
      .subscribe((result: any[]) => {
        let pozycje = {}
        for (var i = 0; i < result.length; i++) {
          pozycje[result[i]] = null;
        }
        console.log(pozycje);
        instance.updateData(pozycje);
      })

troncomputers avatar Mar 02 '18 07:03 troncomputers

i have the same issue

DeweyOx avatar Sep 06 '18 23:09 DeweyOx

Me too

julienfr112 avatar Oct 02 '18 11:10 julienfr112

did someone find a way to put this to work?

optyler avatar Nov 14 '18 13:11 optyler

any solution guys? i have the same problem -_-

ramiborni avatar Apr 22 '19 21:04 ramiborni

Why do you need to update data on key click? The problem here is probably the render of the dropdown menu. If you really need this feature you could try to force opening and closing of the dropdown using .open() and .close() methods like stated here

Or you could add a button like "Refresh data" which calls the .updateData() method.

EDIT: Maybe it's the observer async behaviour fault? I've tested in a CodePen that it's not the dropdown fault on https://codepen.io/LukeSavefrogs/pen/ROYZEM.

LukeSavefrogs avatar Apr 23 '19 10:04 LukeSavefrogs

@LukeSavefrogs My example shows a dynamic autocomplete way, every new char will ask API for result so I need to "rebuild" the dropdown with new data. The items are not loaded at the page init, there might be too much of them. I think the .updateData() does not work only with Angular. I didn't find any solution. Just used different approach, designed for Angular.

troncomputers avatar Apr 23 '19 15:04 troncomputers

this what i did as a solution , not a perfect solution but useful : my html :

          <form autocomplete="off" class=" hide-on-med-and-down" id="form1">
            <div class="input-field" style="max-width: 300pt;">
                <input class="autocomplete" id="autocomplete-input" type="search" onclick="Auto.AutoComplete('#autocomplete-input', '#listAuto');">
                <ul id="listAuto" class="autocomplete-content dropdown-content" tabindex="0" style="display: none; width: 400px; left: 0px; top: 64px; height: 110px; transform-origin: 0px 0px; opacity: 1; transform: scaleX(1) scaleY(1);"></ul>
                <label class="label-icon" for="autocomplete-input">
                    <i class="material-icons prefix searchbar">search</i>
                </label>
                <i class="material-icons rtlx">close</i>
            </div>
         </form>

my js :

var Auto = {
ElemAutoComplete: null,
TextSearch: '',
AutoComplete: function (input, ListObject) {
    $(input).focusout(function () {
        $(ListObject).hide();
        $(ListObject).html("");
    })
    $(input).focusin(function () {
        if ($(input).val().trim() != '') {

            $(ListObject).html("");
            this.ElemAutoComplete = $(input);
            this.TextSearch = $(this.ElemAutoComplete).val();
            Auto.getdata(ListObject, this.TextSearch);
        }
    })
    $(input).keyup(function () {
        $(ListObject).html("");
        this.ElemAutoComplete = $(input);
        this.TextSearch = $(this.ElemAutoComplete).val();
        Auto.getdata(ListObject, this.TextSearch);
    });
},
getdata: function (ListObject, TextSearch) {
    $.ajax({
        type: "GET",
        url: "https://localhost:44358/searching?text=" + TextSearch.replace('+','*'),
        processData: false,
        contentType: "application/json",
        success: function (data) {
            try {
                console.log(TextSearch.replace(/\+/g, '*'));
                var Lis = Auto.ListConstructor(data);

                $(ListObject).css('height', data.length * 110 + '');
                if (Lis.length != 0) {
                    $(ListObject).html(Lis);
                    $(ListObject).show(500);
                } else {
                    $(ListObject).html('');
                }
            } catch (e) {
                console.log(e);
            }
        }
    });
},
ListConstructor: function (ListPhones) {
    var ListObject = '';
    for (i = 0; i < ListPhones.length; i++) {
        var Li = '<li><img src="' + ListPhones[i].imgUrl + '" class="left"><span><span class="highlight">' + ListPhones[i].brand + ' ' + ListPhones[i].model + '</span></span></li>';
        ListObject += Li;
    }
    return ListObject;
 }

};

ramiborni avatar Apr 23 '19 20:04 ramiborni

Hello, I have the same issues without angular.

I'm trying to put ajax on autocomplete as it crashes with too many elements.

Here is the simple code : input.autocomplete({ limit:8 }); input.on("keyup", function() { var words=input.val().trim(); $.ajax({ data: {words:words}, dataType : "json", url: "datas.php" }).done(function(datas) { input.autocomplete("updateData", datas); }); });

I get the same results as this main post. Dropdown not always showing and with old datas. I checked the materialize code and it seems updateData is calling a function to render dropdown so why is it not working as expected ?

Any chance someone successfuly used ajax with autocomplete or should I use another lib just for that ?

Dahkon avatar Jan 15 '20 17:01 Dahkon

@Dahkon this issue is almost 2 years old. Last release is from September 9th, 2018. I think this framework is dead...

troncomputers avatar Jan 16 '20 14:01 troncomputers

For this specific problem I used another library for autocomplete and I was able to use it even on chips, I tried first to modifiy materialize code but no success. https://github.com/autocompletejs/autocomplete.js

@troncomputers that's a shame really, it's a nice framework, I use it on professional backend and personnal frontend with great feedback from users.

@Dogfalo You're not into it anymore ?

Dahkon avatar Jan 16 '20 14:01 Dahkon

:+1:

samijnih avatar Dec 14 '20 00:12 samijnih

👍

@samijnih Please do not comment with emoji only, like your other 5 comments. You're spamming someone's inbox. Please use the reactions instead.

Smankusors avatar Dec 14 '20 04:12 Smankusors

How am I supposed to notice people that I agree with them in order to push improvement on this framework?

There are kinda 5 issues where people are complaining about the way materialize autocomplete has been designed and for me it's a shame that no iteration has been made over that, since 2 years ago.

samijnih avatar Dec 15 '20 12:12 samijnih

Deal with it and live on 😉

troncomputers avatar Dec 15 '20 12:12 troncomputers

Deal with it and live on

doing so. Not using that thing anymore :/

samijnih avatar Dec 15 '20 12:12 samijnih

How am I supposed to notice people that I agree with them in order to push improvement on this framework?

There are kinda 5 issues where people are complaining about the way materialize autocomplete has been designed and for me it's a shame that no iteration has been made over that, since 2 years ago.

yeah I understand that (and you got me 😉). But knowing that the original maintainers not active anymore (except their patreons), welp. 😞

If, you decided to help fix these issues, you can do PR on the new repo here, and I will happily review your PR, if I have a free time to do so.

Smankusors avatar Dec 15 '20 13:12 Smankusors

@Smankusors How is this repo better than (for example) Angular Material? What it has that Angular Material doesn't have? I think it's not worth it and original maintainers are probably aware of that. This issue was specific for Angular and it might work with other frameworks or with plain JS. Should I close this issue?

troncomputers avatar Dec 15 '20 13:12 troncomputers

How is this repo better than (for example) Angular Material? What it has that Angular Material doesn't have?

unfortunately I have no knowledge about this. But one thing you need to know that "Material Design" is made by Google, and Angular is also made by Google. And Angular Material is also made by Google. Meanwhile, Materializecss is not made by Google, but follow strictly to Material Design.

If you use Angular already, IMO it's better to use Angular Material, as it's designed to use on Angular, while Materializecss not.

Should I close this issue?

well... if "your issue about Materializecss" are solved, then feel free to close. If not, left this open.

Smankusors avatar Dec 15 '20 15:12 Smankusors

It's now three years later and the issue is still open, but I have a simple working solution. I figured out that the autocomplete, for some reason, thought that it was closed, and it wouldn't render as a result. Forcing it open seems to render the data provided by updateData().

const inst = M.Autocomplete.getInstance(elem)
inst.updateData(suggestionObj)
inst.open()

kschroeder avatar Sep 20 '23 14:09 kschroeder