Hallo, lieber Forumbenutzer. Wir haben in letzter Zeit festgestellt, dass die Kommunikation via Slack viel schneller und zielführender ist als ein Beitrag im Forum. Aufgrund der neuen Möglichkeiten der Kommunikation ist das Forum ein wenig eingeschlafen und weniger Nutzer benutzen das Forum aktiv (trotzdem lohnt es sich evtl. hier nach Lösungen zu suchen oder seine Frage zu stellen).

Wir empfehlen, für deine Fragen/Probleme aktuell (zusätzlich) Slack zu nutzen. Dort sind viele kompetente Benutzer aktiv und beantworten jegliche Fragen, gerne auch von REDAXO-Anfängern! Slack wird von uns sehr intensiv und meistens "rund um die Uhr" benutzt :-)
Selbst einladen kannst Du dich hier: http://redaxo.org/slack/
Popkultur
Beiträge: 82
Registriert: 1. Apr 2014, 19:55

Modul Produktkonfigurator / AJAX im Modul

21. Apr 2015, 15:43

Hallo!

Ich möchte sowas programmieren wie hier. Ich habe mal angefangen und eine DB-Tabelle mit Beispielprodukten erstellt und die ersten Zeilen hab ich auch schon. Das Ganze soll aber per AJAX laufen, wie setze ich das jetzt am Besten um? Über ein paar Tipps wäre ich dankbar. Er muss jetzt quasi den Wert, der ausgewählt wird, nehmen und damit eine neue SQL Abfrage machen und die Produkte anzeigen, die dazu gehören.

Und macht es eventuell Sinn, das Ganze als Addon zu machen? Ich denke nicht. Später muss ich in der Moduleingabe noch eine Möglichkeit einbauen, die Produkte zu pflegen, da wäre eventuell doch ein Addon sinnvoll, um die ganzen technischen Daten im Backend anzuzeigen.

Modul Ausgabe:

Code: Alles auswählen

<?php
	$sql = rex_sql::factory();
	// $sql->debugsql = 1; //Ausgabe Query

	$sql->setQuery('SELECT * FROM '.$REX['TABLE_PREFIX'].'produktkonfigurator WHERE groesse=21.50');
    $ausgabe = '';
    for($i=0; $i<$sql->getRows(); $i++)
	{
		$wert = $sql->getValue('groesse');
		$ausgabe .= '<option value="$wert">'.$wert.' Zoll</option>';
		$sql->next();
	}

?>


<script type="text/javascript">
  $(function() {
    $( "#groesse" ).selectmenu({ width: 200 });
  });	
</script>

<div class="produktkonfigurator">
	<form>
		<select id="groesse">
			<?php echo $ausgabe; ?>
        </select>
	</form>
</div>

Benutzeravatar
Cheffchen
Beiträge: 1809
Registriert: 3. Mär 2009, 13:51
Wohnort: Berlin
Kontaktdaten: Website

Re: Modul Produktkonfigurator / AJAX im Modul

22. Apr 2015, 10:55

Hallo,

also als ADDON vielleicht nicht.

Das als Ajax zu machen ist ein möglichkeit, alle daten bei change einsammeln per serialize() und per ajax post an die gleiche Seite schicken, die Daten verarbeiten und ausgeben.
Bei Ajax kannst ja sagen was bei beforeSend und bei success passieren soll, da musst die halt ein schönen effect einfügen.

hier mal ein teil wie mit der verarbeitung anfangen kannst, einfach in die Modul ausgabe

Code: Alles auswählen

<?
#autocomplet abfrage für ajax
if(isset($_GET['ajax']) && isset($_GET['send']) && $_GET['send'] =='plz' ){
    if($REX['REDAXO']!=1) while(ob_end_clean());#das mögliche template ausgaben gelöscht werden
        
    $q=$_GET['q'];          
    $array= array();  
   
    $sql = new sql(2);
    $sql->setQuery("SELECT * FROM geodaten where (plz like '".$q."%' or ort like '".$q."%')  limit 30");
    if($sql->getRows()){
        for($i = 0; $i < $sql->getRows(); $i ++){ 
            $array[]=array('item'=>$sql->getValue('plz'),'extra'=>$sql->getValue('latitude').','.$sql->getValue('longitude'), 'value'=>$sql->getValue('ort').' '.$sql->getValue('ortsteil'));
            $sql->next();
        } 
        echo json_encode( $array );
    }
    die();        
}

?>
Cheffchen

Benutzeravatar
frag-seb
Beiträge: 211
Registriert: 27. Sep 2011, 17:53
Wohnort: München
Kontaktdaten: Website

