npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

flood-simple-form

v0.2.4

Published

The Data Down, Actions Up form builder with ember-changeset and validations

Downloads

16

Readme

flood-simple-form Build Status Ember Observer Score

The DDAU (Data Down, Actions Up) form builder we use at Flood IO. It's based on a lot of great work by others in the Ember community, but we felt we needed something more flexible and slightly less opinionated about how data is persisted.

The basic principle behind this is to borrow a similar syntax to Simple Form from the Rails world, and apply an intermediate change layer using ember-changeset.

The inputs themselves are all DD,AU. When a change occurs it fires an action which propagates that change up to the form component, where the value is assigned to the changeset, which also fires the validations so you get realtime feedback as fields change.

When the form is submitted, you can choose how you persist the changeset, but typically you would just call changeset.save().

Form lifecycle

flood-simple-form is implemented with certain life cycle behaviours, designed to provide a consistent user experience.

To start, create a form and supply a changeset as the first argument. The underlying model can be an Ember.Object, DS.Model or POJO, and on submit all changes will be applied to this object if the changeset is valid.

Assuming user has an email property:

{{#simple-form (changeset user (action "validate") as |f|}}
  {{f.input "email" placeholder="[email protected]" label="Email Address"}}
{{/simple-form}}

flood-simple-form supports errors from ember-changeset, so you can easily propagate errors from the server and client side validations.

If the action handling on-submit returns a promise, the form will disable all inputs while the promise resolves, re-enabling everything regardless of the outcome of the promise. This is useful to ensure a form is only submitted once, and ensuring consistency while changes are persisted.

export default Ember.Controller.extend({
  actions: {
    saveChanges(changeset) {
      return changeset.save();
    }
  }
});

Installation

ember install flood-simple-form

Requires Ember 2.4+.

Usage

{{#simple-form 
  (changeset user (action "validate"))
  on-submit=(action "createUser") as |f|}}

  {{f.input "email" placeholder="[email protected]" label="Email Address"}}
  {{f.input "fullName" placeholder="John Smith" label="Full Name"}}
  {{f.input "country" label="Country" as="collection" collection=countries labelPath="name" valuePath="isoCode"}}
  
  {{f.submit "Create User"}}
{{/simple-form}}
export default Controller.extend({
	actions: {
		validate({key, newValue}) {
			// Validation logic, must return `true` or an error message.
		},
		
		createUser(changeset) {
			return changeset.save().catch(() => {
				get(this, 'model.errors').forEach(({ attribute, message }) => {
					changeset.addError(attribute, { validation: message });
				});
			})
		}
	}
});

simple-form

This is the main <form> constructor. It accepts an initial form values object/model to populate each form field. This is the initial value per form submission cycle, as mentioned in the lifecycle section above.

Actions

  • on-submit: Fires when form is submitted, either by submit button or other enter key press. The first parameter sent to the action handler is an object containing only the changed attributes.
  • on-change: Fires when any form value changes. The supplied paramters are the attr which changed, and its current value.

Form Controls

Type | HTML form | Additional attributes --- | --- | --- boolean | <input type="checkbox" /> | isInputFirst:<boolean> indicates whether the input comes before the label. collection | <select> | multiple=<boolean> indicates whether the input should be rendered as a list with multiple selection. date | <input type="date" /> | email | <input type="email" />| number | <input type="number" />| password | <input type="password" />| ~~checkboxes~~ | ~~TBD collection of <input type="radio" /> with labels~~ | string | <input type="text" />| text | <textarea> |

Each form input renders the following markup:

<div class="ember-view SimpleForm-input email">
  <label for="ember431-input">Email Address</label>
  <div class="SimpleForm-field">
    <input id="ember431-input" placeholder="[email protected]" type="text" class="ember-view ember-text-field">
    <p class="SimpleForm-hint">Your email address</p>
  </div>
</div>

Error messages are rendered above hints, and an invalid class is added to the input container.

Working with validations

Please refer to the dummy app for a complete implementation of validations

flood-simple-form will automatically display any errors which are present on your data model's errors attribute, as long as they conform to a standard format similar to DS.Errors, where the errors object contains a key for each attribute which has messages, with the value as an array of messages. e.g.

const User = Ember.Object.extend({
  email: null,

  errors: {
    email: ["can't be blank", "must look like an email address"],
  }
});

Custom Form Controls

flood-simple-form is flexible enough to allow custom form components, as long as they behave like all others.

To load a custom component, put it in app/components/simple-form/inputs/custom-input.js. You can then use it by specifying the type attribute as custom:

{{f.input "creditCard" type="custom" placeholder="This will be sent as an attribute to custom-input"}}

Any additional attributes you set on input will be passed down to your custom component.

In order for your component to supply changes back up to the form, it must send an on-change action when there are changes, with the new value as the first parameter.

Running

Running Tests

  • npm test (Runs ember try:each to test your addon against multiple Ember versions)
  • ember test
  • ember test --server

Building

  • ember build

For more information on using ember-cli, visit http://ember-cli.com/.