Archive

Archive for the ‘Ajax’ Category

Sys.WebForms.PageRequestManagerServerErrorException

Followed by:Object reference not set to an instance of an object.
I was struggling in an old Asp.Net site, which is using Microsoft Ajax Toolkit, with this error.

In order to reduce the postbacks i used some jquery for partial page updates, and using a simple html select with a button for change the parameter to a REST call, i got this error.
The problem solution is very simple.. the HTML button tag by default causes a postback, and the error was caused from a null value in the Page_Load event of the behind code: the button type must be “button”, otherwise without specifying the type is considered as “submit”.

Then the HTML is:

<button id="cmdUpdateByFilter" onclick="updateSint ();" type="button" class="Botton">Update</button>

Categories: .NET, Ajax, HTML5, VB.NET

maxJsonLength property

I was working on a asp:DataGrid table , where in every cell there is an asp:Textbox for immediate editing (think to a sort of Excel).
Then with an html button is called the javascript method save:

function save() {
    $get('ContentPlaceHolder1_UpdateProgress1').style.display = 'block';
    var strSql = "";
    var strPartSql = "";
    $("input.editqt").each(function () {
        var strHtmlId = this.id;
        var arrValues = strHtmlId.split("_");
        var strId = arrValues[1];
        var strValue = $("#" + strHtmlId).val();
        if (strValue.trim() === "")
            strValue = "0";
        strPartSql = "UPDATE TSG123_VoyageRes SET Qt = " + strValue + " WHERE ID_Voyage_Res = " + strId + "; ";
        strSql += strPartSql;
    });
    PageMethods.SaveMatrix(strSql, saveCallback, saveErrorCallback, "save");
}

function saveCallback(result, response, context) {
    $get('ContentPlaceHolder1_UpdateProgress1').style.display = 'none';
    window.alert("Save success.");
}

function saveErrorCallback(result, response, context) {
    $get('ContentPlaceHolder1_UpdateProgress1').style.display = 'none';
    if (result._timedOut)
        window.alert("Timeout saving");
    else {
        if (result !== null)
            window.alert(result.get_message());
        else
            window.alert("Error saving.");
    }
}

The javascript code calls an PageMethod (the web site uses ASP.NET 4, VB.NET , Microsoft Ajax Toolkit), defined as:

<System.Web.Script.Services.ScriptMethod(), System.Web.Services.WebMethod()> _
Public Shared Sub SaveMatrix(ByVal sql As String)
    UserFrameworkClass.AccessDB.Database.SetData(sql, Data.CommandType.Text)
End Sub

In practice from the javascript side is generated (not the best method..) a long SQL string, in the Page method is launched “as is” into SQL Server.
At a certain point the datagrid became bigger, and trying to save , crash: error from javascript:
“Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.”
The solution was to add these lines in web.config:

<system.web.extensions>
  <scripting>
    <webServices>
      <jsonSerialization maxJsonLength="2147483647"/>
    </webServices>
  </scripting>
</system.web.extensions>

No more errors, until these pages will be rewritten in a more solid manner.

Categories: .NET, Ajax, VB.NET, Vs2013

Autocomplete extender with Id and Description

It was a very long time ago that i worked with the Ajax Toolkit, but sometimes you are requested to implement old projects..

And the language is VB.NET, that i was not using since 2003.

The request was to implement an Autocomplete extender from a customers list (from a Sql Server table), but in the database is requested to write the autoincrement ID, not the description.

In order to implement the ajax toolkit, in the .aspx markup must be added the header:

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>

With the obvious adding of a reference , for the ASP.NET project, to AjaxControlToolkit.dll

A simple autoextender can be written as

<asp:TextBox ID="txtAgency" runat="server" ></asp:TextBox>
<cc1:AutoCompleteExtender ID="aceAgency" FirstRowSelected="false" MinimumPrefixLength="1" TargetControlID="txtAgency" ServiceMethod="GetListAgencies" runat="server">
</cc1:AutoCompleteExtender>

in the aspx page; in the code behind for this page we can implement a page method (the “ServiceMethod”) as

