Two text boxes, either one or both are required - asp.net

I have two textboxes on an asp.net webpage, either one or both are required to be filled in. Both cannot be left blank. How do I create a validator to do this in asp.net?

You'd need a CustomValidator to accomplish that.
Here is some code demonstrating basic usage. The custom validator text will show after IsValid is called in the submit callback and some text will be displayed from the Response.Write call.
ASPX
<asp:TextBox runat="server" ID="tb1" />
<asp:TextBox runat="server" ID="tb2" />
<asp:CustomValidator id="CustomValidator1" runat="server"
OnServerValidate="TextValidate"
Display="Dynamic"
ErrorMessage="One of the text boxes must have valid input.">
</asp:CustomValidator>
<asp:Button runat="server" ID="uxSubmit" Text="Submit" />
Code Behind
protected void Page_Load(object sender, EventArgs e)
{
uxSubmit.Click += new EventHandler(uxSubmit_Click);
}
void uxSubmit_Click(object sender, EventArgs e)
{
Response.Write("Page is " + (Page.IsValid ? "" : "NOT ") + "Valid");
}
protected void TextValidate(object source, ServerValidateEventArgs args)
{
args.IsValid = (tb1.Text.Length > 0 || tb2.Text.Length > 0);
}

Try a CustomValidator.
You'll need to create a method that does the following to handle the ServerValidate event:
void ServerValidation (object source, ServerValidateEventArgs args)
{
args.IsValid = TextBox1.Text.Length > 0 || TextBox2.Text.Length > 0;
}

In addition to creating server-side validation, you can use the ClientValidationFunction property on the CustomValidator to provide client-side validation as well. That might look something like this:
function(sender, args) {
args.IsValid = document.getElementById('<%=TextBox1.ClientID%>').value != ''
|| document.getElementById('<%=TextBox2.ClientID%>').value != '';
}

Onclientclick of your button or whatever submits your page call a javascript function like this
function valtxtbox(){
if (document.getElementById('<%=TextBox1.ClientID%>').value== '' && document.getElementById('<%=TextBox2.ClientID%>').value== '')
{
alert('You must enter in data!');
return false;
}

Related

ServerValidateEventArgs and custom validation control in ASP.NET

I'm a beginner in ASP.NET, just a question on the custom validation, we know that it works in this way:
protected void customValidation_ServerValidate(Object source, ServerValidateEventArgs e)
{
if(e.Value...)
{
...
} else
{
e.IsValid = false;
}
} //customValidation is the id of the custom validation control
but how the value of e.isValid get transferred to the validation's IsValid property?why we have to use ServerValidateEventArgs instead of coding like;
...
} else
{
customValidation.IsValid = false;
}
isn't this approach more sensible? setting the validation control's isValid to false? why via ServerValidateEventArgs instance?
Lets say you have several controls that use the same custom validation. You only want to indicate those controls which are invalid. This is where ServerValidateEventArgs comes in.
This will then be used to indicate which control(s) have failed validation on the page.
E.G.
ASPX
<asp:TextBox runat="server" ID="txtCustomDate" />
<asp:CustomValidator runat="server" OnServerValidate="cstvDate_ServerValidate"
ControlToValidate="txtCustomDate" ID="ctValDate1" ></asp:CustomValidator>
<asp:TextBox runat="server" ID="txtCustomDate2" />
<!-- Same Logic for validation -->
<asp:CustomValidator runat="server" OnServerValidate="cstvDate_ServerValidate"
ControlToValidate="txtCustomDate2" ID="ctValDate2" ></asp:CustomValidator>
Code behind
protected void customValidation_ServerValidate(Object source, ServerValidateEventArgs e)
{
if(e.Value...)
{
...
} else
{
e.IsValid = false;
}
}
The validation method is identified by the OnServerValidate attribute. The validation control passes information about itself via the source parameter and the validation event via the e parameter.
For more information see:
https://learn.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.customvalidator?view=netframework-4.7.2
https://learn.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.servervalidateeventargs?view=netframework-4.7.2

ASP.Net NPE inside hidden parent container if not asp control

