2016-11-21 3 views
0

Mir wurde gesagt, mein vorheriger Beitrag war nicht sehr klar, so werde ich versuchen, es auf eine andere Weise zu fragen.php, jquery und ajax - bevölkern Auswahl Dropdown auf dem vorherigen ausgewählten Wert

Ich arbeite in einem OOP Rezeptbuch. Im Moment arbeite ich daran, Rezepte hinzuzufügen. Dafür zeige ich eine Dropdown-Liste mit Messungen an. Wenn der Benutzer die Messung auswählt, möchte ich ein weiteres Dropdown mit den für diese measurement_id gefundenen Einheiten anzeigen.

Die Tabellen auf mysql sind Messungen mit ID- und Name-Spalte und Einheiten mit ID, Name und Spalte measurement_id (measurement_id ist der Fremdschlüssel für die Units-Tabelle). Mehrere Einheiten gehören zu einer Messung.

Dafür habe ich eine Messung PHP-Objekt/Klasse erstellt.

Auf new_recipe.php, schließe ich ein Formular, mit dem Rest der Spalten ein Rezept zu schreiben, werde ich nur die Angelegenheit enthält ich die Behandlung jetzt:

HINWEIS: auf measurement.php, die Messung PHP Objekt/class verfügt über folgende Methoden: - display_measurements() -> Wählt einfach ALLE Messungen aus der Messtabelle aus. - get_units_for_measurement ($ measurement_id) -> Wählt ALLE Einheiten mit derselben measurement_id aus.

public function display_measurements() { 
     include 'includes/db_connection.php'; 
      try { 

     $sql = "SELECT id, name FROM measurements"; 

     $results = $conn->prepare($sql); 
     $results->execute(); 
    } catch(PDOException $e) { 
     echo 'Error: ' . $e->getMessage() . '<br />'; 
     return array(); 
    } 
     return $results->fetchAll(PDO::FETCH_ASSOC); 
    } 


    public function get_units_for_measurement($measurement_id = ':measurement_id') { 
     include 'includes/db_connection.php'; 

     try { 
      $sql = "SELECT measurements.id, units.id, units.name " 
       . "FROM measurements " 
       . "JOIN units " 
       . "ON measurements.id=units.measurement_id WHERE measurements.id=:measurement_id"; 
      $result = $conn->prepare($sql); 
      $result->bindParam(':measurement_id', $measurement_id, PDO::PARAM_INT); 
      $result->execute(); 
     } catch(PDOException $e) { 
     echo 'Error: ' . $e->getMessage() . '<br />'; 
     return array(); 
    } 
    return $result->fetchAll(PDO::FETCH_ASSOC); 
    } 

<form id="newRecipe" method="POST" action="new_recipe.php"> 
(...) 
    <div class="input_group"> 
     <label for="name" class="required">Name</label> 
     <input name="name" type="text" value="" /> 
    </div> 
    <div class="input_group"> 
     <label for="measurements" class="required">Measurements</label> 
     <select name="measurements" class="selectMeasurement"> 
      <option disabled selected value=""> -- select a measurement -- </option> 
<?php 
$measurements = $measurementObj->display_measurements(); 
foreach ($measurements as $measurement) { 
    echo '<option value="' . $measurement['id'] . '" '; 
    echo '>' . $measurement['name'] . '</option>'; 
} 
?> 
     </select>   
    </div> 
    <div class="input_group"> 
     <label for="units" class="required">Units</label> 
     <select id="selectUnit" name="units"> 
      <option disabled selected value=""> -- select a unit -- </option> 
      <?php 
      if (isset($_POST['measurements'])) { 
       die('ddddd'); 
       // $units = $measurementObj->get_units_for_measurement($_POST['measurements']); 
      //  foreach ($units as $unit) { 
      //   echo '<option value="' . $unit['id'] . '" '; 
      //   echo '>' . $unit['name'] . '</option>'; 
      //  } 
      } 
      ?> 
     </select> 
    </div> 
    (...) 
    <button class="submit" type="submit" name="submit">Submit</button> 
</form> 

Sie können in der Form zwei Dropdown-Listen auswählen; der erste ist der, wo ich die Messungen anzeige, und der nächste, den ich mit einigen kommentierten Zeilen habe, ist, wo ich die im ersten Dropdown ausgewählte measurement_id "filtern" soll, um die zugehörigen Einheiten anzuzeigen Wenn die Seite nicht neu geladen wurde, wurde mir geraten, das mit Ajax zu tun (was mir nicht sehr vertraut ist). Diese Ajax-Aufruf in eine JS-Datei, in die Fußzeile des Projekts verknüpft.