<System.Web.Script.Services.ScriptMethod(), _
System.Web.Services.WebMethod()> _
Public Shared Function GetListAgencies(ByVal prefixText As String, ByVal count As Integer) As List(Of String)
    Dim conn As SqlConnection = New SqlConnection
    '
    conn.ConnectionString = <string from web.config>
    Dim cmd As SqlCommand = New SqlCommand
    cmd.CommandText = "SELECT AnagId, AnagName FROM [dbo].[SomeTableOrView] WHERE AnagName LIKE @SearchText + '%'"
    cmd.Parameters.AddWithValue("@SearchText", prefixText)
    cmd.Connection = conn
    conn.Open()
    Dim lstAgencies As List(Of String) = New List(Of String)
    Dim sdr As SqlDataReader = cmd.ExecuteReader
    While sdr.Read
        lstAgencies.Add(sdr("AnagName").ToString))
    End While
    conn.Close()
    Return lstAgencies
End Function

This works, we type one letter (MinimumPrefixLength=”1″) on the keyboard and we are proposed with the list of names beginning with the typed letter.

But from the database in our sample we have only the AnagName value , the AnagId is not connected in some manner with the selected item: if we need to save that Id instead of the name this approach is not valid.

In order to save that id we need some javascript code and another approach in the web method.

First, this is the new aspx markup:

<asp:TextBox ID="txtAgency" runat="server"></asp:TextBox>
<cc1:AutoCompleteExtender ID="aceAgency" FirstRowSelected="false" TargetControlID="txtAgency" ServiceMethod="GetListAgencies" OnClientHidden="onClientHiddenAgency" MinimumPrefixLength="1"  EnableCaching="true" OnClientItemSelected="onClientItemSelectedAgency" OnClientPopulating="onClientPopulatingAgency" runat="server">
</cc1:AutoCompleteExtender>
<input type="hidden" id="hdnAgencyId" name="hdnAgencyId" runat="server" value="0" />

The OnClient… properties are the names of javascript functions; the EnableCaching is true because the underlying data are in this case very static.

Note that there is an hidden field where to save the requested Id and this is runat=server because we need to refer this field when we will save the record.

The javascript functions (ok, not the best javascript code…):

var boolChosenAgency = false;

function onClientItemSelectedAgency(source, e) {
    window.document.getElementById("<%=hdnAgencyId.ClientID%>").value = e.get_value();
    boolChosenAgency = true;
}

function onClientHiddenAgency(source, e) {
    if (!boolChosenAgency) {
        window.document.getElementById("<%=hdnAgencyId.ClientID%>").value = "0";
        window.document.getElementById("<%=txtAgency.ClientID%>").value = "";
    }
}

function onClientPopulatingAgency(source, e) {
    window.document.getElementById("<%=hdnAgencyId.ClientID%>").value = "0";
    boolChosenAgency = false;
}

What happens with this code is:

  • When the user begins to write, the Id value is changed to 0 and boolChosenAgency is set to false (“the user has not stille chosen an valid value”)
  • Only when an item is chosen the Id (coming from e.get_value()) is written in the hidden field
  • OnClientHiddenAgency is always executed, if the user has opened the list but has not clicked on a value then the id value is changed to 0

On the code behind so we must verify : if the hidden id is 0 and/or the textbox is empty the the id must be null on the db, otherwise we can write the int value.

The scope of the code is also: if the user write a not valid text, the Id is invalidated.

But how we can have the id in e.get_value() ?

This is done with this code for the web method:

<System.Web.Script.Services.ScriptMethod(), _
System.Web.Services.WebMethod()> _
Public Shared Function GetListAgencies(ByVal prefixText As String, ByVal count As Integer) As List(Of String)
    Dim conn As SqlConnection = New SqlConnection
    '
    conn.ConnectionString = <string from web.config>
    Dim cmd As SqlCommand = New SqlCommand
    cmd.CommandText = "SELECT AnagId, AnagName FROM [dbo].[SomeTableOrView] WHERE AnagName LIKE @SearchText + '%'"
    cmd.Parameters.AddWithValue("@SearchText", prefixText)
    cmd.Connection = conn
    conn.Open()
    Dim lstAgencies As List(Of String) = New List(Of String)
    Dim sdr As SqlDataReader = cmd.ExecuteReader
    While sdr.Read
        lstAgencies.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(sdr("AnagName").ToString, sdr("AnagID").ToString))
    End While
    conn.Close()
    Return lstAgencies
