Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Ссылка onclick="location.href" не поддерживает required. Чем заменить required? (https://javascript.ru/forum/misc/78400-ssylka-onclick%3D-location-href-ne-podderzhivaet-required-chem-zamenit-required.html)

Lefseq 08.09.2019 08:14

Ссылка onclick="location.href" не поддерживает required. Чем заменить required?
 
Всем привет. Хотел реализовать переход с формы на другую страницу с помощью onclick="location.href", с обязательной проверкой полей формы на заполненность, но как оказалось required тут не работает. Подскажите, чем можно заменить required?
action с submin не вариант, с ними данные из формы не передаются и не происходит переход на страницу.

<section id="user-greeting">
	<form>
		<label>
			Имя
			<input type="text" autocomplete="name" name="name" required>
		</label>
		<label>
			Фамилия
			<input type="text" autocomplete="family-name" name="family-name" required>
		</label>
		<button onclick="location.href='https://site.ru/next.html'">Перейти</button>
	</form>
	<section>
		Привет, <span class="name"></span>, добро пожаловать на сайт!
	</section>
</section>


(function main() {
		var form = document.querySelector("#user-greeting > form");
		var section = document.querySelector("#user-greeting > section");
		
		function changeView() {
			if ("name" in localStorage) {
				form.style.display = "none";
				section.style.display = "";
				document.querySelector("#user-greeting .name").textContent = localStorage.name;
			} else {
				section.style.display = "none";
				form.style.display = "";
			}
		}
		
		form.addEventListener("submit", function(event) {
			event.preventDefault();
			var data = new FormData(form);
			localStorage.name = [data.get("name"), data.get("family")].join(" ");
			changeView();
		});
		
		document.getElementById("user-greeting-forget-button").addEventListener("click", function() {
			delete localStorage.name;
			changeView();
		});
		
		changeView();
	})();

laimas 08.09.2019 08:26

Цитата:

Сообщение от Lefseq
Хотел реализовать переход с формы на другую страницу с помощью onclick="location.href"

Для этого есть атрибут action и событие submit у формы.

Lefseq 08.09.2019 08:47

Цитата:

Сообщение от laimas (Сообщение 512574)
Для этого есть атрибут action и событие submit у формы.

Да, но в таком случае не передаются данные из формы.

(function main() {
		var form = document.querySelector("#user-greeting > form");
		var section = document.querySelector("#user-greeting > section");
		
		function changeView() {
			if ("name" in localStorage) {
				form.style.display = "none";
				section.style.display = "";
				document.querySelector("#user-greeting .name").textContent = localStorage.name;
			} else {
				section.style.display = "none";
				form.style.display = "";
			}
		}
		
		form.addEventListener("submit", function(event) {
			event.preventDefault();
			var data = new FormData(form);
			localStorage.name = [data.get("name"), data.get("family")].join(" ");
			changeView();
		});
		
		document.getElementById("user-greeting-forget-button").addEventListener("click", function() {
			delete localStorage.name;
			changeView();
		});
		
		changeView();
	})();

laimas 08.09.2019 08:49

Цитата:

Сообщение от Lefseq
в таком случае не запоминаются данные из формы

С чего вдруг? Зачем вам вообще форма, если вы ее не используете?

Lefseq 08.09.2019 10:30

Цитата:

Сообщение от laimas (Сообщение 512576)
С чего вдруг? Зачем вам вообще форма, если вы ее не используете?

Почему же не использую?
Рассказываю, посетитель пишет в форме свои Имя и Фамилию, эти данные запоминаются в localStorage, посетитель нажимает на кнопку "Перейти". Его перенаправляет на другую страницу где выводятся данные из localStorage. Все работает. Но проблема в том, что использую данный код, не работает required и пользователь может отправить пустые данные. Вот я и спрашиваю, чем проверять поля используя данный код?

laimas 08.09.2019 11:02

Цитата:

Сообщение от Lefseq
Почему же не использую?

Потому, что в вашем коде серверу ваша форма нафиг не нужна, не отправляете ее вы. Следовательно вам нужны только два поля и две кнопки без формы. На эти кнопки нужно повесить обработчик события, в котором для кнопки запоминания и перенаправления нужно проверять ввод и если ОК, то перенаправить, а для кнопки удаления очищать локальное хранилище. Можете и два отдельных обработчика, это уже как душе угодно.

Для этого достаточно:

<section id="user-greeting">
        <label>
            Имя
            <input type="text" autocomplete="name" required>
        </label>
        <label>
            Фамилия
            <input type="text" autocomplete="family" required>
        </label>
        <button name="mem">Запомнить</button>
    <section>
        Привет, <span class="name"></span> <span class="family"></span>, добро пожаловать на сайт!
        <button name="del">Забудь обо мне!</button>
    </section>
</section>


и суть обработчика:

document.querySelectorAll("button").forEach((b) => {
    b.addEventListener("click", (b) => {
        if(b.target.name=='mem') {
            var err = false, mem = [];
            document.querySelectorAll("#user-greeting [required]").forEach(function(f) {
                if(!f.value.trim()) {
                    //поле не заполнено, вывод ошибки и запрет перенаправления err = true
                } else mem.push(f.value); //запомнить ввод
            });
            if(!err) { //поля заполнены
                localStorage.name = mem.join(' '); //запомнить ввод в хранилище
                location.href = URL; //перенаправление на URL
            }
        } else delete localStorage.name;  //удалить запомненное
    });
});


А вот проверка полей, тут можно издеваться до бессовестного.

Lefseq 08.09.2019 14:23

laimas, Не работает ваш код, совсем. Поля не проверяет, данные не запоминает.

laimas 08.09.2019 14:52

Это ваш не работает, а это будет работать
<html>
<body>
<section id="user-greeting">
        <label>
            Имя
            <input type="text" autocomplete="name" required>
        </label>
        <label>
            Фамилия
            <input type="text" autocomplete="family" required>
        </label>
        <button name="mem">Запомнить</button>
    <section>
        Привет, <span class="name"></span> <span class="family"></span>, добро пожаловать на сайт!
        <button name="del">Забудь обо мне!</button>
    </section>
</section>

<script>
document.querySelectorAll("button").forEach((b) => {
    b.addEventListener("click", (b) => {
        if(b.target.name=='set') {
            var err = false, mem = [];
            document.querySelectorAll("#user-greeting [required]").forEach(function(f) {
                if(!f.value.trim()) {
                    err = true;
                    alert('Не заполнено!');
                } else mem.push(f.value); //запомнить ввод
            });
            if(!err) { //поля заполнены
                alert('Запомнить '+mem.join(' '))
            }
        } else delete localStorage.name;  //удалить запомненное
    });
})
</script>
</body>
</html>


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

Lefseq 08.09.2019 15:28

Цитата:

Сообщение от laimas
Что-то в песочнице не работает, но запустите это отдельной страницей

И на отдельной странице не работает. Кнопки вообще ни на что не реагируют.
И еще, а куда в вашем коде ссылку на страницу для перенаправления вставить?

laimas 08.09.2019 15:35

Цитата:

Сообщение от Lefseq
И на отдельной странице не работает. Кнопки вообще ни на что не реагируют.

У вас что эксклюзивный браузер? Под каким проверяете?

Lefseq 08.09.2019 15:37

Цитата:

Сообщение от laimas
У вас что эксклюзивный браузер? Под каким проверяете?

Opera 63.0.3368.71

laimas 08.09.2019 15:38

Цитата:

Сообщение от Malleys
Форма нужна для проверки.

Это да, иначе внутренняя проверка работать не будет.

Цитата:

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

А это полная хрень, ибо само действо на странице бред полнейший, если серверу этого не нужно. Зачем вообще ради этого пустяка два поля? А показать/разукрасить ошибку можно и без внутренней проверки.

Malleys 08.09.2019 15:49

Lefseq, я ответил на ваш вопрос...

Цитата:

Сообщение от Lefseq
Malleys,
Код рабочий, но нужно кое что исправить. Буду признателен, если поможете.

1. Нужно убрать на страницах кнопку/функцию "Забудь обо мне!"
2. Надо чтобы введенные пользователем имя (name) и фамилия (family-name) выводились на странице next.html по отдельности, чтобы можно было поставить их в разные части страницы.

Тогда страница с формой выглядит так...
<section id="user-greeting">
	<form action="next.html">
		<label>
			Имя
			<input autocomplete="name" name="name" required>
		</label>
		<label>
			Фамилия
			<input autocomplete="family-name" name="familyName" required>
		</label>
		<button>Запомнить</button>
	</form>
</section>
<script>
	(function main() {
		var form = document.querySelector("#user-greeting > form");
		
		form.addEventListener("submit", function(event) {
			event.preventDefault();
			var data = new FormData(form);
			localStorage.name = JSON.stringify(Object.fromEntries(data));
			form.submit();
		});
	})();
</script>


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

Тогда страница next.html может выглядеть так...

<h3>Привет, <span data-field="name"></span>, добро пожаловать на сайт!
</h3>
<p>Привет, <span data-field="name"></span> <span data-field="familyName"></span>. Мы вас ждали.</p>
<p>Как видите, <span data-field="name"></span>, страница называет вас
  по имени. Ваше имя (<i data-field="name"></i>) и фамилия (<i data-field="familyName"></i>)
  были сохранены в локальном хранилище, поэтому теперь их можно было использовать.
  </p>
  
  <button onclick="delete localStorage.name; location.reload();">Забыть меня</button>
  
<script>
	document.addEventListener("DOMContentLoaded", function() {
    if("name" in localStorage === false) return location.replace("./");
    const data = JSON.parse(localStorage.name || "{}");
    
    for(const [key, value] of Object.entries(data)) {
      for(const node of document.querySelectorAll(`[data-field="${key}"]`)) {
        node.textContent = value;
      }
    }
	});
</script>
В <span data-field="name"></span> подставляется значение из отправленной формы. Значению data-field соответствует имя поля из формы.

Рабочий пример на основе этого кода вы можете посмотреть тут... https://charm-launch.glitch.me/localstorage

Цитата:

Сообщение от laimas
Для этого достаточно:

А зачем вам атрибут required без формы? Оно так не работает!

Цитата:

Сообщение от laimas
ваша форма нафиг не нужна

Почему вы решили, что данные формы нужны только для того, чтобы их отправить обрабатывать в текстовый препроцессор PHP?

Форма нужна для проверки. Форма нужна для связности, чтобы пользователь мог по порядку заполнить поля без необходимости поиска следующего поля. Это громадное улучшение UX.

Цитата:

Сообщение от laimas
А уж по каким правилам проверять, это уже не мне решать, тем более, что по логике все это похоже на бред.

Всё уже стандартизировано, никаких костылей изобретать не нужно. (атрибут pattern)

Цитата:

Сообщение от laimas
А это полная хрень

Мир не ограничен Windows

laimas 08.09.2019 15:55

Вот в Опере

laimas 08.09.2019 15:58

Цитата:

Сообщение от Malleys
Почему вы решили, что данные формы нужны только для того, чтобы их отправить обрабатывать в текстовый препроцессор PHP?

Я ничего не решил, я просто вижу полную дурь, это как если бы я утром ради выпить чашку кофе обязательно бы отправлялся в ресторан вместо того, чтобы приготовить ее дома.

Я знаю вы любитель мусолить, но это ваше мнение и мне оно пофигу, я лишь высказываю свое.

Lefseq 08.09.2019 16:03

Цитата:

Сообщение от Malleys
Lefseq, я ответил на ваш вопрос...

Спасибо большое за помощь, теперь все работает.

Lefseq 08.09.2019 16:08

laimas,
Успокойтесь, Malleys хоть поделился действительно рабочим решением, без упоминания дурь мое ТЗ или не дурь.

laimas 08.09.2019 16:16

Цитата:

Сообщение от Lefseq
Успокойтесь

Я спокоен как танк, мне пофигу что у вас там будет, как говорится "хозяин барин". ;) Но, вся эта хрень (не в плане кода, а как результат вашей хотелки) вам написанная с успехом скушает и ввод одних пробелов полях, и даже не заикнется об ошибках. А вот логика во втором варианте "действий" (#13) уже какая-то есть, в отличие от ахинеи первого.


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