Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Обработка radio buttons (https://javascript.ru/forum/events/81110-obrabotka-radio-buttons.html)

wrbanker 02.10.2020 11:27

Обработка radio buttons
 
Приветствую.
Стоит задача: показать выбранное значение radio. Работает только при выборе первого переключателя. В остальных случаях показывает, что переключатель не выбран. Помогите, плиз, понять где ошибка.

<form id="test-form">        
     <ul>
         <li><input type="radio" name="radio-button" value="one"></li>
         <li><input type="radio" name="radio-button" value="two"></li>
         <li><input type="radio" name="radio-button" value="three"></li>
     </ul>
     <input type="submit" value="Обработать">
</form>
             
    <script>
        const form = document.querySelector('#test-form');
        form.addEventListener('submit', function (event) {         
            const testValue = (this.querySelector('[name="radio-button"]').checked) ? this.querySelector('[name="radio-button"]').value : 0;           
            alert (testValue);            
        });
    </script>

voraa 02.10.2020 12:04

const testValue = this.elements['radio-button'].value;

wrbanker 02.10.2020 12:12

Цитата:

Сообщение от voraa (Сообщение 529415)
const testValue = this.elements['radio-button'].value;

Спасибо! А почему вот этот код некорректно работает?

const testValue = (this.querySelector('[name="radio-button"]').checked) ? this.elements['radio-button'].value : 0;

voraa 02.10.2020 12:20

Цитата:

Сообщение от wrbanker
Спасибо! А почему вот этот код некорректно работает?

const testValue = (this.querySelector('[name="radio-button"]').checked) ? this.elements['radio-button'].value : 0;

Потому, что querySelector выбирает только один (первый) элемент
Если их несколько, надо использовать querySelectorAll - получить ВСЕ элементы и перебирать их в цикле.

wrbanker 02.10.2020 12:58

Цитата:

Сообщение от voraa (Сообщение 529420)
Потому, что querySelector выбирает только один (первый) элемент
Если их несколько, надо использовать querySelectorAll - получить ВСЕ элементы и перебирать их в цикле.

Да, про это я забыл. Спасибо. Работает только такой вариант:
const testValue = this.querySelector('[name="radio-button"]:checked').value


Тогда у меня ещё один вопрос. Можно ли обойтись без цикла, чтобы переменной присваивать значение radio, которое отмечено и '0' если не отмечено ничего? Через условное ветвление, например?

laimas 02.10.2020 13:10

Цитата:

Сообщение от wrbanker
Можно ли обойтись без цикла

А как вы думаете работает querySelector, знает что в третьем ряду слева нужное? Как бы не так, это обход циклом элементов формы, причем DOM, и это при том, что у this (формы) они уже доступны. Выведите в консоль this, изучите.

Какова вообще цель, может вы делаете то, без чего вообще можно обойтись?

wrbanker 02.10.2020 13:27

Цитата:

Сообщение от laimas (Сообщение 529424)
Какова вообще цель, может вы делаете то, без чего вообще можно обойтись?

Внутри формы есть несколько элементов input различных типов: number, date, radio, checkbox. При событии submit необходимо переменным присвоить определенные значения. В типах number и date - введенное значение или '0', если поле ввода не заполнено, в типе checkbox - '0' или'1', в типе radio - значение переключателя или '0', если ни один из переключателей не выбран.

laimas 02.10.2020 13:45

wrbanker, так задачи не описывают, это просто рассказ о нулях.

У вас форма, у нее поля, если нужно привести соответствие состояния неких переменных состоянию полей, значит простой обойти поля циклом и ... Но для этого нужно связать сами переменные с полями. В тоже время почему имена полей и их значения не могут сами служить таким набором?

wrbanker 02.10.2020 14:08

Ок, попробую описать задачу иначе. Есть страница с условной анкетой. После её заполнения пользователь нажимает кнопку и получает документ, который определён его ответами.
Я думаю, что перво-наперво необходимо отловить все его ответы и присвоить зависимые от ответов значения переменным. Далее, анализируя значения переменных, формировать документ.
Возможно, что я не прав.

laimas 02.10.2020 14:26

Вот это уже ближе к телу, а тут два сценария - если этот документ готовит сервер, то то что вы делаете на клиенте лишено смысла. Серверу нужно просто отправить форму, он должен анализировать что пришло. Если документ готовится на клиенте, то зачем посредник в виде 0 и ... Формируйте документ, в который вставляйте нужное, получая ответы из обхода циклом полей формы.

wrbanker 02.10.2020 14:45

Документ формирует клиент. И у меня тогда тогда ещё есть вопрос.
Документ формируется не просто из конкретных ответов. Например, есть два поля - одно с checkbox, а второе с radio. В зависимости от того, что и где отмечено в обоих этих полях и будет добавляться в документ тот или иной абзац. Поэтому, видимо, у меня и есть желание объявить какие-то понятные переменные, записать в них зависимые от заполнения полей формы значения, и уже дальше с ними работать.

Возможно, что вы уже ответили на все мои вопросы и я просто не понимаю ответов. Но последний язык программирования, на котором я решал задачи, был Fortran 4 (да, мы ещё живы):)

