Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Модальные окна, паттерн, JS (https://javascript.ru/forum/events/52641-modalnye-okna-pattern-js.html)

TepKuH 28.12.2014 17:55

Модальные окна, паттерн, JS
 
Уважаемые коллеги,
Сам я не местный и имею крайне мало опыта в разработке фронт-ендов и у меня вопрос относительно паттерна проектирования UI. А именно как делать правильно.
Задача следующая:
Есть элементы списка и нужно чтобы при нажатии на какой либо элемент появлялось модальное окно. Где при нажатии на кнопку "Cancel" не происходило ничего, т.е. модальное окно закрывалось.
Но при нажатии на кнопку "Continue" происходила отправка id элемента LI на сервер-сайд.
В качестве демонстрации выше сказанного привожу 3и варианта того что удалось придумать, но я не совсем не уверен в их правильности.
Как впрочем и не уверен в том что есть какой то 4ый расово верный.
В общем хочу получить совет о правильном подходе при работе с модальными окнами.


<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
	<form id="dialog-confirm" style="display:none">
		<span>If you continue following connections will be lost</span>	
		<input type="hidden" name="tmp">
		<button>Continue</button>
		<button onclick="$('#dialog-confirm').hide(); return false;">Cancel</button>
	</form>
	<ul>
        <li id="first" onClick="showModal(this);">my first text</li>
        <li id="secod" onClick="showModal(this);">my second text</li>
    </ul>
<script src="jquery-2.1.1.min.js" type="text/javascript"></script>
<script src="script.js" type="text/javascript"></script>
</body>
</html>



Первый подход не нравится тем что нужно постоянно вызывать функцию удаления всех евентов с элемента $( "#dialog-confirm" ).

function showModal(item) {
	var id = $(item).attr("id");
	$( "#dialog-confirm" ).show();
	$( "#dialog-confirm" ).off(); //Вот этот момент больше всего не нравится, так как всегда приходит удаление всех event'ов у #dialog-confirm
	$( "#dialog-confirm" ).on('submit', function(e) {
		var deleted = sendData(id);
	});
}

function sendData(id) {
	console.log(id);
	//Отправка данных на сервер-сайд
	return true;
}


Второй подход не нравится тем что в HTML необходимо держать часть логики, а именно деражать в элемент
<input type="hidden" name="tmp"> что идеологически кажется не правильным.


function showModal(item) {
	var id = $(item).attr("id");
	var $tmp = $('#dialog-confirm').find("input[name='tmp']");
	$tmp.val(id);
	$( "#dialog-confirm" ).show();
}

function sendData(id) {
	console.log(id);
	//Отправка данных на сервер-сайд
	return true;
}

$( "#dialog-confirm" ).on('submit', function(e) {
	var $tmp = $('#dialog-confirm').find("input[name='tmp']");
	var id = $tmp.val();
	var deleted = sendData(id);
});


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

var id;
function showModal(item) {
	id = $(item).attr("id");
	$( "#dialog-confirm" ).show();
}

function sendData(id) {
	console.log(id);
	//Отправка данных на сервер-сайд
	return true;
}

$( "#dialog-confirm" ).on('submit', function(e) {
	var deleted = sendData(id);
});

Rise 28.12.2014 18:45

TepKuH, в чем смысл off в первом подходе?
Цитата:

в случаи наличия большого числа модальных окон
Что это значит их одновременно что-ли все открыть можно?

TepKuH 28.12.2014 21:34

Цитата:

Сообщение от Rise (Сообщение 348674)
TepKuH, в чем смысл off в первом подходе?
Что это значит их одновременно что-ли все открыть можно?

Нет, одновременно нельзя, но если делать без .off() event onsubmit назначается несколько раз на селектор $( "#dialog-confirm" ).
Что негативно сказывается на кейсах:
1) Пользователь открыл модальное окно
2) Пользователь нажал cancel
3) Пользователь несколько раз повторил п.1 и п.2
4) Пользователь всё таки нажал в модальном окне кнопку "Continue"
Функция:
$( "#dialog-confirm" ).on('submit', function(e) {
var deleted = sendData(id);
});
сработала столько раз сколько раз пользователь нажал на кнопку cancel в модальном окне.
Функция же off() очищает все ранее назначеные события на селектор "#dialog-confirm" в противном случаи они назначаются снова и снова

Rise 29.12.2014 00:16

TepKuH, а без submit никак, на click например? надо же как то кнопки различить при submit не получится...

Яростный Меч 29.12.2014 03:12

TepKuH,

В showModal:
$( "#dialog-confirm" ).data("itemid", item.id).show();


В обработчике сабмита:
var deleted = sendData($(this).data("itemid"));

TepKuH 29.12.2014 15:26

Цитата:

Сообщение от Яростный Меч
В showModal:
$( "#dialog-confirm" ).data("itemid", item.id).show();


В обработчике сабмита:
var deleted = sendData($(this).data("itemid"));

Пасиба, вроде круто выглядит :)

TepKuH 29.12.2014 15:28

Цитата:

Сообщение от Rise (Сообщение 348736)
TepKuH, а без submit никак, на click например? надо же как то кнопки различить при submit не получится...

А это сути третьего варианта не поменяет.
$( "#dialog-confirm" ).on('submit', function(e) {
}
Был селектор формы, станет селектор кнопки, был onSubmit, станет onClick. Все остальное ведь останется неизменным, так же нужно держать глобальную переменную которая отвечает только за локальную функцию. Что не выглядит расово верным

Rise 29.12.2014 19:57

TepKuH, расово верным не выглядит писать js в атрибутах html элементов (а при наличии jquery вообще бред), click позволит полностью разделить js и html.

TepKuH 30.12.2014 15:29

Цитата:

Сообщение от Rise (Сообщение 348843)
TepKuH, расово верным не выглядит писать js в атрибутах html элементов (а при наличии jquery вообще бред), click позволит полностью разделить js и html.

Всё верно, это не выглядит правильным по моему ИМХО. Потому я предложил три варианта (какие смог выдумать с моими знаниями JS) решения задачи где я пишу в атрибутах HTML и не пишу в атрибутах HTML.
Но ведь конструкция
$( "#dialog-confirm" ).data("itemid", item.id).show();
Не говорит о том что я что то пишу в атрибуты элементов HTML. Или говорит?
Предложенная вами конструкция на сколько я понял должна выглядит так:
var a;
function showModal(item) {
	var id = $(item).attr("id");
        a = id;
	$( "#dialog-confirm" ).show();
}

function sendData(a) {
	console.log(a);
	//Отправка данных на сервер-сайд
	return true;
}

$("button[name=continue]").on('click',function(){
        sendData(a);
});	
	
});

Она конечно выглядит максимально правильной, так как полностью разделяет верстку HTML и логику. Но есть одно НО, это держать глобальную переменную. При наличии одного модального окна, эт конечно не проблема, но у меня модальных окон на странице порядка 15 штук. Что выглядит ужасно и трудно понять какая переменная относится к какому модальному окну.
Но ведь предложная конструкция господина "Яростный Меч" так же разделяет верстку и логику и позволят не держать глобальной переменной в коде JS и в HTML
Или я не прав?

Rise 30.12.2014 15:53

TepKuH,
Цитата:

я предложил три варианта решения задачи где я пишу в атрибутах HTML и не пишу в атрибутах HTML
Ты во всех вариантах пишешь, 11, 14, 15 строки html кода.
Цитата:

у меня модальных окон на странице порядка 15 штук
Все одинаковые что-ли? Какой в них контент?


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