Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Wednesday, March 28, 2012

Ajax Best Practices

I am grappling with bestpractice guidelines for Ajax, especially for detecting whether javascript isenabled. Having a slideshow stuck onthe first slide or an update panel not updating is not a disaster, but havingimportant info lost in a nonfunctioning CascadingDropDown, CollapsiblePanel, orAccordion could be very bad.

I have been researching thison the web and it is pretty confusing. From what I have found so far, the most important best practices appearto be: 1) Notify users (of Ajax usage, browser requirements, and probableoccurrence of page updates) and 2) don't create anything that doesn't work ifjavascript is not available in the user's browser.

I am interested in whatothers are doing with regard to Ajax best practices – at a practicallevel. Do you provide notification ofAjax usage and requirements? Do youdetect whether javascript is enabled and have options in place if it is not? Do you ever avoid using Ajax in crucial performanceareas?

I am using Ajax cautiouslywith good results so far, but worry about using some of the controls in certainsituations. Any feedback from those whoare more experienced in this exciting technology would be greatly appreciated.

http://www.fieldexpert.com/2006/01/03/ajax-best-practices-dont-break-back/

http://www.fieldexpert.com/2006/01/04/ajax-best-practices-dont-break-bookmarks/

http://www-03.ibm.com/able/resources/ajaxaccessibility.html#best

Should add that I will use Ajax in Intranet apps where I can guarantee that javascript is available. I only use it for its practical applications in improving forms. I don't confuse useful asynchronous requests with gimmicky dhtml.


Those are fantastic questions, and imo what this forum should be about (more than the bazillion questions about how come my UpdatePanel doesn't work with control X...)

Myself, I feel that a mix of approaches as you describe work best. The first line of defense would be to write (as much as possible) code that is compatible w/o JS. You then can write the js code to replace actions and whatnot, if available.

I feel like the 'notification' thing sorta falls short in most cases, as it's too often used as a cop-out "Well, we tell them they need js enabled, so we can pretty much do as we please now"

I've considered a detection scheme, though not implemented it, where the Master page first checks for the existence of a session variable (call it "ajaxed" or something). If it's not there, it renders a small js script that makes an async call back to the server to set said variable. w/o the variable set, subsequent pages render in 'legacy' mode that dont' require js at all. if the variable is already set, then the page renders in 'ajax' mode. This would obviously result in a lot more code, so that's why I haven't done it yet.

I think for crucial operations, I'd definitely make sure that the user has a non-ajax alternative somehow, favor being given to the first method if possible for the scenario in question. I actually *thought* that the original idea of the 'extenders' was to do just that, but I haven't worked with them lately since in my experience I can do the same as what I need for them with less js downloaded to the client.

Saturday, March 24, 2012

AJAX and User controls which emit and execute Javascript

I have a user control which emits a bit of Javascript in its Render(HtmlTextWriter) method. When I use this control on a simple ASP.NET page with full page postbacks, it emits the Javascript which is then run by the browser.

However, when I naively drop this control into an UpdatePanel, when the panel gets updated the control renders the Javascript into the right place on the page, but the script is not run, so the control does not appear correct. Is it possible to achieve this somehow? (It ought to be, as we have an alternative AJAX package which does it without modification)

In order to achieve this you should not generate the script text in the Render method. Instead you should use ScriptManager.RegisterClientScriptBlock function. This will work for both postbacks as well as partial postbacks.

I've moved the script into a RegisterClientScriptBlock function, but it still appears not to be executed... here's my control's test OnPreRender() which does the registering, and I can see in the debugger it's called on both full and partial postbacks, but the Javascript alert() only fires off on full postbacks. Any ideas?

protectedoverridevoid OnPreRender(EventArgs e)

{

base.OnPreRender (e);if(Visible)

{

StringBuilder sb =newStringBuilder();StringWriter writer2 =newStringWriter(sb);

writer2.Write(

"<script type=\"text/javascript\">");

writer2.Write(

"//<![CDATA[");

writer2.Write(

"alert('hello world!');");writer2.Write("//]]>");

writer2.Write(

"</script>");

Page.ClientScript.RegisterClientScriptBlock(

this.GetType(),"__Map", sb.ToString());

}

}


Use ScriptManager.RegisterClientScript block not Page.ClientScript.registerClientScriptBlock
Sorry, my mistake. It works fine now... many thanks!

J.

Ajax and JavaScript Arrays

Does anyone know why a new Array Contains data when just created when a script manager is running on the page... I do the following code:

<script language="javascript">
var myArray = new Array();
for (x in myArray)
{
document.write(myArray[x])
}
</script>

And get the output: function (index) { this.splice(index, 1); }

WHY!?!?!??!!?

Hi,

this happens because Array is extended through the prototype object, i.e.

Array.prototype.splice = ...

The solution is to extend Array using "type" methods:

Array.splice = ...

I believe this will be fixed in the next release.


hello.

As always, Garbin is correct. btw, i'd just like to add that, in my opinion, the for each usage in arrays which expects to get only the elements is just a side effect of the way foreach works (in other words, i think that even though everyone uses that for getting the elements of an array, it's not what it was meant for)


