Статьи

Работа с формами в Griffin.Yo — библиотека SPA в TypeScript

Я выпустил новый выпуск, который включает в себя средство чтения форм С помощью нескольких строк кода вы можете получить полный объект JSON, включая иерархию, из формы HTML.

При создании спа вы, как правило, не хотите, чтобы формы отправлялись в виде обычного http-запроса, поскольку это противоречило бы цели спа. Поскольку вы уже работаете с ajax и JSON, почему бы не использовать его и для отправки форм? Теперь это возможно в Griffin.Yo .

Начните с объявления простой формы:

<form id="MyForm">
    <div>
        <label>First name:</label>
        <input name="FirstName" value="Jonas">
    </div>
    <div>
        <label>Last name:</label>
        <input name="LastName" value="Gauffin">
    </div>
</form>

Чтение осуществляется с помощью класса FormReader:

var form = new FormReader("MyForm");
var dto = form.read();

// .. or in your view model:
var dto = ctx.readForm("MyForm");

Возвращенный результат является документом json:

{
    "FirstName": "Jonas",
    "LastName": "Gauffin"
}

Радио-кнопки

Радиокнопки добавляются в документ JSON только в том случае, если они отмечены, т. Е. Все остальные параметры игнорируются:

<form id="MyForm">
    <label>Mood</label>
    <input type="radio" name="Mood" value="Rocking"> Rocking
    <input type="radio" name="Mood" value="Tired" checked> Tired
    <input type="radio" name="Mood" value="Excited"> Excited
</form>

.. результаты в ..

{
    "Mood": "Tired"
}

Флажки

То же самое относится к флажкам:

<form id="MyForm">
    <label>Moods</label>
    <input type="checkbox" name="Moods" value="Rocking"> Rocking
    <input type="checkbox" name="Moods" value="Tired" checked> Tired
    <input type="checkbox" name="Moods" value="Excited" checked> Excited
</form>

.. результаты в ..

{
    "Moods": ["Tired", "Excited"]
}

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

Коллекции

Коллекции, как правило, трудно обрабатывать в формах HTML, поскольку в спецификации HTML нет ничего, что указывало бы, как их обрабатывать. В этой реализации они представлены атрибутом «сбор данных».

Если вы работаете с коллекциями, которые имеют одно значение, вы используете специальное имя ввода «[]», чтобы указать это. Пример следует:

<form id="MyForm">
    <div data-collection="Brands">
        <label>Your favorite brands</label>
        <p>In reality you and new inputs using javascript and a button. Just imagine that it's been done here.</p>
        <input name="[]" value="Headlight" />
        <input name="[]" value="OneTrueError" />
        <input name="[]" value="Griffin.Framework" />
    </div>
</form>

Что приводит к:

{
    "Brands":["Headlight","OneTrueError","Griffin.Framework"]
}

Но если ваша коллекция содержит сложные объекты, вы просто указываете названия элементов:

<div data-collection="Addresses">
    <label>Enter your addresses</label>
    <input name="Street" value="Here1" />
    <input name="City" value="Falun" />
    <input name="Street" value="Here2" />
    <input name="City" value="Stockholm" />
</div>

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

Результат:

{
    "Addresses": [{
        "Street": "Here",
        "City": "Falun"
    }, {
        "Street": "Here2",
        "City": "Stockholm"
    }]
}

Сложные объекты

То же самое касается сложных объектов. В спецификации HTML нет ничего. С этой библиотекой у вас есть два варианта.

Первый вариант — включить <div data-name="SubObjectName">обертку для подобъекта:

<form id="MyForm">
    <div>
        <label>First name:</label>
        <input name="FirstName" value="Jonas">
    </div>
    <div>
        <label>Last name:</label>
        <input name="LastName" value="Gauffin">
    </div>
    <div data-name="Address">
        <h2>Address</h2>
        <label>Street:</label>
        <input name="Street" value="Awesome street"><br>
        <label>Postal code:</label>
        <input name="PostalCode" value="12345"><br>
        <label>City:</label>
        <input name="City" value="Falun"><br>
    </div>
</form>

.. который будет генерировать следующий JSON:

{
    "FirstName": "Jonas",
    "LastName": "Gauffin",
    "Address": {
        "Street": "Awesome street",
        "PostalCode": 12345,
        "City": "Falun"
    }
}

Второй вариант заключается в использовании точечной нотации во входных именах:

<div>
    <h2>Address</h2>
    <label>Street:</label>
    <input name="Address2.Street" value="Awesome street"><br>
    <label>Postal code:</label>
    <input name="Address2.PostalCode" value="12345"><br>
    <label>City:</label>
    <input name="Address2.City" value="Falun"><br>
</div>    

.. который даст вам тот же результат.

Обработка значений

Все значения анализируются. Например, строковые значения «истина» и «ложь» преобразуются в логическое значение JSON. Строки, содержащие числа, преобразуются в числа JSON. Все остальное рассматривается как строки.

Резюме

Код доступен на github .