• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

Suchmaske - CSV-Datei durchsuchen

miezekathi

New member
Liebe Forummitglieder,

ich habe ein Suchfeld erstellt, worin man nach Postleitzahlen suchen kann. Im Hintergrund wird eine CSV-Datei aufgerufen, die alle Adressdaten zu den jeweiligen Postleitzahlen beinhaltet.

Das Array wird richtig ausgegeben aber irgendwas hab ich bei der Suchfunktion "PLZSearch" falsch. Ich komm einfach nicht drauf. Die Konsole sagt "TypeError: result.split is not a function". Bin leider kein Javascript-Profi und hoffe ihr könnt mir weiterhelfen.

Code:
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>PLZ Suchmaske</title>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">

//CSV lesen
function asyncCsv2Array(fileName, separator, callback) {
    // Datei einlesen (benötigt JQuery)
   $.get(fileName, function(fileContent){
        // Array für Ergebnis
        var result = [];
        // Eingelesenen Text in ein Array splitten (\r\n, \n und\r sind die Trennzeichen für verschiedene Betriebssysteme wie Windows, Linux, OS X)
        var textArray = fileContent.split(/(\r\n|\n|\r)/gm);
        // Über alle Zeilen iterieren
        for (var i = 0; i < textArray.length; i++) {
            // Nur wenn die Größe einer Zeile > 1 ist (sonst ist in der Zeile nur das Zeilenumbruch Zeichen drin)
            if (textArray[i].length > 1) {
                // Zeile am Trennzeichen trennen
                var elementArray = textArray[i].split(separator);
                // überflüssiges Element am Ende entfernen - nur notwendig wenn die Zeile mit dem Separator endet
                elementArray.splice(elementArray.length - 1, 1);
                // Array der Zeile dem Ergebnis hinzufügen
                result.push(elementArray);
            } // Ende if
        } // Ende for
        callback(result);
    }); // Ende von $.get Aufruf
} // Ende function asyncCsv2Array
    
// Beispielaufruf    
asyncCsv2Array("data.csv", ";", function(result) {
    console.log(result);
    // Ausgabe von "PLZ"
    // console.log(result[0][0]);
    // Ausgabe von "ORT"
    // console.log(result[0][1]);    
});

// var DB = new Array();
// function MakeDB() {
//   DB = result.split(';'); 
// }

function PLZSearch(Plz) {
  var posn = -1;
  for (i=0; i<result.length; i++) {
    tmp = result[i].split(';');
    if (tmp.indexOf(Plz) != -1) { posn = i; break; } 
  }
  if (posn == -1) { alert('Postleitzahl kann nicht gefunden werden'); }
             else { document.getElementById('TArea').value = result[posn]; }
}

</script>
</head>
<body>

<div id="container">
<p><b>Suchen Sie den Experten in Ihrer Nähe</b></p>

<p>
  <input type="text" value="" id="PLZ" name="inputfeld">
  <input type="button" value="Suchen" onclick="PLZSearch(document.getElementById('PLZ').value)">
</p>
<br>
  <textarea id="TArea" rows="3" cols="50"></textarea>

</div>

</body>
</html>

Link: PLZ Suchmaske

Vielen Dank im Voraus und lG,
mieze
 
result ist ja auch ein Array von Arrays und kein Array von Strings... du musst also das split gar nicht mehr durchführen.

PS: globale Variablen sind keine gute Idee. Besonders, wenn sie so generische Namen wie result haben.
 
danke für deine antwort und deinen hinweis auf result. alles klar - klingt eigentlich logisch. nur wäre ich selbst nicht darauf gekommen. ich hab result jetzt unbenannt in "lines".

es scheint zu funktionieren!! danke!

- - - Aktualisiert - - -

so, ich hab doch noch eine frage.
zwischen den einzelnen array-feldern habe ich jetzt einen beistrich, wie bekomme ich den weg und wie kann ich zB einen Zeilenumbruch nach bestimmten array-feldern machen? geht das?
 
Lines ist nur marginal besser als result...

