Обработка событий в динамической форме
Здравствуйте уважаемые форумчане.
Вобщем пишу для себя небольшой сайтик для бух учёта предпринимателей которых я обслуживаю. С миру по нитке собрал форму и 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, время: 21:46. |