Perform at same time javascript and asp.net rendering - javascript

Suppose I have a .gif:
<img alt="" src="./wait.gif" />
And I have a Label:
<asp:Label ID="tbnotif" runat="server" ReadOnly="True" Text="" ></asp:Label>
And a button:
<asp:Button ID="Button1" runat="server" Text="Pubblica" OnClientClick="show_table();add_gif();" OnCommand="Button1_Click" />
I'm using aspx pages, the question is:
Can I click on the button and at same TIME show the .gif with JavaScript and change the Label from code behind? Or will things never be shown at same time?

It looks to me like you want to show a busy animated gif between postbacks, is that right?
Here's how I do it (unless I'm using update panels which have their own progress indicator server control)
<script type="text/javascript">
window.onbeforeunload = function(){showGif();};
</script>
When the page unloads because of a postback (click the button which POSTs to the server), reveal the gif image. When the new page comes back from the server the image will disappear because it's now a new page.
Changing a label is a small operation, so you will probably never see the image as the request/response will turn around very quickly. For testing you can add a System.Threading.Thread.Sleep(3000) in your button handler to simulate a longer running process.
EDIT
AJAX is your only option then, but there are many many ways. One possible solution:
Put the label in an UpdatePanel server control, place button outside of update panel, but set it as an AsyncPostbackTrigger in the update panel's declarative mark-up in the aspx page. Show the gif with OnClientClick handler client-side or using JQuery to attach a client-side click handler to the button.
aspx
<%# Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="AjaxLabel._Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager runat="server" ID="ScriptManager1"></asp:ScriptManager>
<div>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Label runat="server" ID="ajaxLabel">Initial value</asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="asyncButton" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<img id="theImage" src="img/success.png" style="display: none;" />
<asp:Button runat="server" ID="asyncButton" Text="Client & Server Click" OnClientClick="showImage();" OnClick="asyncButton_Click" />
</div>
</form>
<script type="text/javascript">
function showImage() {
document.getElementById('theImage').style.display = "block";
}
</script>
</body>
</html>
aspx.cs
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace AjaxLabel
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void asyncButton_Click(object sender, EventArgs e)
{
ajaxLabel.Text = "Server-side value";
}
}
}

Related

InvalidOperationException: WebForms UnobtrusiveValidationMode in C#

I've a web form with a text box and RequiredFieldValidator Control.
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication2.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
Name : <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate ="TextBox1" ErrorMessage="RequiredFieldValidator">
</asp:RequiredFieldValidator>
<asp:button runat="server" text="Button" />
</div>
</form>
</body>
</html>
When I load the page and click on the button, I get an error saying
Error:
[InvalidOperationException: WebForms UnobtrusiveValidationMode requires a ScriptResourceMapping for 'jquery'. Please add a ScriptResourceMapping named jquery(case-sensitive).]
System.Web.UI.ClientScriptManager.EnsureJqueryRegistered() +145
System.Web.UI.WebControls.BaseValidator.RegisterUnobtrusiveScript() +11
System.Web.UI.WebControls.BaseValidator.OnPreRender(EventArgs e) +88
System.Web.UI.Control.PreRenderRecursiveInternal() +166
System.Web.UI.Control.PreRenderRecursiveInternal() +236
System.Web.UI.Control.PreRenderRecursiveInternal() +236
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4682
I did some googling and found some solutions like changing the target version to 4.0 in web.config, using jquery in the global.asax file and changing the property of UnobtrusiveValidationMode to none.
I even read about unobtrusive javascript at https://en.wikipedia.org/wiki/Unobtrusive_JavaScript. But I could not make any relation with the content given there and the error I encountered
Most of the answers said to refer http://connect.microsoft.com/VisualStudio/feedback/details/735928/in-asp-net-web-application-visual-basic-the-requiredfieldvalidator-doest-work
But this link no longer exists.
When I viewed the source of the web page after changing the target version to 4.0, I found some extra inline javascripts(I guess that's called obtrusive javascripts). What's wrong in using inline codes?
I'm pretty new to ASP.net, so little brevity appreciated.

is there any possible way to display message in both javascript and server side code in one asp button click

My label and button:
<h1 id="display"></h1>
<asp:Button ID="Button1" runat="server" Text="display"
Onclientclick="return show()" onclick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
My script:
<script type="text/javascript">
function show() {
document.getElementById('display').innerHTML =
"iam client side code";
return true;
}
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = "iam server side code";
}
my problem is that when I click on the button click event, client side code calls and next server side code is calling. when server side code calls page refreshes the client side message disappears .How do I display both messages.
Thanks in advance
As you coded a server side button it'll cause a postback to the server. So in two ways you can handle this situation.
First, what you have already tried is handling the message display on client side only. What you need to do is change the server side button into a simple input element.
Second, approach would be to use AjaxExtension <asp:UpdatePanel></asp:UpdatePanel> that will only send the control you want to the server side and won't cause full page reload rather a partial postback.
Second Approach Code : Update your code as follows,
<div>
<asp:ScriptManager runat="server"></asp:ScriptManager>
<h1 id="display"></h1>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Button ID="Button1" runat="server" Text="display"
Onclientclick="return show()" onclick="Button1_Click" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
You can call javascript from button post back also.
you can follow this example
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="Practise.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server">
<title></title>
<script type="text/javascript">
function show() {
document.getElementById('display').innerHTML = "iam client side code";
return true;
}
</script> </head> <body>
<form id="form1" runat="server">
<h1 id="display"></h1>
<asp:Button ID="Button1" runat="server" Text="display" onclick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</form> </body> </html>
Server side code is
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = "iam server side code";
StringBuilder runscript = new StringBuilder();
runscript.AppendLine("show();");
ClientScriptManager manager = Page.ClientScript;
manager.RegisterStartupScript(this.GetType(), "any", runscript.ToString(), true);
}

