Second to list controls (previous tutorial), form control is equally important controls of Enyo App. Today we are going to cover a little bit on the followings :-
- Form input and textarea control
- Form picker control
- Form checkbox control
- Some guide on how to submit the form using enyo Ajax.
- Note: Because of security restrictions, if you choose to develop in Chrome and load your app directly from the file system, you’ll need to launch the browser using the command-line switch “–allow-file-access-from-files”. On Windows, you can do this by creating a shortcut to chrome.exe and adding the switch to the end of the shortcut’s Target property. Then use the shortcut each time you launch the browser. A similar approach should work on Mac and Linux as well. Or just use a webserver.
Like all static pages, you should always create a control kind file for your form (without any submit button, header or footer). Just pure form. This way, you can also reuse the same kind for edit/view mode. I’ve created a SampleForm.js check out the tutorial comment embedded inside.
enyo.kind({ name: "SampleForm", kind: "FittableRows", classes: "enyo-fit enyo-unselectable padding15px formBg", components: [ { style:"height:20px" }, { // input decorator is a special div that surround the actual input. This is useful // to further style the input with icons and etc. Input decorator also has a unique // onfocus selector making it looked like a real input instead. kind: "onyx.InputDecorator", classes:"inputStyler", components: [ { name:"txtName", kind: "onyx.Input", placeholder: "Enter a Name", type:"text", // you can insert all sort of event like onchange, oninput, onfocus etc. // you can use this attributes properties for additional attributes // like data-role, maxlength, readonly and required attributes:{ maxlength:80, required:"required" } } ] }, { style:"height:10px" }, { kind: "onyx.InputDecorator", classes:"inputStyler", components: [ { name:"txtPassword", kind: "onyx.Input", placeholder: "Enter Password", type:"password", attributes:{ maxlength:10, required:"required" } } ] }, { style:"height:10px" }, { //Sometimes, is useful to position fittablecolumsnlayout to place multiple div in //horizontal mode. Also take note, some control won't appear unless you specify some //height onto it. layoutKind: "FittableColumnsLayout", style:'height:32px', components:[ { content:"Registered Member ? ", style:"width:200px;padding:8px;" }, { name:"checkMember", kind:"onyx.Checkbox", onchange:"checkboxChanged", checked: true, style:"width:100px;" } ] }, { style:"height:10px" }, // Next we move on to what is know as a picker. Picker is basically, a control that // creates and popup list of choices. // Alternatively you can use kind:enyo.Select, but according to enyoJS developer, // best to use a enyoJS picker as some platform like webos or third party OS may not // have select tag, build to them. Like onyx.input, picker also comes with it's own // decorator and a special button that trigger the picker to popup itself. All together // 3 components. { name:"pickerMemberType", kind: "onyx.PickerDecorator", components: [ { kind: "onyx.PickerButton", content: "Select Member Type...", style: "width: 100%" }, { kind: "onyx.Picker", components: [ {content: "Platinum"}, {content: "Gold"}, {content: "Silver"} ] } ] }, { style:"height:10px" }, // Lastly this is textarea. Which is also comes with it's decorator. Unlike normal // textarea, enyo has maxlength controls on it too :) { kind: "onyx.InputDecorator", classes:"inputStyler", components:[ { kind:"onyx.TextArea", name:"txtAddress", style:'width:100%', placeholder:"Enter Address", attributes:{ maxlength:300, required:"required" } } ] } ], create: function(inSender,inEvent){ this.inherited(arguments); } }); |
My App.js is modified like this, I basically, include the form as a kind within the component of the scroller. So, the content of the form will scroll automatically should any height changes e.g. mobile orientation changes.
enyo.kind({ name: "App", kind: "FittableRows", classes: "enyo-fit enyo-unselectable", components: [ { kind:"Header" }, { kind: "Scroller", name: "contentControl", fit:true, touch:true, thumb:true, components:[ { name:"registerFormControl", kind:"SampleForm" } ] }, { kind:"Footer" } ], create: function(){ this.inherited(arguments); } }); |
Next, we need to script some form method like getFormValues(), so that, any parent controller can access and get the values of each form elements using the hash later.
enyo.kind({ name: "SampleForm", kind: "FittableRows", classes: "enyo-fit enyo-unselectable padding15px formBg", components: [ { style:"height:20px" }, { // input decorator is a special div that surround the actual input. This is useful // to further style the input with icons and etc. Input decorator also has a unique // onfocus selector making it looked like a real input instead. kind: "onyx.InputDecorator", classes:"inputStyler", components: [ { name:"txtName", kind: "onyx.Input", placeholder: "Enter a Name", type:"text", // you can insert all sort of event like onchange, oninput, onfocus etc. // you can use this attributes properties for additional attributes // like data-role, maxlength, readonly and required attributes:{ maxlength:80, required:"required" } } ] }, { style:"height:10px" }, { kind: "onyx.InputDecorator", classes:"inputStyler", components: [ { name:"txtPassword", kind: "onyx.Input", placeholder: "Enter Password", type:"password", attributes:{ maxlength:10, required:"required" } } ] }, { style:"height:10px" }, { //Sometimes, is useful to position fittablecolumsnlayout to place multiple div in //horizontal mode. Also take note, some control won't appear unless you specify some //height onto it. layoutKind: "FittableColumnsLayout", style:'height:32px', components:[ { content:"Registered Member ? ", style:"width:200px;padding:8px;" }, { name:"checkMember", kind:"onyx.Checkbox", onchange:"checkboxChanged", checked: true, style:"width:100px;" } ] }, { style:"height:10px" }, // Next we move on to what is know as a picker. Picker is basically, a control that // creates and popup list of choices. // Alternatively you can use kind:enyo.Select, but according to enyoJS developer, // best to use a enyoJS picker as some platform like webos or third party OS may not // have select tag, build to them. Like onyx.input, picker also comes with it's own // decorator and a special button that trigger the picker to popup itself. All together // 3 components. { name:"pickerMemberType", kind: "onyx.PickerDecorator", components: [ { kind: "onyx.PickerButton", content: "Select Member Type...", style: "width: 100%" }, { kind: "onyx.Picker", components: [ {content: "Platinum"}, {content: "Gold"}, {content: "Silver"} ] } ] }, { style:"height:10px" }, // Lastly this is textarea. Which is also comes with it's decorator. Unlike normal // textarea, enyo has maxlength controls on it too :) { kind: "onyx.InputDecorator", classes:"inputStyler", components:[ { kind:"onyx.TextArea", name:"txtAddress", style:'width:100%', placeholder:"Enter Address", attributes:{ maxlength:300, required:"required" } } ] } ], create: function(inSender,inEvent){ this.inherited(arguments); }, getFormValues:function(){ this.payLoad = {}; //To do this method, make sure all controls are named. this.payLoad.txtName = this.$.txtName.getValue(); this.payLoad.txtPassword = this.$.txtPassword.getValue(); this.payLoad.isMember = this.$.checkMember.getValue(); // This is how you access picker selected item. Should also check // if the values are selected for validation. if (this.$.pickerMemberType.selected != null){ this.payLoad.memberType = this.$.pickerMemberType.selected.content; } // Accessing textarea is the same as input type. this.payLoad.txtAddress = this.$.txtAddress.getValue(); console.log(this.payLoad); return this.payLoad; } }); |
I’ve change the footer with this code and added a this.bubble to pass the event to it’s parent the App.js.
enyo.kind({ name: "Footer", kind: "Control", components: [ { kind: "onyx.Toolbar", style:"text-align:center;margin:0px !important;padding:0px !important", components:[ { kind:"onyx.Button", classes:"fullScreenButton", content:"Submit", ontap:"handleSubmit" } ] } ], handleSubmit:function(inSender,inEvent) { //bubbling an event to the parent. this.bubble("onSubmit"); } }); |
The final step, we attached an onSubmit listener into footer and initiate the ajax called
enyo.kind({ name: "App", kind: "FittableRows", classes: "enyo-fit enyo-unselectable", components: [ { kind:"Header" }, { kind: "Scroller", name: "contentControl", fit:true, touch:true, thumb:true, components:[ { name:"registerFormControl", kind:"SampleForm" } ] }, { kind:"Footer", onSubmit:"handleFormSubmit" } ], create: function(){ this.inherited(arguments); }, handleFormSubmit:function(inSender,inEvent) { //Access a kind method is as simple as hashing it's name and trigger the method. this.payLoad = this.$.registerFormControl.getFormValues(); console.log(this.payLoad); //This is a standard enyo.Ajax to post data. var ajax = new enyo.Ajax({ url: "http://www.yourgatewayurl.com", method:"POST", timeout:5000, contentType:"application/json" }); // send parameters the remote service using the 'go()' method ajax.go(this.payLoad); // attach responders to the transaction object. processResponse is the handler function. ajax.response(this, "processResponse"); // handle error ajax.error(this, "processError"); }, processResponse:function(inSender,inResponse) { alert("All Done"); }, processError:function(inSender,inResponse) { alert("Failed"); } }); |
FYI, the enyo.ajax is just an example and it will return as failed. You should modify it to point to a simple ajax web service of your own ip or domain to test it out. That’s it for today comprehensive lesson.
As for today’s tutorial stuff
Enyo Tutorial #5 (680 downloads)