asp.net Dropdownlist Customvalidator servervalidate referencing control - c#

I have a dropdownlist that I populate from the DB, and depending on business logic I need to be able to validate the selected item (TEXT) from the dropdownlist with server side vaildation. Requirements state I cannot simply filter it out as part of the SQL statement. The solution I have been trying to get to work is to simply create a customvalidation in the code behind.
The validation is called, BUT I cannot figure out how to reference the ddl DataTextField value for the item selected. When I try and do the server side code below the asp.net system states that my dropdownlist does not exist within the detailsview and provides a red underline as a result. In this instance it will always be insertmode.
Suggestions
ASP Code
<asp:DetailsView ID="dtlSample" runat="server" AutoGenerateEditButton="true" AutoGenerateRows="false">
<Fields>
.
.
.
<asp:TemplateField HeaderText="Position">
<ItemTemplate>
<%# Eval("Age") %>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlPosition" runat="server" AutoPostBack="True"
LDataSource="Select Position, PositionId from ...." DataTextField="Position" DataValueField="PositionId"
></asp:DropDownList>
</EditItemTemplate>
<InsertItemTemplate>
<asp:DropDownList ID="ddlPosition" runat="server" AutoPostBack="True"
LDataSource="Select Position, PositionId from ...." DataTextField="Position" DataValueField="PositionId"
></asp:DropDownList>
</InsertItemTemplate>
<asp:CustomValidator ID="cvPos" Display="Dynamic" ControlToValidate = "DDLPosition"
OnServerValidate="ddlPos_Check" runat="server" ForeColor="Red" ErrorMessage="My error message"></asp:CustomValidator>
</asp:TemplateField>
</Fields>
CODE BEHIND
protected void ddlPos_Check(object sender, ServerValidateEventArgs args)
{
if (ddPosition.SelectedItem.Text.Contains("some value")
args.IsValid = false;
else
args.IsValid = true;
}

Murphy's law, answer your own question a few hours after.
DropDownList ddlList=DetailsView2.FindControl("ddlPosition") as DropDownList;
if (ddlList != null)
{
if (ddlList.SelectedItem.Text.Contains("text")) {
args.IsValid = false;
}
else
{
args.IsValid = true;
}
}

Related

Required field validator not working for dropdownlist in repeater control

I have a drop down list in a repeater. I am trying to add a required field validator to it.
The aspx code is:
<asp:Repeater ID="myRepeter" runat="server" OnItemDataBound="myRepeter_ItemDataBound">
<ItemTemplate>
<asp:DropDownList ID="ddl_Name" runat="server" DataTextField="value" DataValueField="key" ></asp:DropDownList>
<asp:RequiredFieldValidator ID="rfv_Name" ControlToValidate="ddl_Name" InitialValue="0" runat="server" ErrorMessage="Please select a Name" ValidationGroup="valgrp_Name" ForeColor="Red"></asp:RequiredFieldValidator>
</ItemTemplate>
</asp:Repeater>
I also tried the same from code behind:
protected void myRepeter_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
foreach(RepeaterItem item in myRepeter.Items)
{
DropDownList NametList = item.FindControl("ddl_Name") as DropDownList;
RequiredFieldValidator validator = item.FindControl("rfv_Name") as RequiredFieldValidator;
validator.ControlToValidate = NametList .ID;
validator.ValidationGroup = "valgrp_Name";
}
}
How can I add the required field validator?
Why are you looping through your repeater inside the databound event? It will automatically loop. Try using e.Item.FindControl instead.
DropDownList NametList = e.Item.FindControl("ddl_Name") as DropDownList;
RequiredFieldValidator validator = e.Item.FindControl("rfv_Name") as RequiredFieldValidator;
validator.ControlToValidate = NametList.ID;
validator.ValidationGroup = "valgrp_Name";

Nesting Gridview inside Formview breaks insert codebehind context