Actually you are absolutely right. I have solved the problem and what i did was just remove the:

for (x in Array)

and replace it with:

for (x = 0; x < Array.length; x++)

this seemed to fix it right up. It wasn't the fact that the array actually had those values in it. It's just somehow they array accessed those things when used in the for each statement... As gabin said it has to do with prototyping, which i was not familiar with. Thanks for the help guys, and the explanation.


hello again.

btw, i do believe that if you go the other way around, you'll have amore performant solution (ie, instead of goin from 0 to length, do it the other way around - if you can, of course).


I can't. It seems to always be populated with that data otherwise... I don't see why it would cause better performance. My array lengths are exact and not allocated longer then there last bit of information.

hello.

well, it all dependes on the number of items. check this and let me know:

http://www.devpro.it/examples/loopsbench/

Wednesday, March 21, 2012

AJAX and Code Behind

i would like to do some code behind work along with javascript on my page. I have a modalPopup taht when the user clicks submit i want it to call the javascript function to alert the user and also call a function in my codebehind to insert so values into a database. when i added an OnClick to my button it never fires. Why?

You can handleBeginRequest to execute some JavaScript code as the partial postback initializes.


Hi,

This should work if you do not cancel the form submit event.

Please share your code for better understanding.


<%@. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" MasterPageFile="iPort.master" %><%@. Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %><asp:Content ContentPlaceHolderID="ContentPlaceHolder1" runat="server" > <script type="text/javascript"> // JScript File var styleToSelect; function onOk() { alert('New portfolio created!'); } function Getnew() { var num = Math.ceil(Math.random()*10); var control = document.getElementById('Text7'); control.value = num; } </script> <br /> <br /> <p id="P1"> <table style="border-right: black thin solid; border-top: black thin solid; border-left: black thin solid; border-bottom: black thin solid" cellpadding="0" cellspacing="0"> <tr> <td colspan="5"> <asp:Button ID="New_iPort" runat="server" Text="New" Width="75px" OnClientClick="Getnew()" /></td> </tr> <tr> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> <strong> PortfolioID</strong></td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> <strong> PortInfo1</strong></td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> <strong> PortInfo2</strong></td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> <strong> PortInfo3</strong></td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> <strong> ActivePortfolio</strong></td> </tr> <tr> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> 1001</td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> Data</td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> Data</td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> Data</td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> 1</td> </tr> <tr> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> 1002</td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> Data</td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> Data</td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> Data</td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> 0</td> </tr> <tr> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> 1003</td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> Data</td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> Data</td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> Data</td> <td style="width: 100px; border-right: black 1px solid; border-top: black 1px solid; border-left: black 1px solid; border-bottom: black 1px solid;"> 1</td> </tr> </table> </p> <p> <asp:Label ID="Label9" runat="server" Text="Label"></asp:Label> </p> <asp:Panel ID="Panel1" runat="server" Width="505px" CssClass="modalPopup" style="display:none;"> <div style="width: 100%; font-weight: bold; font-size: 14pt; text-align: center;">  New Portfolio <hr /> </div> <div style="width: 100%;"> <table cellpadding="0" cellspacing="1"> <tr> <td style="width: 100px"> <asp:Label ID="Label1" runat="server" Text="PortfolioID"></asp:Label></td> <td style="width: 100px"> <input id="Text7" disabled="disabled" type="text" /></td> <td style="width: 100px"> </td> </tr> <tr> <td style="width: 100px"> <asp:Label ID="Label2" runat="server" Text="PortData1"></asp:Label></td> <td style="width: 100px"> <input id="Text8" type="text" /></td> <td style="width: 100px"> </td> </tr> <tr> <td style="width: 100px"> <asp:Label ID="Label7" runat="server" Text="PortData2"></asp:Label></td> <td style="width: 100px"> <input id="Text9" type="text" /></td> <td style="width: 100px"> </td> </tr> <tr> <td style="width: 100px"> <asp:Label ID="Label3" runat="server" Text="PortData3"></asp:Label></td> <td style="width: 100px"> <input id="Text10" type="text" /></td> <td style="width: 100px"> </td> </tr> <tr> <td style="width: 100px"> <asp:Label ID="Label4" runat="server" Text="PortData4"></asp:Label></td> <td style="width: 100px"> <input id="Text11" type="text" /></td> <td style="width: 100px"> </td> </tr> <tr> <td style="width: 100px; height: 19px"> <asp:Label ID="Label6" runat="server" Text="PortData5"></asp:Label></td> <td style="width: 100px; height: 19px"> <input id="Text12" type="text" /></td> <td style="width: 100px; height: 19px"> </td> </tr> <tr> <td style="width: 100px; height: 19px"> <asp:Label ID="Label5" runat="server" Text="PortData6"></asp:Label></td> <td style="width: 100px; height: 19px"> <input id="Text13" type="text" /></td> <td style="width: 100px; height: 19px"> </td> </tr> <tr> <td style="width: 100px; height: 20px;"> <asp:Label ID="Label8" runat="server" Text="Active"></asp:Label></td> <td style="width: 100px; height: 20px;"> <input id="Checkbox2" type="checkbox" /></td> <td style="width: 100px; height: 20px;"> </td> </tr> </table> </div> <div style="width: 100%; text-align: center;"> <asp:Button ID="Button1" runat="server" Text="Submit" OnClick="Button1_Click" />   <asp:Button ID="Button2" runat="server" Text="Cancel" OnClick="Button2_Click" /> </div> </asp:Panel> <br /> <ajaxToolkit:ModalPopupExtender id="ModalPopupExtender1" runat="server" TargetControlID="New_iPort" PopupControlID="Panel1" BackgroundCssClass="modalBackground" DropShadow="true" OkControlID="Button1" OnOkScript="onOk()" CancelControlID="Button2"> </ajaxToolkit:ModalPopupExtender> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> </asp:Content>

