Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 28.09.2015, 20:24
Интересующийся
Отправить личное сообщение для amd3000 Посмотреть профиль Найти все сообщения от amd3000
 
Регистрация: 12.08.2014
Сообщений: 12

Обработка событий в динамической форме
Здравствуйте уважаемые форумчане.

Вобщем пишу для себя небольшой сайтик для бух учёта предпринимателей которых я обслуживаю.
С миру по нитке собрал форму и 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"
        );
    }); 
});
Ответить с цитированием
  #2 (permalink)  
Старый 29.09.2015, 00:15
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Чтобы не возникало проблем с обработкой полей формы, нужно делегировать обработку их событий ближайшему общему родителю. Тогда не важно динамически добавлено ли было поле или уже существовало.
Ответить с цитированием
  #3 (permalink)  
Старый 29.09.2015, 10:56
Интересующийся
Отправить личное сообщение для amd3000 Посмотреть профиль Найти все сообщения от amd3000
 
Регистрация: 12.08.2014
Сообщений: 12

Сообщение от laimas Посмотреть сообщение
Чтобы не возникало проблем с обработкой полей формы, нужно делегировать обработку их событий ближайшему общему родителю. Тогда не важно динамически добавлено ли было поле или уже существовало.
Спасибо за наводочку, но если можна, ткните пожалуйста в пример рабочего кода с сходным функционалом.
Ответить с цитированием
  #4 (permalink)  
Старый 29.09.2015, 13:51
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Ваш код какой-то "грузный", даже лень вникать в него. )
Но суть простая, на jQuery описывается просто. Допустим есть область в форме, в которой нужно обрабатывать поля в нее помещенные и помещаемые динамически. Не важно что это за элемент такой, главное знать его селектор (и что важно, этот элемент гарантировано есть на странице при загрузке ее) и пусть это будет id="dynamic", тогда делегирование ему обработки полей формы описывается так:

$('#dynamic').on('событие или события которые нужно обрабатывать', 'input', function() {
    //код обработчика
})
Ответить с цитированием
  #5 (permalink)  
Старый 29.09.2015, 14:59
Интересующийся
Отправить личное сообщение для amd3000 Посмотреть профиль Найти все сообщения от amd3000
 
Регистрация: 12.08.2014
Сообщений: 12

Сообщение от laimas Посмотреть сообщение
Ваш код какой-то "грузный", даже лень вникать в него. )
Но суть простая, на 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>
Ответить с цитированием
  #6 (permalink)  
Старый 29.09.2015, 15:25
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

<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?
Ответить с цитированием
  #7 (permalink)  
Старый 29.09.2015, 15:33
Интересующийся
Отправить личное сообщение для amd3000 Посмотреть профиль Найти все сообщения от amd3000
 
Регистрация: 12.08.2014
Сообщений: 12

Извините, всё правильно. У меня они все в массиве sel1[ ], sel2[ ] итд.

Чекбокс не подойдёт, опция там не одна, список опций селекта sel2[ ] подгружается через AJAX запрос который находится в функции обработки изменения селекта sel1[ ].
Ответить с цитированием
  #8 (permalink)  
Старый 30.09.2015, 12:13
Интересующийся
Отправить личное сообщение для amd3000 Посмотреть профиль Найти все сообщения от amd3000
 
Регистрация: 12.08.2014
Сообщений: 12

Ну вот и всё, решил свою задачку простым переносом обработчика событий в SELECT,
<select id="expense[0]" name="expense[0]" disabled="disabled" onchange="ChangeExpense([0])">

и всё норм, никакого головняка.

Тему можно закрывать.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Canvas обработка событий ДанилаDeep Events/DOM/Window 6 28.08.2014 16:55
ie и другие браузеры - обработка событий torsar Javascript под браузер 1 24.05.2014 20:29
Обработка событий в нужной очередности. lamer Общие вопросы Javascript 15 29.04.2013 18:40
JQuery отложенная обработка событий hover DemonWather jQuery 2 09.03.2011 09:01
GetElementById не хочет работать в динамической форме Игорёk Events/DOM/Window 8 23.06.2009 13:27