SwarmOnline Menu Mobile
  • Home
  • About
  • Services
  • Portfolio
  • Blog
  • Contact

Recent Posts

  • Launching Sencha Insights
  • Documenting your Sencha apps with JSDuck
  • Localising Sencha Touch and Ext JS applications with Ux.locale.Manager
  • Announcing SwarmOnline’s New Website!
  • Constructing a complex form layout with Ext JS 4

Recent Comments

  • Stuart on Ext.ux.TouchCalendar – A Sencha Touch Calendar component
  • Stuart on Localising Sencha Touch and Ext JS applications with Ux.locale.Manager
  • Manuel Rodriguez on Localising Sencha Touch and Ext JS applications with Ux.locale.Manager
  • Remi Bloch on Ext.ux.TouchCalendar – A Sencha Touch Calendar component
  • Remi Bloch on Ext.ux.TouchCalendar – A Sencha Touch Calendar component

Archives

  • March 2013
  • February 2013
  • December 2012
  • September 2012
  • August 2012
  • November 2011
  • October 2011
  • May 2011
  • March 2011
  • February 2011
  • January 2011
  • November 2010

Categories

  • Development Tips
  • Ext JS
  • News
  • Sencha Touch
  • Sencha Touch Extensions & Plugins
  • Web Design
  • Web Design & Development Blog

Dynamic Sencha Touch Forms : Part 3 : Adding form fields on the fly

6
30 May
2011
DynamicFormsPart3Screenshot

Sencha Touch

Web Design & Development Blog

After a comment from Brandon looking for advice on adding form fields on the fly, I thought it would be worth a mini blog article to explain it.

What we want to do is add a button to our form that, when tapped, will add a new field to the form. By adding this functionality we can allow users to enter arbitrary amounts of data. This can be applied to situations such as, when entering ingredients for a recipe (we don’t want to restrict them to a set number, nor do we want to prepopulate the form with too many fields); adding qualifications to your CV (not everyone has the same number of qualifications so how do we allow them to enter the right number?).

So, you get the idea about why we might want this – but how do we make it?

As with all our tutorials there is a Tutorial Package that contains all the files you need to try the examples and follow the tutorial step by step. If you click on the Step’s header you can view the demo for that step.

Dynamic Sencha Touch Forms - Part 3 - Tutorial Package (1333)

Just drop into the Sencha Touch ‘examples’ directory

View the Final Result

Step 1 – Create our Form

As in the previous parts we’re going to create a basic form to house our dynamic fields. This is a simple form (with no fields) with an Add button docked to the top and a Submit button docked to the bottom.

Ext.ns('DynamicForms'); // register our namespace
DynamicForms.MyForm = Ext.extend(Ext.form.FormPanel, {
    initComponent: function(){
        Ext.apply(this, {
            floating: true,
            width: 350,
            height: 370,
            centered: true,
            modal: true,
            hideOnMaskTap: false,
            scroll: 'vertical',
            dockedItems: [{
                dock: 'top',
                xtype: 'button',
                text: 'Add Field',
                handler: function(){
                    // handler to be completed in Step 2
                },
                scope: this
            }, {
                dock: 'bottom',
                xtype: 'button',
                text: 'Submit',
                handler: function(){
                    // handler to be completed in Step 2
                },
                scope: this
            }],
            items: []
        });
        DynamicForms.MyForm.superclass.initComponent.call(this);
    }
});

We have left our buttons’ handlers empty just now, but we will add in that functionality in Step 2.

Step 2 – Make it Dynamic

Now we add the fun stuff. What we want to do is, when the Add button is tapped, create a new TextField and add it to the Form. This is remarkably simple and requires a whopping two lines of code. So we add this code to the Add button’s handler.

this.add({
    xtype: 'textfield',
    name: 'MyField-' + this.items.length
});
this.doLayout();

We use the Form’s ‘add‘ method to create the new TextField and just pass it a configuration option that will create the field (I’ve only used a couple of config options to show the idea but you can add a full config object). We have dynamically added a number to the TextField’s name by appending the item count which is necessary due to a (in my opinion) bug with the ‘getValues‘ method which I’ll discuss later.

Finally we call a wee doLayout to force the Form to redraw itself with the new field in place.

Now if you open the Step 2 HTML page and tap the Add button a new TextField will be added. That’s it, done!

These dynamically added fields will be automatically included in the form submission and if you add the following code to the Submit button’s handler you will get a popup that shows the output of the ‘getValues‘ method.

var displayString = '';
var formValues = this.getValues();
for(var fieldName in formValues){
    displayString = displayString + fieldName + ': ' + formValues[fieldName] + '
';
}
Ext.Msg.alert('Output of this.getValues()', displayString);

View the Final Result

The current implementation of the getValues method means that only Checkboxes can have the same name and consequently be sent to the server as an array on submission. The situations I’ve described previously are prime candidates to be sent as arrays which make it much easier to deal with on the server-side rather than having to parse field names with numbers suffixed. Therefore I think it’s a bug in the framework and should be changed to allow any field type to have the same name.