$(document).ready(function() { 
    $('#newRecipe').on('change','.selectMeasurement', function(){ 
     var selectedMeasurementId = this.value; 
     $.ajax({ 
      method: 'POST', 
      url: 'classes/measurement.php', 
      data: selectedMeasurementId 
     }); 
     return true; 
    }); 
});  

oder
$ (document) .ready (function() { $ ('# newRecipe') auf (‘ . Änderung‘, 'selectMeasurement', function() {var selectedMeasurementId = this.value; .ajax $ ({ Methode: 'POST', url: 'Klassen/measurement.php', Daten: selectedMeasurementId, Erfolg: Funktion() { Alarm (selectedMeasurementId); } }); });
});

In der JS-Datei, was ich im Sinn hatte, auf Erfolg war, rufen Sie die Methode Objekt:

Erfolg: $ measurementObj-> get_units_for_measurement ($ _ POST [ 'Messungen']), und ich verstehe, ich, wenn habe eine Ajax-Antwort, ich möchte die Einheiten für die gegebene Messung bekommen, aber ich kann hier kein PHP-Objekt aufrufen.

Ich habe auch versucht, etwas zu tun, wenn die Messungen eingestellt sind. Nach dem Wählen Sie für die Messungen habe ich versucht zu tun:

if (isset($_POST['measurements'])) { 
    //then $measurementObbj->get_units_for_measurement|($_POST['measurements']), but it seems it does not "detect" the measurements has been set. 
} 

Also meine Frage ist .... wie kann ich das measurementObj- $ ausführen> get_units_for_measurement (measurement_id im ersten Drop-Down ausgewählt), für den Erfolg der Ajax-Anfrage?

Ich hoffe, es ist jetzt ein bisschen klarer. Danke

+0

Hmm .. es sehr verwirrend ist nur auf Ihre Frage zu verstehen. –

+0

Sie haben ein paar Dinge miteinander vermischt. Zuerst, was Sie in dieser Datei haben: 'classes/measure.php'? ist es die _ Maßklasse_ oder eine Datei, die dafür verantwortlich ist, die'Ajax'-Anfrage zu erhalten und die Daten zurückzusenden, nach denen Ajax gefragt hat? – EhsanT

+0

Ohm .... es ist die _Mess-Klasse. Soll ich die Datei anders umbenennen? Ich habe tatsächlich gesucht, wenn es üblich ist, die Datei mit Kapital zu benennen, als die Klasse, aber ich habe nichts gefunden, also habe ich nur mit dem Klassennamen benannt.Die Datei, die für die Ajax-Anfrage zuständig ist, befindet sich im Moment nur in der Fußzeile ^^ –

Antwort

1

Haftungsausschluss: dies ist ein nur eine grobe und nicht getestete Skizze, wie Sie es tun können.

Wie Sie OOP erwähnt haben, würde ich zuerst umgestalten, wie Sie auf die Datenbank zugreifen, um objektorientierter zu sein. Ich werde eine gekürzte Version eines DAO-Patterns verwenden. Wenn Sie certain conventions folgen, ist es sehr einfach zu bedienen. Mit diesem Muster gibt es einige Nachteile, aber der Code bleibt größtenteils besser organisiert.

Zuerst würde ich zwei Klassen erstellen MeasurementDAO und UnitDAO, die für den Zugriff auf Daten für jede Tabelle jeweils verwendet werden. (Sie können nur eine Klasse verwenden, wenn es bequemer für Sie ist.)

Klassen/MeasurementDAO.php

class MeasurementDAO 
{ 
    protected $conn; 

    public function __construct(PDO $conn) { 
     $this->conn = $conn; 
    } 

    public function getMeasurements() { 
     try { 
      // no need to use prepare() if you are not using any placeholders e.g. :name or ? 
      // query() and prepare() do not return results, but a (st)atement (h)andler 
      $sth = $this->conn->query("SELECT id, name FROM measurements"); 
      return $sth->fetchAll(PDO::FETCH_OBJ); 
     } catch (PDOException $e) { 
      echo 'Error: ' . $e->getMessage() . '<br />'; 
     } 
    } 
} 

Klassen/UnitDAO.php

