Как SerializeArray() HTML-теги, которые находятся внутри формы, которые также должны быть сериализованы?

Я создаю форму, которая позволяет пользователям отправлять информацию на сайт для публикации. Я использую комбинацию встроенного редактирования с помощью contenteditable=true на редактируемые теги HTML, и я также использую стандартные формы ввода, такие как выборки и текстовые поля.

Когда пользователь отправляет форму, я хочу, чтобы это происходило через Ajax. Я понимаю, как сериализовать саму форму, но я не понимаю, как также сериализовать элементы HTML, которые имеют contenteditable=true установить одновременно, чтобы все это отправлялось на сервер в одном комплекте.

Вот пример кода HTML:

<form action="/path/to/server/file" enctype="multipart/form-data">
<!--- Start WYSIWYG Inline Editing  --->
  <div id="ItemContainer">
    <h1 id="ItemTitle" contenteditable="true">A title would go here</h1>
    <h2 id="ItemSubtitle" contenteditable="true">A subtitle here</h2>
    <div id="ItemMainBody" contenteditable="true">
      <p>Integer condimentum sit amet, tempor elit odio, a dolor non ante at sapien. Sed ac lectus. Nulla ligula quis eleifend mi, id leo velit pede cursus arcu id nulla ac lectus. Phasellus vestibulum. Nunc viverra enim quis diam.</p>
      <p>Donec ullamcorper, risus tortor, pretium porttitor. Morbi quam quis lectus non leo.</p>
      <img src="/path/to/imagefile" /> 
    </div>
  </div>
<!--- End WYSIWYG Inline Editing. Standard Form elements follow... --->
  <select name="ItemCategory" id="ItemCategory">
    <option value="1">Planes</option>
    <option value="2">Trains</option>
    <option value="3">Automobiles</option>
  </select>
  <input type="text" name="ItemURL"  id="ItemURL">
<input type="submit" name="Submit" id="Submit" value="Submit"/>
</form>

Чтобы отправить это через ajax, я бы сделал это сейчас:

('form').submit(function (e) {
        $.ajax({
            type: 'post',
            url: '/path/to/formprocessor',
            data: $('form').serializeArray(), // serializing the form
            dataType: "json",
            done: function (result) {
               // tell user its done!
            },
            error: function (result) {
                alert("An error has occured.");
            }
        });
        e.preventDefault();
    });

Как также сериализовать элементы HTML, чтобы все передавалось вместе? Я хотел бы, чтобы идентификатор contenteditable элемента представлял его имя. Так что в POST я хотел бы видеть:

ItemCategory    1
ItemTitle   A title would go here
ItemSubtitle A subtitle here
ItemURL http://www.com
ItemMainBody <p>Integer condimentum sit amet, tempor elit odio, a dolor non ante at sapien. Sed ac lectus. Nulla ligula quis eleifend mi, id leo velit pede cursus arcu id nulla ac lectus. Phasellus vestibulum. Nunc viverra enim quis diam.</p>
      <p>Donec ullamcorper, risus tortor, pretium porttitor. Morbi quam quis lectus non leo.</p>
      <img src="/path/to/imagefile" /> 

2 ответа

В этом случае вам придется вручную добавить параметры в массив перед отправкой, вот код JS:

('form').submit(function(e) {
  var formToSubmit = e.target;
  var serialisedFormArrayObject = $(formToSubmit).serializeArray();
  var $contentEditableItems = $("[contenteditable=true]");
  $contentEditableItems.each(function(index) {
    serialisedFormArrayObject.push({
      name: $contentEditableItems[index].id,
      value: $contentEditableItems[index].innerHTML
    });
  });
  $.ajax({
    type: 'post',
    url: '/path/to/formprocessor',
    data: serialisedFormArrayObject,
    dataType: "json",
    done: function(result) {
      // tell user its done!
    },
    error: function(result) {
      alert("An error has occured.");
    }
  });
  e.preventDefault();
});

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

Чтобы избежать html-строки, вам нужно использовать встроенный в Javascript метод encodeURIComponent. Так, например, если у вас есть:

console.log(encodeURIComponent("<div>potato</div>"));

Вы получите: %3Cdiv%3Epotato%3C%2Fdiv%3E В зависимости от языка, который вы используете на стороне сервера, вы можете затем декодировать его обратно.

Будьте внимательны, позволяя пользователям вводить script тег, поскольку это может привести к атакам межсайтового скриптинга (XSS)

Так что вам нужно будет изменить строку

data: $(this).serializeArray(), // сериализация формы

к

data: encodeURIComponent($(this).serializeArray()), // serializing the form

Наконец, если вы хотите, чтобы форма была представлена ​​в виде строки запроса, а не в качестве содержимого формы, вам нужно будет установить глагол в GET вместо POST

Пытаться

$("form").click(function (e) {
    e.preventDefault();
    $("#ItemURL").val(location.href);
    var res = $(this).serializeArray(); // serializing the form
    // `serialize` `ItemContainer` elements to `{name:value}` pairs
    $("#ItemContainer *[id^=Item]")
    .each(function(i, el) {
        var j = {};
        j.name = el.id;
        j.value = $.trim(el.innerHTML);
        res.push(j)
    });
    $.ajax({
        type: "POST",
        url: "/echo/json/",
        data: {json:JSON.stringify(res)}, 
        dataType: "json",
        // substitute `success` for `done` _within_ `ajaxSettings` ,
        // utilize `.done` or `.then` _after_ , 
        // i.e.g., `$.ajax({}).done()` , `$.ajax({}).then()`
        success: function (result) {  
                // tell user its done!
                $("pre").text(JSON.stringify(result, null, 4))                   
            },
            error: function (result) {
                alert("An error has occured.");
            }
        });
    });

jsfiddle http://jsfiddle.net/guest271314/3zn4Lbab/

Другие вопросы по тегам