I have a couple of GridViews in my FormView page and I am wanting to make an Insert row in the FooterRow of the Gridviews. Layout and everything is fine. However, as I'm building the codebehind for the Insert command, I'm running into a context problem. If I move the GridView outside of the FormView markup, the context errors clear up immediately.
GridView Markup
<asp:GridView ID="gvBFMats" runat="server" ShowFooter="True" AutoGenerateColumns="False" DataKeyNames="MaterialID" DataSourceID="BFMatsSQL" OnRowCommand="gvBFMats_RowCommand">
<Columns>
<asp:TemplateField HeaderText="Commands" ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="ButtonUpdate" runat="server" CausesValidation="True" CommandName="Update" Text="Update"></asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel"></asp:LinkButton>
</EditItemTemplate>
<ItemTemplate>
<asp:LinkButton ID="ButtonEdit" runat="server" CausesValidation="False" CommandName="Edit" Text="Edit"></asp:LinkButton>
<asp:LinkButton ID="ButtonDelete" runat="server" CausesValidation="False" CommandName="Delete" Text="Delete"></asp:LinkButton>
</ItemTemplate>
<FooterTemplate>
<asp:LinkButton ID="ButtonAdd" runat="server" CommandName="Insert" Text="Add to Table" />
</FooterTemplate>
...
Insert Command Codebehind
protected void gvBFMats_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Insert" && Page.IsValid)
{
BFMatsSQL.Insert();
}
}
protected void BFMatsSQL_Inserting
(object sender, ObjectDataSourceMethodEventArgs e)
{
DropDownList ddlNewMfr =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewMfr");
DropDownList ddlNewThickness =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewThickness");
DropDownList ddlNewCore =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewCore");
DropDownList ddlNewSize =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewSize");
TextBox txtNewColor =
(TextBox)gvBFMats.FooterRow.FindControl("txtNewColor");
TextBox txtNewQty =
(TextBox)gvBFMats.FooterRow.FindControl("txtNewQty");
DropDownList ddlNewFinish =
(DropDownList)gvBFMats.FooterRow.FindControl("ddlNewFinish");
TextBox txtNewExtra =
(TextBox)gvBFMats.FooterRow.FindControl("txtNewExtra");
// Set the SQLDataSource's InsertParameters values
e.InputParameters["MatManufacturerID"] =
Convert.ToInt32(ddlNewMfr.SelectedValue);
e.InputParameters["MatThicknessID"] =
Convert.ToInt32(ddlNewThickness.SelectedValue);
e.InputParameters["MatCoreID"] =
Convert.ToInt32(ddlNewCore.SelectedValue);
e.InputParameters["MatSizeID"] =
Convert.ToInt32(ddlNewSize.SelectedValue);
e.InputParameters["MatFinishPrePostID"] =
Convert.ToInt32(ddlNewFinish.SelectedValue);
string strNewColor = null;
if (!string.IsNullOrEmpty(txtNewColor.Text))
strNewColor = txtNewColor.Text;
e.InputParameters["MatFinishColor"] = strNewColor;
int? intNewQty = null;
if (!string.IsNullOrEmpty(txtNewQty.Text))
intNewQty = Convert.ToInt32(txtNewQty.Text);
e.InputParameters["MatQty"] = intNewQty;
string strNewExtra = null;
if (!string.IsNullOrEmpty(txtNewExtra.Text))
strNewExtra = txtNewExtra.Text;
e.InputParameters["MatNumExtraSheets"] = strNewExtra;
}
Specifically, I get the red squiggly under the gvBFMats in the (Control)gvBFMats.FooterRow.FindControl("Control ID"); that says "The name 'gvBFMats' does not exist in the current context." I'm only guessing that it doesn't like the call to the GridView when it's nested inside a FormView template. Is there a way to pass this context along programatically?
You're right about it not recognizing the name gvBFMats because it's embedded in a template. Only "top-level", non-embedded controls will be treated in Code Behind as if they had been explicitly declared. Controls declared in a template will not. The compiler doesn't recognize those names.
There's a reason for this. Imagine you have a control called TextBox1 in one of the ItemTemplates for a repeating control. You bind it. Your page's control tree now has dozens of controls with the ID TextBox1. If you want to refer to TextBox1, how does it know which one you mean?
So. What can you do in your situation? Well, BFMatsSQL_Inserting and gvBFMats_RowCommand are both event handlers, so you can't change their signatures.
But, you can make use of them belonging to the same class, and use a module-level variable to hold the reference to gvBFMats. Like this:
private GridView gvBFMats;
protected void gvBFMats_RowCommand(object sender, GridViewCommandEventArgs e)
{
gvBFMats = [your form view].Row.FindControl("gvBFMats") as GridView;
if (e.CommandName == "Insert" && Page.IsValid)
{
BFMatsSQL.Insert();
}
}
Now, BFMatsSQL_Inserting will be able to refer to gvBFMats, and it should have a value.