End Function

The trick is done using the CreateAutoCompleteItem method as in the above code.

In the javascript code we can use e.get_value for the ID and e.get_text() for the name (“AnagName” in the sample).

Categories: .NET, Ajax, Javascript, VB.NET, Vs2010

Asp:ButtonColumn not working in Ie11

I was working to an old VB.NET web application with Visual Studio 2010 , .NET 4.0; the solution for tables uses asp:DataGrid

Until Internet Explorer 10 all ok, with Ie11 the asp:ButtonColumn inside an asp:DataGrid was not working, clicking the link nothing.

It seems that the .NET 4 framework does not work well with Ie11 , and the update to .NET 4.5 was not an option (Windows Server 2003).

With the latest updates Ie11 was still recognized as Mozilla 0.0

The solution is to add an App_Browser folder

And then inside the folder create an .browser file with this content:

<browsers>
  <browser id="IE11" parentID="Mozilla">
    <identification>
      <userAgent match="Trident\/7.0; rv:(?'version'(?'major'\d+)(\.(?'minor'\d+)?)(?'letters'\w*))(?'extra'[^)]*)" />
      <userAgent nonMatch="IEMobile" />
    </identification>
    <capture>
      <userAgent match="Trident/(?'layoutVersion'\d+)" />
    </capture>
    <capabilities>
      <capability name="browser" value="IE" />
      <capability name="layoutEngine" value="Trident" />
      <capability name="layoutEngineVersion" value="${layoutVersion}" />
      <capability name="extra" value="${extra}" />
      <capability name="isColor" value="true" />
      <capability name="letters" value="${letters}" />
      <capability name="majorversion" value="${major}" />
      <capability name="minorversion" value="${minor}" />
      <capability name="screenBitDepth" value="8" />
      <capability name="type" value="IE${major}" />
      <capability name="version" value="${version}" />
    </capabilities>
  </browser>

  <!-- Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11,0) like Gecko -->
  <browser id="IE110" parentID="IE11">
    <identification>
      <capability name="majorversion" match="11" />
    </identification>

    <capabilities>
      <capability name="ecmascriptversion" value="3.0" />
      <capability name="jscriptversion" value="5.6" />
      <capability name="javascript" value="true" />
      <capability name="javascriptversion" value="1.5" />
      <capability name="msdomversion" value="${majorversion}.${minorversion}" />
      <capability name="w3cdomversion" value="1.0" />
      <capability name="ExchangeOmaSupported" value="true" />
      <capability name="activexcontrols" value="true" />
      <capability name="backgroundsounds" value="true" />
      <capability name="cookies" value="true" />
      <capability name="frames" value="true" />
      <capability name="javaapplets" value="true" />
      <capability name="supportsCallback" value="true" />
      <capability name="supportsFileUpload" value="true" />
      <capability name="supportsMultilineTextBoxDisplay" value="true" />
      <capability name="supportsMaintainScrollPositionOnPostback" value="true" />
      <capability name="supportsVCard" value="true" />
      <capability name="supportsXmlHttp" value="true" />
      <capability name="tables" value="true" />
      <capability name="supportsAccessKeyAttribute" value="true" />
      <capability name="tagwriter" value="System.Web.UI.HtmlTextWriter" />
      <capability name="vbscript" value="true" />
    </capabilities>
  </browser>
</browsers>
Categories: .NET, Ajax, Vs2010

Transform legacy js in Module Pattern

Tipically a lot of existing javascript code is written in the old plain mode:

function cmdAddNew_onClick() {
    showEditBox('0');
}

Every javascript programmers know that this spaghetti-code approach is hard to maintain, every function is public so it is easy to have strange behaviors that is a nightmare to debug.

The worst problems are in portals as the old Aqualogic, where was easy to have portlets with a different behavior is you inverted two portlets position in the page…

A better approach is to write our modules using a modern pattern as the Module pattern or the Singleton, there is lot a documentation about searching on Google, for examples this and this.

A skeleton of a correct Module Pattern implementation could be:

$(document).ready(function ($) {
    mycomsite.customername.projectname.context = (function ($) {
        "use strict";
        
        var cmdAddNew_onClick = function () {
            showEditBox('0');
        };      
        
        var showEditBox = function (id) {
            // js code for showing an Jquery dialog...
        }
        
        var numericSetvMax = function () {
            return '100';
        };        
        
        return {
            cmdAddNew_onClick: cmdAddNew_onClick,
            numericSetvMax: numericSetvMax            
        };
    }(jQuery));
});

The main trick is the namespace; note that we pass the jQuery variable to the module in order to use jQuery inside the module.

For example if we are a IT company with a internet site www.acme.com , we are working to a tickets solution for the scandinavian KLM company and the current is the js file for the ticketing by VISA ,a namespace could be

$(document).ready(function ($) {
    comacme.klm.ticketing.visatickets = (function ($) {
...

But we can’t have js variables with “.” in javascript, you say … the trick is a initial first module of our web app with lines as these :

if (!comacme) {
    var comacme= {};
}
comacme.klm= {};
comacme.klm.ticketing = {};

So we have defined a pseudonamespace.

Using the Microsoft Ajax Toolkit there is a better support for the namespacing , with the Toolkit we have an object named Type and we can use the method Type.registerNamespace :

<script type="text/javascript">
function pageLoad(sender, args) {
    Type.registerNamespace('comacme.klm.ticketing.visatickets');
    window.alert(Type.isNamespace(comacme.klm.ticketing)); //displays 'True'
    window.alert(Type.isNamespace(comacme.klm.ticketing.Samples.Test)); //displays 'False'
    var namespaces = Type.getRootNamespaces();
    for (var i = 0, length = namespaces.length; i < length; i++) {
        window.alert(namespaces[i].getName()); //displays 'Sys' and  other namespace components
    }
}
</script>

Ok , but we don’t use the Ajax Toolkit so let’s go back to our sample.

In the return section we indicate the public names, so cmdAddNew_onClick and numericSetvMax (functions, but also variables) are public , showEditBox is private and cannot be accessed.

That is in another javascript module we can write

comacme.klm.ticketing.visatickets.cmdAddNew_onClick();

and it works , instead

comacme.klm.ticketing.visatickets.showEditBox('0);

gives error, the internal routine is not reachable.

The variables declared correctly (with “var ” in front) remains private in the module.

This encapsulation , if well used, leads to a structure more maintainable.

Ok , but our original problem is that we could have a lot of existing js code written in the spaghetti-mode, how to convert this code to the module pattern with a minimal effort?

The Regular Expression in the Visual Studio 2012 search & replace is our tool.

We can convert an existing js file with a lot of function to the module pattern with these three couples of regexp expressions for search & replace:

^(function)
var

^(var)(.*)(\()
$1$2 = function $3

^(})(.*)
$1;$2

Open the js file (better is you separe the js code form the aspx pages…) in Visual Studio, in Search & Replace (ctrl+h) click on Regular Expression


And write the first two search%replace strings:


Note that Visual Studio 2012 gives an preview of what the search expression has found (and will be replaced):


After the three search & replace we can see something as:


The last operation is to copy the converted code in the namespace structure (below “use strict”, in practice) , inserting in the “return” part the routines names that must be public.

After, there is a tedious work of searching for the original calls (must be added the namespace part) : but this effort should resolve a lot a problems.

Categories: .NET, Ajax, Javascript, JQuery, Vs2012

Ajax on Aqualogic portals

I’m no more (for now…) working on Aqualogic Portals: i began years ago , when the original publisher was Plumtree, then the technology was buyed from BEA and Oracle subsequently acquired BEA; i don’t know of new releases.

I wrote many “portlets” (originally termed “gadgets”) so i have fighted with the well knowed (from Aqualogic developers) javascript problem : that is your javascript routines in the Aqualogic environment (in the portlet code, in practice) are “gatewayed”.

The “gatewaying” was a strange feature: you wrote your javascript functions and behind the curtains the functions names at runtime were changed adding a special marker $$PORTLET_ID$$ if not present in the function name: an internal identifier for the current portlet.

Another trick to know: if you was using the same id for an html object in more than one portlet it was necessary to add the special marker so the portlet javascript code can refer the correct object , for example

<span id="spaWorkingImage$$PORTLET_ID$$" style="display: none">

At runtime examining the page source the marker was substituted with numbers; this caused a wide array of problems, first of all there was no thirdy party Ajax library (Microsoft Ajax toolkit for example) usable : the first call was working , the subsequent calls no because the gatewaying was changing under the covers the routines names.

Obviously was promised to a customer the use of “not page refreshing” features… so i struggled in order to find a solution.

I went to a minimal but working solution , that could be still useful to someone.

My approach was to write minimal ajax routines using the $$PORTLET_ID$$ , and this is the latest code written from me five years ago:

<script type="text/javascript" language="javascript"> 
var objAquaXHttp; 
 
function getXmlHttpObject$$PORTLET_ID$$(){ 
    try{
        objAquaXHttp = null;
        if (typeof XMLHttpRequest != "undefined"){
            objAquaXHttp = new XMLHttpRequest();
            return objAquaXHttp;  
        }
        else if (window.ActiveXObject){              
            var aVersions = ["MSXML2.XMLHttp.5.0","MSXML2.XMLHttp.4.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp","Microsoft.XMLHttp"];
            for (var i = 0; i < aVersions.length; i++) {
                try {
                    objAquaXHttp = new ActiveXObject(aVersions[i]);
                    return objAquaXHttp;
                } catch (ex2) {
                    //Do nothing
                }
            }
            throw new Error("MSXML not installed.");        
        }                      
    }
    catch(ex){
        var strErr = "\nError getXmlHttpObject$$PORTLET_ID$$ num.: " + (ex.number & 0xFFFF);
        strErr += "\nDescription: " + ex.description;
        window.alert(ex + strErr);
    }                                                   
} 
 
function stdAjaxCall$$PORTLET_ID$$(urlWithQueryString, callbackFunction){ 
    try{
        objAquaXHttp = getXmlHttpObject$$PORTLET_ID$$();
        if (objAquaXHttp == null){
            window.alert ("Browser does not support HTTP Request.");
            return;
        } 
        objAquaXHttp.onreadystatechange = callbackFunction;
        objAquaXHttp.open("GET", urlWithQueryString, true);
        objAquaXHttp.send(null);                   
    }
    catch(ex){
        var strErr = "\nError stdAjaxCall$$PORTLET_ID$$ num.: " + (ex.number & 0xFFFF);
        strErr += "\nDescription: " + ex.description;
        window.alert(ex + strErr);
    }                                                   
}         
 
function stdAjaxCallPOST$$PORTLET_ID$$(urlWithoutQueryString, xmlString ,callbackFunction){ 
    try{
        objAquaXHttp = getXmlHttpObject$$PORTLET_ID$$();
        if (objAquaXHttp == null){
            window.alert ("Browser does not support HTTP Request.");
            return;
        } 
        objAquaXHttp.onreadystatechange = callbackFunction;
        objAquaXHttp.open("POST", urlWithoutQueryString, true);
        objAquaXHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") ;
        objAquaXHttp.setRequestHeader("Content-length", xmlString.length) ;
        objAquaXHttp.setRequestHeader("Connection", "close") ;
        objAquaXHttp.send(xmlString);                   
    }
    catch(ex){
        var strErr = "\nError stdAjaxCallPOST$$PORTLET_ID$$ num.: " + (ex.number & 0xFFFF);
        strErr += "\nDescription: " + ex.description;
        window.alert(ex + strErr);
    }                                                   
}             
 
function getXMLFromResponse$$PORTLET_ID$$(objHttp){
    var y;
    var x = objHttp.responseXML.childNodes;
    for (i = 0 ;i < x.length; i++){ 
        if (x[i].nodeType == 1){ 
            y = x[i].childNodes;
            for (j = 0; j < y.length; j++){ 
                if (y[j].nodeType == 1){ 
                    if (y[j].childNodes[0] != null)
                        return y[j].childNodes[0].nodeValue;
                    else
                        return '';
                } 
            }
        }
    }       
}        
</script>

Is very plain Javascript because i tried to use the module pattern, but there were strange problems.

This code define a public variable objAquaXHttp , and was calling aspx pages with an XML response type , used as pseudo web services.

In order to create a call we need the address, for example

var strUrl = CurrentAppPath$$PORTLET_ID$$ + "GetCitiesByProv.aspx" + "?q=" + encodeURIComponent(window.document.getElementById('listProvince').value);

In this case we obtain the path of the GetCitiesByProv.aspx and assigned to the variable CurrentAppPath$$PORTLET_ID$$, and then we create the complete url for a GET call.

But the real solution, the silver bullet, is the call (in the example from a onBlur event on a textbox):

stdAjaxCall$$PORTLET_ID$$(PTPortlet.getPortletByID($$PORTLET_ID$$).transformURL(strUrl), txtCityOnBlurCallback$$PORTLET_ID$$);

Note the transformURL: it does the magic of change the url as the Aqualogic portal does; and as in any async Ajax call we assign a callback (txtCityOnBlurCallback$$PORTLET_ID$$)

The pseudo web services is simple, the aspx is only a header:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="GetCitiesByProv.aspx.cs" Inherits="ShipperPickupAddressDetails.GetCitiesByProv" %>

And the code behind , in my sample (is ASP.NET 2.0… no Task, async, await…):

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text;
 
namespace ShipperPickupAddressDetails
{
    public class GetCitiesByProv : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Clear();
            Response.ContentType = "text/xml";
            Response.ContentEncoding = Encoding.UTF8;
            System.Xml.XmlTextWriter objX = new System.Xml.XmlTextWriter(Response.OutputStream, Encoding.UTF8);
            objX.WriteStartDocument();
            //
            objX.WriteStartElement("root");
            //   Request.Form.ToString() if POST call
            theDataLayer objData = new theDataLayer();
            string strProvince = Request.QueryString["q"].ToString();
            const string strChar39 = "'";
            const string strApo = "'";
            try
            {
                DataSet ds = objData.ReadCity(strProvince);  
                DataTable dt = new DataTable();
                DataColumn dc = new DataColumn("City");
                dt.Columns.Add(dc);
                DataRow dr = null;
                StringBuilder objString = new StringBuilder();
                // add cities of province in a datatable
                if (ds != null && ds.Tables[0].Rows.Count > 0)
                {
                    dr = dt.NewRow();
                    dr[0] = "Select...  ";
                    dt.Rows.Add(dr);
                    for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                    {
                        string city = ds.Tables[0].Rows[i]["City"].ToString();
                        if (!city.Equals(String.Empty))
                        {
                            dr = dt.NewRow();
                            dr[0] = city;
                            dt.Rows.Add(dr);
                        }
                    }
                }
                string strItem = String.Empty;
                objString.Append("<select id='listCitySugg'  style='width: 250px;' onchange='javascript:listCitySugg_onchangeAddressManager(this);'>");
                foreach (DataRow objRow in dt.Rows)
                {
                    strItem = objRow[0].ToString().Replace(strApo, strChar39);
                    objString.Append("<option value='" + strItem + "'>" + objRow[0].ToString());
                }
                objString.Append("</select>");
                objX.WriteElementString("data", objString.ToString());
                //
                objX.WriteEndElement();
                objX.WriteEndDocument();
                objX.Flush();
            }
            catch (Exception)
            {
                throw ;
            }
            finally()
            {
                if(objX  != null)
                   objX.Close();
                Response.End();     
            }
        }
    }
}


The code outputs an XML string, which is managed from the callback:

function txtCityOnBlurCallback$$PORTLET_ID$$(){ 
    try{  
        if (objAquaXHttp.readyState == 4 || objAquaXHttp.readyState == "complete"){ 
            if (objAquaXHttp.status == 200) {
                var strResult = getXMLFromResponse$$PORTLET_ID$$(objAquaXHttp);             
                window.document.getElementById('spaListCitySugg').innerHTML = strResult ;
            }else{
                window.alert('Error in txtCityOnBlurCallback, status = ' +  objAquaXHttp.status);
            }
        } 
    }
    catch(ex){
        var strErr = "\nError txtCityOnBlurCallback num.: " + (ex.number & 0xFFFF);
        strErr += "\nDescription: " + ex.description;
        window.alert(ex + strErr);
    }                   
}  

So we can dinamically inject html code into a div and generate on the fly without a postback cities items of a province into an html select, in our Aqualogic portlet.

Categories: .NET, Ajax, Aqualogic, Javascript