You are on page 1of 168

Project Setup Page 1 of 168

Project Setup
To make use of the various features of PHPMaker and create scripts that best suit your Web sites, read the following information and get
to know the options PHPMaker provide. It is assumed that you have basic knowledge of HTML and PHP and the technical terms are used
without further explanation. To generate a Web site, please perform the following steps:

1. Database
2. PHP
3. HTML
4. Security
5. Generate

To further control the functionality of the generated scripts, you can setup different options for each table/field:

• Table Setup
• Field Setup

You can also setup additional database objects for your project in PHPMaker:

• Custom View
• Report
• Custom File
• Linked Table

 ©2002-2019 e.World Technology Ltd. All rights reserved.

Database Setup
If you are not at the [Database] tab yet, clicking the icon in the toolbar to go to [Database] tab. PHPMaker can connect to MySQL,
PostgresSQL, Microsoft Access, Microsoft SQL Server, Oracle and SQLite.

1. MySQL

Select MySQL as database type.

There are 2 connection methods you can choose:

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 2 of 168

Direct Connection (default)

1. Enter your database host/server name (or IP address), username, password and port number (default is 3306 for MySQL),
2. Select your database,
3. Click the [Connect] button to load the database information.

Note The server name or IP should be valid on your production Web server also. Otherwise you'll need to modify the generated
connection info in ewcfg*.php before you upload it to your production server. For example, if you have a testing MySQL Server
installed on the same computer, you can use "localhost" as server name when you connect to it with PHPMaker. The generated
scripts will then try to connect to a MySQL Server on the same computer as the production Web server, if this is not the case, the
connection will fail.

URL Connection (for remote database)

(Also see Tutorial - Connecting Remote MySQL using PHPMaker Connection Script)

While the direct connection method is quick and easy, some remote MySQL server may not allow direct connection. PHPMaker provides
an alternative simple way to connect remote servers:

1. Upload the PHP connection script provided by PHPMaker to your site. Note that:

a. The script is named "phpmaker.php" and can be found under your installed folder, usually C:\Program Files (x86)\PHPMaker
<version>\,
b. Always use the script shipped with your version of PHPMaker. PHPMaker may not work with script shipped with
previous versions.

2. If it is the first time that you use this script, you may want to test the script with your browser:

a. Browse to this script with your browser,

b. Enter the connection info,

c. Click "Get Database List" and then "View Schema", you should be able to view the schema of your database in XML properly.
Now go back to PHPMaker.

