how change textbox text after clicking on a button inside a gridview - c#

i have one textbox and one button both on a gridview , when user clicks on button i want to get the textbox text and save to database then clear the text! i used code below it works fine and saves to database but cant clear the textbox why ?
protected void sendcm_Click(object sender, EventArgs e)
{
try
{
Button sendcm = (Button)sender;
GridViewRow gvrow = (GridViewRow)sendcm.NamingContainer;
int ActivityTypeID = Convert.ToInt32(activity.DataKeys[gvrow.RowIndex].Values["ActivityTypeID"].ToString());
int SourceID = Convert.ToInt32(activity.DataKeys[gvrow.RowIndex].Values["SourceID"].ToString());
TextBox tt = (TextBox)activity.Rows[gvrow.RowIndex].FindControl("cmtextbox");
if (tt.Text != "")
{
BusinessLayer.StatusComment_Table ncm = new BusinessLayer.StatusComment_Table();
ncm.Id = Convert.ToInt32(Session["ID"].ToString());
ncm.Statusid = SourceID;
ncm.Statuscommentdate = System.DateTime.Now;
ncm.Statuscommenttext = tt.Text;
ncm.Save();
tt.Text = ""; // its not working !!!!
}
}
protected void Page_Load(object sender, EventArgs e)
{
SessionLable.Text = Session["ID"].ToString();
if (!IsPostBack)
{
getData();
}
}
public void getData()
{
activity.DataSource = BusinessLayer.Activity_Table.GetByProfileData(ID, -1, activity.PageSize);
activity.DataBind();
}

You need to do this at the UI level.
Use jquery.post to call the method that saves the data.
return something back to the $.post callback to tell jquery that the post s complete,
then do something like $('#mytextfield').val('')
assuming that the text box has an ID. I am assuming this is HTML?

you might need to rebind your grid because from the code that you posted it's not clear that where are you re binding your grid.

You need to enable AjaxPostback in your page. After that, in your Page_Load logic, include the code
if(IsPostBack){...}else{...}
So you can handle the construction of UI elements depending on whether this is a fresh new view of the page or a postback (page refreshed due to user clicking the button). UI elements are sent to the browser, after that, there is no way for the server to change it except to refresh the page itself.
The manual (and the one I recommend) way is to do this via jQuery postback. As pointed out in the other answer, you'll need to setup an endpoint for the client browser to connect. After the server has done its job, return the result to the client. Then use jQuery to update the textbox.

i did this to solve my problem !
<asp:TextBox ID="cmtextbox" type="text" clientid="cmtextbox" TextMode="MultiLine" placeholder="نظر دهید..." Rows="1" style="resize:none" class="form-control" runat="server"></asp:TextBox>
<asp:Button ID="sendcm" style="margin-top:2px;" OnClick="sendcm_Click" class="btn btn-success btn-sm pull-left " OnClientClick="ClearTextbox(this)" runat="server" Text="ارسال" />
</script>
<script type="text/javascript">
ClearTextbox = function (that) {
$(that).prevUntil('div.stop', '[ClientID="cmtextbox"]').val('');
}
</script>

Related

dropdown selected item and repose.redirect

I have two dropdownlist in my project and get the items from sql server. One of them show list of something (And I named it DropdownSoore) and another one show list of members of it (And I named it DropdownAye) that update when select an item from DropdownSoore. then when select an item from DropdownAye go to page of them by forwarding query string. I have no problem to updating DropdownAye but when I select item from it and redirect to page of it, the DropdownAye lose the selected item and show the first item (as default) and index to query string in url.
what should I do?
Excuse me about my grammer, I'm not English...
I set DropdownSoore:
<asp:DropDownList ID="DropDownListSoore" runat="server" class="nav-link btn btn-outline-secondary dropdown-toggle" aria-haspopup="true" aria-expanded="true" AutoPostBack="True"></asp:DropDownList>
for (int i = 0; i <= dt.Rows.Count - 1; i++)
{
string IdSoore = Convert.ToString(dt.Rows[i]["IdSoore"]);
string NameSoore = Convert.ToString(dt.Rows[i]["NameSoore"]);
DropDownListSoore.Items.Add(IdSoore + "." + NameSoore);
}
string forwardedIdSoore = Request.QueryString["IdSoore"];
if (forwardedIdSoore != null)
{
DropDownListSoore.Items.FindByValue(forwardedIdSoore);
}
And then set DropdownAye:
<asp:DropDownList ID="DropDownListAye" runat="server" class="nav-link btn btn-outline-secondary dropdown-toggle" aria-haspopup="true" aria-expanded="true" OnSelectedIndexChanged="DropDownListAye_SelectedIndexChanged" AutoPostBack="True"></asp:DropDownList>
DropDownListAye.Items.Clear();
for (int i = 0; i <= dt1.Rows.Count - 1; i++)
{
DropDownListAye.Items.Add(Convert.ToString(dt1.Rows[i]["NumberAye"]));
}
int iSelectedAye = Convert.ToInt32(DropDownListAye.SelectedIndex) + 1;
string SelectedAye = Convert.ToString(dt1.Rows[iSelectedAye]["IdAye"]);
Session["SSelectedAye"] = SelectedAye;
string forwardedIdAye = Request.QueryString["IdAye"];
if (forwardedIdSoore != null)
{
DropDownListSoore.Items.FindByValue(forwardedIdAye);
}
in page_Load. and dont have problem to update DopdownAye but when I used it to redirect always get IdAye=1 in url and show the first item of DropdownAye ...:
protected void DropDownListAye_SelectedIndexChanged(object sender, EventArgs e)
{
int SelectedAye = Convert.ToInt32(Session["SSelectedAye"]);
int SelectedSoore = Convert.ToInt32(DropDownListSoore.SelectedIndex) + 1;
string forward = "~/contentAye.aspx?IdSoore=" + SelectedSoore + "&IdAye=" + SelectedAye;
Response.Redirect(forward);
}
I try !IsPostBack but dont have utility too.
I do all thing I think and i dont know what shoild i do.
And where are you loading up these infomration?
Remember, page load ALWAYS fires and triggers for each post-back, for each button click, and any OTHER event on the page that calls code behind.
What does the above really mean?
Well, it means that you need to ONLY ONE TIME load up the drop downs, the gridview(s), or whatever else you have.
So, for the last 200+ web pages I have built, I ALWAYS have this code stub in the page load event:
so this markup:
<h3>Select Hotel</h3>
<asp:DropDownList ID="DropDownList1" runat="server"
DataValueField="ID"
DataTextField="HotelName" Width="356px">
</asp:DropDownList>
<br />
<br />
<asp:Button ID="Button1" runat="server"
Text="Show/get/display drop selection" OnClick="Button1_Click"
CssClass="btn" />
<br />
<h3>Selected result</h3>
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>
and code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// load up data, controls etc.
string strSQL =
"SELECT ID, HotelName FROM tblHotelsA ORDER BY HotelName";
DataTable dt = General.MyRst(strSQL);
DropDownList1.DataSource = dt;
DropDownList1.DataBind();
DropDownList1.Items.Insert(0, new ListItem("Please Select Hotel", ""));
}
}
protected void Button1_Click(object sender, EventArgs e)
{
string sResault =
$#"dropdown list value (pkid) = {DropDownList1.SelectedItem.Value}
<br/>
Dropdown list Text (Hotel) = {DropDownList1.SelectedItem.Text}";
Label1.Text = sResault;
}
and the result:
SUPER important:
If I leave out the !IsPostBack test in page load, then for EVERY button click, the dropdown list re-load code will trigger, and runs BEFORE your button stubb, or post back. As a result, I will see/find/get no valid value from the drop down list, since page load ALWAYS runs before the given code stub, and thus if page load "every time" re-loads the data, then it will blow out the choosen value in the drop down list.
So, loading up of grids, data, dropdowns etc. can ONLY occur one time in page load, since page load ALWAYS runs before each button or event code stub you have behind.
If you thus only load up the controls and dropdowns on the first REAL page load, then the values the user selects in those dropdowns should work, but only will work if you ALWAYS include that all important if (!IsPostBack) code stub in your page load event.
Now, of course in place of that button to loadup + display the dropdown list into that label?
Well, of course that button click may well (like often) jump or navigate to another page. So, in place of that code to fill out the selected value(s) into that lable, we could pass the selected value to the next page. And how to do that? Well, you can use session(), you can use parmaters in the URL, or you can even use a post-back URL, and then the WHOLE previous page becomes available (Page.Previous), which then in theory allows you to grab ANY and ALL values from the previous page.
but, say we choose session() to pass the value, then this:
Session["HotelPK"] = DropDownList1.SelectedItem.Value;
Response.Redirect("GridFun3.aspx");

