Список с многоуровневой зависимостью
Вложений: 1
Я не программист, я по железу.
Но прижало и возникла необходимость создать для поступающей на ремонт техники создать небольшую бд. Для регистрации техники выбираем из динамических списков сначало отдел, далее с помощью javascript для второго окна формируется список категории техники отфильтрованный в запросе во выбранному ранее отделу, список для третьего окна должен фильтроваться как по выбранной категории, так и по выбранному отделу, но вот как получить значение выбраного отдела ума не приложу. Чтобы закончить свой проект, осталось решить только эту задачу, но времени в связи с загруженностью на изучение теории нет. Данные задачи приложил. Данные в бд для простоты урезал. |
Ничего не напутано в представлении данных?
|
Ткни носом на сомнительное место
|
Здесь не место, а подход к представлению данных. Откуда тут могут взяться многоуровневые списки, если набор 'Контрольный', 'Планировочный', 'Сдаточный', 'Приёмочный' характеризует видимо этапы ремонта, а набор 'ИБП', 'Монитор', 'Принтер', 'Системник', 'Сканер', это категория техники принятой на ремонт, и оба этих набора есть разные сущности?
Первый набор вообще не обязательно помещать в отдельную таблицу, как и нет необходимости помещать второй набор в отдельную таблицу. Оба этих набора могут быть полями ENUM одной единственной таблицы. Принимается техника на ремонт, выбирается ее категория, а также отдел куда она попадает, и все это пишется в одну таблицу. Выбор же того что имеется в базе, это может быть выбор всех записей как по одному из этих наборов, так и по обоим, что задается в условии выборки. Результат такой выборки, это таблица, в которой можно по ID записи выбрать любую их них как для редактирования, например перемещения из отдела в отдел, так и для удаления из базы. |
Приемочный, сдаточный, контрольный и т.д. это гипотетические отделы. Писать реальные отделы посчитал не желательным. Извеняюсь что ввёл в заблуждение своей фантазией :write:
Код формы: [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 произвольной вложенности, где в начале статьи приводится: Цитата:
[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] |
Не майтесь хренью, а ответьте себе на вопрос - что должна содержать база? Если записи когда, от кого, какая техника поступила на ремонт, и ее сопровождение по циклу ремонта, то зачем все это, что только усложняет все, и пользы никакой нет?
Какая к черту разница гипотетические ли названия или реальные. Нет в принципе вообще многоуровневых списков в контексте select, есть связанные списки. Но связанные списки потребуются только тогда, когда в наличие есть дерево, той же категории техники. У вас этого нет, и все что вы пишите, это бесполезная трата ресурсов сервера и клиента. |
я не программист, языков не знаю, а беру готовые примеры и подставляю свои данные.
В бд есть три таблицы. 1. Содержит перечень отделов 2. Содержит перечень категорий техники 3. Содержит номера техники, id отдела, к которому принадлежит, id категории техники к которой относится Чтобы не производить ручной ввод данных первый список даёт возможность сузить возможные номера техники выбранным отделом, к которому эта техника пренадлежит, второй список всю технику выбранного отдела сортирует по категориям, например все принтеры бухгалтерии, в котором их 5 с номерами 107, 104, 108, 207, 301. Во первых я исключаю этим опечатку во время заполнения акта приёма, во вторых контролирую принадлежность техники данному отделу. Бывало что принтер одного отдела долгие месяцы использовал второй отдел, а так как при использовании 200 принтеров одной марки сами пользователи могли и не заметить подмены. Во вторых, пользователи могли бы следить за судьбой своего принтера через запросы в бд. Как вы решение этих проблем предложите сделать проще? пс: Реализовать это через перезагрузку форм проблемы нет. Но как это сделать с помощью одной формы и динамических списков? |
Во вложении есть дамп базы. В нем простой список отделов, а также простой список техники. Оба списка не являются деревьями, то есть не имеют зависимостей. В третье таблице не понятно что к чему, какие-то номера....
Предположим, что принимается на ремонт техника, для простоты: Принтеры, Компьютеры, Сканеры. Техника может распределяться между тремя отделами: Первый, Второй, Третий. Пусть эти списки постоянны и не изменяются, что в общем не так важно, к примеру если перечень техники может изменяться, то тогда его держать как отдельную таблицу. Достаточно для хранения такой записи иметь единственную таблицу заказов (туман, что есть 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, то заполнять ничего не требуется, кроме указания какого-то номера (?). При этом делать какие либо запросы не понятно за какими списками не требуется. Вывод содержимого этой таблицы можно производить по любому из параметров - фильтр. Это могут быть списки только по отделу со всей его техникой, либо по конкретной технике, по дате поступления и т.д., и т.п. То есть по известным полям формы задаются параметры запроса: выбор в списках, задание условия, например равно дате, либо больше даты и прочее. Чтобы построить базу данных, нужно понимать задачу решаемую. Для примера описанного выше этой таблицы вполне хватит. И из вашего представления не видно того, чтобы требовалась какая-то последовательная выборка не понятно чего и зачем. А из описанного вообще не понять деталей. |
Безусловно ваши советы при разработке хранения и использования данных мне пригодятся, за что вам выражают благодарность.
Но я всего лишь хотел узнать как в Javascript получить из формы значения двух полей и передать их для обработки запроса, видимо пока это останется непознаным. Под отделами в базе я имел ввиду не отделы по ремонту техники, а отделы, которые участвуют в их "истреблении" и которые их на ремонт и отправляют. То что кажется в бд излишним для вас, для меня на практике экономит время и нервы, так как "оптимизация" затрат на производстве привела к тому что работы стало так много и такой разнообразной что приходится и принимать на ремонт и ремонтировать и подключать и настраивать, учить пользоваться, обеспечивать связь, консультировать и отчитываться в лице одного. Поэтому, чтобы избавить себя от бесконечных звонков "как там мой принтер с цветочком на лотке? когда будет готов? Что с ним было?" пользователи открывают страничку и видят в режиме реального времени состояния своего любимца. Кстате в реале отделов полсотни и техники тысячи единиц. |
Хотите получить ответы, описывайте задачу не абстрактно, а как есть. Правда, если задачей является администрирование, то это не простой вопрос и простой на него ответ. Это скорее работа, и если нет опыта, то лучше заказать таковую.
Из того, что описано вами, то что вы пытаетесь сделать, это пустое никчемное занятие. К примеру, если их 5 принтеров с номерами .... означает равномерное распределение нагрузки, то запрашивать что-то последовательно все равно не требуется. В данном случае сперва надо выбрать в списке Техника, и пока нет в нем выбора, выбор в списке Отдел не разрешается, что обеспечит JS. Выбор в списке Техника автоматически отправляет асинхронный запрос на сервер с параметрам - ID техники. Сервер выбирает, подсчитывая количество записей у каждого раздела для указанного ID техники (по примеру мной приведенному, это WHERE mechanism=ID запроса). Возвращается и отображается список, по которому можно судить кому отдать технику. Или, к примеру, заказы не просто принимаются, но и ведется база данных заказчиков: ФИО, адрес, телефон. Если заказчик уже был вашим клиентом, то достаточно ввести, к примеру, его номер телефона, если такой будет найден в базе, данные заказчика автоматически будут заполнены в форме. Либо при вводе фамилии/адреса в фоновом режиме происходит опрос базы и предлагаются имеющиеся адреса/фамилии. Это называется атозаполнением и работает в фоновом режиме. Из представленного вами ранее нет никакой причины что-то выковыривать последовательно, да еще и отображать в каких то отдельных окнах. А последнее говорит о гораздо больших задачах, которые нужно решать. Но если таковые задачи ставятся, то и подход к ним должен быть не такой примитивный, как вы пытаетесь делать. |
Извините меня конечно, но видимо на свой конкретный вопрос как передать значение, кроме критики о вреде абстрактно-примитивного взгляда на построения кода в мире программирования я ничего не получу. Буду абстрагироваться в своём примитивном мире железа самостоятельно, хотя надеялся что кто-нибудь протянет хоть ножку помощи, а получил кирпич критики :)
Не принимайте мои слова на свой личный счёт, как сожалению это явление повсеместное и в профессиональной среде встречается чаще чем где-либо. |
Цитата:
Цитата:
Тут только два варианта: либо вы не можете описать подобающе задачи свои, а их всегда решают от общего к частному, либо вы представляете задачи, но описываете данные для них в очень неудобной структуре, что рано или поздно еще скажется. |
Цитата:
|
$('form').submit(function(e) { e.preventDefault(); $.get(this.action, $(this).serialize(), function(data) { //ответ сервера }) }) |
О, буду жевать ваш код, сразу мне не понятно что к чему, огромное спасибо!
Кстате, озарило вчера, можно создать табличку для хранения оперативных данных, заносить туда значение полей, пользоваться ими в процессе заполнения формы а при отправки данных с формы в бд табличку чистить DELETE FROM. |
Цитата:
Что такое оперативные данные, зачем их хранить в таблице, секрет для всех. Ну если надо, на здоровье. |
Оперативные данные в моём понятие это переменные в рамках, в моём случае, заполнения формы.
Когда получаю значение первого поля, вставляю в таблицу temp бд, также значение второго и т.д. по необходимости. После того как данные с помощью формы сохраняю в бд очищаю таблицу temp (ну чтобы база не забивалась). |
Как и с получением чего-то по спискам, не понятно для чего, так и с какими то переменными, которые нужно хранить, тоже ничего не понятно.
Есть, к примеру, последовательный прием данных от клиента, например, заполнили форму каким либо выбором, отправили серверу, сервер это сохранил, и для этого может и сессии хватит. Далее клиенту отдается следующая форма, где нужно заполнить свои данные. Отправление этих данных есть сигнал серверу сохранить ранее запомненное и вновь полученное. Такое делается если большой набор данных, и чтобы облегчить навигацию по ним, заполнение формы разбивают на этапы, при этом всегда можно вернуться назад по этапам. Существует также понятие как кеширование, которое к контексте "запросить сервер" есть клиентское понятие. Чего вы там пытаетесь хранить, да еще в контексте ранее описанного, даже представить трудно. Ну коли надо, никто не запрещает, но и возможно вы опять делаете лишние никчемные операции. |
Цитата:
|
Цитата:
Я сужу только по тому, что вижу. Если говорить по первому, то не видно смысла в действиях вами предпринимаемых, ибо у вас простые зависимости, а не дерево, и получить их можно сразу, одним запросом к базе. Что было мной и высказано. Цитата:
|
Дак я же не с претензий тему начал, да и в ходе беседы её не выражал, а лишь искал помощи. Просто выразил мнение об вашем отношении к моей проблеме. Вы слишком требовательны к нубам. Вопрошающий, который вас может удовлетворить своим вопросом должен предварительно хорошо подготовиться.
Про свои комплексы слышу впервые, поинтересуюсь у знакомых, может что и скрывают от меня :) Извеняюсь за оффтоп. Кстате да, "последнее слово за мной" - страдаю :) |
Цитата:
Вот каков бы был ваш ответ на такой мой пост: "сегодня меня посетила мысль, а что если то, что у меня есть я умножу на два и отниму половину, это будет нормально"? Скорее всего - "а хрен его знает, может и нормально, а может от жиру бесимся". Чтобы и овцы были целы, и волки сыты, на ваше озарение тогда надо было бы ответить - "мы прочили и порадовались за вас". Или чего вы ожидали? Если вы разобрались "что к чему" в запросе клиента к серверу, то должны понять, что код передает все элементы формы серверу, коими у вас по коду являются только списки. А это означает, что всегда будут передаваться все списки не зависимо от того был ли в них выбор. Попутно можно заметить, что у опций по умолчанию (Выберите категорию и т.п.) значение лучше определять ни как 0, а как пустое, так как в этом случае проще проверить был ли выбор в списке. Но не это суть. Пусть в списках был выбор, если на сервере удалить из набора данных списки с не выбранными опциями, то сервер будет запрашивать только то, что будут в наборе. Это означает, что не важно как будут передаваться данные формы, все ли сразу, или же при каждом изменении списка, катастрофы не произойдет, так как запросы данных определяются ключами запроса слева направо. А из этого следует, что можно установить нужный набор этих ключей (выбрав опции), сделать единственный запрос, а ответ, если уж так надо распихать на клиенте куда и как душа пожелает. С деревом данных так не получится, ибо это будет крайне неудобно для навигацию пользователю по всему сразу. Сразу все, ну это чтобы отобразить ветви дерева, то же меню к примеру, а получить конкретное, это постепенно от корня к вершине. Запросы к SQL, это всегда есть "больное место" веб приложения, их оптимизируют, их не используют когда в этом нет причины. Нуб, не нуб, это не мне разбираться, но уж коли взялись писать, ну так надо как минимум понимать, что база, это не обязательно единственный ящик для всего что угодно, данные можно хранить и вне базы. Поэтому ответ на "многие Х в вопросе" может быть таким каким я его и пишу. А уж вам думать, что есть из этого золотое сечение, что оправдано, а что нет. |
На одном из форумов получил прямой ответ на вопрос, для тех кто ищет подобное решение:
$('#sp_category_tech').change(function () { var sp_category_tech = $(this).val(); var sp_otdel = $('#sp_otdel').val(); if (sp_otdel == '0') { ... $.get( url, "sp_category_tech=" + sp_category_tech + "&sp_otdel=" + sp_otdel, Спасибо всем! |
Цитата:
$('form').on('change', 'select', function() { var f = $(this).closest('form'); $get(f.attr('action'), f.serialize(), ... }) Сервер: if($get = array_diff(array_map('intval', $_GET), [0])) { //... } |
Часовой пояс GMT +3, время: 06:04. |