Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Подключение js к динамически созданным input (https://javascript.ru/forum/events/64850-podklyuchenie-js-k-dinamicheski-sozdannym-input.html)

Albionix 09.09.2016 10:50

Подключение js к динамически созданным input
 
Здравствуйте...Прошу помощи в решении следующей проблемы:

Есть страничка с полями ввода город, улица, дом Сделана кнопка добвления полей, например адрес 2, 3, ....

<script>
	$(function() {
		$("#add").click(function () {
		$("<div class='param'><div class='box'><input type='text' name='city' placeholder='Город'></div><div class='box'> <input type='text' name='street' placeholder='Улица'></div> <div class='box'><input type='text' name='building' placeholder='Дом'> </div><div class='box last-child'><input type='text' name='pod' placeholder='Подъезд'></div><div class='box'></div></div><div class='spacer'><br></div>" ).insertBefore("#form_status_added"); 
		})
	 });
	</script>


При создании страницы подключаются скрипты и css "Кладр в облаке" и jquery

<link href="jquery.kladr.min.css" rel="stylesheet">
script src="js/lib/jquery-1.11.1.min.js" type="text/javascript"></script>
<script src="jquery.kladr.min.js" type="text/javascript"></script>
<script src="js/form_with_map.js" type="text/javascript"></script>
<link href="css/form_with_map.css" rel="stylesheet">


У элементов размещенных в коде до этого статически
<div class="param" >
				<div class="box">
					<input type="text" name="city" placeholder="Город">
				</div>
				<div class="box">
					<input type="text" name="street" placeholder="Улица">
				</div>
				<div class="box">
					<input type="text" name="building" placeholder="Дом" >
				</div>
				<div class="box last-child">
					<input type="text" name="pod" placeholder="Подъезд" >
				</div>
			</div>

все работает нормально, автозаполнение срабатывает. А вот у добавленных скриптом нет. Вопрос как подключить его к динамически созданным формам.

На всякий случай ссылку привожу на ГитХаб (https://github.com/garakh/kladrapi-jsclient), там описание проекта и примеры есть, но как их использовать не знаю, недавно начал ...Заранее спасибо!

laimas 09.09.2016 14:52

.insertBefore("#form_status_added").find('input').trigger('событие');

Albionix 09.09.2016 16:27

Цитата:

Сообщение от laimas (Сообщение 428146)
.insertBefore("#form_status_added").find('input').trigger('событие');

Если ен трудно, попрошу пояснить код ) И с примером, что в событии писать?

laimas 09.09.2016 16:46

Я думал в курсе.

Найдите в коде установку обработчиков запросов к КЛАДР на имеющиеся на странице поля ввода. Пусть это будет keyup, тогда ваш код должен быть такой:

$("<div class='param'><div class='box'><input type='text' name='city' placeholder='Город'></div><div class='box'> <input type='text' name='street' placeholder='Улица'></div> <div class='box'><input type='text' name='building' placeholder='Дом'> </div><div class='box last-child'><input type='text' name='pod' placeholder='Подъезд'></div><div class='box'></div></div><div class='spacer'><br></div>" ).insertBefore("#form_status_added").find('input').trigger('keyup');


Метод trigger запускает ранее установленный обработчик. Но я и элементы указал произвольно - find('input'), то есть все вставляемые поля, а это может быть не так, поэтому в качестве селектора здесь нужно не 'input', а только те, которые требуется. В курсе как это делать?

Albionix 09.09.2016 17:53

Цитата:

Сообщение от laimas (Сообщение 428169)
Я думал в курсе.

Найдите в коде установку обработчиков запросов к КЛАДР на имеющиеся на странице поля ввода. Пусть это будет keyup, тогда ваш код должен быть такой:

$("<div class='param'><div class='box'><input type='text' name='city' placeholder='Город'></div><div class='box'> <input type='text' name='street' placeholder='Улица'></div> <div class='box'><input type='text' name='building' placeholder='Дом'> </div><div class='box last-child'><input type='text' name='pod' placeholder='Подъезд'></div><div class='box'></div></div><div class='spacer'><br></div>" ).insertBefore("#form_status_added").find('input').trigger('keyup');


Метод trigger запускает ранее установленный обработчик. Но я и элементы указал произвольно - find('input'), то есть все вставляемые поля, а это может быть не так, поэтому в качестве селектора здесь нужно не 'input', а только те, которые требуется. В курсе как это делать?

Да, спасибо. Теперь понятно. Скажите а будет ли проблемой то, что поля создаются с оинаковыми name и без id?

Albionix 09.09.2016 18:02

Из первого вытекает второе: вставляю по клику на radio город в нужный адрес. То есть если 3 адреса:

<div class="korpus">
				<input name="city_id" type="radio" id="vkl12" value="6600001500000"><label id="2" for="vkl12">Новоуральск</label>
				<input name="city_id" type="radio" id="vkl22" value="6600002300000"><label id="2" for="vkl22"> Н. Тагил</label>
				<input name="city_id" type="radio" id="vkl32" value="6600000100000"><label id="2" for="vkl32"> Екатеринбург</label>
			
			</div>
				<div class="box">
					<input type="text" name="city2" id="c2" placeholder="Город">
					<script>$('[name="city2"]').kladr({type: $.kladr.type.city});</script>
				</div>

У каждого последующего в имени и id номер больше на 1...

Код такой:
<script>$('label').click(function () {
	var $city = $('[name="city'+this.id+'"]');

	$city.kladr({
		type: $.kladr.type.city
	});

	$('[name="city_id"]').change(function () {
		var id = $(this).val();

		// Устанавливаем значение поля ввода по id
		$city.kladr('controller').setValueById(id);
	});
})</script>;


Поведение такое: нажимаем на радио1 заполняется например екатеринбург в адресе 1, нажимаем радио 2 в 1 и 2 адресе заполняется например новоуральск, нажимаем на радио 3 - например тагил, все три адреса становятся тагил. заием по клику на любой радио меняются все три поля. Если после загрузки страницы начать не с первого адреса а со второго. то есть 2. затем 3, то одновременно меняются только 2 и 3 , а 1 остается пустым пока не нажмешь на радио 1. Прошу прощения если сумбурно объяснил.

laimas 09.09.2016 18:16

будет ли проблемой то, что поля создаются с оинаковыми name

Если поля добавляются в форму, которая затем будут отправлена на сервер, то да, проблемой будет прием данных - сервер получит значения не всех полей city, street и т.д., а только значения этих последних полей.
Чтобы получить значения всех полей именовать их нужно как элементы вложенного массива: city[], street[] и т.д. В этом случае на сервере будут получены массивы city => [значение поля 1, значение поля 2, и т.д.]. Аналогично и других полей.

ID, если они только нужны, должны быть различны.

laimas 09.09.2016 18:22

Цитата:

Сообщение от Albionix
Поведение такое: нажимаем на радио1 заполняется например екатеринбург в адресе 1, нажимаем радио 2 в 1 и 2 адресе заполняется например новоуральск, нажимаем на радио 3 - например тагил, все три адреса становятся тагил. заием по клику на любой радио меняются все три поля. Если после загрузки страницы начать не с первого адреса а со второго. то есть 2. затем 3, то одновременно меняются только 2 и 3 , а 1 остается пустым пока не нажмешь на радио 1. Прошу прощения если сумбурно объяснил.


Ничего не понял.

label id="2" - id должен быть уникален. И вообще не увлекайтесь ими, если они не нужны, не используйте их вообще, этот атрибут не обязателен у тега.

Albionix 09.09.2016 22:37

Попробую объяснить... Представьте есть три поля ввода над каждым из них по 3 кнопки с названиями городов. Екатеринбург нижний Тагил и Новоуральск. 3 кнопки и поле ввода лежат в диве. При нажатии на одну из них, в соответствующем инпуте должно появиться название города (это я упрощаю...там не название). Так вот нажимаем на кнопку в первом блоке...выполняется код приведенный выше онклик. Значение заполняется в первом инпуте. Нажимаем на кнопку 2 блока. И вот тут заполняются выбранным значением второй и первый инпуты. Соответственно если затем нажать на кнопку 3 блока то выбранным значением заполнятся все 3 поля ввода. А мне бы чтобы они независимотработали. Вариант с .one. Не помог. Надеюсь на Вашу помощь. Заранее спасибо

laimas 10.09.2016 04:13

Цитата:

Сообщение от Albionix
Представьте есть три поля ввода над каждым из них по 3 кнопки с названиями городов.

Представил, но... Такие же кнопки добавляются и полям, добавляемым в форму динамически, кодом ранее показанном?

Albionix 10.09.2016 12:15

Да кодом выше. Только такое поведение наблюдается у прописанных заранее элемнгтов. У созданных кнопки вообще не работают

laimas 10.09.2016 13:43

Если структура кода кнопок и поля ими обслуживающего такова:

<div class="korpus">
    <label><input name="city_id" type="radio" value="6600001500000"> Новоуральск</label>
    <label><input name="city_id" type="radio" value="6600002300000"> Н. Тагил</label>
    <label><input name="city_id" type="radio" value="6600000100000"> Екатеринбург</label>
</div>
<div class="box">
    <input type="text" name="city[]" placeholder="Город">
</div>


то код обработчика (собственно как и все обработчики иные) лучше сделать через делегирование. В примере для этих кнопок делегируется BODY, но если все динамически вставляемые элементы имеют общего ближайшего родителя присутствующего в документе, например форма, то лучше ему:

$('body').on('change', 'div.korpus input', function() {
        $(this).closest('.korpus').next().find('input').val(this.value)
     });


В этом случае добавляемые динамически элементы будут обрабатываться. Единственно что не понятно вот с этим:

<script>$('[name="city2"]').kladr({type: $.kladr.type.city});</script>

Это также вставляется в документ динамически? А нужно после добавления div.box найти в нем input и подключить kladr:

(вставляемый код).appendTo(selector).find('input').kladr({type: $.kladr.type.city});


Я удалил id у меток, кнопок и поля, вполне можно обойтись и без них. У добавляемых радио кнопок (группы из трех) имена должны отличать от имен других групп.
Поле ввода именовано так как я писал ранее. Как могут у сервера не закипеть мозги, если ему прислать ключи city1, city2, city3, ... cityN? Это же просто очень не удобно для обработки.

Albionix 10.09.2016 20:20

Огромное спасибо за помощь, все в принципе заработало. Единственно, еще 2 диллетантских вопроса напоследок. У меня функции обработки клика по полю завязаны на id label'a как быть в случае city_id[] b city[]....

и второе как в скрипт добавления вставить еще скрипт...?? Из-за закрывающего тега скрипт не работает ( пробовал разбивать на ск+рипт все равно ен взлетает (

laimas 11.09.2016 05:53

Цитата:

Сообщение от Albionix
все в принципе заработало

Если заработало, это хорошо, хотя у меня после показа кода о кнопках есть чувство, что я не правильно представлял задачу и советовал не то. Ну да ладно.

Цитата:

Сообщение от Albionix
У меня функции обработки клика по полю завязаны на id label'a как быть в случае city_id[] b city[]....

Связать метку с полем можно не обязательно по id посредством for, можно и обернуть меткой связанный с ней элемент, как я и сделал. Если по каким-то причинам удобен обработчик не по полю, а именно по метке, то обратиться к полю в обработчике, это сослаться на ее дочерний элемент. Если элемент обернут меткой так:

<label><input name="a" /></label>

то есть первым дочерним элементом label будет обязательно поле ввода, то это так:

$('label').click(function() {
    //для примера получили имя поля           
    console.log(this.childNodes[0].name)
})


Если же <label>текст к полю <input /></label>, то средствами JS нужно получить не текстовый узел. Но в среде JQ это описать легко. В общем в данном случае большой надобности применения id тоже нет. Тем более, что в представленном ранее коде что-то не видно, чтобы <input type="text" name="city2" placeholder="Город"> был обернут в метку. Код обращение к нему из обработчика щелчков по радио кнопкам без всяких id я показал. Не зная о каких еще метках речь и причем тут имя поля, я ничего не могу сказать.

Именно потому, что динамическое добавление полей, я бы сразу отказался от id - следить за этим, усложнять код связями, это не выгодно. Также не выгодно именовать поля как city1, city2, ... На сервере придется работать либо с каждым из полей (ключом) индивидуально, при этом зная размерность массива, либо отбрасывать ключи, получать значения, связывать их так, чтобы не допустить ошибки. Это еще более не выгодно, чем чехарда на клиенте, ибо индивидуальность будет предполагать и отдельную запись в базу каждого поля, а этого крайне не желательно делать.

Было предположение, что запросы к КЛАДР для того, чтобы получить адресные данные и пополнить ими свою базу. Но радио кнопки "Новоуральск", "Н. Тагил", "Екатеринбург" никак не вяжутся с таким предположением. Во первых странностью, во-вторых сохранением идентификаторов типа 6600000100000. КЛАДР, это DBF база, идентификаторы ее есть строки, а связь записей определяется частью этой строки. Если нужно просто "сграбить" себе, то лучше связать у себя в базе ключами используемой базы данных, а не DBF ключами.

Но если решается какая-то иная задача и требуется сохранять city_id как связанное со своим полем sity, то нужно опять таки использовать не id приклеенное к имени поля, а связать именование этих полей под одним ключом или индексом. Можно поступить так - связывать по ключу равному меткам текущего времени (исходим из того, что id это морока и следить за ними не хотим). При этом имеющиеся поля получают метку времени от сервера равную time() (в случае РНР). В примере это первая группа полей формы. А при добавлении полей они будут получать метку клиента, как new Date().getTime(). В примере вторая группа полей. Именование полей в итоге будет таким:

<label><input name="addr[1473561296][id]" type="radio" value="6600001500000"> Новоуральск</label>
<label><input name="addr[1473561296][id]" type="radio" value="6600002300000"> Н. Тагил</label>
<label><input name="addr[1473561296][id]" type="radio" value="6600000100000"> Екатеринбург</label>
<input type="text" name="addr[1473561296][city]" placeholder="Город">
<input type="text" name="addr[1473561296][street]" placeholder="Улица">

<label><input name="addr[1473561207070][id]" type="radio" value="7600001500000"> Город 1</label>
<label><input name="addr[1473561207070][id]" type="radio" value="7600002300000"> Город 2</label>
<label><input name="addr[1473561207070][id]" type="radio" value="7600000100000"> Город 3</label>
<input type="text" name="addr[1473561207070][city]" placeholder="Город">
<input type="text" name="addr[1473561207070][street]" placeholder="Улица">


Если отправить форму на сервер, то сервер получить связанные по меткам времени данные под ключом addr. Получив содержимое этого массива получим:

Код:

Array
(
    [1473561296] => Array
        (
            [id] => 6600001500000
            [city] => aaaa
            [street] => bbbb
        )

    [1473561207070] => Array
        (
            [id] => 7600002300000
            [city] => cccc
            [street] => dddd
        )

)

При дальнейшей обработке этого массива ключи заданные метками времени нас совсем не интересуют. Главное - это каждый вложенный массив описывает все данные каждого индивидуального объекта. Обработка же этого массива будет очень проста как для формирование запроса многострочной записи в базу, так и для получения отдельных компонент, если это требуется.

С ключами же sity_id1, sity_id2, ..., sity1, sity2, ..., так "бескровно" работать с массивом уже не получится.

Цитата:

Сообщение от Albionix
как в скрипт добавления вставить еще скрипт

Какой скрипт и зачем?

warren buffet 11.09.2016 06:41

Цитата:

Сообщение от Albionix
ак в скрипт добавления вставить еще скрипт...?


laimas 11.09.2016 07:02

warren buffet,
ты так любишь слово "говнокод", скорее потому, что сам состоишь из первого слагаемого этого слова. И тому есть доказательства:

это первое - http://javascript.ru/forum/misc/6450...tml#post425654

это второе упоминание этой ахинени выдаваемой тобой за гениальность - http://javascript.ru/forum/misc/6467...tml#post427063

Только за то, что ты опустил понятие Array ниже плинтуса, тебя убить и то мало. А ты тут еще рассуждаешь о качестве кода. Кодер хренов, тупой как валенок. И приклей эту тупую картинку себе на лоб.

warren buffet 11.09.2016 07:05

Цитата:

Сообщение от laimas
приклей эту тупую картинку себе на лоб.

Тогда я не смогу ее прочесть. А ты сможешь. Что и требовалось доказать.

warren buffet 11.09.2016 07:06

Цитата:

Сообщение от laimas
форма обратной связи

Сейчас все еще проблема нарисовать форму для фидбэка?

laimas 11.09.2016 07:08

Цитата:

Сообщение от warren buffet
Сейчас все еще проблема нарисовать форму для фидбэка?

Ты дебил конченный, ты даже не понимаешь, что пишешь бред, что с тобой придурком разговаривать? Нахрен ты мне нужен.

warren buffet 11.09.2016 07:59

Цитата:

Сообщение от laimas
Ты дебил конченный, ты даже не понимаешь, что пишешь бред, что с тобой придурком разговаривать? Нахрен ты мне нужен.

Это не ко мне. Ты ТСу попробуй объяснить, что выводить хтмл надо из базы, а не рисовать вручную. Тогда он сам все поймет, когда увидит, что часть данных потерялась, задумается куда ж ее воткнуть и воткнет.

laimas 11.09.2016 08:29

Цитата:

Сообщение от warren buffet
выводить хтмл надо из базы

Идиот, что еще с тобой говорить.

warren buffet 11.09.2016 09:07

Ну выводи из своего костного мозга, лал.

Albionix 11.09.2016 14:59

Не ссорьтесь, уважаемые знатоки )
Суть задачи такова, есть страницица в ней две части - блок адресов и карта гугл. Изначально в блоке адресов 2 адреса начальный и конечный - каждый адрес состоит из 4 полей - город улица дом и подъезд. Пользователь может добавить промежуточный адрес и при добавлении маркер должен будет попасть в карту гугл.
вот и все. Сначала для подбора адресов хотел использовать подсказки гугл мэпс. Но там ввод адреса одной строкой, без разбивки по полям. Поэтому решил использовать сервис "Кладр в облаке". Сами адреса локально в базе не хранятся. Большинство адресов будет из трех городов: Екатеринбург, Нижний тагил и Новоуральск. Вот поэтому их вынес в радио над полями ввода. Еще был вариант не с динамическим добавлением а с показом полей которые были скрыты при создании страницы)))