Going back from JSF to ASP.Net I have a problem in following markup:
I get a null pointer exceptin on this.value within the panel component. I even called DataBind() on the panel itself.
<asp:Panel id="pnl" runat="server" visible="<%# this.value != null%>">
<%= this.value.Foo %>
</asp:Panel>
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
return;
if (this.value == null)
return;
this.pnl.DataBind();
}
Must i use an asp control always?
You probably have mistakes here :
You should do inside : <%# this.value.Foo %>
Capital letter : Visible {capital}).
The code inside the panel will still be executed even if the panel is not visible. It will not be rendered into the result but it will be executed. I would recommend that you use control properties and set your values via code behind on controls that are not repeating anything
<asp:Panel id="pnl" runat="server">
<asp:Literal ID="literal" runat="server" />
</asp:Panel>
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
return;
if(this.value != null)
{
pnl.Visible = true;
literal.Text = this.value.Foo;
}
else
{
pnl.Visible = false;
}
}

asp net repeater checkbox

I use a Checkbox in a Repeater, how can I know which
Checkbox have changed in OnCheckedChanged?
I have tried to set id then checkbox is binding data, but
it will not work. Hope someone can help me
Thanks
/Mats
Check the sender(Event Target) parameter
protected void Chb_Changed(object sender, EventArgs e)
{
if (sender != null)
{
CheckBox cb=(CheckBox)sender;
string clickedCheckBoxID=cb.ID;
}
}
Try following . Please note that we can also bind some primary column let's say "ID" column in some hidden field then get in code behind.
ASPX Side
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="sqldtasource" >
<ItemTemplate>
<asp:CheckBox ID="chk" runat="server" AutoPostBack="true" Text='<%#Bind("Name")%>' OnCheckedChanged="Chb_Changed"/>
<asp:HiddenField ID="hdn_ID" runat="server" Value='<%# DataBinder.Eval(Container.DataItem, "ID") %>'/>
</ItemTemplate>
</asp:Repeater>
Code Behind :
protected void Chb_Changed(object sender, EventArgs e)
{
if (sender != null)
{
try
{
var hdnID = (HiddenField)checkBox.NamingContainer .FindControl("hf_ID");
if(hdnID != null)
{
string primaryFieldValue = hdnID.Value;
}
if (((CheckBox)sender).Checked)
{
Response.Write(((CheckBox)sender).Text + " is checked");
}
}
catch {
}
}
}

Repeater with Buttons doesn't fire OnItemCommand even when DataBind doesn't happen when IsPostBack is true

I've got an image button in a Repeater, which is in a User Control, and I can't get the OnItemCommand event to fire when I click it. It always gives the error: "... Invalid postback or callback argument. Event validation is enabled using ..."
When I change the image button to a link button, it doesn't give me the error, but it still doesn't fire the OnItemCommand function.
I found some other relevant answers (such as How to process events from Buttons inside Repeaters? And what's this EnableEventValidation thing?) but they all say, "Make sure you're data-binding your repeater inside of a if(!Page.IsPostBack) block." I have done that, but it didn't make a difference.
Here's the markup for the repeater:
<asp:Repeater ID="rptExpenses" OnItemDataBound="rptExpenses_ItemDataBound" OnItemCommand="Button_Command" runat="server" >
<ItemTemplate>
<asp:ImageButton ID="ibDelete" ImageUrl="~/Images/delete.png" CommandName="Delete" runat="server" />
</ItemTemplate>
</asp:Repeater>
Here's some exerpts from the code-behind
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
rptExpenses.DataSource = ExpenseIds;
rptExpenses.DataBind();
}
}
protected void rptExpenses_ItemDataBound(object sender, RepeaterItemEventArgs e) {
if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem)) {
var ibDelete = (ImageButton)e.Item.FindControl("ibDelete");
ibDelete.CommandArgument = e.Item.DataItem.ToString();
}
}
protected void Button_Command(object sender, EventArgs e) {
var btn = (IButtonControl)sender;
switch (btn.CommandName) {
case "Delete":
//delete it
break;
}
}
Try using this code instead:
<asp:Repeater ID="rptExpenses" runat="server">
<ItemTemplate>
<asp:ImageButton ID="ibRemove" ImageUrl="~/Images/delete.png" runat="server"
CommandName="Remove"
CommandArgument='<%# Container.DataItem %>'
OnCommand="ibRemove_Click"/>
</ItemTemplate>
</asp:Repeater>
And this in the code behind:
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
rptExpenses.DataSource = ExpenseIds;
rptExpenses.DataBind();
}
}
protected void ibRemove_Click(object sender, CommandEventArgs e)
{
var btn = (IButtonControl)sender;
switch (btn.CommandName)
{
case "Remove":
//delete it, use btn.CommandArgument to find id to remove
break;
}
}
If you still receive the ... Invalid postback or callback argument. Event validation is enabled using ... error, it most likely means that you are somewhere re-binding the repeater before the ibRemove_Click(...) event is raised.
I found the reason why this was happening in the answer to this question: Why ItemCommand doesn't fired on My Repeater
Turns out that for some reason the Page's DataBind function was invalidating the repeater's controls without passing through the repeater's OnItemDataBound function a second time.

