How to get textbox value from datalist? - c#

I am using datalist to show product id, name and a textbox("Qty") allow user to input order Qty. I got System.NullReferenceException: Object reference not set to an instance of an object error when user click an item to order. My datasource provides only 2 columns (product id and name). I added a textbox("Qty") and a button to the datalist. I can not get the value from the textbox("Qty") to submit. Could it be my datasource does not contain the "Qty" column thus FindControl alway return null value? How do I fix the problem? Thanks. Here is my code:
<asp:DataList ID="DataList1" runat="server" CellPadding="10" DataKeyField="product_id" DataSourceID="SqlDataSource1" RepeatColumns="2">
<ItemTemplate>
<asp:Label ID="product_id" runat="server"
Text='<%# Eval("product_id") %>' /><br/>
<asp:Label ID="product_name" runat="server"
Text='<%# Eval("product_name") %>' />
<br />
<asp:TextBox ID="Qty" runat="server"></asp:TextBox>
<asp:Button ID="ButtonAddToCart" runat="server" Text="Add to Cart" CommandName="addtocart2" OnCommand="DataList1_ItemCommand"
/>
</ItemTemplate>
</asp:DataList>
Here is the code for the button:
public void DataList1_ItemCommand(object source, System.Web.UI.WebControls.CommandEventArgs e)
{
var qtytxtbox = DataList1.FindControl("Qty") as TextBox;
// qtytxtbox always return null, why?
}

