Jan 29, 2013, 11:08 PM
[FIXED] [2.2] ComboBox.IsEmpty Always Returns False on Postback
Hi,
The ComboBox's IsEmpty property returns false on postback even when no selection is made and nothing was entered.
Ext.Net 2.1.1
Test Case:
Without modifying EmptyValue (defaults to null), IsEmpty will only return true if Value is null:
Assuming that LoadPostData's Value being set to "" was correct, the problem can be fixed by overridding IsEmpty to use EmptyText in ComboBoxBase.cs:
The ComboBox's IsEmpty property returns false on postback even when no selection is made and nothing was entered.
Ext.Net 2.1.1
Test Case:
<%@ Page Language="C#" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<script runat="server">
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest && !IsPostBack)
{
testStore.DataSource = new List<Person>
{
new Person(){ ID = 4, Name = "PHB"},
new Person(){ ID = 5, Name = "Alice"},
new Person(){ ID = 7, Name = "Dilbert"},
};
testStore.DataBind();
}
}
protected void btn_DirectClick(object sender, DirectEventArgs e)
{
if (testCombo.IsEmpty)
X.Msg.Alert("Combo Empty", "Combo Empty").Show();
else
X.Msg.Alert("Combo Not Empty", "Combo Not Empty").Show();
}
</script>
<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
<title>Test</title>
</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="rsMan" runat="server" />
<ext:ComboBox ID="testCombo"
runat="server"
DisplayField="Name"
ValueField="ID"
QueryMode="Local"
FieldLabel="Test Combo">
<Store>
<ext:Store ID="testStore" runat="server">
<Model>
<ext:Model ID="testModel" runat="server">
<Fields>
<ext:ModelField Name="ID" />
<ext:ModelField Name="Name" />
</Fields>
</ext:Model>
</Model>
<Reader>
<ext:JsonReader />
</Reader>
</ext:Store>
</Store>
</ext:ComboBox>
<ext:Button runat="server" Text="Post" ID="btn" OnDirectClick="btn_DirectClick" />
</form>
</body>
</html>
IsEmtpy & EmptyValue is defined in Field.cs. Without modifying EmptyValue (defaults to null), IsEmpty will only return true if Value is null:
[Description("Gets a value indicating whether the Value is equal to EmptyValue.")]
public virtual bool IsEmpty
{
get
{
return this.Value == null ? true : this.Value.Equals(this.EmptyValue);
}
}
[Meta]
[Category("5. Field")]
[DefaultValue(null)]
[Description("The fields null value.")]
public virtual object EmptyValue
{
get
{
return this.State.Get<object>("EmptyValue", null);
}
set
{
this.State.Set("EmptyValue", value);
}
}
TextFieldBase.cs defines EmptyText, it's default is "" not null: [Meta]
[ConfigOption]
[Category("6. TextField")]
[DefaultValue("")]
[Localizable(true)]
[Description("The default text to display in an empty field (defaults to null).")]
public virtual string EmptyText
{
get
{
return this.State.Get<string>("EmptyText", "");
}
set
{
this.State.Set("EmptyText", value);
}
}
LoadPostData of ComboBoxBase.cs sets Value to "" when the ComboBox is blank: [Description("")]
protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
this.HasLoadPostData = true;
string text = postCollection[this.UniqueName];
string state = postCollection[this.ValueHiddenName.IsNotEmpty() ? this.ValueHiddenName : ("_" + this.UniqueName + "_state")];
this.SuspendScripting();
this.RawValue = text;
this.Value = text; //<-------- This line will always result in an empty ComboBox Value to be "" not null
this.ResumeScripting();
if (state == null && text == null)
{
return false;
}
try
{
this.SuspendScripting();
if (!this.EmptyText.Equals(text) && text.IsNotEmpty())
{
List<ListItem> items = null;
if (this.SimpleSubmit)
{
string[] array = state.Split(new char[] { ',' });
items = new List<ListItem>(array.Length);
foreach (string item in array)
{
items.Add(new ListItem(item));
}
}
else if (state.IsNotEmpty())
{
items = ComboBoxBase.ParseSelectedItems(state);
}
bool fireEvent = false;
if (items == null)
{
items = new List<ListItem>
{
new ListItem(text)
};
}
foreach (ListItem item in items)
{
if (!this.SelectedItems.Contains(item))
{
fireEvent = true;
break;
}
}
this.SelectedItems.Clear();
this.SelectedItems.AddRange(items);
if (this.SelectedItems.Count > 0)
{
this.Value = this.SelectedItems[0].Value;
}
return fireEvent;
}
else
{
if (this.EmptyText.Equals(text) && this.SelectedItems.Count > 0)
{
this.SelectedItems.Clear();
return true;
}
}
}
catch
{
this.SuccessLoadPostData = false;
if (this.RethrowLoadPostDataException)
{
throw;
}
}
finally
{
this.ResumeScripting();
}
return false;
}
If LoadPostData's Value being set to "" was not by design, then LoadPostData needs to ensure that Value is left null if ComboBox is empty.Assuming that LoadPostData's Value being set to "" was correct, the problem can be fixed by overridding IsEmpty to use EmptyText in ComboBoxBase.cs:
public override bool IsEmpty
{
get
{
return this.Value == null ? true : this.Value.Equals(this.EmptyText);
}
}
Last edited by Daniil; Feb 07, 2013 at 11:40 AM.
Reason: [FIXED] [2.2]