Calling a server side method from a dynamically generated button inside an update panel

Lets preface this with the fact that I am learning ASP.NET C# and this is my first "real" project so there is a good chance I am missing something obvious, I apologize in advance.
I am working on a web page that displays three columns. The first is "Categories", a user should be able to select a category then have a list of items to choose from appear in the second column "Items". When they click an item the third column should show details about said item. For the most part this is a classic Master/Detail scenario except we take it a step further and do Master/Detail/Detail.
To achieve this I am generating dynamic buttons on Page_Load() in the "Categories" column. In addition I have added a debug line when the page loads, this is important later.
protected void Page_Load(object sender, EventArgs e)
{
//DB query to get categories omitted
for (int i = 0; i < categories.Rows.Count; i++)
{
Button btn = new Button();
btn.Click += new System.EventHandler(CategorySelected_Click);
btn.Attributes["runat"] = "server";
btn.ID = "CatSelBtn" + i;
btn.Attributes["data-categoryid"] = qry.GetCategories().Rows[i]["id"].ToString();
//And some other non-relevant attributes
CategoriesPane.Controls.Add(btn);
}
System.Diagnostics.Debug.WriteLine("Page Loaded");
}
As you may have noticed these buttons have a Click event handler that calls the method CategorySelected_Click(). These buttons all generate successfully and clicking on them results in that method being successfully called. This method is set up in a similar fashion, it grabs a list of items then generates buttons for the items, of course this needs to be done asynchronously so it doesn't reset the user's category selection, so this time it is all contained with an update panel.
C#
protected void CategorySelected_Click(object sender, EventArgs e)
{
//DB query to get items omitted
Button btn = (sender as Button);
string categoryid = btn.Attributes["data-categoryid"].ToString();
for (int i = 0; i < items.Rows.Count; i++)
{
if (items.Rows[i]["Category"].ToString() == categoryid)
{
Button ibtn = new Button();
ibtn.Click += new System.EventHandler(this.ItemSelected_Click);
ibtn.Attributes["runat"] = "server";
ibtn.ID = "ItmSelBtn" + i;
ibtn.Attributes["data-itemid"] = qry.GetItems().Rows[i]["id"].ToString();
//And again some none relevant attributes here
ItemsParent.Controls.Add(ibtn);
}
}
ItemsPanel.Update();
}
ASP
<div class="col-md-2 items-pane">
<asp:UpdatePanel ID="ItemsPanel" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="False">
<ContentTemplate>
<div id="ItemsParent" runat="server">
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
<div class="col-md-8 view-pane">
<asp:UpdatePanel ID="ItemDetailsPanel" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="False">
<ContentTemplate>
<div id="ItemDetailsParent" runat="server">
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
Again this generates a list of buttons for each item matching the correct category. No issue there, but this time I need the clicked button to call the third and final method which will display the details for the item. This is where things stop working. I assumed that because I was able to generate buttons successfully on Page_Load() that it would work the same inside an update panel. Right now the third method just contains a debug line to check if its firing at all.
protected void ItemSelected_Click(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Item has been selected");
ItemDetailsPanel.Update();
}
In my output console in visual studio when I click on an Item Button control it writes Page Loaded indicating a successful postback but I am not seeing Item has been selected indicating that the third method is firing. I also inserted a breakpoint there but it is not being reached.
I initially thought I needed to add an asyncpostback trigger for each button generated to my update panel but that did not seem to resolve that issue, and because I can now see that Page_Load() is getting triggered I am pretty sure that isn't the issue. This leads me to believe that the click event is somehow not being registered. So my question to you is this: How do I make a dynamically generated button inside an update panel call a server side method? Any help is greatly appreciated.
You need to attach the event handlers on every postback.
It works for your categories-buttons, because the attaching is executed on every page load.
Do this for all the other items also, e.g. put in your Page_Load something like this:
foreach (var ctrl in ItemsParent.Controls)
{
Button ibtn = ctrl as Button;
if (ibtn != null)
{
ibtn.Click += new System.EventHandler(this.ItemSelected_Click);
}
}

