Solved

Javascript not loading in partial postback

Posted on 2014-04-17
9
896 Views
Last Modified: 2014-04-22
Hi all,

I have an aspx page with an update panel which i am loading usercontrols dynamically.
The JQuery file is added in the masterpage of the aspx file header;

<script type="text/javascript" src="http://code.jquery.com/jquery.js"></script>

Open in new window


Each usercontrol also has a specific set of js files. I load the js (one example) as follows (note LoadJS() is called in the UserControl pageload event);

    private void LoadJS()
    {
        //load the .js files
        ClientScriptManager cs = Page.ClientScript;
        Type cstype = this.GetType();

//added to try and resolve the issue
        if (!cs.IsClientScriptIncludeRegistered(cstype, "JqueryJS"))
            cs.RegisterClientScriptInclude(cstype, "JqueryJS", ResolveClientUrl("http://code.jquery.com/jquery.js"));

        if (!cs.IsClientScriptBlockRegistered(cstype, "loginClientID"))
        {
            string clientid = "";
            clientid += String.Format("var jutb = '#{0}';", myLogin.FindControl("UserName").ClientID);
            clientid += String.Format("var jptb = '#{0}';", myLogin.FindControl("Password").ClientID);

            cs.RegisterClientScriptBlock(cstype, "loginClientID", clientid, true);

        }

        if (!cs.IsClientScriptIncludeRegistered(cstype, "WatermarkJS"))
            cs.RegisterClientScriptInclude(cstype, "WatermarkJS", ResolveClientUrl("~/js/jquery.watermark.min.js"));

        if (!cs.IsClientScriptIncludeRegistered(cstype, "LoginJS"))
            cs.RegisterClientScriptInclude(cstype, "LoginJS", ResolveClientUrl("~/js/login.js"));
    }

Open in new window


now in my login.js I have (shortened to suit) the following code;

function pageLoad(){
    //alert('partial handler');

    $(jutb).watermark('Username or Email address');
    $(jptb).watermark('Password');

    Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(InitializeRequest);
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
}


// Called when async postback begins
function InitializeRequest(sender, args) {
    // alert("You are in the InitializeRequestHandler function.");  // breakpoint here


}

// Called when async postback ends
function EndRequestHandler(sender, args) {
    // this function is run after an Ajax partial postback occurs

    //alert("You are in the EndRequestHandler function.");    // breakpoint here
 //   $(jutb).val("0test");
 //   alert(jutb);
 //   alert($(jutb).val());
//$(jutb).watermark('Username or Email address');
 //   $(jptb).watermark('Password');
 //   alert('afterwatermark');

    loadUsername();
    loadPassword();

    if (args.get_error() != undefined)
        alert("There was an error" + args.get_error().message);

    return;
}

Open in new window


now just to clarify. alert('partial handler'); IS firing when I load the next usercontrol.

Also, jutb is being assigned the .clientID as the alert in the end_request is showing this.

Finally, I have a validate() js method attached to a linkbutton. When I alert out  $(jutb).val() I am getting 'undefined' returned. I assume this means that JQuery is not being readded to the project?

function validate() {
   
    if (usernameValid && passwordValid)
        return true;
    else {
 
 if (!usernameValid) {
     alert('validating  :' + $(jutb).val() + ":");
     highlightField($(jutb), false);
            highlightFieldMessage($(jutb), false, "Enter your username or email.");

        }

        if (!passwordValid) {
            highlightField($(jptb), false);
            highlightFieldMessage($(jptb), false, "Enter your password.");
        }

        return false;
    }
}

Open in new window


Also to mention I had the .watermark code inside the end_request method, but this then meant that the fields were not watermarked at all. Moving into the pageLoad method fired and watermarked the fields, but only when loading the page (not a partial postback).

In conclusion does anyone have any ideas on whats going on here? It seems that the JQuery files (and maybe watermark too??) are not been loaded?
0
Comment
Question by:flynny
  • 5
  • 4
9 Comments
 
LVL 52

Expert Comment

by:Julian Hansen
ID: 40006589
where is jutb defined?

It sounds like the partial load is not rebinding the JQuery event handlers - if you are downloading controls as part of your AJAX request you have to either

a) Rebind the event handlers after downloading the new content

OR

b) When you initially bind the event handlers use the .on() for dynamic binding.
0
 

Author Comment

by:flynny
ID: 40006637
Hi Julian,

many thanks for the reply.

jutb is bound in the .cs and is basically just the .clientID

string clientid = "";
            clientid += String.Format("var jutb = '#{0}';", myLogin.FindControl("UserName").ClientID);
            clientid += String.Format("var jptb = '#{0}';", myLogin.FindControl("Password").ClientID);

Open in new window


the issue is strange because it appear JQuery itself is not loading? (i.e. a .val() comes back undefined?).

i've created a test link here (I have only tested in firefox);

http://dev3.mfitonline.co.uk/Login.aspx

here login.aspx loads the login.ascx file.

as you can see the .watermark works. if you click the 'login' button you will see the alerts fire with the jutb values.

Now if you then click the 'forgotten password/username' link this will load another .ascx file (the js for this are not loaded either but I think it is part of the same issue).

If you then click the red cross to close this popup (and reload login.ascx) you will see that the js is not working.

If at this point you then click the 'login' button you can see that 'undefined' is returned for the .val() method.

Now I have also notice that if you click the 'forgotten password' link again just once, it reloads the js and the watermark appears???

It seems then that a second click is required to load the usercontrol popup? any ideas why this is happening?
0
 
LVL 52

Expert Comment