Your handler doesn't look correct. you should use DataListCommandEventArgs as second parameter. so try something like this
Markup:
<asp:DataList ID="DataList1" runat="server" OnItemCommand="DataList1_ItemCommand" vCellPadding="10" DataKeyField="product_id" DataSourceID="SqlDataSource1" RepeatColumns="2">
Then Add command name in button
<asp:Button ID="ButtonAddToCart" runat="server" Text="Add to Cart" CommandName="addtocart2" />
and code behind
public void DataList1_ItemCommand(object source, DataListCommandEventArgs e)
{
if(e.CommandName.Equals("addtocart2")
{
TextBox qtytxtbox = (TextBox)(e.Item.FindControl("Qty"));
}
}

Related

How can I make a required field work only when clicking in the button submit?

I am creating a form with a table that the user will register all clients that he wants to put there. And I am using a required field validator for two textboxes which the user will have to fill with the information. But the problem is when I want to update the textbox with new information, the required fields ask me to fill them with new text, and those are not from the textbox that I am editing.
The problem appears here :
The form requires me to fill the other textbox below if I want to update the other ones, but I want that when I am updating a textbox it does not require me to fill the other textbox.
My code :
<asp:TemplateField HeaderText="Nome do Cliente">
<ItemTemplate>
<asp:Label ID="lblClienteNome" runat="server" Text='<%# Eval("cliente_nome")%>'/>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtclienteNome" runat="server" Text='<%# Eval("cliente_nome")%>'/>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="txtbnome" runat="server" />
<asp:RequiredFieldValidator ID="valName" ControlToValidate = "txtbnome"
runat="server" ErrorMessage="*Required" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText = "E-mail do Cliente">
<ItemTemplate>
<asp:Label ID="lblClienteEmail" runat="server" Text='<%# Eval("cliente_email")%>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtclienteEmail" runat="server" Text='<%# Eval("cliente_email")%>'/>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="txtbemail" runat="server"/>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate = "txtbemail"
runat="server" ErrorMessage="*Required" />
<asp:LinkButton ID="LinkButton1" CommandName="AddNew" runat="server" CssClass="btn btn-large btn-info pull-right">
<i class="glyphicon glyphicon-plus"></i> Adicionar
</asp:LinkButton>
</FooterTemplate>
How can I make it not ask me to fill the other textboxes when I am updating the fields?
You can associate your RequiredFieldValidator controls with a specific ValidationGroup; then associate the same ValidationGroup with the corresponding Button or LinkButton:
<asp:RequiredFieldValidator ID="valName" ControlToValidate = "txtbnome"
runat="server" ErrorMessage="*Required" ValidationGroup="ValidationGroup1" />
<asp:LinkButton ID="LinkButton1" CommandName="AddNew" runat="server"
CssClass="btn btn-large btn-info pull-right" ValidationGroup="ValidationGroup1">
<i class="glyphicon glyphicon-plus"></i> Adicionar
</asp:LinkButton>
Each LinkButton will cause the RequiredFieldValidator controls in their own ValidatorGroup to run when clicked; others will not run.
You could create a custom Attribute:
public class ButtonRequiredAttribute : RequiredAttribute
{
private readonly string _buttonName;
public ButtonRequiredAttribute(string buttonName)
{
_buttonName = buttonName;
}
public override bool IsValid(object value)
{
var form = HttpContext.Current.Request.Form;
//only validating if "add"-Button is pressed
if (form[_buttonName] != null)
{
return base.IsValid(value);
}
//When no "add"-Button is pressed, no validation is needed
return true;
}
}
Usage:
[ButtonRequiredAttribute("NameOfYourButton")]
All answers here were very useful to me, but I found a simpler way to solve my problem.
I forgot to show the code of the two buttons, update and delete, with them I simply used the property of CausesValidation to let when I clicked on them, to be not required to fill in the texts to update or delete.
So, my code with the two buttons is now something like that :
<asp:CommandField ShowEditButton="True" ShowDeleteButton="true" CausesValidation="False"/>
To more information, I found it here in this link to be helpful :
https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.button.causesvalidation.aspx

Hyperlink in Gridview in c#?

I want to extract the article id from a gridview row when I click on the hyperlink. My goal is to be able to capture the article id field of a specific row when I click on the hyperlink in gridview.
This is what I tried so far but for some reason, it doesn't go to the codebehind when I click on the hyperlink.
<asp:GridView ID="Rssfeed" runat="server" AutoGenerateColumns="false" onrowcommand="grid_RowCommand" CssClass="Grid">
<Columns>
<asp:TemplateField HeaderText="Info">
<ItemTemplate>
Articleid:
<asp:Label ID="Label1" Text='<%#Eval("articleid") %>' runat="server" />
<br />
Title :
<asp:Label ID="Label2" Text='<%#Eval("title") %>' runat="server" />
<br />
Link:
<asp:HyperLink ID="hlnkFile" runat="server" target="_blank" CommandName="Select" NavigateUrl='<%# Eval("link") %>' Text='<%# Eval("link") %>'></asp:HyperLink> <br />
Publicationdate:
<asp:Label ID="Label3" Text='<%#Eval("publicationdate") %>' runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
public void grid_RowCommand(Object sender, GridViewCommandEventArgs e)
{
// If multiple ButtonField column fields are used, use the
// CommandName property to determine which button was clicked.
if (e.CommandName == "Select")
{
// Convert the row index stored in the CommandArgument
// property to an Integer.
int index = Convert.ToInt32(e.CommandArgument);
// Get the last name of the selected author from the appropriate
// cell in the GridView control.
GridViewRow selectedRow = Rssfeed.Rows[index];
}
}
This example can help:
<ItemTemplate>
Link:
<asp:LinkButton ID="lbFile" CommandName="Select" runat="server"><%# Eval("link") %></asp:LinkButton>
</ItemTemplate>
code behind
public void Rssfeed_RowCommand(Object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
// get text from LinkButton e.g. URL as in question
string link = ((LinkButton)selectedRow.FindControl("lbFile")).Text;
// Redirect to the URL link
Response.Redirect(link);
}
}

Dropdown does not populate when last item deleted from gridview