Dropdownlist SelectedIndexChanged firing on every postback

I am dynamically adding a custom user control to an update panel. My user control contains two dropdownlists and a textbox. When a control outside of the update panel triggers a postsback, I am re-adding the user control to the update panel.
The problem is...on postback when I re-add the user controls, it's firing the "SelectedIndexChanged" event of the dropdownlists inside the user control. Even if the selectedindex did not change since the last postback.
Any ideas?
I can post the code if necessary, but there's quite a bit in this particular scenario.
Thanks in advance!
EDIT...CODE ADDED BELOW
*.ASCX
<asp:DropDownList ID="ddlColumns" OnSelectedIndexChanged="ddlColumns_SelectedChanged" AppendDataBoundItems="true" AutoPostBack="true" runat="server">
*.ASCX.CS
List<dataColumnSpecs> dataColumns = new List<dataColumnSpecs>();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
fillDDLColumns();
}
}
public void fillDataColumnsList()
{
dataColumns.Clear();
//COMMON GETDATATABLE RETURNS A DATA TABLE POPULATED WITH THE RESULTS FROM THE STORED PROC COMMAND
DataTable dt = common.getDataTable(storedProcs.SELECT_COLUMNS, new List<SqlParameter>());
foreach (DataRow dr in dt.Rows)
{
dataColumns.Add(new dataColumnSpecs(dr["columnName"].ToString(), dr["friendlyName"].ToString(), dr["dataType"].ToString(), (int)dr["dataSize"]));
}
}
public void fillDDLColumns()
{
fillDataColumnsList();
ddlColumns.Items.Clear();
foreach (dataColumnSpecs dcs in dataColumns)
{
ListItem li = new ListItem();
li.Text = dcs.friendlyName;
li.Value = dcs.columnName;
ddlColumns.Items.Add(li);
}
ddlColumns.Items.Insert(0, new ListItem(" -SELECT A COLUMN- ", ""));
ddlColumns.DataBind();
}
protected void ddlColumns_SelectedChanged(object sender, EventArgs e)
{
//THIS CODE IS BEING FIRED WHEN A BUTTON ON THE PARENT *.ASPX IS CLICKED
}
*.ASPX
<asp:UpdatePanel ID="upControls" runat="server">
<ContentTemplate>
<asp:Button ID="btnAddControl" runat="server" Text="+" OnClick="btnAddControl_Click" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="btnGo" runat="server" Text="Go" OnClick="btnGo_Click" ValidationGroup="vgGo" />
<asp:GridView...
*.ASPX.CS
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
uc_Counter = 0;
addControl();
gridview_DataBind();
}
else
{
reloadControls();
}
}
protected void btnGo_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
//THIS BUTTON CLICK IS WHAT'S TRIGGERING THE
//SELECTEDINDEXCHANGED EVENT TO FIRE ON MY *.ASCX
gridview_DataBind();
}
}
private void reloadControls()
{
int count = this.uc_Counter;
for (int i = 0; i < count; i++)
{
Control myUserControl = Page.LoadControl("~/Controls/myUserControl.ascx");
myUserControl.ID = "scID_" + i;
upControls.ContentTemplateContainer.Controls.AddAt(i, myUserControl);
((customUserControl)myUserControl).fillDDLColumns();
}
}
private void addControl()
{
Control myUserControl = Page.LoadControl("~/Controls/myUserControl.ascx");
myUserControl.ID = "scID_" + uc_Counter.ToString();
upControls.ContentTemplateContainer.Controls.AddAt(upControls.ContentTemplateContainer.Controls.IndexOf(btnAddControl), myUserControl);
//((customUserControl)myUserControl).fillDDLColumns();
this.uc_Counter++;
}
protected int uc_Counter
{
get { return (int)ViewState["uc_Counter"]; }
set { ViewState["uc_Counter"] = value; }
}
Even though this is already answered I want to put an answer here since I've recently tangled with this problem and I couldn't find an answer anywhere that helped me but I did find a solution after a lot of digging into the code.
For me, the reason why this was happening was due to someone overwriting PageStatePersister to change how the viewstate hidden field is rendered. Why do that? I found my answer here.
One of the greatest problems when trying to optimize an ASP.NET page to be more search engine friendly is the view state hidden field. Most search engines give more score to the content of the firsts[sic] thousands of bytes of the document so if your first 2 KB are view state junk your pages are penalized. So the goal here is to move the view state data as down as possible.
What the code I encountered did was blank out the __VIEWSTATE hidden fields and create a view_state hidden field towards the bottom of the page. The problem with this is that it totally mucked up the viewstate and I was getting dropdownlists reported as being changed when they weren't, as well as having all dropdownlists going through the same handler on submit. It was a mess. My solution was to turn off this custom persister on this page only so I wouldn't have to compensate for all this weirdness.
protected override PageStatePersister PageStatePersister
{
get
{
if (LoginRedirectUrl == "/the_page_in_question.aspx")
{
return new HiddenFieldPageStatePersister(Page);
}
return new CustomPageStatePersister(this);
}
}
This allowed me to have my proper viewstate for the page I needed it on but kept the SEO code for the rest of the site. Hope this helps someone.
I found my answer in this post .net DropDownList gets cleared after postback
I changed my counter that I was storing in the viewstate to a session variable.
Then I moved my reloadControls() function from the Page_Load of the *.ASPX to the Page_Init.
The key was dynamically adding my user control in the Page_Init so it would be a member of the page before the Viewstate was applied to controls on the page.