laimas 11.09.2016 15:32

Цитата:

Сообщение от Albionix
Сами адреса локально в базе не хранятся.

Если адреса не для хранения в базе и поля ввода служат только для набора на клиенте, то имена им вообще не нужны.

Albionix 11.09.2016 17:12

Цитата:

Сообщение от laimas (Сообщение 428419)
Если адреса не для хранения в базе и поля ввода служат только для набора на клиенте, то имена им вообще не нужны.

Имя необходимо для сервиса кладр в облаке их скрипты возвращают значение в поле с именем сити_ид....

laimas 11.09.2016 17:38

Цитата:

Сообщение от Albionix
Имя необходимо для сервиса кладр в облаке их скрипты возвращают значение в поле с именем сити_ид

Ну это не означает, что это нужно полю ввода. Без имени поле формы не будет отправляться формой. Если форма не отправляется, то и полей не надо. Было дело приходилось использовать это API, всего не помню, надо освежить память, но чтобы оно требовало именования полей sity_id да еще с нумерацией, вот это более чем сомнительно.

warren buffet 13.09.2016 04:26

Цитата:

Сообщение от Albionix
Не ссорьтесь, уважаемые знатоки )


laimas не знаток, он тупой и боль в моя дырка задница, никак не могу его перевоспитать, я ведь его люблю по-христиански )))

У тебя каноничная задача построения иерархии путем последовательного выбора пунктов. Как в файловой системе ты открываешь папку, видишь там другие папки, открываешь папку, видишь папки, открываешь папку и так пока не доберешься до файла.

Разница лишь в том, что вместо папок у тебя - компоненты адреса в интерфейсе полей. Первое поле заполнил - второе - третье - четвертое. А подсказки просто загружаются.

warren buffet 13.09.2016 04:32

Я понятия не имею как работает кладр и разбираться не буду. Если он умеет сам искать - проси чтобы искал по тому, что юзер уже ввел. Иначе проси список, список грузи в datalist приделанный к своему полю.

warren buffet 13.09.2016 04:38

Начнем со страны. Сразу загружаем список стран в datalist. Юзер вводит Ро - получает варианты Родезия и Российская Федерация. Я видел такие шняги на сайтах. Выбрал, по событию получения фокуса идут проверки и если надо и все ок - загружается список городов в datalist. Выбрал Default City и все повторяется. Если написать метод достаточного уровня абстракции, он будет во все поля.


Часовой пояс GMT +3, время: 07:35.