3. Enter the SAME connection information, select URL for connection method, enter the URL of the script (e.g.
http://servername/path/phpmaker.php), you can test the URL by clicking the [Test] button,

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 3 of 168

4. Click the [Connect] button to load the database information. PHPMaker will connect to the database server through the PHP script
over HTTP.

2. PostgreSQL

Select PostgreSQL as database type.

There are 2 connection methods you can choose:

Direct Connection (default)

1. Enter your database host/server name (or IP address), username, password and port number (default is 5432 for PostgreSQL),
2. Select your database,
3. Click the [Connect] button to load the database information.

Note The server name or IP should be valid on your production Web server also. Otherwise you'll need to modify the generated
connection info in ewcfg*.php before you upload it to your production server. For example, if you have a testing PostgreSQL Server
installed on the same computer, you can use "localhost" as server name when you connect to it with PHPMaker. The generated
scripts will then try to connect to a PostgreSQL Server on the same computer as the production Web server, if this is not the case,
the connection will fail.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 4 of 168

URL Connection (for remote database)

Similar to above for MySQL.

3. Microsoft Access (Windows only)

Note If you use Microsoft Access database, you need to have OLEDB drivers installed on both the PC running PHPMaker and on the
web server. See System Requirements. (ODBC connection is not supported.)

• Select Microsoft Access as database type,


• Select the Microsoft Access database file by clicking the button,
• Specify the database path where the database file will reside under the your application root,
• Click the Connect button to load the database information.

Notes

1. Database path is relative to application root. Use slashes "/" as path delimiter, no leading slash. e.g. If the application root of
your website is C:\Inetpub\wwwroot\demo and you enter "data/" in this textbox, the folder for the database will be
C:\Inetpub\wwwroot\demo\data.
2. PHP COM extension is required on the web server. As of PHP 5.5, the COM extension requires php_com_dotnet.dll to be
enabled inside of php.ini in order to use these functions. Previous versions of PHP enabled this extension by default. Read
http://php.net/manual/en/book.com.php.

4. Microsoft SQL Server

Notes

1. If you have installed SQL Server 2012 Native Client (x86) on your computer, then Microsoft SQL Server database type will be
available for selection. You can use this database type for connection to SQL Server 2000, 2005 or newer. You can download
SQL Server 2012 Native Client from the Microsoft website. See System Requirements. The native client must also be installed
on the web server. (ODBC or the old OLE DB provider for SQL Server are NOT supported.)
2. PHPMaker connects to the SQL Server by TCP/IP (NOT Windows authentication), make sure TCP/IP protocols is enabled for
your SQL server, you can use SQL Server Configuration Manager to check and configure.
3. If the SQL Server is a remote server (not on the same machine as PHPMaker), make sure your SQL Server allows remote
connection, you can use SQL Server Management Studio to check and configure.
4. If you have firewall enabled on the server, make sure it allows inbound traffic on port 1433 for TCP/IP. If the SQL Server uses
another port number, make sure you have set up the firewall rules accordingly. 

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 5 of 168

• Select Microsoft SQL Server as database type,


• Enter the name or IP of the SQL server,
• Enter the User ID and Password,
• Select the database you want or just enter the name of your database,
• Click the Connect button to load the database information.

Notes
1. If Microsoft SQL Server 2005 or newer, make sure the server name includes the instance name, if any, e.g.
localhost/SQLEXPRESS.
2. The server name or IP should be valid on your production Web server also. Otherwise you'll need to modify the generated
connection string in ewcfg*.php before you upload it to your production server. For example, if you have a testing SQL Server
installed on the same computer, you can use "(local)" as server name when you connect to it with PHPMaker. The generated
scripts will then try to connect to a SQL Server on the same computer as the production Web server, if this is not the case on
the server, the connection will fail. It is common that SQL Server is installed on a different server in production environment.

5. Oracle

Note If you have installed Oracle client on your computer, this database type will be available for selection. You can download
Oracle client from the Oracle website. Make sure the path of your Oracle client (e.g. oci.dll) is among the Path variable under
Windows Environment Variables -> System variable.

• Select Oracle as database type,


• Enter the Oracle Service name,
• Enter the User ID and Password,
• Select the Schema you want or just enter the Schema name,
• Click the Connect button to load the database information.

Note The service name should be valid on your production Web server also. Otherwise you'll need to modify the generated
connection info in ewcfg*.php before you upload it to your production server. The service name must be set to the appropriate
Net8 name which is known to the naming method in use. For example, for Local Naming, it is the alias in the tnsnames.ora file; for
Oracle Names, it is the Net8 Service Name.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 6 of 168

6. SQLite

• Select SQLite as database type,


• Select the SQLite database file by clicking the button,
• Specify the database path where the database file will reside under the your application root,
• Click the Connect button to load the database information.

Load from Project File

If you previously saved your project file (.pmp file), you can load it back by clicking the open button on the tool bar (or select "Project",
"Open" from the menu bar). At completion, the tables and fields information will be loaded and displayed on the left pane.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 7 of 168

The database pane is dockable. If you prefer to display the database pane on the right hand side, simply drag it to the right side.

Dynamic Table Loading

By default all tables in the database are loaded. It is convenient but loading and sychronization could be slow if your database contains a
large number of tables or fields. If this option is enabled, a table will only be loaded when you select it in the database pane. If you just
use a few tables out of a large database, this feature enables you to work much faster than before. To enable this feature, simply check
[Load tables dynamically] BEFORE pressing the [Connect] button.

 ©2002-2019 e.World Technology Ltd. All rights reserved.

PHP Settings

General Options

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 8 of 168

No Cache Whether caching is required on browser

Multi-Language Enable multi-language project. If enabled, a combobox will appear on the top of the generated scripts for user to
select language. See Tools for selecting languages for the multi-language project.

Important
1. Multi-Language project must use utf-8 encoding. The charset of the project must be "utf-8".
2. The data in your database must be stored in unicode, otherwise your data will not be displayed
properly.

Default Language Default language of the project. It must be compatible with Charset (see HTML Settings). Default is English.

There is always one default language for a project. Only the English language file (english.xml) is shipped with
PHPMaker. If your project is single language but you use another language, create a language file for your language
(see Making Language Files), put it in the "languages" subfolder under the installation folder and then select your
default language using this combobox.

If you enable Multi-Language, you must select one of the selected languages as the default language.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 9 of 168

File Upload

Upload folder - The global folder where the uploaded files resides. If you do not enter a specific folder for a file
upload field in the Edit Tag panel of the Field Setup page, all the uploaded files will be put in this folder.

Notes
1. Always specify an upload folder if you allow file upload. This folder is used as the root folder of
temporary folders for file upload fields during Add/Edit. It is also used as the root folder of the user files
folder of CKEditor.
2. Unlike the field specific upload folder setting (which is a PHP expression), this field specific setting
must be a constant string (without double quotes). If you want dynamic upload folders for different
fields, specify upload folder for each field (see Field Setup).
3. The path is relative to application root. Use slashes "/" as path delimiter, no leading slash. e.g. If the
application root of your website is C:\Inetpub\wwwroot\demo and you enter "uploads/" in this textbox,
the folder for the uploaded files will be C:\Inetpub\wwwroot\demo\uploads. If you are not sure which
folder is application root, please read Application Root. If for some reasons you must use another
absolute path, use the Advanced Setting File upload path (absolute) for temporary files.
4. The path supports AWS S3 bucket, e.g. you can enter "s3://my-bucket/" (no double quotes). (In this
special case, the path is not relative to application root.) To use S3 bucket, make sure you register the
Amazon S3 Stream Wrapper in the Global Code server event. If you use S3 bucket, it will also be used
as upload folder for temporary files. If you are only using S3 but your website is not hosted by AWS, you
may want to use a local upload folder on the same server as the web server for better performance,
then you can also use the Advanced Setting File upload path (absolute) for temporary files.
5. Make sure that the Web server user have read/write access to the folder. If you use S3 bucket, note
that the uploaded files in the bucket are not public by default. Remember to configure bucket
permissions so that the uploaded files are accessible by users.

Max File Size - Maximum file upload size in bytes. If <= 0, there is no checking on file size.

Notes File upload also depends on your PHP, web server and database configuration:

1. PHP - Check your php.ini, related configurations are file_uploads, upload_max_filesize, upload_tmp_dir,
post_max_size, max_input_time, memory_limit, and max_execution_time directives in php.ini.
2. Apache - If you use Apache web server, check LimitRequestBody directive.
3. MySQL - Check the max_allowed_packet setting in your MySQL configuration.

Allowed file types - The allowed file extensions of the uploaded files. Separate the file extensions (without ".") by
comma without space, e.g. gif,png,png. If blank, all file types are allowed.

Delete file on update/delete - Option to delete the uploaded file when the field value is replaced, removed or if
the record is deleted.

Note If Delete file on update/delete is enabled, the uploaded file will be deleted. If the deleted record is a
copied record, deleting the uploaded files will affect the original record. To prevent such possible problem,
enable Advanced Setting Create upload file on copy (see Advanced Settings) to duplicate the uploaded file
when copying a record.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 10 of 168

Audit Trail

You can choose to log activities in a log file or in a database table.

Log file folder - The folder where the audit trail log file resides.

Notes
1. Make sure that the Web server user have read/write access to the folder.
2. The path is relative to application root. Use slashes "/" as path delimiter, no leading slash. e.g. If the
application root of your website is C:\Inetpub\wwwroot\demo and you enter "uploads/" in this textbox,
the folder for the log file will be C:\Inetpub\wwwroot\demo\uploads. If you are not sure which folder is
application root, please read Application Root.

Use database table - Log the activities in the specified table instead of log file. The table must have the following
fields: (actual data types depend on database type)

• DateTime (DateTime)
• Script (VarChar)
• User (VarChar)
• Action (VarChar)
• Table (VarChar)
• Field (VarChar)
• KeyValue (Long VarChar)
• OldValue (Long VarChar)
• NewValue (Long VarChar)

You can create the database yourselves and select the table in the combobox, then click the [...] button to select
the fields in your table. Alternatively, if you have not created the table yet, you can click [Create Table] and let
PHPMaker creates the table and setup the settings for you.

Track login/logout activities - If security feature is enabled, login/logout activities will also be logged.

Validation

Server-side - Enable server-side form validation.

Client-side (JavaScript) - Enable client-side form validation.

Note If the available validation format in the Edit Tag panel (see Field Setup) does not fulfil your
requirements, you can use your own server-side and/or client-side validation code using Server Event and
Client Scripts.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 11 of 168

Page Options (Global)

The following page options are global for all tables. If you want different settings for a particular table, you can use table-specific options
available in the Table Setup page.

Records per page Number of records to be displayed on the list page of all tables. If blank or 0, default setting
of 20 will be used.

Selectable page sizes Number of records to be selected by user. Comma separated values, e.g. 10,20,50,ALL.

Note "ALL" (without quotes) is supported, other values must be integers.

Paging section style "NumericPages" or "NextPrev"

Sort type None, Single column or Multiple column. If Multiple column is selected, the generated
list page supports multi-column sorting by Ctrl-clicking the table header.

Multiple column Show multiple records per row. Default is 0. This feature will only take effect if the value is >
0. Possible values: 1, 2, 3, 4, 6, 12

Paging section at top Show the paging section at top (also applies to View page)

Paging section at bottom Show the paging section at bottom (also applies to View page)

Paging section in View page Show paging section in View page also

Paging section in Edit page Show paging section in Edit page also

Multiple delete Show checkboxes in the list page for selecting multiple records to delete

Links on left side Show the links in record row on the left instead of right

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 12 of 168

Use buttons as links Show the links in record row as a button group instead of individual icons or links.

Use button dropdown for links Show the links in record row as a button with dropdown menu instead of individual icons or
links.

Use button dropdown in paging section Show the links in paging section as buttons with dropdown menu instead of individual links.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 13 of 168

Export Enable export in List page - allow export in List pages

Enable export in View page - allow export in View pages also

Use button dropdown - show the export links as a button with dropdown menu. Default is
showing the export links as a row of icons.

Print/CSV/HTML/Excel/Word/XML/PDF/Email - Records can be exported to Print


(printer-friendly), CSV, HTML, Excel, Word, XML, PDF format or sent as HTML email content.

Note The fields in printer friendly version are same as in List/View page, while the
fields in other format are determined by the Export setting of the field in Field Setup
page.

Note that the fields in printer friendly version are same as in List/View page, while the fields
in other format are determined by the Export setting of the field in Field Setup page.

Export type - Determines which records to export. The follows are supported:

• All Pages - Records in all pages are exported


• Current Page - All records in current page are exported
• Selected Record - If selected, a checkbox will be displayed in each row for selection.
Only selected records in the current page are exported. (Selecting records in different
pages is not allowed.) To select records primary key is required, Current Page export
type will be used for tables without primary key.

Notes
1. Binary data (BLOB fields) cannot be exported.
2. Export to HTML/CSV/XML/PDF are not applicable to reports.
3. Export to XML requires PHP DOM (which should be already enabled by default).
4. Export to Word/Excel works by exporting data in HTML format for Word/Excel to
convert/import, the exported file is not native .doc/.xls format. However,
registered users can use the PhpSpreadsheet/PHPWord extension which outputs
native Excel/Word file format.
5. Images cannot be exported to Word/Excel/CSV/XML. However, registered users
can use the PhpSpreadsheet/PHPWord extension which outputs images also.
6. Export to PDF (for all users) and PhpSpreadsheet/PHPWord extensions (for
registered users) support images (jpg, gif and png only), but a temporary folder
is required during export, the extensions use the Upload folder (see File
Upload above) because write permission for the folder should be already setup
properly. Even you do not use file upload to folder, if you want to export with
images, make sure you still specify an upload folder and set up write permission.

Notes (Export to PDF)


1. The extension is an experimental extension only. There are known issues, see
Third-party Tools and read the note in the extension setup page (see Tools ->
Extensions) for more information before use. Only enable it if necessary.
2. The extension performs best if you are using non-unicode alphanumerical
characters (e.g. iso-8859-1) only. If you use unicode, configure advanced settings
for the extension, read the note in the extension setup page (see Tools ->
Extensions) for more information.
3. By default export is only enabled in View page. If you want to enable it in the List
page also (the number of records to be exported is not large), you can set the
advanced settings of the extension (see Tools -> Extensions).

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 14 of 168

Email Settings

PHPMaker supports many features that can send emails. If you use these features, you'll need to specify a SMTP server.

Note PHPMailer (see Third-party Tools) is always used as the email component.

SMTP server The host name or IP of the SMTP server.

Note Some servers do not support "localhost" as SMTP server, in such case you need to specify a
valid SMTP server in the network.

SMTP server port Port number of SMTP server. Default is 25.

SMTP server username User name for SMTP server authentication. If your SMTP server does not require authentication, leave it
blank.

SMTP server password Password for SMTP server authentication. If your SMTP server does not require authentication, leave it
blank.

Sender (Email address) Email address of the sender of all emails

Recipient (Email address) Email address of the recipient(s) for notification emails when a record is added/edited/deleted (if enabled,
see Table Setup). If there are multiple recipients, separate them by comma.

Security Protocol used by the SMTP server. Possible values are: SSL or TLS.

Notes

1. Leave this setting empty if your SMTP server does not use such protocols.
2. If you enable this, make sure you have enabled OpenSSL support in your php.ini, see
Introduction to PHP and MySQL.
3. If you use gmail, read Allowing less secure apps to access your account.

 ©2002-2019 e.World Technology Ltd. All rights reserved.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 15 of 168

HTML Settings
General

Title Title of the website.

Note If you use Multi-Language (see PHP Settings), use Multi-Language Property Editor, see Tools for details.

Charset Charset of the website. Always use utf-8 whenever possible.

Note If you use Multi-Language (see PHP Settings), this setting must be utf-8.

Font Default font. If not specified, Bootstrap (see below) @font-family-sans-serif will be used, default is: "Helvetica Neue",
Helvetica, Arial, sans-serif.

Size (rem) Default font size (rem). Unit must be in rem for working with Bootstrap 4 (see below). Default is .875rem.

Site icon Icon of the site. For browsers to show your URL with an icon. Should be an .ico file.

Brand Logo image or text in the header.


logo/text
Note This setting is enabled in registered version only.

Brand href URL of the brand logo image or text in the header.

Note This setting is enabled in registered version only.

Footer text Footer text (e.g. copyright statement)

Notes
1. If you use Multi-Language (see PHP Settings), use Multi-Language Property Editor, see Tools for details.
2. This setting is enabled in registered version only.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 16 of 168

Theme

Provides over a dozen of themes for you to setup the look and feel of your project quickly.

Themes are integrated with Bootstrap and AdminLTE, you can customize Bootstrap and AdminLTE properties directly in the Theme tab,
scroll down to find the Bootstrap or AdminLTE variables starting with "$".

You can change the various properties of the selected theme to suit your style. The property name are self-explanatory. Read Theming
Bootstrap for more information.

To export custom theme settings, click the [Export theme] button to export the theme to an external xml file. To import custom theme
settings from earlier saved xml files, click the [Import theme] button.

Notes

1. Changing a setting in the user interface does not change the corresponding setting in the theme definitions, it only changes
the setting for the project. The theme definition files (in XML format) are installed in the subfolder "themes" under the
installation folder. You can easily add your own themes by duplicating one of the theme definition file (e.g. plain.xml), rename
it and modify the settings in the file, just make sure you give your theme an unique theme name.
2. AdminLTE builts on top of Bootstrap, some AdminLTE settings change the default value of the corresponding Bootstrap
variables.
3. After changing theme properties, make sure you re-generate all *.css files.

Styles

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 17 of 168

The CSS styles under the System tab are styles generated for the project. The CSS styles under the User tab are your own CSS styles. You
can enter your styles directly in the editor.

Compile styles Complie user styles.

User styles Supports Sass, you can use Bootstrap and AdminLTE variables (starting with "$") in your code. After
entering your styles, press this button to test, PHPMaker will try to compile your styles and show it in the System tab
between BEGIN_USER_STYLES and END_USER_STYLES.

Notes

1. If you want to override the system styles, you can copy the styles to the User Styles Section, or you can use
a separate user stylesheet.
2. If you want to change the system stylesheet template, modify the ew.scss in the "themes" subfolder under
the installed directory. Only modify the ew.scss if you have the necessary knowledges in Sass.

User Stylesheet Specify an external user stylesheet (will be copied across during generation)

You can see the effect of new settings immediately in the preview window at the bottom of the HTML tab.

Note The preview window shows the layout and table colors only, it cannot show changes in all variables. If you want to preview
more, you can customize the file ew.htm installed under <Installed Folder>\themes\preview.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 18 of 168

 ©2002-2019 e.World Technology Ltd. All rights reserved.

Security Settings

Field Description:

Administrator Login (Hard-Coded) Administrator user id and password

Login Name Login Name for administrator

Password Password for administrator

Use Existing Table Link to existing table for login name and password validation

Table Existing table in database containing login name and password information

Login Name Field Login Name field in table used for authentication

Password Field Password field in table used for authentication

Login Option Login options in the login page:

Remember me (Auto-login) - Auto login until the user logout explicitly

If enabled, a "Remember me" checkbox will be shown in the Login page, a few cookies will be
placed on the user's computer to identify the user, meaning that the user do not have to type
username and password every time he/she visit the site. You should advise your users not to use
this feature on a public or shared computer.

Advanced Security

Advanced Security feature allows you to setup User ID, assign User Levels to users and create a complete user registration system. To

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 19 of 168

setup, click the [Advanced] button.

PHPMaker supports two types of security - User ID and User Level. User ID Security secures data at record level. User Level Security
secures data at table level. They complements each other and they can work independently or together. Users get their User ID and User
Level after login. Before login, an user's identity is unknown and the user is an Anonymous User.

User ID
User ID Security secures data at record level. Protected tables must have an User ID field for identifying which user a record belongs to.
The User ID field names can be different in tables though. When User ID security is enabled, users can only access their own data.

Steps to setup User ID security for different tables/views:

1. Click on User ID in the left pane.


2. Select the [User ID field] from your user table, this field is usually the primary key of the User Table. (Note: if this field is not set, the
feature is disabled)
3. (Optional) Select the [Parent User ID field] from your user table. Parent User ID field stores the parent User ID that the user
belongs to, parent user can modify the child user's records. Parent User ID is hierarchical, parent users can access the records owned
by the child users of their child users. (Note: if this field is not set, the Parent User feature is disabled.)
4. In the [User ID Field] column, select the User ID Field for the tables/views that requires User ID security.
5. (Optional) Enable [Allow View All] if you allow all logged in users (not including Anonymous User) to list/search/view (but not
add/copy/edit/delete) all records in the table.

User Level
User Level Security secures data at table level. Each user level is granted with specific permissions to tables in the database.

There are 2 types of User Level security:

1. Static User Levels - the User Levels and the permissions are defined in this form and the User Levels are not to be changed after script
generation.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 20 of 168

Steps to setup static User Level security for different tables/views:

1. Click on User Levels in the left pane,


2. Select an integer field in your user table as the [User Level field], (Note: if this field is not set, the feature is disabled)
3. Define your user levels, click icon the add an user level and icon to delete an user level.

2. Dynamic User Levels - the User Levels and the permissions are defined in 2 tables in the database, the User Levels can still be changed
with the generated scripts.

Steps to setup dynamic User Level security for different tables/views:

1. Click on User Levels in the left pane,


2. Select an integer field in your user table as the [User Level field],(note: if this field is not set, the feature is disabled)
3. Switch to the [Dynamic User Levels] tab, check [Enable Dynamic User Levels],
4. Select your User Level Table and User Level Permission Table and the required fields.

The User Level Table and User Level Permission Table must have the following fields, note the data types, User Level ID and the
Permission fields must be of integer type, the field names can be different though:

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 21 of 168

If you want PHPMaker to create these 2 tables in your database, click the [Create tables] button, the following form will display for you to
change the table/field names if necessary. You can change the table/field names and then click OK to continue.

If you have projects created by previous versions of PHPMaker you may want to use dynamic User Levels and migrate the previously
defined static User Levels in the project to the database. After selecting or creating the User Level and User Level Permission tables/fields,
just click the [Migrate] button to let PHPMaker do that for you.

After setting the user levels, PHPMaker will populate the user levels to the User Level field's Edit Tag (also see Field Setup) so
administrators can assign user levels using the generated pages.

There are three built-in user levels:

Anonymous - Anonymous user level is a built-in user level for the anonymous user (i.e. users that have not logged in). The User Level ID
of the anonymous user is -2.

Administrator - Administrator user level is a built-in user level that has all permissions plus the privileges to modify User IDs and User
Levels. Its permissions are same as that of the hard-coded Administrator. The User Level ID of Administrator is -1.

Default - Default user level is built-in user level with user level = 0. Since User Level field is an integer field, if you set a default value of 0
for this field, this user level will become the default user level for the user after registration and before the Administrator assigning
another higher user level.

Important Notes on User Levels


1. Even you enable all permissions for an user defined User Level, the User Level will NOT become same as this Administrator
User Level.
2. From v9, the permissions for List/Search/View are separate in newly created projects. However, for backward compatibility, the
permissions for List/View/Search in converted projects (created by previous versions) are the same unless you have enabled
Separate permissions for List/View/Search in Advanced Settings.
3. You may need to use the hard-coded Administrator Login to log on and assign dynamic user levels to users initially.
4. 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 automatically fulfilled.
However, if the projects use different databases, you need to use Database_Connecting server event to change the connection
info so the user can get the Dynamic User Levels from the common Advanced Security tables correctly during login. For the
projects not using the database with the common Advanced Security tables, you still need to create dummy Advanced
Security tables (with same table/field names as the common Advanced Security tables) in the project database so you can
setup Advanced Security.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 22 of 168

From v2019+, administrators can enable users to (partially) administer user level permissions by performing the following
steps:

1. Login as hard-coded administrator, go to the user level table and click the Permissions button for the required user level,
e.g. the Administrator user level.
2. Check the Admin checkbox for the required tables so that users from this user level can administer these tables.
3. Make sure that you have enabled the List and Admin checkboxes for the user level table for this user level as well or users
from this user level cannot see and admin the user level table.
4. Click Update to save the settings. Users from this user level can then administer the specified tables in their next login. They
can in turn grant Admin permission to other user levels so that other user levels can also manage the user level
permissions of this user level as well.
5. Note that users can only grant permissions that they have. For example, if they have only permissions to list/view/admin
for the cars table, they can only grant list/view/admin permissions (but NOT any other permissions) to other user levels.
6. Alternatively, use UserLevel_Loaded and TablePermission_Loaded server event (see Server Events and Client Scripts) to call
the setCanAdmin() method to grant Admin permission.

User Login Options


User Login Options allows you to create a complete user registration system for your Web site, with options to let user register, change
password and recover password.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 23 of 168

Login

Track failed attempts If enabled, number of failed login attempts (invalid password) will be tracked. If exceeded,
the user will be locked out and the password must be reset.

Maximum failed attempts The maximum number of failed login attempts

Failed attempts windows (minutes) The time window, in minutes, during which failed password attempts are tracked.

Disallow concurrent login If enabled, only one session is allowed for each user (except the hard-coded Administrator).
If one user has already logged in, other users trying to login with the same username (and
password) will be rejected.

Note Users are distinguished by Session ID as recognized by the web server. If you
login again with your PC in another window of the same browser or in just another
tab of your browser, you can still login. If you login again with another browser or
another PC, the Session ID will be different and the login will be rejected.

Maximum concurrent user session count For use with Disallow concurrent login. By default only one session is allowed for each
user. But you may want to give more than one chance to user so they will not be rejected
after unexpected incidents such as a system crash.

Note Please be reminded that this option somewhat compromise the Disallow
concurrent login feature. Use this option discreetly and always use the smallest
possible value.

Login status timeout (minutes) The number of idle minutes after which the login status will be considered as logged out
and login will be allowed again.

If a logged-in user does not explicitly log out (for example, close the browser directly), the
user session is not closed and the user's login status will remain as "logged in". Attempts to
login again will fail. This timeout setting ensures login will be allowed again after a period
of idle time.

CAPTCHA (requires extension) Optionally requires user to type letters or digits from a distorted image that appears on the
screen..

Note Requires CAPTCHA extension, click Tools -> Extensions from the main menu
to enable. Also see Third-party Tools.

Password

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 24 of 168

Hashed password Use hashed password. If the advanced setting Use password hash is enabled,
password_hash will be used to create password, otherwise md5 will be used.

Notes
1. If you enable this setting, make sure that the passwords in your user table are
stored as the corresponding hash of the clear text password. If you also use
case-insensitive password, convert the clear text passwords to lower case first
before calculating the hash. Otherwise, existing users will not be able to login.
The hash is irreversible, password will be reset during password recovery.
2. PHPMaker will try to detect salted password created by other application.
(PHPMaker itself does NOT create salted password.) If salted, the password
must be stored in '<hashedstring>:<salt>' format, and the hashed string must
be the md5 hash of the concatenated string of the clear text password and the
salt. Other salt algorithm is not supported, you can however customize the
function EncryptPassword() in the template to suit your application.
3. If you enable the advanced setting Use password hash, the password field in
the user table should be able to store more than 60 characters (255 characters
would be a good choice).

Case-sensitive password Use case-sensitive password

Enable password expiry If enabled, user password will expire after a period of time (except the hard-coded
Administrator password)

Password expiry time (days) For use with Enable password expiry, user password will expire after the specified number
of days

User Registration Page

Enabled Generate user registration page and add a link in login page.

Fields Select fields (from the user table) to show in the registration page. Click the [...] button the
select the fields.

Confirm before submit Optionally send email confirmation after registration

Send registration email Optionally send email confirmation after registration

Requires activation Optionally requires user click an activation link in the email sent after registration to
activate the user account.

Note Send email must be enabled for sending the email with activation link.

Auto login after registration/activation Optionally auto-login the user after registration or activation.

Note Requires activation is enabled, the user is not activated yet after registration,
auto login will be applied when the user clicks the activation link in the email.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 25 of 168

CAPTCHA (requires extension) Optionally requires user to type letters or digits from a distorted image that appears on the
screen..

Note Requires CAPTCHA extension, click Tools -> Extensions from the main menu
to enable. Also see Third-party Tools.

Change Password Page

Enabled Generate change password page

Send email Optional email confirmation after changing password

CAPTCHA (requires extension) Optionally requires user to type letters or digits from a distorted image that appears on the
screen.

Note Requires CAPTCHA extension, click Tools -> Extensions from the main menu
to enable. Also see Third-party Tools.

Password Recovery Page

Enabled Generate password recovery page (forgot password page) and add a link in login page.
User name and password will be sent to the user's email address.

CAPTCHA (requires extension) Optionally requires user to type letters or digits from a distorted image that appears on the
screen.

Note Requires CAPTCHA extension, click Tools -> Extensions from the main menu
to enable. Also see Third-party Tools.

User Table Fields

Email address field Email address field in user table used for sending email

Activated field Email activated field in user table used for storing the status of user. A boolean field is
recommended, although an integer field or a string field will also work.

Notes
1. To enable user account activation, the Requires activation and Send email
options under User Registration Page must be checked. The user needs to
click an activation link in the email sent after registration to activate the user
account.
2. If enabled, make sure the activated field for existing users in your user table is
updated with your activation values (e.g. True/False, 1/0, Y/N) or the existing
users cannot login because they are not recognized as activated. You can
enable Multi-Update feature for the user table so administrators can activate or
deactivate existing users easily.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 26 of 168

Profile field A memo field for persisting all the additional user information. This field is required if the
following options are used:

• Track failed attempts


• Disallow concurrent login
• Enable password expiry

Note The field is also required if the advanced setting Search filter save option is
set to Server, see Tools -> Advanced Settings.

User Table List Page Options

Reset concurrent user session count If enabled, a new option is generated in the User Table list page for the administrator to
reset the concurrent user session count for an user to 0

Reset login failed attempts If enabled, a new option is generated in the User Table list page for the administrator to
reset the login failed attempts for an user to 0

Reset login failed attempts If enabled, a new option is generated in the User Table list page for the administrator to
reset the login failed attempts for an user to 0

Set password expired If enabled, a new option is generated in the User Table list page for the administrator to set
the password of an user as expired

Resend registration email If enabled, a new option is generated in the User Table list page for the administrator to
resend the registration email to an user

Email Template

The email sending function and the email contents can be customized in the template. The following special tags are used in the email
templates:

<!--$From--> is sender email address


<!--$To--> is user email address
<!--$Password--> is user password
<!--FieldName--> (without the $ symbol) is the field value. For example, <!--LastName--> is the field value of the field "LastName".

You can also dynamically change the email by code using Email_Sending event before the email is sent. (See Server Events and Client
Scripts)

Email Templates for Multi-Language projects To set up email templates for Multi-Language projects, read the topic Tutorial -
Multi-Language Project Setup

Also See:

Tutorial - User ID Security


Tutorial - Static User Level Security
Tutorial - Dynamic User Level Security
Tutorial - User Registration System
Tutorial - Multi-Language Project Setup

 ©2002-2019 e.World Technology Ltd. All rights reserved.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 27 of 168

Generate Settings

Template file Template archive (zip file)

Application root folder The root folder of the PHP application. (See Application Root for more info on application root)

Destination folder The destination folder where the PHP scripts are to be generated. The folder is usually same as the
application root folder or a subfolder under the application root folder.

Output filename None - no prefix/infix/suffix is added


Prefix - a prefix is added to all output file names
Infix - an infix (between table name and page ID) is added to all table-specific file names
Suffix - a suffix is added to all output file names

Prefix/Infix/Suffix The string to be concatenated to output file names when the Prefix or Infix or Suffix option is specified

Lowercase Specify whether output file names are in lowercase

Start page Specify the first page that the default page (index.php) should redirect users to.

If this setting is left blank, user will be redirected to the List page of the default table (see Table Setup) or the
first table that the user have permission to access.

If this setting is not blank, the default page will simply redirect user to the page you specify, e.g. a page not
generated by the current project or a custom file.

Note If you start the site by the typical index.php, leave this setting blank, do NOT enter index.php or
there will be a indefinite loop.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 28 of 168

Composer update Specify whether to call composer update after generation. By default PHPMaker will call it automatically when
necessary, but sometimes you may want to call it explicitly by checking this option..

PHPMaker uses Composer which is a tool for dependency management in PHP. It allows you to declare the
libraries your project depends on and it will manage (install/update) them for you.

Make sure you have installed Composer using Composer-Setup.exe before generating your project. It will
install the latest Composer version and set up your PATH so that you can call composer from any directory in
your command line. After installation, open a command prompt and test Composer by entering:

composer -V

If Composer is installed properly, you should see the version number, e.g. Composer version 1.6.2 2018-01-05
15:28:41.

Note Close your current command prompt. Test usage with a new command prompt. This is important
since the PATH only gets loaded when the new command prompt starts.

Testing web server Specify the web server that you want to use to test the generated site. For use with Browse after generation
(see below). You can choose PHP (built-in web server) or Other. Requires PHP >= 5.5 and php.exe installed
on the same machine as PHPMaker.

The PHP built-in web server was designed to aid application development, read the PHP manual for more
information. PHPMaker will try to find the php.exe on your machine, but you can also specify it and the web
server port in advanced settings. If enabled, PHPMaker will run the web server at the Application root
folder, e.g.

"C:\Program Files (x86)\PHP\php.exe" -S localhost:<port>

If you choose Other web server (e.g. if you use IIS or Apache), you need to specify Testing root URL (see
below) also.

Browse after generation Specify whether to open a browser to test the generated site after script generation.

Testing root URL Specify the URL of your testing site that maps to the Application root folder (see above). For use with
Browse after generation. If you use PHP, this setting is NOT required.

For example, if you have set up a website like:

Application root folder: C:\Users\Administrator\Documents\mycompany.com

Destination folder: C:\Users\Administrator\Documents\mycompany.com\project1

and you have setup your testing website's document root at the application root folder, so that you browse
the main site by:

http://localhost/

and browse the PHPMaker generated site by:

http://localhost/project1/

Then the Testing root URL should be:

http://localhost/

(NOT http://localhost/project1/, which points to the Destination folder).

PHPMaker will calculate the relative path and add "project1/" to the Testing root URL when opening the
browser.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 29 of 168

After setting above, click the [Generate] button to generate scripts. PHPMaker allows you select scripts to generate, just select the files
you want to generate in the [Output] column. If you want include PHPMaker scripts into your custom PHP scripts, you may not want to
generate header and footer in those pages. Then you can enable [No header/footer] for those pages. Note that header/footer means
the header row containing the site header logo and the footer row containing the site footer text.

After selection, click the [Generate] button to generate scripts.

If you modify settings for a table and want to re-generate script for that table only, you can click [Unselect All], then select the files you
want to re-generate and click the [Generate] button to generate again. If you are not sure which files to re-generate, click [Select All]
and re-generate all files.

You can also right-click the column header of [Output] or [No header/footer] to quickly select all or unselect all items in the column.

Notes

1. If it is your first generation or you have changed some project level settings, you must select [Other files] to generate the non
table-specific pages.
2. You can press F9 to skip above form and generate all scripts.
3. You can press Ctrl + F9 to skip above form and re-generate previously selected scripts.

If you need to abort script generation in the middle of the process, just click the [Cancel] button under the progress bar that displayed
during generation.

Also See:

Customizing Template
Project File

 ©2002-2019 e.World Technology Ltd. All rights reserved.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 30 of 168

Table Setup
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, a report or a Linked Table.

After loading the database, the tables will be shown in the database pane on the left pane. To access ALL setting for a table (including
Multi-page, Table-specific Options and Master/Detail), click the table node of any table in the database pane and then click the [Table]
tab to go to the Table Setup page. This is the setup page for a single table.

You can also click on the [Tables] or [Views] or [Custom Views] or [Reports] or [Linked Tables] node in the database pane to go to the
Tables Setup page which is a grid showing the most frequently used settings for all tables. If you need to set these settings for multiple
tables, this page allow you to view and set them quickly. Note that this page does not include Multi-page, Table-specific Options and
Master/Detail.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 31 of 168

Notes
1. For all checkbox or combobox columns, if you want to apply the setting to ALL tables or views, you can choose your setting at
the [Tables] or [Views] or [Custom Views] or [Reports] or [Linked Tables] row.
2. View/Edit/Search functionality works at field level and can be setup for each field in the Field Level Setup page. Please refer to
the Field Setup for details. If all fields are not selected for View/Edit/Search, the function will not be generated.

If you prefer to view the tables in alphabetical order, click [Tools]->[Sort Tables Alphabetically] (see Tools).

You can still change the display order of the menu item by drag-and-drop. Select a table by clicking the first column - [Table/View
Name] column, then drag and drop to where you want. Note that a table cannot be moved out of its parent node.

Note that changing the display order of table in this Table Setup page does not change the display order of the tables in the menu. To
change the display order of the menu item, click [Tools]->[Menu Editor] (see Tools).

Important
1. It is assumed that all tables have primary key. (Composite key is supported) If there is no primary key specified,
View/Add/Copy/Delete/Edit/Update settings have no effect and will be reset to disabled when the [Generate] button is
pressed. Only the List page can be generated. If you add back a primary key later, you'll need to come back to this page and
re-enable them. Since reports are read-only, View/Add/Copy/Delete/Edit/Update settings are not applicable to reports.
2. Views or Custom Views involving more than one table are usually NOT updatable. Although you can force PHPMaker to
enable the Add/Copy/Delete/Edit/Update pages by specifying a primary key, the generated pages will not work if these views
or Custom Views cannot be updated like regular tables.

The available table level settings are as follows:

General

Generate Select/unselect a particular table for generation

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 32 of 168

Caption To change the caption of a table, click on [Caption] box to make the necessary change.

Note If you use Multi-Language (see PHP Settings), use Multi-Language Property Editor, see Tools for
details.

Filter Specify a filter (WHERE clause) for the table. Click the [...] button in [Filter] column, the Filter Editor will popup.
Enter your filter, you can drag the field names from the left pane to the editor, the SQL identifier quote characters
will also be added for you automatically.

Note The filter must be a valid PHP expression and it will be concatenated to the SQL. If it is a string, it
should be double quoted.

Sort Specify the sort fields (ORDER BY clause) for the table. Click the [...] button in [Sort] column, the following dialog
box will popup. You can choose up to 6 fields, in either ascending or descending order.

Output folder For use with Custom File only. The output folder is relative to application root.

Include custom files For use with Custom File and for PHP file only. Include common files such as header and footer so the custom
file will have the same layout .

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 33 of 168

Default Set a Table as the Default Table. The Default table is the first table the user see when visiting your site. Select the
table you want in the [Default] column.

List

Inline Add Enable/disable Inline Add function for the table. Inline Add allows users to add a record within the List page.
Default is disabled.

Inline Copy Enable/disable Inline Copy function for the table. Inline Copy allows users to copy a record within the List
page. Default is disabled.

Inline Edit Enable/disable Inline Edit function for the table. Inline Edit allows users to edit a record within the List page.
Default is disabled.

Grid Add Enable/disable Grid-Add function for table. Allows users to add multiple records to the table. Default is
disabled.

Grid Edit Enable/disable Grid-Edit function for table. Grid-Edit allows users to edit multiple records within the List
page. Default is disabled.

Import Enable/disable Import function for table. The Import feature enables you to import records from an external
Excel/CSV file to database table. Default is disabled. Read Import Data for more information.

Requires Search Criteria Specifies if the List page requires search criteria. Default is disabled.

Notes
1. If enabled, the List page always requires search criteria. When the page is initially loaded, no
records will be displayed until searching is done. (Remember to enable Quick Search, including
Extended Quick Search, or Advanced Search or both. See below.)
2. If a record is added but the new record does not meet the search criteria (or there is no search
criteria yet), the record will not appear in the List page. So this option is best for tables which are
for browsing only.

Sequence number Add a column to show the sequence number (record index) of the record in the recordset.

Detail Add Enable/disable Master/Detail-Add function for table (as detail table). Allows users to add multiple records to
the detail table in the Add page of the master table. Default is disabled.

Detail Edit Enable/disable Master/Detail-Edit function for table (as detail table). Allows users to edit multiple records of
the detail table in the Edit page of the master table. Default is disabled.

Detail View Enable/disable Master/Detail-View function for table (as detail table). Allows users to view multiple detail
records in the View page of the master table. Default is disabled.

Multiple Detail Tables Enable/disable multiple Detail Add/Edit/View.

By default each pair of Master/Detail tables are handled separately, meaning that in a page, there are one
master table (the current table) and one of its detail tables only. If this option is enabled, all detail tables will
be displayed together in the same page. Enabling this option will hide separate Master/Detail table pairs.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 34 of 168

Detail Record Count Specifies if the number of detail records for the master record should be displayed. Default is disabled.

Note
1. Applicable to master tables with master/detail relationships defined in PHPMaker only, see below.
2. If the detail table is a report, this feature is NOT applicable, there will be NO detail record counts
for the detail report.
3. The counts are retrieved by using a subquery for each detail table. The more detail tables, the
more performance penalty. You should enable this feature discreetly.

Search

Quick If enabled, Quick Search panel (including Extended Quick Search) will be generated with the List page.
Default is enabled.

Quick Search searches text fields and optionally numeric fields only. These fields are selectable in Field
Setup page. You may want to hide the Quick Search form for tables that do not have searchable fields.

Default value (Quick) Default value for Quick Search.

If no user input for Quick Search, this default value will be used. After users entering their search criteria,
the default value will not be used.

Default search type (Quick) Default search type for Quick Search. Possible values are:

• Any words
• All words
• Exact match

Extended If enabled, Extended Quick Search inputs will be generated in the List page. Default is enabled.

Fields per row (Extended) For use with Extended Quick Search. Specifies the number of fields per row in the Quick Search panel.
Default is 0 (unspecifed), which means one field per row.

Advanced If enabled, an Advanced Search Page will be generated and linked to the List page. Default is disabled.

Modal dialog (Advanced) For use with Advanced Search. Use modal dialog to show the Advanced Search page.

Highlight If this setting is checked, the search criteria in the search result (List page) will be highlighted. Default is
disabled.

View

View If enabled, a View page for the table will be generated (for displaying a record). Default is enabled.

Note The table must have primary key or this setting will be unchecked during generation.

Modal dialog Use modal dialog to show the Multi-Update page.

Add

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 35 of 168

Add If enabled, an Add page for the table will be generated (for adding/copying a record). Default is enabled.

Note The table must have primary key or this setting will be unchecked during generation.

Copy If enabled, Add page will be generated and "Copy" links will be generated for record(s) in List/View page (for copying).
Default is enabled. (If this setting is enabled, the "Add" setting is also enabled by default as copying requires the Add
page.)

Note The table must have primary key or this setting will be unchecked during generation.

CAPTCHA Enable/disable CAPTCHA function for the Add page. Default is disabled. (CAPTCHA requires that the user type the letters
or digits of a distorted image before submitting a form to prevent automated software from posting spam to your web
application.)

Notes
1. Requires CAPTCHA extension, click Tools -> Extensions from the main menu to enable. Also see Third-party
Tools.
2. Not applicable to Inline/Grid-Add/Copy.

Confirm Enable/disable confirmation function for the Add page. Default is disabled. If enabled, there will be a confirmation step
in the Add page, users will be able check their input before actually inserting the record.

Note Not applicable to Inline/Grid-Add/Copy.

Modal dialog Use modal dialog to show the Add page.

Edit

Edit If enabled, an Edit page for the table will be generated (for updating a record). Default is enabled.

Note The table must have primary key or this setting will be unchecked during generation.

CAPTCHA Enable/disable CAPTCHA function for the Edit page. Default is disabled. (CAPTCHA requires that the user type the
letters or digits of a distorted image before submitting a form to prevent automated software from posting spam to
your web application.)

Notes
1. Requires CAPTCHA extension, click Tools -> Extensions from the main menu to enable. Also see Third-
party Tools.
2. Not applicable to Inline/Grid-Edit.

Confirm Enable/disable confirmation function for the Edit page. Default is disabled. If enabled, there will be a confirmation step
in the Edit page, users will be able check their input before actually updating the record.

Note Not applicable to Inline/Grid-Edit.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 36 of 168

Check Conflicts Check if the record is changed by other user before updating the record.

Notes
1. Since processing of current data for later comparison is required, using this feature will increase the time
required to load the page. For better performance only the first hundreds of bytes of the BLOB fields are
processed by default, but there are chances that change of BLOB data is not detected (if the first nth bytes
are not changed). You can increase the number of bytes in Advanced Setting, if you want to process all
bytes, enter 0.
2. You can use the Row_UpdateConflict server event (see Server Events and Client Scripts) to resolve the
conflicts according to your business logic by code.
3. Not applicable to Inline/Grid-Edit.

Modal dialog Use modal dialog to show the Edit page.

Delete

Delete If enabled, a Delete page for the table will be generated (for deleting record or multiple records). Default
is enabled.

Note The table must have primary key or this setting will be unchecked during generation.

Inline Delete (Modal dialog) Use modal dialog to show the deletion confirmation page.

Multi-Update

Multi-Update If enabled, a Multi-Update page for the table will be generated (for updating multiple records). Default is disabled. With
this feature you can select multiple records in the List page and update all records at the same time. You can select
fields (see Field Setup page) to be included in the Multi-Update page.

Note The table must have primary key or this setting will be unchecked during generation.

Confirm Enable/disable confirmation function for the Multi-Update page. Default is disabled. If enabled, there will be a
confirmation step in the Multi-Update page, users will be able check their input before actually updating the selected
records.

Modal dialog Use modal dialog to show the Multi-Update page.

Audit Trail
To use this feature, you must also specify the [Audit Trail folder] or database table and field under [PHP]->[General Options] tab. See
PHP Settings for details.

Audit Trail If audit trail for a table is enabled, when an user add(copy)/edit/delete a record or login/logout, the related information will
be logged in a log file or into the specified database table.

Note By default all add(copy)/edit/delete info will be logged, if you want to select what to log, or want to log
search/view activities also, use the Audit Trail Extension, also see [Tools]->[Extensions].

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 37 of 168

Email Notification
To use this feature, you must also specify the [Email Settings] under [PHP]->[Email Settings] tab. See PHP Setup for details.

On Add If enabled, when an user add a record, an email will be send to pre-set recipient email address(es). Default is disabled.

On Edit If enabled, when an user edit a record, an email will be send to pre-set recipient email address(es). Default is disabled.

On Delete If enabled, when an user delete a record, an email will be send to pre-set recipient email address(es). Default is disabled.

Other than above Tables Setup page, you can also click on a particular table node (under [Tables] or [Views] or [Custom Views] or
[Reports] or [Linked Tables] node) in the database pane to go to the Table Setup page for that table. The Table Setup page includes the
following tabs: Table, Fields, and Server Events/Client Scripts. Click on the Table tab you'll see settings for the selected table only. The
right side includes two panel - the [Table-specific Options] panel and the [Master/Detail] panel (see below), the left side contains
settings same as above (but for the selected table only) and other settings:

Multi-Page

Normally each field is displayed as a table row in the View/Add/Edit page, this Multi-Page features allow you to display divide the fields
into pages and display only one page at a time. To enable, at least one field with page number larger than 1 must be set up in Field Setup
page. This feature is presented as tabs.

Multi-Page type Specifies how to display the pages. Possible values are:

• Tabs - use Bootstrap basic tabs (default)


• Pills - use Bootstrap basic pills
• Accordion - use Bootstrap Collapse

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 38 of 168

Page Labels Specifies the page captions of each page in the Multi-Page. Click the [...] button and enter the page captions and
click [OK] to save.

If page captions are not specified, "Page n" will be used by default. To add a page, go to Field Setup page, specify
the page number for the fields in the page first.

Note If you use Multi-Language (see PHP Settings), use Multi-Language Property Editor, see Tools for
details.

Add page Specifies if Multi-Page is enabled for Add page.

Edit page Specifies if Multi-Page is enabled for Edit page.

View page Specifies if Multi-Page is enabled for View page.

Search page Specifies if Multi-Page is enabled for Advanced Search page.

Registration page Specifies if Multi-Page is enabled for registration page. This setting is only available for the user table specified in
Security Settings.

Return Pages

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 39 of 168

After Add Specifies the return URL after a new record is added. Predefined settings are:

Add Page - returns to the Add page of the current table


Edit Page - returns to the Edit page of the current table
List Page - returns to the List page of the current table (default if the Add page is opened from the List page)
View Page - returns to the View page of the current table (default if the Add page is opened from the View page)

You can also enter your own URL.

Notes

1. The URL must be a valid PHP expression. If it is a string, it should be double quoted.
2. For predefined settings, if the Add page and the return page (Add/Edit/View Page) uses modal dialog, the
return page will be opened in the same modal dialog. However, modal dialog is not supported if the return
page is not one of the predefined settings.

Example 1
If you want to redirect user to a custom page, enter: (with quotes)

"MyPage.php"

Example 2
If you want to pass field values, enter: (with quotes)

"MyPage.php?xxx=" . urlencode($this-><Field>->CurrentValue)

e.g.

"MyPage.php?ID=" . urlencode($this->ID->CurrentValue)

Example 3
If you have just added a master record and want to go to Grid-Add page of the detail table, enter: (with quotes)

"<DetailTable>list.php?a=gridadd&showmaster=<Table>&fk_<KeyField>=" . urlencode($this-><Field>->CurrentValue)

e.g.

"OrderDetailslist.php?a=gridadd&showmaster=Orders&fk_OrderID=" . urlencode($this->OrderID->CurrentValue)

Example 4
If you have just added a master record and want to go to Add page of the detail table, enter: (with quotes)

"<DetailTable>add.php?showmaster=<Table>&fk_<KeyField>=" . urlencode($this-><Field>->CurrentValue)

e.g.

"OrderDetailsadd.php?showmaster=Orders&fk_OrderID=" . urlencode($this->OrderID->CurrentValue)

After Edit Specifies the return URL after a record is edited.

Notes

1. The URL must be a valid PHP expression. If it is a string, it should be double quoted.
2. For predefined settings, if the Edit page and the return page (Add/Edit/View Page) uses modal dialog, the
return page will be opened in the same modal dialog. However, modal dialog is not supported if the return
page is not one of the predefined settings.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 40 of 168

After Grid-Add Specifies the return URL after Grid-Add is done. Predefined settings are:

List Page - returns to the List page of the current table (default)
Grid-Add Page - returns to the Grid-Add page of the current table
Grid-Edit Page - returns to the Grid-Edit page of the current table

You can also enter your own URL. The URL must be a valid PHP expression. If it is a string, it should be double quoted.

After Grid-Edit Specifies the return URL after Grid-Edit is done. Predefined settings are:

List Page - returns to the List page of the current table (default)
Grid-Add Page - returns to the Grid-Add page of the current table
Grid-Edit Page - returns to the Grid-Edit page of the current table

You can also enter your own URL. The URL must be a valid PHP expression. If it is a string, it should be double quoted.

After Register Specifies the return URL after an user is registered. This setting is only available for the user table specified in Security
Settings.

Notes

1. The URL must be a valid PHP expression. If it is a string, it should be double quoted.
2. For predefined settings, if the Add page and the return page (Add/Edit/View Page) uses modal dialog, the
return page will be opened in the same modal dialog. However, modal dialog is not supported if the return
page is not one of the predefined settings.

Table-specific Options
These options are same as the List page options as described in PHP Settings except that the options are table-specific, meaning that you
can have different List page options for different tables. To use table-specific options, select a table in the grid, uncheck [Use global
settings] in the [Table-specific Options] panel, the panel will be enabled for you to setup.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 41 of 168

Master/Detail
When you set up a master/detail relationship, you link two tables so that all the records of one table (the detail table) always correspond
to the single current record in the other table (the master table). Each table can have multiple master tables and details tables.

You can establish master/detail (one-to-many) relationship between two tables as follows

1. Select a table in the table grid,


2. Then in [Master/Detail] panel at the bottom right corner of the page, click [Modify...] to bring up the visual master/detail
relationship editor.
3. Click [Add table] to add the master and detail table to the diagram.
4. Create a relationship between them by dragging from the master field (key field in master table) to the detail field (foreign
key field in the detail table). If there are more linked field, repeat the step until all the relationships are setup.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 42 of 168

If you want to remove a relationship, select the link in the diagram and click [Delete]. After setup, click [OK] to confirm.

Note The diagram only shows master/detail relationships of the selected table. Although you can setup relationships for other
tables in the diagram and view them in the [Master/Detail] panel immediately after clicking [OK], the relationships for other tables
will not be loaded again if you go to other table and then come back to this table. Instead, the relationships will only be displayed
when you change to the related tables.

In most cases, master and detail tables are joined by one field, you have one link between the master/detail table and you have one row
in the Master/Detail panel only.

Referential Integrity Specifies that user may not add/update a record in the detail table unless the foreign key points to a valid record
in the master table.

Cascade Delete Specifies that if a record in the master table is deleted, all corresponding records in the detail table will be
deleted.

Note If you have used ON DELETE CASCADE for the table in the database, no need to enable this setting.

Cascade Update Specifies that if the primary key for a record in the master table changes, all corresponding records in the detail
table will be updated.

Note If you have used ON UPDATE CASCADE for the table in the database, no need to enable this setting.

Also See:

Tutorial - Master/Detail

 ©2002-2019 e.World Technology Ltd. All rights reserved.

Field Setup
After loading the database, the database objects (tables, views, custom views, reports and linked tables) will be shown in the left pane (the
database pane). Click on any table to go to the Field Setup Page for that table at any time.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 43 of 168

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, a report or a Linked Table.

PHPMaker support most commonly used data types. If PHPMaker finds any unsupported fields in a table, an [Unsupported Fields] tab
will appear. You can click on the tab to view the list of fields that are not supported.

The Field Setup pages consists of two section. The upper section is a grid showing available options of all fields. The lower section contain
two panels, the [Edit tag] panel and the [View tag] panel for the selected field.

The grid consists of the following sections:

• General
• List Page
• View Page
• Edit Page
• Add Page
• Multi-Update Page
• Advanced Search Page

General

Properties

Field Name Field Name (read only)

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 44 of 168

Data Type Data Type (read only)

Size Maximum field length (read only)

Expression The expression for custom field (Custom Fields only). See also Custom Fields.

Caption Field caption to be displayed

Primary Key Primary Key of the table. Composite key is supported.

Important
1. You should use the same primary key as declared in the database, do not change it unless you are
absolutely sure that the selected field(s) values are unique. Otherwise a record cannot be located
properly and unexpected results may occur.
2. Primary key is uneditable in the edit page.

Page No. Page number of the field. For use with Multi-Page. By default all the fields are in page 1 and Multi-Page is
disabled.

Multi-Page is supported for Add/Edit/View/Search pages, you can optionally enable it for each page. Page labels
are also supported. See Table Setup.

If Multi-Page is enabled and the page number is 0, the field will appear in all pages.

Note You can multi-select the fields by ctrl-click or shift-click the Field Name column and then right click to
set the page number for the selected fields simultaneously.

Auto-Update Value A dynamic value to update the field function automatically in Add/Edit pages.

The dropdown list for this setting is preloaded with a few functions for your selection. For example, you may want
to record the last modified date of a record, then you can select "CurrentDate". Do not select a function that
return values of unmatching data type, for example, you should not select a function that return a non-numeric
string for a numeric field.

Notes
1. This setting will make the field hidden automatically and it overrides the default value in Add page
and custom value for Hidden Edit tag in Edit page. (see section below)
2. You can add your own PHP functions, the function must accept no argument and return a value. You
can add your function names (comma separated) for the Advanced Settings Auto-Update values (See
Tools - Advanced Settings), e.g. You can enter: (no quotes)
MyAutoValueFunction1,MyAutoValueFunction2
Then put your functions under server side Global Code section, see Server Events and Client Scripts.

Change Field Display Order by Drag-and-Drop

You can change the field order defined in the database by simple drag-and-drop. Simply ctrl-click or shift-click the Field Name column to
select multiple fields, then drag it to where you want. PHPMaker will generate scripts and display records according to this order.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 45 of 168

Change Multiple Field Properties

Some field properties allow multi-update. You can ctrl-click or shift-click the Field Name column to select multiple fields, then right click
and select Set field properties... to update them at the same time.

List Page

Properties

List Show field in list page

Note The setting is also used for Inline/Grid-Add/Edit and Master/Detail-Add/Edit/View.

Export Include the field when export

Sort Allow sorting by clicking the column header

Aggregate Enable Field Aggregation. Aggregated values will be shown at Page Footer. Not applicable in multi-column view.
Aggregate options include:
- TOTAL (sum of all field values in current page)
- COUNT (count of records in current page)
- AVERAGE (average field value in current page)

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 46 of 168

Width Specify CSS width property for field column width. Number, number with unit, or CSS styles are supported, e.g.

Input (no quotes) Output style attribute

200 width: 200px

200px width: 200px

100% width: 100%

min-width: 100px; min-width: 100px;

Note If your table is too wide, browsers will try to best fit the content into screen and the specified width may be
overridden.

Wrap Enable/Disable text-wrap for field value. If enabled, style white-space: nowrap; will be added to the table cell.

Note If you enable text-wrap but the field value has no line-breaking points (e.g. spaces or punctuation), the text
still cannot be wrapped.

Quick Search Include this field when performing Quick(Basic) Search in the List page.

Note Only text fields and numeric fields are supported in Quick Search. By default only text fields are enabled.

Ext. Search Use this field in Extended Quick Search

Extended Quick Search is enhancement of Quick Search. If a field is checked for Ext. Search, a form element for the field
will be shown in the Quick(Basic) Search form and the user input criteria for this field will be included when performing
Quick(Basic) Search.

Extended Quick Search will use the same search operators specified under the "Advanced Search Page" section (see
below).

Note Extended Quick Search only works with field selected to show in the List page or the search criteria cannot be
highlighted (if enabled, see Table Setup) and may confuse some users.

View Page

Properties

View Show field in view page

View Tag HTML tag to display the field. Used in List/View pages.

You can either click the [View Tag] column and select a View Tag from the drop down box or click the icon on the View Tag panel toolbar

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 47 of 168

to select. After selecting the View Tag, you can further setup its properties in the View tag panel.

View Tag

There are two types of View Tag, Formatted Text and Image.

Formatted Text - View Tag to display the field value as formatted text using <div> tag with optional hyperlink. Properties:

DIV Tag attributes

Style Align - Left/Center/Right/Justify. Align the data.


Italic - Display as Italic
Bold - Display as Bold

Custom Attributes Other custom attributes for the <div> or <span> tag. For example, you can enter as string, e.g. (string with
single/double quotes)

"onmouseover='my_js_function();' onmouseout='my_js_function2();'"

or preferably as an array, e.g.

["onmouseover" => "my_js_function();", "onmouseout" => "my_js_function2();"]

Notes
1. The setting must be a valid PHP expression. If it is string, it should be single/double quoted.
2. If you use your own JavaScript functions for the client events. You can put your JavaScript
functions in the Global Code for client scripts (see Server Events and Client Scripts) so it is
available for use in the generated scripts.
3. Sometimes the generated code already uses some attributes (e.g. onchange event, class
attribute, style attribute), if you add the same attribute/event using the string format, there will
be more than one event/attributes of the same name and it will be ignored by browsers. But if
you add the same attribute using the array format, the attributes will be concatenated together.
Therefore, the array format is recommended over the string format.

Format

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 48 of 168

None No formatting

Currency Display as formatted currency

Date/Time Display as formatted date. Possible values of Date/Time named format are:

• Default - based on locale file


• DateTime - Date and time, format based on locale file
• Date - Date only, format based on locale file
• Time(AM/PM) - 12-hour with AM/PM
• Time - 24-hour
• Ymd
• mdY
• dmY
• YmdHis
• mdYHis
• dmYHis
• ymd
• mdy
• dmy
• ymdHis
• mdyHis
• dmyHis
• YmdHi
• mdYHi
• dmYHi
• ymdHi
• mdyHi
• dmyHi

where:

• Y - A full numeric representation of a year, 4 digits


• y - A two digit representation of a year
• m - Numeric representation of a month, with leading zeros, 01 through 12
• d - Day of the month, 2 digits with leading zeros, 01 to 31
• H - 24-hour format of an hour with leading zeros, 00 through 23
• i - Minutes with leading zeros, 00 to 59
• s - Seconds, with leading zeros, 00 through 59

Notes

1. Above formats do not include the date or time separator, the actual date or time separator
during runtime is determined by locale file (see Tools -> Locale Settings).
2. For Default, DateTime, Time(AM/PM) and Time, the time format is also affected by the
advanced setting Use Date/Time without seconds (see Advanced Settings).

Number Display as formatted number

Percent Display as formatted percentage

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 49 of 168

String Format the field value with specified PHP string function (e.g. strtolower) or custom function.

If the string function name is not listed in the dropdown, you can enter your own function name. If the
function has one argument only, the argument must be the field value and you only need to enter the
function name, e.g. strtolower. If the function has more than one arguments, use {value} to denote that
field value, for example, to format a date field by PHP date function, enter:

date(DATE_RFC822, strtotime({value}))

Replace CR+LF by <BR> Display the fields with CR+LF replaced by <BR>

Note This setting only applied to memo fields.

Max Length (List page) Truncate the field value at specified max. length and append "..." to the end.

Note This setting only applied to memo fields in list page and must be larger than 0 to take effect.

Hyperlink

HREF field Display the field as hyperlink with the href attribute set to the value of this field. It can be the field itself.

Original field value Use original field value of the Href field in the hyperlink instead of display field value.

If the HREF field has lookup table or user values, by default the display value will be used. If this option is
enabled, the original field value will be used instead.

Target Target attribute of the hyperlink. Possible values are: _top, _parent, _self, or _blank. You can also enter your
own.

Prefix Prefix added before the HREF field value. You can select one of the follows:

• (None)
• http://
• mailto:
• ftp://
• file:///
• news://

You can also enter your own partial URL (preceding the HREF field value).

Note This setting is a string to be quoted by double quotes, if you want to use PHP variable, wrap it in
{ and }. Since { can not be escaped, this syntax will only be recognized when the $ immediately follows
the {. Read PHP Strings for more information on parsing variable in string.

For example, you can enter: (no quotes)

mypage.php?id=

The value of the HREF field will be appended to the end of the your prefix in the outputted HTML.

If you want pass a field value, you can enter: (no quotes)

mypage.php?myfield={$this->UrlEncode($this->MyField->CurrentValue)}&id=

If you need to pass parameters which should not be URL-encoded, for example, if you use Encrypt() to
encrypt your parameter, you can enter: (no quotes)

mypage.php?myfield={$this->Raw(Encrypt($this->MyField->CurrentValue))}&id=

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 50 of 168

Suffix Suffix added after the HREF field value. You can use this setting to append additional URL parameters.

For example, you can enter: (no quotes)

&field2={$this->UrlEncode($this->Field2->CurrentValue)}

Note If the suffix is URL parameter(s), you should use & at the beginning of the string.

Custom Attributes Custom attributes for the <A> tag.

For example, you can enter a string, e.g. (string with single/double quotes)

"rel='xxx'"

or preferably as array, e.g.

["rel" => "xxx"]

Notes
1. The setting must be a valid PHP expression. If it is string, it should be single/double quoted.
2. If you use your own JavaScript functions for the client events. You can put your JavaScript
functions in the Global Code for client scripts (see Server Events and Client Scripts) so it is
available for use in the generated scripts.
3. Sometimes the generated code already uses some attributes (e.g. onchange event, class
attribute, style attribute), if you add the same attribute/event using the string format, there will
be more than one event/attributes of the same name and it will be ignored by browsers. But if
you add the same attribute using the array format, the attributes will be concatenated together.
Therefore, the array format is recommended over the string format.

Tooltip

Tooltip field Display the field as tooltip

Tooltip width The width of the tooltip in pixels. Default is 0 (auto).

By default the width is not specified and the width will depend on the field value. However, when the tooltip
field is a long text field, the width can take up the browser width, which may be unwanted. Then you can
specify a value to limit the width.

Custom View Tag

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 51 of 168

Custom View Tag Display the field value in List/View page by custom code.

Important Custom View Tag overrides ALL above View Tag settings.

There are some ready-to-use Custom View Tag for you to choose:

• Google Maps
• Barcode and QR code
• YouTube videos

If your data stores information for above, just click the down arrow button to open the setup form, enable
one of them, read the notes at the bottom panel carefully, then click the Settings tab to setup, and click OK
to save your settings.

Notes

1. Only one of above Custom View Tag can be selected at a time. All records will use the same
Custom View Tag. For instance, you can NOT use Barcode for a record and use Google Maps for
next record.
2. The above Custom View Tags are provided as examples only. The third party tools used are not
developed by the author of PHPMaker and are not part of PHPMaker, NO TECHNICAL SUPPORT
WILL BE PROVIDED.

You can also create your Custom View Tag, they are implemented in exactly the same way as template
extensions (see Customizing Template). Custom View Tags must be placed under the subfolder
"customviewtags" of the installation folder. Each Custom View Tag must have a XML description file so it can
be loaded for selection. You can open an XML file in the "customviewtags" subfolder to see the content,
which is self-explanatory. Unzip the zip file to see how it is implemented.

If you want absolute freedom, click the [...] button to enter your own code to display the your data in your
own PHP, HTML and JavaScript.

Important If you choose to enter your own code, you are completely on your own to display the field
value. Intermediate knowledge in PHP, HTML, CSS and JavaScript is required.

Custom View Tag is HTML, if you want to embed PHP code, use <?php and ?>, if you want to use JavaScript,
use <script> and </script>.

Note DO NOT use $this in your PHP code. There is no $this in the context, you can use CurrentPage()
to get the current page object.

Custom View Tag supports the following tags:

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 52 of 168

{{{old_tag}}} The old (original) View Tag, that is, the original code for the field. If you need to reuse
the original code without changes (e.g. you just add some additional code for the field),
you can use the special tag {{{old_tag}}} in your code

Example 1

{{{old_tag}}}
...Your HTML...

Example 2

If {{{old_tag}}} is inside JsRender template, it will only be converted to a JsRender


Include tag {{include tmpl=... /}} to include the template of original code.

<script class="ew-js-template" type="text/html">


{{{old_tag}}}
...Your HTML...
</script>

{{{value}}} The CurrentValue of the field object. It will converted to <?php echo
$<page>-><field>->CurrentValue ?>. Note that it includes the <?php echo and ?> tags,
use it in HTML only, do not use it in PHP code.

{{{view_value}}} The ViewValue of the field object. It will converted to <?php echo
$<page>-><field>->ViewValue ?>. Note that it includes the <?php echo and ?> tags, use it
in HTML only, do not use it in PHP code.

The above tags are just some helper tags, you can write your own Custom View Tag without using them at
all.

Example 3

Output the field value conditionally:

<?php
if (CurrentPage()->MyField->CurrentValue == "xxx") { // Assume string field
echo "something";
} else {
echo "something else";
}
?>

Example 4

Output a custom link:

<a href="mypage.php?id=<?php echo urlencode(CurrentPage()->MyField->CurrentValue) ?>">My Link</a>

Image - View Tag to display as Image using <img> tag. The field should be a BLOB field or a field storing the path of an image.

Note Only image files can use the Image View Tag. Other files such as PDF cannot be displayed as image. If the field contains
mixed file types, do not use Image View Tag.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 53 of 168

IMG Tag attributes

Width Specify the width of the image in pixels

Height Specify the height of the image in pixels

Alt Specify the alt attribute of the image tag

Note If you use Multi-Language (see PHP Settings), use Multi-Language Property Editor, see Tools for
details.

Custom attributes Other custom attributes for the <div> or <span> tag. For example, you can enter: (string with single/double
quotes)

"onmouseover='my_js_function();' onmouseout='my_js_function2();'"

or

["onmouseover" => "my_js_function();", "onmouseout" => "my_js_function2();"]

Notes
1. The setting must be a valid PHP expression. If it is string, it should be single/double quoted.
2. If you use your own JavaScript functions for the client events. You can put your JavaScript functions in
the Global Code for client scripts (see Server Events and Client Scripts) so it is available for use in the
generated scripts.
3. Sometimes the generated code already uses some attributes (e.g. onchange event, class attribute, style
attribute), if you add the same attribute/event using the string format, there will be more than one
event/attributes of the same name and it will be ignored by browsers. But if you add the same attribute
using the array format, the attributes will be concatenated together. Therefore, the array format is
recommended over the string format.

Resize image Resize the image to above width and/or height on displaying the image.

Note This feature requires PHP GD extension and supports GIF, JPEG and PNG images only.

Hyperlink, Tooltip and Custom View Tag (same as above)

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 54 of 168

Edit Page

Properties

Edit Show field in edit page

Note The setting is for Edit page only, NOT for Inline/Grid-Add/Edit and Master/Detail-Add Edit in the List page. See
the List setting above.

Title Title to be placed in title attribute of Edit Tag. (see section below) The title will also appear as popup tooltip of the Edit Tag.

Note If you use Multi-Language (see PHP Settings), use Multi-Language Property Editor, see Tools for details.

Read Only Make the field read only in edit page

Note This setting replaces the Edit Tag by a INPUT type=hidden tag and show the field by its View Tag (see above). If
you want to set the Edit Tag's readonly attribute (supported by INPUT type=text, INPUT type=password, TEXTAREA),
use Row_Rendered server event. If you want to set the Edit Tag's disabled attribute, you can set $this-
><field>->Disabled property. (See Server Events and Client Script.)

Edit Tag Form element for the field. Use in Add/Copy/Edit/Search pages. (See below for details)

You can either click the [Edit Tag] column and select a Edit Tag from the drop down box or click the icon on the [Edit Tag] panel toolbar
to select. After selecting the Edit Tag, you can further setup its properties in the Edit Tag panel:

Edit Tags

Edit Tags are HTML forms elements for the field in Add/Copy/Edit/Search pages. All HTML form elements are supported:

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 55 of 168

Text <input type="text"> tag

Display the field as a textbox.

Size Size attribute of the textbox

Maxlength Maximum input length of the textbox

Custom attributes Other custom attributes for the tag. For example, you can enter: (with quotes)

"onmouseover='my_js_function();'"

or

["onmouseover" => "my_js_function();"]

Notes
1. The setting must be a valid PHP expression. If it is string, it should be
single/double quoted.
2. If you use your own JavaScript functions for the client events. You can
put your JavaScript functions in the Global Code for client scripts (see
Server Events and Client Scripts) so it is available for use in the
generated scripts.
3. Sometimes the generated code already uses some attributes (e.g.
onchange event, class attribute, style attribute), if you add the same
attribute/event using the string format, there will be more than one
event/attributes of the same name and it will be ignored by browsers.
But if you add the same attribute using the array format, the attributes
will be concatenated together. Therefore, the array format is
recommended over the string format.

Client side events See section below

Validation See section below

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 56 of 168

Use lookup table For use with Auto-Suggest and/or Auto-Fill (see below) with Lookup Table.

Auto-Suggest is Text Edit Tag with a Lookup Table. When user types in the
textbox, a dynamic dropdown list populated with data from the lookup table
matching the user input will appear for user to select. If the data already exists, the
user can easily select without typing the full text. If not, the user can still input as
usual. Check [Use lookup table] to enable Auto-Suggest and then enter the
lookup table info in the [Lookup Table] panel next to the [Edit Tag] panel. See
Lookup Table for more details.

Use modal dialog for lookup For use with Use lookup table. Replaces Auto-Suggest by a modal dialog for
selecting a record from the lookup table, see Lookup Table for details. Supports
searching, paging and option template (see below).

Note The modal dialog is same for TEXT/SELECT/RADIO/CHEKCBOX.

Modal lookup page size For use with Use modal dialog for lookup. Specifies the number of records per
page in the dialog. If not specified, default is 10.

Force selection For use with Auto-Suggest and/or Auto-Fill (see below) with Lookup Table. This
setting must be enabled if you want to use Auto-Fill with Auto-Suggest.

When this setting is enabled, the user must select one of the auto-suggested
options, the textbox will become similar to a combobox ("select-one"). This setting
is usually enabled if the field is a lookup field, i.e. the field stores Link Field values
(e.g. primary key) of the Lookup Table.

If this setting is disabled, the form will submit the user input (not the Link Field
value) if no suggestion is selected, so make sure user input is acceptable. For
example, if the Link field is same as the Display field #1, then disabling this
setting should be fine and the field will save one of the suggestion (if selected) or
what the user inputs.

If Allow sort/search (see Lookup Table) is enabled, usually the user wants to search
the display value rather than the Link field value, so this setting is disabled
automatically in the search forms, which will submit the selected suggestion's
display value or the user input, and the script will search the display value of the
field.

Dropdown min-width (px) Minimum width for dropdown. For use with Auto-Suggest only.

Dropdown max-height (px) Maximum height for dropdown. For use with Auto-Suggest only.

Option Template Optional JsRender template for options. For use with Auto-Suggest only. See
Lookup Table for details.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 57 of 168

Password <input type="password"> tag

Display the field as a masked textbox.

Size Size attribute of the textbox

MaxLength Maximum input length of the textbox

Custom attributes Same as above (see Text Edit Tag)

Client side events See section below

Validation See section below

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 58 of 168

Radio <input type="radio"> tag

Display the field as a radio button list.

Custom attributes Same as above (see Text Edit Tag)

Client side events See section below

Validation See section below

Use lookup table Use an existing lookup table instead of user input value/label pairs for the radio
buttons. To enable this feature, check this option and enter the lookup table info in
the [Lookup Table] panel next to the [Edit Tag] panel. See Lookup Table for
details. If you don't use lookup table, you can enter the options manually in the
[User Value] panel next to the [Edit Tag] panel.

Use modal dialog for lookup For use with Use lookup table. Replaces radio buttons by a modal dialog for
selecting a record from the lookup table, see Lookup Table for details. Supports
searching, paging and option template (see below).

Note The modal dialog is same for TEXT/SELECT/RADIO/CHEKCBOX, while it


has the same functionality of allowing user to select a record from the lookup
table, it is NOT a radio button list (or dropdown, see below) anymore.

Modal lookup page size For use with Use modal dialog for lookup. Specifies the number of records per
page in the dialog. If not specified, default is 10.

Repeat columns Specifies the no. of radio boxes per row

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 59 of 168

Use dropdown Show the options in dropdown panel with min-width and max-height settings, e.g.

Note that if Repeat columns is 1 (single column), the options will be displayed
same as dropdown selection list (Select Edit Tag with Use dropdown enabled, see
below), radio buttons will be hidden, e.g.

Dropdown min-width (px) Minimum width for dropdown

Dropdown max-height (px) Maximum height for dropdown

Option Template Optional JsRender template for options. See Lookup Table for details.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 60 of 168

Checkbox <input type="checkbox"> tag

Display the field as a checkbox list.

Note For MySQL, PHPMaker considers enum('Y','N') and enum('1','0') as boolean fields. For Oracle, fields with
two and only two User Values (see below) and the labels and values are "Y" and "N" (or "1" and "0") will be
considered as boolean fields. PHPMaker will display a boolean field by a checkbox automatically.

Custom attributes Same as above (see Text Edit Tag)

Client side events See section below

Validation See section below

Use lookup table Use an existing lookup table instead of user input value/label pairs for the
checkboxes. To enable this feature, check this option and enter the lookup table
info in the [Lookup Table] panel next to the [Edit Tag] panel. See Lookup Table
for details. If you don't use lookup table, you can enter the options manually in the
[User Value] panel next to the [Edit Tag] panel.

Use modal dialog for lookup For use with Use lookup table. Replaces checkboxes by a modal dialog for
selecting multiple records from the lookup table, see Lookup Table for details.
Supports searching, paging and option template (see below).

Note The modal dialog is same for TEXT/SELECT/RADIO/CHEKCBOX, while it


has the same functionality of allowing user to select multiple records from the
lookup table, it is NOT a checkbox list (or dropdown, see below) anymore.

Modal lookup page size For use with Use modal dialog for lookup. Specifies the number of records per
page in the dialog. If not specified, default is 10.

Repeat columns Specifies the no. of checkboxes per row

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 61 of 168

Use dropdown Show the options in dropdown panel with min-width and max-height settings, e.g.

Note that if Repeat columns is 1 (single column), the options will be displayed
same as dropdown multiple selection list (Select Edit Tag with Multiple and Use
dropdown enabled, see below), e.g.

Dropdown min-width (px) Minimum width for dropdown

Dropdown max-height (px) Maximum height for dropdown

Option Template Optional JsRender template for options. See Lookup Table for details.

Note The submitted values of the multi-selected checkboxes is a comma-separated string. Therefore you
must use a string field for checkbox list.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 62 of 168

Select <select> tag

Display the field as a combobox ("select-one") or a listbox ("select-multiple").

Size No. of options to show. If more that 1, the selection list is shown as a listbox,
otherwise it is shown as a combobox.

Multiple Check to enable multiple selection (listbox)

Custom attributes Same as above (see Text Edit Tag)

Client side events See section below

Validation See section below

Use lookup table Use an existing lookup table instead of user input value/label pairs for the
checkboxes. To enable this feature, check this option and enter the lookup table
info in the [Lookup Table] panel next to the [Edit Tag] panel. See Lookup Table
for details. If you don't use lookup table, you can enter the options manually in the
[User Value] panel next to the [Edit Tag] panel.

Use modal dialog for lookup For use with Use lookup table. Replaces selection list by a modal dialog for
selecting one or multiple records from the lookup table, see Lookup Table for
details. Supports searching, paging and option template (see below).

Note The modal dialog is same for TEXT/SELECT/RADIO/CHEKCBOX, while it


has the same functionality of allowing user to select one or multiple records
from the lookup table, it is NOT a selection list (or dropdown, see below)
anymore.

Modal lookup page size For use with Use modal dialog for lookup. Specifies the number of records per
page in the dialog. If not specified, default is 10.

Repeat columns Specifies the no. of checkboxes per row

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 63 of 168

Use dropdown Show the options in dropdown panel with min-width and max-height settings, e.g.

select-one (Multiple disabled)

select-mulitple (Multiple enabled)

Note If Use dropdown is used, the HTML element is NOT <select> anymore.
The dropdown panel uses radio buttons (if Multiple disabled) or checkboxes
(if Multiple enabled) to support Option Template (see below). If you need to
write JavaScript for the HTML elements, make sure you write code for correct
HTML elements. Inspect HTML source in your browser to view the HTML
elements.

Dropdown min-width (px) Minimum width for dropdown

Dropdown max-height (px) Maximum height for dropdown

Option Template Optional JsRender template for options. See Lookup Table for details.

Note If Use dropdown is not used, the HTML element is native <select>
element, which usually does NOT support HTML tags in options (depending
on browsers), though HTML entities are supported.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 64 of 168

TextArea <textarea> tag

Display the field as a textarea.

Cols No. of columns of the textarea

Rows No. of rows of the textarea

Custom Same as above (see Text Edit Tag)


attributes

Client side See section below


events

Validation See section below

Use HTML Replace the textarea with a HTML editor for editing the data as HTML. See Third-party Tools for
editor more info on HTML editors.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 65 of 168

File <input type="file"> tag

Display the field as a file upload control. For BLOB fields or string fields only.

Note File upload supports displaying thumbnails of uploaded image. The feature requires PHP GD extension
and supports GIF, JPEG and PNG images only.

Size Size of the input tag (NOT file size)

Custom attributes Same as above (see Text Edit Tag)

Client side events See section below

Validation See section below

If the field is of BLOB (binary) data type, file is uploaded to the database.

You can also store the information of the uploaded file in the following fields: (for BLOB field only)

File type field - Recommended. Useful when you want to response to user browser the exact content type of the
data.

File name field - Optional. Useful if you want to use the original filename.

Note Do not specify file name field if you want IE to open the file automatically. (IE may fail to open non-image
files retrieved from database properly.) Use file name field if you want IE to popup a File Download dialog for
user to save the file with the filename specified in the file name field.

File size field - Optional. Stores the uploaded file size.

Image width field - Optional. For use with images only. Stores the width of the uploaded image.

Image height field - Optional. For use with images only. Stores the height of the uploaded image.

If the field of string type, file is uploaded to a subfolder relative to the application root.

Multiple - Allow multiple upload. Field value will be comma separated file names. NOT application to BLOB field.

Upload folder - Folder where the uploaded file will reside. If you do not enter a specific folder, all the uploaded files

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 66 of 168

will be put in the global upload folder specified in the PHP tab (see PHP Settings).

Notes
1. Unlike the global upload folder setting (which is a constant and must be a string without double quotes,
see PHP Settings), this field setting must be a valid PHP expression. If it is a string, it must be single or
double quoted.
2. Make sure that the Web server user have read/write access to the folder.
3. The path can be dynamic. For example, if the upload path varies with some field value, you can refer to
other fields by $this->MyField->DbValue. However, you must be very careful when using dynamic folder,
make sure the setting is valid as a folder name, i.e. it does not contain some characters which can not be
used in a file path on your server. The setting will be evaluated to obtain the upload folder before the file
is displayed and before the uploaded file is saved, so your setting should be consistent, do not use
random number or current date/time to name the folder. Alternatively, you can also use Row_Rendered,
Row_Inserting and Row_Updating server events to set the field object's UploadPath property.
4. If Multiple is enabled, all upload files use the same upload folder.
5. The path is relative to application root. Use slashes "/" as path delimiter, no leading slash. e.g. If the
application root of your website is C:\Inetpub\wwwroot\demo and you enter "uploads/" in this textbox,
the folder for the uploaded files will be C:\Inetpub\wwwroot\demo\uploads. If you are not sure which
folder is application root, please read Application Root. If you must use another absolute path, use the
Advanced Setting File upload path (absolute) for temporary files.
6. The path supports AWS S3 bucket, e.g. you can enter "s3://my-bucket/" (with quotes). (In this special
case, the path is not relative to application root.) To use S3 bucket, make sure you register the Amazon S3
Stream Wrapper in the Global Code server event.
7. Make sure that the Web server user have read/write access to the folder. If you use S3 bucket, note
that the uploaded files in the bucket are not public by default. Remember to configure bucket
permissions so that the uploaded files are accessible by users.

Resize image - Optionally resize the image to resize width and/or height.

Resize width - Width of the resized image

Resize height - Height of the resized image

Note Resizing requires PHP GD extension and supports GIF, JPEG and PNG images only.

Allowed file types - Comma separated file extensions (e.g. jpg,png,gif) without spaces and quotes. If not specified,
the global setting (see PHP Settings -> General Options -> File Upload) will be used.

Note For security, the field-specific Allowed file types must be included in the allowed file types under PHP
Settings -> General Options -> File Upload.

Max file size (bytes) - The maximum allowed file size in bytes. (Requires browsers supporting the File API.) If not
specified, the global setting (see PHP Settings -> General Options -> File Upload) will be used.

Max number of files - The maximum number of files that are allowed to be uploaded if Multiple (see above) is
enabled. It must be larger than 1. (If you just allow one file, disable Multiple.) If not specified, unlimited file uploads
are allowed. Since file names are stored as comma separated value in the field, the max number of files is also limited
by the field size defined in the database.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 67 of 168

Hidden <input type="hidden"> tag

Hide the field with a hidden form element.

Note This is different from de-selecting the field in the [Edit] column. If a field is de-selected, no code will be
generated for the field in the Edit page and the field will not be updated. With a hidden form element the field
is not seen but it may still get updated.

Custom value - by default the 'value' attribute contains the field value, custom value is used to update the field with
another value when a record is updated using the Edit page.

Notes
1. Custom value is used in Edit page only. It cannot be used with Read-only fields, User ID fields and Detail
fields(Foreign key fields)
2. In Add page, if a default value is specified (see section below), hidden form element will also be used but
the 'value' attribute will contain the default value. If default value is not specified, the field will be
displayed as a normal textbox.
3. Other preferable ways of updating a hidden field is to use Auto-Update Value (see above) or to use
Row_Inserting and/or Row_Updating server events.

Custom attributes - same as above (see Text Edit Tag)

Custom Edit Tag

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 68 of 168

Custom Edit Tag Display the field value in Add/Edit/Search pages by custom code.

Important

1. Custom Edit Tag overrides ALL above Edit Tag settings.


2. Custom Edit Tag is only a provision for your own code or your own implementation of third party tools. If
you choose to enter your own code, you are completely on your own to edit the field value. Intermediate
knowledge in PHP, HTML, CSS and JavaScript is required. NO TECHNICAL SUPPORT WILL BE PROVIDED
for any third-party tools.
3. Only one Custom Edit Tag can be selected at a time. All records will use the same Custom Edit Tag. You
cannot use a Custom Edit Tag for a record and use another Custom Edit Tag for next record.
4. The sample Custom Edit Tag is provided as examples only. The third party tools used is not developed by
the author of PHPMaker and is not part of PHPMaker, NO TECHNICAL SUPPORT WILL BE PROVIDED.

To use Custom Edit Tag, click the down arrow button to open the setup form, enable one of them, read the notes at
the bottom panel carefully, then click the Settings tab to setup, and click OK to save your settings.

You must create your own Custom Edit Tag, they are implemented in exactly the same way as template extensions
(see Customizing Template). Custom Edit Tags must be placed under the subfolder "customedittags" of the
installation folder. Each Custom View Tag is basically a XML description file. You can open the sample Custom Edit
Tag's XML file in the "customedittags" subfolder to see the content, which is self-explanatory.

Example

<?xml version="1.0" encoding="iso-8859-1" ?>


<ew-extension id="colorpicker" name="Colorpicker" version="1.0.0" type="Custom Edit Tag" author="e.World">
<description>
<![CDATA[

COMMENTS

]]>
</description>
<file>colorpicker.zip</file>
<script>plugins/colorpicker/bootstrap-colorpicker.min.js</script>
<stylesheet>plugins/colorpicker/bootstrap-colorpicker.min.css</stylesheet>
<Code><![CDATA[
{{{old_tag}}}
<script>
$("[id='{{{id}}}']:not([id*='$rowindex$'])").colorpicker({ format: "hex" });
</script>
]]></Code>
</ew-extension>

id Unique ID of the Custom Edit Tag. Should contains alphanumeric characters only, e.g. "colorpicker".

file (Optional) External files required by the Custom Edit Tag (zip file). If the files are always available in the
website (e.g. your Custom Edit Tag only uses JavaScript from CDN), you do not need this setting.

The zip file must be placed in the same folder of the XML file, i.e. the "customedittags" folder. In the zip
file, there must be a Control File (control.xml) specifying where these external files to be copied to.

Example

<control id="colorpicker" type="copy" action="add" remark="Copy Colorpicker plugin"


ofolder="plugins" ifolder="plugins" />

This tells PHPMaker to perform an additional task of copying the input folder "plugins" (in the zip file)
to the output folder "plugins" (same name in this case) under the destination folder of the project.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 69 of 168

script (Optional) JavaScript required by the Custom Edit Tag.

Note In more than one scripts, delimit them by | (vertical bar), NOT line breaks, e.g.
<script>//host/path/xxx.js|//host2/path2/yyy.js</script>

The path(s) can be absolute URL, relative URL or absolute physical path, read Scripts and Stylesheets for
details.

stylesheet (Optional) CSS stylesheets required by Custom Edit Tag.

Note In more than one scripts, delimit them by | (vertical bar), NOT line breaks, e.g.
<stylesheet>//host/path/xxx.css|//host2/path2/yyy.css</stylesheet>

The path(s) can be absolute URL, relative URL or absolute physical path, read Scripts and Stylesheets for
details.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 70 of 168

Code The custom code of the Custom Edit Tag.

Custom Edit Tag is HTML and PHP, if you want to embed PHP code, use <?php and ?>, if you want to
use JavaScript, use <script> and </script>.

Notes

1. Make sure your code is inside <![CDATA[...]]>.


2. DO NOT use $this in your PHP code. There is no $this in the context, you can use
CurrentPage() to get the current page object.

The following special tags are supported:


{{{old_tag}}} The old (original) Edit Tag, that is, the original code for the field. If you reuse
the original code without changes (e.g. you just add some additional code
for the field), you can use the special tag {{{old_tag}}} in your code

Example 1

{{{old_tag}}}
< script>
$("[id='{{{id}}}']:not([id*='$rowindex$'])").colorpicker({ format:
"hex" });
< /script>

Example 2

If {{{old_tag}}} is inside JsRender template (<script class="ew-js-


template" type="text/html">...</script>), it will only be converted to a
JsRender Include tag {{include tmpl=... /}} to include the template of original
code.

<script class="ew-js-template" type="text/html">


{{{old_tag}}}
<script>
$("[id='{{{id}}}']:not([id*='$rowindex$'])").colorpicker({ format:
"hex" });
</script>
</script>

{{{id}}} or {{{name}}} The id or name attribute of the HTML element of the field.

Example

$("[id='{{{id}}}']:not([id*='$rowindex$'])").colorpicker({ format:
"hex" });

Note {{{id}}} will not change for each <input> tag for
RADIO/CHECKBOX, always use name="{{{name}}}" for
RADIO/CHECKBOX.

{{{value}}} The CurrentValue of the field object. It will converted to <?php echo
$<page>-><field>->CurrentValue ?>. Note that it includes the <?php echo
and ?> tags, use it in HTML only, do not use it in PHP code.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 71 of 168

{{{edit_value}}} The EditValue of the field object. It will converted to <?php echo
$<page>-><field>->EditValue ?>. Note that it includes the <?php echo and ?>
tags, use it in HTML only, do not use it in PHP code.

Example

<input id="{{{id}}}" name="{{{name}}}}" value="{{{edit_value}}}"


class="form-control" ... />

{{{view_value}}} The ViewValue of the field object. It will converted to <?php echo
$<page>-><field>->ViewValue ?>. Note that it includes the <?php echo and ?>
tags, use it in HTML only, do not use it in PHP code.

{{{tag_id}}} The id of the JsRender Template containing the original Edit Tag. If your
Custom Edit Tag is also a JsRender Template, you can reuse it by including
the template.

Example

<script class="ew-js-template" type="text/html">


{{include tmpl="#{{{tag_id}}}"/}}
<script>
$("[id='{{{id}}}']:not([id*='$rowindex$'])").colorpicker({ format:
"hex" });
< /script>
</script>

If you want absolute freedom, click the [...] button to enter your own code to display the your data in your own PHP,
HTML, CSS and JavaScript. You can enter JavaScript and stylesheet paths in the JavaScripts(Global) and Stylesheets
(Global) respectively. One line for each path. Note that the paths are global for the whole project, not just for a field,
you'll see JavaScript and stylesheet paths required by other fields. A JavaScript or stylesheet may depends on other,
you can move them up or down to make sure the sequences are correct.

Note If the JavaScript(s) and/or stylesheet(s) are not provided by the Custom Edit Tag itself, make sure the
paths are correct and the scripts/stylesheets already exist on the server.

Using User Values for Edit Tag (Radio/Checkbox/Select)

For Radio/Checkbox/Select Edit Tags, the default option values are user input values, you can enter as many value/label pairs as you
want in the [User Values] panel next to the [Edit Tag] panel.

Note For boolean fields, if you use Radio Edit Tag with User Values, the first value/label should be for True and the second for
False.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 72 of 168

Using Lookup Table for Edit Tag (Text/Radio/Checkbox/Select)

In real world applications, the option values usually come from a (lookup) table in the database. PHPMaker make it very simple to use
lookup values for key field values, simple click [Use Table], the [Lookup Table] panel will replace the [User Values] panel, see Lookup
Table for details.

Dynamic Selection Lists

PHPMaker supports Dynamic Selection Lists in which child lookup fields' selection list options change dynamically based on option
selected in the parent selection list. To setup child lookup fields, click the [Child lookup fields...] button and the following setup form will
be displayed:

Read Tutorial - Dynamic Selection List for more information.

Client side events (for Add/Copy/Edit/Search)

You can manipulate fields on the client side quickly with PHPMaker's "fields" jQuery plugin (see Server Events and Client Scripts).

Example 1

Set field values based on current field value

{ // keys = event types, values = handler functions


"change": function(e) {
if (this.value == "xxx") {
$(this).fields("FieldA").value("yyy"); // Set value to FieldA
//$(this).fields("FieldA").visible(false); // true to show, false to hide
//$(this).fields("FieldA").readonly(true); // true as readonly, false as normal (for Text and TextArea only)
//$(this).fields("FieldA").disabled(true); // true as disabled, false as normal
} else {
$(this).fields("FieldB").value("zzz"); // Set value to FieldB
}
}
}

Example 2

Client side calculation based on user input

{ // keys = event types, values = handler functions


"change keyup": function(e) {
var $row = $(this).fields(); // Get an object of all fields, each property is a jQuery object of the input element(s)
of a field
var st = $row["UnitPrice"].toNumber() * $row["Quantity"].toNumber() * (1 - $row["Discount"].toNumber()); // Convert to
number and calculate

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 73 of 168

$row["SubTotal"].value(st); // Set result to a field


}
}

Note All client side events are generated in the script userevt<version>.js, after changing client side events, remember to re-
generate the .js file.

Validation (for Add/Copy/Edit/Search)

The data input for each field can be validated using client-side JavaScript.

Validate Supported validation formats are:

• Integer
• Float
• Range - for validating a range of number
• Date - for validating date with or without time
• Time - for validating time with or without seconds
• Email
• Credit card
• GUID
• US phone number
• US zip code
• US social security number
• Regular Expression

Notes
1. The actual date/time separator during runtime is determined by locale file, see:
a. Customizing Template -> Locale Files, and
b. Tools -> Locale Settings
2. If Regular Expression, client side and server side arguments must be entered, depend on if you
have enabled client-side and server-side validation (see PHP Settings), see Arguments (Client-
side) and Arguments (Server-side) below.
3. You can add your own functions for validation. The function must accept at least one argument
(the value) and return true (valid value) or false (invalid value). If your functions requires
additional arguments, see Arguments (Client-side) and Arguments (Server-side) below. You
can add your function names (comma separated) in the Advanced Setting
CustomValidationFunctions. (See Tools.) Note that since it is both JavaScript and PHP function
name, it must be a string that corresponds to a valid identifier for both sides. For example, you
can enter "myValidateFunction1,myValidateFunction2" (no quotes). If you have enabled Client-
side (JavaScript) validation (see PHP Settings), you need to provide your JavaScript function. If
you have enabled Server-side validation (see PHP Settings), you need to provide your PHP
function. You can put your functions in the Global Code section under Server Events and Client
scripts respectively (see Server Events and Client Scripts) so they are available for use in the
generated scripts.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 74 of 168

Arguments (Client-side) Arguments for the JavaScript functions for validation. For Regular Expression and custom validation
functions only.

Note This is JavaScript arguments, it should be comma separated (if more than one) JavaScript
expressions. e.g. If it is a string, it must be single or double quoted.

If the Validate setting (see above) is Regular Expression, this setting must be a valid JavaScript regular
expression pattern along with flags that identify how to apply the pattern (delimit the pattern by "/"
characters, not single or double quotes), e.g.

/foobar/i

See Creating a Regular Expression for more information about the pattern and flags.

Arguments (Server-side) Arguments for the PHP functions for validation. For Regular Expression and custom validation functions only.

Note This is PHP arguments, it should be comma separated (if more than one) PHP expressions. e.g. If
it is a string, it must be single or double quoted.

If Regular Expression, arguments must be the the pattern to search for, as a single or double quoted string,
e.g.

'/foobar/i'

See PHP function preg_match for more information about the pattern.

Use date/time picker Check this option to use a JavaScript date/time picker instead of manual input.

Notes
1. Popup calendar is only available for validation formats Date, you must select the Date format
first.
2. Time picker is only available for Time validation format, you must select the Time format first.
3. The popup calendar and time picker are not developed by the author of PHPMaker and no
technical support will be provided. (See Third-party Tools.)

Required Check this checkbox if the field is mandatory.

Notes
1. If the field is defined as NOT NULL in your database, the field is required even this option is not
enabled. If you do not want to validate NOT NULL field, you can disable the advanced setting
Validate NOT NULL fields.
2. By default required fields will be denoted by an asterisk beside the field caption. You can change
the asterisk to other or remove it in the language file.

Error message Enter the error message to popup if error occurs.

Note If you use Multi-Language (see PHP Settings), use Multi-Language Property Editor, see Tools
for details.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 75 of 168

Check duplicate Specify whether to check duplicate values for the field before editing or inserting a record.

If the field is an unique indexed field, PHPMaker will generate server side codes to check duplicate values
automatically even this option is not selected. This option is useful when you want to check a non unique
indexed fields for duplicated values.

Add Page

Properties

Add Show field in add page

Note The setting is for Add page only, NOT for Inline/Grid-Add/Edit and Master/Detail-Add Edit in the List page.
See the List setting above.

Default Value Default value for field (for adding new record only) .

The value must be a valid PHP expression. (If it is a string, must be single or double quoted.)

Multi-Update Page

Properties

Multi-Update Show field in Multi-Update page

If a field is selected, it will be included in the Multi-Update page. In the generated Multi-Update page, there is a
checkbox for each field, the field will only be updated if the checkbox is checked so users can update only the checked
fields without affecting values of the other unchecked fields.

Advanced Search Page

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 76 of 168

Properties

Search Show field in Advanced Search page (Note: NOT related to Quick Search)

Search Opr 1 Search operator #1 for the field. Used in Advanced Search or Extended Quick Search.

Default Value Default value for Search Opr 1.

The value must be a valid PHP expression. (If it is a string, must be single or double quoted.)

Search Opr 2 Search operator #2 for the field. Used in Advanced Search or Extended Quick Search.

Notes
1. This second search operators will be useful when you need 2 criteria for the field when searching. You can
also select AND/OR to relate the 2 criteria during runtime.
2. If you want to use "BETWEEN" search operator, select "BETWEEN" as the first search operator. Since
"BETWEEN" requires 2 search criteria, when it is used, the second search operator will be ignored.

Default Value 2 Default value for Search Opr 2 .

The value must be a valid PHP expression. (If it is a string, must be single or double quoted.)

Also See:

Custom Fields

 ©2002-2019 e.World Technology Ltd. All rights reserved.

Lookup Table
Lookup Table is used for lookup field with Text (Auto-Suggest), Radio, Checkbox and Select Edit Tags. To enable, check User lookup
table under Edit Tag panel after selecting one of the Edit Tags.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 77 of 168

Table name Required. The lookup table to be linked to.

Link field Required. The field to be used as the value of an option. Note that this is the actual value to be submitted by the
form This field is usually the key field of the lookup table.

Display field #1 Required. The field in lookup table to be used as the label of an option.

Display field #2 Optional. The 2nd field in lookup table to be included in the label.

Display field #3 Optional. The 3rd field in lookup table to be included in the label.

Display field #4 Optional. The 4th field in lookup table to be included in the label.

Order By Optional. Specify a field in the lookup table for sorting the options.

Asc/Desc Optional. Sorting order. For use with Order By.

Distinct Optional. Specify adding DISTINCT option to the SELECT statement for the lookup table.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 78 of 168

Filter Optional. Specify the WHERE clause of the SELECT statement for the lookup table. The input should be a valid
PHP expression. If it is a string, it should be quoted.

If your lookup table has a special field (e.g. named "ALookupTableField") for filtering the records by a field (e.g.
named "AField") in the current record (of the current table), you can enter:

(strval(CurrentPage()->AField->CurrentValue) <> "") ? "`ALookupTableField` = " . CurrentPage()


->AField->CurrentValue : ""

Notes:

1. Make sure your expression returns a valid string. If some variables in the expression has empty values, the
expression will return an incomplete WHERE clause leading to no records returned from the lookup table.
So you should always check if the variables has non empty values first. If empty, return an empty string (i.e.
no filter) as in above example.

2. If the field in the WHERE clause is of string type, remember to single-quote it. For example, if
ALookupTableField in above example is of VARCHAR type, you need to quote the value by single quotes,
e.g.

a. if the value is fixed,

"`ALookupTableField` = 'SomeValue'"

b. if the value needs to be escaped,

(strval(CurrentPage()->AField->CurrentValue) <> "") ? "`ALookupTableField` = " . QuotedValue


(CurrentPage()->AField->CurrentValue, DATATYPE_STRING) : ""

3. This setting is used in all pages. If you want to used in some pages only, you should add your conditions,
e.g. if you just want to use your filter in the Edit page,

(CurrentPageID() == "edit") ? "`ALookupTableField` = 'SomeValue'" : ""

4. This setting is an one-liner. If your logic is complex and cannot be implemented in one line, you can write a
function and enter a function call, e.g.

MyLookupFilterFunction()

You can also pass some variables to your function as arguments, e.g.

MyLookupFilterFunction(CurrentPage()->AField->CurrentValue)

Your function should return a valid WHERE clause, e.g.

function MyLookupFilterFunction($value) {
if (strval($value) <> "") {
return "`ALookupTableField` = " . $value; // assume ALookupTableField is integer field
} else {
return "";
}
}

You can place your function in Global Code section under Server Events/Client Scripts. (See Server
Events and Client Scripts.)

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 79 of 168

Parent field #1 Optional. For use with dynamic selection lists. Specify the parent field (in the current table) for the current
selection list.

When the parent selection list is changed, the available options in current selection list will be changed
accordingly. Each field can have up to 4 parent fields.

Note Parent field is solely used with Filter field for dynamic selection lists only. Each Parent field MUST
have a corresponding Filter field. The Parent field alone does NOT do any filtering.

Filter field #1 Optional. For use with dynamic selection lists. Specify the filter field (in the lookup table) for filtering.

When the parent selection list changes, only options (records from the lookup table) with Filter field value
matching the selected value(s) of its corresponding Parent field will be shown.

Note Filter field is solely used with Parent field for dynamic selection lists only. Each Filter field MUST
have a corresponding Parent field. The Filter field alone does NOT do any filtering.

Parent/Filter #2 Optional. For use with dynamic selection lists. The 2nd pair of parent field and filter field.

If setup, the filtering of lookup table records will be based on 2 fields.

For example, if you have set up Parent/Filter field #1 and Parent/Filter field #2, and both Parent field #1 and
Parent field #2 have selected value, the records will be filtered by:

(Filter field #1 value = Parent field #1 selected value) AND (Filter field #2 value = Parent field #2
selected value)

Note By default, if either parent field is not selected, above filter will lead to no results, the field will not
have any options.

Parent/Filter #3 Optional. For use with dynamic selection lists. The 3rd pair of parent field and filter field. If setup, the filtering of
lookup table records will be based on 3 fields.

Parent/Filter #4 Optional. For use with dynamic selection lists. The 4th pair of parent field and filter field. If setup, the filtering of
lookup table records will be based on 4 fields.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 80 of 168

Allow add Optional. If enabled, the user will be allowed to add an option to the selection list.

Notes
1. Review your lookup table design before using this option. The option works best if you there is only
one display field and the link field (primary key) is an autoincrement field. In that case the user only
need to fill in a textbox and the option is added. But if the link field (primary key) is not an auto-
increment field, the user will need to enter the link field value which the user may not know.
2. The user will be asked to enter the link field and the display field(s) only. If the lookup table has other
NOT NULL fields other than the link field and display field(s), the new option cannot be added.
However, you can define default values for these fields in the database (not in PHPMaker).
3. This feature is implemented using Ajax.
4. Adding fields other than the link field, display fields and filter field is allowed. Click the [...] button
and select additional fields in the lookup table. However, please note that this feature is designed for
adding a lookup value on-the-fly only, it is NOT supposed to replace the full-featured Add page of
the lookup table. Although file upload and JavaScript features such as popup calendar and HTML
editor are also allowed (v9+), there may be chances that they do not work properly in the popup
form. You should choose as few fields as possible. Also, note that the add option form for each
lookup table is shared among all fields (possibly in different tables) using the same lookup table. If
you change the fields to be added to the lookup table, the shared add option form will affect other
fields as well.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 81 of 168

Auto fill Optional. If enabled, the script fills the target fields for you automatically.

For example, when you select a product number (which is a lookup field using the product table as its lookup
table), it will fill product price textbox for you.

Note Before using Auto-Fill, review your database design, you should consider database normalization, in
many cases you do NOT need to and you should NOT copy the field values from one table to another. You
can view the other field values by creating a query/view joining the current table with the lookup table
using the parent field as linked field.

The required conditions are:

1. The field has Lookup Table and Link field,


2. The field is setup as Radio or Select with Multiple disabled (i.e. "select-one" only),
3. Auto fill is enabled,
4. Source Fields and Target Fields are set up.

If properly set up, when the user changes the selected value of the field, the scripts will try to use other field
values (specified by [Source Field]) of the selected record (from the lookup table) to fill the target fields of the
current table (specified by [Target Field]) automatically.

Click the [...] button and select the source fields and target fields:

Note Remember that the actual field values of the Source Field and Target Field as stored in the database
will be used. The data types of the Source Field and the Target Field must match. If the Source Field has
Lookup Table, its actual field value (NOT its Display Field value) is used. Similarly, if the Target Field has
Lookup Table, you should fill it with a Source Field value that matches its actual field value (NOT its Display
Field value).

In this example, when you select a product from combobox, the script know the product ID from the option
value, so it can use the ID to locate the product from the same lookup table (your product table) and retrieve
other field values such as the product unit price and fill the target fields.

Note Do NOT setup fields to autofill each other. For example, if you set up field A to autofill field B (A ->
B) and B -> A, it will be an infinite loop. Similarly, if you setup A -> B and B -> C and C -> A, it will not
work either.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 82 of 168

Allow sort/search Enable sorting and searching of the looked-up values. For use with Select (select-one) or Radio or Text Edit Tag
only.

Since display values are field values in the lookup table (not in the main table), they are retrieved dynamically by
code during execution of the script and normally the field cannot be sorted or searched by the display values.
PHPMaker makes it possible by adding a subquery to the SQL to create a virtual field in the main table.

Limitations
1. No multiple selection. Select Edit Tag with Multiple enabled and Checkbox Edit Tag are not
supported.
2. No lookup table filter or table filter. If the lookup table has filter, the subquery becomes too
complex and the SQL will not be supported by the database. The table filter and lookup table filter
will be ignored.
3. May not work with all databases. With subqueries the SQL become more complex than usual,
especially for Custom View, the SQL may not be supported by your database. (This is another reason
why you should always use database query/view whenever possible, see Using Custom View.)
4. Enable as few fields as possible. Since the SQL become more complex, there is performance
penalty, so do not blindly enable this feature for all lookup fields.

Text input for search Enable text input for the field in the search forms. For use with Select (select-one) or Radio or Text Edit Tag
with Allow sort/search enabled.

If Edit Tag is not Text (i.e. Select or Radio) and you have enabled Allow sort/search, you may want to search
with a textbox instead of combobox or radio buttons. If so, enable this setting. Note that if Edit Tag is Text and
you have enabled Allow sort/search, the input is textbox, this setting is enabled automatically even you have
not checked this setting to enable it explicitly.

Note NOT compatible with Dynamic Selection Lists. When this option is enabled, the form element value
(and the submitted value) is always the text input (not the Link field value) for searching to work.
Therefore, if the field is a parent field in Dynamic Selection Lists (see below), the child fields may not work
in the search forms.

Option Template
By default, the options are displayed as comma separated values of the display field values. If you just want to change the display value
separator from comma to other string, you can use server events such as Page_Load (see Server Events and Client Scripts) to set the field
object's DisplayValueSeparator property, e.g. if the field name is "MyField",

$this->MyField->DisplayValueSeparator = "-"; // Use hyphen as separator

$this->MyField->DisplayValueSeparator = [",", "|", "-"]; // Array of separators (max. 3) for display field #2 to #4

However, if you want to display the link field and the display fields in your own HTML, you can use Option Template, just write your
HTML code in [Option template] under [Edit Tag] panel, e.g. if you have settings like:

and you enter Option Template like:

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 83 of 168

<span class="text-info">{{:df1}}</span> <small class="text-muted">({{:df2}})</small>

Then the options for the field will be displayed in your HTML format like:

Option Template supports the following tags:

{{:lf}} Link field value


{{:df1}} Display field #1 value

{{:df2}} Display field #2 value

{{:df3}} Display field #3 value

{{:df4}} Display field #4 value

Note Option template is JsRender template, you are not limited to {{:...}}, there are other tags for you to build an advanced
Option Template, refer to JsRender API for more details. 

If the options needs to show some additional data from the lookup table, you can get the additional data as Display fields so you can use
them in Option Template. If you use Text Edit tag (see Field Setup), sometimes you may not need the additional data in the input
textbox, then again you can set the DisplayValueSeparator property by server event. If the separator for a display field is not specified,
the display field value will not be placed in the input textbox. There are 3 possible settings:

$this->MyField->DisplayValueSeparator = []; // No separators, display field #2 to #4 hidden

$this->MyField->DisplayValueSeparator = [", "]; // One separator only, display field #3 to #4 hidden

$this->MyField->DisplayValueSeparator = [",", "|"]; // Two separators only, display field #4 hidden

Ajax by API and Client Scripts


Sometimes you may want to access the lookup table by Ajax yourself. For example, after the user entering a value for a field, you may
want to auto-fill another field in your own way, then you can use API and Client Scripts to do it (in such cases do not enable the built-in
Auto-Fill in the Lookup Table panel). Say, if you want to fill the product price when you select a product number (using products table as
lookup table) when inserting a new record, you can auto-fill the product price in orderdetails table either asynchronously or
synchronously with your code.

Example 1 - Auto-Fill asynchronously by "view" action of API

Write a Startup Script (JavaScript) for Add Page (e.g. orderdetails) to attach onchange event and get data from other table (e.g. products)
by "view" action of API.

$("#x_ProductID").change(function() {
var url = ew.API_URL, object = "products", action = "view", key = encodeURIComponent($(this).val());
//$.get(url + "/" + action + "/" + object + "/" + key + "?token=" + ew.ANTIFORGERY_TOKEN, function(res) { // URL format if
URL Rewrite enabled
$.get(url + "?action=" + action + "&object=" + object + "&key=" + key + "&token=" + ew.ANTIFORGERY_TOKEN, function(res)

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 84 of 168

{ // Get response from API


if (res && res.success) {
var row = res[object];
$("#x_UnitPrice").val(row["UnitPrice"]); // Set the result (manipulate it first if necessary) to the target field
} else {
alert(res.failureMessage);
}
});
});

Notes

1. This example uses the lookup API so there is no need to write server side code.
2. If action = "view", you get a record (object) by passing the primary key in URL. For composite keys, separate the key values by
the composite key separator (default is ","). The result is one record only.
3. If action = "list", you get records (array of objects) by passing search parameters in URL (see URL in List page after searching),
the result is an array of records.
4. If User ID and/or User Level Security is enabled, the records and/or pages are still protected. For example, if the user does not
have permission to the View page, the "view" action is not allowed.
5. The values returned from API are database values. You may format them with your code for your specific needs.

Example 2 - Auto-Fill synchronously by ew.ajax()

Write a Startup Script (JavaScript) for Add Page to attach onchange event.

$("#x_ProductID").change(function() {
var data = { "action": "lookup", "linkTable": "products", "linkField": "ProductID", "displayFields": ["UnitPrice"],
"lookupValue": encodeURIComponent($(this).val()) };
var row = ew.ajax(data);
if (row && row["UnitPrice"])
$("#x_UnitPrice").val(row["UnitPrice"]); // Set the result (manipulate it first if necessary) to the target field
});

Note The built-in function ew.ajax() uses the lookup API so there is no need to specify URL.

Example 3 - Auto-Fill asynchronously by ew.ajax()

Write a Startup Script (JavaScript) for Add Page to attach onchange event. Also see note in Example 2.

$("#x_ProductID").change(function() {
var data = { "action": "lookup", "linkTable": "products", "linkField": "ProductID", "displayFields": ["UnitPrice"],
"lookupValue": encodeURIComponent($(this).val()) };
ew.ajax(data, function(row) { // Pass a callback function as the second parameter of ew.ajax()
if (row && row["UnitPrice"])
$("#x_UnitPrice").val(row["UnitPrice"]); // Set the result (manipulate it first if necessary) to the target field
});
});

Example 4 - Auto-Fill asynchronously by custom API action and client script

Write a custom API handler, say "getUnitPriceByProductID", and add it in server side Global Code to return the required value. In this

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 85 of 168

example, only a single value is required so ExecuteScalar() (see Some Global Functions in Server Events and Client Scripts) is used, e.g.

$API_ACTIONS["getUnitPriceByProductID"] = function(Request $request, Response $response) {


$productId = Param("ProductID"); // Get the input value from $_GET or $_POST
if ($productId !== NULL)
Write(ExecuteScalar("SELECT UnitPrice FROM products WHERE ProductID = " . AdjustSql($productId))); // Output field
value as string
};

If you want to return a whole row as JSON, you may use WriteJson() in combination with ExecuteRow() (see Server Events and Client
Scripts), e.g.

WriteJson(ExecuteRow("SELECT * FROM products WHERE ProductID = " . AdjustSql($productId))); // Output the row (array) as JSON

Write a Startup Script (JavaScript) for Add Page to attach onchange event:

$("#x_ProductID").change(function() {
var url = ew.API_URL, action = "getUnitPriceByProductID", id = encodeURIComponent($(this).val());
//$.get(url + "/" + action + "?ProductID=" + id, function(res) { // URL format if URL Rewrite enabled
$.get(url + "?action=" + action + "&ProductID=" + id, function(res) { // Get response from custom API action
if (res)
$("#x_UnitPrice").val(res); // Set the result (manipulate it first if necessary) to the target field
});
});

Use Modal Dialog for Lookup


For Edit Tags with lookup table (i.e. TEXT/SELECT/RADIO/CHEKCBOX), you can choose to enable Use Modal Dialog for Lookup to
replace the Edit Tag with a modal dialog. The modal dialog does not only allow user select a record from the lookup table, but also
supports searching and paging.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 86 of 168

Note The modal dialog is same for TEXT/SELECT/RADIO/CHEKCBOX, while it has the same functionality of allowing user to select a
record from the lookup table, it is NOT the original inputs (i.e. selection list, radio buttons, checkboxes, or dropdown list) anymore.

 ©2002-2019 e.World Technology Ltd. All rights reserved.

Server Events and Client Scripts


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 PHP procedures

Global The events are applicable to all PHP 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

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 87 of 168

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
PHPMaker provides a Code Repository 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. 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
3. globalcode - common code to be inserted to Global Code (see below), this code will only be inserted once into the project. For
example , if your code is used several times in your project and your code calls a helper function, it is unnecessary to include the
helper function several times. In this case you put your helper function in the globalcode section, then the function will only be
included one time.

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: (not all pages are the same)

• Global Code (Global)


• Language_Load (Language class method)
• Database_Connecting/Connected (Global function)
• User_CustomValidate (Security class method)
• UserLevel_Loaded (Security class method)

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 88 of 168

• 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 function)
• Page_Load (Page class method)
• Page_Rendering (Global function)
• Page_Render (Page class method)
• Page_Head (Global)
• MenuItem_Adding (Global function)
• Menu_Rendering/Rendered (Global function)
• Page_DataRendering (Page class method)
• Recordset*/Grid*/Row* (Page class method)
• Page_DataRendered (Page class method)
• Page_Foot (Global)
• Page_Unload (Page class method)
• Page_Unloaded (Global function)
• Page_Redirecting (Page class method)

Notes
1. The page classes inherit from the table classes, so you can use $this in the page class methods to access table class members.
For backward compatibility, the table object is kept and it is an alias of the page object, so you can also use $this in the table
class methods to access page class members.
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 a server event is a global function, there is NO $this in the function context. If you want to refer to the current page object,
you can use the global function CurrentPage().
4. In the following table, the <fieldname> in code, e.g. in $this-><fieldname>-><property> or x_<fieldname>, represents the field
variable name (see Database, Table and Field Variable Names). 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.
5. Server events are functions or class methods, if you need to use global variables in the events, note the PHP variable scope,
you must use the global keyword or $GLOBALS.

Available server events are:

Global -> All Pages

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 89 of 168

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

For example, PHPMaker does NOT support jQuery UI, AdminLTE plugins, or other jQuery plugins, but you
can include them yourself. Then you can use the widgets using Startup Script (see below).

Example 1

Include jQuery UI by PHP (using CDN):

AddStylesheet("//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css"); // Add CSS


stylesheet
AddClientScript("//code.jquery.com/ui/1.10.3/jquery-ui.js"); // Add JavaScript

Example 2

Alternatively, you can include by HTML:

<link rel="stylesheet" href="//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">


<script src="//code.jquery.com/ui/1.10.3/jquery-ui.js"></script>

Example 3

You can even use both PHP and HTML, but in such case you MUST use <?php ... ?>, e.g.

<?php AddStylesheet("//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css"); ?>


<script src="//code.jquery.com/ui/1.10.3/jquery-ui.js"></script>

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 90 of 168

Page_Foot The code you entered in this event will be placed in the footer.php 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 dropdown menu on the right navbar by JsRender template

<script type="text/html" class="ew-js-template" data-name="myDropdown" data-method="prependTo"


data-target="#ew-navbar-right" data-seq="10">
<li class="nav-item dropdown">
< a class="nav-link" data-toggle="dropdown" href="#">
< i class="fa fa-bell-o"></i>
< span class="badge badge-warning navbar-badge">15</span>
< /a>
< div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
< span class="dropdown-item dropdown-header">15 Notifications</span>
< div class="dropdown-divider"></div>
< a href="#" class="dropdown-item">
< i class="fa fa-envelope mr-2"></i> 4 new messages
< span class="float-right text-muted text-sm">3 mins</span>
< /a>
< div class="dropdown-divider"></div>
< a href="#" class="dropdown-item dropdown-footer">See All Notifications</a>
< /div>
< /li>
</script>

Example 2 - Add a control sidebar on the right side of the site.

Note Control sidebar requires default AdminLTE layout and therefore does NOT work properly if
the Reset Layout Height setting is disabled (see Advanced Settings).

<aside class="control-sidebar control-sidebar-light">


< div class="p-3"><!-- Control sidebar content goes here --></div>
< /aside>

<script type="text/html" class="ew-js-template" data-name="myControlSidebar" data-


method="prependTo" data-target="#ew-navbar-right" data-seq="10">
<li class="nav-item">
<a class="nav-link" data-widget="control-sidebar" data-slide="true" href="#"><i class="fa
fa-th-large"></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="ew-js-template">...</script>. Using these templates you can change
virtually everywhere of the whole layout. Note: The CSS class name "ew-js-template" 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.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 91 of 168

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 ew.vars
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 ew.vars.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.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 92 of 168

Database_Connecting This event will be called by all PHP pages before connecting to the database. Note: This is a global
function.

If general, the argument is an array with the following keys: host, port, user, pass, db. If Access, the key
is connectionstring. 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

// MySQL/PostgreSQL
function Database_Connecting(&$info) {
//var_dump($info);
// assume the scripts are generated with connection info for local PC
if (CurrentUserIP() <> "127.0.0.1") { // not connecting to local PC
// connect to the production database
$info["host"] = "localhost";
$info["user"] = "xxx";
$info["pass"] = "yyy";
$info["db"] = "production_db";
}
}

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.

// MySQL/PostgreSQL
function Database_Connecting(&$info) {
//var_dump($info);
if (preg_match('/login|userpriv/', CurrentPageID()) { // login.php or userpriv.php
// connect to the common database with the common Advanced Security tables
$info["host"] = "localhost";
$info["user"] = "xxx";
$info["pass"] = "yyy";
$info["db"] = "common_db";
}
}

Database_Connected This event will be fired by all PHP pages after connecting to the database. Note: This is a global
function.

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

Example

Call a stored procedure after connection.

function Database_Connected(&$conn) {
$conn->Execute("CALL MyStoredProcedure");
}

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 93 of 168

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

function Language_Load() {
$this->setPhrase("MyID", "MyValue"); // Refer to language file for the actual phrase id
$this->setPhraseClass("MyID", "fa fa-xxx ew-icon"); // Refer to
https://fontawesome.com/v4.7.0/icons/ for icon name
}

Example 2

Change the HTML markup of the language selector.

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

Page_Loading This event will be called by all PHP 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 function, NOT page class member.

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

Page_Unloaded This event will be called by all PHP 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 function, NOT page class member.

Global Code Code to be included in all PHP pages. This may contain your constants, variables, functions and classes.

Example 1

Use another class for Export to Excel (not PhpSpreadsheet)

class MyExportExcel extends ExportExcel {

// Override ExportTableheader()
function ExportTableHeader() {
$this->Text .= "<div>" . $this->Table->TableCaption() . "</div>"; // Add table caption
parent::ExportTableHeader(); // Call the parent method
}

$EXPORT['excel'] = 'MyExportExcel'; // Replace the default ExportExcel class by your own class

Example 2

Add AWS SDK for PHP to composer.json (see Using User Code) and register Amazon S3 Stream Wrapper

putenv("AWS_ACCESS_KEY_ID=xxx"); // Change to your own access key ID


putenv("AWS_SECRET_ACCESS_KEY=xxx"); // Change to your own secret access key
$s3client = new \Aws\S3\S3Client([
"version" => "latest",
"region" => "us-east-2" // Change to your own region
//, "http" => ["verify" => FALSE] // Disable certificate verification (this is insecure!)
]);
$s3client->registerStreamWrapper();

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 94 of 168

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

Remove the domain name to match the user name in user table (for User ID/Level Security, if enabled)
after Windows authentication, if the user table stores the user name without domain name.

function User_CustomValidate(&$usr, &$pwd) {


if (IsAuthenticated()) { // Windows authentication
$ar = explode("\\", $usr);
if (count($ar) > 1)
$usr = $ar[1]; // Return the user name only
}
}

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

Check groups of Active Directory user.

function Ldap_Validated(&$usr, &$pwd) {


// Do something (if any) after binding an user successfully, for example, use the Search()
method which returns entries directly
// The arguments are $base_dn, $filter and $attributes, see ldap_search, actual values
depending on LDAP server.
$entries = $this->Search("OU=Departments,DC=college,DC=school,DC=edu", // Base DN for the
directory
"(sAMAccountName=" . $this->User . ")", // Search filter
["memberof"]); // Attributes
foreach ($entries[0]["memberof"] as $grp) { // Check groups
if (in_array($grp, ["group1", "group2"]))
return TRUE;
}
return FALSE; // Return TRUE/FALSE to validate the user
}

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 95 of 168

User_Validated For use with security. (See Security Settings) This event is fired after validating the user with the user
table. 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. If the user is found in the user table, the argument $rs is an array, you can get a field value by
$rs['<fieldname>']. If the user is not found, $rs is NULL. By default most user info is already
loaded into the global user profile object, Profile(), but the info does not include the
password field, BLOB fields, and memo fields, you can use this event to get more info from
the user table.
3. You can use this event to override the user name, User ID, Parent user ID and User Level (if
User ID/Level Security is enabled) for the validated user by the LoginUser() method of the
security class. The arguments of the method are:
function LoginUser($userName = NULL, $userID = NULL, $parentUserID = NULL, $userLevel
= NULL)
If any argument is NULL, the corresponding property will not be affected.

Example 1

Add additional current user info to the global user profile object

function User_Validated(&$rs) {
Profile()->Set("Notes", $rs["Notes"]); // Set additional data to the profile object
Profile()->Save(); // Save to session
}

You can get it later elsewhere by Profile()->Get("Country").

Example 2

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

function User_Validated(&$rs) {
if ($rs["PasswordExpired"] == "Y") { // Assume the user table has a field named
"PasswordExpired" storing if the password has expired
Profile()->setPasswordExpired($rs["Username"]); // Assume the user name field is named
"Username"
return FALSE; // Return FALSE to invalidate the user
}
}

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 96 of 168

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 1

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
function UserLevel_Loaded() {
$this->deleteUserPermission("Sales", "orders", ALLOW_ADD); // The first 2 arguments can also
be array
$this->addUserPermission("Sales", "orders", ALLOW_EDIT); // The first 2 arguments can also be
array
}

Example 2

Grant all permissions to 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
function UserLevel_Loaded() {
$this->addUserPermission("Manager", "employees", ALLOW_ALL); // The first 2 arguments can
also be array
}

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 97 of 168

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 cMenuItem 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 is
a global function.

Example 1

Only show a menu item after the user has logged in

function MenuItem_Adding(&$item) {
//var_dump($Item);
// Return False if menu item not allowed
if ($item->Text == "Download")
return Security()->IsLoggedIn();
return TRUE;
}

Example 2

Set the menu item properties

function MenuItem_Adding(&$item) {
//var_dump($item);
if ($item->Text == "Download")
$item->Icon = "fa-download";
if ($item->Text == "Something")
$item->Label = "<small class=\"label float-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.php to see the item names
or URLs.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 98 of 168

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 is a global function.

Example 1

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

function Menu_Rendering($menu) {
if ($menu->Id == "menu") { // Sidebar menu or change from "menu" to "navbar" for top menu
$menu->addMenuItem(10000, "MyName", "MyMenuText", "MyPage.php", -1, "", IsLoggedIn());
$menu->moveItem("Logout", $menu->Count() - 1); // Move to last
}
}

Example 2

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

function Menu_Rendering(&$menu) {
if ($menu->Id == "menu") { // Sidebar menu
$menu->Clear(); // Clear all menu items
$menu->addMenuItem(1, "MyName1", "MyMenuText1", "MyPage1.php");
$menu->addMenuItem(2, "MyName2", "MyMenuText2", "MyPage2.php");
}
}

Example 3

Change options of sidebar menu (vertical menu).

function Menu_Rendering(&$menu) {
if ($menu->Id == "menu") { // sidebar menu
$menu->Accordion = FALSE; // Whether to collapse the open menu when expanding another,
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 is a global function.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 99 of 168

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
function TablePermission_Loading() {
if (CurrentUserName() == "nancy")
$this->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 setCanXXX
methods 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
function TablePermission_Loaded() {
if (CurrentUserName() == "nancy" && CurrentTable()->TableName == "orders")
$this->setCanEdit(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
function UserID_Loading() {
if (CurrentParentUserID() <> "")
$this->CurrentUserID = CurrentParentUserID();
}

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 100 of 168

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
function UserID_Loaded() {
if (CurrentUserName() == "nancy")
$this->AddUserName("janet"); // Add User ID by user name
}

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. Note: This is a global function.

PersonalData_Downloading This event will be called when Use Personal Data Page is enabled and before the user downloads his
personal data. The personal data is passed to the event as an associative array, you can get the
information by $row["<fieldname>"] where <fieldname> is an user table field name. You can also add
additional data to the array so it will also be downloaded by the user. Note: This is a global function.

PersonalData_Deleted This event will be called when Use Personal Data Page is enabled and before the user deletes his
personal data. The personal data is passed to the event as an associative array, you can get the
information by $row["<fieldname>"] where <fieldname> is an user table field name. Note: This is a
global function.

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.

function Recordset_Selecting(&$filter) {
AddFilter($filter, "Field1 = 1234"); // Add your own filter expression
}

Recordset_Selected This event will be called after selecting records. Note: The argument is the recordset object (not array).

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 101 of 168

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

function Recordset_SearchValidated() {
$this->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

Search a MySQL DATE field for a selected date or within 3 days after the selected date.

function Recordset_Searching(&$filter) {
//die($filter); // Uncomment to view the filter first
$filter = preg_replace('/`MyDateField` = (\'\d{4}-\d{2}-\d{2}\')/', '`MyDateField` >= $1 AND
`MyDateField` < DATE_ADD($1, INTERVAL 3 DAY)', $filter); // 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.

function Row_Deleted(&$rs) {
// Assume ForeignKeyField is of integer type
Execute("DELETE FROM DetailTable WHERE 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.

function Row_Inserting(&$rsold, &$rsnew) {


if ($rsnew["Percentage"] > 100)
$rsnew["Percentage"] = 100;
// To cancel, set return value to False
return TRUE;
}

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 102 of 168

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

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

function Row_Inserted(&$rsold, &$rsnew) {


$this->setSuccessMessage("Record Inserted. The ID of the new record is " . $rsnew["ID"]);
}

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 PHP's
var_dump function in the server event, e.g.

var_dump($this->RowAttrs);
var_dump($this->Trademark);
var_dump($this->Trademark->CellAttrs);
var_dump($this->Trademark->EditAttrs);
var_dump($this->Trademark->ViewAttrs);

Example

Change CSS styles of row and cells:

function Row_Rendered() {
// Change the row color in List page by Bootstrap classes
if ($this->Trademark->CurrentValue == 1) // List page only
$this->RowAttrs["class"] = "info";
// Change the table cell color
if ($this->PageID == "list" || $this->PageID == "view") { // List/View page only
if ($this->Cyl->CurrentValue == 4) {
$this->Cyl->CellAttrs["style"] = "background-color: #ffcccc";
} elseif ($this->Cyl->CurrentValue == 6) {
$this->Cyl->CellAttrs["style"] = "background-color: #ffcc99";
} elseif ($this->Cyl->CurrentValue == 8) {
$this->Cyl->CellAttrs["style"] = "background-color: #ffccff";
}
}

// Change text style by Bootstrap classes


if ($this->Category->CurrentValue == "SPORTS")
$this->Category->ViewAttrs["class"] = "bg-warning text-warning";
}

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 103 of 168

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. The
event is still fired when inserting a new record, but in such case there is no "selected" row and the
argument is an array with all field values as NULL.

Example

Disable a field in Edit page

function Row_Selected(&$rs) {
if ($this->PageID == "edit") // Edit Page only
$this->MyField->Disabled = ($rs["MyField"] == "xxx"); // Disable a field if the field
value equals some value
}

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

function Row_Updating(&$rsold, &$rsnew) {


if ($rsnew["Qty"] < $rsold["Qty"]) {
// To cancel, set return value to False
$this->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.

function Row_Updated($rsold, &$rsnew) {


//var_dump(rsold, rsnew); die(); // Print the old and new record and end the script
$rs = ["FieldInMasterTable" => $rsnew["FieldInDetailTable"]]; // Set field values
(new MasterTable())->Update($rs, "PrimaryKeyFieldInMasterTable = " . $rsold
["ForeignKeyFieldInDetailTable"]); // Note: Table class is named as <TableName>. Assume
PrimaryKeyFieldInMasterTable is integer.
}

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 104 of 168

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.

function Grid_Inserting() {
$rsnew = $this->GetGridFormValues(); // Get the form values of the new records as an array of
array
//var_dump($rsnew); die(); // Print the records and end the script
$sum = 0;
foreach ($rsnew as $row) // Loop through the new records
$sum += intval($row["Percentage"]);
if ($sum < 100) {
// To cancel, set return value to False
$this->setFailureMessage("The total of 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.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 105 of 168

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.

function Grid_Updating($rsold) {
$rsnew = $this->GetGridFormValues(); // Get the form values of the new records as an array of
array
//var_dump($rsnew); die(); // Print the records and end the script
$oldtotal = 0;
foreach ($rsold as $row) // Loop through the old records
$oldtotal += intval($row["Subtotal"]);
$newtotal = 0;
foreach ($rsnew as $row) // Loop through the new records
$newtotal += intval($row["Subtotal"]);
if ($newtotal < $oldtotal) {
// To cancel, set return value to False
$this->setFailureMessage("The new total must be larger than the old total.");
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_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.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 106 of 168

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.

If Add, the new record in the format of array can be access by $args["rsnew"].
If Copy, the old record in the format of array can be access by $args["rsold"].
If Edit/Update, the old data of the records in the format of array can be access by $args["rsold"], the
new data of the records in the format of array can be access by $args["rsnew"].
If Register, the new record in the format of array can be access by $args["rs"].

You can get a field value by, e.g.

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

or

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

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

If Grid-Add/Edit or Update page, there are more than one records, the arguments are array of array.

Example

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

function Email_Sending($email, &$args) {


//var_dump($email, $args);
//exit();
if (CurrentPageID() == "add") { // If Add page
$email->Recipient = $args["rsnew"]["MyEmailField"]; // Change recipient to a field value
in the new record
$email->Subject = "My New Subject"; // Change subject
$email->Content .= "\nAdded by " . CurrentUserName(); // Append additional content
}
return TRUE;
}

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 107 of 168

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 field name, Lookup object and filter for the lookup can be viewed by:

var_dump($fld->Name, $fld->Lookup, $filter);

$fld->Lookup is an object. To change the lookup SQL, you can modify the following properties of the
Lookup object:

UserSelect SELECT Statement (SELECT clause and FROM clause only)

UserFilter WHERE clause

UserOrderBy ORDER BY clause

Example 1

Add additional filter to the lookup table filter

function Lookup_Selecting($fld, &$filter) {


//var_dump($fld->Name, $fld->Lookup, $filter); // Uncomment to view the field name, Lookup
object and the filter
if ($fld->Name == "MyLookupField")
$fld->Lookup->UserFilter = "MyField = 'xxx'"; // Assume the field is of string type
}

Example 2

Change the default filter operator of a filter field

function Lookup_Selecting($fld, &$filter) {


if ($fld->Name == "MyLookupField") {
$fld->Lookup->UseLookupCache = FALSE; // Make sure that lookup cache is disabled
$fld->Lookup->setFilterOperator("FilterField", ">");
}
}

Example 3

Modify lookup SQL SELECT / ORDER BY

function Lookup_Selecting($fld, &$filter) {


if ($fld->Name == "MyLookupField") {
$fld->Lookup->UserSelect = "SELECT Field1 AS lf, Field2 AS df, Field3 AS df2, '' AS df3,
'' AS df4 FROM Table1"; // Modify SELECT
$fld->Lookup->UserOrderBy = "Field2 ASC"; // Modify ORDER BY
}
}

Example 4

Use static array

function Lookup_Selecting($fld, &$filter) {


if ($fld->Name == "MyLookupField")
$fld->Lookup->setOptions([
["link value 1", "display value 1", "display value 2", "...", ""],
["link value 2", "display value 1", "display value 2", "...", ""]
]); // Use static array
}

Example 5

Use data from ExecuteRows

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 108 of 168

function Lookup_Selecting($fld, &$filter) {


if ($fld->Name == "MyLookupField")
$fld->Lookup->setOptions(ExecuteRows("SELECT LinkField, DisplayField1, DisplayField2,
DisplayField3, DisplayField4 FROM LinkTable")); // Use data from ExecuteRows
}

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.

function UserID_Filtering(&$filter) {
AddFilter($filter, "MyUserIDField2 = " . 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.php is included. You can use this event to add content at the top
of page content.

Page_DataRendered This event will be called before the footer.php is included. 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.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 109 of 168

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".

Example

Replace an error message by custom message

function Message_Showing(&$msg, $type) {


if ($type == 'success') {
//$msg = "your success message";
} elseif ($type == 'failure') {
if (strpos($msg, "some standard message") !== FALSE) // The original message contains
some keywords you want to replace
$msg = "My custom message";
} elseif ($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 $this-><Field>->FormValue (e.g.
$this->HP->FormValue). Alternatively, you can get all the form values in an array first, e.g.

$rs = $this->GetFieldValues("FormValue");

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

function Form_CustomValidate(&$customError) {
$rs = $this->GetFieldValues("FormValue"); // Get the form values as array
if (intval($rs["Qty"]) % 10 <> 0) {
// Return error message in $customError
$customError = "Order quantity must be multiples of 10.";
return FALSE;
}
return TRUE;
}

Note If you use this server event, make sure you have enabled server-side validation, see
Validation in PHP Settings.

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.php is included. You can use this event to add content at the top
of page content.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 110 of 168

Page_DataRendered This event will be called before the footer.php is included. 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.php is included. You can use this event to add content at the top
of page content.

Page_DataRendered This event will be called before the footer.php is included. 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

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 111 of 168

Page_Load This event will be called after connecting to the database.

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 defaut 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:

function Page_Load() {
$item = @$this->ExportOptions->Items["pdf"];
if ($item)
$item->Visible = FALSE;
}

Example 2

Add a custom link at the end of the export links

function Page_Load() {
$item = &$this->ExportOptions->add("MyName");
$item->Body = "<a href='MyURL'>My Link</a>";
}

Example 3

Add a custom action to submit selected records by HTTP POST

function Page_Load() {
$this->CustomActions["star"] = "Add Star"; // Where "star" is the id and "Add Star" is the
caption of the custom action
}

Adding a custom action by its name and caption is a actually a short form of

$this->CustomActions["star"] = new ListAction("star", "Add Star");

and is supported for backward compatibility only. Use the ListAction class so you have more options for
the custom action. The constructor of ListAction class is

function __construct($action, $caption, $allow = TRUE, $method = ACTION_POSTBACK, $select =


ACTION_MULTIPLE, $confirmMsg = "", $icon = "fa fa-star ew-icon", $success = "")

$method is either ACTION_POSTBACK (submit by HTTP POST) or ACTION_AJAX (submit by Ajax).

$select is either ACTION_MULTIPLE (submit the selected records) or ACTION_SINGLE (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).

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 112 of 168

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

function Page_Load() {
$this->CustomActions["star"] = new ListAction("star", "Add Star", IsLoggedIn(), ACTION_AJAX,
ACTION_MULTIPLE, "Add Star to selected records?", "fa fa-star ew-icon");
}

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

Example 5

When Custom Templates (see Custom Templates) is used, they will be used for export to
Word/Excel/PDF/Email (not including PhpSpreadsheet and PHPWord) by default. You can however
change it.

function Page_Load() {
$item = @$this->ExportOptions->Items["excel"];
if ($item)
$item->Body = $this->getExportTag("excel", FALSE); // Do not use Custom Templates for
export to Excel
}

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.php is included. You can use this event to add content before
the main table.

Example

Hide a field from the main table

function Page_DataRendering() {
$this->MyField->Visible = FALSE; // Hide a field named "MyField"
}

Page_DataRendered This event will be called before the footer.php is included. 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.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 113 of 168

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
$this->ListOptions->Item["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
• 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.

function ListOptions_Load() {
$item = &$this->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 PHP
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.

function ListOptions_Load() {
$this->ListOptions->Items["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)

function ListOptions_Load() {
$this->DetailPages->Items["MyDetailTable"]->Visible = FALSE;
}

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 114 of 168

ListOptions_Rendering This event will be called before list options are rendered. To access field object of the current row, you
can use $this-><Field>-><Property> (e.g. $this->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"

function ListOptions_Rendering() {
$GLOBALS["orderdetails_grid"]->DetailAdd = (...condition...); // Set to TRUE or FALSE
conditionally
$GLOBALS["orderdetails_grid"]->DetailEdit = (...condition...); // Set to TRUE or FALSE
conditionally
$GLOBALS["orderdetails_grid"]->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

function ListOptions_Rendering() {
$this->Category->AddClass("some-class"); // Add CSS class to the field
}

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.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 115 of 168

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 $this-
><Field>-><Property> (e.g. $this->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.

function ListOptions_Rendered() {
if ($this->MyField->CurrentValue == "xxx") {
$this->ListOptions->Items["new"]->Body = "yyy";
} else {
$this->ListOptions->Items["new"]->Clear(); // Set Body = ""
}
}

Example 2

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

function ListOptions_Rendered() {
$this->ListOptions->Items["new"]->Body = "<a href=\"#\" onclick=\"return ew.submitAction
(event, {action: 'star', method: 'ajax', msg: 'Add star?', key: " . $this->KeyToJson(TRUE) .
"});\">Add Star</a>";
}

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

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 116 of 168

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 Mulit-
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.

function Row_CustomAction($action, $row) {


if ($action == "star") { // Check action name
$rsnew = ["Starred" => "Y", ...]; // Array of field(s) to be updated
$result = $this->update($rsnew); // Note: The Update() method updates the current record
only
if (!$result) { // Failure
$this->setFailureMessage("Failed to update record, ID = " . $row["ID"]);
return FALSE; // Abort and rollback
} elseif ($this->SelectedIndex == $this->SelectedCount) { // Last row
$this->setSuccessMessage("All selected records updated.");
}
return TRUE; // Success
}
}

Note If you cancel the action by returning FALSE in the event, you can use the setFailureMessage
() method 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 setSuccessMessage() method 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 $this->Export for the
export type (e.g. "excel", "word"). The content of the export document is $this->ExportDoc->Text (except
PhpSpreadsheet/PHPWord).

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 (not PhpSpreadsheet)

function Page_Exporting() {
if ($this->Export == "excel") {
$this->ExportDoc->Text = "<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
}

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 117 of 168

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 $this->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 (not PhpSpreadsheet)

function Row_Export($rs) {
if ($this->Export == "excel")
$this->ExportDoc->Text .= "<div>" . $this->MyField->ViewValue . "</div>"; // Build HTML
with field value: $rs["MyField"] or $this->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 (not PhpSpreadsheet)

function Page_Exported() {
if ($this->Export == "excel")
$this->ExportDoc->Text .= "my footer"; // Add a footer
//die($this->ExportDoc->Text); // View the whole export document for debugging
}

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 118 of 168

Page_Importing This server event allows you to modify the Import options before the import process begins. The first
argument is the data reader and the second argument is an array containing the import options. You can
also return FALSE to skip the import.

The options (accessed by $options["<value>"]) you can change during Page_Importing are:
maxExecutionTime - Maximum execution time for import
activeSheet - Active spreadsheet for import (default is 0, zero-based)
headerRowNumber - Header row number (default is 0, zero-based)
headers - Header array (default is empty array)
offset - Offset to start import (default is 0, zero-based)
limit - Number of records to import (default is 0, which means all records)
inputEncoding - Input encoding for data (CSV only)
delimiter - Delimiter for data (CSV only)
enclosure - Quote character for data (CSV only)

Example 1

Import selected records only

$options["offset"] = 10; // Skip the first 10th records


$options["limit"] = 5; // Import the next 5 records

Example 2

The spreadsheet contains pure data only. Supply the header manually.

$options["headers"] = ["CategoryName", "Description"];

Example 3

Change input encoding, delimiter and enclosure for CSV file

$options["inputEncoding"] = "CP1252"; // Use CP1252 for input encoding

$options["delimiter"] = ";"; // Semi Colon for delimiter

$options["enclosure"] = "'"; // Single Quote for enclosure

Row_Import This server event is executed before a record is imported. The first argument is an array containing the
data to be imported and the second argument is an integer containing the current import record count.
You can return FALSE to skip the import.

Example 1

Modify data before import

$row["Trademark"] = ExecuteScalar("SELECT ID FROM trademarks WHERE Trademark ='" . AdjustSql($row


["Trademark"]) . "'"); // Get Trademark ID from trademarks table

Example 2

Validate input data

if (intval($row["Quantity"]) > 100) // Quantity must be <= 100

return FALSE; // Skip import

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 119 of 168

Page_Imported This server event is executed after import is completed. The first argument is the data reader and the
second argument is an array containing the import results.

The data available in the results array are (accessed by $results["<value>"]):


file - File name of the imported file
totalCount - Total records imported
successCount - Total records imported successfully
failCount - Total records imported unsuccessfully
failList - Array containing failed imports and reasons

Example

Write audit trail for import

$msg = "imported " . $results["totalCount"] . " records (successful: " . $results


["successCount"] . " / failed: " . $results["failCount"] . ") from " . $results["file"]; // Set
up import message

WriteAuditTrail("log", DbCurrentDateTime(), ScriptName(), CurrentUserID(), $msg, CurrentUserIP(),


"", "", "", ""); // Write audit trail

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.php is included. You can use this event to add content at the top
of page content.

Page_DataRendered This event will be called before the footer.php is included. 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.php is included. You can use this event to add content at the top
of page content.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 120 of 168

Page_DataRendered This event will be called before the footer.php is included. 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.php is included. You can use this event to add content at the top
of page content.

Page_DataRendered This event will be called before the footer.php is included. 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.php is included. You can use this event to add content at the top
of page content.

Page_DataRendered This event will be called before the footer.php is included. 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.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 121 of 168

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 $this->Export for the
export type (e.g. "excel", "word"). The content of the export document is $this->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.

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 are unformatted database values. If you want to export formatted values, use
$this->MyField->ViewValue.

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.

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.

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 -> Default 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.php) after successful login. You can change
that by using this event.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 122 of 168

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.php is included. You can use this event to add content at the top
of page content.

Page_DataRendered This event will be called before the footer.php is included. 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.php) 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.php) 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.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 123 of 168

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

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

Page_DataRendered This event will be called before the footer.php is included. 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.php) 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.php is included. You can use this event to add content at the top
of page content.

Page_DataRendered This event will be called before the footer.php is included. 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.php) after successful login. You can change
that by using this event.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 124 of 168

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.php is included. You can use this event to add content at the top
of page content.

Page_DataRendered This event will be called before the footer.php is included. 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.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 125 of 168

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.

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.

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
});

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 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.

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

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 126 of 168

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 JavaScript events.

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 ew-prev"><a href="#"><span
class="icon-prev"></span> {Prev}</a></li><li class="next ew-next"><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, data is a query string and is
available for method="post" only
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 HTML editor is created.

$(document).on("create.editor", function(e, args) {


//console.log(args); // Uncomment to view the arguments in browser console
if (args && args.id == "x_MyField")
args.settings.height = "300px"; // Refer to HTML editor doc for details about the settings
});

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 127 of 168

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.

PHPMaker 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 = $(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() get field value, .value(value) set the field value.
([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 .visible() get the visibility of the field, .visible(value) set the visibility of the field. The value
([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 Get/Set the readonly attribute of the input element. The value should be a Boolean value.
(value)
Note For <input type="text"> and <textarea> only.

.disabled Get/Set the disabled attribute of the input element. The value should be a Boolean value.
(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).

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 128 of 168

Example 1

Add onchange event to 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
});

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 129 of 168

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 PHP 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 this.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.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 130 of 168

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 -> 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.

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 -> 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.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 131 of 168

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 PHPMaker custom script editor and save it.

Objects in PHPMaker 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 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>.php".

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 132 of 168

Field Object
A Field object is generated for each field in a table. For example, the "Trademark" object is generated for the "Trademark" field in the
"Cars" table. You can access the object properties using the -> notation (e.g. CurrentPage()->Trademark->CurrentValue). For the complete
list of methods and properties, please refer to the class DbField in the generated file "phpfn*.php".

Security Object
The Security object is used to store the current Advanced Security settings. Please refer to the class AdvancedSecurity in the generated
file "phpfn*.php" 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 file "phpfn*.php" 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 and
Menu_Rendered events as argument and let you work with the menu. Please refer to the class Menu in the generated file "phpfn*.php"
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 file "phpfn*.php" 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 file "phpfn*.php" 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 file "phpfn*.php" 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 Language in the generated file
"phpfn*.php" 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 file "phpfn*.php" for the complete list of methods and properties.

There are other objects in the generated code, please refer to the source code of the "phpfn*.php" in template or generated scripts.

Some Global Functions


The following are some useful global function 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.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 133 of 168

Function Description Example


Get($name[, $default]) Get a value from $_GET. If the value is not set, $value = Get("name");

the default value $default (NULL by default) is


returned.
Post($name[, $default]) Get a value from $_POST. If the value is not $value = Post("name");
set, the default value $default (NULL by
default) is returned.
Param($name[, $default]) Get a value from $_POST. If the value is not $value = Param("name");
set, get the value from $_GET. If the value is
not set, the default value $default (NULL by
default) is returned.
Route([$i]) Get the nth (0-based) route value. For use $value = Route(1);
with API and URL Rewrite enabled only. If $i
unspecified, all route values are returned as
array.

For example, if you make a request to API


like /api/hello/world, the parameters are
hello/world, the first value, Route(0), is the
action name "hello", the second value, Route
(1), is "world".

Conn([$dbname]) Get the global connection object. $rs = Conn()->Execute("SELECT ..."); //


execute a SELECT statement and get
If $dbname is not specified, it returns the recordset object
connection object for the database of the
$rs = Conn("MyDbName")->Execute
project. If $dbname is specified, it returns the
("SELECT ..."); // execute a SELECT
connection object for the specified database statement and get recordset object
of a Linked Table.

Security() Get the global 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 global language object Language()->setPhrase("AddLink",


"xxx"); // change the wording for the
"Add" link

Profile() Get the global user profile object Profile()->Set("xxx", "yyy"); // set a
value
Profile()->Save(); // save to session
Profile()->Get("xxx"); // get the value
in other pages

CurrentUserName() Get current user name. $username = CurrentUserName();

CurrentUserID() For used with User ID Security (see Security $userid = CurrentUserID();
Settings). Get current User ID.
CurrentUserLevel() For used with User Level Security (see Security $levelid = CurrentUserLevel();
Settings). Get current user's User Level ID
(integer). (Note: NOT current user's permission
as integer.)

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 134 of 168

CurrentUserInfo($fieldname) For used with Advanced Security (see Security $email = CurrentUserInfo("email");
Settings). Get current user's info from the user
table. The argument is the field name in the
user table.
CurrentPageID() Get current page ID. A page ID identifies the if (CurrentPageID() == "add") {

page type, it can be "list", "view", "add", "edit", ...your code...


}
"delete", "search", etc.

CurrentPage() Get current page object. $rowindex = CurrentPage()->RowCnt;

CurrentLanguageID() Get current language ID. $langid = CurrentLanguageID();

Page([$tablename]) Get page object of another table in the page, $value = Page("MyMasterTable")
e.g. the page object of the master table or ->MyField->CurrentValue;

detail table. If $tablename is not specified, it


returns CurrentPage().
IsLoggedIn() For used with Advanced Security (see Security if (IsLoggedIn()) {
Settings). Get the login status of the current ...your code...
}
user.
IsAdmin() For used with Advanced Security (see Security if (IsAdmin()) {
Settings). Check if the current user is an ...your code...
}
administrator.
IsExport([$format]) Check if the page is exporting data. if (IsExport("print")) {
...your code...
}

Execute($sql [,$dbname]) Execute UPDATE, INSERT, or DELETE Execute("UPDATE MyTable SET...


statements. WHERE...");

ExecuteRow($sql [,$dbname]) Executes the query, and returns the first row as $row = ExecuteRow("SELECT * FROM
an array. MyTable WHERE...");

ExecuteRows($sql [,$dbname]) Executes the query, and returns the rows as an $rows = ExecuteRows("SELECT * FROM
array. MyTable WHERE...");

ExecuteScalar($sql [,$dbname]) Executes the query, and returns the first $value = ExecuteScalar("SELECT MyField
column of the first row. FROM MyTable WHERE...");

ExecuteHtml($sql [,$options] [,$dbname]) Executes the query, and returns the data as $html = ExecuteHtml("SELECT * FROM
HTML table. See source code for options. MyTable WHERE...");

ExecuteJson($sql [,$options] [,$dbname]) Executes the query, and returns the data as $json = ExecuteJson("SELECT * FROM

JSON. See source code for options. MyTable WHERE...");

DbHelper([$dbname]) Get database helper object of a database (also $db = DbHelper();


see Custom Files).
SetClientVar($name, $value) Pass server side data to client side as a SetClientVar("myName", "myValue"); //
property of the ew.vars object. PHP (server side)
var myValue = ew.vars.myValue; //
JavaScript (client side)

There are many other useful functions in the generated code, please refer to the source code of the file "phpfn*.php" in template or
generated scripts.

 ©2002-2019 e.World Technology Ltd. All rights reserved.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 135 of 168

Custom Templates
By default fields are presented in tabular form, e.g. one field per row in Add/Edit/Search/View page, or one record per row in List/Delete
page. Custom Templates enable you to re-arrange the fields in your own way.

Note Do not confuse Custom Template (which is a table level setting within a project) with customizing the whole template zip file.
If you want to customize the general layout of the generated site or customize something for all tables and all projects, you should
customize the template zip file, see Customizing Template.

How it Works

If a Custom Template is provided, PHPMaker splits the original code in many small client side templates. A client side template is HTML
code enclosed by <script type="text/html"> and </script>. Since browsers do not know how to execute "text/html" scripts, they simply
ignore it. So it is possible to re-assemble HTML from the small client side templates by JavaScript based on your provided Custom
Template. In other words, it is simply re-arrangement of existing HTML parts in browser.

During script generation, PHPMaker converts your Custom Template to a client side template and outputs JavaScript to render the
template. The client side template is rendered by JsRender (see Third-Party Tools) which is a third-party JavaScript template engine
optimized for high-performance pure string-based rendering. The generated scripts only use its "template composition" feature to render
HTML from other external templates, your Custom Template can however make use of its other features if you need to. (Note that
JsRender is still in beta, if you use its features directly, be aware that there may be some breaking changes in the future.)

What it Can Do (and Cannot Do)

Custom Templates let you customize the layout of the fields originally placed in the main HTML table of the page, they cannot customize
HTML outside those regions. The customizable regions are highlighted as follows:

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 136 of 168

Custom Template Tags

To let you create your Custom Templates easily, PHPMaker supports the following Custom Template Tags. Since JsRender template tags
use {{ and }} (double curly brackets), in order to let you use them in your Custom Templates, PHPMaker Custom Template Tags use
{{{ and }}} (triple curly brackets) to differentiate. Note that Custom Template Tags will be converted to JsRender tags during script
generation, they can only be used in PHPMaker user interface, they cannot be used elsewhere such as template (zip file) or generated
scripts.

In the following table, field 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.

IMPORTANT Remember that Custom Template is rearrangement of existing HTML fragments in the page. Most of the following
tags output HTML markup for the field in the page, NOT plain text or numeric values.

{{{field}}} Field with or without caption and other values, depending on where it is used:

• List/Delete page
CustomTemplateHeader - field caption (supports sorting)
CustomTemplateBody - field value only
CustomTemplateFooter - field aggregate value
• Search page/Extended Search panel - field caption + search operator + search value (+ search
condition + search operator 2 + search value 2)
• Other pages - field caption + field value

{{{caption field}}} Field caption

{{{header field}}} Field header (caption with sort links)


{{{value field}}} Field value (or input) without caption.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 137 of 168

{{{dbvalue field}}} Field raw value from database, NOT HTML. The value is straight from database and is unformatted. For
use in CustomTemplateBody (List/Delete pages) or in CustomTemplate (other pages) only. NOT
applicable to Add/Search/Register pages since there are no database values in those pages.

Important Notes

1. You ALWAYS use JsRender template tags together with this tag, e.g. {{: {{{dbvalue
field}}} }}, see more examples below.
2. For List/Delete pages, since there are more than one records, the field value will be
outputted as data path using JsRender's built-in '~root' contextual parameter. Using this tag
is recommended.
3. For other pages (e.g. View page), since there is only one record, although you may still use
this tag, it is possible (and better) to use JsRender template tags directly, e.g. you can use
either {{: {{{dbvalue field}}} }} or preferrably {{:field}}.
4. Unlike other tags, you can even use this tag for fields not selected for that page. However,
NOT all fields are available, by default only short string, numeric, date, time and boolean
fields are included. Date and time field values are string, if you need to do some
manipulation, you need to convert the data type first. In such cases, using JsRender
converters is recommended, see Using converters. You can also register your own converters
in CLIENT side Global Code.

Example 1 - Output the field value directly

{{: {{{dbvalue field}}} }}

Example 2 - Output the field value with JavaScript method of the data type with JsRender {{:...}} tag.

{{: {{{dbvalue field}}}.toUpperCase() }}

Example 3 - Output HTML-encoded field value with JsRender HTML-encode tag {{>...}}.

{{> {{{dbvalue field}}} }}

Example 4 - Output field value with JsRender built-in URL encoder {{url:...}}.

<img src='{{url: {{{dbvalue field}}} }}'/>

Example 5 - Output field value with JsRender built-in attribute encoder {{attr:...}}.

<div title='{{attr: {{{dbvalue field}}} }}'>...</div>

Example 6 - Output field value with JsRender {{if ...}} and {{else ...}} tags.

{{if {{{dbvalue field}}} == "Y" }}Yes{{else {{{dbvalue field}}} == "N" }}No{{else}}Unknown


{{/if}}

{{{value2 field}}} Search value 2. For use with Search page or Extended Search panel only.
{{{operator field}}} Search operator. For use with Search page or Extended Search panel only.
{{{operator2 field}}} Search operator 2. For use with Search page or Extended Search panel only.
{{{condition field}}} Search condition. For use with Search page or Extended Search panel only.
{{{cell_attrs field}}} Cell attributes for the field in the current row (originally for the <td> tag of the field). For use in
List/Delete page only.

{{{list_options}}} or List options with <td> tags. Each list option is enclosed by "<td>" and "</td>". For use in List page
{{{list_options n}}} only.

n is the "rowspan" attribute of the <td> tag and it is optional. If not specified, default is 1.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 138 of 168

{{{list_options_2}}} List options with <span> tags. Each list option is enclosed by "<span>" and "</span>". For use in
CustomTemplateBody (List Page) only.

{{{list_option xxx}}} List options with name xxx. For use in CustomTemplateBody (List Page) only. Possible values of xxx are
same as those used in server events, i.e.

• copy
• delete
• edit
• checkbox
• preview - for use with Preview extension (for registered users) only, or
• detail_<DetailTable> - NOT for use with Preview extension (for registered users)

{{{page_n}}}...{{{/page_n}}} Multi-Page template tag for page n. The content inside the tags is the Custom Template for page n.

Note For use with Multi-Page (see Table Setup) only. No need to use this tag if single page.

{{{row_attrs}}} Current row attributes (originally for the <tr> tag of the record) . For use in List/Delete page only.

{{{row_cnt}}} or Current row index (1-based). NOT HTML. For use in List/Delete page only.
{{{row_index}}} or
{{{i}}} Note This tag is used inside the for-loop and will be replaced by <?php echo $i ?> in the
generated script. You can also use PHP code in CustomTemplateBody if you need to use the
variable $i to output HTML conditionally. The $i is looped from 1 (or 0 if there is Inline-Add/Copy)
to CurrentPage()->RowCnt.

{{{confirm_password}}} Text input (with caption) for password confirmation. For use in Registration Page only.

{{{value confirm_password}}} Text input (without caption) for password confirmation. For use in Registration Page only.

How to Use

To enter your Custom Template for a table, follow the following steps:

1. Select the table in the database pane,


2. Select the Code tab (which contains Server Events, Client Scripts and Custom Templates),
3. Scroll down the treeview or collapse the Server Events and Client Scripts node, select a template node under Custom Templates,
4. Enter your Custom Template in the editor.

Note You can enter the first character of a field name and then press Ctrl + Space to open the completion list of the editor
and select a {{{field}}} tag.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 139 of 168

Then just generate and run your scripts in your browser as usual.

Examples

Example 1 - Custom Template in Add/Edit/Search/View page or Extended Search in List page

{{{Trademark}}}&nbsp;{{{Model}}}<br>
{{{HP}}}&nbsp;{{{Liter}}}

If you want to have more control on the layout, use DIV and SPAN with CSS styles, e.g.

<div class="ew-row"><span class="ew-cell">{{{Trademark}}}</span><span class="ew-cell">{{{Model}}}</span></div>


<div class="ew-row"><span class="ew-cell">{{{HP}}}</span><span class="ew-cell">{{{Liter}}}</span></div>

or use a HTML table, e.g.

<table class="ew-table">
< tbody>
<tr><td>{{{Trademark}}}</td><td>{{{Model}}}</td></tr>
<tr><td>{{{HP}}}</td><td>{{{Liter}}}</td></tr>
</tbody>
</table>

Example 2 - Custom Template in Add/Edit/Search/View page (Multi-Page)

{{{page_1}}}
<div class="ew-row"><span class="ew-cell">{{{Trademark}}}</span><span class="ew-cell">{{{Model}}}</span></div>
<div class="ew-row"><span class="ew-cell">{{{HP}}}</span><span class="ew-cell">{{{Liter}}}</span></div>
{{{/page_1}}}

{{{page_2}}}
<div class="ew-row">{{{Description}}}</div>
{{{/page_2}}}

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 140 of 168

{{{page_3}}}
<div class="ew-row">{{{Picture}}}</div>
{{{/page_3}}}

Example 3 - Card view in List page using {{{list_options_2}}}

CustomTemplateHeader

<table class="ew-table">
< tbody>

CustomTemplateBody

<tr{{{row_attrs}}}>
< td>
<div class="ew-row">
<span class="ew-cell"><b>{{{caption Trademark}}}:</b>&nbsp;{{{Trademark}}}</span>
<span class="ew-cell"><b>{{{caption Model}}}:</b>&nbsp;{{{Model}}}</span>
</div>
<div class="ew-row">
<span class="ew-cell"><b>{{{caption HP}}}:</b>&nbsp;{{{HP}}}</span>
<span class="ew-cell"><b>{{{caption Liter}}}:</b>&nbsp;{{{Liter}}}</span>
</div>
<div class="ew-row">{{{list_options_2}}}</div>
</td>
</tr>

CustomTemplateFooter

</tbody>
</table>

Example 4 - Show each record in 2 rows in List page using {{{list_options n}}} where n is the rowspan. Note: Do not confuse
{{{list_options 2}}} with {{{list_options_2}}}.

CustomTemplateHeader

<table cellspacing="0" class="ew-table ew-table-separate">


<thead>
<tr class="ew-table-header">
{{{list_options 2}}}<td>{{{Trademark}}}</td><td>{{{Model}}}</td>
</tr>
<tr class="ew-table-header">
<td>{{{HP}}}</td><td>{{{Liter}}}</td>
</tr>
</thead>
<tbody>

CustomTemplateBody

<tr{{{row_attrs}}}>
{{{list_options 2}}}<td>{{{Trademark}}}</td><td>{{{Model}}}</td>
< /tr>
< tr{{{row_attrs}}}>
< td>{{{HP}}}</td><td>{{{Liter}}}</td>
< /tr>

CustomTemplateFooter

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 141 of 168

</tbody>
</table>

Important
1. Remember that Custom Template is rearrangement of existing HTML fragments in the page, all other code is still the same,
the fields in the Custom Template cannot be more than the original script. The available fields are same as the
original script, if you try to include other fields in the table or from other table by Custom Template, it will NOT work. In
Add/Copy/Edit page, if a field is missing, no field value is submitted but the generated scripts contain code for the field,
unwanted results may occur, for example, if a field is missing in the Edit page, the field value in the table will be cleared after
editing. If Multi-Page (see Table Setup) is enabled for the page, the Custom Templates should include templates for all pages
using {{{page_n}}} and {{{/page_n}}}, and each field should be placed in the same page as in the original script.

2. Custom Template is HTML, if you want to embed PHP code, you need to use <?php and ?> to enclose your code, if you want to
use JavaScript, you need to use <script> and </script>.

3. DO NOT use $this in your PHP code. There is no $this in the context, you can however use CurrentPage() to get the current
page object.

4. Avoid using JavaScript in the template. If you need to use JavaScript, try to put your JavaScripts in Client Scripts and Startup
Scripts of the page (see Server Events and Client Scripts). If you have to use JavaScript in the template, DO NOT using
document.write() because the script will be extracted from the template and be executed at the end of the template, you can
however use a DIV with unique id and write to its innerHTML.

5. In List page, CustomTemplateBody is the template for a record. Your Custom Template needs NOT to be a HTML table, but if
it is (see the example above), then CustomTemplateHeader and CustomTemplateFooter must at least contains
<table><tbody> and </tbody></table> respectively, and you need to provide the <tr> and <td> tags in these templates. If the
table uses Aggregate values (see Field Setup), you should also include <tfoot> in your CustomTemplateFooter. If you want
to use the PreviewRow extension (for registered users only), your Custom Template must be a HTML table because the
extensions works by inserting a preview row in the table, and in CustomTemplateBody each <tr> row must contain the
attribute data-rowindex="{{{row_cnt}}}" or {{{row_attrs}}} as the extension needs the row index for inserting a row below it.
The row index attribute is also required for alternating/selected/highlighted row colors. Basic sample code of
CustomTemplateHeader/Body/Footer can be found in Code Repository (below the editor).

6. Before the Custom Template is applied, the jQuery event "rendertemplate" will be fired, you can use Client Script of the page
(see Server Events and Client Scripts) to subscribe this event and pass custom data to the Custom Template or even disable it.

7. Custom Template does NOT support the following:


◦ Export to CSV/HTML/PhpSpreadsheet/PHPWord/XML (the data is exported in original tabular format)
◦ Add Blank Row in Grid-Add/Edit
◦ Detail grid in Master/Detail-Add/Edit/View

8. Custom Template supports Printer-Friendly/Export to Excel/Word/Email. Note that Export to Excel/Word works by letting
Word/Excel to import the exported HTML, so make sure your Custom Template is simple enough for Word/Excel to import. As
for Export to Email, the exported HTML will be rendered by email clients. Different email clients render HTML email content
differently, the result may vary with email client. In general, keep your Custom Template simple and stupid for export. You can
even use PHP's if/elseif/else to output different Custom Template according to the value of CurrentPage()->Export. Also,
Custom Template will override Page_Loading, Row_Export and Page_Exported server events, you can however use
Page_Load server event to disable using Custom Template for export, see Server Events and Client Scripts.

 ©2002-2019 e.World Technology Ltd. All rights reserved.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 142 of 168

Using Custom View


WARNING! Custom View expects simple SELECT statements only, they are NOT designed to and cannot replace views provided by
the database. PHPMaker supports creating database view, you should always use database views whenever available. Views
provided by database allow you to use them more like regular tables. If you use MySQL 5, you should ALWAYS use MySQL view.

A Custom View is basically a stored SELECT statement. Custom View allows you to save your SELECT statements in a project as a virtual
table. If your database, for example, MySQL 4, does not support views, you'll find this feature useful.

Converting Custom View to Database View

Custom View expects a simple SELECT statement only. If you create a Custom View with a SELECT statement with some complex clauses,
or with an UNION statement instead of a single SELECT statement, the sorting or searching may fail. In such cases you should change the
Custom View to database view. PHPMaker allows converting your Custom View to database view provided that the database user have
CREATE VIEW privilege.

After loading the database in PHPMaker, the database objects (tables, views, custom views and reports) will be shown in the left pane (the
database pane). To convert a Custom View to database view, right click the Custom View in the database pane and select [Convert
Custom View to View]. Alternatively, you can select the Custom View first, then click [Edit] in the main menu and then select [Convert
Custom View to View]. After creating the view, the existing Custom View and field settings will be moved to the new view. If your project
is connected to a development database, export the new views and recreate them on your production database during deployment.

If under some circumstances you cannot change Custom View to database view (e.g. you are still using MySQL 4.1) and you must use
Custom View, you can try use a derived table (supported since MySQL 4.1) in the format of SELECT * FROM (<Original SQL>) AS t as the
SQL of the Custom View. (Note for MySQL 4.1 users only: If you upgrade to MySQL 5 later, you should convert your Custom Views to
MySQL views. If you use the derived table approach before, edit the Custom View, remove the derived table and use the original SQL first,
MySQL 5 still does not support subquery in the FROM clause when creating view.)

Creating Custom View

To create a custom view, right click the database pane and select [Add Custom View]. Alternatively, you can click [Edit] in the main
menu and then select [Add Custom View].

The Custom View Setup window will show up:

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 143 of 168

PHPMaker will give the new Custom View a temporary name, CustomView<n>, where n is an integer. If you want to change the name,
enter a new name in the [Custom View name] edit box in the main toolbar.

It is recommended that the built-in visual query builder be used to build your SQL. The query builder interface is intuitive and fully
supports drag-n-drop, in most cases you don't need to type the table or field names.

On the left hand side, the available tables are displayed in the table pane. On the right hand side, there are three tabs: [Builder], [SQL]
and [Result]. (The [Result] tab will only be visible after you execute the SQL.)

Builder

To build your SQL, drag your tables from the table pane on the left to the builder area and check the required fields.

To create a link between two objects (i.e. join them) you should select the field by which you want to link an object with another and drag
it to the corresponding field of another object. After you finish dragging, a line will appear between the linked fields. The join type created
by default is INNER JOIN, i.e. only matching records of both tables will be included in resulting dataset. To define other types of joins you
should right click the link and select the Edit... item from the drop down menu or simply double-click it to open the Link Properties
dialog. This dialog allows you to define join type and other link properties.

The easiest way to add a field to the list of query output fields is to check the checkbox at the left of field name in the Query Building
Area. To include all the fields of an object you should click the checkbox at the left of the asterisk item of an object.

Note You should select your fields explicitly, not using the * symbol.

Another way is to select a field name from the drop-down list of the Expression column in the Columns Pane. And the most common way
is to write any valid expression to the Expression column in the Columns Pane.

To remove a field from the list of query output fields you should uncheck the checkbox at the left of field name in the Query Building Area
or you may remove it by unchecking the Output column checkbox. Such operations as removing lines from the Columns Pane or re-
ordering output fields are available by right clicking on the left-most gray column via the drop-down menu.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 144 of 168

To define sorting of output query fields you should use the Sort Type and Sort Order columns of the Columns Pane.

The Sort Type column allows you to specify how the fields will be sorted - in Ascending or Descending order.

The Sort Order column allows you to setup the order in which fields will be sorted, if there are more than one field to sort specified.

To cancel sorting by some field you should clear the Sort Type column for this field.

To define criteria for the expression listed in the Columns Pane you must use the Criteria column.

Here you should write the criteria omitting the expression itself. For get the following criteria in your query

WHERE (field >= 10) AND (field <= 20)

you should write

>= 10 AND <= 20

in the Criteria column.

You may specify several criteria for one expression using the Or... columns. These criteria will be concatenated in the query with the OR
operator.

To setup grouping by some of the fields and/or to define aggregate functions on grouped rows you may use the Group by column.

You may select one of the following values for this column from the drop-down list:

• "Expression" and "Where": These values are used when no grouping is specified. The "Expression" value is set when this expression
is used as output expression in the SELECT clause and nothing else. The "Where" value is set automatically when you define a criteria
to this expression that results in including this expression to the WHERE clause. Normally you shouldn't care about value of the
Group By column when you don't want to define grouping.

• "Group by" and "Having": These values are similar to the previous two, but used when you want to define grouping in your query.
In this case you should set the "Group by" value for all columns you want to group by. Specifying criteria for the grouped columns
will include these criteria in the HAVING clause. If you want to include an expression ONLY in the HAVING clause you should set the
"Having" value in the Group By column for this expression.

• Aggregate functions (Count, Sum, etc): By selecting one of these values you will create an aggregate expression for the value
indicated in the Expression column.

SQL

You can always click the [SQL] tab to check the SQL generated by the query builder, the SQL editor is also syntax-highlighted to enhance
the readability of the SQL.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 145 of 168

The SQL tab is actually an SQL editor, you can type your SQL directly without using the query builder here, or paste your SQL from
elsewhere, or open a saved SQL script (*.sql) from file.

Notes
1. If the SQL is not generated by the built-in query builder, there are chances that query builder cannot parse the SQL and
display it visually in the [Builder] tab. However, this does not necessarily mean that the SQL is invalid, you can verify its
validity by executing it (see below) and check if it returns the data you want in the [Result] tab. And you can create the
Custom View directly by click the OK button without switching to the [Builder] tab.
2. If you type your SQL directly, always use aliases (use "AS") for fields whenever applicable. Otherwise, the alias will be assigned
by the database and you will not be able to refer to the field with a known and meaningful name.

Result

When you have finished your SQL, you can test the SQL by any one of the following ways: (for "DIRECT" connection only)

• Clicking the [Execute] button in the toolbar


• Pressing [F9] on your keyboard
• Clicking [Query] in the menu and then [Execute]

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 146 of 168

The [Result] tab will become visible and display the result data. If the data is correct, the Custom View setup is almost done.

Note: Executing the SQL is for testing the SQL only. The data displayed in the [Result] tab will not show the memo fields and blob fields,
they may be represented by "(MEMO)" and "(BLOB)" only. This is not related to the data that will be displayed by the generated scripts.

Since a Custom View is based on an existing table, there is an option that the fields in the Custom View use the same Field Setup (Edit
Tags, View Tags, etc.) as the source table. If you want to copy field settings, check the checkbox [Copy field settings from source table
(when applicable)]; if not, uncheck it. Then you can press [OK] to finish.

Note: "when applicable" means that if enabled, field settings will be copied from the source table when a new Custom View is created,
or when a new field is found after editing a Custom View, and the field can be found from existing tables. (This is also why building a SQL
with the built-in query builder and not using * symbol are recommended, these ensure that the SQL can be parsed and therefore the
source table and source field can be found.)

When a Custom View is added, PHPMaker will load it and display it in the database pane and Table Setup page under the [Custom
Views] node. To view the SELECT statement of the Custom View, right click the Custom View in database pane and select [Object
Properties]. Alternatively, you can select the Custom View first, then click [Project] in the main menu and then select [Object
Properties].

To edit a custom view, right click the Custom View in the database pane and select [Edit Custom View]. Alternatively, you can select the
Custom View first, then click [Edit] in the main menu and then select [Edit Custom View].

When a Custom View is added or edited, PHPMaker will check the SQL. If the SQL is invalid, the icon of the Custom View will have a cross
on it like , you can view the error in the [Object Properties] window and then edit the Custom View to correct the SQL.

Important
1. After a Custom View is created, it works independently from the table(s) it based on. Changing the structure of the source
table(s) does not change the Custom View. If you delete a field in the source table that is used by a Custom View, the Custom
View will fail. You should edit the Custom View to update the SELECT statement. Also, a Custom View has its own field
settings, changing field settings in the source table does not change the field settings in related Custom Views.
2. During searching, sorting and grouping, PHPMaker generated codes need to change the WHERE and/or ORDER BY clause of
SQL for the list page dynamically. For Custom Views, since there might be fields with aliases, it is necessary to use the actual
expressions of the aliases in order to ensure the result SQL works. For example, if you have a field, "UnitPrice*12 AS TotalPrice"
in your SQL, you cannot sort using "ORDER BY TotalPrice", you need to use "ORDER BY UnitPrice*12". Therefore, if your
Custom View contain fields with aliases, it is important that the SQL can be parsed correctly by PHPMaker. To make sure that,
here are the recaps:
a. It is recommended that the built-in visual query builder be used to build your SQL.
b. You should select your fields explicitly, not using the * symbol.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 147 of 168

c. If you type your SQL directly, always use aliases (use "AS") for fields whenever applicable.

 ©2002-2019 e.World Technology Ltd. All rights reserved.

Using Report
Report in PHPMaker can be used with any supported databases. A report is created from one existing table or view. If you need to display
data from more than one table or view, join them first using a view in your database.

After loading the database, the database objects (tables, views, Custom Views and reports) will be shown in the left pane (the database
pane). To create a report, right click the database pane and select [Add Report]. Alternatively, you can click [Edit] in the main menu and
then select [Add Report].

The Report Setup window will show up:

The Report Setup window has 4 tabs. Go through these tabs one by one to setup your report.

General

PHPMaker will give the new Report a temporary name, Report<n>, where n is an integer. If you want to change the name, enter a new
name in the [Report name] edit box. Then you can select a table, or a view, or a Custom View form the [Table or View] combobox.

The field in the table will be displayed in the [Available fields] listbox, select fields you want to display by moving them to the [Selected
fields] listbox. It is recommended that you select only the fields you required or the report page may be too wide to view without
scrolling.

This settings in this tab are mandatory.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 148 of 168

Grouping Levels

You can optionally add up to 6 grouping levels in either ascending or descending order and choose to show summary for each level.
Select the grouping field for each level in the comboboxes and click the button next to the comboboxes to choose the sorting order. To
enable summary, check [Show Summary] next to the grouping fields. When any of the [Show Summary] fields is selected, the
[Summary Values] tab will appear for you to setup the summary values later. (See below)

Sort Order

You can optionally sort records by up to 6 fields, in either ascending or descending order. Select the sorting fields in the comboboxes.
Press the button to change the sort order.

Summary Values

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 149 of 168

If any of the [Show Summary] checkboxes is selected in the [Grouping Levels] tab, this tab will become visible. You can optionally select
aggregate values for each selected numeric field. Available summary values are [Sum], [Avg], [Min] and [Max]. These summary values
will be shown at the end of the grouping levels with [Show Summary] enabled.

In this tab, you can also choose to show [Detail and Summary] or [Summary only] for your report. If [Detail and Summary] is selected,
records belonged to each grouping level will be displayed under the grouping level title, then followed by the summary. [Detail and
Summary] is the default.

Finally, you can choose to [Show grand summary] for all records at the end of the report. This options is enabled by default.

Press [OK] to finish setup. When a report is created, the field settings will be copied from the source table. But from then on, the Report
has its own field settings and is much like other table in PHPMaker.

To edit a Report, right click the Report in the database pane and select [Edit Report]. Alternatively, you can select the Report first, then
click [Edit] in the main menu and then select [Edit Report]. Note that the source table of a report cannot be changed.

Important
1. After a report is created, a report works independently from the source table it based on. Changing the structure of the source
table does not change the report. If you delete a field in the source table that is used by a report, the report will fail. Similarly,
if the report is based on a Custom View and you change the SELECT statement of the Custom View, the report may fail if a
field in the report is missing. However, in the latter case, when a Custom View is edited, PHPMaker will check the validity of
the SQL. If the SQL fails, both the Custom View and reports that based on the Custom View will be displayed with a cross in
the icon, like and . Also, a Report has its own field settings, changing field settings in the source table does not change
the field settings in related Reports.
2. Report does not support exporting to HTML, CSV, XML or PDF. You should export from the source table.
3. Report does not include BLOB fields or fields that use file upload.
4. Report is not updatable or searchable, but it supports User ID and User Level. (See Security)

Also See:
Security

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 150 of 168

 ©2002-2019 e.World Technology Ltd. All rights reserved.

Custom Files
Custom Files enables you to add your own files to the project. Basically, a custom file is a blank page with the layout of the project for you
to add your own content so it will have a consistent look and feel like other generated files.

How to Use

To create a Custom File, simply right click the database pane or click Edit in the main menu, then select Add File, the following form will
show:

The properties are as follows:

File Name File name with extension.

Notes

1. Do not include path, you can enter Output Folder later (see below).
2. Do not use characters not allowed as a file name on your machine or on your
server. Alphanumerical characters only is recommended.
3. If file name on your server is case-sensitive, make sure you enter the file
name in correct lettercase. If you have selected Lowercase in Generate tab
(see Generate Settings), the file name will be converted to lowercase during
generation.
4. The file name cannot be same as any table (including view, Custom View and
report) name.

Caption The caption of the page. This is similar to table caption for a table and will be shown up
in the menu and in the Breadcrumbs of the page.

Includes common files For .php file only. Specify whether to include the common files (mainly header, menu
and footer) in the file so it will be consistent with other generated scripts and able to use
PHPMaker classes and functions.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 151 of 168

Output folder (relative to application root) The output folder of the page. This must be relative to application root of the project
(see Generate Settings).

For example, if you have set up a website like:

Application root folder: C:\Users\Administrator\Documents\mycompany.com

Destination folder: C:\Users\Administrator\Documents\mycompany.com\project1

and you want to generate your Custom File in the destination folder, you should enter
"project1/" (no quotes).

Note Do NOT use parent path ".." or the file will be generated outside the
application root leading to some unexpected results.

After entering above properties, click OK button to save. The Custom File will show up in the database pane under the Custom Files
node:

To edit the Custom File properties, right click the Custom File in the database pane and select Edit File.

To delete a Custom File, right click the Custom File in the database pane and select Delete File.

To enter content for the file, select the Custom File in the database pane , then select the Code tab (which contains Server Events, Client
Scripts and Custom Templates) in the right pane.

Scroll down the treeview or collapse the Server Events and Client Scripts node, select the Custom Templates -> Table-Specific ->
Custom File -> Content node, then you can enter or paste your content in the editor:

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 152 of 168

Then just save your project generate and run your scripts in your browser as usual.

Important Although it is convenient to save your own files in the project, you should avoid saving all the contents in the project or
the project will become so large that the performance of the UI will be affected. If the file content is large, you can put the content
in an external file and then include it in the Custom File. If the number of files is large, put the minimum number of files in the
project by Custom Files only, you can generate a blank Custom File and duplicate it as containers for other files, then just add menu
items to the project by the Menu Editor for those external files.

Examples

Example 1 - Include an external file instead of saving the page content in the project.

<?php include_once "MyPage.php"; // Includes an external file ?>

Example 2 - Add a Bootstrap Panel in the page to show some news.

<div class="panel panel-default">


< div class="panel-heading">Latest news</div>
< div class="panel-body">
< p>PHPMaker 2019 is released</p>
< /div>
< /div>

The result:

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 153 of 168

Example 3 - Add multiple Bootstrap Panels in the page as a dashboard page. Use database helper to execute SQLs and display data as
HTML table.

<?php
$db =& DbHelper(); // Create instance of the database helper class by DbHelper() (for main database) or DbHelper
("<dbname>") (for linked databases) where <dbname> is database variable name
?>
< div class="panel panel-default">
< div class="panel-heading">Out of stock products</div>
< ?php
$sql = "SELECT DISTINCT " .
"`categories`.`CategoryName` AS `CategoryName`," .
"`products`.`ProductName` AS `ProductName`," .
"`products`.`QuantityPerUnit` AS `QuantityPerUnit`" .
" FROM `categories` JOIN `products` ON (`categories`.`CategoryID` = `products`.`CategoryID`)" .
" WHERE " .
"`products`.`UnitsInStock` <= 0";
echo $db->ExecuteHtml($sql, ["fieldcaption" => TRUE, "tablename" => ["products", "categories"]]); // Execute a SQL and show as
HTML table
?>
< /div>
< div class="panel panel-default">
< div class="panel-heading">Discontinued products</div>
< ?php
$sql = "SELECT DISTINCT " .
"`categories`.`CategoryName` AS `CategoryName`," .
"`products`.`ProductName` AS `ProductName`," .
"`products`.`QuantityPerUnit` AS `QuantityPerUnit`," .
"`products`.`UnitsInStock` AS `UnitsInStock`" .
" FROM `categories` JOIN `products` ON (`categories`.`CategoryID` = `products`.`CategoryID`)" .
" WHERE " .
"`products`.`Discontinued` = '1'";
echo $db->ExecuteHtml($sql, ["fieldcaption" => TRUE, "tablename" => ["products", "categories"]]); // Execute a SQL and
show as HTML table
?>
< /div>

The result:

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 154 of 168

Note Other than ExecuteHtml(), there are a few other useful methods in the database helper class, refer to the source code of the
file ewdb.php in the template for details. You can also extend the database helper class (e.g. in server side Global Code, see Server
Events and Client Scripts) and add your own methods.

 ©2002-2019 e.World Technology Ltd. All rights reserved.

Custom Fields
The feature enables you to add your own Custom Fields to a table or view based on valid SQL expressions. You can treat a Custom Field
as a dummy field you added to the table and the value of the Custom Field is evaluated from the specified SQL expression. Once added,
the field can be treated as a normal field and will appear in all generated pages. You can use Server Events and Client Scripts to
manipulate the Custom Field to display any content you want.

Important Notes

1. The SQL expression must be a valid SQL expression for the database based on the fields of the table/view. Otherwise, the
Custom Field cannot be created.
2. If no SQL expression is entered, the Custom Field will be a blank field and you need to write your own Server Events and/or
Client Scripts to handle the value of the Custom Field.
3. A Custom Field is not an actual field in the database table/view so input value will NEVER be inserted/updated to the
database.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 155 of 168

How to Use

To add a Custom Field to a table/view, simply right click on any database table/view (in the database pane) or click Edit in the main menu,
then select Add Custom Field, the following form will show:

The properties are as follows:

Field Name Field name of the Custom Field. Note that the field name cannot be the same as any fields/Custom Fields in the table/view

Caption The caption of the Custom Field.

Expression A valid SQL Expression based on existing fields.

After entering above properties, click OK button to save. The Custom Field will show up in the Fields panel of the specific table/view.

To edit the Custom Field, right click the Custom Field and select Edit Custom Field.

To delete the Custom Field, right click the Custom Field and select Delete Custom Field.

Testing SQL Expression

Custom Field is just a subquery in the SELECT statement for the table, e.g.

SELECT *, (SQL Expression) AS CustomField FROM MyTable

The highlighted part is the Custom Field, it is a subquery inserted to the normal SELECT statement for the table. That is why the
expression for the Custom Field must be a valid SQL Expression. To make sure your SQL expression is valid, you can test your expression
in your database manager first by executing:

SELECT (SQL Expression) AS CustomField FROM MyTable

e.g. SELECT (`UnitPrice`*`Quantity`*(1-`Discount`)) AS SubTotal FROM MyTable

If it works, your SQL expression is valid, then you can enter your SQL Expression and CustomField to create your Custom Field and use
them as Expression and Field Name in the Add Custom Field dialog said above.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 156 of 168

 ©2002-2019 e.World Technology Ltd. All rights reserved.

Linked Tables
Linked Tables enables you to add tables/views from other databases to the project. Linked Tables can be used like regular tables in the
project, for example, you can generate Add/Edit/Delete/Update scripts for the Linked Tables, you can use a Linked Table as lookup table,
user table, master or detail table.

Note Using Linked Tables in Custom Views or Views is not supported.

Adding a Linked Table

To add new Linked Tables, simply right click the database pane or click [Edit] in the main menu, then select [Add Linked Table], the
following form will show:

Click the [Add Database] button in the toolbar to add a database.

The Database Connection form is same as that in the Database tab, see Database Setup for detail.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 157 of 168

Enter your database connection information and click the [Connect] button to load the database information. The list of tables/views of
the selected database will be displayed.

Note The database combobox will show the database name, database variable name and the database type. The database variable
name is to be used for retrieving the database information in server side code such as server events (see Server Events and Client
Scripts). By default it is same as the database name if the database name contains alphanumeric characters and underscore only.
Otherwise, the database variable name will be different, with non-alphanumeric characters replaced. Besides, the database name of
a Linked Table can be same as the main database or database of other Linked Tables. If database names are the same, an index will
be appended to the database variable name. If your project uses databases with the same name and you need to write server side
code, make sure you check the variable name here.

Select the tables/views you need and click [OK]. The selected tables/views will be added to the project as a Linked Table and will appear
under the [Linked Tables] node of the database pane. You can then manipulate the Linked Table as a regular table/view.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 158 of 168

Deleting a Linked Table

To remove a Linked Table from the project, right click the Linked Table in the database pane, and click Delete Linked Table. Click "Yes" to
confirm deletion.

Note that if the database related with the Linked Table being deleted no longer has any other Linked Tables associated, you may want to
remove this database from the project as well.

To do that, right click the database pane or click [Edit] in the main menu, then select [Add Linked Table]

Select the database you want to remove from the dropdown selection, and click the [Remove Database] button. Click "OK" to confirm
deletion.

Synchronizing with Database of Linked Tables

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 159 of 168

If you are adding Linked Tables and you have altered the database of the Linked Tables, you may want to synchronize the table list with
the database so you can choose the new or renamed tables. Or if you have changed some connection information of the database such
as the username or password, you may also want to update it.

To do that, right click the database pane or click [Edit] in the main menu, then select [Add Linked Table], select the database and click
the [Synchronize Database] button.

The connection information will be displayed again.

Change the connection information if necessary and then press the [Synchronize] button.

Note If you create a Linked Table and then rename the table in your database, the Linked Table will fail, synchronizing with the
database will NOT fix it since the renamed table cannot be determined. You need to delete the old Linked Table and create a new
one.

 ©2002-2019 e.World Technology Ltd. All rights reserved.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 160 of 168

Multi-Language Project
Important
1. Multi-Language project must use utf-8 for everything. The charset of the project must be "utf-8".
2. The data in your database must be stored in unicode, otherwise your data will not be displayed properly.
3. Only the English language file is provided by our products, you'll need to prepare the language files for other languages
yourself. You may also check our website and see if there are any user submitted language files. If you want to share your
language files with others (without any conditions), you can submit your language file to us too.

Making Language Files


Language files are placed in the subfolder "languages" under the installed folder. The files are used for all templates.

To translate a language, duplicate the shipped english.xml and rename it. It is recommended that the file name should contain
alphanumeric characters (and underscore) and in lowercase only.

1. Open the new XML file with any text or XML editor, you'll see the root node:

<ew-language date="2018/07/25" version="15.0.0" id="en" name="English" desc="English" author="e.World Technology Ltd.">

You must change at least the id, name and desc attributes.

The id is an identifier for identifying the language in generated scripts, it must be unique. It is recommended that you use the
following values as the language IDs.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 161 of 168

Language Value Language Value Language Value

Arabic ar German (Austria) de-AT Portuguese pt

Bengali bn German (Switzerland) de-CH Portuguese (Brazil) pt-BR

Bulgarian bg Greek el Portuguese (Portugal) pt-PT

Catalan ca Hebrew iw Romanian ro

Chinese (Simplified) zh-CN Hindi hi Russian ru

Chinese (Traditional) zh-TW Hungarain hu Serbian sr

Croatian hr Indonesian id Slovak sk

Czech cs Italian it Slovenian sl

Danish da Japanese ja Spanish es

Dutch nl Kannada kn Spanish (Latin America) es-419

English (UK) en-GB Korean ko Swedish sv

English (US) en Latvian lv Tamil ta

Estonian et Lithuanian lt Telugu te

Filipino fil Malay ms Thai th

Finnish fi Malayalam ml Turkish tr

French fr Marathi mr Ukrainian uk

French (Canadian) fr-CA Norwegian no Urdu ur

German de Persian fa Vietnamese vi

Gujarati gu Polish pl

The name is for displaying the language name in the user interface (which does not support unicode), it should contain
alphanumeric characters, underscore and spaces only.

The desc is for displaying the language name in generated scripts, it can be in the encoding of the XML file.

For example, if you want to make language file for Traditional Chinese, you may rename the file as chinese.xml and modify the node
as:

<ew-language date="2018/07/25" version="15.0.0" id="zh-TW" name="Traditional Chinese" desc="繁體中文" author="e.World


Technology Ltd.">

2. Each language file should have a corresponding locale file with the same language ID. See:
a. Customizing Template -> Locale Files, and
b. Tools -> Locale Settings

3. You can edit or even add your own phrases. Just open the language file with any text or XML editor, edit/add your <phrase> nodes.
Make sure you provide an unique id to each phrase. The id must be alphanumerical only.

The phrases are not limited to text, you can also use CSS class, e.g.

<phrase id="FieldRequiredIndicator" class="fa fa-asterisk ew-required"/>

4. Language file is an XML file, when you edit the file, make sure that you keep it well-formed. If you use HTML tags or special
characters in the attributes of the XML tags, you need to use entity references. For example, to insert the > symbol, you need
to use &lt;. Make sure your characters are supported by the encoding of the XML file specified in the processing instruction node
(the first line). You can load the file in your browser to check if the file is well-formed, if it is, the browsers should be able to load and
display it without any errors.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 162 of 168

Note DO NOT use old language files from previous versions directly or the new phrases will be missing. You should compare the
English version of the language files from old and new version and then add the new phrases to your new language file.

Selecting Language Files for Project


Click [Tools] -> [Languages] to select the languages you want to use in the project. If more than one language is selected, a combobox
will appear on the top of the generated scripts for user to select language.

Enabling Multi-Language and Selecting Default Language


If you want to use multi-language project, make sure you have enabled Multi-Language in the [PHP]->[General] tab (see PHP Settings).

Then, select a Default Language in the [PHP]->[General] tab (see PHP Settings).

Multi-Language Property Editor

Note If you use single language, you do NOT need to use this editor, just enter your phrases in the general user interface. Only use
this editor if you use Multi-Language.

Some text properties support Multi-Language. This editor allows you to enter your property values for each language. Supported
properties are:

• Table/Field Captions
• Menu Text

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 163 of 168

• Site Title and Footer Text


• Table Page Names
• Field Edit Tag Title
• Field Error Message
• Field Image Tag Alt
• Field User Values

To edit these properties, click [Tools] -> [Multi-Language Property Editor] to open the editor. Alternatively, you can also click the small
button next to above properties in the user interface to open.

Select a property in the Property pane on the left to edit, then enter your properties in unicode. For example, you can copy and paste
from Word.

The editor supports import/export of the phrases (of the mutli-language properties only, not including the phrases in the language files):

Click the export button to export the phrases to a XML file so you can edit the file with text or XML editor or share the file with other
project. Click thie import button to choose the XML file that you want to import so you can quicky use edited phrases or easily reuse
other project's XML file.

Note Previously saved properties are displayed in bold font. Once you use this editor to save your unicode text, the saved unicode
property values will always be used prior to the original property values (in the general user interface) . The original property value
will only be used if unicode property value of the language cannot be found. If you want to edit the property, always go back to this
editor. After editing and saving unicode properties, remember to re-generate the languages file and upload them again.

Sending Email in Multi-Language


There is a subfolder named "html" inside the template archive (e.g. phpv20190.zip) containing the following HTML email templates:

• changepwd.html
• forgotpwd.html
• notify.html
• register.html
• resetpwd.html

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 164 of 168

The content of these files are in English. To make email templates in other langauges, copy the files and rename the files and translate the
content to the your languages. The files must be renamed as <original_file_name>_<language_id>.html. For example, the file nofify.html
should be renamed as notify_zh-TW.html if the file is to be translated into traditional Chinese.

Remember to put the translated files back into the "html" subfolder of the template archive.

Note If translated files not found in the "html" subfolder of the template archive and hence translated files not copied to the
generated "phphtml" subfolder, the default English version will be used.

Using Server Events


If you prefer to customize the language phrases by code, you can use the Language_Load server event. However, note that the
Language_Load event cannot change the email templates, if you want to change the email content by server event, use Email_Sending
server event to customize the Content property of the Email object. You can use the global function CurrentLanguageID() to get the
current language ID and write your code accordingly. See Server Events and Client Scripts for more details.

 ©2002-2019 e.World Technology Ltd. All rights reserved.

Import Data
The Import feature enables you to import records from an external Excel/CSV file to database table.

How to Use

To enable the feature for a table, select the table and click the Table tab, then enable the Import checkbox.

After generation, an Import button will be displayed in the table list page.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 165 of 168

To start importing the external records, click the Import button and an Import dialog box will be displayed. Click the Choose button to
select the file for import, and the import process will begin. Click the Close button once the import process is completed to refresh the list
page.

Important Notes

1. Supported import file formats are native Excel spreadsheets (xls/xlsx) and CSV (csv) only.
2. The first row of the file should contain the field names to be imported. The field names MUST match the corresponding field
names in the table. You can manipulate the field names in the Page_Importing server event (see Server Events for Import) if
the file contains pure data only.
3. All data in the file MUST match the data types of the corresponding field in the table. For example, if you are importing
into an Integer field, the data is expected to contain an integer value or the import may fail. You can however modify the field
values in the Row_Import server event (see Server Events for Import below). Importing lookup fields from display values is
NOT supported, but you can also use Row_Import event to support it in your own ways.
4. If you are importing a lot of records, the import may take a long time to complete. In that case, you can increase the
maximum execution time in Advanced Settings (see Advanced Settings for Import below).
5. For CSV file, the default quote character and delimiter used are " (double quote) and , (comma). You can change in Advanced
Settings or by Page_Importing server event.
6. To ensure an ALL OR NOTHING import, you can enable the Import records by transaction in Advanced Settings. The
transaction will be rollbacked if there is any error during the import process.
7. The default import operation is "Insert only". If you want also to update records if record with the same record key is found,
you can disable the Import records by insert only in Advanced Settings. Please make sure that you understand the
implication of this change before modifying the setting.
8. If User Level Security is enabled, by default only the Administrators has the rights to import records. To allow a non-admin
user to import records, use the TablePermission_Loaded server event (see Server Events and Client Scripts) to set an user
with Import permission, e.g. $this->setCanImport(TRUE).

Server Events for Import

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 166 of 168

Table Specific -> List Page

Page_Importing This server event allows you to modify the Import options before the import process begins. Arguments are:

$reader - File reader (\PhpOffice\PhpSpreadsheet\Reader\IReader)


$options - Array containing the import options (see below)

You can return FALSE to skip importing the file.

The options (accessed by $options["<value>"]) you can change during this event are:
maxExecutionTime - Maximum execution time for import
activeSheet - Active spreadsheet for import (default is 0, zero-based)
headerRowNumber - Header row number (default is 0, zero-based)
headers - Header array (default is empty array)
offset - Offset to start import (default is 0, zero-based)
limit - Number of records to import (default is 0, which means all records)
inputEncoding - Input encoding for data (CSV only)
delimiter - Delimiter for data (CSV only)
enclosure - Quote character for data (CSV only)

Example 1

Import selected records only

$options["offset"] = 10; // Skip the first 10th records


$options["limit"] = 5; // Import the next 5 records

Example 2

The spreadsheet contains pure data only. Supply the header manually.

$options["headers"] = ["CategoryName", "Description"];

Example 3

Change input encoding, delimiter and enclosure for CSV file

$options["inputEncoding"] = "CP1252"; // Use CP1252 for input encoding

$options["delimiter"] = ";"; // Semi-colon for delimiter

$options["enclosure"] = "'"; // Single quote for enclosure

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 167 of 168

Table Specific -> List Page

Row_Import This server event is executed before a record is imported. Arguments are:

$row - Array of data to be imported


$cnt - Current import record count

You can return FALSE to skip importing the row.

Example 1

Modify data before import

$row["Trademark"] = ExecuteScalar("SELECT ID FROM trademarks WHERE Trademark ='" . AdjustSql($row


["Trademark"]) . "'"); // Get Trademark ID from trademarks table

Example 2

Validate input data

if (intval($row["Quantity"]) > 100) // Quantity must be <= 100

return FALSE; // Skip import

Page_Imported This server event is executed after import is completed. Arguments are:

$reader - File reader (\PhpOffice\PhpSpreadsheet\Reader\IReader)


$results - Array containing the import results

The data available in the results array are (accessed by $results["<value>"]):


file - File name of the imported file
totalCount - Total records imported
successCount - Total records imported successfully
failCount - Total records imported unsuccessfully
failList - Array containing failed imports and reasons

Example

Write audit trail for import

$msg = "imported " . $results["totalCount"] . " records (successful: " . $results["successCount"] . " /
failed: " . $results["failCount"] . ") from " . $results["file"]; // Set up import message

WriteAuditTrail("log", DbCurrentDateTime(), ScriptName(), CurrentUserID(), $msg, CurrentUserIP(), "", "",


"", ""); // Write audit trail

Advanced Settings for Import

Import maximum execution time (seconds) Maximum executing time for import. Default value is 300 (5 minutes). Change to a larger
value if you are importing a lot of records.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019
Project Setup Page 168 of 168

Import records by insert only Only insert is performed. Default value is true. Uncheck if you also want to update
records with the same primary key.

Important

1. Make sure that you understand the implication before modifying this setting.
2. Beware of that if some field values in the import data are empty, they will
overwrite the data in the database.

Import records by transaction Use transaction for import. Default value is false. Change to true if you want an ALL OR
NOTHING import.

Import supported file extensions Supported file extensions for import (comma separated)

Import to CSV delimiter Delimiter for CSV file for import. Default value is , (comma).

Import to CSV quote character Quote for CSV file for import. Default value is " (double quote).

 ©2002-2019 e.World Technology Ltd. All rights reserved.

file:///C:/Users/Avijit/AppData/Local/Temp/~hhDF6F.htm 14-02-2019

You might also like