elclanrs / jq-idealforms-old

The ultimate framework for building and validating responsive HTML5 forms.
665 stars 95 forks source link

Ideal Forms logo

Check out Ideal Forms 3! Ideal Forms 2 is no longer supported.

Ideal Forms is the ultimate framework for building and validating responsive HTML5 forms.

Features:

Updates:

02/26/13

Update history

Videos:

FAQ:

Help:

Table of contents:

Setup:

<!--[if IE 8]> <html class="ie8" lang="en"> <![endif]-->
<!--[if IE 9]> <html class="ie9" lang="en"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html lang="en"> <!--<![endif]-->
var $myform = $('#my-form').idealforms({ options }).data('idealforms');

Markup:

For Ideal Forms to work its magic create your markup using the following template as a reference, nothing fancy, just the usual form tags wrapped in a <div>. Drop the form into a container of any size and Ideal Forms will do the rest.

<form id="my-form">

  <!-- TAB -->
  <section name="First tab">

    <!-- Heading -->
    <div>
      <h1>My Heading</h1>
      <p>Description here</p>
    </div>

    <!-- Text -->
    <div><label>Username:</label><input type="text" name="username"/></div>
    <div><label>Date:</label><input type="text" name="date" class="datepicker" placeholder="mm/dd/yy"/></div>
    <div><label>Comments:</label><textarea name="comments"></textarea></div>

    <!-- File -->
    <div><label>File Upload:</label><input type="file" multiple name="file"/></div>

    <!-- Select -->
    <div>
      <label>Colors:</label>
      <select name="colors">
          <option value="default">Choose a color</option>
          <option value="Red">Red</option>
          <option value="Blue">Blue</option>
          <option value="Green">Green</option>
      </select>
    </div>

  </section> <!-- END TAB -->

  <!-- TAB -->
  <section name="Second tab">

    <div>
      <h1>My Heading</h1>
      <p>Description here</p>
    </div>

    <!-- Checkbox -->
    <div>
      <label>Languages:</label>
      <label><input type="checkbox" name="langs[]" value="English"/>English</label>
      <label><input type="checkbox" name="langs[]" value="Chinese"/>Chinese</label>
      <label><input type="checkbox" name="langs[]" value="Spanish"/>Spanish</label>
    </div>

    <!-- Radio -->
    <div>
      <label>Options:</label>
      <label><input type="radio" name="options" value="One"/>One</label>
      <label><input type="radio" name="options" value="Two"/>Two</label>
      <label><input type="radio" name="options" value="Three"/>Three</label>
    </div>

  </section> <!-- END TAB -->

  <!-- Separator -->
  <div><hr/></div>

  <!-- Buttons -->
  <div>
    <button type="submit">Submit</button>
    <button id="reset" type="button">Reset</button>
  </div>

</form>

The name attribute will be used in the plugin's options to add filters to each input. This provides a lot of flexibility and the possibility to create custom errors, and tweak the filter's values.

Alternatively, for very simple forms, you can do it "the easy way" and just add the filters to the data-ideal attribute.

<form id="my-form">
  <div><label>Username:</label><input type="text" name="username" data-ideal="required username"/></div>
  <div><label>Password:</label><input type="text" name="password" data-ideal="required pass"/></div>
  <div><label>E-Mail:</label><input type="text" name="email" data-ideal="required email"/></div>
</form>

Notes:

Options:

inputs

Add all the inputs you want to validate here. Use the name attribute of the input as key. To be consistent always put the key in quotes. Array group names can be used too, ie. name[].

inputs: {
  // The name attribute of the input in quotes
  'myinput': {
    filters: 'required min',
    data: { min: 10 },
    errors: { min: 'At least 10 characters' },
    flags: 'noclass noinvalidicon'
  }
}

globalFlags

List the flags that you want to apply to all inputs.

globalFlags: 'noerror noicons'

onSuccess

onSuccess: function(e) {
  // Form validates
}

onFail

onFail: function(){
  // Form does NOT validate
}

responsiveAt

