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
Related
I have an ASP.NET datagrid with a few rows in it. I'd like some of the rows to be editable, but not all of them (based on a particular data item in that row).
Originally, I was doing this with a ButtonColumn, but I wasn't able to turn that on or off for specific rows.
Here's what I have now:
<asp:DataGrid ID="grid1" runat="server" AutoGenerateColumns="false" EnableViewState="true" CssClass="GridviewControlStyle" CellSpacing="0" CellPadding="4" HeaderStyle-CssClass="HeaderStyle"
OnEditCommand="grid1_EditCommand" OnUpdateCommand="grid1_UpdateCommand" OnCancelCommand="grid1_CancelCommand" OnItemDataBound="grid1d_ItemDataBound">
<Columns>
<asp:TemplateColumn>
<HeaderTemplate>
<strong><%# Resources.Status %></strong>
</HeaderTemplate>
<ItemTemplate>
<%# DataBinder.Eval(Container, "DataItem.STATUS") %>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn>
<HeaderTemplate>
<strong><%# Resources.Amount %></strong>
</HeaderTemplate>
<ItemTemplate>
<%# DataBinder.Eval(Container, "DataItem.AMT") %>
</ItemTemplate>
<EditItemTemplate>
<asp:CustomValidator ID="cvAmountGrid" OnServerValidate="cvAmountGrid_ServerValidate" Display="None" runat="server" ControlToValidate="txtAmount" />
<asp:TextBox ID="txtAmount" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.AMT") %>' CssClass="small" />
</EditItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn>
<ItemTemplate>
<asp:Button runat="server" Text="Edit" ID="btnEdit" Visible='<%# IsRowEditable(Eval("STATUS").ToString()) %>' CommandName="Edit" />
<asp:Button runat="server" Text="Update" ID="btnUpdate" Visible="false" CommandName="Update" />
<asp:Button runat="server" Text="Cancel" ID="btnCancel" Visible="false" CommandName="Cancel" />
</ItemTemplate>
</asp:TemplateColumn>
</asp:DataGrid>
Code Behind:
public bool IsRowEditable(string status)
{
return !status.Equals("Locked", StringComparison.OrdinalIgnoreCase);
}
protected void grid1_EditCommand(object source, DataGridCommandEventArgs e)
{
grid1.EditItemIndex = e.Item.ItemIndex;
grid1.DataBind();
TextBox t = e.Item.FindControl("txtAmount") as TextBox;
t.Visible = true; //this can't be found
Button b = e.Item.FindControl("btnEdit") as Button;
b.Visible = false;
Button u = e.Item.FindControl("btnUpdate") as Button;
u.Visible = true;
Button c = e.Item.FindControl("btnCancel") as Button;
c.Visible = true;
}
There are a few problems I've run into with this approach. Firstly, calling DataBind seems to reset the visibility status I've set on any buttons. If I don't databind, then my editable column doesn't show as editable. So, I try to set the textbox to be editable manually; but findcontrol returns null so I can't. What am I doing wrong here?
Another way to achieve it;
There I removed data validation and column name data binders to avoid
complexities. You can try below with them.
Update and cancel buttons are under EditItemTemplate so they will appear at edit event.
.ASPX
<asp:DataGrid ID="grid1" runat="server" AutoGenerateColumns="false" EnableViewState="true" CssClass="GridviewControlStyle" CellSpacing="0" CellPadding="4" HeaderStyle-CssClass="HeaderStyle"
OnEditCommand="grid1_EditCommand" OnUpdateCommand="grid1_UpdateCommand" OnCancelCommand="grid1_CancelCommand" OnItemDataBound="grid1d_ItemDataBound">
<Columns>
<asp:TemplateColumn>
<HeaderTemplate>
<strong>Status</strong>
</HeaderTemplate>
<ItemTemplate>
<%# DataBinder.Eval(Container, "DataItem.STATUS") %>
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn>
<HeaderTemplate>
<strong>Amount</strong>
</HeaderTemplate>
<ItemTemplate>
<%# DataBinder.Eval(Container, "DataItem.AMT") %>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtAmount" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.AMT") %>' CssClass="small" ReadOnly="false"/>
</EditItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn>
<ItemTemplate>
<asp:Button runat="server" Text="Edit" ID="btnEdit" Visible='<%# IsRowEditable(Eval("STATUS").ToString()) %>' CommandName="Edit" />
</ItemTemplate>
<EditItemTemplate>
<asp:Button runat="server" Text="Update" ID="btnUpdate" CommandName="Update" />
<asp:Button runat="server" Text="Cancel" ID="btnCancel" CommandName="Cancel" />
</EditItemTemplate>
</asp:TemplateColumn>
</Columns>
Code Behind
There you don't have set the visibility manually. EditItemTemplate will handle it at the edit event and when the user clicks cancel or update the Edit template will be replaced with the view.
I used some hardcoded list of Data Items and you can replace it with actual data source and try.
List<DataItem> t;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadData();
}
}
private void LoadData()
{
t = new List<DataItem>();
DataItem t1 = new DataItem() { AMT = 5, STATUS = "LOCKED" };
DataItem t2 = new DataItem() { AMT = 15, STATUS = "OPEN" };
DataItem t3 = new DataItem() { AMT = 25, STATUS = "OPEN" };
DataItem t4 = new DataItem() { AMT = 35, STATUS = "LOCKED" };
t.Add(t1);
t.Add(t2);
t.Add(t3);
t.Add(t4);
grid1.DataSource = t;
grid1.DataBind();
}
protected void grid1_UpdateCommand(object sender, DataGridCommandEventArgs e)
{
string newAmount = (e.Item.Cells[1].FindControl("txtAmount") as TextBox).Text;
//Update the data source with edited data
grid1.EditItemIndex = -1;
//Load Data with updated data
LoadData();
}
protected void grid1_CancelCommand(object sender, DataGridCommandEventArgs e)
{
grid1.EditItemIndex = -1; //Bring back the previous state
LoadData();
}
public bool IsRowEditable(string status)
{
return !status.Equals("Locked", StringComparison.OrdinalIgnoreCase);
}
protected void grid1_EditCommand(object source, DataGridCommandEventArgs e)
{
grid1.EditItemIndex = e.Item.ItemIndex;
LoadData();
}
protected void grid1d_ItemDataBound(object sender, DataGridItemEventArgs e)
{
}
DataItem.cs
public class DataItem
{
public int AMT { get; set; }
public string STATUS { get; set; }
}
Okay, I figured out a better way to do this. I added the code below to my markup for all three buttons:
Visible='<%# IsRowEditing(Container.ItemIndex) %>'
In my code behind, I checked to see if the row was currently being edited, and used that to control the visibility of the buttons:
protected bool IsRowEditing(int index)
{
return index > 0 && index == grid1.EditItemIndex;
}
This fixed all my issues and was much simpler than what I was trying to do previously. Databinding also works with this method.
I have a nested repeater and I use a textbox in footer template. I wanto to get textbox.text value in button click. Here is my repeater:
<asp:Repeater ID="rprSSFirst" runat="server" OnItemDataBound="rprSSFirst_ItemDataBound" >
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
//******Some Items******
<asp:Repeater ID="rprSSNested" runat="server" > //Nested Repeater
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
//******Some Items******
</ItemTemplate>
<FooterTemplate>
<div style=" padding: 20px 35px;" id='ajax'>
<asp:TextBox ID="textbox" TextMode="MultiLine" Columns="50" Rows="10" runat="server"></asp:TextBox>
<br />
<asp:Button ID="Button2" runat="server" OnClick="btn_Save_Click" Text="Save" />
</div>
</FooterTemplate>
</asp:Repeater>
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater>
//In Code Behind
protected void btn_Save_Click(object sender, EventArgs e)
{
TextBox txtAns = (TextBox)rprSSFirst.Controls[rprSSFirst.Controls.Count - 1].FindControl("textbox");
}
But txtAns Value is always null. How to get footer item textbox value in button click? or any other way?
Thanks for your answers.
You have to find the nested RepeaterItem first where both controls are sitting. You can get it by casting the NamingContainer:
protected void btn_Save_Click(object sender, EventArgs e)
{
Button btnSave = (Button) sender;
RepeaterItem item = (RepeaterItem) btnSave.NamingContainer;
TextBox txtAns = (TextBox) item.FindControl("textbox");
}
You can use Commandname property like this for button of nested repeater:
<asp:Repeater ID="rprSSNested" runat="server" OnItemCommand="rprSSNested_ItemCommand" >
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
//******Some Items******
</ItemTemplate>
<FooterTemplate>
<div style=" padding: 20px 35px;" id='ajax'>
<asp:TextBox ID="textbox" TextMode="MultiLine" Columns="50" Rows="10" runat="server" ></asp:TextBox>
<br />
<asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="Save" CommandName="cmd" CommandArgument="arg"/>
</div>
</FooterTemplate>
</asp:Repeater>
And add event in c# code like this:
protected void rprSSNested_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.Item.ItemType == ListItemType.Footer)
{
if (e.CommandName == "cmd")
{
string ss = ((TextBox)e.Item.FindControl("textbox")).Text;
Response.Write(ss);
}
}
}
I'm trying to write a code that would update only one record for the data.
I do not need to be able to update every field on the row, only one particular field.
I have page that defines a GridView as following:
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
<UpdatePanel>
<ContentTemplate>
<fieldset style="width: 1%">
<legend>Search Customer</legend>
<table>
<tr>
<td>
<asp:DropDownList id="ddlSearchOption"
AutoPostBack="True"
OnSelectedIndexChanged="ddlSearchOption_SelectedIndexChanged"
runat="server">
<asp:ListItem Selected="True" Value="SearchBy"> Search By </asp:ListItem>
<asp:ListItem Value="CustID"> Customer ID </asp:ListItem>
<asp:ListItem Value="CustFirst"> First Name </asp:ListItem>
<asp:ListItem Value="CustLast"> Last Name </asp:ListItem>
<asp:ListItem Value="CustCity"> City </asp:ListItem>
</asp:DropDownList>
</td>
<asp:Panel id="pnlCustSearch" runat="server" >
<td>
<asp:Label id="lblEntry" runat="server" Text="" width="120px"></asp:Label>
</td>
<td>
<asp:TextBox id="txtSearchOptions" runat="server" width="50px">Hello</asp:TextBox>
</td>
<td>
<asp:Button id="btnFind" Text="Search" runat="server" onClick="btnFind_Click"></asp:Button>
</td>
</asp:Panel>
</tr>
</table>
</fieldset>
<div id ="msg">
<asp:Label id="lblMsg" runat="server" Text=""></asp:Label>
</div>
<div id="gridShow">
<asp:GridView ID="GridView1" runat="server" GridLines="None" AutoGenerateColumns="false"
AlternatingRowStyle-BackColor="#EEEEEE" EditRowStyle-BorderColor="Red">
<Columns>
<asp:TemplateField Visible="true" HeaderText="Customer ID">
<ItemTemplate>
<asp:Label runat="server" ID="lblCustID" Text='<%#Eval("CustID")%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="First Name">
<ItemTemplate>
<asp:Label runat="server" ID="lblFirstName" Text='<%#Eval("CustFirstName") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Last Name">
<ItemTemplate>
<asp:Label runat="server" ID="lblLastName" Text='<%#Eval("CustLastName") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="City">
<ItemTemplate>
<asp:Label runat="server" ID="lblCity" Text='<%#Eval("CustCity") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Email">
<ItemTemplate>
<asp:TextBox runat="server" ID="txtEmail" Text='<%#Eval("CustEmail") %>' />
<asp:Button runat="server" ID="btnUpdate" Text="Update" onClick="GridView1_btnUpdate_Click"/>
<asp:RequiredFieldValidator runat="server" ID="rfdCountry" ControlToValidate="txtEmail"
ValidationGroup="var1" ErrorMessage="*" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</ContentTemplate>
</UpdatePanel>
</asp:Content>
Then in codebehind I write the following:
protected void GridView1_btnUpdate_Click(Object sender, EventArgs e)
{
//Code goes here
}
When clicking button to update email nothing happens.
What am I doing wrong?
I tried to use one of suggestions here:
if (!IsPostBack)
{
GridView1.DataSource = App_Data.DataHandler.GetData("fname", "de");
GridView1.DataBind();
GridView1.Visible = true;
}
The data is displayed but the click event does not work anyway
I added the following to my GridView definition:
onrowcommand="GridView1_RowCommand"
and added the code suggested:
<asp:Button runat="server" ID="btnUpdate" Text="Update" CommandName="UpdateEmail"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"/>
In my .cs file I added the following:
protected void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "UpdateEmail")
{
//Get the index from the argument
int index = Convert.ToInt32(e.CommandArgument);
//Get the row
GridViewRow row = GridView1.Rows[index];
//Do whatever you need with your row here!
}
}
Still, click event does not fire.
Ok, here is my code behind .cs file:
public partial class index : System.Web.UI.Page
{
protected override object LoadPageStateFromPersistenceMedium()
{
return Session["__VIEWSTATE"];
}
protected override void SavePageStateToPersistenceMedium(object viewState)
{
Session["VIEWSTATE"] = viewState;
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
Reset();
else
lblMsg.Text = "";
}
protected void Reset()
{
pnlCustSearch.Visible = false;
GridView1.Visible = false;
lblMsg.Text = "";
}
protected void ddlSearchOption_SelectedIndexChanged(object sender, EventArgs e)
{
Reset();
String ddlSelected = ddlSearchOption.SelectedValue;
if (ddlSelected != "")
{
ViewState["ddlSelected"] = ddlSelected;
pnlCustSearch.Visible = true;
SelectLabel(ddlSelected);
}
}
protected void SelectLabel(String choice)
{
switch (choice)
{
case "CustID":
lblEntry.Text = "Enter Customer ID";
break;
case "CustFirst":
lblEntry.Text = "Enter First Name";
break;
case "CustLast":
lblEntry.Text = "Enter Last Name";
break;
case "CustCity":
lblEntry.Text = "Enter City";
break;
default:
lblEntry.Text = "Enter Customer ID";
break;
}
}
protected void btnFind_Click(object sender, EventArgs e)
{
GridView1.Visible = true;
String option = (String)ViewState["ddlSelected"];
String input = txtSearchOptions.Text.Trim();
GridView1.DataSource = DataHandler.GetData(option,input);
GridView1.DataBind();
GridView1.Visible = true;
}
protected void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "UpdateEmail")
{
//Get the index from the argument
int index = Convert.ToInt32(e.CommandArgument);
//Get the row
GridViewRow row = GridView1.Rows[index];
//Do whatever you need with your row here!
}
}
protected void btnUpdate_Click(Object sender, EventArgs e)
{
String txt = null;
txt = "here";
}
}
When you try to handle events from GridView, you need to use a CommandName and a CommandArgument then handle the RowCommand event from the GridView.
See http://msdn.microsoft.com/... for reference.
ASP.Net page should look like :
<asp:ButtonField runat="server" ID="btnUpdate" Text="Update"
CommandName="UpdateEmail"
CommandArgument="<%# CType(Container,GridViewRow).RowIndex %>" />
In the RowCommand event :
if (e.CommandName == "UpdateEmail")
{
//Get the index from the argument
int index = Convert.ToInt32(e.CommandArgument);
//Get the row
GridViewRow row = GridView1.Rows[index];
//Do whatever you need with your row here!
}
I got it, finally. I had to change <asp:Button/> to
`<asp:ButtonField Text="Update Email" CommandName="UpdateEmail"`
and remove it from ItemTemplate.
But why this was a problem. What I wanted to do is just to display textfield in the same itemtemplate with button?
Actually, the answer was much easier then I thought originally. I just used different values to set session: __VIEWSTATE and VIEWSTATE
protected override object LoadPageStateFromPersistenceMedium()
{
return Session["__VIEWSTATE"];
}
protected override void SavePageStateToPersistenceMedium(object viewState)
{
Session["VIEWSTATE"] = viewState;
}
As soon as I changed it, button was able to fire events.
Thank you
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"));
}
}
I have the next code and i don't get why it's not working.
<asp:Label ID="lblFull" Visible="false" runat="server">
<asp:TextBox ID="EmailtxtboxFull" Width="250px" runat="server" Font-Size="Medium" ForeColor="Blue" BorderWidth="1"></asp:TextBox>
</asp:Label>
<asp:Label ID="lblEnd" Visible="false" runat="server"></asp:Label>
<asp:Button ID="btnFull" OnClick="btnFull_Click" runat="server" Text="Send" Font-Size="Medium" ForeColor="#0066FF" BorderStyle="Solid" BorderWidth="1" />
c # code :
protected void btnFull_Click(object sender, EventArgs e)
{
String Email = EmailtxtboxFull.Text.ToString();
lblFull.Visible = false;
lblEnd.Visible = true;
lblEnd.Text = Email;
}
When i click on the btn ... i got empty lable and not the email that i wrote on the textbox. why this it's happent? that's connect to the autopostback ? how to fix that?
You have your EmailtxtboxFull textbox inside your label, are you sure the code sample is right?
when i corrected the label the code behaved correctly for me.