Re: Modul Produktkonfigurator / AJAX im Modul

22. Apr 2015, 17:43

Hallo zusammen,

warum willst du das unbedingt mit Ajax machen?

Bei deinem Bespiel wirft die Änderung des select Felds auch kein Request und braucht es auch nicht. Die Daten werden nach dem Aufruf mit einem Ajax Request abgefragt und der Response ist in einem JSON Format. Die ganze Geschäftslogik der Anwendung ist in JavaScript geschrieben, es werden die Boxen zum Div hinzugefügt die der Filterung entsprechen, schau dir einfach mal das script.js auf der Seite an.

Das die Boxen so schon animiert werden macht Masonry.

Link: http://desandro.github.io/masonry/demos ... rnizr.html

Eigentlich nicht so wild.

Grüße
Jochen

Popkultur
Beiträge: 82
Registriert: 1. Apr 2014, 19:55

Re: Modul Produktkonfigurator / AJAX im Modul

23. Apr 2015, 10:16

Vielen Dank für die Analyse und Tipps. Ich werde da wohl Schritt für Schritt vorgehen müssen, wenn ich mir den Riesenbatzen JS-Code anschaue, den ich nur zu einem drittel verstehe. Sind viele Bibliotheken und Frameworks drin.

Frage: Was ist der Unterschied zwischen:
$sql = new sql();
und
$sql = rex_sql::factory();

und Cheffchen: ist Dein Beispiel nicht anfällig für SQL-Injection durch $_GET['q']?

mein Code sieht jetzt so aus:

Code: Alles auswählen

<?php
	// AJAX Abfrage
	if(isset($_POST['groesse'])){
		if($REX['REDAXO']!=1) while(ob_end_clean());
		$sql = new sql();
		$sql->setQuery('SELECT * FROM '.$REX['TABLE_PREFIX'].'produktkonfigurator WHERE groesse = '.mysql_real_escape_string($_POST['groesse']).';');
		if($sql->getRows()){
			for($i = 0; $i < $sql->getRows(); $i ++){
				$array[]=array('bilddatei'=>$sql->getValue('bilddatei'),'produktbezeichnung'=>$sql->getValue('produktbezeichnung'));
				$sql->next();
			}
			//header("Content-Type: application/json", true);
			echo json_encode( $array );
		}
		die();       
	}




	// Werte aus DB auslesen und Formular aufbauen.

	$sql = rex_sql::factory();
	// $sql->debugsql = 1; //Ausgabe Query

	$sql->setQuery('SELECT * FROM '.$REX['TABLE_PREFIX'].'produktkonfigurator;');
    $ausgabe = '';
    for($i=0; $i<$sql->getRows(); $i++)
	{
		$wert = $sql->getValue('groesse');
		$ausgabe .= '<option value="'.$wert.'">'.$wert.' Zoll</option>';
		$sql->next();
	}

?>


<link rel="stylesheet" href="css/jquery-ui.min.css" >
<script src="js/vendor/jquery-ui.min.js"></script>
<script src="js/vendor/jquery-ui.theme.min.css"></script>
<script src="js/vendor/jquery-ui.structure.min.css"></script>



<script type="text/javascript">
  $(function() {
	  
    $('#groesse').selectmenu({ width: 200 });
	$('#produktkonfigurator').on('selectmenuchange','select',function(){
		var $form = $("#produktkonfigurator");
		var method = $form.attr("method") ? $form.attr("method").toUpperCase() : "GET";
		$.ajax({
			url: $form.attr("action"),
			data: $form.serialize(),
			type: method,
			success: function(data) {
				obj = JSON.parse(data);
				obj.forEach(function(produkt) {
					$('#produktansicht').append('<div class="produkt"><img src="files/'+produkt.bilddatei+'" /><p>'+produkt.produktbezeichnung+'</p></div>');				
				});
				//console.log(obj);
			}
		});
	});		
	
  });	
</script>






<div>
	<form id="produktkonfigurator" method="post" action="<?php echo rex_getUrl('$REX_ARTICLE_ID',$REX['CUR_CLANG']); ?>">
		<select name="groesse" id="groesse">
			<?php echo $ausgabe; ?>
        </select>
	</form>
</div>
<div id="produktansicht">
</div>
// edit: geht jetzt!

Benutzeravatar
frag-seb
Beiträge: 211
Registriert: 27. Sep 2011, 17:53
Wohnort: München
Kontaktdaten: Website

Re: Modul Produktkonfigurator / AJAX im Modul

23. Apr 2015, 19:17