Tweet

6
  1. Brandon Rodak - Reply

    June 1, 2011 at 11:43 pm

    Stuart – Thanks for the mention. I have implemented the code you sent me (as mentioned above) and it works great. Now, I just have to rename a few inputs to make it save properly to my DB.

    I did have a question that has stumped me today and it might be puzzling for others.

    What if I want the newly created input field to become part of an existing fieldset? Would I use a “listener” and in some manner use some dom manipulation like “appendChild”?

    What do you suggest would be the optimal way to add the new field to an existing fieldset (it has an id)?

    Thanks in advance – lovin’ the detailed responses,

    Brandon

    • Stuart - Reply

      June 8, 2011 at 1:29 pm

      The simplest way would be to just grab a reference to the FieldSet (items.get(x)) and call the add method of that container with your Field’s definition.

  2. Mihail - Reply

    June 4, 2011 at 3:19 pm

    Thanks to this tutorial I made a huge step in my thesis! I’d love to see some more tutorials!

  3. BrendanMc - Reply

    June 17, 2011 at 11:20 am

    Stuart,

    Having great fun going through the detailed examples you provide here with your excellent explanations. One issue however, I find a little worrying/strange.

    On any Sencha Touch apps I look at (I’m using an iPhone 4), create the shortcut on my springboard, launch the app. Then launch another app my Sencha app goes into the background (multitasking). If I return the to app (by clicking the icon in the list at the bottom showing all current processes running) the Sencha app reloads – the screen freezes while this reload occurs. Time ticks on while the user waits….

    This reloading means the entire Sencha Touch framework must reload before the app I was just using becomes available again. At best this is redundant work/time – at worst it provides a poor experience for the user; let’s say it – ‘compared to native apps’.

    Is there a solution to this reload or is it inherent in the Sencha framework. If there is no solution then I’m afraid we would seriously reconsider Sencha as the answer to our requirements.

  4. Brandon Rodak - Reply

    June 21, 2011 at 9:57 pm

    Stuart,

    Thanks again for your help. I have implemented the ability to add the form field but I am having issues auto-generating the input Name value. It seems I am only able to add 2 items so after that my input names are repeated and thus the values I am POSTing to the database are repeated. Here is what I have come up with:

    var formBase = {
    scroll: ‘vertical’,
    url : ‘server.php’,
    standardSubmit : false,
    items: [
    {
    xtype: 'fieldset',
    title: 'Add Recipe',
    ref: 'fs',
    id: 'foo',
    //instructions: 'Please enter the information above.',
    defaults: {
    required: true,
    labelAlign: 'left',
    labelWidth: '40%'
    },

    items: [

    {
    xtype: 'textfield',
    name : 'name',
    label: 'Recipe Name',
    useClearIcon: true,
    autoCapitalize : false
    },

    {
    xtype: 'emailfield',
    name : 'email',
    label: 'Email',
    placeHolder: 'user@foo.com',
    useClearIcon: true
    },
    {
    xtype: 'textareafield',
    name : 'comments',
    label: 'Comments',
    maxLength: 50,
    maxRows: 5,
    height: 120
    },
    {
    xtype: 'textfield',
    name : 'ingredients',
    label: 'Ingredients',
    useClearIcon: true,
    autoCapitalize : false
    },

    ]

    }
    ],

    dockedItems: [

    {
    xtype: ‘toolbar’,
    dock: ‘bottom’,

    items: [
    {
    text: ‘Add Ingredient’,
    ui: ’round’,

    handler: function() {

    form.add({

    xtype: ‘textfield’,
    label: ‘Ingredients’,
    labelAlign: ‘left’,
    labelWidth: ’40%’,
    useClearIcon: true,
    autoCapitalize : false,
    id: ‘ing’,
    name: ‘ingredients’ + form.items.length
    }

    );

    form.doLayout();

    },

    scope: form

    },

    Let me know if you need any more code. So the resulting input names become “ingredients1″, “ingredients2″ and then repeating…

    I hope that makes sense – Thanks again!

    Brandon

  5. Katrin - Reply

    January 24, 2012 at 10:35 am

    I added the name like this:
    this.add({
    xtype: ‘textfield’,
    name: ‘MyField[]‘
    });

Leave a Comment - Cancel reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

About SwarmOnline

Based in Glasgow’s West End, SwarmOnline provide web development, cross platform mobile app development and training services for local and international organisations. We have expert knowledge of Sencha technologies and have been Sencha Partners since 2011. We specialise in creating dynamic, innovative and practical solutions.

Meet the Team...

Newsletter

Subscribe to our newsletter and we’ll keep you up-to-date. We don't do spam.

Get in touch!

Email: info@swarmonline.com   
Skype: andrew-swarmonline stuart-swarmonline   
Phone: 0141 438 2231   


© 2013 SwarmOnline Ltd. All Rights Reserved.

SwarmOnline Ltd is a Limited Company registered in Scotland, with company number SC411633. Our Registered Office is 1-2 249 Byres Road, Glasgow G12 8UB.