Показват се публикациите с етикет JavaScript. Показване на всички публикации
Показват се публикациите с етикет JavaScript. Показване на всички публикации

Inline Scripts in UpdatePanel – Doesn’t Work After Partial Postback

събота, 28 март 2009 г.

Hello, guys!
Last months I have worked on a very interesting project which uses latest .NET technologies as well as some other APIs like Microsoft Virtual Earth and Google Earth. My team and I had a lot of challenging problems to solve some of which I want share with you.

The situation
Imagine that we have a user control called UserControlWithInlineScripts with the following code in it:

As you can see, the only thing which we have on the page is a button, which calls a JavaScript function SayHelo() when clicked. The interesting thing here to note is that the function is declared inline in the .ascx file (we will see later why this is so important).

Now let’s put the control in a sample page like the following:

The ButtonShowControl on the server side only sets the Visible property of our user control to true. From first sight nothing strange – we have just a control which is showed dynamically by a button. If you test this code it will work perfectly well.

But what is the actual problem? Just put a wrapping UpdatePanel…
You will have problem if you try to put the content of the page in an UpdatePanel. When you click the button to show the control – it will be shown (as we actually expect). But if you click the button which calls the inline script, the following JavaScript error appears:

As you can see the browser cannot find the function which the button’s click calls. You know that everything with the function and its call should be OK as we have just tested it without the UpdatePanel. Therefore problem obviously is in the panel, but where exactly?

Explanation of the problem
Why this happens? When you update the content inside an UpdatePanel the old content of the panel is replaced by the new content trough the innerHTML property. In general if you set the innerHTML of a DOM element with markup which contains a script block inside it, this doesn’t cause the script to be registered as script in the DOM tree. In other words the browser looks at this new content as pure markup (text). If you want to say to the browser that some string is script (in other words inject a script block into the DOM) you can do this with the method document.createElement(“script”). Another way to evaluate and execute script, which you have as string is to use the eval(string) function, which takes only one string argument – the script to be executed.

There are some interesting static methods into the ScriptManager class which gives you the ability to register startup script, script block, onsubmit statement, etc. They prevent us from this problem if we do not have our scripts as inline and register them trough this methods.

Conclusion
In general it is not a good practice to have your scripts as inline and is better to have them as an external .js files. But the problem with the inline one still exists. You can think of some workarounds of this problem and this is my challenge for you – just share your ideas!

How to disable validation group with JavaScript?

събота, 10 ноември 2007 г.

Hi again!
I haven’t blogged from a long time ago – I haven’t had enough time to do all of the stuff that I wanted. But now (at last :-)) I have time for my blog. There are a lot of ideas/problems which I want to share with you! So let’s go to the first one.

What is the problem?
These days comes up the need to disable a bunch of validators on the client side. For example imagine that you have a checkbox which shows/hides a number of textboxes. When the checkbox is checked the user is able to fill the boxes (thus validation is required) and on the other hand when he can’t see/fill the boxes, validators should be turned off. I tried to find an example of how to disable ValidationGroup with JavaScript but I couldn’t.

How we can fix this?
Ok guys let’s solve the problem ourselves. The idea is very simple and straightforward.
1. We have a function provided by Microsoft ValidatorEnable(validator, isEnable) which takes a validator and whether it should be enabled/disabled.
2. What else we have? If we look at the rendered html of a page that contains at least one validator, we will see that all of them are elements of the array Page_Validators.
3. The third thing which we have is the property of each validator named validationGroup.

Now we know how to enumerate all validators in a page, how to enable/disable particular validator and how to ask a validator whether it is part of particular validationGroup. Thus we have enough knowledge to solve the problem.
Below is sample code of an .aspx file. In it you will see two text boxes. Both have required field validator. The second has regular expression validator, too. I have made groups for the validators from a particular type. There are two buttons – the one which enables the required field validators group and the other to disable it. The two buttons call my custom function named (accordingly to Microsoft convension) ValidationGroupEnable. The function enumerates all page’s validators and if a validator is from the given validation group it is enabled/disabled according to the value given to isEnabled. Internally the function HasPageValidators fixes the situation when we doesn’t have any validators (the problem here is that when you don’t have any validators Page_Validators array is not defined and if you try to use it there will be an error).

The code

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_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 id="Head1" runat="server">

<title>Enable/Disable validation group with JavaScript</title>

<script type="text/javascript">
function HasPageValidators()
{
var hasValidators = false;

try
{
if (Page_Validators.length > 0)
{
hasValidators = true;
}
}
catch (error)
{
}

return hasValidators;
}

function ValidationGroupEnable(validationGroupName, isEnable)
{
if (HasPageValidators())
{
for(i=0; i < Page_Validators.length; i++)
{
if (Page_Validators[i].validationGroup == validationGroupName)
{
ValidatorEnable(Page_Validators[i], isEnable);
}
}
}
}
</script>


</head>
<body>
<form id="form1" runat="server">
<div>

<input type="button" value="Disable required field validators!"
onclick="ValidationGroupEnable('vgRequiredFields', false)" />
<input

type="button" value="Enable required field validators!"
onclick="ValidationGroupEnable('vgRequiredFields', true)" />
<table>
<tr>

<td style="width: 229px">
<asp:Label ID="lblName" runat="server" Text="Name: " /><asp:TextBox ID="txtName" runat="server" />

<asp:RequiredFieldValidator ID="rfvName" runat="server"
ErrorMessage="*" ControlToValidate="txtName"
ValidationGroup="vgRequiredFields" /></td>


</tr>
<tr>
<td style="width: 229px">
<asp:Label ID="lblEmail" runat="server" Text="Email: " /><asp:TextBox ID="txtEmail" runat="server"/>

<asp:RequiredFieldValidator ID="rfvEmail" runat="server"
ErrorMessage="*" ControlToValidate="txtEmail" ValidationGroup="vgRequiredFields" />

<asp:RegularExpressionValidator ID="revEmail" runat="server"
ErrorMessage="!" ControlToValidate="txtEmail" ValidationGroup="vgRegularExpressions"

ValidationExpression="^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$" /></td>
</tr>
</table>
</div>

</form>
</body>
</html>

Conclusion

Hope this helps :-).
P.S. DD you now have what you needed. Keep up the good work! ;-)

 
Vesko Kolev's Blog : IDeveloper -