jQuery сериализует атрибуты данных HTML5

Нигде не нашел, может кто знает или подскажет.

У меня была форма с большим количеством <inputs>, я хотел отправить эту форму с функциональностью jQuery $.ajax, поэтому я сделал $('#myform').serialize() и отправил ее как json.

Теперь моя форма более продвинутая и имеет атрибуты HTML5 data-, которые я тоже хочу отправить, но .serialize() их не видит.

Пробовал помещать их в теги <form>, <input> - ничего не работает.

Как лучше всего захватить их и отправить со всеми данными формы? Я знаю о .serializeArray(), но как мне получить сериализованные все атрибуты data-, прикрепленные к моему тегу <form>?


person Sergey Telshevsky    schedule 23.08.2012    source источник
comment
Вам нужно определить, как вы ожидаете, что эти атрибуты будут сериализованы. Вы просто хотите, чтобы data-foo="bar" было сопоставлено с foo=bar ? Кроме того, есть ли какая-то причина, по которой они не могут войти во входные теги hidden?   -  person Alnitak    schedule 24.08.2012
comment
Поскольку атрибуты данных могут называться как угодно, вам также необходимо указать, какие из них вы хотите сериализовать.   -  person Mike Robinson    schedule 24.08.2012
comment
Технически - да, я хочу придумать простой способ сделать это, чтобы я мог сделать $('#myform').serialize(), и строка имела бы входные значения и значения атрибутов data-, сериализованные и экранированные. Это может быть пользовательская функция.   -  person Sergey Telshevsky    schedule 24.08.2012
comment
@MikeRobinson все атрибуты данных, если бы я хотел взять только несколько, я бы сделал это с помощью жесткого кодирования   -  person Sergey Telshevsky    schedule 24.08.2012
comment
Это, конечно, выполнимо, но остается много вопросов. Как вы будете обрабатывать повторяющиеся атрибуты данных (например, data-id=1, data-id=2) в разных элементах. Должны ли они быть отправлены в виде массива или связаны с именем элемента ввода, на котором они находились?   -  person Mike Robinson    schedule 24.08.2012
comment
@MikeRobinson никогда не слышал, что это допустимо, но в любом случае просто заставьте последний перезаписать другие. (как самый простой вариант)   -  person Sergey Telshevsky    schedule 24.08.2012
comment
Идея @Alnitak об использовании скрытых входных данных кажется мне правильным подходом.   -  person sissonb    schedule 24.08.2012
comment
@sissonb это действительно распространенное решение, которое используется уже много лет, и вопрос не в этом.   -  person Sergey Telshevsky    schedule 24.08.2012
comment
возможный дубликат: stackoverflow.com/questions/ 5560293/   -  person Nope    schedule 24.08.2012
comment
@FrançoisWahl, не могли бы вы сказать мне, где вы видите слово serialize в теме, на которую вы ссылаетесь?   -  person Sergey Telshevsky    schedule 24.08.2012
comment
@Vlakarados: Насколько я могу судить, вы пытаетесь опубликовать данные, расположенные в атрибутах данных. Вы хотите сериализовать их автоматически, что, насколько я знаю, возможно, не автоматически. Вопрос, который я связал, обсуждает проблемы с публикацией данных атрибутов данных и указывает, что скрытые поля в этом случае являются лучшим решением (а не обходным путем). Если вам не нравятся скрытые поля, вы можете применить обходной путь, написав собственную функцию для чтения каждого атрибута данных в свойство объекта, затем сериализовать этот объект и опубликовать его вместе с данными формы.   -  person Nope    schedule 24.08.2012


Ответы (3)


Вот как это можно сделать. Возможно, это не лучший способ, но он работает так, как должен работать.

http://jsfiddle.net/Bvzqe/12/

HTML:

<form id="frm" data-id="123" data-list[one]="first" data-list[two]="second">

Сериализация:

    var form = $('#frm');
    var dataarr = new Array();
    for(var i in form.data()) {
        var subarr = new Array();
        subarr['name'] = i;
        subarr['value'] = form.data()[i];
        dataarr.push(subarr);
    }
    var serialized = $.param(form.serializeArray().concat(dataarr));

Он даже позволяет вам иметь массивы data- атрибутов, таких как

data-list[one]="first" data-list[two]="second"

Закодированный URL-адрес может показаться неправильным, так как он пропускает квадратные скобки, но я проверил это на стороне сервера - он анализирует все точно так, как должен.

Это только для тех, кто не хочет использовать <input type="hidden">

person Sergey Telshevsky    schedule 24.08.2012
comment
Это работает, и это правильный путь. Я использовал такой код в нескольких вспомогательных методах. Новое расширение jQuery serializeDataArray() и метод обратной отправки AJAX, который включает в себя три части... исходная форма сериализует массив, а затем сериализует атрибуты данных как для формы, так и для исходного/обратного контроля. Не знаю, каковы правила HTML 5, но я думаю, что в большинстве случаев необходимы атрибуты данных как из (более глобальной) формы, так и из (контекстного) исходного элемента. - person Tony Wall; 17.03.2015
comment
Спасибо, что напомнили, что можно просто использовать скрытый ввод, лол. - person twan; 01.02.2021

Если это вообще возможно, вы должны хранить свои дополнительные значения как hidden полей ввода (по одному на значение), а не как метаданные в других полях ввода. Затем они будут автоматически сериализованы как часть формы.

Я не буду писать для вас сериализатор, так как считаю это плохой идеей. Если вы настаиваете на отправке значений в браузер как data- полей, вы можете сделать это, чтобы преобразовать эти data- поля в hidden входных данных.

$('#myform:input').each(function() {
    var input = this;
    $.each($(input).data(), function(key, value) {
        $('<input>', {type: hidden, name: key, value: value}).insertAfter(input);
    });
});

