PHP, MySQL - Связывание флажка с выпадающим списком


У меня возникла проблема с попыткой добавить "количество" к продукту, который заказывает человек. У меня есть таблица продуктов, таблица заказов, таблица order_item (которая представляет собой таблицу "многие ко многим", содержащую идентификаторы как продуктов, так и заказов). У меня есть выпадающее окно слева, в котором указано нужное вам количество. Максимальное значение - это запас, доступный в системе.

Вот как выглядит форма:

enter image description here

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

Названия продуктов и номера запасов указаны в таблице продуктов:

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;

Теперь я делаю то, что создаю массив из проверенных названий продуктов. Что я хочу сделать, так это связать значения из выпадающего меню, НО ТОЛЬКО ЕСЛИ ОНИ ЯВЛЯЮТСЯ ОДНИМ ИЗ ПРОВЕРЕННЫХ ЗНАЧЕНИЙ. Кроме того, если значение проверено, количество не может быть равно 0. Я, вероятно, делаю это крайне неприятным способом, но это то, что я считал лучшим. Я мог бы сделать текстовое поле, но тогда вам пришлось бы очистить пользовательский ввод. Это бы будет хорошо, если это сработает в отличие от того, что не работает =/

Я добавляю заказы, получая массив продуктов:

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

Тогда моя функция добавления заказа работает следующим образом:

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

Я думал, что мне, возможно, придется немного поработать с JavaScript, но в этом я полный профан.

Если бы я не смог объяснить себе: Короче говоря; Мне нужно добавить количество в массив продуктов, но только если продукты проверены и количество > 0.

Спасибо в вперед, Ура:)

ИЗМЕНИТЬ: Я внес некоторые изменения, но теперь я получаю следующую ошибку: Ошибка 1452: Не удается добавить или обновить дочернюю строку: не удается выполнить ограничение внешнего ключа (db/SEOrder_items, ОГРАНИЧЕНИЕ SEOrder_items_ibfk_2 ВНЕШНИЙ КЛЮЧ (product_id) ССЫЛКИ SEProducts (id))

Author: JheeBz, 2011-05-28

2 answers

В качестве первого шага я бы объединил массивы продуктов и количеств, чтобы количества, флажок и название продукта находились в одном массиве:

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

Приведет к следующему массиву (где 1 и 2 - идентификаторы продуктов, "is_checked" устанавливается только в том случае, если флажок был установлен):

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

Должно быть легко пройти через такой массив, используя:

foreach($_POST['products'] as $currentProductId => $currentProductArray)
 2
Author: feeela, 2011-05-28 15:05:51

Я думаю, вам просто нужно немного подправить свою логику и свой шаблон.

Во-первых, вы хотите полностью использовать продукты, доступные на странице заказа, а не продукты, которые возвращаются; это:

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

Должно выглядеть примерно так:

$products = the_products_list_that_you_sent_to_the_page();

Конечно, если список продуктов большой, то вам придется вытаскивать список продуктов со страницы (и проверять каждый продукт), как вы делаете сейчас. Однако, если продукты список невелик, тогда проще начать с известного и действительного списка.

Суть проблемы заключается в вашем взаимодействии с базой данных и в том, как работает add_order. Ваш add_order получает список продуктов для просмотра в $products. Все, что вам нужно сделать, это следующее:

  • Создайте массив данных для вставки.
  • Просмотрите $products, если продукт проверен и у него есть количество, добавьте его и его количество в список.
  • Проверьте, есть ли что-нибудь в списке заказов после того, как описанный выше цикл законченный:
    • Если в списке заказов что-то есть, add_order можно добавить все это в базу данных.
    • Если в списке заказов ничего нет, add_order может вернуть код ошибки (например, нулевой идентификатор заказа), и вызывающий абонент может пожаловаться пользователю, что вообще ничего не заказывать не имеет смысла.

Основная стратегия заключается в том, чтобы собирать ваши данные и затем действовать в соответствии с ними, а не пытаться действовать в соответствии с вашими данными, пока вы их собираете.

Теперь возникает проблема: как сделать мы связываем количество с конкретной проблемой? Это легко решить, так как у нас есть идентификаторы продуктов; ваши элементы <select> должны быть:

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

Затем, когда вы ищете количество определенного продукта, вы можете извлечь его прямо из $_POST в виде скаляра, как $q = $_POST['quantity_' . $product_id].

Я знаю, что мог бы решить корень вашей проблемы, просто сказав вам переименовать ваши элементы <select>, но я решил, что по ходу дела разберусь с некоторыми другими вашими возможными проблемами.

 1
Author: mu is too short, 2011-05-28 14:59:33