Hallo Popkultur,
Frage: Was ist der Unterschied zwischen:
$sql = new sql();
und
$sql = rex_sql::factory();
new sql() würde ich mal sagen gibt ein neues Object zurück und rex_sql::factory(); (Singleton) gibt immer das gleiche zurück. Was ach noch ein zum vorteil ist, dass man nicht direkt die Classe indizierte, was eine lose Kopplung ermöglicht (factory).

http://de.wikipedia.org/wiki/Entwurfsmuster
und Cheffchen: ist Dein Beispiel nicht anfällig für SQL-Injection durch $_GET['q']?


Würde ich auch so sehen.. Soll ja sicher nur ein Beispiel sein und keine endgültige Lösung..

Grüße
Jochen

Benutzeravatar
frag-seb
Beiträge: 211
Registriert: 27. Sep 2011, 17:53
Wohnort: München
Kontaktdaten: Website

Re: Modul Produktkonfigurator / AJAX im Modul

23. Apr 2015, 19:24

PS:
dass man nicht direkt die Classe indizierte, was eine lose Kopplung ermöglicht (factory).
Bin mir nicht sicher ob das so verständlich ist, als mit lose Kopplung ist gemient.

Wenn sich irgendwann mal die sql classe ändern sollte würde es bei einem direkt Aufruf krachen.
Durch die Factory würdest du gar nicht mitbekommen das sich was geändert hat.

Grüße

Popkultur
Beiträge: 82
Registriert: 1. Apr 2014, 19:55

Re: Modul Produktkonfigurator / AJAX im Modul

28. Apr 2015, 17:37

Mag mir nochmal jemand helfen? Die zwei Checkboxen (siehe ganz unten) übertragen keine Werte :( Wenn ich die anderen Formularselects abfrage, geht es allerdings.
:?

Code: Alles auswählen

<?php
	// AJAX Abfrage
	if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
		if($REX['REDAXO']!=1) while(ob_end_clean());

		$sql = new sql();
		$query = 'SELECT * FROM '.$REX['TABLE_PREFIX'].'meineprodukte';
		$cond = array();
		if (isset($_REQUEST['ed'])) {
			$cond[] = 'ed = "'.mysql_real_escape_string($_REQUEST['ed']).'"';
		}
		if (isset($_REQUEST['vw'])) {
			$cond[] = 'vw = "'.mysql_real_escape_string($_REQUEST['vw']).'"';
		}
		if (!isset($_REQUEST['vw']) and !isset($_REQUEST['ed'])) {
			$cond[] = '1=2';
		}
		if (count($cond)) {
			$query .= ' WHERE ' . implode(' AND ', $cond);
		}
		$sql->setQuery($query.';');


		if($sql->getRows()){
			for($i = 0; $i < $sql->getRows(); $i ++){
				$array[]=array('bilddatei'=>$sql->getValue('bilddatei'),'produktbezeichnung'=>$sql->getValue('produktbezeichnung'));
				$sql->next();
			}
			//header("Content-Type: application/json", true);
			echo json_encode( $array );
		} else echo '{}';
		die();       
	}
?>


<?php

	// Werte aus DB auslesen und Formular aufbauen.

	$sql = rex_sql::factory();
	// $sql->debugsql = 1; //Ausgabe Query

	$sql->setQuery('SELECT * FROM '.$REX['TABLE_PREFIX'].'meineprodukte;');
    for($i=0; $i<$sql->getRows(); $i++)	{
		$werte_aufloesung[] = $sql->getValue('aufloesung');
		$werte_seitenverhaeltnis[] = $sql->getValue('seitenverhaeltnis');
		$werte_technologie[] = $sql->getValue('technologie');
		$werte_groesse[] = $sql->getValue('groesse');
		$sql->next();
	}

	$werte_aufloesung = array_unique($werte_aufloesung);
    foreach($werte_aufloesung as $wert) {
		$select_aufloesung .= '<option value="'.$wert.'">'.$wert.'</option>';
	}

	$werte_seitenverhaeltnis = array_unique($werte_seitenverhaeltnis);
    foreach($werte_seitenverhaeltnis as $wert) {
		$select_seitenverhaeltnis .= '<option value="'.$wert.'">'.$wert.'</option>';
	}

	$werte_technologie = array_unique($werte_technologie);
    foreach($werte_technologie as $wert) {
		$select_technologie .= '<option value="'.$wert.'">'.$wert.'</option>';
	}

	$werte_groesse = array_unique($werte_groesse);
	$min_groesse = min($werte_groesse);
	$max_groesse = max($werte_groesse);

?>


