nxAjax is an easy to use ASP.NET jQuery AJAX library. Its features include:
- jQuery JavaScript core
- AJAX WebControl postback modes: Async or Sync
AjaxQueue
(by Pat Nakajima) used by Sync postbacks- Auto "loading message" in Sync postbacks (in MainPage div -> id="loading")
- Auto loading image in Async postbacks (each control:
LoadingImg
or LoadingImgId
attribute)
MainPage
with container loading ContainedPage
.- Multilanguage system
- Template based Web Render
- Low bandwidth usage: Only posts the current control value
- Only posts form content when
ISubmit
control is clicked
- DOCTYPE XHTML 1.1 W3C compliant
[Index]
To use nxAjax, add a reference to the "nxAjax.dll" assembly.
For a more convenient use of controls within the Toolbox, you can right click and select "Choose Items...". In the new form, browse the "nxAjax.dll" assembly and mark all its components.
Now, we will have our Toolbar as follows:
[Index]
Create a new Web Project in Visual Studio 2008, and add a reference to the nxAjax binary. Add this to the Web.Config file:
<system.web />
...
<pages />
<controls />
...
<add assembly="nxAjax"
namespace="Framework.Ajax.UI.Controls"
tagprefix="ajax" />
</controls />
</pages />
<httphandlers />
....
<add validate="false"
type="Framework.Ajax.HttpHandlers.ScriptResourceHandler, nxAjax"
path="AjaxScriptResource.axd" verb="GET,HEAD" />
<add validate="false"
type="Framework.Ajax.HttpHandlers.FileUploadHandler, nxAjax"
path="AjaxUploadFile.axd" verb="*" />
</httphandlers />
...
</system.web />
[Index]
Edit default.aspx like this:
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
<title>My nxAjax Test</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<ajax:Container ID="container"
runat="server"></ajax:Container>
</div>
</form>
</body>
</html>
Edit default.aspx.cs:
using System;
using System.Collections.Generic;
using Framework.Ajax.UI;
using Framework.Ajax.UI.Controls;
public partial class _Default : Framework.Ajax.UI.MainPage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
container.ContainedPage = "Contained1.aspx";
}
}
Create a new WebForm named "Contained1.aspx":
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Contained1.aspx.cs" Inherits="Contained1" %>
<form id="form1" runat="server">
<div>
<ajax:FileUpload ID="btnFile" runat="server"
UploadingMessage="Uploading..."
ExtensionNotAllowedMessage="Only image files!"
Text="Upload image"
LoadingImg="ajax-loader.gif"
OnServerComplete="btnFile_ServerComplete"></ajax:FileUpload>
<ajax:CheckBox ID="chkTest" Checked="true"
runat="server"></ajax:CheckBox>
<ajax:Submit ID="btnSubmit" Value="Send"
runat="server"
OnServerClick="btnSubmit_ServerClick"></ajax:Submit>
</div>
</form>
Edit Contained1.aspx.cs:
using System;
using System.Collections.Generic;
using Framework.Ajax.UI;
using Framework.Ajax.UI.Controls;
public partial class Contained1 : Framework.Ajax.UI.ContainedPage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
btnFile.AllowedExtensions.Add("jpg");
btnFile.AllowedExtensions.Add("gif");
btnFile.AllowedExtensions.Add("png");
btnFile.AllowedExtensions.Add("bmp");
btnSubmit.Disabled = true;
}
}
protected void btnSubmit_ServerClick(AjaxControl sender, string value)
{
System.Web.HttpPostedFile file = btnFile.File;
if (!chkTest.Checked)
return;
if (file == null)
DocumentAlert("not file uploaded");
else
{
DocumentAlert(file.FileName + " saved!");
}
}
protected void btnFile_ServerComplete(AjaxControl sender, string value)
{
DocumentAlert(value + " uploaded, you can " +
"click on 'send' button...");
btnSubmit.Disabled = false;
}
}
Launch and test it ;)
[Index]
In the Quick Example, add a new WebForm named Default2.aspx:
<system.web>
<%@ Page Language="C#" EnableEventValidation="False"
AutoEventWireup="true" CodeFile="Default2.aspx.cs"
Inherits="Default2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
<title>Don't use it, it does not works... :(</title>
</head>
<body>
<ajax:Form runat="server" ID="formu">
<div>
<ajax:Button ID="btnOne" Value="One"
runat="server"
OnServerClick="btnOne_ServerClick"></ajax:Button>
<ajax:Button ID="btnTwo" Value="Two"
runat="server"
OnServerClick="btnTwo_ServerClick"></ajax:Button>
<ajax:TextBox ID="txtOne" runat="server"
Value="One"></ajax:TextBox>
<ajax:Submit ID="submitOne" runat="server"
OnServerClick="submitOne_ServerClick"></ajax:Submit>
</div>
</ajax:Form>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnAsp" Text="Asp"
runat="server" OnClick="btnAsp_Click" />
<asp:TextBox ID="txtAsp" Text=""
AutoPostBack="True" runat="server"
OnTextChanged="btnAsp_Click" />
</div>
</form>
</body>
</html>
</system.web>
In order for this to work properly, you should modify the WebForm properties:
EnableViewState = true;
EnableEventValidation = false;
ViewStateEncryptionMode = System.Web.UI.ViewStateEncryptionMode.Never;
EnableViewStateMac = false;
And, add event code management in the code-behind. The final result should be something like:
using System;
using System.Collections.Generic;
using System.Linq;
using Framework.Ajax.UI;
using Framework.Ajax.UI.Controls;
public partial class Default2 : System.Web.UI.Page
{
public Default2() : base()
{
this.EnableViewState = true;
this.EnableEventValidation = false;
this.ViewStateEncryptionMode =
System.Web.UI.ViewStateEncryptionMode.Never;
this.EnableViewStateMac = false;
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
}
}
protected void btnOne_ServerClick(AjaxControl sender, string value)
{
btnOne.AjaxController.DocumentAlert("Hi!! " + value);
txtOne.Value = "Three";
}
protected void submitOne_ServerClick(AjaxControl sender, string value)
{
txtOne.Value = "One";
}
protected void btnTwo_ServerClick(AjaxControl sender, string value)
{
btnOne.AjaxController.DocumentAlert("Hi!! " + value);
txtOne.Value = "Two";
}
protected void btnAsp_Click(object sender, EventArgs e)
{
txtOne.AjaxController.DocumentAlert("Hi! " + btnAsp.Text);
txtOne.Value = "Three";
}
}
[Index]
The client events store JavaScript that will be evaluated when they will be raised, always on the client side. The server events are handled by ASP.NET running on the web server and returns the amendments.
The Container
control is a special control for management and operation. Its function is to be a container of ContainedPage
s. These are nxAjax web pages (like MainPage
) displayed as a piece of code and a type of entity in a single form.
In this way, we can navigate between different web pages without having to return to reload all AJAX libraries, or re-create the Web format main container. It can resemble a UserControl, but which is loaded dynamically without being instantiated within the main container.
[Index]
For now, MainPage
is the requirement for the nxAjax library to work as it does. MainPage
inherits from AjaxPage
(which inherits from the .NET framework System.Web.UI.Page
). And it overwrites much of its functionality. It clears all JavaScript from the Microsoft code, transforms the format of the form, adds the JavaScript library (jQuery, internals, ...) and processes requests in a way that the library can understand.
The viewstate is stored in session variables so it is no longer on the served page. MainPage removes doPostBack
functions and the __VIEWSTATE
hidden input. And, it also provides a new template and multilanguage systems.
[Index]
A ContainedPage
is only loaded into a container control (Framework.Ajax.UI.Controls.Container
). And again in the MainPage
. It inherits from AjaxPage
(which inherits from the .NET framework System.Web.UI.Page
). But unlike its older sister MainPage
, it does not load any scripts. So it is dependent. ContainedPage
is the tool we use to dynamically load content from AJAX on our website.
AjaxUserControl
works like System.Web.UI.UserControl
. But if you want to dynamically load content, it is better to use ContainedPage
.
[Index]
The AjaxControl
server control is the base of the entire nxAjax library. Every control inherits from this.
To render AjaxControl
, we use two methods: RenderHTML
and RenderJS
. The first writes the HTML code that we see on the Web. And, the second renders the JavaScript used for initialization and status changes.
To avoid overload, the HTML rendering uses an internal cache for each instance of the control. And it is written only once, when the page is loaded the first time.
Then, rendering JavaScript comes into play. It is launched the first time and then on each postback which changes its status.
To force a status change or otherwise, use the functions AjaxUpdate
and AjaxNotUpdate
.
Every AjaxControl
postback has two methods, synchronous and asynchronous. The default is Sync.
In the synchronous call context uses an AJAX queue. It adds requests to be loaded sequentially. If you want to show a loading screen during the server processing, add in MainPage
a div
object with id="loading"
.
Asynchronous calls are made for each of the controls at the time of requesting. The PostBackMode
property specifies it. And, if you want to add a loading image while processing the request, you can set these properties: LoadingImg
(image source) or LoadingImgID
(image control ID).
AjaxControl
postback only posts the current control value. If you want to post all the form content, you should use the ISubmit
control (like Submit
or LinkSubmit
).
Finally, the AjaxPage
property gets the container page: ContainedPage
or MainPage
.
[Index]
Using the nxAjax Template System involves converting all the HTML code to XML files. So, in order to meet the standards, we have chosen the option to be W3C compliant in the XHTML 1.1 context.
[Index]
Open the Quick Example project. Create a new file named "english.language". You can add all the application strings here:
#
# This is a coment, you can write what you want here...
#
#
# English Language File
#
# Information section:
[INFO]
name=English
id=ENG
#
#Dictionary section:
[DICTIONARY]
# Format:
# [MyKey]=[Literal]
Test.ErrorMessage01=not file uploaded
Test.SavedMessage=%s saved!
Test.UploadedMessage=%s uploaded, you can click on 'send' button...
Now, go to Menu -> Website -> Add New File, and select "Global Application Class". Open the Global.asax file and add this:
...
void Application_Start(object sender, EventArgs e)
{
Application["Language"] =
new Framework.Ajax.Language(Server.MapPath("english.language"));
}
...
Or this:
...
void Session_Start(object sender, EventArgs e)
{
Session["Language"] = new Framework.Ajax.Language(
Server.MapPath("english.language"));
}
...
Edit Contained1.aspx.cs:
public partial class Contained1 : Framework.Ajax.UI.ContainedPage
{
...
protected void btnSubmit_ServerClick(AjaxControl sender, string value)
{
System.Web.HttpPostedFile file = btnFile.File;
if (!chkTest.Checked)
return;
if (file == null)
DocumentAlert(lang["Test.ErrorMessage01"]);
else
{
DocumentAlert(lang["Test.SavedMessage"].Replace(
"%s", file.FileName));
}
}
protected void btnFile_ServerComplete(AjaxControl sender, string value)
{
DocumentAlert(lang["Test.UploadedMessage"].Replace("%s", value));
btnSubmit.Disabled = false;
}
}
[Index]
With the Quick Example project, we are going to use nxAjax templates. Open default.aspx and delete all HTML tags:
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<form id="form1" runat="server"></form>
<ajax:Container ID="container"
runat="server"></ajax:Container>
ASP.NET needs a form
with the attribute runat="server"
in order for this to work... Create a new "main.template" empty text file:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
<title>My nxAjax Test</title>
</head>
<body>
<div>
<ajax:Container ID="container" runat="server"></ajax:Container>
</div>
</body>
</html>
Replace the AJAX control ASPX code with a tag like "<$ControlID$>
". And, you must add two special tags in the MainPage
: <$PreScript$>
and <$PostScript$>
. The first in the header section, and the second at the end of the document body:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
<title>My nxAjax Test</title>
<$PreScript$>
</head>
<body>
<div>
<$container$>
</div>
<$PostScript$>
</body>
</html>
Edit default.aspx.cs:
public partial class _Default : Framework.Ajax.UI.MainPage
{
protected void Page_Load(object sender, EventArgs e)
{
this.TemplateFile = "main.template";
if (!IsPostBack)
container.ContainedPage = "Contained1.aspx";
}
}
Inside the MainPage
template, you can use two optional special tags: <$InitForm$>
and <$EndForm$>
, in order to submit the main form.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
<title>My nxAjax Test</title>
<$PreScript$>
</head>
<body>
<$InitForm$>
<div>
<$container$>
</div>
<$EndForm$>
<$PostScript$>
</body>
</html>
[Index]
Open "Contained1.aspx" and delete all HTML tags (except the server form):
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Contained1.aspx.cs" Inherits="Contained1" %>
<form id="form1" runat="server"></form>
<ajax:FileUpload ID="btnFile" runat="server"
UploadingMessage="Uploading..."
ExtensionNotAllowedMessage="Only image files!"
Text="Upload image"
LoadingImg="ajax-loader.gif"
OnServerComplete="btnFile_ServerComplete"></ajax:FileUpload>
<ajax:CheckBox ID="chkTest" Checked="true" runat="server"></ajax:CheckBox>
<ajax:Submit ID="btnSubmit" Value="Send" runat="server"
OnServerClick="btnSubmit_ServerClick"></ajax:Submit>
Create a new "container1.template" empty text file, with <$ControlID$>
tags where you want to show each control:
<div>
<$btnFile$>
<$chkTest$>
<$btnSubmit$>
</div>
You can optionally add a <$PostBack$>
tag if you want to put the postback controls in a specified position in the document.
Add this line to Contained1.aspx.cs:
...
public partial class Contained1 : Framework.Ajax.UI.ContainedPage
{
protected void Page_Load(object sender, EventArgs e)
{
this.TemplateFile = "container1.template";
if (!IsPostBack)
{
...
Inside the ContainedPage
template, you do not need to declare an HTML form. This is because of ContainedPage
is a form, and the render will write the begin and end form tags.
[Index]
Template with XML Source
You have the option to create your own XML ASP structures. This is not compatible with the previous method. Open "container1.template" file and modify it to something like:
<div>
<$File$>
<$Submit$>
</div>
To fill this template, we need to modify "Contained1.aspx":
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Contained1.aspx.cs" Inherits="Contained1" %>
<form id="form1" runat="server"></form>
<file>
<ajax:FileUpload ID="btnFile" runat="server"
UploadingMessage="Uploading..."
ExtensionNotAllowedMessage="Only image files!"
Text="Upload image"
LoadingImg="ajax-loader.gif"
OnServerComplete="btnFile_ServerComplete"></ajax:FileUpload>
</file>
<submit>
<ajax:CheckBox ID="chkTest" Checked="true"
runat="server"></ajax:CheckBox>
<ajax:Submit ID="btnSubmit" Value="Send"
runat="server"
OnServerClick="btnSubmit_ServerClick"></ajax:Submit>
</submit>
Note you can nest two or more AJAX controls inside an XML element. If you run the project, the result will look like in the previous example. When the template system processes an ASPX document, it checks the document, beginning with a ".
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Contained1.aspx.cs" Inherits="Contained1" %>
="1.0"="utf-8"
<page>
<form id="form1" runat="server"></form>
<file>
<ajax:FileUpload ID="btnFile" runat="server"
UploadingMessage="Uploading..."
ExtensionNotAllowedMessage="Only image files!"
Text="Upload image"
LoadingImg="ajax-loader.gif"
OnServerComplete="btnFile_ServerComplete"></ajax:FileUpload>
</file>
<submit>
<ajax:CheckBox ID="chkTest" Checked="true"
runat="server"></ajax:CheckBox>
<ajax:Submit ID="btnSubmit" Value="Send"
runat="server"
OnServerClick="btnSubmit_ServerClick"></ajax:Submit>
</submit>
</page>
And it works too.
[Index]
Going into modeling templates, we found a series of special commands to create template parts. These template parts are named "areas". When defining an area, you must use two special tags: <!$Begin AreaName>
and <!$End AreaName>
.
<!$Begin divArea>
<div>
<$object$>
</div>
<!$End divArea>
<$divs$>
Or:
<!$Begin divArea>
<div>
<$file$>
<$submit$>
</div>
<!$End divArea>
<$divs$>
Inside the ASPX XML code, you must define an area tag with the attributes:
Id
: Area name.Place
: Template tag where the area will be rendered.Method
: Add
or Allocate
. Optional. By default, Add
.
Add
for more than one area in the same position.Allocate
for only one area in this position.
To fill this new template, we need to modify "Contained1.aspx":
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Contained1.aspx.cs" Inherits="Contained1" %>
<form id="form1" runat="server"></form>
<area id="divArea" place="divs" method="allocate">
<object>
<ajax:FileUpload ID="btnFile" runat="server"
UploadingMessage="Uploading..."
ExtensionNotAllowedMessage="Only image files!"
Text="Upload image"
LoadingImg="ajax-loader.gif"
OnServerComplete="btnFile_ServerComplete"></ajax:FileUpload>
<ajax:CheckBox ID="chkTest" Checked="true"
runat="server"></ajax:CheckBox>
<ajax:Submit ID="btnSubmit" Value="Send"
runat="server"
OnServerClick="btnSubmit_ServerClick"></ajax:Submit>
</object>
</area>
And also:
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Contained1.aspx.cs" Inherits="Contained1" %>
<form id="form1" runat="server"></form>
<area id="divArea" place="divs">
<file>
<ajax:FileUpload ID="btnFile" runat="server"
UploadingMessage="Uploading..."
ExtensionNotAllowedMessage="Only image files!"
Text="Upload image"
LoadingImg="ajax-loader.gif"
OnServerComplete="btnFile_ServerComplete"></ajax:FileUpload>
</file>
<submit>
<ajax:CheckBox ID="chkTest" Checked="true"
runat="server"></ajax:CheckBox>
<ajax:Submit ID="btnSubmit" Value="Send"
runat="server"
OnServerClick="btnSubmit_ServerClick"></ajax:Submit>
</submit>
</area>
And, if we want to create two div blocks instead of one (with the first example):
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Contained1.aspx.cs" Inherits="Contained1" %>
<form id="form1" runat="server"></form>
<area id="divArea" place="divs">
<object>
<ajax:FileUpload ID="btnFile" runat="server"
UploadingMessage="Uploading..."
ExtensionNotAllowedMessage="Only image files!"
Text="Upload image"
LoadingImg="ajax-loader.gif"
OnServerComplete="btnFile_ServerComplete"></ajax:FileUpload>
</object>
</area>
<area id="divArea" place="divs">
<object>
<ajax:CheckBox ID="chkTest" Checked="true"
runat="server"></ajax:CheckBox>
<ajax:Submit ID="btnSubmit" Value="Send"
runat="server"
OnServerClick="btnSubmit_ServerClick"></ajax:Submit>
</object>
</area>
[Index]
Another special command is "<!$Include TemplatePartFileName>
". It will be replaced by the template file referenced. The template file name is the relative path from the current document to the document we want to include.
Create a new empty text file named "divpart.template":
<!$Begin divArea>
<div>
<$object$>
</div>
<!$End divArea>
And, modify the "container1.template" file:
<!$Include divpart.template>
<$divs$>
And it works like the others.
[Index]
The template based render system can auto-replace strings using the language file. You have to write another special tag with the language key: <&LanguageKey&>
If you have to create a language file, you can try to add the page title to "english.language":
...
[DICTIONARY]
...
Title=My nxAjax Test
And replace in the "main.template" file, the page title by the language tag:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
--- <title><&Title&></title>
<$PreScript$>
</head>
<body>
<div>
<$container$>
</div>
<$PostScript$>
</body>
</html>
[Index]
The nxAjax GridView
control contains the attribute ContentTemplateFileName
. It allows to set a template file name, and the grid will render based on this template file.
<ajax:GridView ID="gridImages" runat="server"
ContentTemplateFileName="grid.template">
<ajax:GridImageColumn DataColumn="img" />
<ajax:GridLabelColumn DataColumn="name" />
</ajax:GridView>
The template file has to have three areas: "header
", "content
", "footer
".
header
: The first (no repeat) code you want to render.content
: Repetitive code; for each row, it will render a content area by replacing each <$Column{N}$>
.footer
: The last (no repeat) code you want to render.
<!$Begin header>
<div class="imageListDiv">
<!$End header>
<!$Begin content>
<div class="imageDiv">
<$Column{0}$><br />
<span><$Column{1}$></span>
</div>
<!$End content>
<!$Begin footer>
</div>
<!$End footer>
[Index]
You can read more about this here: nxAjax CodePlex page.