By default, Ideal Forms will make the form "adaptive". It will adapt to the container allowing it to work with any responsive grid system. You can change this behavior by assigning a number value to the responsiveAt option.

// Make responsive only at a certain window size.
// Default is `"auto"` to adapt to the container
// Set to `false` to disable responsiveness
// To always show the responsive layout use a large number ie `3000`
responsiveAt: 480

disableCustom

Disables custom inputs and uses system default so you can use other replacement plugins.

disableCustom: 'file select radiocheck button'

Filters:

required

The field is required. This filter ONLY works with text inputs (text, password, textarea). For select use exclude to exclude the default option. For radio and checkbox use min: 1 which will require at least one option to be checked.

number

Must be a number.

digits

Only digits.

range

Only numbers within a range. Usually combined with number or digits.

'myinput': {
  filters: 'number range',
  data: { range: [ 1, 100 ] }
}

name

Must be at least 3 characters long, and must only contain letters.

username

Must be between 4 and 32 characters long and start with a letter. You may use letters, numbers, underscores, and one dot (.)

pass

Must be at least 6 characters long, and contain at least one number, one uppercase and one lowercase letter.

strongpass

Must be at least 8 characters long and contain at least one uppercase and one lowercase letter and one number or special character.

email

Must be a valid e-mail address.

phone

Must be a valid US phone number.

zip

Must be a valid US zip code.

url

Must be a valid URL.

date

Must be a valid date. This filter effectively validates a date, so stuff like 02-31-2012 or 30/80/2000 would be invalid. You can use any format with 4 digit year and any delimiter character. The default format is mm/dd/yyyy.

'myinput': {
  filters: 'date',
  data: { date: 'dd-mm-yyyy' } // or `yyyy~dd~mm` or `mm*yyyy*dd`
}

To use the datepicker you need to load jQuery UI and add the class datepicker to your date input. Ideal Forms will apply the custom format that you specify without having to configure the datepicker. It's seamless.

dob

Must be a valid date of birth in this century, that is 100 years range from the current year.

'myinput': {
  filters: 'dob',
  data: { dob: 'yyyy/dd/mm' }
}

min

'myinput': {
  filters: 'min',
  data: { min: 10 }
}

max

'myinput': {
  filters: 'max',
  data: { max: 10 }
}

exclude

'myinput': {
  filters: 'exclude',
  data: {
    // Always an array even if just one value
    // Values are case-sensitive
    exclude: ['one', 'two', 'three']
  }
}

equalto

The value must match a value of another input.

'myinput': {
  filters: 'equalto',
  data: { equalto: '#myid' } // You can use any valid jQuery selector
}

extension

This filter is designed for file inputs. It supports multifile in HTML5 browsers.

'myinput': {
  filters: 'extension',
  data: { extension: [ 'jpg', 'png' ] } // Always array even if just one
}

ajax

Validate a response from the server. The ajax filter must be added at last after all other filters.

This method is a light wrapper around $.ajax, so any parameter valid in jQuery's $.ajax is also valid in Ideal Forms' ajax except success and error because they are set up automatically but you can use _success and _error instead.

In most cases passing the url should be enough. The server will receive the value of the input in $_POST[inputname]. The default dataType is json. Ideal Forms handles success and error from the server. The field will switch to loading status if the response takes some time to come back. Here's an example in PHP:

validate.php

<?php
$usernames = array('mike', 'john', 'louis', 'james'); // Unavailable usernames, usually from a database
sleep(2); // Simulate delay from the server to see loading status
echo json_encode(!in_array($_POST['username'], $usernames));

JavaScript:

'username': {
  filters: 'required username ajax',
  data: {
    ajax: {
      url: 'validate.php',
      _success: function( resp, text, xhr ) {
        // The request was succesful
      },
      _error: function( xhr, text, error ) {
        // The request failed
      },
      // Other $.ajax methods
    }
  },
  errors: {
    ajax: {
      success: 'Username not available.',
      error: 'Sorry, there was an error on the server. Try again later.'
    }
  }
}

Flags:

