ASP.net firing jQuery AFTER asp UPDATE - c#

I have a formview which launches in editmode and allows the user to select yes or no from a dropdown and hit the 'save' button which is the Formviews Update command:
<asp:FormView ID="FormView1" runat="server" DataSourceID="CustomerEdit">
<ItemTemplate>
hello
</ItemTemplate>
<EditItemTemplate>
<asp:Label ID="CustomerNameLabel2" runat="server"
Text='<%# Bind("CustomerName") %>' />
<asp:Label ID="CustID" runat="server" visible="false"
Text='<%# Bind("CustID") %>' />
<br>
<br></br>
Is This Your Customer?
<br>
<br>
<asp:DropDownList ID="DropDownList1" runat="server"
SelectedValue='<%# Bind("IsThisMyCustomer") %>'>
<asp:ListItem Selected="True"></asp:ListItem>
<asp:ListItem>Yes</asp:ListItem>
<asp:ListItem>No</asp:ListItem>
</asp:DropDownList>
<br>
<br>
<asp:Button ID="Button" runat="server" CausesValidation="True"
CommandName="Update" Text="Save" />
</EditItemTemplate>
</asp:FormView>
This button also has JQuery behind it
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<script>
$(document).ready(function () {
$("input[id$='Button']").click(function () {
var div = $("div");
$("img").hide();
div.animate({ height: '300px', opacity: '0.4' }, "slow");
div.animate({ width: '300px', opacity: '0.8' }, "slow", function () {
window.location.href = "MyCustomers.aspx";
});
});
});
</script>
Now when the user hits the button, the Jquery script kicks in, then about halfway through the animation of the jquery script, the SQL update through the FormView Update command kicks in, essentially stopping jquery from doing its stuff and launching the itemtemplate of the formview as per a regular update.
What I want is the SQL update to occur and postback, then the jquery fire straight after.
What's the best approach to doing this

