Получение пользовательских данных HTML-* атрибутов из переключателей при отправке формы

#javascript #forms #serializearray #html5-data

#javascript #HTML #формы #serializearray

Вопрос:

Есть ли способ получить пользовательские HTML data-* атрибуты для выбранной переключающей кнопки при отправке формы? Значение, похоже, не распознается serializeArray() .

HTML

 <form id="preference-form">
<table>
<tr class ="result">
    <td width="100%">{{Title}}</td>
    <td><input type="radio" id="radio-{{Project_No}}-1" data-application="{{Application_ID}}" name="{{Project_ID}}" value="1"></td>
    <td><input type="radio" id="radio-{{Project_No}}-2" data-application="{{Application_ID}}" name="{{Project_ID}}" value="2"></td>
    <td><input type="radio" id="radio-{{Project_No}}-3" data-application="{{Application_ID}}" name="{{Project_ID}}" value="3"></td>
    <td><input type="radio" id="radio-{{Project_No}}-9" data-application="{{Application_ID}}" name="{{Project_ID}}" value="9"></td>
</tr>
</table>
</form>
  

JavaScript

 $("#preference-form).on('submit', function() {
    var data = $(this).serializeArray();
    console.log(data)
});
  

Это выводит поля name и value , но, похоже, я не могу найти простой ответ о data-* полях. К сожалению, мне нужны все три фрагмента информации, чтобы выполнить обновление записи базы данных, и, насколько я понимаю,:

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

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

Комментарии:

1. Не могли бы вы просто использовать скрытый ввод?

2. Обратите внимание, что перенос <tr> в <form> является недопустимой разметкой

3. Возможно, если бы я знал, как связать это с входными данными. <tr> Элемент моего HTML на самом деле имеет глубину 3 или 4; как бы я это связал? Обновлена разметка.

4. Есть ли у вас другие элементы управления формой, кроме радио? Достаточно просто написать собственный сериализатор для радиостанций и создавать объекты типа [{app:123, name:'foo', value:3}]

5. Тогда я бы предложил другой атрибут данных для идентификации update vs insert также

Ответ №1:

Основываясь на комментарии, что все, что у вас есть, это радиостанции; написать свой собственный сериализатор просто.

Сначала я бы поместил атрибут data в <tr> для меньшего количества повторений

 <tr data-application="{{Application_ID}}">
  

Затем вы могли бы сделать что-то вроде:

 var data = $(this).find('tr:has(:radio:checked)').map(function(){
   var $row=$(this), radio = $row.find(':radio:checked')[0]
   return {
      app: $row.data('application'),
      name: radio.name,
      value: radio.value
   }
}).get()
  

Комментарии:

1. Не могли бы вы немного разбить свой код. Я предполагаю, что $(this) это элемент, который был выбран при выполнении submit действия; в моем случае $("#preference-form") , но как насчет $row = $(this) ? Мои radio элементы также помещены в <td> элементы, найдет ли это независимо?

2. Во-первых this , форма … правильная. Внутренний this in map() — это <tr> экземпляр

3. Он продолжает выбрасывать unrecognized expression: tr.has(:radio:checked)

4. та же ошибка, только tr.has(… :radio:checked) если я правильно понял ваш последний комментарий, но это, я думаю, также сломает Edge.

5. Здесь работает нормально jsfiddle.net/vp8d3tc6 . Здесь не используется ничего, что не должно работать даже в Edge или более старом IE. Вероятно, работает даже в IE 7-8

Ответ №2:

Вы упускаете #

  $('#preference-form').on('submit', function(e) {
  

Используйте скрытый ввод для data-* значений атрибутов. Следующая демонстрационная версия отправляется на тестовый сервер в режиме реального времени, и ответ будет показан в iframe ниже.

 $('#preference-form').on('submit', function(e) {
  radData(e);
  var data = $(this).serializeArray();
  console.log(data);
});

var radData = e => {
  $(':radio:checked').each(function(e) {
    var dataSet = $(this).data('application');
    $(this).closest('tr').find('.dataSet').val(dataSet);
  });
}  
 .as-console-wrapper {
  width: 350px;
  min-height: 100%;
  margin-left: 45%;
}

.as-console-row.as-console-row::after {
  content: '';
  padding: 0;
  margin: 0;
  border: 0;
  width: 0;
}

.hide {
  display: none
}  
 <form id="preference-form" action='https://httpbin.org/post' method='post' target='response'>
  <table width='100%'>
    <tr class="result">
      <td><input type="radio" id="rad1" data-application="rad1" name="rad1" value="1"></td>
      <td><input type="radio" id="rad2" data-application="rad2" name="rad1" value="2"></td>
      <td><input type="radio" id="rad3" data-application="rad3" name="rad1" value="3"></td>
      <td><input type="radio" id="rad9" data-application="rad9" name="rad1" value="9">
      </td>
      <td class='hide'>
        <input class='dataSet' name='dataSet1' type='hidden'>
      </td>
    </tr>

    <tr class="result">
      <td><input type="radio" id="rad4" data-application="rad4" name="rad2" value="4"></td>
      <td><input type="radio" id="rad5" data-application="rad5" name="rad2" value="5"></td>
      <td><input type="radio" id="rad6" data-application="rad6" name="rad2" value="6"></td>
      <td><input type="radio" id="radA" data-application="radA" name="rad2" value="A">
      </td>
      <td class='hide'>
        <input class='dataSet' name='dataSet2' type='hidden'>
      </td>
    </tr>

    <tr class="result">
      <td><input type="radio" id="rad7" data-application="rad7" name="rad3" value="7"></td>
      <td><input type="radio" id="rad8" data-application="rad8" name="rad3" value="8"></td>
      <td><input type="radio" id="radB" data-application="radB" name="rad3" value="B"></td>
      <td><input type="radio" id="radC" data-application="radC" name="rad3" value="C">
      </td>
      <td class='hide'>
        <input class='dataSet' name='dataSet3' type='hidden'>
      </td>
    </tr>
  </table>
  <input type='submit'>

</form>
<iframe name='response'></iframe>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>  

Комментарии:

1. Как насчет 2 или более строк с переключателями? Самая большая проблема, которую я обнаружил при скрытом вводе, заключается в том, что нет способа связать data-* поле, когда отображается не более 1 строки. В моем случае каждая строка представляет приложение, а каждый столбец представляет предпочтение.

2. Обновлено еще на 2 строки