How to prevent a Javascript disabled button from re-enabling after postback?

The following code sample demomstrates the problem.
When Button1 is clicked, Button3 is disabled through JavaScript. Clicking Button2 causes a server event that intitiates the postback. After the postback Button3 is no longer disabled.
ASPX
<%# Page Language="C#" AutoEventWireup="true" CodeFile="TestDisableButton.aspx.cs" Inherits="StudentForms_CaseManagement_TestDisableButton" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script language="javascript" type="text/javascript">
function Button1_onclick() {
document.getElementById("<%= Button3.ClientID %>").disabled = true;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input id="Button1" type="button" value="Disable Button 3" onclick="return Button1_onclick()" />
<asp:Button ID="Button2" runat="server" Text="Perform Post Back" onclick="Button2_Click" />
<asp:Button ID="Button3" runat="server" Text="Button3" />
<br />
<asp:Label ID="Label1" runat="server" ></asp:Label>
</div>
</form>
</body>
</html>
CodeBehind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class StudentForms_CaseManagement_TestDisableButton : System.Web.UI.Page
{
protected void Button2_Click(object sender, EventArgs e)
{
Label1.Text = "Button 2 clicked";
}
}
The button is recreated on the server side, based on it's latest state (stored in ViewState, which goes from server to browser and back to server), and the posted value.
The problem is that the disabled state is in the ViewState and you cannot modify it on the client side. The only posted value is the value of the control itself (for example the text in a text box).
So, as you cannot modify the ViewState, the only alternative is to have an extra control in your form tha allows to post the disabled state back to the sever. So you need to add a HiddenField, set its state on the client side (in the same script that enables/disables the button), and then, on the server side recovere the posted back value and apply it to the control. I.e., read the hidden field value, and set the Enabled property of the button accordingly.
On postback disable your Button3
protected void Button2_Click(object sender, EventArgs e)
{
Button3.Enabled = false;
}

AddThis.com - ScriptManager

I am trying to register a JS file after a postback from an Update Panel. I am trying to get AddThis.com to work after a postback. It works if I set the multiview.activeviewindex equal to 1. However If I go from view 1 to view 2 it does not work.
Here is the server side code for the project.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'ScriptManager.RegisterStartupScript(Me, Me.GetType, "Test", "http://s7.addthis.com/js/250/addthis_widget.js#username=xa-4d4c6a5604aba88b", False)
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType, "Test1", "http://s7.addthis.com/js/250/addthis_widget.js#username=xa-4d4c6a5604aba88b", True)
MultiView1.ActiveViewIndex = 0
End Sub
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
MultiView1.ActiveViewIndex = 1
End Sub
Here is the ASPX code:
<%# Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="WebApplication6._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=xa-4d4c6a5604aba88b"></script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
<asp:View ID="View1" runat="server">
<asp:Button ID="Button1" runat="server" Text="Button" />
</asp:View>
<asp:View ID="View2" runat="server">
<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style addthis_32x32_style">
<a class="addthis_button_preferred_1"></a>
<a class="addthis_button_preferred_2"></a>
<a class="addthis_button_preferred_3"></a>
<a class="addthis_button_preferred_4"></a>
<a class="addthis_button_compact"></a>
</div>
<!-- AddThis Button END -->
</asp:View>
</asp:MultiView>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
I have tried registering the startup script on the scriptmanager.
Does anyone know how to get this working?
Thanks!
It looks like AddThis works only during window or document load and therefore a little trick is required here. Basically the idea is that you should render AddThis div on first view, than grab it into javascript field and than show inside a div provided in second view.
First of all you have to change your server side code, because you would like to include a whole file, not a script block. You should also do it during PageLoad method only (I'm using c# so that you have to rewrite call below).
ScriptManager.RegisterClientScriptInclude(this, GetType(), "Test", "http://s7.addthis.com/js/250/addthis_widget.js#username=xa-4d4c6a5604aba88b");
You can also just put it in your html header (as you did) and get rid of ScriptManager call which is unnecessary in that case.
Than you have to change a content of your multiview a bit
<asp:View ID="View1" runat="server">
<asp:Button ID="Button1" runat="server" Text="Button" />
<div style="left:-2000em; position:absolute;">
<div class="addthis_toolbox addthis_default_style addthis_32x32_style" id="addThis">
<a class="addthis_button_preferred_1"></a>
<a class="addthis_button_preferred_2"></a>
<a class="addthis_button_preferred_3"></a>
<a class="addthis_button_preferred_4"></a>
<a class="addthis_button_compact"></a>
</div>
</div>
</asp:View>
<asp:View ID="View2" runat="server">
<div id='addHere'></div>
</asp:View>
To do this I wrote a simple javascript module which handle the task.
PageModules = {};
PageModules.AddThis = function ()
{
var $addThis;
function takeAddThis()
{
setTimeout(function ()
{
$addThis = $('#addThis');
$addThis.remove();
}, 100);
Sys.Application.remove_load(takeAddThis);
}
function fixAddThis()
{
var $addHere = $('#addHere');
if ($addHere.length)
{
$addHere.html($addThis);
}
}
Sys.Application.add_load(fixAddThis);
Sys.Application.add_load(takeAddThis);
} ();
Notice that PageModules plays only a namespace role to avoid messing up with a global scope. The AddThis module is self-initialized and it is a kind of singleton. Also you would need to reference jQuery or rework the body of inner methods. I have wrapped your AddThis div by additional "hidden" div to not show it to user. add_load method is fired after all scripts are loaded and after all objects are created according to msdn reference
http://msdn.microsoft.com/en-us/library/bb383829.aspx
We need takeAddThis to be fired only once so that I unbind this method after first call. Additional timeout shifts our logic to the end of queue which secure that AddThis logic would be properly executed (i could use $(document).ready from jQuery here as well, however I wanted to stay consistent.

JQuery event not working on async postback, fixing on 2nd postback, breaking on 3rd

Here is a simplified version of my page:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
var cbFuncInit = function() {
$('div').click(function(evt) {
if (evt.target.type !== 'checkbox') {
var checkbox = $(':checkbox', this);
checkbox.attr('checked', !checkbox.attr('checked'));
evt.stopPropagation();
return false;
}
});
};
$(document).ready(function() {
cbFuncInit();
});
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div id="myDiv" style="background-color:red;height:50px;width:50px;">
<asp:checkbox ID="Checkbox1" runat="server" ></asp:checkbox>
</div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<div id="myDiv" style="background-color:red;height:50px;width:50px;">
<asp:checkbox ID="Checkbox1" runat="server"></asp:checkbox>
</div>
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1"/>
</Triggers>
</asp:UpdatePanel>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</form>
</body>
</html>
Here's a simplified code-behind:
protected void Button1_Click(object sender, EventArgs e)
{
var list = new List<string> { "", "", "" };
Repeater1.DataSource = list;
Repeater1.DataBind();
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "", "cbFuncInit();", true);
}
Here's the problem:
The page allows you to click a div in order to click its nested checkbox. However, when doing a postback to great more checkboxes, then using ScriptManager.RegisterStartupScript to rebind the events, the original div is no longer clickable, while the new divs are...
HOWEVER (it gets better)...
When you click the button once more, all the divs are clickable now...
BUT WAIT...
When you click the button a second time, the first div is once again, no longer clickable.
Anyone know why? I was wondering if it had to do with JQuery's event object. Unfortunately my JavaScript debugging skills are a bit outmatched here.
I'm not sure what is going on here without looking at an actual version of the page, but it seems like there is some kind of conflict happening when you rebind the events.
One thing you can try is:
First replace jQuery 1.2.6 with jQuery 1.3
And then replace $('div').click(function(evt){//function code here}) with $('div').live('click',function(evt){//function code here})
Once you have done that, you do not need to use ScriptManager.RegisterStartupScript to rebind the events, as the events will be captured via delegation. Keep adding new checkboxes via postback, and the events will be bound automatically...
Hope that solves your problem...

Categories