Обработка событий в динамической форме
Здравствуйте уважаемые форумчане.
Вобщем пишу для себя небольшой сайтик для бух учёта предпринимателей которых я обслуживаю. С миру по нитке собрал форму и AJAX обработчик для неё. На даном этапе пишу банковскую выписку, с одной строкой данных <div id="rows"> всё работает нормально, но мне этого мало, нужна динамическая форма с добавлением строк по мере необходимости. Сделал клонировавие строки с поиском и заменой всех элементов в строке с "name[ i ]" на "name[ i++ ]" функции addline() и rename(). Вроде получилось. Но теперь стоит следующая задача: как заставить функции обработки связаных списков select.js это всё хазяйство адекватно обрабатывать? И тут у меня полный штопор, помогите разобратся с кодом JS, у меня с ним всё плохо, очень плохо. Ну и собственно код HTML <fieldset><div id="rows"> <div class="row"><select id="plus[0]" name="plus[0]" disabled="disabled" required style="width:10%"><option disable selected value="">+ или -</option><option value="1">Приход</option><option value="0">Расход</option></select> <select id="expense[0]" name="expense[0]" disabled="disabled" required style="width:20%"> <option disable selected value="">- Выбрать счёт-</option> <?php $result1 = mysql_query("SELECT id,exp_name FROM expenses",$db); $myrow1 = mysql_fetch_assoc($result1); do { ?> <option value="<?php echo $myrow1['id'];?>"><?php echo htmlspecialchars($myrow1['id'].' - '.$myrow1['exp_name'],ENT_QUOTES, 'UTF-8');?></option> <?php } while ($myrow1 = mysql_fetch_assoc($result1)); ?> </select> <select id="sub1[0]" name="sub1[0]" disabled="disabled" required style="width:20%"> <option>- Субконто 1 -</option></select> <select id="sub2[0]" name="sub2[0]" disabled="disabled" required style="width:20%"> <option>- Субконто 2 -</option></select> <input type="text" name="summa[0]" id="suma[0]" placeholder="Сумmа" required style="width:7%"> </div></div> </fieldset> <a href="#" onclick="return start();">Добавить нову строку</a> <button type="submit">Создать</button> </form> JS код добавления новой строки с переименовыванием ]/* Вставлен в файл с формой index.php */ function addline() { var itm = document.getElementById("rows").lastChild; var cln = itm.cloneNode(true); document.getElementById("rows").appendChild(cln); } function rename() { var i; var x = document.getElementsByClassName("row"); for (i = 0; i < x.length; i++) { var d = x[i].innerHTML; var two = d.replace(/\[\d+\]/gi,'['+i+']'); document.getElementsByClassName("row")[i].innerHTML = two; } } function start() { addline(); rename(); } JS код обработчика связанных списков с передачей данный по AJAX /* Файл select.js*/ $(document).ready(function () { /* Эта функция работает с шапкой формы */ $('#employer_id').change(function () { var employer_id = $(this).val(); if (employer_id == '') { $('#bank').html('<option disable>- Выбрать счёт -</option>'); $('#bank').attr('disabled', true); return(false); } $('#bank').attr('disabled', true); $('#bank').html('<option>Загрузка...</option>'); var url = './modules/get.php'; $.get( url, "employer_id=" + employer_id + "&select_type=bank", function (result) { if (result.type == 'error') { alert('error'); return(false); } else { var options = ''; $(result.banks).each(function() { options += '<option value="' + $(this).attr('id') + '">' + $(this).attr('name_bank') + '</option>'; }); $('#bank').html('<option value="0" disable>- Выбрать счёт -</option>'+options); $('#bank').attr('disabled', false); } }, "json" ); }); /* Эта функция работает с шапкой формы */ $('#bank').change(function () { var bank = $(this).val(); if (bank == '') { $('#plus').html('<option disable>- + или - -</option>'); $('#plus').attr('disabled', true); return(false); } else { $('#plus').attr('disabled', false); } }); /* Эта функция должна работать с масивом строк */ $('#plus').change(function () { var plus = $(this).val(); if (plus == '') { $('#expense').html('<option disable>- + или - -</option>'); $('#expense').attr('disabled', true); return(false); } else { $('#expense').attr('disabled', false); } }); /* Эта функция должна работать с масивом строк */ $('#expense').change(function () { var expense = $(this).val(); if (expense == '') { $('#sub1').html('<option disable>- Субконто 1 -</option>'); $('#sub1').attr('disabled', true); return(false); } $('#sub1').attr('disabled', true); $('#sub1').html('<option>Загрузка...</option>'); var url = './modules/get.php'; $.get( url, "expense=" + expense + "&select_type=expense", function (result) { if (result.type == 'error') { alert('error'); return(false); } else { var options = ''; $(result.sub1s).each(function() { options += '<option value="' + $(this).attr('one') + '">' + $(this).attr('two') + '</option>'; }); $('#sub1').html('<option disable>- Субконто 1 -</option>'+options); $('#sub1').attr('disabled', false); } }, "json" ); }); /* Эта функция должна работать с масивом строк */ $('#sub1').change(function () { var sub1 = $(this).val(); var sub1exp = $('#expense :selected').val(); var emp = $('#employer_id :selected').val(); if (sub1 == '') { $('#sub2').html('<option disable>- Субконто 2 -</option>'); $('#sub2').attr('disabled', true); return(false); } $('#sub2').attr('disabled', true); $('#sub2').html('<option>Загрузка...</option>'); var url = './modules/get.php'; $.get( url, "sub1=" + sub1 + "&select_type=sub1&sub1exp=" + sub1exp + "&emp=" + emp, function (result) { if (result.type == 'error') { alert('error'); return(false); } else { var options = ''; $(result.sub2s).each(function() { options += '<option value="' + $(this).attr('one') + '">' + $(this).attr('two') + '</option>'; }); $('#sub2').html('<option disable>- Субконто 2 -</option>'+options); $('#sub2').attr('disabled', false); } }, "json" ); }); }); |
Чтобы не возникало проблем с обработкой полей формы, нужно делегировать обработку их событий ближайшему общему родителю. Тогда не важно динамически добавлено ли было поле или уже существовало.
|
Цитата:
|
Ваш код какой-то "грузный", даже лень вникать в него. )
Но суть простая, на jQuery описывается просто. Допустим есть область в форме, в которой нужно обрабатывать поля в нее помещенные и помещаемые динамически. Не важно что это за элемент такой, главное знать его селектор (и что важно, этот элемент гарантировано есть на странице при загрузке ее) и пусть это будет id="dynamic", тогда делегирование ему обработки полей формы описывается так: $('#dynamic').on('событие или события которые нужно обрабатывать', 'input', function() { //код обработчика }) |
Цитата:
Например, если можно, подскажите как можно снимать атрибут disabled у связаных селектов в определённом обьекте div id="row", независимо от соседних обьектов <form> <select id="on" name="on"><option>- on -</option></select> <!-- После изменения селекта с id="on" нужно снять атрибут disabled с всех селектов с id="sel1" --> <div id="rows"name="rows"> <!-- div id="row" Динамически клонируется по мере необходимиости --> <div id="row" name="row"> <!-- Эти селекты связаные списки --> <!-- После изменения селекта с id="sel1" нужно снять атрибут disabled с селекта с id="sel2" и так далее по цепочке" --> <select id="sel1" name="sel1" disabled="disabled"><option>- 1 -</option></select> <select id="sel2" name="sel2" disabled="disabled"><option>- 2 -</option></select> <select id="sel3" name="sel3" disabled="disabled"><option>- 3 -</option></select> <select id="sel4" name="sel4" disabled="disabled"><option>- 4 -</option></select> </div> <!-- Этот div создан динамически --> <div id="row" name="row"> <!-- Эти селекты связаные списки --> <select id="sel1" name="sel1" disabled="disabled"><option>- 1 -</option></select> <select id="sel2" name="sel2" disabled="disabled"><option>- 2 -</option></select> <select id="sel3" name="sel3" disabled="disabled"><option>- 3 -</option></select> <select id="sel4" name="sel4" disabled="disabled"><option>- 4 -</option></select> </div> <!-- Этот div создан динамически --> <div id="row" name="row"> <!-- Эти селекты связаные списки --> <select id="sel1" name="sel1" disabled="disabled"><option>- 1 -</option></select> <select id="sel2" name="sel2" disabled="disabled"><option>- 2 -</option></select> <select id="sel3" name="sel3" disabled="disabled"><option>- 3 -</option></select> <select id="sel4" name="sel4" disabled="disabled"><option>- 4 -</option></select> </div> </div> </form> |
<select id="sel1" name="sel1" disabled="disabled"><option>- 1 -</option></select>
далее опять <select id="sel1" name="sel1" disabled="disabled"><option>- 1 -</option></select> и далее тоже самое, как и с именами других списков. Если так именовать поля формы, то на сервере вы получите значения последних списков с именами "sel1", "sel2", .... Если задавать так имена, то они должны принадлежать массиву, то есть не name="sel1", а name="sel1[]". Чтобы изменить режим доступа у следующего списка, нужно в обработчике этой операции снимать у следующего. Так как у вас они следуют друг за другом, то снять у следующего это: $(this).next().prop('disabled', 0); где this - это текущий список, событие которого обрабатывается в каком-то Х-обработчике вашей формы. Но чтобы такое проделать последовательно со всеми, первый должен быть по умолчанию доступен, а у вас нет, если только некий обработчик не устанавливает ему таковое состояние. Кстати, если ваши списки имеют по одной опции, то может лучше checkbox? |
Извините, всё правильно. У меня они все в массиве sel1[ ], sel2[ ] итд.
Чекбокс не подойдёт, опция там не одна, список опций селекта sel2[ ] подгружается через AJAX запрос который находится в функции обработки изменения селекта sel1[ ]. |
Ну вот и всё, решил свою задачку простым переносом обработчика событий в SELECT,
<select id="expense[0]" name="expense[0]" disabled="disabled" onchange="ChangeExpense([0])"> и всё норм, никакого головняка. Тему можно закрывать. |
Часовой пояс GMT +3, время: 08:00. |