I have a textbox that users can enter comments into, and then click save. When they click save, some code executes in the background, but their comments stay in the textbox so that they can see them. I want to display some text above the box that says "Comments saved" when they click save, so that they know that their request went through, since nothing else changes on the page after clicking save. However, they can then change the text in the textbox, and it won't save unless they click "save" again. So, I want the "Comments saved" text to disappear if they change the text in the box. However, I cannot set AutoPostBack="true", because it will mess up some other stuff that's happening on the page. Is there a way to make the "Comments Saved" text disappear when the textbox is changed, without reloading the page? Here is the code I have so far:
<div id="savedMsg" runat="server"><p class="msgAlert"> Comments Saved! </p></div>
<div>
<asp:Panel runat="server" DefaultButton="Save">
<asp:TextBox runat="server" ID="TextBox" CssClass="form-control" TextMode="MultiLine"/>
</asp:Panel>
</div>
Here is the code behind:
protected void SaveComments(object sender, EventArgs e)
{
//some code here that is unrelated
savedMsg.Visible = true;
}
Ideally, I would set TextChange="SomeMethod" and include this in my code behind:
protected void SomeMethod(object sender, EventArgs e)
{
savedMsg.Visible = false;
}
but I can't enable AutoPostBack, so this event never happens.
You can hide the message on the onkeydown event of the TextBox:
<asp:TextBox runat="server" ID="TextBox" onkeydown="hideSaveMessage();" CssClass="form-control" TextMode="MultiLine" />
with the Javascript code:
<script type="text/javascript">
function hideSaveMessage() {
var div = document.getElementById('<%= savedMsg.ClientID %>');
div.style.visibility = 'hidden';
}
</script>
You could also use div.style.display = 'none' to hide the message but that causes the TextBox to "jump" to a new position, which is somewhat disturbing.
I used document.getElementById('<%= savedMsg.ClientID %>') to account for any modification applied to the div ID by ASP.NET. The simpler syntax document.getElementById('savedMsg') may work in your case.
Related
since I am new to ASP .NET I wonder whether this is normal behavior or something strange. I am trying to convert C# WinForms app to web app and it is behaving not as I expected.
In desktop app I get data after user press enter on textbox. Data are loaded I can modify it and then, when I am done changing data I can press one of two buttons and data are saved to database or form is cleared. Something like this.
private int idOrder;
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
if(load_data)
{
label1.Text = "some loaded data";
...
else{ MessageBox.Show("Something went wrong. No data loaded");
}
}
protected void Button2_Click(object sender, EventArgs e)
{
//save to database;
}
But When I try to do the same in ASP.NET Web form, whenever I press enter on textbox all controls are fired (as it is written in source code line after line) when page is refreshed. Could you please advice we what should I do to replicate same behavior as in winforms e.g. user input - enter - load data - modify - press button when I want. Thank you.
//Is the view state thing I am looking for?
Here is a snippet to get you started. Keep in mind that posting a HTML form when pressing enter is default behavior for websites. So the first thing is preventing that by wrapping the TextBox and Submit Button with a Panel with a DefaultButton assigned to it. Now when the enter is pressed in TextBox1, it will post the form as dummyButton
Next we add an OnTextChanged event to TextBox1 and set AutoPostBack to true. This will fire when the focus of TextBox1 is lost. You could remove this and just use the enter with dummyButton.
The dummyButton is added to ensure the form will PostBack when enter is pressed in TextBox1 to get the desired behaviour.
<asp:Panel ID="Panel1" runat="server" DefaultButton="Button1">
<asp:TextBox ID="TextBox1" runat="server" AutoPostBack="true" OnTextChanged="TextBox1_TextChanged"></asp:TextBox>
<br />
<br />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<br />
<br />
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
<asp:LinkButton ID="dummyButton" runat="server" OnClick="TextBox1_TextChanged"></asp:LinkButton>
</asp:Panel>
And then in code behind.
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
//load from database
Label1.Text = TextBox1.Text;
}
protected void Button1_Click(object sender, EventArgs e)
{
//save to database
Label1.Text = "Data saved!";
TextBox1.Text = "";
}
You can also prevent PostBack with enter like this. The JavaScript will block all enters. Depending on your page design you could set this in the <body> tag for example.
<div onkeydown="return (event.keyCode!=13);">
<asp:TextBox ID="TextBox1" runat="server" AutoPostBack="true" OnTextChanged="TextBox1_TextChanged"></asp:TextBox>
</div>
I'm having a really strange problem where my code works with a breakpoint set in the code, but when I remove the breakpoint, parts of the code stop functioning.
I'm trying to make a textbox select all text on focus; I want it to automatically focus, selecting all text, when a search is performed.
I have a texbox (groupSearchTextbox), button (groupSearchButton), and a listbox which is inside of an update panel, inside of a panel with a default button specified:
<asp:Panel ID="groupPanel" runat="server" CssClass="listContainer" DefaultButton="groupSearchButton">
<h2>User Groups</h2>
<div class="searches">
<asp:TextBox ID="groupSearchTextbox" runat="server"></asp:TextBox>
<asp:Button ID="groupSearchButton" runat="server" Text="Search" OnClick="groupSearchButton_Click" />
<asp:Button ID="showAllGroupsButton" runat="server" Text="Show All" OnClick="showAllGroupsButton_Click" CssClass="right" />
</div>
<asp:UpdatePanel ID="groupUpdate" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:ListBox ID="groupListbox" runat="server" CssClass="list"></asp:ListBox>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="groupSearchButton" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="showAllGroupsButton" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</asp:Panel>
I also have a jquery function to make the textboxes select on focus:
$('.searches input[type=text]').focus(function () {
$(this).select();
});
and onclick of groupSearchButton I have the following function to remove items from the listbox if they are not results of a search, and focus on the textbox:
protected void groupSearchButton_Click(object sender, EventArgs e) {
fillGroups(); //Sets the listbox to the original list
string searchString = groupSearchTextbox.Text;`
for (int i = groupListbox.Items.Count - 1; i > 0; i--) {
string itemName = groupListbox.Items[i].ToString();
if (!itemName.ToLower().Contains(searchString.ToLower())) {
groupListbox.Items.Remove(groupListbox.Items[i]);
}
}
groupSearchTextbox.Focus();
}
When I click the groupSearchButton, everything works as expected. I get my results and the groupSearchTextbox gets focus with the text selected.
When I press enter while focused on the textbox, making use of the panel's default button attribute, I get my results but the text in the textbox is not selected.
The strange part is, if I put a breakpoint where I set the focus in the groupSearchButton_Click method, the above method of pressing enter in the textbox works properly and the text is selected.
Any ideas what might be going on here?
Edit:
So I'm pretty sure that the issue is that the textbox needs to lose focus in order for it to select the text when it focuses again. That would explain the actual clicking of the button working, as well as (I believe) the breakpoint issue, since the textbox would lose focus when Visual Studio is displayed.
I came up with a fairly hacky jquery fix for this, but would still love to know if there's a decent way to handle this properly
If you want to focus on only one text box then you can use
<asp:Panel ID="groupPanel" runat="server" CssClass="listContainer" DefaultButton="groupSearchButton" defaultfocus="groupSearchTextbox">
on your panel
You can use this in Page_Load:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
groupSearchTextbox.Focus();
}
}
this is my scenario:
I want to display a button(btnGenerate) based on the amount of rows displayed in my gridview. I've gotten it to display for a second then it goes away again. I'm using the onclientclick of one of my other buttons(btnImport). What I think is causing the problem is that on the same button(btnImport)'s OnClick event two gridview's performs for each a databind. Could this be the problem? I have written a script using javascript to perform this task from the client side. Is there a better way to do it? What can I do to fix my problem?
Here is my code that I have so far:
<asp:Button runat="server" ID="btnImport" Text="Load Data from File"
BackColor="#990000" ForeColor="White" nowrap OnClick="btnImport_Click"
style="display:none" OnClientClick="DisplayButtonGenerate()"/>
<asp:Button ID="btnGenerate" runat="server" Text="Generate New Stock Codes"
BackColor="#990000" ForeColor="White" OnClick="btnGenerate_Click"
style="display:none" />
I have two gridviews : ErrorsGrid that displays all the faulty records and InventoryGrid that displays the records that are correct. Like I said above, the idea is to display btnGenerate if ErrorsGrid has rowCount=0.
protected void btnImport_Click(object sender, EventArgs e)
{
InventoryGrid.DataBind();
ErrorsGrid.DataBind();
}
protected void btnGenerate_Click(object sender, EventArgs e)
{
FinalMessage.AppendLine(_InsertWrapper.PostData());
}
Here is the script:
<script language="javascript" type="text/javascript">
function DisplayButtonGenerate() {
var rowCount = <%=ErrorsGrid.Rows.Count %>;
var buttonGen = document.getElementById("<%=btnGenerate.ClientID%>");
if(rowCount == 0)
{
buttonGen.style.display = "block";
}
}
</script>
Your btnImport has server-side OnClient and client-side OnClientClick both set. I guess what's happening is the client-side is called first, shows the button, then the server-side one kicks in, the page gets refreshed from the server, and your button is hidden again. You can do it in one way or another, but not both:
Server-side: Remove the OnClientClick & style="display:none" & JavaScript, set the Visible property of the button to false, and in the code-behind click event on the server add:
if(ErrorsGrid.Rows.Count == 0)
btnImport.Visible = True;
Client-side: Return false from the JavaScript function to the OnClientClick:
OnClientClick="return DisplayButtonGenerate()"
function DisplayButtonGenerate() {
....
return false;
}
If you want to update InventoryGrid,ErrorsGrid grid controls in code after you click a button, you need to keep those in a UpdatePanel
<asp:UpdatePanel ID="upnl" runat="server" UpdateMode="Conditional">
<contenttemplate>
InventoryGrid,ErrorsGrid mark up
</contentTemplate>
<Triggers>
//set async trigger as btnImport
</Triggers>
</asp:UpdatePanel>
Let's breakdown your problem into steps.
you click on btnImport, it first calls the OnClientClick, does client side processing
and then does a full postback, goes to server side and processes its server side handler OnClick.
after the OnClick handler is processed, the page again renders, the unconditioned code in the btnGenerate display:none again runs, and the default state is again rendered.
you see the problem? even if you are manipulating certain logic in your clientClick, it all resets on page reload, because your btnImport is doing that.
Solutions:
there are couple of things I can suggest.
Use UpdatePanel to prevent Postback of the entire page or
make your btnImport a client side button altogether, and do a post using xhr or jQuery's ajax.
Set the visibility of btnGenerate on the server side itself
most simple would be the 3rd one i.e. remove the onclientclick event from the code and change your btnImport to do this:
protected void btnImport_Click(object sender, EventArgs e)
{
InventoryGrid.DataBind();
ErrorsGrid.DataBind();
//set visibility of btnGenerate in Page_Load also;
btnGenerate.Visible = ErrorsGrid.Rows.Count == 0;
}
and remove display:none from btnGenerate from client
There's no need for a JS function here.
Simply check the datasource for ErrorsGrid if count != 0 and if it's not just set the visibility of your button in codebehind.
If i've understood your req. correctly, setting 'Visbible' property of button to true or false should work. i.e btnGenerate.Visible=true/false. Initially you can set the button visibility as false then based on the record count you can modify it in the required event handler.
How to remove disabled attribute from asp.net button from code-behind.
I have made disbled attribute to be true for button from javascript and want to enable it in code-behind.
In Javascript,
btnCalc.disabled=true;
In Code-behind,in the checkbox changed event,I am making it to enable,
btnCalc.enabled=true;//but this does not enable the button.
I tried to remove attributed for button,but it didt works for me.
btnCalc.Attributes.Remove("disabled");
Please,let me know,any other way to achieve this.
Hi Maha i have Tried this and Got Working.,
JavaScript:
<script type="text/javascript">
function handleChange(cb) {
var btn = document.getElementById('ButtonTest');
if (cb.checked == true) {
btn.disabled = true;
alert('Checked True');
return true;
} else {
alert('False');
btn.disabled = false;
return false;
}
}
</script>
ASPX Page Code:
<div>
<asp:CheckBox runat="server" ID="checkMe" title="Hey Check Me" name="Check Me" ClientIDMode="Static" onclick="handleChange(this)" AutoPostBack="false" Text="Check Me" />
<asp:Button runat="server" ID="ButtonTest" title="Hey Check Me" ClientIDMode="Static" Text="Submit Button" OnClick="ButtonTest_Click" />
</div>
Code Behind:
protected void ButtonTest_Click(object sender, EventArgs e)
{
// Your Logic
}
But the Check Box AutoPostBack="false" should be in false. Other wise the Entire page will be reloaded and disabled will attribute will removed.
Hope it may helpful., :)
You may need some knowledge of ASP.NET page life circle
You enabled the button from code-behind, it just help generate a response text to browser, the JavaScript will run after browser load HTML(the response text), you JavaScript code run and disable the button again.
You can register a startup script to enable the button after you disable button script
I've got a DIV which contains some text in it.
Ive also got an asp:Button, which when pressed I would like to retrieve this text. However, it appears that as soon as I press the button, the DIV's contents is reset - most likely due to postback.
The DIV has got runat=server". Does anyone have any idea as to what may be done to make this DIV retain its contents on pressing the button? The data is manipulated countless times before the button is pressed, so I would like to try avoiding updating a Session every time.
Try something like this:
getText = function(){
alert($("#<%=Panel1.ClientID%>").text());
return false;
}
<asp:Panel ID="Panel1" runat="server">
</asp:Panel>
<asp:Button ID="Button1" runat="server" OnClientClick="return getText();" ... />
You can also try this:
$("#<%=Button1.ClientID%>").click(function(){
alert($("#div1").text());
return false;
});
One way would be grabbing button click event in your makrkup, store your DIV content in a hidden field, then fire postback manually in your button click.
Try using an asp:Panel. It renders as a DIV and you have access to all of its properties at all points in the page life cycle.
another way is to use Ajax. specifically - updatepanel control
You can store you DIV content in a hidden field by calling a JavaScript function in onClientClick event of the button - it will execute just before OnClick event, before postback. This way, there's no need to fire postback manually.
Let's say you have one div, one hidden field and button with onClientClick and OnClick events. You use simple JavaScript function for the job:
<div id="myDiv" runat="server" ></div>
<asp:Button ID="btnGetDiv" runat="server" Text="Get div value" OnClick="getValueOnServer" OnClientClick="setHiddenFieldF()"/>
<asp:HiddenField ID="hf" runat="server" />
<script type="text/javascript">
function setHiddenFieldF() {
var nevValue = document.getElementById('<%= myDiv.ClientID %>').innerHTML;
document.getElementById('<%= hf.ClientID %>').value = nevValue;
}
</script>
Then, on the server, just use the value of the hidden field.
You can't read your DIV's content because it is not send to the server in the postback. Only values of form elements (<input>, <textarea>, <select>, etc.) are send.
If you really want to read DIV's content, you can copy it to the hidden input (as wrote Kavousi).
Just add hidden field to your page:
<asp:HiddenField ID="hidden" runat="server" />
And then in code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Page.Form.Attributes["onsubmit"] = string.Format(#"$(""#{0}"").val($(""#{1}"").html());", hidden.ClientID, div.ClientID);
}
}
(div is your div's name).
You can then read div's content by reading hidden.Value.