• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Suchworte per JS aus MySQL auslesen

lucarp

Mitglied
Es geht glaube ich um ein recht simples Problem.
Ich brauche für eine Autocomplete Suchfunktion ein Array mit allen Suchworten die vorgeschlagen werden sollen.

Code:
var aNames =
    [
"Wort 1", "Wort 2", "Wort 3", "Wort 4", "Wort 5", "Wort 6"
    ];

Diese Worte müssen aus einer MySQL ausgelesen werden, woran ich bisher gescheitert bin. --> JS Anfänger

Kann mir da jemand eine anzupassende Funktion an die Hand geben oder auf einen passenden Beitrag verweisen?
 
Zuerst einmal, mit JavaScript geht das nicht, vorallem aus sicherheitstechnischen Gründen.

Du kannst mittels AJAX eine Verbindung zum Server herstellen, wo dann ein Script die Datenbank ausließt und die Ergebnisse zurück gibt.

Mit dem JS-Framework jQuery lassen sich AJAX-Requests recht sicher und einfach stellen (->jQuery.ajax() – jQuery API) und als serverseitige Verarbeitungssprache wäre PHP gut geeignet, da sie gute Zugriffsmöglichkeiten auf MySQL bietet und weit verbreitet ist.

Siehe dir am besten das mal an, dürfte für dich passen: AutoCompleter Tutorial – jQuery(Ajax)/PHP/MySQL - html tutorials | css tutorials | php tutorials | Nodstrum Blog.
 
Danke!

Ich habe jetzt mal folgendes gebastelt

Code:
$(document).ready(function() {
  $.post('/js/Autocompleter.php', {}, 
    function(data) {
      alert(data);
  });
});
Das funktioniert auch.
2 Probleme habe ich jetzt noch.

1.) wie kriege ich das was ich hier mit alert ausgebe in das
Code:
  function createAutoComplete()
 {
 var aNames =
    [
hier muss der String rein...
    ];
 
 new autoComplete(aNames,document.getElementById('txt'),document.getElementById('suggest'),10);
 }
hinein?

2.) an welcher stelle kann ich die Umlaute retten die mir irgendwo flöten gehen?
Aus der PHP bekomme ich den utf_8 codierten String.
 
Kenne mich mit Arrays in JS nicht sonderlich aus, doch du müsstest die PHP-Ausgabe so modifizieren, dass es die Struktur eines JS-Arrays annimmt. Danach kannst du "data" der Variable "aNames" zuweisen.


[Halbwissen]
 
jetzt habe ich noch eine Frage bzgl. des Geltungsbereiches der Variablen.

mit folgendem Code wird das alert ganz normal mit dem gewünschten Inhalt ausgegeben

Code:
<script type="text/javascript">
  $(document).ready(function() {
  $.post('/js/Autocompleter.php', {}, 
    function(data) {
      autocomplete = (data);
      alert(autocomplete);
  });
});
            
            
            </script>

wenn ich das alert jedoch aus der Funktion hinausnehmen

Code:
<script type="text/javascript">
  $(document).ready(function() {
  $.post('/js/Autocompleter.php', {}, 
    function(data) {
      autocomplete = (data);
      
  });
});
            
        alert(autocomplete);    
            </script>

klappt es nichtmehr.

Ich hatte gelesen, dass die Variablen global sind wenn man sie innherhalb der Funktion ohne var definiert.
warum geht das also nicht?
 
Sie muss außerhalb der Funktion deklariert werden, damit sie global ist.

Als Beispiel:
Code:
var h = 1;
function hallo()
{
  var h = 2;
  var h2 = 33;
}
alert(h); //h = 1
hallo();
alert(h); //h = 1
alert(h2); //Fehler: h2 nicht deklariert
 
Nochmal schlau gemacht.

Also, PHP muss die Daten in einer bestimmen Struktur senden (JSON), damit JS diese in ein Array umwandeln kann. Jetzt kannst du in deinem PHP-Script die Ausgabe ersetzen durch eine Ausgabe von JSON deines PHP-Arrays. PHP: json_encode - Manual
Mit jQuerys Funktion jQuery.parseJSON – jQuery API kannst du 'data' (welches diese JSON-Struktur enthält) dann in ein 'echtes' JS-Array zurück umwandeln.

