简体   繁体   English

PHP、MySQL - 将复选框与下拉菜单关联

[英]PHP, MySQL - Associating a checkbox with a dropdown

I'm having an issue with trying to add a "quantity" to a product that a person is ordering.我在尝试向人们订购的产品添加“数量”时遇到问题。 I've got a Products table, an orders table, an order_item table (which is a many-to-many table that contains the id's from both products and orders).我有一个 Products 表、一个 orders 表、一个 order_item 表(这是一个包含产品和订单的 id 的多对多表)。 I've got a dropdown box on the left which has the quantity that you want.我在左边有一个下拉框,里面有你想要的数量。 The maximum value is the stock available in the system.最大值是系统中可用的库存。

This is what the form looks like:这是表单的样子:

在此处输入图像描述

<form name ="order_form" method="post" action="add_order_action.php" enctype="multipart/form-data">
                    <table border=1 cellpadding=2 cellspacing=2>
                        <caption>Order Form</caption>
                        <tr>
                            <th align="right"> Property </th>

                            <th align="left"> Value </th>
                        </tr>
                        <tr>
                            <td class="col1"> Name </td>
                            <td class="col2"> <input type="text" name="customer" id ="customer" size=30> </td>
                        </tr>
                        <tr>
                            <td class="col1"> Address </td>
                            <td class="col2"> <input type="text" name="address" id ="address" size=30> </td>
                        </tr>
                        <tr>
                            <td class="col1"> Products </td>
                            <td class="col2">

                                <!-- Interests is an array of all interests in the database-->
                                {foreach $products as $product}
                                <select name="products[{$product.id}][quantity]" id ="quantities">
                                        {section name=quantities start=0 loop=$product.stock + 1 step=1}
                                        <option value="{$smarty.section.quantities.index}">{$smarty.section.quantities.index}</option>
                                        {/section}
                                </select>
                                <input type="checkbox" name="products[{$product.id}][is_checked]" value="1">{$product.name}<br>
                                {/foreach}
                            </td>
                        </tr>
                        <tr>
                            <td colspan=2 align="center">
                                <input type="submit" name="submit" value="Submit">
                                <input type="reset"  name="reset"  value="Reset">
                            </td>
                        </tr>
                    </table>
                </form>

The product names and stock numbers are both from the products table:产品名称和库存编号均来自产品表:

create table if not exists SEProducts
(
    id int not null auto_increment primary key,
    price double not null,
    name varchar(30) not null,
    stock int not null,
    original_stock int not null,
    sold_stock int not null
)ENGINE=INNODB;

Now, what I do is that I make an array from the product names that are checked.现在,我要做的是从检查的产品名称中创建一个数组。 What I wanna do is associate the values from the dropdown menus, BUT ONLY IF THEY ARE ONE OF THE CHECKED VALUES.我想做的是关联下拉菜单中的值,但前提是它们是检查值之一。 Additionally, if a value is checked, the quantity can't be 0. I'm probably doing this an extremely frustrating way but this is what I thought was the best.此外,如果检查了一个值,则数量不能为 0。我可能这样做是一种非常令人沮丧的方式,但这是我认为最好的方式。 I could've done a text field but then you'd have to sanitise user input.我可以做一个文本字段,但你必须清理用户输入。 That'd be okay if it works as opposed to this which doesn't =/如果它起作用而不是不起作用,那就没关系了=/

I add the orders by getting the product array:我通过获取产品数组来添加订单:

<?php
include "includes/defs.php";

$customer = $_POST['customer'];
$delivery_address = $_POST['address'];
if (isset($_POST['products'])) 
{
    $products = $_POST['products'];
} 
else 
{
    $error = "An order must consist of 1 or more items.";
    header("Location: list_inventory.php?error=$error");
    exit;
}

$id = add_order($customer, $delivery_address, $products);

header("Location: order.php?id=$id");
exit;
?>

Then my add order function works like this:然后我的添加订单 function 的工作方式如下:

function add_order($customer, $delivery_address, $products)
{
    $connection = mysql_open();
    $customer = mysql_escape_string($customer);
    $delivery_address = mysql_escape_string($delivery_address);

    $query = "insert into SEOrders (name, address, status) " .
             "values ('$customer', '$delivery_address', 'New')";
    $result = mysql_query($query, $connection) or show_error();

    $id = mysql_insert_id();

foreach ($products as $product)
    {
        if ($product['is_checked'] != 0 && $product['quantity'] != 0)
        {
            $query2 = "insert into SEOrder_items (order_id, product_id, quantity) " .
                    "values ('$id', '$product.id', '$product.quantity')";
            $result2 = mysql_query($query2, $connection) or show_error();
        }
    }

mysql_close($connection) or show_error();
return $id;
}

I was thinking I might have to do some JavaScript but I'm absolutely rubbish at that.我在想我可能不得不做一些 JavaScript 但我绝对是垃圾。

If I wasn't able to explain myself: Long story short;如果我无法解释自己:长话短说; I need to add quantities to the products array but only if the products are checked and the quantity is > 0.我需要将数量添加到产品数组中,但前提是检查了产品并且数量> 0。

Thanks in advance, Cheers:)在此先感谢,干杯:)