I am having trouble determining where the bug is for this problem.
I have an ASP.NET Master.Page web application that has a Gridview. I am using the jquery-chosen plugin for a dropdown list in the EmptyDataTemplate (or FooterControl if there is data).
On initialization if there is no data for the grid, the dropdown is populated and displays correctly. If the grid has items in it and I delete all of them, so that there is no data, the dropdown does not display any data. The DataBound event is called and the DataTable has all of the correct data in it. It is bound to the dropdown. But do items appear in the list.
This is my markup:
<div id="DelegateGridWrapper">
<asp:GridView ID="DelegateInfoGridView" runat="server"
AutoGenerateColumns="false" Caption="Delegate Information"
CaptionAlign="Top" CssClass="grid" RowStyle-Wrap="true"
HorizontalAlign="Left" ShowFooter="true"
AllowPaging="true" PageSize="5" ShowHeaderWhenEmpty="false" onrowediting="DelegateInfoGridView_RowEditing"
onrowcancelingedit="DelegateInfoGridView_RowCancelingEdit" onrowdeleting="DelegateInfoGridView_RowDeleting"
onrowupdating="DelegateInfoGridView_RowUpdating"
ondatabound="DelegateInfoGridView_DataBound"
onrowcommand="DelegateInfoGridView_RowCommand">
<Columns>
<asp:TemplateField HeaderText="Recipient ID">
<ItemTemplate>
<asp:Label ID="deligvLblRecipientID" runat="server" Text='<%# Bind("RecipientID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Delegate" ItemStyle-Wrap="false">
<ItemTemplate>
<asp:Label ID="deligvLblRecipientName" runat="server" Text='<%# Bind("RecipientName") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:DropDownList ID="deligvDDLRecipientName" runat="server" ClientIDMode="Static"
data-placeholder="Choose delegate…" class="chosen-single">
</asp:DropDownList>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Active">
<ItemTemplate>
<asp:Label ID="deligvLblActive" runat="server" Text='<%# (Boolean.Parse(Eval("Active").ToString())) ? "Yes" : "No" %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="deligvDDLActive" runat="server" Text='<%# (Boolean.Parse(Eval("Active").ToString())) ? "Yes" : "No" %>'>
<asp:ListItem>Yes</asp:ListItem>
<asp:ListItem>No</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
<FooterTemplate>
<asp:DropDownList ID="deligvDDLActiveInsert" runat="server">
<asp:ListItem Selected="True">Yes</asp:ListItem>
<asp:ListItem>No</asp:ListItem>
</asp:DropDownList>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Action" ItemStyle-Wrap="false" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button ID="deligvEditButton" runat="server" CausesValidation="False" CommandName="Edit"
Text="Edit" CssClass="gridActionbutton">
</asp:Button>
<asp:Button ID="deligvDeleteButton" runat="server" CausesValidation="False" CommandName="Delete" ClientIDMode="Static"
Text="Delete" CssClass="gridActionbutton" OnClientClick="return confirm('Are you sure you want to delete this Delegate Information?')" >
</asp:Button>
</ItemTemplate>
<EditItemTemplate>
<asp:Button ID="deligvUpdateButton" runat="server" CausesValidation="False" CommandName="Update"
Text="Update" CssClass="gridActionbutton"></asp:Button>
<asp:Button ID="deligvCancelButton" runat="server" CausesValidation="False" CommandName="Cancel"
Text="Cancel" CssClass="gridActionbutton"></asp:Button>
</EditItemTemplate>
<FooterTemplate>
<asp:Button ID="deligvAddButton" runat="server" CommandName="Add" Text="Add Delegate" Width="90%" CausesValidation="false"
CssClass="gridActionbutton">
</asp:Button>
</FooterTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
<tr>
<th>Recipient ID</th>
<th>Delegate</th>
<th>Active</th>
<th>Action</th>
</tr>
<tr>
<td colspan="4" style="text-align:center;">
No Delegates were found for you. Delegates can be added by clicking the 'Add Delegate' Button.
</td>
</tr>
<tr>
<td></td>
<td>
<asp:DropDownList ID="deligvDDLRecipientName" runat="server" ClientIDMode="Static"
data-placeholder="Choose delegate…" class="chosen-single">
</asp:DropDownList>
</td>
<td>
<asp:DropDownList ID="deligvDDLActiveInsert" runat="server">
<asp:ListItem Selected="True">Yes</asp:ListItem>
<asp:ListItem>No</asp:ListItem>
</asp:DropDownList>
</td>
<td>
<asp:Button ID="deligvAddButtonEmpty" runat="server" CommandName="Add" Text="Add Delegate" Width="90%" CausesValidation="false"
CssClass="gridActionbutton">
</asp:Button>
</td>
</tr>
</EmptyDataTemplate>
</asp:GridView>
This is my DataBound event:
protected void DelegateInfoGridView_DataBound(object sender, EventArgs e)
{
try
{
m_strUserID = CommonMethods.ParseUserID(User.Identity.Name);
//Get the Footer controls that have the new entry data
Control tFooterControls = getFooterControls(DelegateInfoGridView);
DropDownList ddlRecipientNames = tFooterControls.FindControl("deligvDDLRecipientName") as DropDownList;
m_strXmlTableData = m_pagingClient.GetAllPossibleDelegates(m_strUserID);
DataTable tdtAllDelegates = CommonMethods.ParseXML(m_strXmlTableData);
ddlRecipientNames.DataSource = tdtAllDelegates;
ddlRecipientNames.DataTextField = "RecipientName";
ddlRecipientNames.DataValueField = "RecipientID";
ddlRecipientNames.DataBind();
ddlRecipientNames.Items.Insert(0, new ListItem("", "0"));//This is needed for the jquery-chosen dropdown to add data-holder text
}
catch (Exception ex)
{
//TO DO: Response.Redirect("~/Error.aspx");
}
}
Why won't the dropdown display the items after all items are deleted but will correctly display if initially there are no items in the gridview to display?
I tried triggering an update for the chosen dropdown but that is called initially, before the data is retrieved.
I don't know if there is a bug in the code-behind or do I need to add something in the javascript.
Thanks.
UPDATE
The problem is not with the chosen plugin. I removed the attribute from the DropDown list that changes it to a 'chosen' style and the problem still exists. So the asp:DropDownList will not populate after the user deletes all of the items in the grid. But if the grid is initialized with no items, the DropDown is correctly populated.
UPDATE
I got a suggestion to use the 'RowDeleted' event to bind the dropdown. However, the event is not firing. I added the event to the markup:
onrowdeleted="DelegateInfoGridView_RowDeleted"
This is the event that is never called:
protected void DelegateInfoGridView_RowDeleted(object sender, GridViewDeletedEventArgs e)
{
try
{
m_strUserID = CommonMethods.ParseUserID(User.Identity.Name);
//Get the Footer controls that have the new entry data
Control tFooterControls = getFooterControls(DelegateInfoGridView);
DropDownList tddlRecipientNames = tFooterControls.FindControl("deligvDDLRecipientName") as DropDownList;
m_strXmlTableData = m_pagingClient.GetAllPossibleDelegates(m_strUserID);
DataTable tdtAllDelegates = CommonMethods.ParseXML(m_strXmlTableData);
tddlRecipientNames.DataSource = tdtAllDelegates;
tddlRecipientNames.DataTextField = "RecipientName";
tddlRecipientNames.DataValueField = "RecipientID";
tddlRecipientNames.DataBind();
tddlRecipientNames.Items.Insert(0, new ListItem("", "0"));//This is needed for the jquery-chosen dropdown to add data-holder text
}
catch (Exception ex)
{
//TO DO: Response.Redirect("~/Error.aspx");
}
}
What is different about the RowDeleted event that it will not fire?
The problem was that I was checking if the FooterControl was null. If it was, I got the EmptyTemplateData control. When you delete all of the rows, the FooterControl is not null, but it needs to get the EmptyTemplateData control.
So, I changed the logic to check for Grid Row Count > 0 instead of a null FooterControl.
That fixed the problem..