Gruß

P.S. Zeig bitte nochmal deinen gesamten JS- und PHP-Quelltext.
 
okay.

Also in der Datenbank sind die Keywords mit kommas getrennt aufgelistet
PHP
Code:
<?php
$autocomplete_abfrage = mysql_query("SELECT * FROM products");

while($autocomplete = mysql_fetch_array($autocomplete_abfrage))
{
    $keyword_split = explode(", ",$autocomplete["keywords"]);
    
    for($split_count=0;$split_count<=count($keyword_split);$split_count++)
    {        
            if(utf8_decode($keyword_split[$split_count]) != "" && strpos($autocomplete_string,utf8_decode($keyword_split[$split_count])) == false)
            {
                if($split_count+1 < count($keyword_split))
                {
                    $autocomplete_string .= '"' . utf8_decode($keyword_split[$split_count]) . '", ';
                }
                else
                {
                    $autocomplete_string .= '"' . utf8_decode($keyword_split[$split_count]) . '"';
                }
            }
        }
    
}

echo  $autocomplete_string;
?>
JS
Code:
<script type="text/javascript">
  $(document).ready(function() {
  $.post('/js/Autocompleter.php', {}, 
    function(data) {
      autocomplete = (data);
      
  });
});
            
     function createAutoComplete()
 {
 var aNames = [autocomplete];
 
 new autoComplete(aNames,document.getElementById('txt'),document.getElementById('suggest'),10);
 }  

            </script>
 
Die Schleife für die einzelnen Keywords brauchst du in PHP garnicht durchlaufen, sondern kannst $keyword_split direkt encoden.
PHP:
<?php
$autocomplete_abfrage = mysql_query("SELECT * FROM products");

while($autocomplete = mysql_fetch_array($autocomplete_abfrage))
{
    $keyword_split = explode(", ",$autocomplete["keywords"]);
    
    echo json_encode($keyword_split);
}

?>
Und zugehöriger JavaScript-Code:
Code:
var autocomplete = new Array();

function createAutoComplete(autocompleteIn)
{
    var aNames = autocompleteIn;
 
    new autoComplete(aNames,document.getElementById('txt'),document.getElementById('suggest'),10);
}  

$(document).ready(function() {
    $.post('/js/Autocompleter.php', {}, 
        function(data) {
            autocomplete = jQuery.parseJSON(data);  
            createAutoComplete(autocomplete);
    });
});
[ungetestet]

gruß
 
Also ich habe das mit JSON und dem JQuery mal probiert, aber dann bekomme ich ein JS Array in Form von

Wort 1, Wort 2, Wort 3, ....

brauchen tu ich aber genau das hier

["Wort 1","Wort 2","Wort 3","..."]

Das einzige Problem ist jetzt noch das mit der globalen ausgabe.

Code:
 $(document).ready(function() {
  $.post('/js/Autocompleter.php', {}, 
    function(data) {
      keywords = (data);
  });
});
       
 
 function createAutoComplete()
 {
 var aNames = keywords;
 
 new autoComplete(aNames,document.getElementById('txt'),document.getElementById('suggest'),10);
 }

Ich bekomme es einfach nicht hin, dass die Variable keywords der var aNames zugeordnet wird.
 
brauchen tu ich aber genau das hier

["Wort 1","Wort 2","Wort 3","..."]
Aber weshalb in dieser Form? Meinst du nicht ("Wort 1","Wort 2","Wort 3","...")? Denn das wäre die Parameterliste eines Arrays und somit meine Lösung richtig.

Ich bekomme es einfach nicht hin, dass die Variable keywords der var aNames zugeordnet wird.
Indem du die Variable "keywords" bereits vor dem gesamten JavaScript zusammen mit dem Kürzel "var" deklarierst. Ansonsten wird sie als lokale Variable angesehen.
 