Stop DropDownList SelectedIndexChanged Event firing on FormView command

I have a dropdown list inside an editItemTemplate. The Dropdownlist onSelectedIndexChanged event fires on change like I want. However it also will fire when I submit the form.
********UPDATE ************
Per Saechel comment below, I started to investigate further. Here it describes it can be done. http://blog.programmingsolution.net/net-windows-application/selectionchangecommitted-and-selectedindexchanged-events-system-nullreferenceexception-while-closing-windows-form/
BUT, I tried it and it didn't even fire the event.
I checked http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.dropdownlist(v=vs.110).aspx and they don't list the event.
My goal is to let the user enter the values as a % of the Total or actual as actual tons and then toggle back and forth. The end value that will be inserted into the DB will be in tons.
I want to either:
a) not fire the "onSelectedIndexChanged" event
b) Some how determine if I am on the same index and have an if statement to skip everything
c) A better way of going about this that I don't know of.
I tried verifying via the ViewState the Dropdown's current index and skip the code if it was the same but couldn't find the value. Maybe help me figure out how to get that value? Searched around and could not find how do do it.
I tried: `var vs = ViewState["ddl_units"].ToString(); and some other variations as I needed to find the control via FindControl
.aspx:
<asp:Panel ID="pnlRecycledMaterialsReceivedForm" runat="server" Visible="false">
<asp:FormView ID="fvAddRecycledMaterialsReceived" runat="server" SkinID="annualReportFormview" EnableViewState="false"
HeaderText="Selected Recycled Materials Received Detail" DataKeyNames="RecycleDetailId" DefaultMode="Insert"
DataSourceID="odsRecycledMaterialsReceivedDetail" OnDataBound="fvAddRecycledMaterialsReceived_DataBound"
OnItemCommand="fvAddRecycledMaterialsReceived_ItemCommand" OnItemInserted="fvAddRecycledMaterialsReceived_ItemInserted"
OnItemUpdated="fvAddRecycledMaterialsReceived_ItemUpdated" OnItemDeleted="fvAddRecycledMaterialsReceived_ItemDeleted">
<EditItemTemplate>
<asp:TextBox ID="tbxRecycledTotalWasteQuantity" runat="server" Text='<%# Bind("TotalWasteQuantity") %>' Width="64px"></asp:TextBox>
<asp:TextBox ID="tbxRecycledWasteCommercialQuantity" runat="server" Text='<%# Bind("CommercialQuantity") %>' Width="64px"></asp:TextBox>
<asp:TextBox ID="tbxRecycledWasteResidentialQuantity" runat="server" Text='<%# Bind("ResidentialQuantity") %>' Width="64px"></asp:TextBox>
<asp:DropDownList ID="ddl_Units" runat="server" AutoPostBack="true" OnSelectedIndexChanged="ddl_Units_SelectedIndexChanged">
<asp:ListItem Value="" Text="" Enabled="false" />
<asp:ListItem Text="Tons" Value="1" />
<asp:ListItem Text="Percent" Value="9" />
</asp:DropDownList>
<asp:LinkButton ID="lbtnWasteReceivedUpdate" runat="server" Text="Update" CommandName="Update"
ValidationGroup="RecycledWasteReceivedDetail" Font-Bold="True" />
<asp:LinkButton ID="lbtnWasteReceivedInsertCancel" runat="server" Text="Cancel" CausesValidation="False" CommandName="Cancel" />
</EditItemTemplate>
</asp:FormView>
</asp:Panel>
.cs:
protected void ddl_Units_SelectedIndexChanged(object sender, EventArgs e)
{
TextBox tbxRecycledTotalWasteQuantity = (TextBox)fvAddRecycledMaterialsReceived.FindControl("tbxRecycledTotalWasteQuantity");
TextBox tbxRecycledWasteResidentialQuantity = (TextBox)fvAddRecycledMaterialsReceived.FindControl("tbxRecycledWasteResidentialQuantity");
var d_TotalWasteQuantity = Convert.ToDecimal(tbxRecycledTotalWasteQuantity.Text);
ResidentialQuantity = Convert.ToDecimal(tbxRecycledWasteResidentialQuantity.Text);
DropDownList ddl_units = (DropDownList)fvAddRecycledMaterialsReceived.FindControl("ddl_units");
if (ddl_units.SelectedIndex.ToString() == "2")
{
//2 = percent
//Take tb value and convert to percent
//300/700 * 100
tbxRecycledWasteResidentialQuantity.Text = ((ResidentialQuantity / d_TotalWasteQuantity) * 100).ToString();
//ResidentialQuantity = ResidentialQuantity * (d_TotalWasteQuantity / 100);
}
else
{
//Else 'tons' was chosen. Convert value(%) to tons.
//700 * (43/100) = 301
ResidentialQuantity = d_TotalWasteQuantity * (ResidentialQuantity / 100);
tbxRecycledWasteResidentialQuantity.Text = ResidentialQuantity.ToString();
//tbxRecycledWasteResidentialQuantity.Text = "Tons";
}
}
Try using the SelectionChangeCommitted Event.
This will not trigger on form load but triggers on selectionchange

Get selected product from a datalist in visual studio and SQL

Im trying to learn asp and C# and trying to make a webshop.
I have a working dataset and datalist
<asp:DataList ID="DataList1" runat="server" DataKeyField="ID" DataSourceID="ObjectDataSource1" RepeatDirection="Horizontal" CellSpacing="10">
<ItemTemplate>
<asp:Image ImageUrl='<%# Eval("PicURL") %>' runat="server" ID="PicURLImage" Width="150px" /><br />
<asp:LinkButton ID="AddProduct" Text='<%# Eval("ProductName") %>' runat="server" OnClick="AddProduct_Click"></asp:LinkButton><br />
</ItemTemplate>
</asp:DataList>
I want to press this linkbutton and then It eventually should add this product to a shoppingcart. But right now I just need help to get the selected product row from the datalist that is using a datasource that is connected to the database.
When I click the link I want to execute this code:
Data.DataSet1.ProductDataTable pTable = new Data.DataSet1TableAdapters.ProductTableAdapter().GetDataByCategory();
protected void AddProduct_Click(object sender, EventArgs e)
{
// Add product to the shopping cart
//Class //method
ShoppingCart.Instance.AddItem(THIS IS HE QUESTION I NEED HELP WITH!);
// Redirect the user to view their shopping cart
Response.Redirect("ViewCart.aspx");
}
public void AddItem(int productId)
{
// Create a new item to add to the cart
CartItem newItem = new CartItem(productId);
// If this item already exists in our list of items, increase the quantity
// Otherwise, add the new item to the list
if (Items.Contains(newItem))
{
foreach (CartItem item in Items)
{
if (item.Equals(newItem))
{
item.Quantity++;
return;
}
}
}
else
{
newItem.Quantity = 1;
Items.Add(newItem);
}
}
Do you guys need more information? Do you have any tips or suggestions? Im stuck >__<
Here is how I would do this.
add CommandName attribute to your button (you will not longer need the OnClick event handler for the button) and add event handler for ItemCommand on DataList:
<asp:DataList ID="DataList1" runat="server" DataKeyField="ID" DataSourceID="ObjectDataSource1" RepeatDirection="Horizontal" CellSpacing="10" OnItemCommand="Item_Command">
<ItemTemplate>
<asp:Image ImageUrl='<%# Eval("PicURL") %>' runat="server" ID="PicURLImage" Width="150px" /><br />
<asp:LinkButton CommandName="AddProduct" ID="AddProduct" Text='<%# Eval("ProductName") %>' runat="server" OnClick="AddProduct_Click"></asp:LinkButton><br />
</ItemTemplate>
</asp:DataList>
Change your c# to define Item_Command
void Item_Command(Object sender, DataListCommandEventArgs e)
{
if (e.CommandName == "AddProduct")
{
// e.Item.ItemIndex is the selected index
// DataList1.DataKeys[e.Item.ItemIndex] will return the product id
}
}
Also you can refer to MSDN for further details.
protected void Btn_Command(object sender, CommandEventArgs e)
{
DataListItem dli = (DataListItem)(sender as Control).Parent.Parent;
int indx = dli.ItemIndex;
}

Drop Down List and Selected Value

I'm having a very hard time figuring out what I'm doing wrong here. In my Edit Item Template I have the following code for my drop down list:
<asp:DropDownList ID="dd_is_active" runat="server" AppendDataBoundItems="true"
DataValueField="Enabled">
<asp:ListItem Text="Yes" Value="1"></asp:ListItem>
<asp:ListItem Text="No" Value="0"></asp:ListItem>
</asp:DropDownList>
<asp:HiddenField ID="is_activeTextBox" runat="server" Value='<%# Bind("Enabled") %>' />
Here is my aspx.cs code:
protected void ListView1_ItemInserting(object sender, ListViewInsertEventArgs e)
{
e.Values["SUB_last_modified_date"] = DateTime.Now.ToString();
e.Values["SUB_last_modified_by_user_id"] = HttpContext.Current.User.Identity.Name;
e.Values["SUB_last_modified_by_user_name"] = Session["UserName"].ToString();
e.Values["Enabled"] = ((DropDownList)(sender as ListView).InsertItem.FindControl("dd_is_active")).SelectedValue;
e.Values["Category_ID"] = ((DropDownList)(sender as ListView).InsertItem.FindControl("dd_category")).SelectedValue;
}
protected void ListView1_ItemUpdating(object sender, ListViewUpdateEventArgs e)
{
e.NewValues["SUB_last_modified_date"] = DateTime.Now.ToString();
e.NewValues["SUB_last_modified_by_user_id"] = HttpContext.Current.User.Identity.Name;
e.NewValues["SUB_last_modified_by_user_name"] = Session["UserName"].ToString();
}
It seems something is either missing from my .cs code or I have the values of 1 and 0 bound incorrectly in the html code. This exact same code works for the Insert Item Template, but the Update (or Edit Item Template) is not working correctly.
When I try to edit an item in my table I get an error stating the input string is in an incorrect format. I know it's trying to bind the Text of "Yes" or "No" but I need to ind to the Values of either "0" or "1". Any help is greatly appreciated!
I think your syntax is wrong for HiddenField value.
Instead of this
<asp:HiddenField ID="is_activeTextBox" runat="server" Value='<%# Bind("Enabled") '>' />
It should be
<asp:HiddenField ID="is_activeTextBox" runat="server" Value='<%# Bind("Enabled")%>' />

Categories