zwischen den einzelnen array-feldern habe ich jetzt einen beistrich
Was meinst du damit genau? Wenn du die Ausgabe anders formatieren willst, darfst du das Ergebnisarray hald einfach nicht direkt in die <textarea> schreiben. Also anstatt
Code:
document.getElementById('TArea').value = result[posn];
das so reinschreiben, wie du es gerne hättest.
 
naja, jetzt wird zum beispiel alles in einer wurscht ausgegeben:
Firma1,Bahnstrasse,1,2000,Stockerau,02266/000,Google.

Ich möchte es aber so zB so haben:
Firma1
Bahnstrasse 1
2000 Stockerau
02266/000
Google

Also ohne Beistrich und mit Zeilenumbruch. Wie mach ich das am schnellsten? Geht das überhaupt?
 
hm, ja, dann wird es so ausgegeben (nach jedem Beistrich):
Firma1
Bahnstrasse
1
2000
Stockerau
02266/000
Google

ich würde gerne jedes array element einzeln ausgeben, wo ich dann genau sagen kann wann ein zeilenumbruch folgt und wann nicht. hab leider noch keinen weg gefunden wie man das macht.
 
Dann musst du die Ausgabe hald per Hand zusammenbauen:
Code:
document.getElementById('TArea').value =
	result[posn][0] + "\n" +
	result[posn][1] + " " + result[posn][2] + "\n" +
	...

Wobei dein komplettes Datenmodell so weder flexibel, robust noch gut wartbar ist. Du willst eigentlich keinen Array als Datensatz haben, sondern ein Objekt. Hol' dir also aus dem CSV die Headerzeile und baue dir dann für jede andere Zeile ein Objekt zusammen:
Code:
function parseCSV(data, separator){
	var lines = data.split(/\r?\n|\r/).map(function(line){return line.trim();}).filter(function(line){return line.length});
	var header = lines.shift().split(separator).map(function(cell){return cell.trim()});
	return lines.map(function(line){
		var obj = {};
		line.split(separator).forEach(function(cell, i){
			if (header[i]){
				obj[header[i]] = cell.trim();
			}
		});
		return obj;
	});
}
Wobei das natürlich noch kein Vollständiger CSV-Parser ist. Dazu fehlen noch ein paar Dinge wie Escaping und weitere Konfigurationsmöglichkeiten.
 
danke für deine Antwort. ich habe es jetzt irgendwie doch selber geschafft.

ich bin jetzt leider drauf gekommen, dass wenn ich in meiner CSV Datei zB zweimal, dreimal,... die selbe PLZ habe, aber eine andere Strasse, dass immer nur die Zeile des ersten Ergebnisses ausgegeben wird aber nicht ALLE Zeilen mit der gesuchteb PLZ und deren Adressen.
Wo kann ich festlegen, dass ich ALLE Zeilen mit der gesuchten PLZ ausgeben werden?