<link rel="stylesheet" href="css/jquery-ui.min.css" />
<script src="js/vendor/jquery-ui.min.js"></script>
<script src="js/vendor/jquery-ui.theme.min.css"></script>
<script src="js/vendor/jquery-ui.structure.min.css"></script>
<script src="js/vendor/masonry.pkgd.min.js"></script>
<script src="js/vendor/imagesloaded.pkgd.min.js"></script>

<script type="text/javascript">
	function makeSafeForCSS(name) {
		return name.replace(/[^a-z0-9\-]/g, function(s) {
			var c = s.charCodeAt(0);
			if (c == 32) return '-';
			if (c >= 65 && c <= 90) return '_' + s.toLowerCase();
			return '__' + ('000' + c.toString(16)).slice(-4);
		});
	}


	function updateProdukte() {

		var $form = $("#meineprodukte");
		var method = $form.attr("method") ? $form.attr("method").toUpperCase() : "GET";
		$.ajax({
			url: $form.attr("action"),
			data: $form.serialize(),
			type: method,
			success: function(data) {
				obj = JSON.parse(data);
//console.log(obj);
				// Alle DIVs durchgehen, nicht vorhandene löschen
				$('#produktansicht div.produkt').each(function() {
					var loeschen = true;
					
					if (!jQuery.isEmptyObject(obj)) obj.forEach(function(produkt) {
						if ($(this).attr('id') == makeSafeForCSS(produkt.produktbezeichnung)) { loeschen = false; }
					});
					if (loeschen) { $(this).remove(); }
				});
				// Alle ausgewählten Objekte durchgehen, neue hinzufügen
				if (!jQuery.isEmptyObject(obj)) obj.forEach(function(produkt) {
					produkt.status = 'neu';
					$('#produktansicht div.produkt').each(function() {
						if ($(this).attr('id') == makeSafeForCSS(produkt.produktbezeichnung)) { produkt.status = 'bleibt'; }
					});
					if (produkt.status == 'neu') {
						$('#produktansicht').append('<div class="produkt" id="'+makeSafeForCSS(produkt.produktbezeichnung)+'"><img src="files/'+produkt.bilddatei+'" /><p>'+produkt.produktbezeichnung+'</p></div>');
					}
				});
	
			}
		});
		
	};
	
	
	
  $(function() {
	  
	$('#meineprodukte').on('selectmenuchange', 'select', updateProdukte);		
	$('#meineprodukte input[type="checkbox"]').change(updateProdukte);
	
    $('#aufloesung').selectmenu({ width: 200 });
    $('#seitenverhaeltnis').selectmenu({ width: 200 });
    $('#technologie').selectmenu({ width: 200 });
	$('#checkboxes').buttonset();

    $('#slider-groesse').slider({
      range: true,
	  min: <?php echo $min_groesse; ?>,
	  max: <?php echo $max_groesse; ?>,
	  change: updateProdukte,
      values: [ <?php echo $min_groesse; ?>, <?php echo $max_groesse; ?> ],
      slide: function( event, ui ) {
			$( "#min_groesse" ).val( $( "#slider-groesse" ).slider( "values", 0 ));
			$( "#max_groesse" ).val( $( "#slider-groesse" ).slider( "values", 1 ));
      }
    });
    $( "#min_groesse" ).val( $( "#slider-groesse" ).slider( "values", 0 ));
    $( "#max_groesse" ).val( $( "#slider-groesse" ).slider( "values", 1 ));

	var $container = $('#produktansicht').masonry();
	$container.imagesLoaded( function() {
	  $container.masonry();
	});
	  
  });	
</script>



<div>
	<form id="meineprodukte" method="post" action="<?php echo rex_getUrl('$REX_ARTICLE_ID',$REX['CUR_CLANG']); ?>">
        <div id="checkboxes">
        	<input type="checkbox" name="ed" id="ed" value="ed"><label for="ed">ed</label>
        	<input type="checkbox" name="vw" id="vw" value="vw"><label for="vw">vw</label>    
        </div>
        <select name="technologie" id="technologie">
            <?php echo $select_technologie; ?>
        </select>
        <select name="aufloesung" id="aufloesung">
            <?php echo $select_aufloesung; ?>
        </select>
        <select name="seitenverhaeltnis" id="seitenverhaeltnis">
            <?php echo $select_seitenverhaeltnis; ?>
        </select>
        <input type="text" id="min_groesse" name="min_groesse" readonly />
        <input type="text" id="max_groesse" name="max_groesse" readonly />
        <div id="slider-groesse"></div>
	</form>
</div>
<div id="produktansicht"></div>
<div style="clear: both;"></div>


Benutzeravatar
runstop64
Beiträge: 369
Registriert: 23. Okt 2012, 21:34
Wohnort: Hamburg
Kontaktdaten: Website Facebook Twitter