Danke für die Geduld.
Aber egal was ich mache. es klappt nicht.

Ich habe jetzt mal versucht das

Code:
var aNames = ["Wort 1", "Wort 2", "...."];
mit
Code:
var aNames = ("Wort 1", "Wort 2", "....");
zu ersetzen und das funktionert nicht.

zu deinem Beispiel haben ich 2 Anmerkungen

1.) in der PHP Schleife war noch eine Funktion versteckt die mir die doppelten keywords aussortiert und weiters wird bei deinem Code ja folgendes ausgegeben

Code:
["Wort 1","Wort 2","...."]["Wort 4","Wort 5","...."]
Was dann ja wieder die falsche struktur hat. Ich bekomme dann einen Error "uncaught exception: Invalid JSON"

2.) auch wenn die Variable vor JS Funktion deklariert wird, spuckt er mir an jeder Stelle ein "undefined" aus

Ich galube wir sind nicht mehr weit entfernt :-)

Danke nochmal
 
Also hier einfach mal der gesamte JS Code. So wie ich Ihn habe und er auch funktioniert wenn man die Worte direkt eingibt.
In diesem Beispiel würden mir im Suchfeld also "Wort 1", "Wort 2" usw. vorgeschlagen werden.

ganz unten ist dann der wichtige Teil indem aNames deklariert wird.