Code:
// Array ausspielen
  var posn = -1;
  for (i=0; i<lines.length; i++) {
    // tmp = lines[i].split(';');
    tmp = lines[i];
    if (tmp.indexOf(Plz) != -1) { posn = i; break; } 
  }

  if (posn == -1) { 
    document.getElementById('ergebnis').style.display = "none";
    // wenn keine PLZ hinterlegt Fehlermeldung
    // alert('Postleitzahl kann nicht gefunden werden. Bitte geben Sie eine andere Postleitzahl ein.'); 
    document.getElementById('error').innerHTML = "<p style='color:red;'>Zu der von Ihnen eingegebenen Postleitzahl</br>gibt es keinen teilnehmenden Partner.</p>";
    } else {  
    document.getElementById('error').style.display = "none";
    // wenn PLZ hinterlegt dann anzeigen
    document.getElementById('haendler').innerHTML = "<b>" + lines[i][0] + "</b>" + "</br>" + lines[i][1] + " " + lines[i][2] + ", " + lines[i][3] + " " + lines[i][4] + "</br>" +  "Telefon: " + lines[i][5] + "</br>" +  "Website: " + "<a target='_blank' href='" + lines[i][6] + "'>" + lines[i][6] + "</a>";
 
Sehe gerade, dass deine Suche sowieso nicht ideal ist. Wenn eine Firma "36472" heißt, wird die auch bei deiner PLZ-Suche für diese PLZ zurückgegeben... ich kann mich nur wiederholen: dein Datenmodell ist nicht gut.

Zu deinem Problem: die Schleife wird ja auch abgebrochen, wenn etwas gefunden wurde. Ich würde das mit ARRAY.filter() machen:
Code:
var matches = lines.filter(function(line){
	return line.indexOf(Plz) !== -1;
});
Dann hast du ein Array aller Datensätze, die passen. Über ein ARRAY.map() kannst du dann jeden Datensatz in das passende HTML umwandeln, per ARRAY.join() dann die HTML-Fragmente zusammenhängen und dann ins innerHTML sschreiben.
 
Zuletzt bearbeitet:
ja, stimmt - danke für das feedback. muss ich noch korrigieren.

ich hab es jetzt geschafft die "matches" in der konsole auszugeben aber es scheitert noch an der anzeige in html.

Code:
Code:
  var matches = lines.filter(function(line){
    return line.indexOf(Plz) !== -1;
  });
  

  var posn = -1;
  for (i=0; i<matches.length; i++) {
    tmp = matches[i];
    // console.log(matches[i][5]);
  }


  if (posn == -1) { 
    document.getElementById('ergebnis').style.display = "none";
    // wenn keine PLZ hinterlegt Fehlermeldung
    // alert('Postleitzahl kann nicht gefunden werden. Bitte geben Sie eine andere Postleitzahl ein.'); 
    document.getElementById('error').innerHTML = "<p style='color:red;'>Zu der von Ihnen eingegebenen Postleitzahl</br>gibt es keinen teilnehmenden Partner.</p>";
    } else {  
    document.getElementById('error').style.display = "none";
    // wenn PLZ hinterlegt dann anzeigen
    document.getElementById('haendler').innerHTML = "<b>" + matches[i][0] + "</b>" + "</br>" + matches[i][1] + " " + matches[i][2] + ", " + matches[i][3] + " " + matches[i][4] + "</br>" +  "Telefon: " + matches[i][5] + "</br>" +  "Website: " + "<a target='_blank' href='" + matches[i][6] + "'>" + matches[i][6] + "</a>";

momentan gibt er noch aus dass keine PLZ gefunden wurde wenn ich nach einer vorhandenen PLZ suche.
stimmt die schleife bzw die filter()-funktion so?

Und reicht für die Umwandlung in HTML der Code:
Code:
matches.map();

oder fehlt da noch etwas in der Klammer? Denn hier schreibt er "missing argument 0 when calling function Array.prototype.map".
 
Das filter() passt so, aber du brauchst gar keine Schleife mehr. Ob es einen Treffer gibt, kannst du einfach mit match.length === 0 überprüfen.

Und reicht für die Umwandlung in HTML der Code:
Ja, da fehlt noch etwas in der Klammer - steht ja auch in der Fehlerkonsole und in dem von mir verlinkten Link:
Code:
var html = matches.map(function(match){
	return "<b>" + match[0] + "</b>" + "</br>" +
		match[1] + " " + match[2] + ", " + match[3] + " " + match[4] + "</br>" +
		"Telefon: " + match[5] + "</br>" +
		"Website: " + "<a target='_blank' href='" + match[6] + "'>" + match[6] + "</a>";
}).join("<br>");
 
ok ok, ich komme der sache schon näher, es werden die zeilen mit der selben PLZ ausgegeben. vielen Dank!
eine frage habe ich noch.

wie kann ich festlegen, dass nur die erste spalte der csv datei nach dem eingegebenen input-wert durchsucht wird? er gibt mir nämlich jetzt einige zeilen doppelt aus, da die postleitzahl in einer anderen spalte auch noch angegeben wird.
 
Dopplte Zeilen können eigentlich nur aus Doppelungen im CSV kommen. Aber wenn du nur in der ersten Spalte nach der PLZ suchen willst, musst du die Filterfunktion anpassen:
Code:
var matches = lines.filter(function(line){
	return line[0] === Plz;
});
 
Zurück
Oben