php,jquery和ajax - 根据之前选择的值

时间:2016-11-21 16:06:17

标签: php mysql ajax

我被告知我以前的帖子不是很清楚,所以我会尝试以不同的方式提问。

我在OOP食谱书中工作。目前,我正在努力添加食谱。为此,我显示一个测量下拉列表,当用户选择测量时,我想显示另一个下拉列表,其中包含为该measurement_id找到的单位。

mysql上的表是具有id和name列的度量,以及具有id,name和measurement_id列的单位(measurement_id是单位表的外键)。多个单元属于一个测量。

为此,我创建了一个测量php对象/类。

在new_recipe.php上,我添加了一个表单,其余列添加了一个配方,我将只包括我现在正在处理的问题:

注意:在measurement.php上,Measurement php对象/类具有以下方法: - 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;
    });   
});    


    $(document).ready(function(){         $('#newRecipe')。on('change','。selectMeasurement',function(){           var selectedMeasurementId = this.value;             $就({                 方法:'POST',                 url:'classes / measurement.php',                 data:selectedMeasurementId,                 成功:function(){                     警报(selectedMeasurementId);                 }             });         });
    });

在js文件中,我想到的是成功,调用方法对象:

成功:$ measurementObj-&gt; 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. 
}

所以我的问题是......为了ajax请求的成功,我怎么能执行这个$ measurementObj-&gt; get_units_for_measurement(在第一个下拉列表中选择了measurement_id)?

我希望现在有点清楚。 谢谢

1 个答案:

答案 0 :(得分: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 />';
        }
    }
}

(您可能还需要使用getRecipes()addRecipe($recipe)updateRecipe($recipe)deleteRecipe($id)等方法 RecipeDAO.php 。)

接下来,当您向脚本发出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 中的所有内容进行必要的调整。