Code:
function autoCompleteDB()
 {
    this.aNames=new Array();
 }
 
 autoCompleteDB.prototype.assignArray=function(aList)
 {
    this.aNames=aList;
 };
 
 autoCompleteDB.prototype.getMatches=function(str,aList,maxSize)
 {
    /* debug */ //alert(maxSize+"ok getmatches");
    var ctr=0;
    for(var i in this.aNames)
    {
         if(this.aNames[i].toLowerCase().indexOf(str.toLowerCase())==0) /*looking for case insensitive matches */
       {
          aList.push(this.aNames[i]);
          ctr++;
       }
       if(ctr==(maxSize-1)) /* counter to limit no of matches to maxSize */
          break;
    }
 };
 
 function autoComplete(aNames,oText,oDiv,maxSize)
 {
 
    this.oText=oText;
    this.oDiv=oDiv;
    this.maxSize=maxSize;
    this.cur=-1;
 
    
    /*debug here */
    //alert(oText+","+this.oDiv);
    
    this.db=new autoCompleteDB();
    this.db.assignArray(aNames);
    
    oText.onkeyup=this.keyUp;
    oText.onkeydown=this.keyDown;
    oText.autoComplete=this;
    oText.onblur=this.hideSuggest;
 }
 
 autoComplete.prototype.hideSuggest=function()
 {
    this.autoComplete.oDiv.style.visibility="hidden";
 };
 
 autoComplete.prototype.selectText=function(iStart,iEnd)
 {
    if(this.oText.createTextRange) /* For IE */
    {
       var oRange=this.oText.createTextRange();
       oRange.moveStart("character",iStart);
       oRange.moveEnd("character",iEnd-this.oText.value.length);
       oRange.select();
    }
    else if(this.oText.setSelectionRange) /* For Mozilla */
    {
       this.oText.setSelectionRange(iStart,iEnd);
    }
    this.oText.focus();
 };
 
 autoComplete.prototype.textComplete=function(sFirstMatch)
 {
    if(this.oText.createTextRange || this.oText.setSelectionRange)
    {
       var iStart=this.oText.value.length;
       this.oText.value=sFirstMatch;
       this.selectText(iStart,sFirstMatch.length);
    }
 };
 
 autoComplete.prototype.keyDown=function(oEvent)
 {
    oEvent=window.event || oEvent;
    iKeyCode=oEvent.keyCode;
 
    switch(iKeyCode)
    {
       case 38: //up arrow
          this.autoComplete.moveUp();
          break;
       case 40: //down arrow
          this.autoComplete.moveDown();
          break;
       case 13: //return key
          window.focus();
          break;
    }
 };
 
 autoComplete.prototype.moveDown=function()
 {
    if(this.oDiv.childNodes.length>0 && this.cur<(this.oDiv.childNodes.length-1))
    {
       ++this.cur;
       for(var i=0;i<this.oDiv.childNodes.length;i++)
       {
          if(i==this.cur)
          {
             this.oDiv.childNodes[i].className="over";
             this.oText.value=this.oDiv.childNodes[i].innerHTML;
          }
          else
          {
             this.oDiv.childNodes[i].className="";
          }
       }
    }
 };
 
 autoComplete.prototype.moveUp=function()
 {
    if(this.oDiv.childNodes.length>0 && this.cur>0)
    {
       --this.cur;
       for(var i=0;i<this.oDiv.childNodes.length;i++)
       {
          if(i==this.cur)
          {
             this.oDiv.childNodes[i].className="over";
             this.oText.value=this.oDiv.childNodes[i].innerHTML;
          }
          else
          {
             this.oDiv.childNodes[i].className="";
          }
       }
    }
 };
 
 autoComplete.prototype.keyUp=function(oEvent)
 {
    oEvent=oEvent || window.event;
    var iKeyCode=oEvent.keyCode;
    if(iKeyCode==8 || iKeyCode==46)
    {
       this.autoComplete.onTextChange(false); /* without autocomplete */
    }
 else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode <= 46) || (iKeyCode >= 112 && iKeyCode <= 123))
    {
       //ignore
    }
    else
    {
       this.autoComplete.onTextChange(true); /* with autocomplete */
    }
 };
 
 autoComplete.prototype.positionSuggest=function() /* to calculate the appropriate poistion of the dropdown */
 {
    var oNode=this.oText;
    var x=0,y=oNode.offsetHeight;
 
    while(oNode.offsetParent && oNode.offsetParent.tagName.toUpperCase() != 'BODY')
    {
       x+=oNode.offsetLeft;
       y+=oNode.offsetTop;
       oNode=oNode.offsetParent;
    }
 
    x+=oNode.offsetLeft;
    y+=oNode.offsetTop;
 
    this.oDiv.style.top=y+"px";
    this.oDiv.style.left=x+"px";
 }
 
 autoComplete.prototype.onTextChange=function(bTextComplete)
 {
    var txt=this.oText.value;
    var oThis=this;
    this.cur=-1;
    
    if(txt.length>0)
    {
       while(this.oDiv.hasChildNodes())
          this.oDiv.removeChild(this.oDiv.firstChild);
       
       var aStr=new Array();
       this.db.getMatches(txt,aStr,this.maxSize);
       if(!aStr.length) {this.hideSuggest ;return}
       if(bTextComplete) this.textComplete(aStr[0]);
       this.positionSuggest();
       
       for(i in aStr)
       {
          var oNew=document.createElement('div');
          this.oDiv.appendChild(oNew);
          oNew.onmouseover=
          oNew.onmouseout=
          oNew.onmousedown=function(oEvent)
          {
             oEvent=window.event || oEvent;
             oSrcDiv=oEvent.target || oEvent.srcElement;
 
             //debug :window.status=oEvent.type;
             if(oEvent.type=="mousedown")
             {
                oThis.oText.value=this.innerHTML;
             }
             else if(oEvent.type=="mouseover")
             {
                this.className="over";
             }
             else if(oEvent.type=="mouseout")
             {
                this.className="";
             }
             else
             {
                this.oText.focus();
             }
          };
          oNew.innerHTML=aStr[i];
       }
       
       this.oDiv.style.visibility="visible";
    }
    else
    {
       this.oDiv.innerHTML="";
       this.oDiv.style.visibility="hidden";
    }
 };
 
 function createAutoComplete()
 {
 var aNames =
    [
"Wort 1", "Wort 2", "Wort 3", "..."
    ];
 
 new autoComplete(aNames,document.getElementById('txt'),document.getElementById('suggest'),10);
 }
 
Zu 1:
Versuche mal diesen PHP-Code:
PHP:
<?php
$autocomplete_abfrage = mysql_query("SELECT * FROM products");