You're mixing client-side and server-side functionality. The order of events you're observing is this:
Load the page
Bind the click event to the element
Click the element (begins the animation)
Reload the page
Bind the click event to the element
Your click event is really only accomplishing one thing, redirecting the user to another page. If the page is being reloaded anyway, then why not do that from server-side code?
Response.Redirect("MyCustomers.aspx");
It doesn't have the animation, but since you're reloading the page anyway then the animation is kind of moot. If you want to have the animation then you probably don't want to reload the page, in which case you'll want to start looking into AJAX for interacting with the server from JavaScript code. (Which can be a pretty big subject, especially when dealing with WebForms controls. It's often better in that case to just "do it the WebForms way" and not try to mess with them.)
In your comment above, you said you tried this...
$(window).load(function () { $(document).ready(function () { ...
That's... not right. Don't just randomly mix and match jQuery code, understand what it is you're doing here. You're binding events (such as ready) inside of an event handler (such as load), which can get pretty strange pretty fast. Separate the event you want to respond to from the code you use to respond to it. For example, consider what you have here:
$("input[id$='Button']").click(function () {
//...
});
This doesn't execute the code inside the function, it binds that function to be executed when the click event happens. The same is true of this structure:
$(document).ready(function () {
$("input[id$='Button']").click(function () {
//...
});
});
This binds a function to be executed when the ready event happens. That function, in turn, binds another function to be executed when the click event happens.
Consider for example what I mentioned in my comment above... If you really want to animate the element and then redirect after the page reloads (which I still contend is a pretty poor UX, to be honest) then you would do this:
$(document).ready(function () {
var div = $("div");
$("img").hide();
div.animate({ height: '300px', opacity: '0.4' }, "slow");
div.animate({ width: '300px', opacity: '0.8' }, "slow", function () {
window.location.href = "MyCustomers.aspx";
});
});
This skips the click event and just sets that code to execute immediately on the ready event. Which means it'll execute when the page loads, basically. Which also means that you don't want to always include this in the page (otherwise you'd never be able to view the page for more than a moment). You'd want to only include it dynamically from the post-back which should cause this redirect.
Ultimately, you need to separate your client-side functionality from your server-side functionality. If you're just redirecting after a form post (which is what you're doing), then redirect from server-side code. If you want the bells and whistles of client-side animations and UX, don't use WebForms post-backs.

Related

How to implement a click event on textbox in ASP.NET?

In my web application I need a functionality so that when users click on textbox to input values, it should make the button and the other fields visible?
I am using the code provided below but, could not get it working.
C#:
protected void TextBox1_Click(object sender, EventArgs e)
{
ButtonSearch.Visible = true;
}
ASP.NET:
<asp:TextBox ID="TextBox1" runat="server" OnTextChanged="TextBox1_TextChanged" OnClick="TextBox1_Click"></asp:TextBox>
<asp:Button ID="ButtonSearch" runat="server" OnClick="ButtonSearch_Click" Text="Search" Visible="False" />
How to accomplish this?
Set AutoPostback="True". This way the event will be fired server-side, and the button will become visible.
<asp:TextBox ID="TextBox1" runat="server" OnTextChanged="TextBox1_TextChanged" OnClick="TextBox1_Click" AutoPostBack="true"></asp:TextBox>
However, if you only want to toogle visility of a button, you really should considerate javascript. This will save a trip back to the server.
<asp:TextBox onclick="txtBox1_ClientClicked()" ID="TextBox1" runat="server" OnClick="TextBox1_Click"></asp:TextBox>
<asp:Button ID="ButtonSearch" runat="server" OnClick="ButtonSearch_Click" Text="Search" style="display:none;" />
<script type="text/javascript">
function txtBox1_ClientClicked(){
var theButton = document.getElementById('<%=ButtonSearch.ClientID%>');
theButton.style.display = 'block';
}
</script>
You do not need to post back to the server to accomplish your job. You can use client side onFocus event and javascript/jquery, for example.
I know I used an input of type text, and you are using an ASP Control which posts on server, but here is a JSFiddle to get you on the right track: http://jsfiddle.net/Mmjtz/1/
$("<%= ButtonSearch.ClientID %>").click(function(){
$("#TextBox1").show():
});
In this code you need to pass fields ID which you want to visible on the click of button.
Put the textbox inside a div and use the div's onClick event from codebehind. It's not what you asked but it works for me without any errors. Here is a javascript function to implement requested event:
function toggleVisibility()
{
document.getElementById('TextBox1').disabled = true;
/*
...some other code...
*/
}
And of course, you have to define your onclick event at the div definition after implementing this JS function.
<div id="TBdiv" onClick="toggleVisibility()">
<asp:TextBox ID="TextBox1"..../>
</div>
IMPORTANT: Since you now disabled your TextBox from codebehind, you have to enable it in somewhere before you want to use it again. Otherwise you will not see it while the page is running.
jQuery is the perfect solution for your problem. The code would be something like this:
$("#TextBox1").on("click",function(){$("#ButtonSearch").css("visibility", "visible");})
You include the script by adding <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> to the page and then you can add the piece of code above to within <script></script> tags.

CodeMirror with UpdatePanel in asp.net

I'm using CodeMirror in an ASP.NET web application. The web app uses UpdatePanel (ajax).
In ajax postback, I'm not able to get updated text from the CodeMirror textbox on server side and after the postback, the text gets reset. This WORKS if I don't use an update panel. What am I missing?
Below is the code mirror code:
editor = CodeMirror.fromTextArea(document.getElementById("<%=txtLua.ClientID%>"), {
matchBrackets: true,
theme: "neat",
pollInterval: 100,
continuousScanning: 500
});
<asp:UpdatePanel ID="upd" runat="server">
<ContentTemplate>
<asp:TextBox runat="server" ID="txtLua" Height="320" Width="600" TextMode="MultiLine"></asp:TextBox>
<asp:Button ID="btn" runat="server" OnClick="btn_Click" Text="btn" />
</ContentTemplate>
</asp:UpdatePanel>
Is there an asp.net/C# sample for using CodeMirror? Any help is appreciated.
The short answer is: create a javascript event hook that fires early (before the UpdatePanel begins to do its work) and manually calls CodeMirror's .save() function.
The problem seems to arise because the auto-magic form.submit override that CodeMirror supplies is triggered after the ScriptManager has already passed the ViewState of the panel back to the server. This means the server only receives the TextBox in its initial state (CodeMirror hasn't put what you've typed into it yet). I checked the DOM events in Chrome and ScriptManager's hook was consistently ahead of the form.submit override that CodeMirror added.
I got around this by adding an .onclick to the submit button right after CodeMirror loaded. Using your example:
var editor = CodeMirror.fromTextArea(document.getElementById("<%=txtLua.ClientID%>"), {
leaveSubmitMethodAlone: true, //since you don't need this anymore, no reason to complicate your DOM
matchBrackets: true,
theme: "neat",
pollInterval: 100,
continuousScanning: 500
});
window['cmLocalStateEvent'] = function () { editor.save(); };
//saveButton = document.getElementById("<%=btn.ClientID%>"); //grab the save button
//if (saveButton) {
// saveButton.onclick = function () { editor.save(); }; //make it do what the submit action was going to do
//}
<asp:UpdatePanel ID="upd" runat="server">
<ContentTemplate>
<asp:TextBox runat="server" ID="txtLua" Height="320" Width="600" TextMode="MultiLine"></asp:TextBox>
<asp:Button ID="btn" runat="server" OnClientClick="if(window['cmLocalStateEvent'])window.cmLocalStateEvent();" OnClick="btn_Click" Text="btn" />
</ContentTemplate>
</asp:UpdatePanel>
Now the .onclick is ahead of the ScriptManager hook, and will fire first. Infact, if you put an OnTextChanged= and AutoPostBack= on the TextBox it'll fire even before the button that you just clicked does.
Essentially, the trick is to get CodeMirror's save to apply before ScriptManager submits the ViewState back to the server.
EDIT:
I've found since posting this, that you'll run into a troublesome issue if your submit button is also inside the UpdatePanel (which yours is). The .onclick will not persist after the initial submit and you'll be reset to a clean button with no event hooks. My current working solution to that scenario is adding a window['cmLocalSaveEvent'] function and adding the client .onclick to the ASP template (so the panel refresh puts it back for you). Updated code above to reflect this.
This is how I managed to make it work, just in case someone else needs it. After instantiating editor, I'm keeping the textbox aligned every time the blur event occurs.
editor.on('blur', function () {
arguments[0].save();
});

save form on code behind

I want to save (update) a form from code behind.
I have in the edit form the buttom
<asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" CommandName="Update" style="color: #FF0000; font-size: medium; font-weight: 700" Text="Update" />
but in some cases I want to save the form automatically before firing the update button.
How can I do this on code behind?
You can add a Timer to the page to have ASP cause a postback on a fixed interval. You can then attach an event handler to the Tick event and save the form there.
That alone would cause a full page postback on each interval; if you want to have the saving be asynchronous you can wrap the Timer in an UpdatePanel to have it do an async postback. You could also have a label in the UpdatePanel as well, or some other control, to indicate that the form was saved.
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Timer runat="server" Interval="5000" ID="timer" />
<asp:Label runat="server" ID="lblTimerResponse" />
</ContentTemplate>
</asp:UpdatePanel>
Then in your code behind all you need is:
timer.Tick += (s, _) =>
{
SaveForm();
lblTimerResponse.Text = "Form automatically saved";
};
but in some cases I want to save the form automatically before firing
the update button.
You can use JavaScript interval or timeout functions in order to achieve a timer functionality.
Personally, I would do it using jQuery framework, AJAX technique, interval and serialize functions.
Add the following to the head section in your aspx page (verify that form1 is the ID of your form or change it accordingly):
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script type="text-javascript">
var result = self.setInterval(function(){
var $frm = $('#form1');
$.ajax({
type: $frm.attr('method'),
url: $frm.attr('action'),
data: $frm.serialize(),
success: function (msg) {
alert("Success");
}
});
}, 10000); // Post(update) your form each 10 seconds.
</script>

Triggering a postback from Javascript fails

I am trying to trigger a postback if a certain condition is true. Initially, a user will click on a button on my form, the server does some work, and in the process of doing that work it assigns a hidden field the value of '1'. When the page reloads after that very first postback, I am trying to use javascript to check the hidden field, and if it is '1' I need the page to postback again so the server side can do some additional processing. The reason for doing it this roundabout way is so that I can create controls on the form from my C# code behind as well as download a file in 1 user interaction. Here is what I have so far:
<script type="text/javascript" language="JavaScript">
function atload() {
var HWInfo = document.getElementById('HiddenHW').value;
if (HWInfo == '1') {
alert("flag has been set");
__doPostBack('<%= hdnHidden.UniqueID %>', '');
}
}
$(document).ready(atload);
</script>
The alert that says the flag has been set correctly fires, but the __doPostBack does not. In my ASPX file, here is the relevant part:
<form id="InventoryForm" runat="server">
<div>
<asp:Label ID="lblClientList" runat="server" Text="Client List"></asp:Label>
<asp:DropDownList ID="comboClientList" runat="server"></asp:DropDownList>
<asp:Label ID="spacer1" runat="server" Text=" "></asp:Label>
<asp:Button ID="btnGenerateHWReport" runat="server" Text="Generate Hardware Inventory Report" />
<asp:Label ID="spacer2" runat="server" Text=" "></asp:Label>
<asp:Button ID="btnGenerateSWReport" runat="server" Text="Generate Software Inventory Report" />
<br />
<br />
<asp:Panel ID="MissingCompPanel" runat="server"></asp:Panel>
<asp:HiddenField ID="HiddenHW" runat="server" Value="0" />
<asp:HiddenField ID="hdnHidden" runat="server" />
</div>
</form>
I can tell the postback never fires, because I have breakpoints in the Page_Load C# codebehind that never get tripped. I have break points on almost every single line of this:
if (!Page.IsPostBack)
{
// Page is not a postback, this is the first visit here
string foo = HiddenHW.Value;
}
else
{
// Page is a postback and not initial load
string foo = HiddenHW.Value;
}
Why is my __doPostBak after the alert not firing, and is there a better way to do this? The end result I want is if my hidden field is '1', then I want my 2nd trip to the server to 1) actually happen and 2) know that the hidden field is '1' and not its default '0'.
Thanks!
how about just clicking the submit button programatically and have it call __doPostBack the way it normally does?
Try invoking the __doPostBack method on the page instead of the hidden control
__doPostBack('__Page', '');
When you get the value of HiddenHW, you're not using the right ID. If you look at the rendered source, the ID of the control is something like ctl00_HiddenHW. To get that ID, you should use HiddenHW.ClientID. I believe __doPostBack also needs the ClientID, not UniqueID.
function atload() {
var HWInfo = document.getElementById('<%= HiddenHW.ClientID %>').value;
if (HWInfo == '1') {
alert("flag has been set");
__doPostBack('<%= hdnHidden.ClientID %>', '');
}
}

Setting focus on top of the page on click of asp.net link button

I've a asp.net datagrid which shows customer order details.
Pagination at the bottom of the grid is done using datalist and asp.net Linkbutton controls.
Here is the code:
<asp:DataList ID="DataList2" runat="server" CellPadding="1" CellSpacing="1"
OnItemCommand="DataList2_ItemCommand"
OnItemDataBound="DataList2_ItemDataBound" RepeatDirection="Horizontal">
<ItemTemplate>
<asp:LinkButton ID="lnkbtnPaging" runat="server"
CommandArgument='<%# Eval("PageIndex") %>'
CommandName="lnkbtnPaging"
Text='<%# Eval("PageText") %>' />
<asp:Label runat="server" ID="lblPageSeparator" Text=" | " name=></asp:Label>
</ItemTemplate>
</asp:DataList>
When the user clicks on any page number(ie.Link button), I need to set focus on top of the page.
How do i do this?
Thanks!
I think the default behaviour would be for the page scroll position to be set back to the top of the page. Is there anything else in your page that might be overriding this behaviour?
For example:
Is your DataList inside an UpdatePanel? In that case the current scroll position will be maintained over a (partial) post-back. You would therefore need to reset the scroll position to the top of the page yourself. One way to do this would be to implement a handler for the PageRequestManager's EndRequest client-side event which would set the scroll position - this thread explains how
Is the Page MaintainScrollPositionOnPostBack property set to true?
You could try setting a named anchor at the top of the page. Here is an article that explains it http://www.w3schools.com/HTML/html_links.asp
After an AJAX partial postback you may need to return to the top of your ASPX page to display an error message, etc. Here is one way that I have done it. You can add the JavaScript function below to your ASPX page and then call the method when needed in your code-behind by using the ScriptManager.RegisterClientScriptBlock method.
ASP.NET C# Code-behind:
ScriptManager.RegisterClientScriptBlock(this, Page.GetType(),
"ToTheTop", "ToTopOfPage();", true);
JavaScript:
<script type="text/javascript">
function ToTopOfPage(sender, args) {
setTimeout("window.scrollTo(0, 0)", 0);
}
You can also just JavaScript to scroll to the top of the page by using the OnClientClick property of your button. But this will cause this behavior to occur every time the button is clicked and not just when you want it to happen. For example:
<asp:Button id="bntTest" runat="server"
Text="Test" OnClick="btn_Test" OnClientClick="javascript:window.scrollTo(0,0);" />
<asp:LinkButton ID="lbGonder" runat="server" CssClass="IK-get" ValidationGroup="ik" OnClick="lbGonder_Click" OnClientClick="ddd();" title="Gönder">Gönder</asp:LinkButton>`
<script type="text/javascript">
var ddd = (function () {
$('body,html').animate({
scrollTop: 300
}, 1453);
return false;
});

Categories