Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Обработка событий и динамические списки. (https://javascript.ru/forum/dom-window/79166-obrabotka-sobytijj-i-dinamicheskie-spiski.html)

savsoft 26.12.2019 17:19

Обработка событий и динамические списки.
 
Всем привет,

Есть форма/таблица с колонкой input поля даты.
Даты выбираются из календаря. Часто даты нужно выбирать по дням недели. Сначала, например ввести пять вторников, потом например семь четвергов и т.д.

Клиент хочет, чтобы добавили еще одну колонку с выпадающим списком. При каждом выборе даты, определить день недели и запомнить. Если после этого открыть выпадающий список, то его перед открытием динамически заполнить десятком дат с днем недели, как у последней введенной даты.

<form name="FormDates" id="fd" method="post" action="">
			<div class="row">
				<table class="table table-striped table-bordered">
					<thead>
						<tr>
							<th>Id</th>
							<th>Name</th>
							<th>Date</th>
							<th>Select</th>
						</tr> 
					</thead>
					<tbody>
						<tr> 
							<td>1</td>
							<td>Name 1</td>
							<td><input type="date" name="task_date[1]" value=""></td>
							<td>
								<select name="select_date[1]">
								</select>						
							</td>
						</tr> 
						<tr> 
							<td>2</td>
							<td>Name 2</td>
							<td><input type="date" name="task_date[2]" value=""></td>
							<td>
								<select name="select_date[2]">
								</select>						
							</td>
						</tr> 
						<tr> 
							<td>3</td>
							<td>Name 3</td>
							<td><input type="date" name="task_date[3]" value=""></td>
							<td>
								<select name="select_date[3]">
								</select>						
							</td>
						</tr> 
					</tbody>					
				</table>
			</div>
		</form>


Собственно вопросы:

1. Как перехватить событие после выбора даты и вызвать функцию, которая обнулит массив дат и заполнит его датами с таким же днем недели?

2. Как при открытии списка, его динамически заполнить датами из массива?

3. После выбора элемента - автоматически заполнить соответствующую дату и отобразить ее?

Как-то так. Извините, что слегка путано, только начинаю разбираться с javascriot.

Спасибо.

рони 26.12.2019 18:23

savsoft,
:-?

Malleys 26.12.2019 20:41

Цитата:

Сообщение от savsoft
Клиент хочет, чтобы добавили еще одну колонку с выпадающим списком. При каждом выборе даты, определить день недели и запомнить. Если после этого открыть выпадающий список, то его перед открытием динамически заполнить десятком дат с днем недели, как у последней введенной даты.

Если вам нужно выбрать дату из календаря (например завтра — пятница), а затем из списка одну из 10 дат (какую-то одну из десяти пятниц), то вам не нужен отдельный массив, всё это решается «на лету»

Цитата:

Сообщение от savsoft
Как перехватить событие после выбора даты и вызвать функцию, которая обнулит массив дат и заполнит его датами с таким же днем недели?

Метод addEventListener на общем родителе позволит обрабатывать все календари.

Цитата:

Сообщение от savsoft
Как при открытии списка, его динамически заполнить датами из массива?

После выбора даты можно сразу заполнить список следующими десятью датами (следующими 10-ю пятницами), так что изначально будет указана выбранная дата (только одна пятница, а открыв список, можно увеличить кол-во пятниц) с возможностью затем выбрать другую дату.

Цитата:

Сообщение от savsoft
После выбора элемента - автоматически заполнить соответствующую дату и отобразить ее?

Здесь не совсем понятно, что вы имеете в виду, однако стоит учитывать, что если вы что-то выбираете в списке, то он сам знает, что выбрано, и при отправке формы (или чтении данных формы) выбранная дата будет на месте.

Например так...
<form name="FormDates" id="fd" method="post" action="">
	<table class="table table-striped table-bordered">
		<thead>
			<tr>
				<th>Id</th>
				<th>Name</th>
				<th>Date</th>
				<th>Select</th>
			</tr>
		</thead>
		<tbody>
			<tr>
				<td>1</td>
				<td>Name 1</td>
				<td><input type="date" name="task_date[1]" value=""></td>
				<td>
					<select name="select_date[1]"></select>
				</td>
			</tr>
			<tr>
				<td>2</td>
				<td>Name 2</td>
				<td><input type="date" name="task_date[2]" value=""></td>
				<td>
					<select name="select_date[2]"></select>
				</td>
			</tr>
			<tr>
				<td>3</td>
				<td>Name 3</td>
				<td><input type="date" name="task_date[3]" value=""></td>
				<td>
					<select name="select_date[3]"></select>
				</td>
			</tr>
		</tbody>
	</table>
</form>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css">
<style>
	#fd select:empty {
		display: none;
	}
	#fd table {
		table-layout: fixed;
	}
</style>
<script>
document.getElementById("fd").addEventListener("input", event => {
	const target = event.target;
	if(target.matches("[name^=task_date]")) {
		const select = target.form.querySelector(`[name="${target.name.replace("task", "select")}"`);
		select.textContent = "";
		if(!target.value) return;
		const date = new Date(target.value);
		for(let i = 0; i < 10; i++) {
			select.append(new Option(
				date.toLocaleDateString(navigator.language),
				date.toISOString().replace(/T.+$/, ""))
			);
			date.setDate(7 + date.getDate());
		}
	}
});	
</script>

savsoft 26.12.2019 22:17

Цитата:

Сообщение от Malleys (Сообщение 518077)
Если вам нужно выбрать дату из календаря (например завтра — пятница), а затем из списка одну из 10 дат (какую-то одну из десяти пятниц), то вам не нужен отдельный массив, всё это решается «на лету»

Метод addEventListener на общем родителе позволит обрабатывать все календари.


После выбора даты можно сразу заполнить список следующими десятью датами (следующими 10-ю пятницами), так что изначально будет указана выбранная дата (только одна пятница, а открыв список, можно увеличить кол-во пятниц) с возможностью затем выбрать другую дату.

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

Malleys 26.12.2019 22:30

Цитата:

Сообщение от savsoft
Проблема в том, что таблица может быть достаточно большой, там выбираются материалы для домашней работы, сначала самые соответствующие поиску, а затем по убывающей.

А зачем рисовать то, что не влезает на экран? Может стоит показывать только ту часть, которая видна на экране? (Это можно легко сделать, если высота строки таблицы фиксированная)

Или другой вариант — постраничная разбивка (pagination) — вместо того, чтобы показывать все результаты, показывайте на странице, например, по 20 за раз. (например, как это сделано в поисковых системах, вам же не всё сразу на странице показывают, а по частям)

savsoft 27.12.2019 06:00

Цитата:

Сообщение от Malleys (Сообщение 518085)
А зачем рисовать то, что не влезает на экран? Может стоит показывать только ту часть, которая видна на экране? (Это можно легко сделать, если высота строки таблицы фиксированная)

Да, это я могу сделать, но как пробежаться по всем селектам и заполнить их? У меня пока не получилось.


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