while($autocomplete = mysql_fetch_array($autocomplete_abfrage))
{
    $keyword_split = explode(", ",$autocomplete["keywords"]);
    $autocomplete_array = array();
    
    for($split_count=0;$split_count<=count($keyword_split);$split_count++)
    {        
            if(utf8_decode($keyword_split[$split_count]) != "" && strpos($autocomplete_string,utf8_decode($keyword_split[$split_count])) == false)
            {
                
                $autocomplete_array[] = utf8_decode($keyword_split[$split_count]);
            }
        }
    
}

echo  json_encode($autocomplete_array);
?>

Zu 2:
Man könnte die Keywords auch als Parameter übergeben.
Code:
var keywords = new Array();

 $(document).ready(function() {
  $.post('/js/Autocompleter.php', {}, 
    function(data) {
      keywords = jQuery.parseJSON(data);
  });
});

 function createAutoComplete(keywords)
 {
 var aNames = keywords;
 
 new autoComplete(aNames,document.getElementById('txt'),document.getElementById('suggest'),10);
 }
createAutoComplete(keywords);

Jetzt aber... ;)
 
Also ich glaube mit dem PHP code sind wir durch.

Code:
$autocomplete_abfrage = mysql_query("SELECT * FROM products");

while($autocomplete = mysql_fetch_array($autocomplete_abfrage))
{
    $keyword_split = explode(", ",$autocomplete["keywords"]);
    if(!isset($keyword_array) || $keyword_array == "")
    {
        $keyword_array = array();
    }
    
    for($split_count=0;$split_count<=count($keyword_split);$split_count++)
    {        
            if($keyword_split[$split_count] != "" && in_array($keyword_split[$split_count],$keyword_array) == false)
            {
                
                    array_push($keyword_array, $keyword_split[$split_count]);
                
            }
        }
    
}

echo json_encode($keyword_array);
?>

Bei deiner Variante wird das Array ja immer überschrieben und er gibt mir nur die Keywords aus dem letzten Datenbankeintrag.
In meinem Code werden alle zusammengesetzt. Das Format was hinten rauskommt ist aber das selbe.

Es hängt also nur noch am JS.
Die Funktion createAutoComplete() wird bei onLoad im Body jeder Seite aufgerufen.
Wenn ich mir in dieser Funktion "keywords" per alert ausgeben lassen, kommt jetzt zumindest mal kein "undefined" sondern einfach ein leerer alert.

die Variable besteht also. Aber die aten sind nicht drin.

Muss also irgendwie an
Code:
 $(document).ready(function() {
  $.post('/js/Autocompleter.php', {}, 
    function(data) {
      keywords = jQuery.parseJSON(data);
  });
});

liegen oder?
 
Was, wenn du hinter der Befüllung von keywords diese Variable mit alert ausgibst?

P.S. Auch mein PHP-Code dürfte das Array nicht überschreiben, da hinter dem Variablennamen die beiden eckigen Klammern [] einen neuen Index anführen.
 
Dann wird der alert ausgeführt mit dem Inhalt "Wort 1, Wort 2, Wort 3,..."


Jetzt habe ich noch etwas anderes Bemerkt
Und zwar wird bei folgendem Code

Code:
var keywords = new Array();

 $(document).ready(function() {
  $.post('/js/Autocompleter.php', {}, 
    function(data) {
      keywords = (data);
      alert(keywords);
  });
});

 function createAutoComplete(keywords)
 {
     keywords = ["Hallo", "Test"];
     alert(keywords);
 var aNames = keywords;

 new autoComplete(aNames,document.getElementById('txt'),document.getElementById('suggest'),10);
 }

zuerst der alert mit ["Hallo", "Test"] ausgeführt und dann der mit dem Inhalt aus dem PHP-Script.

kann das vielleicht an der Reihenfolge liegen, dass der Inhalt nicht korrekt zugeordnet wird?
Wann wird denn dieser Code ausgeführt in dem das JS Script die Daten vom PHP-Script holt?
 
Zuletzt bearbeitet:
Zurück
Oben