Server Events and Client Scripts

Breaking Changes

Since v2018, the naming conventions used in server side code (C#) has been changed to be more consistent with .NET Core. ASP.NET Maker will try to convert the code when opening a project created by older versions. However, the conversion may not be 100% and you may need to convert your code yourself and use the conventions in your new code. In general, the breaking changes are (but not limited to):

  1. The "ew_" or "EW_" prefix has been removed, e.g. ew_ExecuteScalar() => ExecuteScalar().
  2. The constants or static properties has been moved to the Config static class and Pascal case has been used for the property names, e.g. EW_SMTP_SERVER => Config.SmtpServer.
  3. The "c" prefix for class names has been removed, e.g. cEmail => Email.
  4. The "c" prefix for table or page class names has been changed to "_", e.g. cCars => _Cars.
  5. OrderedDictionary has been changed to Dictionary<string, object>.
  6. Some method names has been changed to avoid using abbreviations, e.g. ew_SameStr() => SameString().

Please refer to the source code in template or generated scripts for exact changes.

You can implement your own business logic by writing your own server events and client scripts. Your code is stored in the project so you can migrate your project to other templates or future versions easily. This feature reduces the need of template customization and create maximum possibilities for you to customize and create more advanced features for your projects.

After loading the database, the database objects (tables, views, custom views and reports) will be shown in the left pane (the database pane). Click on any table to go to the Field Setup Page and then select the Code tab (which contains Server Events, Client Scripts and Custom Templates).

Note: For simplicity, we use "table" in the following description to refer to any of database object in the project. A database object can be either a table, a view, a custom view or a report.


The treeview shows the available server events and client scripts that you can add to your project:

Server Events Server-side ASP.NET Code

Global

The events are applicable to all pages

Table-Specific

The set of events are table-specific, the events are applicable to the selected table only

Other

The events are applicable to some common pages in the project only
Client Scripts Client-side JavaScript

Global

The JavaScript are included in all pages with header and footer

Table-Specific

The JavaScript are table-specific, they are included to pages for the selected table only

Other

The JavaScript are included in some common pages in the project only

To add your custom scripts to the server events or client scripts, select an item in the treeview, then enter your code in the editor.

The editor supports Find and Replace. Press Ctrl-F to open the Find dialog and press Ctrl-H to open the Replace dialog.

You can click the [Clear] button to discard the existing code and reset template code for the server event or client script.

 

Code Repository

Code Repository is provided for easy reuse of your code across projects and sharing with other users. Click the [Code Repository] button to open it, categorized reusable code will be displayed:

You can add the code to the editor by clicking the [Add to Editor] button, or by double-clicking the item, or simply drag the item to the editor. The reusable code is stored in XML files which reside in s subfolder name "code" under the installation folder. The format of the XML files is simple, there are 3 parts:

  1. description - description of the reusable code
  2. code - code to be inserted to editor

There are a few example files in the "code" folder, you can copy and modify for your own code and then save them under the "code" folder for reuse.

 

Server Events

In general, server events are fired in the following order:

  • ContentType_Mapping (Global)
  • Class_Init (Global)
  • Language_Load (Language class method)
  • Database_Connecting/Connected (Global)
  • User_CustomValidate (Security class method)
  • UserLevel_Loaded (Security class method)
  • User_Validated (Security class method)
  • TablePermission_Loading/Loaded (Security class method)
  • TablePermission_Loaded (Security class method)
  • UserID_Loading/Loaded (Security class method)
  • Page_Loading (Global)
  • Page_Load (Page class method)
  • Page_Rendering (Global)
  • Page_Render (Page class method)
  • Page_Head (Global)
  • MenuItem_Adding (Global)
  • Menu_Rendering/Rendered (Global)
  • Page_DataRendering (Page class method)
  • Recordset*/Grid*/Row* (Page class method)
  • Page_DataRendered (Page class method)
  • Page_Foot (Global)
  • Page_Terminate (Page class method)
  • Page_Unload (Page class method)
  • Page_Unloaded (Global)
  • Page_Redirecting (Page class method)
Notes
  1. Page class inherit from the table class, so you can access table class members also in page class methods .
  2. The Page_Unload and Page_Unloaded are server side events to be fired every time the page is accessed and before the HTML is outputted to the browser on the client side. They are NOT events to be fired before you leave the page and reload the page or go to another page. For example, if you submit a form in the page, usually it submits to the page itself, you are actually reloading the page, all server events will be fired again. For another example, if you click a hyperlink which links to another page, the page on the server side is not even accessed again and no server events for the page will be fired.
  3. If you want to refer to the current page object, you can use the variable CurrentPage.
  4. In the following table, the <fieldname> in code, e.g. in <fieldname>.<property> or x_<fieldname>, represents the field variable name. In general, if the field name is alphanumeric, field variable name is same as the field name. Otherwise, spaces are replaced by underscores, and other non alphanumeric characters are replaced by their hexadecimal string representation of their unicode value. If the variable is a reserved word or starts with a digit, it will be prepended with an underscore. If you are not sure, drag a field from the database pane to the editor instead of typing the field variable name. However, note that if the field name is quoted, e.g. as a key in rs["<fieldname>"], <fieldname> is the actual field name as in the database, not the field variable name.

Available server events are:

Global -> All Pages

Page_Head

The code you entered in this event will be placed in the header before closing the <head> section. You can use this event to can add your code in head section. Note: This is a global server event.

Example

ASP.NET Maker does NOT use jQuery UI, but you can include it yourself (using CDN):

AddStylesheet("https://code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css"); // Add CSS stylesheet
AddClientScript("https://code.jquery.com/ui/1.12.1/jquery-ui.js"); // Add JavaScript

Then you can use the widgets using Startup Script (see below).

Page_Foot

The code you entered in this event will be placed in the _Layout.cshtml after the <footer> section. You can use this event to can add your code for the website. Note: This is a global function.

Example 1

Add a Control Siderbar (light color)

<!-- The Right Sidebar -->
<aside class="control-sidebar control-sidebar-light">
<!-- Content of the sidebar goes here -->
</aside>
<!-- The sidebar's background -->
<!-- This div must placed right after the sidebar for it to work-->

<div class="control-sidebar-bg"></div>

Once you create the sidebar, you will need a toggle button to open/close it. By adding the attribute data-toggle="control-sidebar" to any button, it will automatically act as the toggle button.  

Example 2

Add a toggle button for the control sidebar by JsRender template:

<script type="text/html" class="ewJsTemplate" data-name="myControlSidebar" data-method="appendTo" data-target=".navbar-custom-menu .nav" data-seq="10">
<li><a href="#" data-toggle="control-sidebar"><i class="fa fa-gears"></i></a></li>
</script>

The generated script can apply JsRender templates automatically if the template is in the format of <script type="text/html" class="ewJsTemplate">...</script>. Using these templates you can change virtually everywhere of the whole layout. Note: The CSS class name "ewJsTemplate" is mandatory and is case-sensitive.

The following data-* attributes are supported:

data-name (Optional) Name of the template.
Note If more than one templates have the same name, only the first template will be used.
data-target

(Required) The target (CSS selector) of the template. To be used with data-method (see next).

Notes

  1. This must be a valid CSS selector, otherwise the target cannot be found and the template cannot be rendered.
  2. Press F12 in browser, inspect the HTML elements, check the id and class attributes to find the correct CSS selector of your target.
data-method

(Optional) The jQuery method name to apply the template. In general, the template will be rendered by:

$(<html>)[method](target);

The following jQuery methods are supported:

Name Method Description
appendTo .appendTo() Insert HTML to the end of the target
prependTo .prependTo() Insert HTML to the beginning of the target
insertAfter .insertAfter() Insert HTML after the target
insertBefore .insertBefore() Insert HTML before the target
replaceAll .replaceAll() Replace target with the HTML

If method is unspecified, the template will be rendered by:

$(target).html(<html>);

data-data

(Optional) Data to be passed to the template. It must be a property name of the ewVar object or the window object. If you want to pass data to the template, make sure you set the data first.

For example, menu data is set to ewVar.menu and then data-data="menu" is set for the menu template. You can override the default menu template by adding your own with same name (i.e. data-name="menu") in Page_Foot event. Similarly for the multi-language selector (data-name="languages") and the logged-in user dropdown panel (data-name="login").

data-seq (Optional) The sequence number of the template to be applied. If unspecified, it is 0. The larger the number, the later the template will be applied. If there are more than one templates for the same target, you may need to use this attribute to determine which template applies first.
Note An empty template can be found in Code Repository.

Database_Connecting

This event will be called by all pages before connecting to the database. Note: This is a method of database connection class.

The argument is the connection string. You can use this event to change the connection string (e.g. changing connection info with server, or even connect to other databases).

Example 1

public void Database_Connecting(ref string connstr) {
    // assume the scripts are generated with connection info for local PC
    if (!IsLocal())
// not connecting to local PC
        connstr = "MyConnectionString"; // connect to the production database        
}

Example 2

It is possible to use single login and common Dynamic User Levels for multiple projects provided that ALL projects use the same project name and same Advanced Security tables (i.e. User Table, User Level Table and User Level Permission Table). If all projects uses the same database and same Advanced Security tables, then the latter condition is auto fulfilled. However, if the projects use different databases, you can use this event to change the connection info so the user can get the Dynamic User Levels from the common Advanced Security tables correctly during login, e.g.

public void Database_Connecting(ref string connstr) {
    if (CurrentPageID() == "login" || CurrentPageID() == "userpriv") {
        // connect to the common database with the common Advanced Security tables
        connstr = "MyConnectionString";
    }
}

Example 3

It is possible to access the configuration settings in appsettings.json (or appsettings.Development.json during development) file, see Configuration in ASP.NET Core for details, e.g.

public void Database_Connecting(ref string connstr) {
    string str = Configuration["Databases:DB:connectionstring"]; // where "DB" is the default database variable name in your project, replace it if connecting to other database
    // your code to change the connection string
    connstr = str;
}

Database_Connected

This event will be fired by all ASP.NET pages after connecting to the database. Note: This is a method of database connection class.

The argument is the connection object, you can use it to execute your own statements.

Example

Execute a SQL after connection.

public void Database_Connected(DbConnection conn) {
    Execute("My SQL statement", conn);
}

Language_Load

This event will be fired when the language file is loaded. You can use it to change the language phrases if necessary. Note: This event is a language class member.

Example 1

public void Language_Load() {
    SetPhrase("MyID", "MyValue"); // Refer to language file for the actual phrase id
    SetPhraseClass("MyID", "glyphicon glyphicon-xxx ewIcon");
// Refer to https://getbootstrap.com/docs/3.3/components/#glyphicons for icon name
}

Example 2

Change the HTML markup of the language selector.

public void Language_Load() {
    Type = "DROPDOWN";
// Set the Type, supported types are: LI/DROPDOWN (for used with top Navbar) or SELECT/RADIO (NOT for used with top Navbar)
    
//Template = "<My JsRender template>"; // OR use custom JsRender template
}

Page_Loading

This event will be called by all pages at the beginning of the page. If the pages involves database connection, it will be called after connecting to the database and before the Page_Load event. Note: This is a global server event, NOT page class member.

Page_Rendering

This event will be called by all ASP.NET pages before outputting HTML for the page. Note: This is a global server event, NOT page class member.

Page_Unloaded

This event will be called by all pages at the end of the page. If the pages involves database connection, it will be called before closing database connection and after the Page_Unload event. Note: This is a global server event, NOT page class member.

Global Code

Code to be included in the main class. This may contain your own constants, static fields, properties and methods.

ContentType_Mapping

This event will be fired in static constructor of the main class for modifying file extension content type mappings. The FileExtensionContentTypeProvider class contains a default collection that maps file extensions to MIME content types. The collection may not contain file extensions you need, or you may want to remove or replace some mappings.

Example

public void ContentType_Mapping(IDictionary<string, string> mappings) {
    mappings.Add(".image", "image/png"); // Add new mappings
    mappings[".rtf"] = "application/x-msdownload"; // Replace an existing mapping
    mappings.Remove(".mp4"); // Remove MP4 videos
}

Class_Init

This event will be fired in static constructor of the main class for initializing static fields and properties.

Example

public void Class_Init() {
    Config.UploadAllowedFileExtensions += ",mp4"; // Allow uploading MP4 videos
}

Controller_Action

This event allow you to add your own controller actions in the controller. Read Routing to Controller Actions for details about routing.

Example

Add an action to return JSON result and add attribute routing.

[Route("myaction")]
[Route("Home/myaction")]
public IActionResult MyAction() {
    // your code to create the output object (e.g. named "myObject") to serialize
    return Json(myObject);
}

User_CustomValidate

For use with security. (See Security Settings) This event is fired before default user validation. You can use this event to validate the user yourself. The arguments are the user name and password the user entered. Return true if the username and password pass your custom validation. Note: This event is a security class member.

Notes

  1. If you use "Windows" or "LDAP" authentication (see Advanced Settings), returning true or false in this event does not matter. The user will be validated by Windows or LDAP later.
  2. If you use "LDAP" authentication (see Advanced Settings), you can use this event to modify the username and password, if necessary, for subsequent validation with LDAP server.
  3. Default validation will continue after this event is fired. If you return true, the user will always pass the default validation and get the User ID and User Level, if any. If you return false, the default validation proceeds as normal. If you use Advanced Security, you still need the user table to store user information such as User ID and User Level, although the password field value can be empty or any value if you return true.

Example

Login user by Windows Authentication. Note: You must first setup your site with IIS Manager to enable Windows Authentication and disable Anonymous Authentication.

// Note: This event is a Security class member, so you can refer to other members of the Security class directly
public bool User_CustomValidate(ref string usr, ref string pwd) {   
    if (IsAuthenticated() && !IsPost()) { // Authenticated Windows user and is not logging in by login page
        var userName = User.Identity.Name; // Note that the Windows user name is in the format of MachineName\UserName
        usr = userName.Split('\\')[1]; // Split and get the second part
        return true;
    }
    return false;   
}

Note The above example only validates if the user is authenticated as a Windows user only. The Windows user account does not have any information about Advanced Security (User ID and User Level Security). If the user tries to access a page protected by User Level Security, the user does not have permissions and will still be redirected to the login page. Although the user can enter any password to login, if the user name cannot be found in the user table, the user cannot get permissions from the database. Note that the user name and password in this event is passed by reference, so you can change the user name (and password), if required, so that the user can get permissions. For example, you can duplicate the Windows user names into the user table.

 

Ldap_Validated

For use with "LDAP" authentication (see Advanced Settings) only. This event is fired after User_CustomValidate (see above). When this event is fired, the user bind is already done successfully, but you can use this event to do further validation or to get some more information of the user from the LDAP server. Return true if the user your custom validation. Note: This event is a Ldap class member.

Example 1

Login user of the free online LDAP Server. Enter the following advanced settings:

LDAP host name: www.zflexldap.com

LDAP port number: 389

LDAP distinguished name: uid={username},ou=users,ou=guests,dc=zflexsoftware,dc=com

Then login as:

User name: guest3

Password: guest3password

Check whether the user belongs to the user group "deptGRP1" or "deptGRP2". If yes, allow the user to login.

public bool Ldap_Validated(string usr, string pwd) {
    string searchBase = String.Empty;
    string userDn = "";
    string filter = $"(uid={usr})"; // Filter for the user name
    var user = Search(searchBase, filter, null); // Search the user entity of the logged in user
    if (user.hasMore())
        userDn = user.next().DN; // User found
    else
        return false; // User not found
    filter = "(&(objectClass=groupOfNames)(|(cn=deptGRP1)(cn=deptGRP2)))"; // Filter for the groups "deptGRP1" and "deptGRP2"
    var search = Search(searchBase, filter, new string[] { "member" }); // Search for members
    while (search.hasMore()) {
        if (search.next().getAttribute("member").StringValueArray.Contains(userDn)) // Check if the user DN exists in the attributes
            return true;
    }
    return false; // Return true/false to validate the user
}

Example 2

Check if the Active Directory user exists in "group1" or "group2".

public bool Ldap_Validated(string usr, string pwd) {
    var groups = SearchForGroup("group1");
    groups.UnionWith(SearchForGroup("group2")); // Get the DN of groups
    var users = SearchForUser(groups, $"(sAMAccountName={usr})"); // Get the users of the group with the same user name
    return users.Any(); // Return true/false to validate the user
}

User_Validated

For use with security. (See Security Settings) This event is fired after successful user login. The user info is passed to the event as an array (see note), you can get more info of the user and use it as you need. Note: This event is a security class member.

Notes
  1. This event is not fired for the hard-coded administrator (who is not an user in the user table).
  2. The argument rs is DbDataReader, you can get a field value by rs["<fieldname>"].

Example 1

Add additional current user info to the global user profile object

// Note: This event is a Security class member, so you can refer to other members of the Security class directly
public bool User_Validated(DbDataReader rs) {
    Profile.SetValue("Notes", rs["Notes"]); // Set additional data to the profile object
    Profile.Save(); // Save to session
    return true;
}

Example 2

Add current user info to user Claims (requires Cookie Authentication)

// Note: This event is a Security class member, so you can refer to other members of the Security class directly
public bool User_Validated(DbDataReader rs) {
    Claims.Add(new Claim("Email", Convert.ToString(rs["Email"]))); // Assume the user table has a field named "Email"
}

Then you can retrieve user info in other server events, e.g.

var email = User.FindFirst("Email").Value;

Example 3

Check if an user password has expired by custom code with Enable password expiry (see Security Settings) enabled

public bool User_Validated(DbDataReader rs) {
    if (ConvertToBool(rs["PasswordExpired"])) { // Assume the user table has a field named "PasswordExpired" storing if the password has expired
        SetPasswordExpired(rs["Username"]); // Assume the user name field is named "Username"
        return false; // Return false to invalidate the user
    }
}

UserLevel_Loaded

For use with User Level security. (See Security Settings) This event is fired after successful user login and after the User Level settings are loaded. It is possible to do actions such as changing or adding User Level permissions. Note: This event is a security class member.

Example

Change the permissions of an User Level for a table

// Note: This event is a Security class member, so you can refer to other members of the Security class directly
public void UserLevel_Loaded() {
    DeleteUserPermission("Sales", "orders", Config.AllowAdd);
    AddUserPermission("Sales", "orders", Config.AllowEdit);
}

MenuItem_Adding

This event is fired for custom menu items before it is added to the menu. The menu item info is passed to the event as an instance of the MenuItem object (see below). Return false if you don't want to show the menu item. If you return true, the menu item will be added to the menu, but it does not mean that it will be always displayed. A menu item will be displayed only if its Allowed property is true. When the menu item is passed to this event, the Allowed property is set based on the User Level Security of the project, you can however change it by setting item.Allowed as true or false as needed. Note: This event is a menu class member.

Example 1

Only show a menu item after the user has logged in

public bool MenuItem_Adding(MenuItem item) {
    //VarDump(item); // View menu item properties for debug
    // Return false if menu item not allowed

    if (item.Text == "Download")
        return IsLoggedIn(); // Return true if the user has already logged in
    return item.Allowed; // Return the original permission
}

Example 2

Set the menu item properties

public bool MenuItem_Adding(MenuItem item) {
    //VarDump(item);
    if (item.Text == "Download")
        item.Icon = "glyphicon-download"; // Icon can be glyphicon-* or fa-*
    if (item.Text == "Something")
        item.Label = "<small class=\"label pull-right bg-green\">new</small>"; // Label shows on the right hand side of the menu item (for vertical menu only)
    return true;
}

Note If your project is multi-language, the item.Text will be different for each language, you may check item.Name or item.Url instead. Check the generated ewmenu.cshtml to see the item names or URLs.

Menu_Rendering

This event is fired before the menu is rendered. You can manipulate the menu items in this event. The argument is the menu object. (See Menu Object below.) Note: This event is a menu class member.

Example 1

Add an additional menu item to the menu for logged in users only.

public void Menu_Rendering(MenuBase menu) {
    if (menu.IsRoot) { // Root menu
        menu.AddMenuItem(10000, "MyName", "MyMenuText", "MyPage", -1, "", Allowed: IsLoggedIn());
        menu.MoveItem("Logout", Menu.Count - 1);
// Move to last
    }
}

Example 2

Remove all the default menu items and use your own menu items.

public void Menu_Rendering(MenuBase menu) {
    
if (menu.IsRoot) { // Root menu
        menu.Clear();
        menu.AddMenuItem(1, "MyName1", "MyMenuText1", "MyPage1");
        menu.AddMenuItem(2, "MyName2", "MyMenuText2", "MyPage2");

    }
}

Example 3

Change options of sidebar menu (vertical menu).

public void Menu_Rendering(MenuBase menu) {
    
if (menu.IsRoot) { // Root menu
        menu.Accordion = false; // Whether to collapse the open menu when expanding another, default is true
        menu.FollowLink = false;
// Whether to follow the link in the a element instead of expanding the sub menu, default is true
    }
}

Menu_Rendered

This event is fired after the menu is rendered. You may want to clean up in this event if you have created something in the Menu_Rendering event. The argument is the menu object. (See Menu Object below.)Note: This event is a menu class member.

TablePermission_Loading

For use with User Level security. (See Security Settings) This event is fired before the user permission for the table of the current page is loaded. It is possible to do actions such as changing or adding more User Level permissions to the current user. Note: This event is a security class member.

Note This is an event fired for the current table only. If you change the permissions of the other tables in this event, there will be no effect. Use the UserLevel_Loaded event if you need to change permissions of other tables.

Example

Grant another User Level to the user and let the user have permissions of more than one User Level for the current table.

// Note: This event is a Security class member, so you can refer to other members of the Security class directly
public void TablePermission_Loading() {
    if (CurrentUserName() == "nancy")
        AddUserLevel("Manager");
}

TablePermission_Loaded

For use with User Level security. (See Security Settings) This event is fired after the user permission for the table of the current page is loaded. It is possible to to change the permission by using the CanXXX properties of the Security class. Note: This event is a security class member.

Note This is an event fired for the current table only. If you change the permissions of the other tables in this event, there will be no effect. Use the UserLevel_Loaded event if you need to change permissions of other tables.

Example

Grant more permissions to the user and let the user have more permissions than his/her User Level allows for the current table.

// Note: This event is a Security class member, so you can refer to other members of the Security class directly
public void TablePermission_Loaded() {
    if (CurrentUserName() == "nancy" && CurrentTable.TableName == "Orders")
        CanEdit = true;
}

UserID_Loading

For use with User ID security. (See Security Settings) This event is fired after successful user login and before loading the User ID and its child User IDs of the current user. These User IDs determine which records the current user can access. It is possible to do actions such as changing the User ID of the current user so the user can access records that he/she can access by its original User ID. Note: This event is a security class member.

Example

Change the user's User ID to his parent user's user ID and let the user access more records (accessible by the parent user).

// Note: This event is a Security class member, so you can refer to other members of the Security class directly
public void UserID_Loading() {
    if (!Empty(CurrentParentUserID()))
        CurrentUserID = CurrentParentUserID();
}

UserID_Loaded

For use with User ID security. (See Security Settings) This event is fired after loading the User ID and its child User IDs of the current user. These User IDs determine which records the current user can access. It is possible to do actions such as adding or deleting the loaded User IDs for the current user so the user can access more or less records that he/she can access by its originally loaded User IDs. Note: This event is a security class member.

Example

Add more User IDs to the user and let the user access more records

// Note: This event is a Security class member, so you can refer to other members of the Security class directly
public void UserID_Loaded() {
    if (CurrentUserName() == "nancy")
        AddUserIDByUserName("janet");
}

User_PasswordExpired

This event will be called if the user password is already expired. User information is passed to the event as argument, you can get user information by rs["<fieldname>"] where <fieldname> is a field name of the user table. Note: This event is a security class member.

AuditTrail_Inserting

This event will be called before an audit trail record is written. The audit trail information is passed to the event as argument, you can get the information by rsnew["<fieldname>"] where <fieldname> is the audit trail field name. Return false to cancel the insert.

Routes_Add

This event will be called in Startup.cs for adding routes, call routes.MapRoute() to add more routes. See Routing in ASP.NET Core for details.

Example

routes.MapRoute(name: "MyName", template: "MyTemplate");

Table-Specific -> Common (Note: These events are members of the page class)

Recordset_Selecting

This event will be called before selecting records. The argument of the event is the filter (part of the WHERE clause of the SQL) for selecting records, you can customize the filter to change the records to be selected.

Example

Add your own filter. Note that the filter may have value, if you want to add some additional filter, append your filter to it, not replace it.

public void Recordset_Selecting(ref string filter) {
    AddFilter(ref filter, "Field1 = 1234"); // Add your own filter expression, assume Field1 is of integer type so no need to quote    
}

Recordset_SearchValidated

This event will be called after the Form_CustomValidate event and the search criteria is assigned to the table/field objects. You can modify the search criteria in this event.

This event is a member of the table class. There is no arguments for this event. To change the Quick Search criteria, change the BasicSearchKeyword and BasicSearchType property of the table object. To change the Advanced Search criteria, change the AdvancedSearch property (which is an object of the AdvancedSearch class) of the field object.

Example

public void Recordset_SearchValidated() {
    MyField1.AdvancedSearch.SearchValue = "your search criteria"; // Search value
}

Recordset_Searching

This event will be called before the search criteria is saved for the session. The argument of the event is the part of WHERE clause built from the Quick/Extended/Advanced search criteria. You can modify the WHERE clause in this event.

Example

Replace filter by regular expression.

public void Recordset_Searching(ref filter) {
    //VarDump(filter); // View the filter first   
    filter = Regex.Replace(filter, "MyPattern", "MyReplacement"); // Replace part of the filter with your modified filter 
}

Row_Deleting

This event will be called before deleting a record. The argument of the event is the record to be deleted as an array.

Row_Deleted

This event will be called after deleting a record. The argument of the event is the record deleted as an array.

Example

Delete detail records from the detail table after the master record is deleted.

public void Row_Deleted(Dictionary<string, object> rs) {
    //Log(rs); // Log the record to be deleted
    // Assume "ForeignKeyField" is of integer type so no single quotes required
    Execute("DELETE * FROM DetailTable WHERE ForeignKeyField=" + rs["PrimaryKeyField"]);
}

Alternatively, you can use the detail table object.

public void Row_Deleted(Dictionary<string, object> rs) {
    //Log(rs); // Log the record to be deleted
    var tbl = CreateTable("DetailTable"); // Assume the detail table name is "DetailTable" here
    // Assume "ForeignKeyField" is of integer type so no single quotes required
    tbl.Delete(null, "ForeignKeyField=" + rs["PrimaryKeyField"]);
}

Row_Inserting

This event will be called before inserting a record. The arguments of the event are the arrays of the old (if copying record) and new record to be inserted. You can change the values in the rsnew.

Example

Make sure a field value is valid.

public bool Row_Inserting(Dictionary<string, object> rsold, Dictionary<string, object> rsnew) {
    //Log(rsold, rsnew); // Log the old and new record
    if (ConvertToInt(rsnew["Percentage"]) > 100)
        rsnew["Percentage"] = 100;
    // To cancel, set return value to false
    return true;
}

Row_Inserted

This event will be called after inserting a record. The arguments of the event are the arrays of the old (if copying record) and new record just inserted.

Example 1

Get the ID (autoincrement field) of the just inserted record

public void Row_Inserted(Dictionary<string, object> rsold, Dictionary<string, object> rsnew) {
    SuccessMessage = "Record Inserted. The ID of the new record is " + Convert.ToString(rsnew["ID"]);    
}

Example 2

Insert the new record to another table (Note: Assume the field names are the same in both tables.)

public void Row_Inserted(Dictionary<string, object> rsold, Dictionary<string, object> rsnew) {
    //Log(rsold, rsnew); // Log the old and new record end the script
    //rsnew.Remove("FieldName"); // Remove some fields if necessary
    //rsnew.Add("FieldInAnotherTable", SomeValue); // Add some fields if necessary
    CreateTable("AnotherTableName").Insert(rsnew);
}

Row_Rendering

This event will be called before rendering (applying the View/Edit Tag settings) a record.

Row_Rendered

This event will be called after rendering a record.

This is an extremely useful event for conditional formatting, you can do a lot of things with this event, such as changing font color, font styles, row background color, cell background color, etc. by changing the table or field class properties in the event according to field values.

Note The table class has a RowAttrs property which is an associative array of HTML attributes for the table row. The field class has CellAttrs, ViewAttrs and EditAttrs for the table cell, View Tag and Edit Tag of the field respectively. The keys of these arrays must be valid HTML attributes for the HTML tag, always use lowercase for the keys. The attribute values will be outputted as double quoted attributes, so if you have double quotes in your values, try to use single quotes if possible, or use "&quot;".

To view the properties of the field class for development or debugging, you can use the VarDump function in the server event.

Example

Change CSS styles of row and cells:

public void Row_Rendered() {
    // VarDump(RowAttrs, Trademark);

    // Change the row color in List page
    if (SameString(Trademark.ViewValue, "BMW"))
        RowAttrs["class"] = "info";

    // Change the cell color
    if (PageID == "list" || PageID == "view") { // List/View page only
        if (SameInteger(Cyl.CurrentValue, 4)) {
            Cyl.CellAttrs["style"] = "background-color: #ffcccc";
        } else if (SameInteger(Cyl.CurrentValue, 6)) {
            Cyl.CellAttrs["style"] = "background-color: #ffcc99";
        } else if (SameInteger(Cyl.CurrentValue, 8)) {
            Cyl.CellAttrs["style"] = "background-color: #ffccff";
        }
    }

    // Change text style
    if (SameString(Category.CurrentValue, "SPORTS"))
        Category.ViewAttrs["class"] = "bg-warning text-warning";
}

Row_Selecting

This event will be called before selecting a record. The argument of the event is the filter (part of the WHERE clause of the SQL) for selecting the record, you can customize the filter to change the record to be selected.

Row_Selected

This event will be called after selecting a record. The argument is the record selected as an array.

Row_UpdateConflict

This event will be called if conflicts is found before updating a record (if Check Conflicts is enabled, see Table Setup). The arguments of the event are the old record (as array) and new record (as array) to be updated.

You can use this event to resolve the conflicts according to your own criteria. If you want to ignore conflicts or you have resolved the conflicts in the event (by setting new values to the argument rsnew) and want to continue update, return false. Otherwise, return true. By default the event returns true.

Row_Updating

This event will be called before updating a record. The arguments of the event are the arrays of the old and new record to be updated.

Example

Make sure a field value is not changed

public bool Row_Updating(Dictionary<string, object> rsold, Dictionary<string, object> rsnew) {
    //Log(rsold, rsnew); // Log the old and new record
    if (Convert.ToInt32(rsnew["Qty"]) < Convert.ToInt32(rsold["Qty"])) {
        // To cancel, set return value to False
        CancelMessage = "The new quantity must be larger than the old quantity.";
        return false;
    }         
    return true;
}

Row_Updated

This event will be called after updating a record. The arguments of the event are the arrays of the old and new record updated.

Example

After updating a field in detail table, update a field in the master table.

public void Row_Updated(Dictionary<string, object> rsold, Dictionary<string, object> rsnew) {
    //Log(rsold, rsnew); // Log the old and new record
    var d = new Dictionary<string, object>() { {"FieldInMasterTable", rsnew["FieldInDetailTable"]} }; // Set field values
    CreateTable("MasterTableName").Update(d, "PrimaryKeyFieldInMasterTable = " + Convert.ToString(rsold["ForeignKeyFieldInDetailTable"])); // Assume PrimaryKeyFieldInMasterTable is integer.
}

Grid_Inserting

For use with Grid-Add for a table and Master/Detail-Add for a detail table, this event will be called before inserting records. This event has no arguments.

You can use this event to check all records to be inserted. If you want to cancel insert, return false. Otherwise, return true. By default the event returns true.

Note If you only need to check individual record, there is no need to use this event, simply use Row_Inserting (see above) which will be called for each row in the grid.

Example

Check all records before inserting. Note that this event is called before Row_Inserting, the field values are not loaded yet, but you can load them yourself.

public bool Grid_Inserting() {
    var rsnew = GetGridFormValues(); // Get the form values of the new records as List<Dictionary<string, string>>
    //Log(rsnew); // Log the records
    int sum = rsnew.Aggregate(0, (sum, row) => sum += Convert.ToInt32(row["Percentage"])); // Loop through the new records and get the sum
    if (sum < 100) {
        // To cancel, set return value to false
        FailureMessage = "The total percentages must be 100.";
        return false;
    }
    return true;
}

Note Data returned from GetGridFormValues() is read only, do not try to change the values. To change the values, use Row_Inserting (see above) which will be called for each row in the grid.

Grid_Inserted

For use with Grid-Add for a table and Master/Detail-Add for a detail table, this event will be called after inserting all records. The argument of the event (rsnew) is array of records inserted (retrieved from database).

For example, you can use this event to update a field in the master table (similar to the example for Row_Updated above) after Master/Detail-Add.

Grid_Updating

For use with Grid-Edit for a table and Master/Detail-Edit for a detail table, this event will be called before updating records. The argument of the event (rsold) is array of records to be updated (retrieved from database).

You can use this event to check all records to be updated. If you want to cancel update, return false. Otherwise, return true. By default the event returns true.

Note If you only need to check individual record, there is no need to use this event, simply use Row_Updating (see above) which will be called for each row in the grid.

Example

Check all records before updating. Note that this event is called before Row_Updating, the field values are not loaded yet, but you can load them yourself.

public bool Grid_Updating(List<Dictionary<string, object>> rsold) {
    var rsnew = GetGridFormValues(); // Get the form values of the new records as as List<Dictionary<string, string>>
    int oldtotal = rsold.Aggregate(0, (sum, row) => sum += Convert.ToInt32(row["Subtotal"])); // Loop through the old records and get the total
    int newtotal = rsnew.Aggregate(0, (sum, row) => sum += Convert.ToInt32(row["Subtotal"])); // Loop through the new records and get the total
    if (newtotal < oldtotal) {
        // To cancel, set return value to false
        FailureMessage = "The new total must be larger than the old total.";
        return false;
    } else {        
        return true;
    }
}

Note Data returned from GetGridFormValues() is read only, do NOT try to change the values. To change the values, use Row_Updating (see above) which will be called for each row in the grid.

Grid_Updated

For use with Grid-Edit for a table and Master/Detail-Edit for a detail table, this event will be called after updating all records. The argument of the event (rsold and rsnew) are array of records before and after update (retrieved from database).

For example, you can use this event to update a field in the master table (similar to the example for Row_Updated above) after Master/Detail-Edit.

Email_Sending

This event is fired before the email notification is sent. You can customize the email content using this event. Email_Sending event has the following parameters:

email - the email object instance which contain all the information about the email to be sent. It is an instance of the Email class (see below).

args - an object which contains additional information.

If Add, the new record in the format of Dictionary<string, object> can be access by args["rsnew"]. If Copy, the old record in the format of Dictionary<string, object> can be access by args["rsold"]. If Edit/Update, the old data of the records in the format of Dictionary<string, object> can be access by args["rsold"], the new data of the records in the format of Dictionary<string, object> can be access by args["rsnew"]. You can get a field value by, e.g.

var rsnew = args["rsnew"];
var myValue = rsnew["MyField"];

or

var myValue = args["rsnew"]["MyField"];

Return false in the event if you want to cancel the email sending.

If Grid-Add/Edit, there are more than one records, the arguments are List<Dictionary<string, object>>.

Example

Assume there is an email field in the record, and you want to change the recipient to the value of that field when a new record is inserted.

public bool Email_Sending(Email email, dynamic args) {
    //Log(email, args); // View the arguments
    if (CurrentPageID() == "add") { // If Add page
        email.Recipient = Convert.ToString(args["rsnew"]["MyEmailField"]); // Change recipient to a field value in the new record
        email.Subject = "My New Subject"; // Change subject
        email.Content += "\r\nAdded by " + CurrentUserName(); // Append additional content
    }
    return true;
}

Lookup_Selecting

This event is fired before building the SQL for selecting records from the lookup table. You can use this event to change the filters.

In the event, the SQL and filter for the lookup can be viewed by:

VarDump(LookupFilters);

The property LookupFilters is an Dictionary, the key values are:

s SQL (SELECT clause and FROM clause only)
d Database ID
f<n>

Filter template for filter field <n> (where n = 1 to 4), by default it is in the format of FilterField<n> = {filter_value} where "{filter_value}" is to be replaced by selected value(s) submitted from client side by Ajax.

t<n> The data type of the filter field. Do not change unless you change the filter field in f<n>.
fn<n> The function used to concatenate the filter, by default it is empty and the default function "AddFilter" is used to concatenate the filters by "AND".

Example 1

Add additional filter to the lookup table filter for Add Page

public void Lookup_Selecting(DbField fld, ref string filter) {
    if (fld.FldName == "MyLookupField" && CurrentPageID() == "add")
        AddFilter(ref filter, "MyField = 'xxx'"); // Assume the field is of string type
}

Example 2

Change the default filter of a filter field from MyFilterField IN ({filter_value}) to MyFilterField > ({filter_value})

public void Lookup_Selecting(DbField fld, ref string filter) {
    if (fld.FldName == "MyLookupField")
        fld.LookupFilters["f1"] = fld.LookupFilters["f1"].Replace("IN", ">");
}

UserID_Filtering

For use with User ID security. (See Security Settings) This event is fired before adding the User ID filter to the WHERE clause of the table. It is possible to modify, replace or add filter so the user can access more or less records that he/she can access by its originally loaded User IDs.

Example

Assume you have 2 User ID fields in the current table and in the user table, and you want to filter by both User ID fields.

public void UserID_Filtering(ref string filter) {
    AddFilter(ref filter, "MyUserIDField2 = " + Convert.ToString(CurrentUserInfo("MyUserIDField2InUserTable"))); // Assume the field is of integer type
}

Table-Specific -> Add/Copy page

Page_Load

This event will be called after connecting to the database.

Page_Render

This event will be called before outputting HTML for the page. You can use this event to make some last minute changes to the page before it is outputted.

Page_Unload

This event will be called before closing database connection.

Page_DataRendering

This event will be called after the header. You can use this event to add content at the top of page content.

Page_DataRendered

This event will be called before the footer. You can use this event to add content at the bottom of page content.

Page_Redirecting

This event will be called before redirecting to other page. The argument is the URL to be redirected to.

By default after inserting a record user is redirected back to the List page. You can change that by using Return Page (see Table Setup). However, If you want to change by code, you can also use this event.

Message_Showing

This event is fired before the message stored in the session variable is shown.

The first argument msg is the message to be shown, the second argument type is the type of the message, possible values of type are: "" (empty string), "success", "failure", and "warning". Note: Do not add message outside these 4 cases or your message will be shown many times.

Example

Replace an error message by custom message

public void Message_Showing(ref string msg, string type) {
    if (type == "success") {
        //msg = "your success message";
    } else if (type == "failure") { // If a failure/error message
        if (msg.Contains("some standard message")) // The original message contains some keywords you want to replace
            msg = "My custom message";
    } else if (type == "warning") {
        //msg = "your warning message";
    } else {
        //msg = "your message";
    }
}

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. In general, the form data can be accessed by <Field>.FormValue (e.g. HP.FormValue). Alternatively, you can get all the form values in an string dictionary first, e.g.

var rs = GetFormValues();

An argument customError is passed to the event, you can add your error message and return false if the form values do not pass your validation.

Example

Make sure an integer field value meet a certain requirement

public bool Form_CustomValidate(ref string customError) {
    var rs = GetFormValues(); // Get the form values as Dictionary<string, string>
    if (Convert.ToInt32(rs["Qty"]) % 10 != 0) {
        // Return error message in customError
        customError = "Order quantity must be multiples of 10.";
        return false;
    }       
    return true;    
}

Table-Specific -> Delete Page

Page_Load

This event will be called after connecting to the database.

Page_Render

This event will be called before outputting HTML for the page. You can use this event to make some last minute changes to the page before it is outputted.

Page_Unload

This event will be called before closing database connection.

Page_DataRendering

This event will be called after the header. You can use this event to add content at the top of page content.

Page_DataRendered

This event will be called before the footer. You can use this event to add content at the bottom of page content.

Message_Showing

This event is fired before the message stored in the session variable is shown. You can use this event to change the message which is passed to the event as argument.

Page_Redirecting

This event will be called before redirecting to other page. Event argument is the URL to be redirected to.

By default after deleting record(s) user is redirected back to the List page. You can change that using this event.

Table-Specific -> Edit Page

Page_Load

This event will be called after connecting to the database.

Page_Render

This event will be called before outputting HTML for the page. You can use this event to make some last minute changes to the page before it is outputted.

Page_Unload

This event will be called before closing database connection.

Page_DataRendering

This event will be called after the header. You can use this event to add content at the top of page content.

Page_DataRendered

This event will be called before the footer. You can use this event to add content at the bottom of page content.

Message_Showing

This event is fired before the message stored in the session variable is shown. You can use this event to change the message which is passed to the event as argument.

Page_Redirecting

This event will be called before redirecting to other page. Event argument is the URL to be redirected to.

By default after updating a record user is redirected back to the List page. You can change that by using Return Page (see Table Setup). However, If you want to change by code, you can use this event.

Table-Specific -> List Page

Page_Load

This event will be called after connecting to the database.

Example

Note The export links are stored as a ListOptions object (also see ListOptions_Load, ListOptions_Rendering and ListOptions_Rendered event below), you can manipulate the links in the same way. The default names of the options are:

  • print
  • html
  • excel
  • word
  • xml
  • csv
  • pdf
  • email

Note that the names are in lowercase and are case-sensitive.

Example 1

Hide the export to PDF link in List page:

public void Page_Load() {
    ExportOptions["pdf"].Visible = false;  
}

Example 2

Add a custom link at the end of the export links

public void Page_Load() {
    var item = ExportOptions.Add("MyName");
    item.Body = "<a href='MyURL'>My Link</a>";
}

Example 3

Add a custom action to submit selected records by HTTP POST using the ListAction class. The constructor of ListActions class is

public ListAction(string name, string caption, bool allow = true, string method = Config.ActionPostback, string select = Config.ActionMultiple, string confirmMsg = "", string icon = "glyphicon glyphicon-star ewIcon", string success = "")

submit is either Config.ActionPostback (submit by HTTP POST) or Config.ActionAjax (submit by Ajax).

select is either Config.ActionMultiple (submit the selected records) or Config.ActionSingle (submit the current record only).

success is the name of JavaScript callback function, if any. You can place your callback function in client side Global Code section (see below).

Note To process the action, you also need to write a handler with Row_CustomAction server event (see below).

Example 4

Add a custom action to submit selected records by Ajax

public void Page_Load() {
    ListActions.Add("star", "Add Star", IsLoggedIn(), Config.ActionAjax, Config.ActionMultiple, "Add Star to selected records?", "glyphicon glyphicon-star ewIcon");
}

Note To process the action, you also need to write a handler with Row_CustomAction server event (see below).

Page_Render

This event will be called before outputting HTML for the page. You can use this event to make some last minute changes to the page before it is outputted.

Page_Unload

This event will be called before closing database connection.

Page_DataRendering

This event will be called after the header. You can use this event to add content before the main table.

Example

Hide a field from the main table

public void Page_DataRendering() {
    MyField.Visible = false; // Hide a field named "MyField"
}

Page_DataRendered

This event will be called before the footer. You can use this event to add content after the main table.

Page_Redirecting

This event will be called before redirecting to other page. Event argument is the URL to be redirected to.

Message_Showing

This event is fired before the message stored in the session variable is shown. You can use this event to change the message which is passed to the event as argument.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. See description of Form_CustomValidate for Add/Copy page above.

ListOptions_Load

This event will be called before the main table is rendered. Use this event to modify the non data columns of the main table (i.e. the links and the checkbox for each record). You can modify these columns or add your own columns using this event. You can get a column by name using ListOptions["name"].

Note The following predefined names are reserved, do not use them for your own columns. These names are case-sensitive and are in lowercase except for the detail table names.

  • checkbox
  • view
  • copy
  • delete
  • edit
  • detail_<DetailTable> - Detail table column
  • detailreport_<Report> - Report (as detail table) column
  • details - the Multiple Master/Detail column
  • preview - column for preview row of the Detail Preview extension (for registered users) only
  • sequence - column for sequence number
  • button - column for button group or button dropdown

Example 1

Add a new column.

public void ListOptions_Load() {
    var item = ListOptions.Add("new");
    item.Header = "MyCaption"; // Set the column header (for List page)
    item.OnLeft = true; // Link on left
    item.MoveTo(0); // Move the column to the specified index
}

Note If you have enabled Use buttons as links and/or Use button dropdown for links (see ASP.NET Settings), note that the feature will hide the list options and try to move hyperlinks to the button group or button dropdown. If your Body property (see below) is not hyperlink(s), it cannot be shown in the button group or button dropdown, you should remove your list option from the button group or button dropdown by adding, e.g.

item.ShowInButtonGroup = false;

and/or

item.ShowInDropDown = false;

Example 2

Hide the "view" column.

public void ListOptions_Load() {
    ListOptions["view"].Visible = false;     
}

Example 3

Hide a detail table named "MyDetailTable" in Preview Row or Overlay (requires Detail Preview extension which is for registered users only)

public void ListOptions_Load() {
    DetailPages["MyDetailTable"].Visible = false;     
}

ListOptions_Rendering

This event will be called before list options are rendered. To access field object of the current row, you can use <Field>.Property> (e.g. HP.CurrentValue).

Note Do NOT try to show/hide a column dynamically by setting the Visible property of the list option in this event. If the column is visible in one row but invisible in another, the table will be malformed.

Example 1

Disable Master/Detail-Add/Edit/View, e.g. if the detail table name is "orderdetails"

public void ListOptions_Rendering() {
    orderdetailsGrid.DetailAdd = (...condition...); // Set to true or false conditionally
    orderdetailsGrid.DetailEdit = (...condition...); // Set to true or false conditionally
    orderdetailsGrid.DetailView = (...condition...); // Set to true or false conditionally
}

Example 2

Append a CSS class to all cells (including header/footer cell) of a field in the List page

public void ListOptions_Rendering() {
    Category.AddClass("visible-lg"); // Add CSS class to show the field for large screen only
}

Notes

  1. The AddClass() method add class to all cells including those in table header and footer. Do not use this method if you want to add class for the current row only.
  2. Use this example carefully if your List page supports Inline/Grid-Add/Copy/Edit. If a field is only visible in large screen, it cannot be updated in smaller screens.
ListOptions_Rendered

This event will be called after list options are rendered. Use this event to modify content of the non data columns for the record. To access field object of the current row, you can use <Field>.<Property> (e.g. HP.CurrentValue).

Note Do NOT try to show/hide a column dynamically by setting the Visible property of the list option in this event. If the column is visible in one row but invisible in another, the table will be malformed. If you want to hide the content dynamically, you can set the Body property as empty string.

Example 1

Set the content of the new column dynamically based on a field value.

public void ListOptions_Rendered() {
    if (SameString(MyField.CurrentValue, "xxx")) {
        ListOptions["new"].Body = "xxx";
    } else {
        ListOptions["new"].Body = "";
    }
}

Example 2

Add a link to perform a custom action for the row by Ajax.

public void ListOptions_Rendered() {
    ListOptions["new"].Body = "<a href=\"#\" onclick=\"return ew_SubmitAction(event, {action: 'star', method: 'ajax', msg: 'Add star?', key: " + KeyToJson() + "});\">Add Star</a>";
}

Note To process the action, you also need to write a handler with Row_CustomAction server event (see below).
Row_CustomAction

If you have used Page_Load server event (see above) to add your custom action to the List page, the page will show the checkbox column for users to select records (similar to Multi-Update and Multi-Delete). When user clicks the custom action link or button, the page will post back to itself and this event will be fired (after Page_Load and before Page_Render) for each selected row to process the custom action.

Return true to proceed to next record or return false to abort custom action.

Example

Update the status of the selected records, assuming the table has a field named "Starred" for storing the status.

public void Row_CustomAction(string action, Dictionary<string, object> row) {
    if (action == "star") { // Check action name
        var rsnew = new Dictionary<string, object>() {{"Starred", "Y"}}; // field(s) to be updated
        var result = Update(rsnew); // Note: The Update() method updates the current record only
        if (result < 0) { // Failure
                FailureMessage = "Failed to update record, ID = " + Convert.ToString(row["ID"]);
                return false; // Abort and rollback
        } else if (SelectedIndex == SelectedCount) { // Last row
               
 SuccessMessage = "All selected records updated.";                 
        }
        return true; // Success
    }     
    return true;
}

Note If you cancel the action by returning false in the event, you can use the FailureMessage property to set your message. However, note that if the event returns false, subsequent rows will not be processed and the database changes for previous rows will be rolled back (if your database supports transaction). So if you just want to cancel action for a row without affecting other rows, the event should still return true and use SuccessMessage property to set your message.
Page_Exporting

This event will be called before the page is exported. You can use this event to add your additional code to the beginning of file to be exported. Return false to skip default export and use Row_Export event (see below). Return true to use default export and skip Row_Export event. Check Export for the export type (e.g. "excel", "word"). The content of the export document is ExportDoc.Text.

Note If Custom Templates is used (see Custom Templates), this event may be overridden. You can disable using Custom Templates for report, see example for Page_Load above.

Example

Add a title to the export document and use custom export if export to Excel (without extension)

public bool Page_Exporting() {
    if (Export == "excel") {
        ExportDoc.Text.Append("<p>My Title</p>"); // Add a title
        return false; // Return false to skip default export and use Row_Export event
    }
    return true; // Return true to use default export and skip Row_Export event
}

Row_Export

If you return false in Page_Exporting event (see above), this event will be called when a row is exported for you to export in your own code.

The argument (rs) is an array of the record to be exported. The values in rs are unformatted database values. If you want to export formatted values, use MyField.ViewValue.

Notes

  1. If you return true in Page_Exporting event (see above), default export will be used and this event will NOT be called.
  2. If Custom Templates is used (see Custom Templates), this event may be overridden. You can disable using Custom Templates for report, see example for Page_Load above.

Example

Export a record with custom code if export to Excel (without extension)

public void Row_Export(DbDataReader rs) {
    if (Export == "excel")
        ExportDoc.Text.Append("<div>" + MyField.ViewValue + "</div>"); // Build HTML with field value: rs["MyField"] or MyField.ViewValue
}

Page_Exported

This event will be called after the page is exported. You can use this event to add your additional code to the end of the file to be exported.

Note If Custom Templates is used (see Custom Templates), this event may be overridden. You can disable using Custom Templates for report, see example for Page_Load above.

Example

Add a footer to the export document if export to Excel (without extension)

public void Page_Exported() {
    if (Export == "excel")
        ExportDoc.Text.Append("my footer"); // Add a footer
    //Log(ExportDoc.Text); // View the whole export document for debugging
}

Table-Specific -> Multi-Update Page

Page_Load

This event will be called after connecting to the database.

Page_Render

This event will be called before outputting HTML for the page. You can use this event to make some last minute changes to the page before it is outputted.

Page_Unload

This event will be called before closing database connection.

Page_DataRendering

This event will be called after the header. You can use this event to add content at the top of page content.

Page_DataRendered

This event will be called before the footer. You can use this event to add content at the bottom of page content.

Page_Redirecting

This event will be called before redirecting to other page. Event argument is the URL to be redirected to.

By default after updating records user is redirected back to the List page. You can change that by using this event.

Message_Showing

This event is fired before the message stored in the session variable is shown. You can use this event to change the message which is passed to the event as argument.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. See description of Form_CustomValidate for Add/Copy page above.

Table-Specific -> Report Page

Page_Load

This event will be called after connecting to the database.

Page_Render

This event will be called before outputting HTML for the page. You can use this event to make some last minute changes to the page before it is outputted.

Page_Unload

This event will be called before closing database connection.

Page_DataRendering

This event will be called after the header. You can use this event to add content at the top of page content.

Page_DataRendered

This event will be called before the footer. You can use this event to add content at the bottom of page content.

Page_Redirecting

This event will be called before redirecting to other page. Event argument is the URL to be redirected to.

Message_Showing

This event is fired before the message stored in the session variable is shown. You can use this event to change the message which is passed to the event as argument.

Table-Specific -> Search Page

Page_Load

This event will be called after connecting to the database.

Page_Render

This event will be called before outputting HTML for the page. You can use this event to make some last minute changes to the page before it is outputted.

Page_Unload

This event will be called before closing database connection.

Page_DataRendering

This event will be called after the header. You can use this event to add content at the top of page content.

Page_DataRendered

This event will be called before the footer. You can use this event to add content at the bottom of page content.

Page_Redirecting

This event will be called before redirecting to other page. Event argument is the URL to be redirected to.

By default user is redirected to the List page after the search criteria is processed. You can change that by using this event.

Message_Showing

This event is fired before the message stored in the session variable is shown. You can use this event to change the message which is passed to the event as argument.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. See description of Form_CustomValidate for Add/Copy page above.

Table-Specific -> View Page

Page_Load

This event will be called after connecting to the database.

Page_Render

This event will be called before outputting HTML for the page. You can use this event to make some last minute changes to the page before it is outputted.

Page_Unload

This event will be called before closing database connection.

Page_DataRendering

This event will be called after the header. You can use this event to add content at the top of page content.

Page_DataRendered

This event will be called before the footer. You can use this event to add content at the bottom of page content.

Page_Redirecting

This event will be called before redirecting to other page. Event argument is the URL to be redirected to.

Message_Showing

This event is fired before the message stored in the session variable is shown. You can use this event to change the message which is passed to the event as argument.

Table-Specific -> Preview Page

Page_Load

This event will be called after connecting to the database.

Page_Render

This event will be called before outputting HTML for the page. You can use this event to make some last minute changes to the page before it is outputted.

Page_Unload

This event will be called before closing database connection.

Page_DataRendering

This event will be called before the page content is outputted. You can use this event to add content at the top of page content.

Page_DataRendered

This event will be called after the page content is outputted. You can use this event to add content at the bottom of page content.

Page_Redirecting

This event will be called before redirecting to other page. Event argument is the URL to be redirected to.

Message_Showing

This event is fired before the message stored in the session variable is shown. You can use this event to change the message which is passed to the event as argument.

Other -> Login Page

Page_Load

This event will be called at the beginning of the page.

Page_Render

This event will be called before outputting HTML for the page. You can use this event to make some last minute changes to the page before it is outputted.

Page_Unload

This event will be called at the end of the page.

Page_DataRendering

This event will be called after the header. You can use this event to add content at the top of page content.

Page_DataRendered

This event will be called before the footer. You can use this event to add content at the bottom of page content.

Page_Redirecting

This event will be called before redirecting to other page. Event argument is the URL to be redirected to.

By default user is redirected to the default page (e.g. Index) after successful login. You can change that by using this event.

Message_Showing

This event is fired before the message stored in the session variable is shown. You can use this event to change the message which is passed to the event as argument.

User_LoggingIn

This event will be called before validating the username and password.

User_LoggedIn

This event will be called after the user login.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. Inspect the HTML source of the page in your browser to view the form element names.

An argument customError is passed to the event, you can add your error message and return false if the form values do not pass your validation.

User_LoginError

This event will be called if the user fail to login.
Other -> Logout Page

Page_Load

This event will be called at the beginning of the page.

Page_Unload

This event will be called at the end of the page.

Page_Redirecting

This event will be called before redirecting to other page. Event argument is the URL to be redirected to.

By default user is redirected to the default page (e.g. Index) after successful login. You can change that by using this event.

User_LoggingOut

This event will be called before user logout.

User_LoggedOut

This event will be called after user logout.

Other -> Registration Page

Page_Load

This event will be called at the beginning of the page.

Page_Render

This event will be called before outputting HTML for the page. You can use this event to make some last minute changes to the page before it is outputted.

Page_Unload

This event will be called at the end of the page.

Page_DataRendering

This event will be called after the header. You can use this event to add content at the top of page content.

Page_DataRendered

This event will be called before the footer. You can use this event to add content at the bottom of page content.

Page_Redirecting

This event will be called before redirecting to other page. Event argument is the URL to be redirected to.

By default user is redirected to the default page (e.g. Index) after successful login. You can change that by using this event.

Email_Sending

This event is fired before the email notification is sent. You can customize the email content using this event. Email_Sending event has the following parameters:

email - the email object instance which contain all the information about the email to be sent. It is an instance of the Email class (see below).

args - an array which contains additional information. For registration page, the new record in the data type of a recordset can be accessed by args["rs"].

Return false in the event if you want to cancel the email sending.

Message_Showing

This event is fired before the message stored in the session variable is shown. You can use this event to change the message which is passed to the event as argument.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. See description of Form_CustomValidate for Add/Copy page above.

User_Registered

This event is fired after successful registration of a new user. Argument is a recordset of the new record in the user table.

User_Activated

This event is fired after activating a new user (if user activation is required, see Security Settings). Argument is a recordset of the new record in the user table.

Other -> Change Password Page

Page_Load

This event will be called at the beginning of the page.

Page_Render

This event will be called before outputting HTML for the page. You can use this event to make some last minute changes to the page before it is outputted.

Page_Unload

This event will be called at the end of the page.

Page_DataRendering

This event will be called after the header. You can use this event to add content at the top of page content.

Page_DataRendered

This event will be called before the footer. You can use this event to add content at the bottom of page content.

Page_Redirecting

This event will be called before redirecting to other page. Event argument is the URL to be redirected to.

By default user is redirected to the default page (e.g. Index) after successful login. You can change that by using this event.

Email_Sending

This event is fired before the email notification is sent. You can customize the email content using this event. Email_Sending event has the following parameters:

email - the email object instance which contain all the information about the email to be sent. It is an instance of the Email class (see below).

args - an array containing additional information. For Change Password page, the old data of the records in the data type of recordset can be accessed by args["rsold"], the new data of the records in the data type of recordset can be accessed by args["rsnew"].

Return false in the event if you want to cancel the email sending.

Message_Showing

This event is fired before the message stored in the session variable is shown. You can use this event to change the message which is passed to the event as argument.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. Inspect the HTML source of the page in your browser to view the form element names.

An argument customError is passed to the event, you can add your error message and return false if the form values do not pass your validation.

Other -> Password Recovery Page

Page_Load

This event will be called at the beginning of the page.

Page_Render

This event will be called before outputting HTML for the page. You can use this event to make some last minute changes to the page before it is outputted.

Page_Unload

This event will be called at the end of the page.

Page_DataRendering

This event will be called after the header. You can use this event to add content at the top of page content.

Page_DataRendered

This event will be called before the footer. You can use this event to add content at the bottom of page content.

Page_Redirecting

This event will be called before redirecting to other page. Event argument is the URL to be redirected to.

By default user is redirected to the login page after successful login. You can change that by using this event.

Email_Sending

This event is fired before the email notification is sent. You can customize the email content using this event. Email_Sending event has the following parameters:

email - the email object instance which contain all the information about the email to be sent. It is an instance of the Email class (see below).

args - an array containing additional information. For Password Recovery Page, the old data of the records in the data type of recordset can be accessed by args["rs"].

Return false in the event if you want to cancel the email sending.

Message_Showing

This event is fired before the message stored in the session variable is shown. You can use this event to change the message which is passed to the event as argument.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. Inspect the HTML source of the page in your browser to view the form element names.

An argument customError is passed to the event, you can add your error message and return false if the form values do not pass your validation.

User_RecoverPassword

This event is fired after the password is recovered. Argument is a recordset of the user's record in the user table.

 

Client Scripts

In general, each page has two blocks of JavaScript:

Client Script - the first block of JavaScript to be included at the beginning of the page, you can put your JavaScript variables and functions there. The View Tag (for display) and Edit Tag (for input) of the fields supports Custom Attributes (See Field Setup) so you can add your own attributes to work with your own JavaScript included here.

Startup Script - the second block of JavaScript to be included at the end of the page, you can put code here to "start up" your JavaScript.

Note In the following table, the <fieldname> in code represents the field variable name. In general, if the field name is alphanumeric, field variable name is same as the field name. Otherwise, spaces are replaced by underscores, and other non alphanumeric characters are replaced by their hexadecimal string representation of their unicode value. If the variable is a reserved word or starts with a digit, it will be prepended with an underscore. If in doubt, always inspect HTML source in your browser to check the actual id, name, and other attributes of the elements.

Example

Set div.content-wrapper and footer min-width if advanced setting "Reset layout height" (see Advanced Settings) is disabled

$(document).on("overflow", function(e, $form) { // "overflow" event (fired if content wider than screen)
    if (EW_IS_SCREEN_SM_MIN) // Not mobile
        $(".content-wrapper, footer").css("min-width", "900px"); // Set min-width
});

Global -> Pages with header/footer

Client Script

The script will be placed in the header and therefore included in all pages with header.

Note This event is NOT related to the No header/footer setting in the Generate form (see Generate Settings). Even if No header/footer is enabled, this event will also be fired.

Startup Script

The script will be placed in the footer and therefore included in all pages with footer. This is a very useful event which is fired fired for all pages with footer, you can almost do everything by changing the document DOM.

Note This event is NOT related to the No header/footer setting in the Generate form (see Generate Settings). Even if No header/footer is enabled, this event will also be fired.

Example

Enable AdminLTE mini sidebar

$("body").addClass("sidebar-mini"); // Enable mini sidebar
$(".logo-mini").html("<strong><em>P</em></strong>"); // Set mini logo

Global Code

JavaScript code to be included in all pages with header. This may contain your global constants, variables and functions.
Table-Specific -> Add/Copy page

Client Script

The script will be placed after the header. This may contain your JavaScript variables and functions for the page. You can also use this event to subscribe a custom event.

Example 1

Set Multi-Page (see Table Setup) properties

CurrentForm.MultiPage.Set({
    //LastPageSubmit: true, // Enable submit button for the last page only
    //HideDisabledButton: true, // Hide disabled submit button
    //HideInactivePages: true, // Hide inactive pages

    //HideTabs: true, // Hide all tabs
    //ShowPagerBottom: true, // Show pager at bottom
    //PagerTemplate: '<nav><ul class="pager"><li class="previous ewPrev"><a href="#"><span class="icon-prev"></span> {Prev}</a></li><li class="next ewNext"><a href="#">{Next} <span class="icon-next"></span></a></li></ul></nav>' // Pager template
    
LockTabs: true,// Set inactive tabs as disabled
    
ShowPagerTop: true // Show pager at top
});

Note The argument of the Set() method is a JavaScript object, if you modify above example, make sure that the syntax is correct and that the last property value does not have a trailing comma.

Example 2

Subscribe the jQuery ajaxSend event before an Ajax request is sent (e.g. "updateoption", "autosuggest", "autofill")

$(document).ajaxSend(function(event, jqxhr, settings) {
    var data = settings.data;     
    //console.log(data); // Uncomment to view data in browser console
    if (ew_Get("ajax", data) == "updateoption" && ew_Get("name", data) == "x_MyField") // Ajax selection list
        settings.data = data.replace("xxx", "yyy"); // Replace data with custom data
});

Example 3

Subscribe the "updatedone" event for Dynamic Selection Lists. The event fires after options of a child field is updated.

$(document).on("updatedone", function(e, args) {
    //console.log(args); // Uncomment to view the arguments in browser console
    alert($(args.target).data("field") + " has been updated.");
});

Example 4

Subscribe the "create.editor" event for the field named "MyField" to change configuration of the HTML editors. The event fires before the DHTML editor is created.

$(document).on("create.editor", function(e, args) {
    //console.log(args); // Uncomment to view the arguments in browser console
    
if (args.name == "x_MyField")
        args.settings.height = "300px"; // Refer to HTML editor doc for details about the settings
});

Startup Script

The script will be placed before the footer. This is a very useful event which you can almost do everything by changing the document DOM.

ASP.NET Maker provides a jQuery plugin .fields() for you to easily get/set the form values in client side events such as Startup Script and Form_CustomValidate (see below)

$row = $(CurrentForm).fields(); // Note: Do not use "this" in Startup Script.

and Form_CustomValidate event (see below), e.g.

$row = $(this).fields(); // return an object of all fields, each property is a jQuery object of the input element(s) of a field
$field = $row["<fieldname>"]; // get jQuery object of the input element(s) of a field

You can also get the jQuery object for a field directly,

$field = $(this).fields("<fieldname>"); // return jQuery object of the input element(s) of a field

The jQuery object of the field is the jQuery object of the input element of the field. (Note that if Edit Tag of the field is CHECKBOX or RADIO, the jQuery object may contain more than one elements.)

For example, if the page is an Edit page and the field is named "Field1" and it is a textbox, $(this).fields("Field1") is equivalent to $("#x_Field1"). The advantages of using .fields() plugin is that the returned jQuery object has the following additional methods:

.value([value])

.value() get field value, .value(value) set the field value.

Note This method is NOT the same as jQuery's .val() method. This method takes other features (e.g. HTML editor, AutoSuggest) into consideration.
.visible([value])

.visible() get the visibility of the field, .visible(value) set the visibility of the field. The value should be a boolean value.

Note
  1. This method shows/hides the row of the field (i.e. the <tr> or the <div>), NOT just the input element(s) of the field itself in Add/Edit page.
  2. The setter is NOT the same as jQuery's .toggle() method.
.readonly(value)

Get/Set the readonly attribute of the input element. The value should be a Boolean value.

Note For <input type="text"> and <textarea> only.
.disabled(value)

Get/Set the disabled attribute of the input element. The value should be a Boolean value.

Note A disabled control's value is NOT submitted with the form. Use this carefully in Add/Edit page or the field may be updated with an empty value.
.row()

Get the jQuery object of the row (<tr> or <div>) of the field.

Notes
  1. If Add/Edit page, the row is the <tr> or the <div> of the field.
  2. If Grid page, the row is the <tr> of the record.
.toNumber() Get the input value as a JavaScript Number (by default the input value is string).
.toDate() Get the input value as a moment object (by default the input value is string).
.toJsDate() Get the input value as a JavaScript Date object (by default the input value is string).

Example 1

Add onchange event the field named "Field1" in Add/Edit page to change other fields by jQuery plugin .fields()

$("input[name='x_Field1']").change(function() { // Assume Field1 is a text input
    if (this.value == "xxx") {

        $(this).fields("FieldA").value("yyy"); // Set value to FieldA
    } else {
        $(this).fields("FieldB").value("zzz"); // Set value to FieldB
    }     
});

Example 2

Add onclick event to the field named "Field2" which uses CHECKBOX as Edit Tag.

$("input[name='x_Field2']").click(function() { // Field2 has multiple inputs (checkboxes) so they should be selected by name
    if (this.checked) { // If checked
        // Do something
    } else { // Not checked
        // Do something else
    }
});

Example 3

Add onchange event to the field named "Field1" in Grid-Add/Edit page to change other fields by jQuery plugin .fields()

$("input[data-field='x_Field3']").change(function() { // Field1 has multiple inputs in Grid-Add/Edit so they should be selected by data-field attribute
    if (this.value == "xxx") {

        $(this).fields("FieldA").value("yyy"); // Set value to FieldA in the same row
    } else {
        $(this).fields("FieldB").value("zzz"); // Set value to FieldB in the same row
    }     
});

Example 4

Toggle visibility of a page in Multi-Page (see Table Setup)

$(function() {
    CurrentForm.MultiPage.TogglePage(2, false); // Hide the 2nd page
});

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. Note: This function is a member of the JavaScript page class.

Return false if the form values do not pass your validation.

Note If you use this client side event, make sure you have enabled client-side validation, see Validation in ASP.NET Settings.

The HTML form object can be accessed by the parameter fobj. You can also use the jQuery plugin .fields() in this event.

Example 1

Make sure an integer field value meet a certain requirement

function(fobj) { // DO NOT CHANGE THIS LINE!
    var $qty = $(this).fields("Qty"); // Get a field as jQuery object by field name
    if ($qty.toNumber() % 10 != 0) // Assume Qty is a textbox         
        
return ew_OnError($qty, "Order quantity must be multiples of 10."); // Return false if invalid
    return true; // Return true if valid
}

Example 2

Compare 2 date fields

function(fobj) { // DO NOT CHANGE THIS LINE!
    var $row = $(this).fields(); // Get all fields
    if ($row["Start"].toJsDate() > $row["End"].toJsDate()) // Assume Start and End are textboxes        
        
return this.OnError($row["End"], "The End Date must be later than the Start Date."); // Return false if invalid
    return true; // Return true if valid
}

Example 3

Manipulation of date fields

function(fobj) { // DO NOT CHANGE THIS LINE!
    var $start = $(this).fields("Start"), $end = $(this).fields("End"); // Get fields as jQuery objects by field names
    if ($start.toDate().add(7, "days").isAfter($end.toDate())) // Assume Start and End are textboxes        
        
return this.OnError($end, "The End Date must be at least 7 days after the Start Date."); // Return false if invalid
    return true; // Return true if valid
}

Table-Specific -> Delete Page

Client Script

The script will be placed after the header.

Startup Script

The script will be placed before the footer.
Table-Specific -> Edit Page

Client Script

The script will be placed after the header.

Startup Script

The script will be placed before the footer.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. The form object can be accessed by the parameter fobj. Return false if the form values do not pass your validation.

The form object can be accessed by the parameter fobj.

Note that the form element names are different in Inline-Add/Copy/Edit or Grid-Add/Edit mode of List page. They are named as x0_<fieldname> in Inline-Add/Copy, as x1_<fieldname> in Inline-Edit mode, and as x1_<fieldname>, x2_<fieldname>, etc. in Grid-Add/Edit since there are multiple rows. Inspect the elements in your browser to check the actual form element names.

Note Form_CustomValidate is fired for EVERY row in the grid. You can also use the jQuery plugin .fields() (see above) to manipulate the fields, but remember that the plugin return field(s) of the CURRENT row only. If you need to access fields in other rows, either use fobj.elements or jQuery with CSS selectors.
Table-Specific -> List Page

Client Script

The script will be placed after the header.

Startup Script

The script will be placed before the footer.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. Return false if the form values do not pass your validation.

The form object can be accessed by the parameter fobj. In general, the HTML form element for the field can be referred to as fobj.elements["x_<fieldname>"].

Note that he form element names are different in Inline-Add/Copy/Edit or Grid-Add/Edit mode of List page. They are named as x0_<fieldname> in Inline-Add/Copy, as x1_<fieldname> in Inline-Edit mode, and as x1_<fieldname>, x2_<fieldname>, etc. in Grid-Add/Edit since there are multiple rows. Inspect the elements in your browser to check the actual form element names.

Table-Specific -> Multi-Update Page

Client Script

The script will be placed after the header.

Startup Script

The script will be placed before the footer.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. The form object can be accessed by the parameter fobj. Return false if the form values do not pass your validation.

Table-Specific -> Report Page

Client Script

The script will be placed after the header.

Startup Script

The script will be placed before the footer.
Table-Specific -> Search Page

Client Script

The script will be placed after the header.

Startup Script

The script will be placed before the footer.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. The form object can be accessed by the parameter fobj. Return false if the form values do not pass your validation.

Table-Specific -> View Page

Client Script

The script will be placed after the header.

Startup Script

The script will be placed before the footer.
Other -> Login Page

Client Script

The script will be placed after the header.

Startup Script

The script will be placed before the footer.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. The form object can be accessed by the parameter fobj. Return false if the form values do not pass your validation.

Other -> Registration Page

Client Script

The script will be placed after the header.

Startup Script

The script will be placed before the footer.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. The form object can be accessed by the parameter fobj. Return false if the form values do not pass your validation.

Other -> Change Password Page

Client Script

The script will be placed after the header.

Startup Script

The script will be placed before the footer.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. The form object can be accessed by the parameter fobj. Return false if the form values do not pass your validation.

Other -> Password Recovery Page

Client Script

The script will be placed after the header.

Startup Script

The script will be placed before the footer.

Form_CustomValidate

This event is fired after the normal form validation. You can use this event to do your own custom validation. The form object can be accessed by the parameter fobj. Return false if the form values do not pass your validation.

Note It is recommended that you develop your server event and client scripts in the generated script so you can edit and test it immediately. When you finish your custom script, copy it to ASP.NET Maker and save it.

 

Objects in Generated Code

The following objects are available in the generated code and you can use them in the Server Events to add more power to the code. The most important objects are:

Page and Table Object
The Page object is generated for most pages. You can access the object properties using the "." notation (e.g. CurrentPage.PageID). The page class inherits from the table class generated for each table. The methods and properties of the page class varies with page, for the complete list of methods and properties, please refer to the generated page class in the generated scripts and the class "_<Table>" (e.g. _Cars) in the generated file "<Table>info.cs".

Field Object
A <Field> object is generated for each field in a table as property of the table/page class. For example, the "Trademark" property is generated for the "Trademark" field in the "Cars" table. For the complete list of methods and properties, please refer to the class "Field" in the generated scripts.

Security Object
The Security object is used to store the current Advanced Security settings. Please refer to the class "AdvancedSecurity" in the generated scripts for the complete list of methods and properties.

Email Object
The Email object contains the required information of the email to be sent, the instance of the object will be passed to the Email_Sending events as argument and let you modify the email. Please refer to the class "Email" in the generated scripts for the complete list of methods and properties.

Menu Object
The Menu object contains all information of a menu, the instance of the menu will be passed to the Menu_Rendering events as argument and let you work with the menu. Please refer to the class "Menu" in the generated scripts for the complete list of methods and properties.

MenuItem Object
The MenuItem object contains all information of the menu item, the instance of the menu item will be passed to the MenuItem_Adding events as argument and let you work with the menu item. Please refer to the class "MenuItem" in the generated scripts for the complete list of methods and properties.

ListOpions Object
The ListOptions object contains all information of the non data columns in the main table of the List page. Please refer to the class "ListOptions" in the generated scripts for the complete list of methods and properties.

ExportOpions Object
The ExportOptions object contains all information of the export links in the List page. It is also an instance of the class "ListOptions". Please refer to the class "ListOptions" in the generated scripts for the complete list of methods and properties.

Language Object
The language Object lets you retrieve a phrase of the active language during runtime. The phrase can be retrieved in the generated scripts using methods such as Phrase, TablePhrase and FieldPhrase. Please refer to the class "Lang" in the generated scripts for the complete list of methods and properties.

Breadcrumb Object
The Breadcrumb object contains all information of the breadcrumb at the top of page. Please refer to the class "Breadcrumb" in the generated scripts for the complete list of methods and properties.

Note There are a few other objects in the generated code, please refer to the source code of the file "aspnetfn*.cs" in template or generated scripts.

 

Some Useful Methods and Properties

The following are some useful static methods available in the generated code for you to get information easier in server events:

Notes

  1. In the following table, the argument dbname or tablename or fieldname is the database/table/field variable name. It is case-sensitive. In general, if the name is alphanumeric, the variable name is same as the name. Otherwise, spaces are replaced by underscores, and other non alphanumeric characters are replaced by their hexadecimal string representation of their unicode value. If the variable is a reserved word, it will be prepended with an underscore. If you use databases with the same name, check the database variable name in the Add Linked Table form, see Linked Tables.
  2. If MS Access, the dbname is the file name of the database without the extension. If Oracle, the dbname is the schema name.
  3. Argument in square brackets means that the argument is optional.
  4. If dbname is not specified, the database of the project is assumed. If dbname is specified, the specified database of Linked Tables is used.
Name Arguments Description Example
GetConnection() [dbname]

Get database connection object for a database.

If dbname is not specified, it returns the database connection object for the main database of the project. If dbname is specified, it returns the database connection object for the specified database of a Linked Table.

var result = GetConnection().Execute("INSERT ..."); // execute a SQL statement

var result = GetConnection("MyDbName").Execute("UPDATE ..."); // execute a SQL statement

Conn -

Get current database connection object for a table or page. Note that it is only available AFTER a table or page is created.

Conn may be the connection returned by GetConnection() or GetConnection("<dbname>") depending on where it is called. For example, if it is called by server events of a page class for a Linked Table, Conn is GetConnection("<dbname of the Linked Table>").

var result = Conn.Execute("INSERT ..."); // execute a SQL statement

Security - Get the static security object if (Security.CanEdit) { // check if current user has Edit permission for the current table (for use with User Level Security
    ...your code...
}
Language - Get the static language object Language.SetPhrase("AddLink", "xxx"); // change the wording for the "Add" link
Profile - Get the static user profile object Profile.SetValue("xxx", "yyy"); // set a value
Profile.Save(); // save to session
Profile.GetValue("xxx"); // get the value
CurrentUserName() - Get current user name. var username = CurrentUserName();
CurrentUserID() - For used with User ID Security (see Security Settings). Get current User ID. var userid = CurrentUserID();
CurrentUserLevel() - For used with User Level Security (see Security Settings). Get current user's User Level ID (integer). (Note: NOT current user's permission as integer.) var levelid = CurrentUserLevel();
CurrentUserInfo() fieldname For used with Advanced Security (see Security Settings). Get current user's info from the user table. The argument is the field name in the user table. var email = CurrentUserInfo("email");
CurrentPageID() - Get current page ID. A page ID identifies the page type, it can be "list", "view", "add", "edit", "delete", "search", etc.

