2016-11-21 311 views
0

我被告知我之前的帖子不是很清楚,所以我會嘗試以不同的方式提出。php,jquery和ajax - 根據之前選定的值填充選擇下拉列表

我正在OOP食譜書中工作。目前,我正在努力添加食譜。爲此,我顯示一個測量下拉列表,當用戶選擇測量時,我想顯示另一個下拉列表,其中包含爲該measurement_id找到的單位。

mysql上的表是帶有id和name列以及id,name和measurement_id列(measurement_id是單位表的外鍵)的單位的度量值。多個單位將屬於一個測量。

爲此,我創建了一個測量php對象/類。

在new_recipe.php,我包括形式,其餘列添加配方,我將只包括這件事我現在治療:

注:上measurement.php,測量PHP對象/ class有這些方法: - display_measurements() - >只需從測量表中選擇所有測量。 - get_units_for_measurement($ measurement_id) - >選擇所有具有相同measurement_id的單位。

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> 

您可以在窗體中看到兩個選擇下拉菜單;第一個是我正在顯示測量結果的那個,另一個是我用一些註釋行來說的地方,我將它放置在「過濾」在第一個下拉列表中選擇的measurement_id以顯示所屬單元。它不會重新加載頁面,我被建議用ajax(我不太熟悉)來做。這Ajax調用在一個js文件,鏈接到項目的頁腳:

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


$(文件)。就緒(函數(){ $( '#newRecipe')上(」 。變化」, 'selectMeasurement',函數(){ VAR selectedMeasurementId = THIS.VALUE; $就({ 方法: 'POST', URL: '類/ measurement.php', 數據:selectedMeasurementId, 成功:function(){ alert(selectedMeasurementId); } }); });
});

在js文件,我在腦子裏很成功,調用該方法的對象:

成功:$ measurementObj-> get_units_for_measurement($ _ POST [ '測量']),我明白,如果我有一個Ajax響應,我想獲得給定度量單位,但是,我不能在這裏調用一個PHP對象。

另外,我在設置測量時試圖做一些事情。選擇的測量後,我試圖做的:

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

所以我的問題是....我怎麼能執行此$ measurementObj-> get_units_for_measurement(measurement_id在第一個下拉列表中選擇),爲的成功ajax請求?

我希望現在有點清楚。 謝謝

+0

嗯..這是非常令人困惑,只是明白你的問題。 –

+0

你有一些東西混雜在一起。首先你在這個文件中有什麼:'classes/measurement.php'?它是_測量class_還是負責獲取'ajax'請求併發回ajax要求的數據的文件? – EhsanT

+0

歐姆....它是_measurement類。我應該以另一種方式重命名文件嗎?我實際上正在研究是否用大寫命名文件是常見的類,但是我沒有找到任何東西,所以我只用類名命名。負責ajax請求的文件目前僅在頁腳^^ –

回答

1

免責聲明:這是一個公正的,你如何能做到這一個粗略的和未經考驗的草圖。如你所說的OOP,我會首先重構你如何訪問數據庫以更加面向對象。我將使用一個縮短版本的DAO模式。如果您按照certain conventions,它使它非常容易使用。這種模式有很多缺點,但大多數情況下它會使您的代碼更加有組織。

首先,我將創建兩個類MeasurementDAOUnitDAO,它們將分別用於訪問每個表的數據。 (你可以只使用一個類,如果它是你更方便。)

類/ 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 />'; 
     } 
    } 
} 

類/ 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 />'; 
     } 
    } 
} 

(您可能還需要一個RecipeDAO.php與方法,如getRecipes(),addRecipe($recipe),updateRecipe($recipe)deleteRecipe($id)。)

接下來,當您向腳本發出AJAX請求時,您不希望直接調用該類。相反,你想調用一個使用該類的腳本。

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); 

你會轉到例如,呼叫從您的JavaScript腳本ajaxHandler.php?action=get_units&measurement=123

接下來,我們將使用我們的新方法得到測量結果。 (我個人覺得它更好,更清潔做的所有數據庫的東西在開始 - 反對這樣做,你的輸出HTML)

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> 

最後,讓我們呼喚ajax處理腳本並構建選項列表。

// 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); 
     }); 
    }); 
}); 

應該是這樣。您需要添加缺少的部分,例如包含PHP文件。

(如果你要保持你的當前設置,剛剛從ajaxHandler.php遵循一切並作出必要的調整。)

相關問題