class UnitDAO 
{ 
    protected $conn; 

    public function __construct(PDO $conn) { 
     $this->conn = $conn; 
    } 

    public function getUnitsByMeasurement($measurementId) { 
     try { 
      // if I am not mistaken, this query should be shorter and equivalent to your initial one 
      $sth = $this->conn->prepare("SELECT * FROM units WHERE measurement_id = ?"); 
      // I have never seen any reason to use bindParam() as you can just pass your values in execute() 
      $sth->execute(array($measurementId)); 
      return $sth->fetchAll(PDO::FETCH_OBJ); 
     } catch (PDOException $e) { 
      echo 'Error: ' . $e->getMessage() . '<br />'; 
     } 
    } 
} 

(Sie Werde wahrscheinlich auch eine RezeptDAO.php mit Methoden wie getRecipes(), addRecipe($recipe), , deleteRecipe($id).)

Wenn Sie als Nächstes eine AJAX-Anforderung an ein Skript senden, möchten Sie die Klasse nicht direkt aufrufen. Stattdessen möchten Sie ein Skript aufrufen, das die Klasse verwendet.

ajaxHandler.php

// this will hold the data to be sent back as our response 
$res = array(); 
// initialize connection 
$conn = new PDO(/*...*/); 
// determine what action to take 
if ($_GET['action'] === 'get_units') { 
    // get units 
    $res['units'] = (new UnitDAO($conn))->getUnitsByMeasurement($_GET['measurement']); 
} 
header('Content-Type: application/json'); 
// last line: send response (it should be the only thing that gets outputted) 
echo json_encode($res); 

Sie würden das Skript von Ihrem JavaScript aufrufen, indem Sie auf z.B. ajaxHandler.php?action=get_units&measurement=123.

Als nächstes würden wir die Messungen mit unserem neuen Weg bekommen. (Ich persönlich es besser finden und sauberere alle Sachen, die Datenbank am Anfang zu tun -. Im Gegensatz zu, es zu tun, wie Sie HTML ausgeben)

new_recipe.php

<?php 
// initialize connection 
$conn = new PDO(/*...*/); 
// get measurements 
$measurements = (new MeasurementDAO($conn))->getMeasurements(); 
?> 

<form id="newRecipe" method="POST" action="new_recipe.php"> 
    <!-- etc --> 
    <div class="input_group"> 
     <!-- sidenote: label's FOR attribute attaches itself to the inputs's ID attribute, not NAME attribute --> 
     <label for="measurements" class="required">Measurements</label> 
     <select name="measurements" class="selectMeasurement"> 
      <option disabled selected value=""> -- select a measurement -- </option> 
      <?php if ($measurements) : ?> 
       <?php foreach ($measurements as $measurement) : ?> 
        <option value="<?php echo $measurement->id ?>"><?php echo $measurement->name ?></option> 
       <?php endforeach ?> 
      <?php endif ?> 
     </select> 
    </div> 
    <div class="input_group"> 
     <label for="units" class="required">Units</label> 
     <select name="units" id="selectUnit"> 
      <option disabled selected value=""> -- select a unit -- </option> 
     </select> 
    </div> 
    <!-- etc --> 
</form> 

Schließlich wollen wir Anruf das Ajax-Skript und erstellen Sie die Liste der Optionen.

// shorter syntax for $(document).ready 
$(function() { 
    $('#newRecipe').on('change', '[name=measurements]', function() { 
     console.log('send request with ', this.value); 
     // we'll use a $.getJSON() which is a shortened version of $.ajax() 
     // make a GET request to ajaxHandler.php?action=get_units&measurement={this.value} 
     $.getJSON('ajaxHandler.php', { action: 'get_units', measurement: this.value }, function (res) { 
      console.log('got response', res); 
      var html = ''; 
      // build list of options if any 
      if (!$.isEmptyObject(res.units)) { 
       $.each(res.units, function (unit) { 
        html += '<option>' + unit.name + '</option>'; 
       }); 
      } 
      // set list of options 
      $('[name=units]').html(html); 
     }); 
    }); 
}); 

Das sollte es sein. Sie müssen die fehlenden Teile hinzufügen, einschließlich der PHP-Dateien.

(Wenn Sie Ihre aktuellen Einstellungen beibehalten möchten, folgen Sie einfach alles von ajaxHandler.php und die notwendigen Anpassungen vorzunehmen.)

Verwandte Themen