EDIT: I've made some changes but now I get the following error: Error 1452: Cannot add or update a child row: a foreign key constraint fails ( db/SEOrder_items , CONSTRAINT SEOrder_items_ibfk_2 FOREIGN KEY ( product_id ) REFERENCES SEProducts ( id ))编辑:我做了一些更改,但现在出现以下错误:错误 1452:无法添加或更新子行:外键约束失败( db/SEOrder_items 、 CONSTRAINT SEOrder_items_ibfk_2 FOREIGN KEY ( product_id ) REFERENCES SEProducts ( id ))

As a first step I would combine the products- and quantities-arrays, so the quantities, the check-box and the product-name are in one array:作为第一步,我将组合产品和数量数组,因此数量、复选框和产品名称在一个数组中:

<select name="products[{$product.id}][quantity]" id ="quantities">
…
</select>
<input type="checkbox" name="products[{$product.id}][is_checked]" value="1" />

would result in following array (where 1 and 2 are the products-ids, 'is_checked' is only set if the box was checked):将导致以下数组(其中 1 和 2 是产品 ID,仅在选中该框时才设置“is_checked”):

$_POST['products'] = array(
    [1] => array(
        'quantity' => 3,
        'is_checked' => 1,
    ),
    [2] => array(
        'quantity' => 1,
        // not checked
    ),
);

It should be easy to get through such an array using:使用以下方法应该很容易通过这样的数组:

foreach($_POST['products'] as $currentProductId => $currentProductArray)

I think you just need to tweak your logic and your template a little bit.我认为你只需要稍微调整你的逻辑和模板。

First, you want to drive the whole thing from the products that are available on the ordering page rather than the products that come back;首先,您希望从订购页面上可用的产品而不是返回的产品中驱动整个事情; this:这个:

if (isset($_POST['products'])) 
{
    $products = $_POST['products'];
} 
else 
{
    $error = "An order must consist of 1 or more items."
    header("Location: list_inventory.php?error=$error");
    exit;
}

Should look more like this:应该看起来更像这样:

$products = the_products_list_that_you_sent_to_the_page();

Of course, if the products list is massive then you'll be stuck pulling the products list out of the page (and validating each product) as you're doing now.当然,如果产品列表很大,那么您将无法像现在这样将产品列表拉出页面(并验证每个产品)。 However, if the products list is small then it is easier to start with a known and valid list.但是,如果产品列表很小,那么从已知且有效的列表开始会更容易。

The meat of the issue is your database interaction and how add_order works.问题的核心是您的数据库交互以及add_order如何工作。 Your add_order gets a list of products to look at in $products .您的add_order获得要在$products中查看的产品列表。 All you need to do is this:您需要做的就是:

  • Create an array of data to be inserted.创建要插入的数据数组。
  • Go through $products , if the product is checked and it has a quantity, add it and its quantity to the list. Go 到$products ,如果产品被选中并且有数量,则将其及其数量添加到列表中。
  • Check if there is anything in the order list after the above loop is finished:上述循环完成后,检查订单列表中是否有任何内容:
    • If there is something in the order list, add_order can add it all to the database.如果订单列表中有东西, add_order可以将其全部添加到数据库中。
    • If there isn't anything in the order list, add_order can return an error code (such as an order ID of zero) and the caller can complain to the user that ordering nothing at all makes no sense.如果订单列表中没有任何内容, add_order可以返回错误代码(例如订单 ID 为零),并且调用者可以向用户抱怨根本没有任何订单是没有意义的。

The basic strategy is to collect your data and then act on it rather trying to act on your data while you collect it.基本策略是收集您的数据,然后对其采取行动,而不是在收集数据时尝试对您的数据采取行动。

Now the problem becomes: how do we associate a quantity with a specific problem?现在问题变成了:我们如何将数量与特定问题联系起来? This is easy to solve as we have product IDs;这很容易解决,因为我们有产品 ID; your <select> elements should be:你的<select>元素应该是:

<!--
  Note that this also avoids the evil of having
  duplicate id attributes in one page
-->
<select name="quantity_{$product.id}">

Then, when you're looking for the quantity of a specific product, you can pull it straight out of $_POST as a scalar as $q = $_POST['quantity_'. $product_id]然后,当您查找特定产品的数量时,您可以将其作为标量直接从$_POST中提取出来,如$q = $_POST['quantity_'. $product_id] $q = $_POST['quantity_'. $product_id] . $q = $_POST['quantity_'. $product_id]

I know I could have solved the root of your problem just by telling you to rename your <select> elements but I figured I'd sort out some of your other possible issues along the way.我知道我可以通过告诉您重命名<select>元素来解决您的问题的根源,但我想我会在此过程中解决您的其他一些可能的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM