Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / guides / forms / README.js
1 Ext.data.JsonP.forms({"guide":"<h1>Forms</h1>\n\n<hr />\n\n<p>A <a href=\"#!/api/Ext.form.Panel\" rel=\"Ext.form.Panel\" class=\"docClass\">Form Panel</a> is nothing more than a basic <a href=\"#!/api/Ext.panel.Panel\" rel=\"Ext.panel.Panel\" class=\"docClass\">Panel</a> with form handling abilities added.\nForm Panels can be used throughout an Ext application wherever there is a need to collect data from the user.\nIn addition, Form Panels can use any <a href=\"#!/api/Ext.layout.container.Container\" rel=\"Ext.layout.container.Container\" class=\"docClass\">Container Layout</a>, providing a convenient and flexible way to handle the positioning of their fields.\nForm Panels can also be bound to a <a href=\"#!/api/Ext.data.Model\" rel=\"Ext.data.Model\" class=\"docClass\">Model</a>, making it easy to load data from and submit data back to the server.\nUnder the hood a Form Panel wraps a <a href=\"#!/api/Ext.form.Basic\" rel=\"Ext.form.Basic\" class=\"docClass\">Basic Form</a> which handles all of its input field management, validation, submission, and form loading services.\nThis means that any of the config options of a Basic Form can be used directly on a Form Panel.</p>\n\n<h2>Basic Form Panel</h2>\n\n<p>To start off, here's how to create a simple form that collects user data:</p>\n\n<pre class='inline-example '><code>Ext.create('Ext.form.Panel', {\n    renderTo: Ext.getBody(),\n    title: 'User Form',\n    height: 130,\n    width: 280,\n    bodyPadding: 10,\n    defaultType: 'textfield',\n    items: [\n        {\n            fieldLabel: 'First Name',\n            name: 'firstName'\n        },\n        {\n            fieldLabel: 'Last Name',\n            name: 'lastName'\n        },\n        {\n            xtype: 'datefield',\n            fieldLabel: 'Date of Birth',\n            name: 'birthDate'\n        }\n    ]\n});\n</code></pre>\n\n<p>This form renders itself to the document body and has three <a href=\"#!/api/Ext.form.field.Field\" rel=\"Ext.form.field.Field\" class=\"docClass\">Field</a>s - \"First Name\", \"Last Name\", and \"Date of Birth\". Fields are added to the Form Panel using the <a href=\"#!/api/Ext.form.Panel-cfg-items\" rel=\"Ext.form.Panel-cfg-items\" class=\"docClass\">items</a> configuration.\nThe <a href=\"#!/api/Ext.form.Labelable-cfg-fieldLabel\" rel=\"Ext.form.Labelable-cfg-fieldLabel\" class=\"docClass\">fieldLabel</a> configuration defines what text will appear in the label next to the field, and the <a href=\"#!/api/Ext.form.field.Base-cfg-name\" rel=\"Ext.form.field.Base-cfg-name\" class=\"docClass\">name</a> configuration becomes the <code>name</code> attribute of the underlying html field.\nNotice how this Form Panel has a <a href=\"#!/api/Ext.form.Panel-cfg-defaultType\" rel=\"Ext.form.Panel-cfg-defaultType\" class=\"docClass\">defaultType</a> of 'textfield'.  This means that any of its items that do not have an <a href=\"#!/api/Ext.Component\" rel=\"Ext.Component\" class=\"docClass\">xtype</a> specified (the \"First Name\" and \"Last Name\" fields in this example), are <a href=\"#!/api/Ext.form.field.Text\" rel=\"Ext.form.field.Text\" class=\"docClass\">Text Field</a>s.\nThe \"Date of Birth\" field on the other hand has its <code>xtype</code> explicitly defined as 'datefield' which makes it a <a href=\"#!/api/Ext.form.field.Date\" rel=\"Ext.form.field.Date\" class=\"docClass\">Date Field</a>. Date Fields expect to only contain valid date data, and come with a <a href=\"#!/api/Ext.menu.DatePicker\" rel=\"Ext.menu.DatePicker\" class=\"docClass\">DatePicker</a> for selecting a date.</p>\n\n<p>See the <a href=\"guides/forms/examples/simple_form/index.html\">Simple Form</a> example for a live demo.</p>\n\n<h2>Fields</h2>\n\n<h3>Field Types</h3>\n\n<p>Ext JS provides a set of standard Field types out of the box. Any of the Fields in the <code>Ext.form.field</code> namespace can be used in a Form Panel. For more information see the API documentaion for each Field type:</p>\n\n<ul>\n<li><a href=\"#!/api/Ext.form.field.Checkbox\" rel=\"Ext.form.field.Checkbox\" class=\"docClass\">Ext.form.field.Checkbox</a></li>\n<li><a href=\"#!/api/Ext.form.field.ComboBox\" rel=\"Ext.form.field.ComboBox\" class=\"docClass\">Ext.form.field.ComboBox</a></li>\n<li><a href=\"#!/api/Ext.form.field.Date\" rel=\"Ext.form.field.Date\" class=\"docClass\">Ext.form.field.Date</a></li>\n<li><a href=\"#!/api/Ext.form.field.Display\" rel=\"Ext.form.field.Display\" class=\"docClass\">Ext.form.field.Display</a></li>\n<li><a href=\"#!/api/Ext.form.field.File\" rel=\"Ext.form.field.File\" class=\"docClass\">Ext.form.field.File</a></li>\n<li><a href=\"#!/api/Ext.form.field.Hidden\" rel=\"Ext.form.field.Hidden\" class=\"docClass\">Ext.form.field.Hidden</a></li>\n<li><a href=\"#!/api/Ext.form.field.HtmlEditor\" rel=\"Ext.form.field.HtmlEditor\" class=\"docClass\">Ext.form.field.HtmlEditor</a></li>\n<li><a href=\"#!/api/Ext.form.field.Number\" rel=\"Ext.form.field.Number\" class=\"docClass\">Ext.form.field.Number</a></li>\n<li><a href=\"#!/api/Ext.form.field.Radio\" rel=\"Ext.form.field.Radio\" class=\"docClass\">Ext.form.field.Radio</a></li>\n<li><a href=\"#!/api/Ext.form.field.Text\" rel=\"Ext.form.field.Text\" class=\"docClass\">Ext.form.field.Text</a></li>\n<li><a href=\"#!/api/Ext.form.field.TextArea\" rel=\"Ext.form.field.TextArea\" class=\"docClass\">Ext.form.field.TextArea</a></li>\n<li><a href=\"#!/api/Ext.form.field.Time\" rel=\"Ext.form.field.Time\" class=\"docClass\">Ext.form.field.Time</a></li>\n</ul>\n\n\n<h3>Validation</h3>\n\n<h4>1. Built-in Validations</h4>\n\n<p>Ext JS has built in support for validation on any type of Field, and some Fields have built in validation rules.\nFor example if a value is entered into a <a href=\"#!/api/Ext.form.field.Date\" rel=\"Ext.form.field.Date\" class=\"docClass\">Date Field</a> and that value cannot be converted into a <code>Date</code>, the Field will have the <code>x-form-invalid-field</code> CSS class added to its HTML element.\nIf necessary, this CSS class can be changed using the <a href=\"#!/api/Ext.form.field.Base-cfg-invalidCls\" rel=\"Ext.form.field.Base-cfg-invalidCls\" class=\"docClass\">invalidCls</a> configuration. In the default <a href=\"#/guide/theming\">theme</a>, adding the <code>invalidCls</code> adds a red \"invalid underline\":</p>\n\n<p><p><img src=\"guides/forms/invalid_field.png\" alt=\"Invalid Field\"></p></p>\n\n<p>A Field containing invalid data will also display an error message. By default this message displays as a tool tip:</p>\n\n<p><p><img src=\"guides/forms/invalid_field_hover.png\" alt=\"Invalid Field Hover\"></p></p>\n\n<p>It's easy to change the location of a Field's error message using the <a href=\"#!/api/Ext.form.Labelable-cfg-msgTarget\" rel=\"Ext.form.Labelable-cfg-msgTarget\" class=\"docClass\">msgTarget</a> configuration, and the <a href=\"#!/api/Ext.form.field.Base-cfg-invalidText\" rel=\"Ext.form.field.Base-cfg-invalidText\" class=\"docClass\">invalidText</a> configuration changes the error message.\nEach Field provides its own implementation of <code>invalidText</code>, and many support token replacement in the error message.\nFor example, in a Date Field's <code>invalidText</code>, any occurrences of \"{0}\" will be replaced with the Field's value, and any occurrences of \"{1}\" will be replaced with the required date <a href=\"#!/api/Ext.form.field.Date-cfg-format\" rel=\"Ext.form.field.Date-cfg-format\" class=\"docClass\">format</a>.\nThe following code demonstrates placing the error message directly under the Field, and customizing the error message text:</p>\n\n<pre><code>{\n    xtype: 'datefield',\n    fieldLabel: 'Date of Birth',\n    name: 'birthDate',\n    msgTarget: 'under', // location of the error message\n    invalidText: '\"{0}\" bad. \"{1}\" good.' // custom error message text\n}\n</code></pre>\n\n<p><p><img src=\"guides/forms/custom_error_message.png\" alt=\"Custom Error Message\"></p></p>\n\n<h4>2. Custom Validations</h4>\n\n<p>Some validation requirements cannot be met using the built-in validations. The simplest way to implement a custom validation is to use the <a href=\"#!/api/Ext.form.field.Text\" rel=\"Ext.form.field.Text\" class=\"docClass\">Text Field</a>'s <a href=\"#!/api/Ext.form.field.Text-cfg-regex\" rel=\"Ext.form.field.Text-cfg-regex\" class=\"docClass\">regex</a> configuration to apply validation rules, and the <a href=\"#!/api/Ext.form.field.Text-cfg-maskRe\" rel=\"Ext.form.field.Text-cfg-maskRe\" class=\"docClass\">maskRe</a> configuration to limit which characters can be typed into the field. Here's an example of a Text Field that validates a time.</p>\n\n<pre><code>{\n    fieldLabel: 'Last Login Time',\n    name: 'loginTime',\n    regex: /^([1-9]|1[0-9]):([0-5][0-9])(\\s[a|p]m)$/i,\n    maskRe: /[\\d\\s:amp]/i,\n    invalidText: 'Not a valid time.  Must be in the format \"12:34 PM\".'\n}\n</code></pre>\n\n<p>While the above method works well for validating a single field, it is not practical for an application that has many fields that share the same custom validation.\nThe <a href=\"#!/api/Ext.form.field.VTypes\" rel=\"Ext.form.field.VTypes\" class=\"docClass\">Ext.form.field.VTypes</a> class provides a solution for creating reusable custom validations. Here's how a custom \"time\" validator can be created:</p>\n\n<pre><code>// custom Vtype for vtype:'time'\nvar timeTest = /^([1-9]|1[0-9]):([0-5][0-9])(\\s[a|p]m)$/i;\nExt.apply(Ext.form.field.VTypes, {\n    //  vtype validation function\n    time: function(val, field) {\n        return timeTest.test(val);\n    },\n    // vtype Text property: The error text to display when the validation function returns false\n    timeText: 'Not a valid time.  Must be in the format \"12:34 PM\".',\n    // vtype Mask property: The keystroke filter mask\n    timeMask: /[\\d\\s:amp]/i\n});\n</code></pre>\n\n<p>Once a custom validator has been created it can be used on Text Fields throughout an application using the <code><a href=\"#!/api/Ext.form.field.Text-cfg-vtype\" rel=\"Ext.form.field.Text-cfg-vtype\" class=\"docClass\">vtype</a></code> configuration:</p>\n\n<pre><code>{\n    fieldLabel: 'Last Login Time',\n    name: 'loginTime',\n    vtype: 'time'\n}\n</code></pre>\n\n<p>See <a href=\"guides/forms/examples/validation\">Validation Example</a> for a working demo. For more information on custom validations please refer to the API Documentation for <a href=\"#!/api/Ext.form.field.VTypes\" rel=\"Ext.form.field.VTypes\" class=\"docClass\">VTypes</a>.</p>\n\n<h2>Handling Data</h2>\n\n<h3>Submitting a Form</h3>\n\n<p>The simplest way to submit data to the server is to use the <a href=\"#!/api/Ext.form.Basic-cfg-url\" rel=\"Ext.form.Basic-cfg-url\" class=\"docClass\">url</a> configuration of <a href=\"#!/api/Ext.form.Basic\" rel=\"Ext.form.Basic\" class=\"docClass\">Basic Form</a>. Since <a href=\"#!/api/Ext.form.Panel\" rel=\"Ext.form.Panel\" class=\"docClass\">Form Panel</a> wraps a Basic Form, we can use any of Basic Form's configuration options directly on a Form Panel:</p>\n\n<pre><code>Ext.create('Ext.form.Panel', {\n    ...\n    url: 'add_user',\n    items: [\n        ...\n    ]\n});\n</code></pre>\n\n<p>The Basic Form's <a href=\"#!/api/Ext.form.Basic-method-submit\" rel=\"Ext.form.Basic-method-submit\" class=\"docClass\">submit</a> method can be used to submit data to the configured <code>url</code>:</p>\n\n<pre><code>Ext.create('Ext.form.Panel', {\n    ...\n    url: 'add_user',\n    items: [\n        ...\n    ],\n    buttons: [\n        {\n            text: 'Submit',\n            handler: function() {\n                var form = this.up('form').getForm(); // get the basic form\n                if (form.isValid()) { // make sure the form contains valid data before submitting\n                    form.submit({\n                        success: function(form, action) {\n                           Ext.Msg.alert('Success', action.result.msg);\n                        },\n                        failure: function(form, action) {\n                            Ext.Msg.alert('Failed', action.result.msg);\n                        }\n                    });\n                } else { // display error alert if the data is invalid\n                    Ext.Msg.alert('Invalid Data', 'Please correct form errors.')\n                }\n            }\n        }\n    ]\n});\n</code></pre>\n\n<p>In the above example a button is configured with a handler that handles form submission. The handler takes the following actions:</p>\n\n<ol>\n<li>First a reference to the Basic Form must be acquired.</li>\n<li>Then the <a href=\"#!/api/Ext.form.Basic-method-isValid\" rel=\"Ext.form.Basic-method-isValid\" class=\"docClass\">isValid</a> method is called before submission to verify that none of the fields have validation errors.</li>\n<li>Finally the <code>submit</code> method is called, and two callback functions are passed - <code>success</code> and <code>failure</code>.  Within these callback functions <code>action.result</code> refers to the parsed JSON response.</li>\n</ol>\n\n\n<p>The above example expects a JSON response that looks something like this:</p>\n\n<pre><code>{ \"success\": true, \"msg\": \"User added successfully\" }\n</code></pre>\n\n<p><a href=\"guides/forms/examples/submit/index.html\">Form Submission Example</a></p>\n\n<h3>Binding a Form to a Model</h3>\n\n<p>The <a href=\"#!/api/Ext.data.Model\" rel=\"Ext.data.Model\" class=\"docClass\">Model</a> class is used throughout Ext JS for representing various types of data, as well as retrieving and updating data on the server.\nA Model representing a User would define the fields a User has, as well as a proxy for loading and saving data:</p>\n\n<pre><code>Ext.define('User', {\n    extend: 'Ext.data.Model',\n    fields: ['firstName', 'lastName', 'birthDate'],\n    proxy: {\n        type: 'ajax',\n        api: {\n            read: 'data/get_user',\n            update: 'data/update_user'\n        },\n        reader: {\n            type: 'json',\n            root: 'users'\n        }\n    }\n});\n</code></pre>\n\n<p>For more details on working with Models please refer to the <a href=\"#/guide/data\">Data Guide</a>.</p>\n\n<p>Data can be loaded into a <a href=\"#!/api/Ext.form.Panel\" rel=\"Ext.form.Panel\" class=\"docClass\">Form Panel</a> directly from a <a href=\"#!/api/Ext.data.Model\" rel=\"Ext.data.Model\" class=\"docClass\">Model</a> using the <a href=\"#!/api/Ext.form.Panel-method-loadRecord\" rel=\"Ext.form.Panel-method-loadRecord\" class=\"docClass\">loadRecord</a> method:</p>\n\n<pre><code>Ext.ModelMgr.getModel('User').load(1, { // load user with ID of \"1\"\n    success: function(user) {\n        userForm.loadRecord(user); // when user is loaded successfully, load the data into the form\n    }\n});\n</code></pre>\n\n<p>Finally, instead of using the <a href=\"#!/api/Ext.form.Basic-method-submit\" rel=\"Ext.form.Basic-method-submit\" class=\"docClass\">submit</a> method to save the data, Basic Form's <a href=\"#!/api/Ext.form.Basic-method-updateRecord\" rel=\"Ext.form.Basic-method-updateRecord\" class=\"docClass\">updateRecord</a> method is used to update the record with the form data, and the Model's <a href=\"#!/api/Ext.data.Model-method-save\" rel=\"Ext.data.Model-method-save\" class=\"docClass\">save</a> method is called to save the data to the server:</p>\n\n<pre><code>Ext.create('Ext.form.Panel', {\n    ...\n    url: 'add_user',\n    items: [\n        ...\n    ],\n    buttons: [\n        {\n            text: 'Submit',\n            handler: function() {\n                var form = this.up('form').getForm(), // get the basic form\n                    record = form.getRecord(); // get the underlying model instance\n                if (form.isValid()) { // make sure the form contains valid data before submitting\n                    form.updateRecord(record); // update the record with the form data\n                    record.save({ // save the record to the server\n                        success: function(user) {\n                            Ext.Msg.alert('Success', 'User saved successfully.')\n                        },\n                        failure: function(user) {\n                            Ext.Msg.alert('Failure', 'Failed to save user.')\n                        }\n                    });\n                } else { // display error alert if the data is invalid\n                    Ext.Msg.alert('Invalid Data', 'Please correct form errors.')\n                }\n            }\n        }\n    ]\n});\n</code></pre>\n\n<p><a href=\"guides/forms/examples/model_binding/index.html\">Model Binding Example</a></p>\n\n<h2>Layouts</h2>\n\n<p>Layouts are used to handle sizing and positioning of components in an Ext JS application.  <a href=\"#!/api/Ext.form.Panel\" rel=\"Ext.form.Panel\" class=\"docClass\">Form Panels</a> can use any <a href=\"#!/api/Ext.layout.container.Container\" rel=\"Ext.layout.container.Container\" class=\"docClass\">Container Layout</a>. For more information on Layouts please refer to the <a href=\"#/guide/layouts_and_containers\">Layouts and Containers Guide</a>.</p>\n\n<p>For example, positioning fields in a form horizontally can easily be done using an <a href=\"#!/api/Ext.layout.container.HBox\" rel=\"Ext.layout.container.HBox\" class=\"docClass\">HBox</a> Layout:</p>\n\n<pre class='inline-example '><code>Ext.create('Ext.form.Panel', {\n    renderTo: Ext.getBody(),\n    title: 'User Form',\n    height: 100,\n    width: 515,\n    defaults: {\n        xtype: 'textfield',\n        labelAlign: 'top',\n        padding: 10\n    },\n    layout: {\n        type: 'hbox'\n    },\n    items: [\n        {\n            fieldLabel: 'First Name',\n            name: 'firstName'\n        },\n        {\n            fieldLabel: 'Last Name',\n            name: 'lastName'\n        },\n        {\n            xtype: 'datefield',\n            fieldLabel: 'Date of Birth',\n            name: 'birthDate'\n        }\n    ]\n});\n</code></pre>\n\n<p>See the <a href=\"guides/forms/examples/layout/index.html\">Layout Example</a> for a live demo.</p>\n","title":"The Form Package"});