protected void Button1_Click(object sender, EventArgs e) { Label9.Text ="Submit button clicked!"; }protected void Button2_Click(object sender, EventArgs e) { Label9.Text ="Cancel Button clicked!"; }

Hi,

I am afraid it is normal,

ASP.NET render the two buttons as following:

<input type="submit" name="ctl00$SampleContent$OkButton" value="OK" id="ctl00_SampleContent_OkButton" />
<input type="submit" name="ctl00$SampleContent$CancelButton" value="Cancel" id="ctl00_SampleContent_CancelButton" />

Wether you add OnClick or not,it render the same, no postback is fired!

But you can fire the postback in the OkScript via javascript.That is the workaround.

Best Regards,


and how would one go about doing that?


hello.

for instance, you can call the __doPostBack method from your js code and set the target to the client id of your button.

ajax and clientsidescript

Hello, just a question, we have a page that is ajax enabled, when the user clicks on the button a email is sent to him and then a javascript message popups saying that the email was sent.

The problem is that when we are using ajax and it posts back, we dont get the messagebox. I have tried both:

ClientScript.RegisterStartupScript(mType,

"emailError","<script language=\"Javascript\" type=\"text/javascript\">alert('Email gesendet');</script>");

ClientScript.RegisterClientScriptBlock(mType,

"emailUncheck","<script language=\"Javascript\" type=\"text/javascript\">uncheckAll();</script>");

None of the above happens when the page was posted back using ajax update panel. How do you send javascript back to the client when you are using ajax?

Patrick

Hi,

to inject custom scripts when using ASP.NET AJAX, you should rely on the RegisterXXX methods exposed by the ScriptManager control.


perfect thanks