Radio button doesn't get selected after a post back

I have an item template within repeater:
<ItemTemplate>
<li>
<input type="radio"
value="<%# GetAssetId((Guid) (Container.DataItem)) %>"
name="AssetId"
<%# SelectAsset((Guid) Container.DataItem) %> />
</li>
</ItemTemplate>
I have a method that compares ids and decides whether to check the radio button.
protected string SelectAsset(Guid uniqueId)
{
if (uniqueId == GetSomeId())
return "checked=\"checked\"";
return string.Empty;
}
SelectAsset gets hit, but it doesn't select a radio button on a post back, but it does work if I just refresh the page. What am I doing wrong here?
Answer here: How to display "selected radio button" after refresh? says that it's not possible to achieve, is this really the case?
Thank you
Update
It appears that view state isn't available for simple controls if they don't have a runat attribute. I have solved this by using a custom GroupRadioButton control. Thank you for your help.
I'd suggest using a RadioButtonList:
Page Code
<asp:RadioButtonList RepeatLayout="UnorderedList" OnSelectedIndexChanged="IndexChanged" AutoPostBack="true" ID="RadioRepeater" runat="server" />
<asp:Label ID="SelectedRadioLabel" runat="server" />
Code Behind
if (!Page.IsPostBack)
{
/* example adds items manually
- you could iterate your datasource here as well */
this.RadioRepeater.Items.Add(new ListItem("Foo"));
this.RadioRepeater.Items.Add(new ListItem("Bar"));
this.RadioRepeater.Items.Add(new ListItem("Baz"));
this.RadioRepeater.SelectedIndex = this.RadioRepeater.Items.IndexOf(new ListItem("Bar"));
this.RadioRepeater.DataBind();
}
protected void IndexChanged(object sender, EventArgs e)
{
this.SelectedRadioLabel.Text = string.Format("Selected Item Text: {0}", this.RadioRepeater.SelectedItem.Text);
}
I assume you only need to select one item.
As described in the comments, it even works to access the SelectedItem in the Page_Loadevent handler:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// previous code omitted
}
else
{
string foo = this.RadioRepeater.SelectedItem.Text;
}
}
If you are creating all your controls dynamically at run-time (directly from code), then things are a little different. Here is the code that I used:
Page Code
<form id="form1" runat="server">
</form>
Code Behind
protected void Page_Load(object sender, EventArgs e)
{
RadioButtonList rbl = new RadioButtonList();
rbl.AutoPostBack = true;
rbl.SelectedIndexChanged += rbl_SelectedIndexChanged;
rbl.Items.Add("All");
// generate your dynamic radio buttons here
for (int i = 0; i<5; i++)
{
rbl.Items.Add(string.Format("Dynamic{0}", i));
}
form1.Controls.Add(rbl);
if (!Page.IsPostBack)
{
rbl.SelectedValue = "All";
PopulateTextBox(rbl.SelectedValue);
}
}
void rbl_SelectedIndexChanged(object sender, EventArgs e)
{
RadioButtonList foo = (RadioButtonList)sender;
PopulateTextBox(foo.SelectedValue);
}
void PopulateTextBox(string selection)
{
TextBox box = new TextBox();
box.Text = selection;
form1.Controls.Add(box);
}

Resources