Send data from javascript to code behind at first load

I am actually buidling a web application and I need to get data of the local environment of the machine viewing the application.To do this, I use a little javascript script such as:
<script language="javascript">
function GetUserName()
{
//Permits to get username of client machine
var wshell = new ActiveXObject("WScript.Shell");
var arpege = wshell.ExpandEnvironmentStrings("%USERNAME%");
document.getElementById("arpege").value=arpege;
}
</script>
<input type=hidden id="arpege" runat=server />
My problem is that this script is executed after the page is loaded and so I can't use it on the page load...
My code on the page load is:
protected void Page_Load(object sender, EventArgs e)
{
myConnection.ConnectionString = ActionSource.ConnectionString;
myConnection.Open();
String account = arpege.value;
...
}
But i just get "" in account...
Thanks for your help,
Quentin
Page_Load occurs on the server side before any data is being sent to the client.
you can't do that without initiating a new postback once the page is loaded.
Solution coming up...
EDIT:
So, it (might) be possible to achieve this using some jQuery
$(document).ready(function() {
var wshell = new ActiveXObject("WScript.Shell");
var arpege = wshell.ExpandEnvironmentStrings("%USERNAME%");
__doPostBack('__Page', arpege);
});
And catch it on the server side:
public void Page_Load(object sender, EventArgs e)
{
string arpege= Request["__EVENTARGUMENT"];
}
Worth's a shot!
A variant of the proposition made by Shai could be the following:
generate an asyncpostback on a hidden button.
Like that, the logic could be separated from the Page_Load, and
put instead in the handler attached to the input which generated the asyncpostback.
I don't like to put too much logic in the page_load event, i find it confusing.
the implementation will be a little more complicated though
Get the username server side in Page_Load instead of with an ActiveX control.
protected void Page_Load(object sender, EventArgs e)
{
myConnection.ConnectionString = ActionSource.ConnectionString;
myConnection.Open();
String account = User.Identity.Name;
// ...
}
Also, ActiveX only works in Internet Explorer - User.Identity.Name works on the server and therefor all browsers.
The ASPX code:
<body>
<form id="form1" runat="server">
<input type="hidden" id="hdnUser" runat="server" />
<input type="hidden" id="hdnRun" runat="server" value="true" />
<asp:Label ID="lblSayHello" runat="server" Text="I dont know you"></asp:Label>
</form>
<script type="text/javascript">
$(function () {
var run = $('#hdnRun').val();
if (run == 'true') {
var wshell = new ActiveXObject("WScript.Shell");
$('#hdnUser').val(wshell.ExpandEnvironmentStrings("%USERNAME%"));
$('#form1').submit();
}
});
</script>
</body>
The Code behind
protected void Page_Load(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(hdnUser.Value))
{
hdnRun.Value = "false";
lblSayHello.Text = String.Format(#"Hello, {0}", hdnUser.Value);
}
}
The best (easiest) way that I know of sending data from the client to the server is to
1. Store it in an asp hidden field
2. Click an ASP button via javascript
3. Handle the data in the OnClick Event
For example:
ASPX Page
<asp:HiddenField ID="myHf" class="myHf" runat="server" />
<asp:Button ID="myButton" class="myButton" runat="server" OnClick="myButton_Click" style="display: none;" />
Javascript
function SendMyData(data) {
document.getElementByClassName('myHf').value = data;
document.getElementByClassName('myButton').click();
//I use classes since those won't change - IDs become really long and messed up
//in the actual page, and may change depending on where the element is placed.
}
CodeBehind
protected void myButton_Click(object sender, EventArgs e)
{
//Do whatever you want with myHf.Value
MyServerMethod(myHf.Value);
}
I think that doing it this way is better than using the Page_Load and submitting the form, just because if you are doing enough of these, the Page_Load method can get huge. But that's just my opinion.