Keep value after postback updatepanel

I have a textbox which is inside a updatepanel -> detailsview. When I click insert I basically call a method to update DB. Now I'm trying to save the value typed in the textbox in the textbox so I don't lose it.
Shortly I wanna set the textbox value, with the value that is inserted.
My aspx:
<asp:UpdatePanel runat="server" ID="insert" UpdateMode="Conditional">
<ContentTemplate>
<table>
<tr>
<Fields>
<td class="style1">
<asp:DetailsView ID="DetailsView1" runat="server" Height="50px" Width="500px" AutoGenerateRows="False"
DataKeyNames="strPositionId,nFolderId,tmVaRPosition" DataSourceID="ODSManualPosVaR"
OnItemInserted="DetailsView1_ItemInserted" OnItemInserting="DetailsView1_ItemInserting"
DefaultMode="Insert" SkinID="detailsviewSkin" EnableModelValidation="True">
<asp:TemplateField HeaderText="Name" SortExpression="strPositionName">
<InsertItemTemplate>
<asp:TextBox ID="strPositionName" Width="380px" MaxLength="49" runat="server" Text='<%# Bind("strPositionName") %>'></asp:TextBox>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Width="380px" Text='<%# Bind("strPositionName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</asp:DetailsView>
</td>
</Fields>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
My Page_Load:
protected new void Page_Load(object sender, EventArgs e)
{
base.Page_Load(sender, e);
strSystemId = Request["nSystemId"];
CheckPermission(strSystemId);
if (!IsPostBack || !PageHeader1.SystemId.Equals(strSystemId))
{
RefreshGrid();
DetailsView1.DataBind();
}
}
When click insert:
protected void DetailsView1_ItemInserted(object sender, DetailsViewInsertedEventArgs e)
{
UpdateDB();
//Trying to store the textbox value in a session variable
Session["Test"] = ((TextBox)DetailsView1.FindControl("strPositionName")).Text;
KeepValues();
}
KeepValues:
private void KeepValues()
{
var txtName = (TextBox)DetailsView1.FindControl("strPositionName");
var name = Session["Test"].ToString();
txtName.Text = name;
}
When I debug it stops at KeepValues and the Session variable is working. But I still can't set the textbox.text to it.
Why does this not work? Is it because of a postback? All I want is the value inside strPositionName to be stored in a variable (working) and then set as textbox.text