if (CurrentPageID() == "add") {
    ...your code...
}

CurrentPage - Get current page object.

var rowindex = CurrentPage.RowCnt;

CurrentLanguage - Get current language ID.

var langid = CurrentLanguage;

IsLoggedIn() - For used with Advanced Security (see Security Settings). Get the login status of the current user. if (IsLoggedIn()) {
    ...your code...
}
IsExport() [format] Check if the page is exporting data. If format not specified, the method returns true for any format. if (IsExport("print")) {
    ...your code...
}
Execute() sql[, dbname] Executes a SQL statement against the connection and returns the number of rows affected. int result = Execute("UPDATE MyTable SET... WHERE...");
ExecuteScalar() sql[, dbname] Executes the query, and returns the first column of the first row only. var value = ExecuteScalar("SELECT MyField FROM MyTable WHERE...");
ExecuteRow() sql[, dbname] Executes the query, and returns the first row as Dictionary<string, object>. var row = ExecuteRow("SELECT * FROM MyTable WHERE...");
ExecuteRows() sql[, dbname] Executes the query, and returns the rows as List<Dictionary<string, object>>. var rows = ExecuteRows("SELECT * FROM MyTable WHERE...");
ExecuteJson() sql[, options[, dbname]] Executes the query, and returns the row(s) as JSON. string json = ExecuteJson("SELECT * FROM MyTable WHERE...");
ExecuteHtml() sql[, options[, dbname]] Executes the query, and returns the row(s) in HTML table. string html = ExecuteHtml("SELECT * FROM MyTable WHERE...");
Get() name Get query value as string. If the value does not exists, the result is empty string. string value = Get("xxx");
Get<string>() name Get query value as string. If the value does not exists, the result is null. string value = Get<string>("xxx");
Get<int>() name Get query value as integer. If the value does not exists, the result is 0. int value = Get<int>("xxx");
Get<bool>() name Get query value as boolean. If the value does not exists, the result is false. bool value = Get<bool>("xxx");
Post() name Get HTTP POST value as string. If the value does not exists, the result is empty string. string value = Post("xxx");
Post<string>() name Get HTTP POST value as string. If the value does not exists, the result is null. string value = Post<string>("xxx");
Post<int>() name Get HTTP POST value as integer. If the value does not exists, the result is 0. int value = Post<int>("xxx");
Post<bool>() name Get HTTP POST value as boolean. If the value does not exists, the result is false. bool value = Post<bool>("xxx");
SetClientVar() name, value Pass server side data to client side as a property of the ewVar object. SetClientVar("myName", "myValue"); // C# (server side)
var myValue = ewVar.myValue; // JavaScript (client side)
Note There are many other useful methods and properties in the generated code, please refer to the source code of the file "aspnetfn*.cs" in template or generated scripts.

 

 

 

 

 ©2004-2018 e.World Technology Ltd. All rights reserved.