21.01.2017, 11:34
|
Интересующийся
|
|
Регистрация: 21.01.2017
Сообщений: 12
|
|
Список с многоуровневой зависимостью
Я не программист, я по железу.
Но прижало и возникла необходимость создать для поступающей на ремонт техники создать небольшую бд.
Для регистрации техники выбираем из динамических списков сначало отдел, далее с помощью javascript для второго окна формируется список категории техники отфильтрованный в запросе во выбранному ранее отделу, список для третьего окна должен фильтроваться как по выбранной категории, так и по выбранному отделу, но вот как получить значение выбраного отдела ума не приложу. Чтобы закончить свой проект, осталось решить только эту задачу, но времени в связи с загруженностью на изучение теории нет. Данные задачи приложил. Данные в бд для простоты урезал.
Последний раз редактировалось dfii, 21.01.2017 в 12:01.
|
|
21.01.2017, 17:54
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Ничего не напутано в представлении данных?
|
|
22.01.2017, 07:20
|
Интересующийся
|
|
Регистрация: 21.01.2017
Сообщений: 12
|
|
Ткни носом на сомнительное место
|
|
22.01.2017, 07:43
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Здесь не место, а подход к представлению данных. Откуда тут могут взяться многоуровневые списки, если набор 'Контрольный', 'Планировочный', 'Сдаточный', 'Приёмочный' характеризует видимо этапы ремонта, а набор 'ИБП', 'Монитор', 'Принтер', 'Системник', 'Сканер', это категория техники принятой на ремонт, и оба этих набора есть разные сущности?
Первый набор вообще не обязательно помещать в отдельную таблицу, как и нет необходимости помещать второй набор в отдельную таблицу. Оба этих набора могут быть полями ENUM одной единственной таблицы. Принимается техника на ремонт, выбирается ее категория, а также отдел куда она попадает, и все это пишется в одну таблицу.
Выбор же того что имеется в базе, это может быть выбор всех записей как по одному из этих наборов, так и по обоим, что задается в условии выборки. Результат такой выборки, это таблица, в которой можно по ID записи выбрать любую их них как для редактирования, например перемещения из отдела в отдел, так и для удаления из базы.
|
|
22.01.2017, 11:24
|
Интересующийся
|
|
Регистрация: 21.01.2017
Сообщений: 12
|
|
Приемочный, сдаточный, контрольный и т.д. это гипотетические отделы. Писать реальные отделы посчитал не желательным. Извеняюсь что ввёл в заблуждение своей фантазией
Код формы:
[spoiler]
<html>
<head>
<meta charset="utf-8" />
<title>Ремонт - Поступление</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="selects.js"></script>
</head>
<body>
<?php
function sp_otdel() {
$dbc = mysqli_connect ('localhost', 'root', '', 'select3');
$query = "SELECT * FROM tbl_otdel ORDER BY name";
$query_res = mysqli_query ($dbc, $query);
$sp_otdel = array();
while($row = mysqli_fetch_assoc($query_res)) {
$sp_otdel[] = $row; }
return $sp_otdel; }
$sp_otdel = sp_otdel();
?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<select name='sp_otdel' id='sp_otdel'>
<option value="0"> - Выберите отдел - </option>
<?php foreach($sp_otdel as $item) {echo "<option value='".$item['id']."'>".$item['name']."</option>";} ?>
</select><br /><br />
<select name='sp_category_tech' id='sp_category_tech' disabled="disabled">
<option value="0"> - Выберите категорию - </option>
</select><br /><br />
<select name='sp_num_tech' id='sp_num_tech' disabled="disabled">
<option value="0"> - Выберите номер - </option>
</select><br /><br />
</form>
</body>
</html>
[/spoiler]
Первый список формируется функцией при загрузке формы, после выбора значения в первом поле срабатывает скрипт и на основе этого значения формирует список категорий техники принадлежащий выбранному отделу. Второй список формируется кодом:
[spoiler]
<?php
$sp_otdel = @intval($_GET['sp_otdel']);
$dbc = mysqli_connect ('localhost', 'root', '', 'select3' );
$query = "SELECT tbl_number_tech.*, tbl_category.* FROM tbl_number_tech, tbl_category WHERE tbl_number_tech.id_location = $sp_otdel AND tbl_category.id = tbl_number_tech.id_category_tech GROUP BY tbl_category.category";
$regs = mysqli_query($dbc, $query);
if ($regs) {
$num = mysqli_num_rows($regs);
$i = 0;
while ($i < $num) {
$sp_category_tech[$i] = mysqli_fetch_assoc($regs);
$i++;
}
$result = array('sp_category_tech'=>$sp_category_tech);
}
else {
$result = array('type'=>'error');
}
print json_encode($result);
?>
[/spoiler]
Результат выборки возвращается обратно в JavaScript, откуда в форму в виде HTML кода.
После выбора категории техники на основе значения ПЕРВОГО и второго полей должен сформироваться третий список, НО значения второго поля я передаю по аналогии первой функции javascript'a, но вместе с со значением второго поля не могу передать значение ранее выбранного первого поля.
Этот код ждёт значения обеих предыдущих полей:
[spoiler]
<?php
$sp_category_tech = @intval($_GET['sp_category_tech']);
$sp_otdel = ; // Сюда нужно передать значение первого поля
$dbc = mysqli_connect ('localhost', 'root', '', 'select3' );
$query = "SELECT * FROM tbl_number_tech WHERE id_category_tech = $sp_category_tech AND id_location = $sp_otdel";
$regs = mysqli_query($dbc, $query);
if ($regs) {
$num = mysqli_num_rows($regs);
$i = 0;
while ($i < $num) {
$sp_num_tech[$i] = mysqli_fetch_assoc($regs);
$i++;
}
$result = array('sp_num_tech'=>$sp_num_tech);
}
else {
$result = array('type'=>'error');
}
print json_encode($result);
?>
[/spoiler]
Ещё меня немного удивила одно выражение в теме Формирование связанных списков select произвольной вложенности, где в начале статьи приводится:
Цитата:
|
Для двух зависимых списков (я публиковал пример более 5 лет назад!) ситуация простая и понятная, но люди задают вопрос — а как развить пример для вложения 3х списков?
Ответ — никак. Придется менять практически все, потому слово — менять тут не подходит.
|
Более конкретно:
[spoiler]
$('#sp_category_tech').change(function () { // Функция запускает скрипт при изменении поля sp_category_tech
var sp_category_tech = $(this).val(); // Инициализирует переменную sp_category_tech и передаёт ей значение второго поля
var sp_otdel = $('sp_otdel').val(); // Тут переменной sp_otdel по замыслу должно быть передано значение первого поля, но этого не происходит.
... // тут всякий дисабл для полей
var url = 'get_num_tech.php'; // объявляется переменная url с именем скрипта для фомирования третьего списка
$.get(url, "sp_category_tech=" + sp_category_tech, // тут смутно представляю что с помощью get должен запуститься скрипт, которому передаются значения выбраных полей, но как это воплотить в код?
[/spoiler]
Последний раз редактировалось dfii, 22.01.2017 в 11:24.
Причина: как тут спойлеры работают?
|
|
22.01.2017, 11:49
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Не майтесь хренью, а ответьте себе на вопрос - что должна содержать база? Если записи когда, от кого, какая техника поступила на ремонт, и ее сопровождение по циклу ремонта, то зачем все это, что только усложняет все, и пользы никакой нет?
Какая к черту разница гипотетические ли названия или реальные. Нет в принципе вообще многоуровневых списков в контексте select, есть связанные списки. Но связанные списки потребуются только тогда, когда в наличие есть дерево, той же категории техники. У вас этого нет, и все что вы пишите, это бесполезная трата ресурсов сервера и клиента.
|
|
22.01.2017, 12:59
|
Интересующийся
|
|
Регистрация: 21.01.2017
Сообщений: 12
|
|
я не программист, языков не знаю, а беру готовые примеры и подставляю свои данные.
В бд есть три таблицы.
1. Содержит перечень отделов
2. Содержит перечень категорий техники
3. Содержит номера техники, id отдела, к которому принадлежит, id категории техники к которой относится
Чтобы не производить ручной ввод данных первый список даёт возможность сузить возможные номера техники выбранным отделом, к которому эта техника пренадлежит, второй список всю технику выбранного отдела сортирует по категориям, например все принтеры бухгалтерии, в котором их 5 с номерами 107, 104, 108, 207, 301. Во первых я исключаю этим опечатку во время заполнения акта приёма, во вторых контролирую принадлежность техники данному отделу. Бывало что принтер одного отдела долгие месяцы использовал второй отдел, а так как при использовании 200 принтеров одной марки сами пользователи могли и не заметить подмены. Во вторых, пользователи могли бы следить за судьбой своего принтера через запросы в бд.
Как вы решение этих проблем предложите сделать проще?
пс: Реализовать это через перезагрузку форм проблемы нет. Но как это сделать с помощью одной формы и динамических списков?
Последний раз редактировалось dfii, 22.01.2017 в 13:26.
|
|
22.01.2017, 14:06
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Во вложении есть дамп базы. В нем простой список отделов, а также простой список техники. Оба списка не являются деревьями, то есть не имеют зависимостей. В третье таблице не понятно что к чему, какие-то номера....
Предположим, что принимается на ремонт техника, для простоты: Принтеры, Компьютеры, Сканеры. Техника может распределяться между тремя отделами: Первый, Второй, Третий. Пусть эти списки постоянны и не изменяются, что в общем не так важно, к примеру если перечень техники может изменяться, то тогда его держать как отдельную таблицу.
Достаточно для хранения такой записи иметь единственную таблицу заказов (туман, что есть 5 с номерами 107, 104, 108, 207, 301, в примере это поле `number`):
CREATE TABLE `orders` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Номер заказа',
`groups` enum('Первый','Второй','Третий') NOT NULL COMMENT 'Отделы',
`mechanism` enum('Компьютеры','Сканеры','Принтеры') NOT NULL COMMENT 'Техника',
`number` int(11) NOT NULL COMMENT 'Идентификатор техники',
`customer` varchar(120) NOT NULL COMMENT 'Заказчик',
`defect` varchar(1000) NOT NULL COMMENT 'Описание дефекта',
`performer` varchar(64) NOT NULL COMMENT 'Исполнитель работ',
`receipt_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Дата поступления',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Список заказов' AUTO_INCREMENT=1;
Соответственно форма приема заказов должна содержать поля для заполнения: number, customer, defect, performer и два списка (select) описывающих массивы [1=>'Первый','Второй','Третий'] и [1=>'Компьютеры','Сканеры','При нтеры'].
Заполнение формы, это выбор в списке раздела, категории техники, и указания остальных значений в полях формы.
При получении формы запись получит номер заказа и автоматически дату поступления заказа как текущую дату.
Если убрать из таблицы поля customer, defect, performer, receipt_date, то заполнять ничего не требуется, кроме указания какого-то номера (?). При этом делать какие либо запросы не понятно за какими списками не требуется.
Вывод содержимого этой таблицы можно производить по любому из параметров - фильтр. Это могут быть списки только по отделу со всей его техникой, либо по конкретной технике, по дате поступления и т.д., и т.п. То есть по известным полям формы задаются параметры запроса: выбор в списках, задание условия, например равно дате, либо больше даты и прочее.
Чтобы построить базу данных, нужно понимать задачу решаемую. Для примера описанного выше этой таблицы вполне хватит. И из вашего представления не видно того, чтобы требовалась какая-то последовательная выборка не понятно чего и зачем. А из описанного вообще не понять деталей.
Последний раз редактировалось laimas, 22.01.2017 в 14:09.
|
|
22.01.2017, 14:45
|
Интересующийся
|
|
Регистрация: 21.01.2017
Сообщений: 12
|
|
Безусловно ваши советы при разработке хранения и использования данных мне пригодятся, за что вам выражают благодарность.
Но я всего лишь хотел узнать как в Javascript получить из формы значения двух полей и передать их для обработки запроса, видимо пока это останется непознаным.
Под отделами в базе я имел ввиду не отделы по ремонту техники, а отделы, которые участвуют в их "истреблении" и которые их на ремонт и отправляют. То что кажется в бд излишним для вас, для меня на практике экономит время и нервы, так как "оптимизация" затрат на производстве привела к тому что работы стало так много и такой разнообразной что приходится и принимать на ремонт и ремонтировать и подключать и настраивать, учить пользоваться, обеспечивать связь, консультировать и отчитываться в лице одного. Поэтому, чтобы избавить себя от бесконечных звонков "как там мой принтер с цветочком на лотке? когда будет готов? Что с ним было?" пользователи открывают страничку и видят в режиме реального времени состояния своего любимца.
Кстате в реале отделов полсотни и техники тысячи единиц.
|
|
22.01.2017, 15:04
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Хотите получить ответы, описывайте задачу не абстрактно, а как есть. Правда, если задачей является администрирование, то это не простой вопрос и простой на него ответ. Это скорее работа, и если нет опыта, то лучше заказать таковую.
Из того, что описано вами, то что вы пытаетесь сделать, это пустое никчемное занятие. К примеру, если их 5 принтеров с номерами .... означает равномерное распределение нагрузки, то запрашивать что-то последовательно все равно не требуется. В данном случае сперва надо выбрать в списке Техника, и пока нет в нем выбора, выбор в списке Отдел не разрешается, что обеспечит JS. Выбор в списке Техника автоматически отправляет асинхронный запрос на сервер с параметрам - ID техники. Сервер выбирает, подсчитывая количество записей у каждого раздела для указанного ID техники (по примеру мной приведенному, это WHERE mechanism=ID запроса). Возвращается и отображается список, по которому можно судить кому отдать технику.
Или, к примеру, заказы не просто принимаются, но и ведется база данных заказчиков: ФИО, адрес, телефон. Если заказчик уже был вашим клиентом, то достаточно ввести, к примеру, его номер телефона, если такой будет найден в базе, данные заказчика автоматически будут заполнены в форме. Либо при вводе фамилии/адреса в фоновом режиме происходит опрос базы и предлагаются имеющиеся адреса/фамилии. Это называется атозаполнением и работает в фоновом режиме.
Из представленного вами ранее нет никакой причины что-то выковыривать последовательно, да еще и отображать в каких то отдельных окнах. А последнее говорит о гораздо больших задачах, которые нужно решать. Но если таковые задачи ставятся, то и подход к ним должен быть не такой примитивный, как вы пытаетесь делать.
|
|
|
|