Shop Hosting
Neuigkeiten
  • Die modified eCommerce Shopsoftware ist kostenlos, aber nicht umsonst.
    Spenden
  • Damit wir die modified eCommerce Shopsoftware auch zukünftig kostenlos anbieten können:
    Spenden
  • Thema: Problem - asynchrone Vorschläge in AJAX-Suche?

    Parker

    • Mitglied
    • Beiträge: 135
    • Geschlecht:
    Hey Freunde!  :) Ich habe mir die AJAX-Suche mit Suchvorschlägen aus dem tpl_modified stibitzt und in mein Template eingebaut, doch leider funktioniert diese nicht immer.

    Problem (wie ich es derzeit vermute):
    Größere Chunks aus aus der autocomplete.php kommen später an und überschreiben die kleineren, konkreteren Suchvorschläge.

    Beispiel:
    Sagen wir, ich verkaufe Hemden. Gebe ich "Hemd grün" ein, so sehe ich kurz die paar grünen Hemden in den Suchvorschlägen und da machts gefühlt *plöp* und ich sehe die Suchvorschläge mit allen Hemden.

    Lösungsversuch:
    Da ich davon ausgehe, dass größere Pakete in der asynchronen Übertragung später ankommen und die neuen Überschreiben (was ja bekanntlich ein Problem sein kann), so hab ich $.post in der Funktion "ac_lookup" in AJAX geändert:

    Code: PHP  [Auswählen]
                $.ajax({
                    type: 'POST',
                    url: "<?php echo xtc_href_link('api/autocomplete/autocomplete.php'); ?>",
                    data: {queryString: ""+inputString+""},
                    success: function(data) {
                        if(data.length > 0) {
                            $('#suggestions').slideDown();
                            $('#autoSuggestionsList').html(data);
                            ac_showPage(1);
                            $('#autocomplete_prev').click(ac_prevPage);
                            $('#autocomplete_next').click(ac_nextPage);
                        }
                    },
                    async:true
                });
     
    (Datei: template/javascript/general_bottom.js.php)

    ...was exakt das gleiche Ergebnis bot. Also habe ich "async" mal auf "false" gesetzt und ja, den Warnungen entsprechend war es laangsam, bot zwar bei wenigen Zeichen das gewünschte Ergebnis, wurde dann aber vom Browser geblockt (deprecated function).

    Nach etwas Recherche habe ich gelesen, dass einige eine ID oder Dergleichen nutzen, um das übermittelte Paket (hier die Suchvorschläge aus der autocomplete.php) zu verifizieren und nur das korrekte Suchergebnis zu nutzen. Also hab ich folgendes gemacht:

    1. Diese Funktion zur Generierung eines Hashes genommen und eingebaut:

    Code: Javascript  [Auswählen]
      function makeid() {
          var text = "";
          var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

          for( var i=0; i < 20; i++ )
              text += possible.charAt(Math.floor(Math.random() * possible.length));

          return text;
        }
     

    2. Diesen Hash in die ac_lookup eingebaut

    Code: PHP  [Auswählen]
    function ac_lookup(inputString) {
            if(inputString.length == 0) {
                $('#suggestions').hide();
            } else {
                var requestHash = makeid();
                $('input#inputString').addClass('ac_loading'); // Loading-Gif
                $.post("<?php echo xtc_href_link('api/autocomplete/autocomplete.php'); ?>", {queryString: ""+inputString+"", requestHash: ""+requestHash+""}, function(data) {
                    if(data.length > 0) {
                        $('#suggestions').slideDown();
                        if (data.search(requestHash) != -1) {
                            console.log("hash found "+requestHash);
                            $('#autoSuggestionsList').html(data);
                        } else {
                            console.log("hash not found"+requestHash);
                        }
                        ac_showPage(1);
                        $('#autocomplete_prev').click(ac_prevPage);
                        $('#autocomplete_next').click(ac_nextPage);
                    }
                });
            }
            $(document).ajaxComplete(function () {
                $('input#inputString').removeClass('ac_loading'); // Loading-Gif
            });
        }
        function ac_closing() {
            setTimeout("$('#suggestions').slideUp();", 100);
            ac_page = 1;
        }

    Hier wird der Hash als Post-Parameter übergeben.

    3. In der autocomplete wird der Hash einer Smarty-Variable zugewiesen

    Code: PHP  [Auswählen]
            if (isset($_POST['requestHash'])) {
                $module_smarty->assign('requestHash', $_POST['requestHash']);
            }

    4. ...und im Modul "module/autocomplete.html" der Liste als verstecktes Listenelement vorangestellt
    Code: PHP  [Auswählen]
          <li style="display: none;">
              {$requestHash}
          </li>

    Nun plöppen aber immer noch die Suchvorschläge für alle Hemden auf, nachdem kurz die Liste mit den wenigen grünen Hemden zu sehen war und wenn ich es in der Konsole loggen lasse, dann steht da sogar das richtige Hash!?!?

    Kann es sein, dass ich bzgl. "asynchron" auf dem falschen Pfad bin? Hab ich 'nen Fisch auf den Augen?  :nixweiss:

    Linkback: https://www.modified-shop.org/forum/index.php?topic=37361.0

    Parker

    • Mitglied
    • Beiträge: 135
    • Geschlecht:
    Re: Problem - asynchrone Vorschläge in AJAX-Suche?
    Antwort #1 am: 19. Juni 2017, 15:43:47
    Hat denn jemand vielleicht Erfahrung mit großen Datenmengen und der Suchfunktion und deren Suchvorschlägen im tpl_modified?

    Mit großen Datenmengen meine ich natürlich viele ähnliche Produkte, welche mit dem gleichen Begriff gesucht werden, wie im o.g. Beispiel mit den Hemden, sodass zuerst eine lange und dann eine schnell eingegrenzte Liste mit Suchvorschlägen ausgegeben wird.

    Wenn es da geht, liegt es ja vielleicht an etwas anderem...

    Parker

    • Mitglied
    • Beiträge: 135
    • Geschlecht:
    Re: Problem - asynchrone Vorschläge in AJAX-Suche?
    Antwort #2 am: 20. Juni 2017, 14:37:59
    Nach weiterem Testen sieht es danach aus, als ob es nicht am Frontend liegt. Die Hash-Werte sind korrekt, denke ich.
    Da bei jedem keyUp Ereignis der Such-String an die autocomplete.php übergeben wird, habe ich mir mal alle Suchergebnisseiten (bzw. Listen mit Suchvorschlägen) nacheinander ausgeben lassen, mittels
    Code: Javascript  [Auswählen]
    $('#content_start').prepend(data);
    Am Ende kommt immer einmal die Liste mit allen Hemden, auch wenn die korrekten Ergebnisse vorher einmal ausgeworfen wurden. Ich vermute daher, dass dies kein AJAX-Problem ist, sondern das Problem in der autocomplete.php selbst steckt, bzw. den darin verwendeten PHP-Dateien und Klassen.
    Seltsam, zumal, wenn ich trotz der falschen Suchvorschläge auf Enter drücke, kommen die richtigen Ergebnisse. Weiß jemand, ob hier eine eigene Suchfunktion verwendet wird?

    Parker

    • Mitglied
    • Beiträge: 135
    • Geschlecht:
    Re: Problem - asynchrone Vorschläge in AJAX-Suche?
    Antwort #3 am: 20. Juni 2017, 15:46:52
    Kommando zurück! Der Hash ist wird nicht korrekt geprüft und somit liegt erst einmal ein AJAX-Problem vor.
    Lasse ich mir die Hashes und den übermittelten inputString ausgeben, sieht man, wie einige erst später ankommen:
    • 3x3ImpBiKLqkLyaJ1ZMl | inputString: hemd rot
    • 1rWEEcmFdPsMspgZsUv1 | inputString: hemd ro
    • vDxY2Iskk2xL79xoRjpJ | inputString: hem
    • PDaq7f6PSf6AH64aeUWy | inputString: hemd
    • Ow5ryRfgbYfvWCqw9VKW | inputString: hem
    • QXQNGFYyIj6U3wiJmFfX | inputString: he
    • 7bfJoYXEWeyCPFlldsVD | inputString: hemd
    • dFHRPLM64WnTQA6tjQFG | inputString: h
    • wtcTl6uDrH9l985Aae3y | inputString: hemd r
    ich melde mich, wenn ich das gelöst habe.

    Parker

    • Mitglied
    • Beiträge: 135
    • Geschlecht:
    Re: Problem - asynchrone Vorschläge in AJAX-Suche?
    Antwort #4 am: 20. Juni 2017, 17:04:33
    GELÖST! *yay*
    Das Problem mit den Hashes war, dass die Resultate der Anfrage zwar asynchron ankamen, aber die Prüfung auf den Hash zum jeweiligen Aufruf der Funktion gehört hat, weshalb diese immer positiv ausfiel.

    Nun habe ich gleich auf die Hashes verzichtet und einen Zähler eingebaut, sodass nur die Resultate mit dem aktuellen Wert angezeigt werden. Hier ist die überarbeitete Funktion "ac_lookup" plus Variablen aus der "general.bottom.js.php" im Template:

    general.bottom.js.php
    Code: Javascript  [Auswählen]
        var requestID = 0; // Unser Zähler
        var receivedID = ""; // Der Zählerstand, welcher mit der Anfrage übermittelt wird
        function ac_lookup(inputString) {
            if(inputString.length == 0) {
                $('#suggestions').hide();
            } else {
                requestID++;
                var requestHash = "|"+requestID+"|"; //hier kann man auch die direkt die ID nehmen, ich mache das halt so
                $('input#inputString').addClass('ac_loading'); //nicht original, setzt Klasse für CSS, zeigt Lade-Icon
                $.post("<?php echo xtc_href_link('api/autocomplete/autocomplete.php'); ?>", {queryString: ""+inputString+"", requestHash: ""+requestHash+""}, function(data) {
                    if(data.length > 0) {
                        $('#suggestions').slideDown();
                        receivedID = $.trim($(data).find('#ac-requestHash').html().replace(/\|/g, ""));
                        if (receivedID >= requestID) {
                            console.log("yep "+receivedID+" | inputString: "+inputString);
                            $('#autoSuggestionsList').html(data);
                        } else {
                        }
                        ac_showPage(1);
                        $('#autocomplete_prev').click(ac_prevPage);
                        $('#autocomplete_next').click(ac_nextPage);
                    }
                });
            }
            $(document).ajaxComplete(function () {
                $('input#inputString').removeClass('ac_loading'); //nicht original, lässt Lade-Icon verschwinden
            });
        }

    Zur Vollständigkeit, hier die Änderungen, welche man zusätzlich vornehmen muss:

    autcomplete.php
    Nach
    Code: PHP  [Auswählen]
    if (xtc_db_num_rows($autocomplete_search_query) > 0) {
    folgendes einfügen, damit der Zähler aus der Anfrage auch in das Resultat übergeben wird:
    Code: Javascript  [Auswählen]
            if (isset($_POST['requestHash'])) {
                $module_smarty->assign('requestHash', $_POST['requestHash']);
            }

    autcomplete.html
    Nun muss man noch den Zähler in den Resultaten verstecken:
    Nach:
    Code: PHP  [Auswählen]
    <ul id="autocomplete_main">
    folgendes einfügen:
    Code: PHP  [Auswählen]
          {if $requestHash}
              <li id="ac-requestHash" style="display: none;">
                  {$requestHash}
              </li>
          {/if}

    Ich weiß, dass dies nicht besonders elegant ist, aber ich bin eben kein Programmierer (mehr). Nun hoffe ich, auch wenn dieser Thread ein Monolog war, dass es jemandem helfen mag.
    2 Antworten
    1978 Aufrufe
    31. Mai 2014, 20:17:23 von tele
    98 Antworten
    31298 Aufrufe
    15. September 2010, 08:49:56 von Tomcraft
    0 Antworten
    1566 Aufrufe
    02. Januar 2014, 16:45:52 von tele
    14 Antworten
    3166 Aufrufe
    21. Dezember 2017, 13:30:25 von web28