Ignore

Please note that your browser is not supported.

We recommend upgrading to the latest Firefox or Google Chrome.

Frontend: Forms

Forms are used to submit user input from the frontend interface to the backend of an application. When the backend receives user input, it's handed off to an action that validates the input and handles it appropriately. Invalid input might cause the action to present errors back to the user, while valid input might lead to data being created or updated in your application's database.

Defining forms

In most cases, a form submits values for particular type of data defined in your application. To define a form, add a binding to a form tag with the data type the form is submitting values for:

<form binding="message">
  ...
</form>

Pakyow automatically sets the action and method attributes on the form based on what context the form is used in. For new objects, the form is setup to create the object. For existing objects, the form is instead setup to update the object.

Here's what the above form would look like after Pakyow sets it up for creating a message:

<form action="/messages" method="post">
  ...
</form>

You can also manually define the endpoint for the form, which is discussed in the frontend endpoint guide.

Defining form fields

Form fields are added to a form to provide specific values for the form's data type. Here we define two fields along with a button that submits the form when clicked. The first field submits the title of the message, while the second field submits the message content:

<form binding="message">
  <div class="form-input">
    <input type="text" binding="title">
  </div>

  <div class="form-input">
    <textarea binding="content"></textarea>
  </div>

  <input type="submit" value="Save Message">
</form>

Pakyow automatically presents existing values in the form fields just like it does for other bindings.

How Pakyow names form fields

You may notice that the above example doesn't explicitly set the name attribute on the form fields. Pakyow hooks this up for you so that the backend receives data in a consistent manner. Here's how the fields will be named:

<form action="/messages" method="post">
  <div class="form-input">
    <input type="text" name="message[title]">
  </div>

  <div class="form-input">
    <textarea name="message[content]"></textarea>
  </div>

  <input type="submit" value="Save Message">
</form>

The backend can access submitted values through the params[:message] helper.

In some cases you may want to control how the field is named. You can do this by naming a form input yourself:

<div class="form-input">
  <input type="text" name="my_title" binding="title">
</div>

Pakyow will submit the value as my_title, but will still present the existing title value in the form field.

Connecting labels to fields

Labels are an important way to improve the accessibility of your forms. Connecting a label to its field can be a challenge, especially for dynamic forms. Fortunately, Pakyow takes care of connecting labels to your forms fields for you. All you need to do is point the for attribute of the label to the binding of the form field.

Here's an example:

<form binding="message">
  <div class="form-input">
    <label for="title">Title:</label>
    <input type="text" binding="title">
  </div>

  <div class="form-input">
    <label for="content">Content:</label>
    <textarea binding="content"></textarea>
  </div>

  <input type="submit" value="Save Message">
</form>

Pakyow matches everything up, resulting in a rendered view that looks like this:

<form action="/messages" method="post">
  <div class="form-input">
    <label for="e2n5">Title:</label>
    <input type="text" name="message[title]" id="e2n5">
  </div>

  <div class="form-input">
    <label for="9szk">Content:</label>
    <textarea name="message[content]" id="9szk"></textarea>
  </div>

  <input type="submit" value="Save Message">
</form>

The field ids are randomly generated and added to the field's related label. That's all there is to it!

Handling form errors

Pakyow provides a form-errors component that attaches error handling behavior to your forms. If the submitting values don't pass the verification and validation process on the backend, the form will automatically be re-rendered with error messages for the user.

You can attach the form-errors component to an element in your form using the ui attribute like this:

<form binding="message">
  <ul class="form-errors" ui="form-errors">
    <li binding="error.message">
      Error message goes here.
    </li>
  </ul>

  <div class="form-input">
    <label for="title">Title:</label>
    <input type="text" binding="title">
  </div>

  <div class="form-input">
    <label for="content">Content:</label>
    <textarea binding="content"></textarea>
  </div>

  <input type="submit" value="Save Message">
</form>

Your form errors element should include a binding within it that defines the error binding type along with a message binding attribute. This is where specific error messages will be presented for the user.

For example, let's assume that both fields in the above form are required. If the user submits the form form without providing values, the form would be re-rendered with errors like this:

<form action="/messages" method="post">
  <ul class="form-errors">
    <li>
      Title cannot be blank
    </li>

    <li>
      Content cannot be blank
    </li>
  </ul>

  <div class="form-input">
    <input type="text" name="message[title]">
  </div>

  <div class="form-input">
    <textarea name="message[content]"></textarea>
  </div>

  <input type="submit" value="Save Message">
</form>

In some cases you may not want to present specific errors. A good example is a sign in form, where you want to tell the user that their sign in failed but don't want to tell them exactly why. You can handle errors like this by defining the form-errors component within an error binding:

<form binding="message">
  <div class="form-errors" ui="form-errors">
    The values you provided were invalid.
  </div>

  ...
</form>

When Pakyow re-renders the errored form, it will only show the component and not try to populate it with specific error messages.

Styling form errors

Pakyow leaves it to you to style form errors to match the look and feel of your application. However, it does add the ui-hidden helper class to the form-errors element when the form is in a non-errored state:

<form binding="message">
  <div class="form-errors ui-hidden" ui="form-errors">
    The values you provided were invalid.
  </div>

  ...
</form>

It's recommended that you define styles for this helper class to hide elements with the ui-hidden class:

.ui-hidden {
  display: none;
}

Styling errored fields

When Pakyow renders a form with errors, it renders each invalid field in an errored state as well. Each field that has an error will receive a ui-errored class. You can define your own styles to indicate errored fields to your users.

Pakyow also adds the error message for the field to the field's title attribute. This is useful if you want to present tooltips or other callouts to each field rather than present errors at the top of the form.

Here's what an errored field looks like:

<div class="form-input">
  <input type="text" name="message[title]" class="ui-errored" title="Title cannot be blank">
</div>

Styling errored forms

Just like errored fields, errored forms will receive the ui-errored class.

<form action="/messages" method="post" class="ui-errored">
  ...
</form>

Submitting forms in the background

Pakyow includes a form component you can use to integrate your forms with other frontend behavior, such as the navigator component. This allows form submissions to happen in the background rather than require a full page reload, making your forms more feel more responsive to end users.

You can attach the form component to your form using the ui attribute like this:

<form binding="message" ui="form">
  ...
</form>

Pakyow will take care of including the necessary JavaScript as an asset pack.

Protecting from cross-site forgery

Pakyow protects your forms with built in cross-site forgery protection. It does this by rendering the form with a special token tied to the user's session. When submitted, the token value is checked for authenticity. If it's authentic, the form submission is allowed in to the backend application. Otherwise, the form submission will be rejected and an errored response will be sent back down to the web browser.

Next Up: Page Titles