how to update listview from a linqdatasource using the event ListView1_SelectedIndexChanged

I have a linqdatasource witch perform a ListView1 list. The listview change when the user select a doctor name from a Dropdownlist. I attached a OnSelectedIndexChanged="ListView1_SelectedIndexChanged" event to it.
The column of the listview1 are apointmentId, doctorName, dateApointment, clientName and a checkbox.
I want to update the row which got selected by the checkbox (basically the user selected a date for his apointment).
<asp:LinqDataSource ID="LinqDataSource1" runat="server" ContextTypeName="ApointmentDataContext"
EnableDelete="True" EnableInsert="True" EnableUpdate="True" EntityTypeName=""
TableName="Apointment" AutoGenerateWhereClause="True">
<WhereParameters>
<asp:ControlParameter
Name="doctorName"
ControlID="DropDownList1"
PropertyName="SelectedValue"
Type="String" />
</WhereParameters>
</asp:LinqDataSource>
<div class="center">
<asp:Label ID="lblDoctorName" runat="server" Text="Choose a doctor name"> </asp:Label>
<div class="value-right">
<asp:DropDownList ID="DropDownList1" runat="server" Width="180px" AutoPostBack="true" >
<asp:ListItem Text="Doctor A" Value="Doctor A" />
<asp:ListItem Text="Doctor B" Value="Doctor B" />
<asp:ListItem Text="Doctor C" Value="Doctor C" />
</asp:DropDownList>
</div>
</div> <br/><br/>
<asp:ListView ID="ListView1" runat="server" DataKeyNames="apointmentId"
DataSourceID="LinqDataSource1" InsertItemPosition="LastItem"
OnSelectedIndexChanged="ListView1_SelectedIndexChanged" >
<AlternatingItemTemplate>
<tr style="">
<td>
<asp:Button ID="EditButton" runat="server" CommandName="Edit" Text="Edit" />
</td>
<!--<td>
<asp:Label ID="ApointmentIdLabel" runat="server" Text='<%#
Eval("ApointmentId") %>' />
</td> -->
<td>
<asp:Label ID="doctorName" runat="server" Text='<%# Eval("doctorName") %>' />
</td>
<td>
<asp:Label ID="dateLabel" runat="server" Text='<%# Eval("dateApointment", "{0:dd-MM-
yyyy}") %>' />
</td>
<td>
<asp:Label ID="ClientLabel" runat="server" Text='<%# Eval("clientName") %>' />
</td>
<input id="MyCheckBox" value='<%# Eval("apointmentId") %>'
type="checkbox" runat="server" />
The following code will list all the available dates from the selected doctors. The goal is the user will select an available date (by checking the checkbox). Now I want to be able to update this row in the apointement table. I am missing the code to be able to use the ListView1 properties.
protected void ListView1_SelectedIndexChanged(object sender, EventArgs e)
{
using (ApointmentDataContext db = new ApointmentDataContext())
{
Listview1.
}
}
When I put ListView1 here I got the error message The name ListView1 does not exist in the current context.
I will like to be able to retrieve the guid or the ApointmentId to be able to update the selected row.
I got the checkbox selection by doing this. Maybe we can do something here ?
protected void btnSubmit_Click(object sender, EventArgs e)
{
int iCptCheckBox = 0;
int indxChkBox = 0;
foreach (ListViewDataItem item in ListView1.Items)
{
var chk = item.FindControl("MyCheckBox") as System.Web.UI.HtmlControls.HtmlInputCheckBox;
if (chk != null && chk.Checked)
{
indxChkBox = Convert.ToInt32(chk.Value);
iCptCheckBox++;
}
}
}
Thanks for your help to guide me to resolve my issue.
I believe you have two issues here:
That your listview is not visible in your code behind, to solve this please clean up your page designer.cs file and make a small change ( could add a space) in aspx, and regenerate the designer file. This should solve this issue.
Second issue getting the selected item, you should use SelectedDataKey property of listview to get the selected id. I can see that you have appointmentid as the datakey name.

Categories