End user add values to a dropdownlist?

I'm populating a dropdownlist in c# asp.net-MVC from a SQL table using Linq2Sql. I'd like for the user to be able to enter something that isn't in the list into the drop down and have it add to the table. Is this possible?
Sounds like you need to add a radio button labeled "Other". When the user clicks the radio button a text box would appear that allows the user to input a new value that you can save to your DB and display in the drop down.
EDIT:
Quick snippet to enable the control using JavaScript:
<script language="javascript" type="text/javascript">
function radioclicked() {
textObj = document.getElementById('<NAME OF TEXT BOX');
textObj.disabled = false;
}
</script>
You can use a check box instead of a radio button so that the enabled property can be toggled.
To completely hide the text box then you will have to look into jQuery/Ajax.
Why can't we use a lightweight Add-on like www.combodropdown.info for this purpose? You can even consider AutoComplete plugin from jQuery, if your app already references jQuery.
Also a combobox will allow a user to enter a value in addition to picking from a list.
My MVC is not so so, but I assume this still applies as MVC is just model view controller.
What if you throw a drop down on your form visible=true, and a textbox on your form visible =false.
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True"
onselectedindexchanged="DropDownList1_SelectedIndexChanged">
</asp:DropDownList>
<asp:TextBox ID="TextBox1" runat="server" Visible="False"></asp:TextBox>
Fill your drop down:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<int> s = Enumerable.Range(1, 10).ToList();
DropDownList1.DataSource = s;
DropDownList1.DataBind();
DropDownList1.Items.Add("Other");
}
}
Add an event to handle if someone selects other. If they do make the textbox visible:
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
switch (this.DropDownList1.SelectedItem.Text)
{
case "Other":
this.TextBox1.Visible=true;
break;
default:
this.TextBox1.Visible=false;
break;
}
}
Now you can enter your value and re-store back to the db.

Categories

Resources