laimas 02.10.2020 15:11

Цитата:

Сообщение от wrbanker
Документ формируется не просто из конкретных ответов. Например, есть два поля - одно с checkbox, а второе с radio.

И что? Если бы "посредник", а он может быть только объектом, можно было сразу вставить в документ, тогда ладно. Но ведь его опять придется обходить циклом. Какой же смысл. В документ вы же что-то будет вставлять "существенное" как-то текст и результат ответа.
А ответ вы получить можете только проверив значение полей. Так почему нельзя сразу при анализе полей сформировать конечный результат, а делать это чрез сторонний набор?
Если у вас условие проверить определенный набор радио и флажок к нему, то вы же в любом случае должны знать имя и набора, и флажка, так ведь. А значит в цикле, если имя поля соответствует этому набору, то напрямую обращаемся к флажку для него, анализируем и определяем соответствующий текст.

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

{"имя_поля": ["Абзац 1", "Абзац 2", "Абзац 3"]}

где индексы абзацев, это сумма значений ответов (0 не выбрано, 1 выбрано) или иным принципам сформированные.

То есть, получить и сформировать можно сразу, зачем сначала что-то чему-то присвоить, а затем еще и с ним разбираться.

wrbanker 02.10.2020 15:18

Да, вы правы. Думая, что это мне задачу упростит, я её усложняю. Буду пробовать без "посредников". Надеюсь, что получится.
Спасибо!

laimas 02.10.2020 15:32

wrbanker, составьте структуру, которая описывает абзацы и прочее для документа и зависящие от значения полей, так, чтобы можно было автоматически на основании значений обращаться к ним. Вот это сложнее будет, "придумать автомат", а написать его будет проще.

wrbanker 02.10.2020 15:42

Структура уже есть. Мы с коллегой её уже сочинили. Я вот теперь её пытаюсь в JS воплотить :)

wrbanker 02.10.2020 15:46

Да, подозреваю, что следующий серьёзный затык у меня возникнет с формированием итогового PDF-документа. Если знаете, что в этом может помочь (помимо библиотеки Pdfmake - про неё я знаю), буду признателен.

laimas 02.10.2020 16:11

Цитата:

Сообщение от wrbanker
Структура уже есть.

Я не об этом. Представьте, что вам поставили задачу написать цифровой автомат, который по единому правилу обрабатывал входные данные. А чтобы такое написать, входные данные должны отвечать определенным условиям, а не быть просто "кучей", которую тоже можно назвать структурой.

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

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

Например, группируем поля в элементах fieldset. Не важно, что у вопроса анкеты может быть только одно поле, оно все равно должно быть помещено в fieldset. Это оговаривается правилом, условием автомата. В fieldset в оговоренном атрибуте, например, data-fields описаны имена полей, значения которых надо получить/проверить...

<fieldset data-fields="neme1,neme2">

Не важно что поле одно, оно все равно в этом атрибуте должно быть описано в этом атрибуте.

Автомат получает коллекцию fieldset, обходит циклом, извлекает имена полей из data-fields и получает их массив.

var fields = elm.dataset.fields.split(',');


Обходит их циклом, в котором можно узнать все о нем, и имя, и тип, и значение - form[fields[i]].name, form[fields[i]].type, ...

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

Но можно поступить ведь иначе - data-fields, это не просто текст, а json, в котором одно свойство описывает поля, а второе объект или значение false. Если это объект, то это ссылка на функцию, в которую нужно передать значения/состояния полей, а функция вернет результат. В этом случае просто будет добавить функцию для обработки любых индивидуальных условий, а в атрибуте ссылку на нее. Сам автомат переписывать не нужно будет.

То есть структура это не просто набор вопрос/поля, а подчинена определенному конечному автомату.


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