Re: Modul Produktkonfigurator / AJAX im Modul

28. Apr 2015, 21:48

Wenn sie nicht gesetzt sind, übertragen Checkboxen keine Werte. Liegt es vielleicht daran?
Viele Grüße,
Daniel


studio-ahoi.de | Referenzen | Friends Of REDAXO

Popkultur
Beiträge: 82
Registriert: 1. Apr 2014, 19:55

Re: Modul Produktkonfigurator / AJAX im Modul

29. Apr 2015, 21:26

Danke für den Tipp, ich glaube zwar nicht dass das der Grund ist aber ich werd's überprüfen.

Benutzeravatar
frag-seb
Beiträge: 211
Registriert: 27. Sep 2011, 17:53
Wohnort: München
Kontaktdaten: Website

Re: Modul Produktkonfigurator / AJAX im Modul

30. Apr 2015, 09:40

Hi Popkultur,

versuch es mal so

Code: Alles auswählen

<div id="checkboxes">
           <input type="hidden" name="ed" value="0">        
           <input type="checkbox" name="ed" id="ed" value="ed"><label for="ed">ed</label>
            <input type="hidden" name="vw" value="0">
           <input type="checkbox" name="vw" id="vw" value="vw"><label for="vw">vw</label>   
        </div>
Grüße
Jochen

Popkultur
Beiträge: 82
Registriert: 1. Apr 2014, 19:55

Re: Modul Produktkonfigurator / AJAX im Modul

30. Apr 2015, 10:47

Danke, wird dann aber nicht generell ein Value von 0 übertragen? Ich hatte ja geschrieben dass die anderen Formularfelder durchaus tun.

// Fehler gefunden, war ein Fehler im SQL statement!

Popkultur
Beiträge: 82
Registriert: 1. Apr 2014, 19:55

Re: Modul Produktkonfigurator / AJAX im Modul

7. Mai 2015, 16:53

Kleines Problemchen:

Ich vergebe IDs nummerische Werte, so dass sowas dabei herauskommt:

<input type="checkbox" id="id11">
<input type="checkbox" id="id23">

Und später weise ich mit $('#produktansicht .vergleichen').button(); den checkboxen die jquery ui button Klasse zu. Leider geht das nicht mehr, sobald eine Ziffer in der ID vorkommt. Ich will aber die Ziffer in der ID haben, weil so die Sache mit der Datenbank verknüpft wird. Kann mir jemand folgen? Ich übergebe die ID der checkbox per AJAX an PHP, damit ich dann ne mysql Abfrage machen kann anhand dieser ID. (Natürlich nach Integer konvertiert und limitiert, um Injection zu vermeiden).

Gibts einen anderen Weg?

Eine Behelfslösung wäre, für die Ziffern 1-9 Buchstaben zu verwenden. Hat jemand eine Idee, wie man das möglichst kurz in JS schreibt? Also ersetze 1 durch a, 2 durch b etc... und später in PHP die Rückumwandlung.

Popkultur
Beiträge: 82
Registriert: 1. Apr 2014, 19:55

Re: Modul Produktkonfigurator / AJAX im Modul

13. Mai 2015, 10:09

Hab das Problem gelöst, indem ich die IDs in Buchstaben umwandle. Andere Frage:

Ich habe ein Formular mit verschiedenen Eingabefeldern, es wird per Ajax verschickt sobald sich was an den Eingabefeldern ändert, um sofort die Auswahl der Produkte neu anzuzeigen und auch die Auswahl der Formularfelder anzupassen. Interaktiv quasi.

Nun möchte ich unterscheiden, welches Feld (Welche Checkbox, welcher slider) geändert wurde in der verarbeitenden PHP Datei, die per AJAX aufgerufen wird, um je nachdem unterschiedliche Aktionen in der PHP-Datei durchzuführen. Die PHP Datei gibt dann ein JSON Array zurück, in dem die Aktion wiederum aufgeführt ist, um dann entsprechende Felder des Formulars ein-/auszublenden.

Wie mach ich das am klügsten?

Benutzeravatar
anita
Beiträge: 711
Registriert: 25. Jan 2007, 10:25
Wohnort: Finsterwalde

Re: Modul Produktkonfigurator / AJAX im Modul

18. Mai 2015, 12:22

hallo,

die verschiedenen Methoden in eine PHP-Klasse schreiben
eine Methode speichert den Feldnamen in einer Variablen
mit einer switch-case-Anweisung wird die passende Methode aufgerufen
Gruß Anita

javanita engineering, immer eine zündende Idee
http://www.javanita.com

Zurück zu „Allgemeines [R4]“