Apr 30, 2013, 2:26 PM
[CLOSED] Registration Form updateErrorState modifications
I used the Registration Form example as the basis for this question. I have a user entry form with many more fields. Some fields are explicity hidden based on other field selections, other fields are items of a container that may be hidden.
Modifications to example
1) I have created a Fillout Defaults button that will auto populate my fields for me on the client and server side. Before filling out the fields I suspend the Form events, thus the FieldValidityChange and FieldErrorChange are not fired. After I am done I resume the Form events and then manually fire the FieldValidityChange.
2) In the updateErrorState code I only process fields that are visible, thus;
Controls that are a child of a collapsed fieldset are still processed.
Does this seem reasonable?
Modifications to example
- Removed "Terms of Use" to reduce code size;
- Added Fillout defaults button for client and server side;
- Added hidden TextField for testing;
- Added hidden container with textfield for testing;
- Added fieldset that is collapsible with textfield for testing;
1) I have created a Fillout Defaults button that will auto populate my fields for me on the client and server side. Before filling out the fields I suspend the Form events, thus the FieldValidityChange and FieldErrorChange are not fired. After I am done I resume the Form events and then manually fire the FieldValidityChange.
- What is the proper way to fire the event on the server side?
- Does this seem reasonable?
2) In the updateErrorState code I only process fields that are visible, thus;
- Controls that are explicitly hidden are not processed.
- Controls that are a child of a container that is hidden are not processed.
Controls that are a child of a collapsed fieldset are still processed.
Does this seem reasonable?
<%@ Page Language="C#" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<script runat="server">
protected void FilloutDefaults(object sender, DirectEventArgs e)
{
FormPanel1.SuspendEvents();
txtUsername.SetValue("JanetJones");
txtEmail.SetValue("jjones@server.com");
FormPanel1.ResumeEvents();
//What is the correct way to fire the event from the server side?
//FormPanel1.FireEvent("FieldValidityChange", new object());
}
</script>
<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
<title>Registration Form - Ext.NET Examples</title>
<link href="/resources/css/examples.css" rel="stylesheet" />
<style>
/* Styling of global error indicator */
.form-error-state
{
font-size: 11px;
padding-left: 20px;
height: 16px;
line-height: 18px;
background: no-repeat 0 0;
cursor: default;
}
.form-error-state-invalid
{
color: #C30;
background-image: url(../../../../icons/exclamation-png/ext.axd);
}
.form-error-state-valid
{
color: #090;
background-image: url(../../../../icons/accept-png/ext.axd);
}
/* Error details tooltip */
.errors-tip .error
{
font-style: italic;
}
</style>
<script>
function updateErrorState(form) {
var me = form,
errorCmp, fields, errors;
if (me.hasBeenDirty || me.getForm().isDirty()) { //prevents showing global error when form first loads
errorCmp = me.down('#formErrorState');
fields = me.getForm().getFields();
errors = [];
fields.each(function (field) {
// Only process fields that are visible, thus;
// Fields that are explicitly hidden are not processed.
// Fields that are a child of a container that is hidden are not processed.
// Fields that are a child of a FieldSet that is collapsed is processed.
if (field.isVisible(true)) {
Ext.Array.forEach(field.getErrors(), function (error) {
errors.push({ name: field.getFieldLabel(), error: error });
});
}
});
setErrors(errorCmp, errors);
me.hasBeenDirty = true;
}
}
function setErrors(cmp, errors) {
var me = cmp,
baseCls = me.baseCls,
tip = me.tooltips[0];
errors = Ext.Array.from(errors);
// Update CSS class and tooltip content
if (errors.length) {
me.addCls(baseCls + '-invalid');
me.removeCls(baseCls + '-valid');
me.update("Form has errors");
tip.setDisabled(false);
if (!tip.rendered) {
tip.show();
}
tip.update(me.bin[0].apply(errors));
} else {
me.addCls(baseCls + '-valid');
me.removeCls(baseCls + '-invalid');
me.update("Form is valid");
tip.setDisabled(true);
tip.hide();
}
}
function filloutDefaults() {
App.FormPanel1.suspendEvents();
App.txtUsername.setValue("BobSmith");
App.txtEmail.setValue("bsmith@client.com");
App.FormPanel1.resumeEvents();
App.FormPanel1.fireEvent('fieldvaliditychange', App.FormPanel1, null, null);
}
</script>
</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />
<h1>Registration Form</h1>
<br />
<ext:FormPanel ID="FormPanel1" runat="server" Frame="true" Width="450" BodyPadding="10"
BodyBorder="1" Title="Account Registration" DefaultAnchor="100%">
<FieldDefaults LabelAlign="Left" MsgTarget="None" InvalidCls="" />
<Listeners>
<FieldValidityChange Fn="updateErrorState" />
<FieldErrorChange Fn="updateErrorState" />
</Listeners>
<Items>
<ext:TextField ID="txtUsername" runat="server" Name="username" FieldLabel="User Name"
AllowBlank="false" MinLength="6" />
<ext:TextField ID="txtEmail" runat="server" Name="email" FieldLabel="Email Address"
AllowBlank="false" Vtype="email" />
<ext:TextField ID="txtPassword" runat="server" Name="password1" FieldLabel="Password"
InputType="Password" StyleSpec="margin-top:15px;" AllowBlank="false" MinLength="8" />
<ext:TextField ID="txtPasswordConfirm" runat="server" Name="password2" FieldLabel="Repeat Password"
InputType="Password" AllowBlank="false">
<Validator Handler="return (value === this.previousSibling('[name=password1]').getValue()) ? true : 'Passwords do not match.';" />
</ext:TextField>
<ext:TextField ID="txtJunk01" runat="server" FieldLabel="Junk (txt)" AllowBlank="false" Hidden="true" />
<ext:Container ID="cntrJunk01" runat="server" Hidden="false">
<Items>
<ext:TextField ID="txtJunk02" runat="server" FieldLabel="Junk (in Cntr)" AllowBlank="false" />
</Items>
</ext:Container>
<ext:FieldSet ID="fsJunk01" runat="server" Title="FieldSet" Collapsible="true" >
<Items>
<ext:TextField ID="txtJunk03" runat="server" FieldLabel="Junk (in FS)" AllowBlank="false" />
</Items>
</ext:FieldSet>
</Items>
<DockedItems>
<ext:Container ID="Container1" runat="server" Dock="Bottom" PaddingSpec="10 10 5">
<LayoutConfig>
<ext:HBoxLayoutConfig Align="Middle" />
</LayoutConfig>
<Items>
<ext:Component ID="Component1" runat="server" ItemID="formErrorState" BaseCls="form-error-state"
Flex="1">
<Bin>
<ext:XTemplate ID="XTemplate1" runat="server">
<Html>
<ul>
<tpl for=".">
<li>
<span class="field-name">{name}</span> : <span class="error">{error}</span>
</li>
</tpl>
</ul>
</Html>
</ext:XTemplate>
</Bin>
<ToolTips>
<ext:ToolTip ID="ToolTip1" runat="server" Title="Error Details:" AutoHide="false"
Anchor="top" MinWidth="200" MouseOffset="-11,-2" Closable="true" Disabled="true"
ConstrainPosition="false" Cls="errors-tip" />
</ToolTips>
</ext:Component>
<ext:SplitButton runat="server" Text="Fillout Defaults" Icon="PencilAdd">
<Menu>
<ext:Menu runat="server">
<Items>
<ext:MenuItem runat="server" Text="Client" Icon="Computer" OnClientClick="filloutDefaults" />
<ext:MenuItem runat="server" Text="Server" Icon="Server">
<DirectEvents>
<Click OnEvent="FilloutDefaults" Success="App.FormPanel1.fireEvent('fieldvaliditychange', App.FormPanel1, null, null);" />
</DirectEvents>
</ext:MenuItem>
</Items>
</ext:Menu>
</Menu>
</ext:SplitButton>
<ext:ToolbarSpacer runat="server" />
<ext:Button ID="Button1" runat="server" FormBind="true" Disabled="true" Text="Submit Registration"
Width="140">
<Listeners>
<Click Handler="var form = this.up('form').getForm(); if (form.isValid()) {Ext.Msg.alert('Submitted Values', form.getValues(true));}" />
</Listeners>
</ext:Button>
</Items>
</ext:Container>
</DockedItems>
</ext:FormPanel>
</form>
</body>
</html>
Last edited by Daniil; May 07, 2013 at 3:53 AM.
Reason: [CLOSED]