Эй, вуаля, скрытые поля ввода, которые будут автоматически сериализованы!

Имейте в виду, что jQuery также использует .data() для хранения таких вещей, как события. Чтобы избежать повторения этих объектов, вам придется использовать собственные функции DOM для извлечения data- атрибутов, а не каких-либо связанных с данными свойств, которые были сохранены в элементах. .

person Alnitak    schedule 23.08.2012
comment
Извините, так просто не пойдет. Это не ответ на мой вопрос, это обходной путь. - person Sergey Telshevsky; 24.08.2012
comment
@Vlakarados нет, размещение ваших данных в полях data- - это обходной путь. Использование полей hidden — это стандартный способ включения дополнительных (невидимых) данных в форму. - person Alnitak; 24.08.2012
comment
это обходной путь для моего вопроса, а не решение. Я знаю, что это стандартный способ, но я спросил, как сериализовать атрибуты data-, а не «как скрыть данные от отображения на экране». Скрытые вводы были придуманы только потому, что тогда не было ни js, ни ajax. Для проекта с высокой нагрузкой запись <input type="hidden" name="key" value="value"> вместо `data-key=value` требует большей пропускной способности и большего времени загрузки. И я даже не говорю о простоте манипулирования такими данными в JS. - person Sergey Telshevsky; 24.08.2012
comment
@Vlakarados да, это то, что я называю обходным путем. Вы изобрели схему хранения дополнительной информации в форме (из-за незначительных опасений по поводу времени загрузки страницы), которая не поддерживается тегами W3C <form>, а затем жалуетесь, когда средства сериализации этих данных не работают. не существует?! Скрытые поля были изобретены не потому, что не было AJAX, они были изобретены потому, что именно так вы предоставляете дополнительную информацию в форме! - person Alnitak; 24.08.2012
comment
@Vlakarados и FWIW, я мог бы тривиально написать то, что вам нужно - это было бы около дюжины строк кода. Но ИМХО было бы бесполезно так делать. Вы сами создаете проблему без веской причины. - person Alnitak; 24.08.2012
comment
Должен согласиться с @Alnitak, пропускная способность, создаваемая дополнительными входами, невероятно тривиальна. Скрытые входы также будут работать независимо от того, включен (или не работает) javascript. - person Mike Robinson; 24.08.2012
comment
Хорошо, ребята, я задал нормальный вопрос - как я могу сериализовать атрибуты данных. Как вы думаете, являются ли скрытые входы ответом на этот вопрос? Я также упомянул, что провел исследование по этой теме, и оно нигде не освещено. - person Sergey Telshevsky; 24.08.2012
comment
@Vlakarados разве вы не понимаете, что причина, по которой это нигде не освещается, заключается в потому что это не очень хорошая идея! - person Alnitak; 24.08.2012
comment
@Alnitak Я уверен, вы слышали о других фреймворках, таких как Knockout.js, которые в основном используют атрибуты данных даже для базовых вещей. Что, если в моем текущем проекте вся система внешнего интерфейса основана на этих атрибутах, должен ли я все переписать и использовать входные данные? Я понимаю вашу точку зрения, правда понимаю, но я не спрашивал, хорошая это идея или нет, я не спрашивал, какие существуют другие возможности. - person Sergey Telshevsky; 24.08.2012
comment
@Vlakarados: Ваш вопрос был What is the best practice to grab them and send with all the form data?. Ответ — скрытые поля. Но вы можете применить обходной путь и самостоятельно перебрать все атрибуты данных и создать объект для отправки вместе с сообщением формы. Или используйте фреймворк, если он существует, который сделает это за вас. Если вы найдете его, опубликуйте его как ответ, так как он определенно поможет другим в будущем. - person Nope; 24.08.2012
comment
@Vlakarados, конечно, для data- атрибутов и свойств есть множество применений. Их использует Knockout.js, их использует jQuery. Использование их для хранения данных формы не является для них допустимым вариантом использования! Сам факт того, что эти фреймворки используют их, является еще одной причиной для вас не делать этого! - person Alnitak; 24.08.2012
comment
Спасибо за правку, это не то, что я хотел увидеть, но это ЯВЛЯЕТСЯ ответом на мой вопрос, так что, конечно, спасибо и за голосование. - person Sergey Telshevsky; 24.08.2012
comment
@Vlakarados, вы должны заметить, что я не получаю за это никакой репутации - я уже достиг дневного лимита. Я прилагаю столько усилий, потому что серьезно считаю, что ваша текущая реализация неверна. - person Alnitak; 24.08.2012
comment
Поэтому я тоже спорю, надеюсь, вы не обижаетесь - person Sergey Telshevsky; 24.08.2012
comment
Здесь я должен быть на стороне Сергея. Я сейчас сталкиваюсь с тем же вызовом. Несмотря на то, что использование скрытых элементов ввода считается стандартным, де-факто способом добавления дополнительных данных к форме, большая проблема, присущая этому методу, заключается в том, что больше нельзя связать значения data-* с конкретным элементом формы. Другими словами, после сериализации вы получите плоскую карту, структура которой не представляет ассоциаций. Что я, вероятно, собираюсь сделать, так это написать свой собственный сериализатор, который создает дерево JSON формы. - person Aquarelle; 13.05.2014

вот моя функция, получить все данные-* элемента + поддержка массива игнорирования

Data2Params: function (el, ignoredAtt) {
    ignoredAtt = typeof ignoredAtt !== 'undefined' ? ignoredAtt : [];

    var data = {};
    for (var key in el.data()) {
        if (ignoredAtt.indexOf(key) === -1)
            data[key] = el.data(key);
    }
    return data;
}
person dobs    schedule 01.08.2018