by:Julian Hansen
ID: 40006706
the issue is strange because it appear JQuery itself is not loading? (i.e. a .val() comes back undefined?).
You will get undefined if the element attached to the .val() does not exist. The acid test is do you get
 
undefined

in the console OR
$.val() is not a function

If the former - then JQuery is loading - it is the element that is not defined. If JQuery is not loading you will get the latter.

What appears to be happening is when you regenerate the login page (not sure why you are doing that rather than just hidding the popup), however, the controls are comming back with different id's

When the page loads the username has an id of
#ctl00_ContentPlaceHolder1_ctl01_myLogin_UserName
When you close the popup it has an id of
#ctl00_ContentPlaceHolder1_ctl02_myLogin_UserName

That is why you are getting the undefined.

To solve this problem you need to look at why your callback is generating a different ID.

Also, consider managing the popup client side instead of posting back to restore the login when you close the popup. The popup should just be an overlay over your existing page. By removing it the original page should be restored.

Nice balloons by the way :)
0
 

Author Comment

by:flynny
ID: 40006794
Thanks Julian,

I read your article following on from the question I posed and it give a nice effect doesn't it :). I've been tinkering with a little random movement on the x axis as well but thats another story.

1. Not sure if i've done it right but i've added $(jutb).val() to the watch var window in firebug and this becomes 'undefined'. So it does appear that jquery is loading.

2. The LoadJS is called regardless of postback from the pageload event of the acsx control, but I would have thought that the name stay the same? From looking at breakpoints the cs.RegisterClientScriptBlock(cstype, "loginClientID", clientid, true); is firing so this should overwrite with the new id? could the id be being changed after this call?
private void LoadJS()
    {
        //load the .js files
        ClientScriptManager cs = Page.ClientScript;
        Type cstype = this.GetType();

        if (!cs.IsClientScriptIncludeRegistered(cstype, "JqueryJS"))
            cs.RegisterClientScriptInclude(cstype, "JqueryJS", "http://code.jquery.com/jquery.js");

       // if (!cs.IsClientScriptBlockRegistered(cstype, "loginClientID"))
       // {
            string clientid = "";
            clientid += String.Format("var jutb = '#{0}';", myLogin.FindControl("UserName").ClientID);
            clientid += String.Format("var jptb = '#{0}';", myLogin.FindControl("Password").ClientID);

            cs.RegisterClientScriptBlock(cstype, "loginClientID", clientid, true);

       // }
        if (!cs.IsClientScriptIncludeRegistered(cstype, "WatermarkJS"))
            cs.RegisterClientScriptInclude(cstype, "WatermarkJS", ResolveClientUrl("~/js/jquery.watermark.min.js"));

        if (!cs.IsClientScriptIncludeRegistered(cstype, "LoginJS"))
            cs.RegisterClientScriptInclude(cstype, "LoginJS", ResolveClientUrl("~/js/login.js"));
    }

Open in new window


2. Any ideas on the 2 clicks issue? As the click seems ot revert the id back to the original id?

Finally, I do agree with calling the popup clientside. Its more a proof of concept that I can use this methodology later in the site. As I'll have a number of wizard style forms broken down into usercontrols, each utilising javascript and jquery on the fly.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 52

Accepted Solution

by:
Julian Hansen earned 500 total points
ID: 40006867
JQuery is definitely loading - it loads with the initial page load - and will remain there for the lifetime of the page.

is firing so this should overwrite with the new id? could the id be being changed after this call?

The problem is definitely related to the id's in the controls changing.

The double click to close - I noticed that - have not had a chance to debug that one yet - was focusing on the undefined issue.

I am not really a big fan of the Microsoft model of building pages - I agree it makes it easier from a developer perspecitve to do certain things but sometimes I find the methodology to be counter productive to what I would intuitively like my clientside code to do.

Having said that we have two potential avenues to pursue.

1. Find out why the id's are being recreated with different values.
2. Move to a client side popup.

On 1 - I noticed once you have done the popup once it does not change the id for successive popups - will look at it more and get back to you if I find anything.
0
 

Author Comment

by:flynny
ID: 40007242
OK,

I had a look at the reason for the second click as I was thinking it may be causing the control naming issues.

The first time a button inside the user control is clicked the following happens;

1. the page_load of the login.aspx.cs is called.
2.which invokes the reload of the usercontrol.
3.as the button click has not fired the control being loaded is the existing control.
4.the user control page_load is fired

the same happens as above but on the second click the button click method is fired at the end??
0
 
LVL 52

Expert Comment

by:Julian Hansen
ID: 40010186
Sounds like one of the vagaries in Microsoft's way of doing things that is responsible. Without seeing full code difficult to diagnose.
0
 

Author Comment

by:flynny
ID: 40014304
Hi Julian,

just for info I have managed to solve the issue with jscript loading.

        using (ScriptManager scriptManager = ScriptManager.GetCurrent(this.Page))
        {
         scriptManager.RegisterPostBackControl(ForgotDetails);
        }

Open in new window


However it still doesn't solve the two click being required to launch the button. I have tried numerous things including triggering the button click from jscript to see if it perfomed a full postback that way.

I'll mark this as answered and open a serperate question for this issue.

Thanks for all your time and effort on this. Its appreciated.
0
 
LVL 52

Expert Comment

by:Julian Hansen
ID: 40014397
You are welcome - thanks for the points.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

I found this questions asking how to do this in many different forums, so I will describe here how to implement a solution using PHP and AJAX. The logical flow for the problem should be: Write an event handler for the first drop down box to get …
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.
Many functions in Excel can make decisions. The most simple of these is the IF function: it returns a value depending on whether a condition you describe is true or false. Once you get the hang of using the IF function, you will find it easier to us…

895 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now