Flags are custom functions that you can run on an input whenever a validation event is triggered.

Adding custom filters and flags:

Ideal Forms registers global objects for filters and flags so you can extend it with your own custom object to add more features.

Custom filters:

$.extend( $.idealforms.filters, {
  custom: {
    regex: /regularexpression/,
    error: 'My custom error'
  },
  another: {
  /**
   * @param {Object} inputData Contains the jQuery input as [input] and
   * the user options set by the user on that input as [userOptions]
   * @param {String} value The value of the input
   */
    regex: function ( inputData, value ) {
      var $input = inputData.input
      var userOptions = inputData.userOptions
      var this.error = 'Something ' + value
    }
  }
})

Custom flags:

$.extend( $.idealforms.flags, {
  /**
   * @param {jQuery} input jQuery input object
   * @param {String} event The event that was triggered on the input: focus, blur, change, keyup
   */
  custom: function( input, event ){
    if ( event === 'keyup' ) {
      console.log( input.val() )
    }
  }
})

Methods:

setOptions

Override the options of the form after being initialized.

chainable: yes

var myOps = {
  onFail: function() { // override onFail option
    alert('It failed!')
  },
  inputs: {
    'number': { filters: 'number' } // add new input to validate
  }
}
$myform.setOptions( myOps )

All options are exposed on $myform.opts so you can manually edit them if needed. Make sure to reload the form when doing this.

Note: The disableCustom option cannot be modified after initialization.

setFieldOptions

Override the options of a particular field.

chainable: yes

$myform.setFieldOptions( 'username', { filters: 'username' } )

isValid

Check if the form is valid.

chainable: no

if ( $myform.isValid() ) {
  // do something...
}

isValidField

Check if a particular field is valid. The function takes a string. Ideal Forms will look for the name attribute first and then for the id. You can use array group names for groups of checkboxes.

chainable: no

if ( $myform.isValidField('username') ) { // name="username" OR #username
  // do something...
}
if ( $myform.isValidField('colors[]') ) { // name="colors[]"
  // do something...
}

getInvalid

Get all invalid fields. Returns a jQuery object.

chainable: yes (but it doesn't return the form, just the invalid fields)

var numInvalid = $myform.getInvalid().length // How many invalid fields

getInvalidInTab

Get all invalid fields within a tab.

chainable: yes (but it doesn't return the form, just the invalid fields)

var numInvalidTab = $myform.getInvalidInTab('My Section').length

addFields

Add fields to the form dynamically. It takes an array of objects or a single object. Ideal Forms auto-generates the markup for inputs fields based on the type specified.

chainable: yes

var newFields = [
  {
    name: 'animals',
    label: 'Animals',
    type: 'radio',
    list: ['Dog', 'Elephant', 'Crocodile', 'Spider'],
    addAfter: 'email'
  },
  {
    name: 'zip',
    label: 'Zip Code',
    filters: 'required zip',
    type: 'text',
    addBefore: 'password'
  },
  {
    name: 'instruments',
    label: 'Instruments',
    filters: 'exclude',
    data: { exclude: ['default'] },
    errors: { exclude: 'Please select an instrument' },
    type: 'select',
    list: [
      'Select an instrument::default',
      'Piano::pia',
      'Violin::vio',
      'Guitar::gui'
    ],
    appendToTab: 'My Section'
  }
]
$myform.addFields( newFields )

removeFields

Remove fields from the form dynamically. Ideal Forms will look for the name attribute first and then id.

chainable: yes

$myform.removeFields('username')
$myform.removeFields([ 'username', 'password', 'email' ])

toggleFields

Hide or show fields. When the fields are hidden they will be excluded from the validation process.

$myform.toggleFields('username')
$myform.toggleFields([ 'username', 'password', 'email' ])

focusFirst

Focus the very first field. If there are tabs it will focus the very first field within the current tab.

chainable: yes

$myform.focusFirst()

focusFirstInvalid

Focus the first invalid field.

chainable: yes

$myform.focusFirstInvalid()

switchTab

Change tab by name or index.

chainable: yes

$myform.switchTab('My Section') // case insensitive
$myform.switchTab(2) // zero based index

nextTab

Go to next tab.

chainable: yes

$myform.nextTab()

prevTab

Go to previous tab.

chainable: yes

$myform.prevTab()

firstTab

Go to first tab.

chainable: yes

$myform.firstTab()

lastTab

Go to last tab.

chainable: yes

$myform.lastTab()

reset

Reset all fields to zero including checkboxes, radios, and selects.

chainable: yes

$myform.reset() // Reset all

resetFields

Reset particular fields.

chainable: yes

$myform.resetFields('username')
$myform.resetFields([ 'username', 'password', 'email' ])

fresh

Load the form as if it was never focused. This removes valid and invalid classes until first focus.

chainable: yes

$myform.fresh()

freshFields

"Freshen" particular fields.

chainable: yes

$myform.freshFields('username')
$myform.freshFields([ 'username', 'password', 'email' ])

reload

Re-attach events and re-adjust the form. Use this method when modifying the html or when manually editing the options of the form.

chainable: yes

$myform.reload().fresh() // Usually combined with `fresh()`

Example:

With the Markup provided you'd call the plugin like this:

var options = {
  inputs: {
    'username': {
      filters: 'required username exclude',
      data: { exclude: ['user', 'username', 'admin'] }
    },
    'date': { filters: 'date' },
    'comments': {
      filters: 'min max',
      data: { min: 50, max: 200 }
    },
    'colors': {
      filters: 'exclude',
      data: { exclude: ['default'] },
      errors: { exclude: 'Choose a color from the list.' }
    },
    'langs[]': {
      filters: 'min',
      data: { min: 2 },
      errors: { min: 'Check at least <strong>2</strong> languages.' }
    },
    'options': {
      filters: 'min'
      data: { min: 1 },
      errors: { min: 'Check only <strong>1</strong> option.' }
    }
  }
};

var $myform = $('#my-form').idealforms( options ).data('idealforms');

Theming:

Ideal Forms relays on a carefully crafted LESS stylesheet. Everything is customizable, from the simplest text input, to the select menus, radios, and checkboxes.

Here's a list of all the Ideal Forms UI elements that can be customized: tabs, labels, headings, separators, icons, errors, text inputs, buttons, select dropdowns, radios, checkboxes, datepicker... Really, ANYTHING.

User config:

All user options are located in less/themes/theme/theme.less. You can safely edit all values from the "user config". The "extra" options must be edited wisely since most of the variables here are relative to other variables defined elsewhere.

The names of the user config variables are pretty self-explanatory. If you screw up you can always go back. When you finish editing the user config don't forget to load your theme in less/jquery.idealforms.less and compile into css.

@font-size

The overall font size. Usually adjusting this option should be enough in most cases. Keep in mind that the bigger the font, the bigger the icons need to be. Ideal Forms will try to align everything as close as possible, but it's recommended that the icons are aprox. the same size as the font-size.

@small-font-size

Ideal Forms uses a smaller font-size for button, select, radio, checkbox and file. This makes UI elements stand out more and feel more integrated. Change to 100% to use the default font-size.

@input-width

Adjust this option if the form doesn't quite fit your container. It's recommended to use this format @font-size * number. All inputs will have the width set here but you can change the width of any particular input by targeting its id. This won't affect the responsive layout.

#comments { width: 200px; }

@label-align

Align labels to either left or right.

@label-width

Most of the time auto will work just fine but if you have really long label names then it's a good idea to tweak this value.

@border-width

Width of every border property. Usually there's no need to change the default value of 1px unless you want a "thick" border look, suitable for some occasions. box-shadow properties depend on this option.

@border-radius

Radius for round corners.

@css3-anim

true or false to enable or disable css3 animations (transitions).

@css3-effects

true or false to enable or disable css3 box-shadow and gradients.

Enjoy :)

Update History:

02/21/13

01/28/13

11/29/12

11/21/12

11/01/12

10/24/12

10/12/12

10/11/12

10/09/12

10/07/12

10/02/12