diff --git a/website/changed_md_files.sh b/website/changed_md_files.sh index ef5a602cb..d7b5eee27 100644 --- a/website/changed_md_files.sh +++ b/website/changed_md_files.sh @@ -2,7 +2,7 @@ url_array=() while IFS= read -r line; do url_array+=("$line") -done < <(git diff --name-status --diff-filter=d HEAD~1 HEAD | grep '^.*[.md]$' | awk '{print $(NF)}' | cut -d\. -f1 | cut -f2- -d '/') +done < <(git diff --name-status --diff-filter=d HEAD~1 HEAD | grep '^.*[.md]$' | grep -v 'versioned_docs' | awk '{print $(NF)}' | cut -d\. -f1 | cut -f2- -d '/') echo "[" > ./cypress/fixtures/changedFiles.json for ((i = 0; i < ${#url_array[@]}; i++)); do diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 3d0f1b2eb..97adb83a0 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -84,6 +84,10 @@ module.exports = { "label": 'v10.15', "path": 'v10.15', }, + "v11.8.5": { + "label": 'v11.8.5 (Cordova Sunset)', + "path": 'v11.8.5', + }, }, "admonitions": { "keywords": [ diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/access-levels-permissions.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/access-levels-permissions.md new file mode 100644 index 000000000..50b6f42a1 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/access-levels-permissions.md @@ -0,0 +1,90 @@ +--- +title: "Access Levels & Permissions" +id: "access-levels-permissions" +--- +--- + +Once you have added the roles, you can set up the **permissions**. Permissions is a mix of Authentication and Authorization. The Authentication options are _Everyone_ and _Authenticated_. If the developer chooses “Everyone”, then it's not covered under WaveMaker security. “Authenticated” secures the resource/service. + +Permissions can be set to three levels: + +### 1. Everyone +Access is granted to all users irrespective of whether they are logged in or not. This setting would be used for an About or Contact Us pages which can be viewed by anyone. +### 2. Authenticated +Access is granted only to users who are logged in, for example, the logout button. +### 3. Authorization +Once the `resource/service` is authenticated, then you can choose the level of “visibility”, i.e Authorization. You can choose roles which can have exclusive access to this `resource/service`. By default, all `resources/services` are “Authenticated” and are accessible to all once authenticated. + +[![](/learn/assets/sec_perm_web.png)](/learn/assets/sec_perm_web.png) + +## Setting Permissions + +Users can set permissions for web resources, services, and Prefabs. + +### Web resources +These are pages created in WaveMaker. + +### Services +Selecting **Services** option will list all the services used by your application. Services include java services, database, web services created for consumption. Each service exposes various end points for setting permissions. For example, permissions can be set for the Java service and methods; web service end points; database, table or end-points. + +### Prefabs +Permissions can be set for **Prefabs** incorporated within the app. Permissions set to a particular prefab will cascade onto all services invoked inside that Prefab. + +:::note +The permission level follows a hierarchical structure. Child level inherits from the parent if no permission is set. +::: + +## Examples +Let us look at how the security permissions work at various levels. + +- Consider in the Sample `hrdb`, each entity is exposed as a controller i.e. it has User, Vacation, Department, Employee controllers. At each table-level there are multiple operations defined. For example, User controller has operations ‘getUser’, ‘deleteUser’, ‘editUser’, and more. Once authentication is enabled at the service level, hrdb is set to be authenticated. If permission is set to the respective controller, then it will be retrieved, else it inherits parent permission of ‘hrdb’. + +- Similarly, for operations, if some permission is set, it will be retrieved, else it inherits from its parent ‘User’, else then from its parent ‘hrdb’ permission will be inherited. + +- Changing permission for the parent will affect only the children which do not have specific permissions set, permissions set to children will be retained." + +Let us look at some cases + +### Example 1 +``` +hrdb - ‘Authenticated’ +``` +**Result**: Every controller and their operations are ‘Authenticated’ inherited from hrdb. + +### Example 2 +``` +hrdb - ‘Authenticated’ +``` +``` +Changed: User permitted to ‘Admin, User’ and User operation ‘editUser’ permitted to ‘Admin’ +``` +**Result**: Only ‘editUser’ operation in User controller has permission ‘Admin’ and all other operations has permission ‘Admin, User’ inherited from its parent controller ‘User’. Rest of the controllers (Employee, Vacation etc) remain to be ‘Authenticated’ inherited from hrdb. + +### Example 3 +``` +User - ‘Admin, User’; User operation ‘editUser’ -- ‘Admin’ but hrdb permission set to ‘Everyone’ +``` +**Result**: User controller ’editUser’ operation will have ‘Admin’ and rest of their operations has permissions ‘Admin, User’ inheriting from User. Rest of the controllers (Employee, Vacation etc) will have permission ‘Everyone’ inheriting from hrdb. + +### Example 4 +``` +hrdb - ‘Everyone’, User operation ‘editUser’ permitted to ‘Admin’, User permission set to ‘Authenticated’ +``` +**Result**: User controller ’editUser’ operation will have permission to ‘Admin’ and rest of the User operations have permissions ‘Authenticated’ inherited from User. Rest of the controllers (Employee, Vacation etc) will have permission ‘Everyone’ inherited from hrdb. + +## Role Based Access to Widgets + +Once you create roles in a project, you can enable **role-based access** for a widget. + +1. Select the widget in the **Design** mode. +2. Click on the **Security** tab on the **Properties Panel**. +3. You will find that the _Widget Access_ property is set with the User Role Group as _Everyone_ by default. +You can set the User Role Group as: + - **Everyone** - access is granted to all users irrespective of whether they are logged in or not. This setting would be used for an About or Contact Us pages which can be viewed by anyone. + - **Anonymous** - access is granted only to users who are not logged in. An example would be the login button on the About page + - **Authenticated** - access is granted only to users who are logged in. For example the logout button. + - Further authenticated access can be **Role-based** ie for a particular User Role as defined in the App Role section. + +4. Select a **User Role** to make the selected widget visible to users with this role. + +[![](/learn/assets/sec_widgets.png)](/learn/assets/sec_widgets.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/app-security.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/app-security.md new file mode 100644 index 000000000..94cd5b69c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/app-security.md @@ -0,0 +1,84 @@ +--- +title: "App Security" +id: "app-security" +sidebar_label: "Overview" +--- +--- + +The WaveMaker security feature offers comprehensive security solutions to secure the apps you develop. WaveMaker offers application level security and the two major areas including “Authentication” and “Authorization”. + +### Authentication +“**Authentication**” is the process of establishing a principal who they claim to be (a “principal” generally means a user, device or some other system which can perform an action in your application). + +### Authorization +“**Authorization**” or “**Access-Control**” refers to the process of deciding whether a principal is allowed to perform an action within your application. + +### Onboarding +"**Onboarding**" is the process of retrieving user's data from various providers like DB, LDAP, AD or any custom provider. This data includes roles and role groups information. Then, Authentication is done based on user credentials, which are obtained from the security provider; and Authorization or access to various app resources such as widgets, pages, data, and APIs can be controlled through configuration. + +In WaveMaker, Security can be configured by selecting the Security option from the Project Configurations bar in the Project Workspace. + +[![sec_access](/learn/assets/sec_access.png)](/learn/assets/sec_access.png) + +## How App Security Works + +Browser executed JavaScript can be easily manipulated. Therefore, security is server-side responsibility. WaveMaker server security consists of a series of filters. These filters determine if the request should be allowed. WaveMaker supports the following types of authentication: + +- HTTP BASIC authentication headers - an IETF RFC-based standard +- LDAP/ AD - a very common approach to cross-platform authentication needs, especially in large environments +- Form-based authentication for simple user interface needs +- Automatic "remember-me" authentication +- Anonymous authentication allowing every unauthenticated call to automatically assume a particular security identity + +If the server fails to authenticate a user, it will result in HTTP 401 response to the client. An authorization failure will result in 403 response sent to the client. If the requester is not logged in but must be, to access the requested resource, the user is redirected to the login page or can be prompted with a login dialog. If the user is logged in but lacks the credentials to access the requested resource, the request will be denied (403). + +When security/authentication is enabled, all services are restricted to logged-in users by default. Only the login service is available to anonymous users. This can be customized using setup services. + +WaveMaker also provides Role-based Access Control to control widget visibility. Role-based Access Control is a client-side function. As such, it should only be considered as a helper. It helps present the proper interface, based on the user's role. Role widget visibility must not be relied upon for securing resources. Take the example where only admin users are allowed to access a function invoked by a button click. Hiding the button to all but admin users via the client roles mechanism prevents non-admin users from expecting the button to work. However, the function of the button must be secured using server-side access control in order to be secure. + +## How security is implemented + +Once Authentication is switched on the User Configuration information can be obtained from **Service Providers** like Database, LDAP, AD or any custom provider. + +[![sec_prov](/learn/assets/sec_prov.png)](/learn/assets/sec_prov.png) + +Depending on the security provider enabled, **users and roles** are on-boarded through configuration. Details regarding the access to details and the corresponding App role needs to be configured. + +### App Roles +**App Roles** need to be added based on the configuration. By default, the platform provides with two roles admin and user. You can either retain/delete the same and further add to the list. When adding new App Roles ensure that the Roles are specified by the selected service provider. + +### Permissions +**Permissions** can be set to app resources such as pages and services i.e. database, API & custom Java using the above-configured app roles. **Accessibility** or the level of visibility for each UI component can be configured separately from the widget properties. Widgets can be made accessible to certain roles or role groups based on the configuration. + +### Login +Application **Login** can be configured using a Page or a Dialog. Each role defined in the application can have a separate **landing page**. + +### OWASP +Security vulnerabilities like XSS and CSRF can be prevented from the **OWASP** Configuration. + +## Security Terminology + +The various terminology used by WaveMaker concerning Security: + +- **Authentication**: a process by which the access to app restricted to known/authentic users. +- **Authorization**: a process by which the access to various aspects of the app such as services, widgets, and functionality; is restricted to the specified app roles. +- **Users**: Authentic users of the app identified via a Username and Password. +- **App Roles** identify the level of authorization allowed to a given user. These roles are assigned to Users mentioned in the previous step. +- **Permissions**: Each of the web resource and service used in an app is assigned various permission levels: + + - _Everyone_ - anyone can access this item i.e. no authentication required + - _Authenticated_ - these items are accessible to authenticated users who will be identified via the roles assigned to them + - _Anonymous_ - widgets at this access level are visible to only users who are not logged in. _ + +:::note +This setting can be used only for widget access. +::: + +:::important +The permission levels follow a hierarchical structure with child element inheriting parent permissions if none are specified. +::: + +- **Login Configuration** defines the login behavior once authentication is enabled. There are two behaviors that can be defined - login page and landing page: + - specify the _UI for login_ - dialog or page. In the case of a page for login, you can use the default login page provided by Studio or design your own login page. + - _Landing Page_ defines the page to be displayed once the user logs in. The page to be displayed can be defined based upon the role of the logged in user. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/authentication.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/authentication.md new file mode 100644 index 000000000..9fc590b2d --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/authentication.md @@ -0,0 +1,308 @@ +--- +title: "Authentication" +id: "authentication" +--- +--- +Authentication is a process by which the access to the app is restricted to known/authentic users. + +A WaveMaker application can include a login page that requires users to sign on in order to gain access to the application. In order to set up user authentication, you need to configure a data source that stores the user IDs and passwords. You have the following options for storing this data: + +- Any **database** supported by WaveMaker +- Lightweight Directory Access Protocol (**LDAP**) +- Active Directory (**AD**) +- Central Authentication Service (**CAS**) +- Security Assertion Markup Language (**SAML**) +- Custom Java Service +- WaveMaker Studio also provides a simple **Demo** data source. You can use this data source to set up and test your login page during development. We do not recommend the Demo data source for production applications. + +[![sec_prov](/learn/assets/sec_prov.png)](/learn/assets/sec_prov.png) + +### Selecting Security Providers + +You can choose any of the following security providers for your WaveMaker applications. + +## Demo + +When the WaveMaker developer enables security, the demo is the default option. This option, as the name suggests, is for demo purpose, ease the user into security features. Demo option provides by default two out of box users called “admin” and “user” with password same as username. Developers can add/remove users. + +The Demo data source provides a great design-time tool for authentication. With this data source, you can quickly define a few usernames and passwords to use while creating and testing the login functionality for your application. It is recommended that you set up a more robust data source for authentication before you deploy your application into production. + +By default, the Demo data source provides two users - _user_ and _admin_. These users are assigned to the _user_ and _admin_ role respectively. You can create roles on the **Roles** tab. You can add new users and assign them roles created in the **Roles** tab. You can also delete existing users by clicking the **Delete** icon next to a user row. + +## Database + +You can use a database to store your authentication data. The database must include a table that provides a column for usernames and passwords. The usernames and passwords must be stored in the same table in the database. + +When you choose **Database** as the **Security Provider**, you can perform the following configurations on the **Users** tab: + +- **Database Configuration**: + - **Database**: The Database that contains the tables for the username and password fields. Choose the Database from the pull-down menu. (You have to import the database first. See [Database Integration](/learn/app-development/services/database-services/working-with-databases/). If you have imported the database and it does not appear in this list, try closing and reopening the project). + - **User Table**: Select the table that contains the columns for the usernames and passwords. +- **User**: + - `User Id Column`: Select the column for the user id + - `Username Column`: Select the column for the user (login) name + - `Password Column`: Select the column for the password. +- **Role Mapping**: This will build the query to fetch the role values from the user table based on the logged in user details. See [User Onboarding](/learn/app-development/app-security/authorization/#user-onboarding) for more information. + +## LDAP + +**LDAP** (Lightweight Directory Access Protocol) is a software protocol for enabling anyone to locate organizations, individuals, and other resources such as files and devices in a network, whether on the public Internet or on a corporate intranet. + +To set up authentication using an LDAP data source, choose **LDAP** as the **Security Provider**. + +When you choose **LDAP** as the **Security Provider**, you can perform the following configurations: + +- **LDAP URL**: This field specifies the host name and port number of the LDAP server. This is the root node of which security will be able to use - `ldap://localhost:389/dc=wavemaker,dc=com`. For deployment profile, you can specify _multiple LDAP server URLs_, if required, by providing the multiple LDAP URLs as space-separated values, from the security tab of the [Profile Configuration](/learn/app-development/deployment/configuration-profiles). + +[![](/learn/assets/sec_user_ldap_url.png)](/learn/assets/sec_user_ldap_url.png) + +- **Manager DN**: Distinguished Name for admin access, this is an optional field +- **Manager Password**: Password in case admin access is mentioned above, this is an optional field +- **User Search Pattern:** Filter used to find the user in the directory, relative to the root specified above. The only valid variable is {0} which is replaced with the user's login name. For example: "cn={0},ou=people" +- **Test user DN:** Full DN of the user account for testing connection URL. Example: someUser +- **Test user Password:** The password for the test account that you use to test the LDAP URL. + +Once you have configured the security provider, click the **Test Connection** button.  The **Test Connection** button only verifies that the _Test User DN_ and _Password_ can be used to "bind" using the URL. You must specify a full DN for the _Test User DN_. A search is not performed for **Test Connection** as is normally done for login. + +### Role Mapping + +Role Mapping for logged in users can come from the configured LDAP security provider or an imported Database. [![sec_user_ldap_role](/learn/assets/sec_user_ldap_role.png)](/learn/assets/sec_user_ldap_role.png) + +- **Search User Role**: Check this box to select the user role provider - Database or LDAP. + - If you select _**LDAP**_ then both authentication and authorization (roles) will be retrieved from the LDAP security provider. You need to provide: + - **Group Search Base** the search base from which the search for group membership should be performed. Eg: ou=roles, where ou is organizational unit + - **Group Name Attribute** the attribute that holds data about the role name for a group. Eg: cn (common name) + - **User Group Filter** the search filter used to search through the LDAP directory to find the roles to which an authenticated user belongs. {0} would be substituted with the user's DN. Eg: (member={0}) + - If you select _**Database**_ then authentication is performed using LDAP and authorization (roles) content is retrieved from the database. This allows you to use username and password credentials from LDAP while retrieving role content from a separate database. For role configuration using database [see here](/learn/app-development/app-security/authorization/#user-onboarding). + +:::note +These configurations are for the development profile of the app. Configuration for Deployment profiles needs to be made from the Config Profile. [Refer here for more](/learn/app-development/deployment/configuration-profiles/#deploy-profile). +::: + +## Active Directory + +**Active Directory Domain Service** is Microsoft's Directory Server. It provides authentication and authorization mechanisms as well as a framework within which other related services can be deployed (AD Certificate Services, AD Federated Services, etc). It is an **LDAP** compliant database that contains objects. + +To set up authentication using an Active Directory data source, choose **Active Directory** as the **Security Provider.** + +When you choose **Active Directory** as the **Security Provider**, you can perform the following configurations: + +- **URL:** This field specifies the protocol and hostname of the AD server. Example: _ldap://ad.mydomain.com_ +- **Domain:** The fully qualified domain name (FQDN) of the Active Directory domain is an optional field. For instance: example.com +- **Root Dn:** It will be automatically populated based on domain entry only the first time. The user can change this later and subsequent changes to the domain will have no effect on rootDn. Example: When Domain is example.com; then RootDn is automatically updated as  dc=example, dc=com. +- **User Search Pattern** is a filter which is prepopulated by default. Users can change it, as per their requirement. +- **Test username:** Full DN of the user account for testing connection URL. Example: user1. If the domain is provided, then simply enter the username. On the other hand, if a domain is not provided, then username must be appended to the domain name. +- **Test user password:** The password for the test account that you use to test the AD URL. + +Once you have configured the security provider, click the **Test Connection** button, test user credentials are authenticated in this step. Keep in mind, during runtime, the authentication will happen based on user credentials and user search pattern. [See here for more use cases](/learn/how-tos/active-directory-use-cases/). + +### Role Mapping + +Role Mapping for logged in users can come from the configured Active Directory security provider or an imported Database. [![sec_user_ad_role](/learn/assets/sec_user_ad_role.png)](/learn/assets/sec_user_ad_role.png) + +- **Search User Role**: Check this box to select the user role provider - Database or AD. + - If you select _**AD** _then both authentication and authorization (roles) will be retrieved from the AD security provider. You need to configure the **Group Role Attribute.** + - If you select _**Database** _then authentication is performed using AD and authorization (roles) content is retrieved from the database. This allows you to use username and password credentials from AD while retrieving role content from a separate database. For role configuration using database [see here](/learn/app-development/app-security/authorization/#user-onboarding). + +:::note +These configurations are for the development profile of the app. Configuration for Deployment profiles needs to be made from the Config Profile. [Refer here for more](/learn/app-development/deployment/configuration-profiles/#deploy-profile). +::: + +## CAS + +The **Central Authentication Service** (**CAS**) is a single sign-on protocol for the web. Its purpose is to permit a user to access multiple applications while providing their credentials (such as user id and password) only once. It also allows web applications to authenticate users without gaining access to a user's security credentials, such as a password. + +To set up authentication using a Central Authentication Service, choose **CAS** as the **Security Provider**. [Know more about single sign-on using CAS](/learn/app-development/app-security/central-authentication-system/). + +When you choose **CAS** as the **Security Provider**, you can perform the following configurations on the **Setup** tab: + +- **Server URL**: This field specifies the protocol and hostname of the CAS server. Example: http://mydomain.com:8080/cas +- **Login URL**: This field is the login URL of the CAS server +- **Validation URL**: This field specifies the URL used for validating the service ticket issued by the CAS server. +- **Service Parameter Name**: This field configures the request parameter to look for when sending request to CAS E.g./cas-server-webapp-4.0.0/login?service=https%3A%2F%2Flocalhost%3A8443%2Fcassample-1.0%2Flogin%2Fcas +- **Ticket Parameter Name**: This field configures the Request Parameter to look for when attempting to see if a CAS ticket was sent from the server. The default value is “ticket”. Eg. /cassample-1.0/login/cas?ticket=ST-1-lCYeRuXfmhKid1auqdy2-cas01.example.org + +### Role Mapping + +Role Mapping for logged in users can come from the configured CAS security provider or an imported Database. [![sec_user_cas_role](/learn/assets/sec_user_cas_role.png)](/learn/assets/sec_user_cas_role.png) + +- **Select User Role Provider**: Choose the user role provider. There are two role providers - CAS and Database. + - The user can configure **CAS** role attribute and the same role can be configured in the WaveMaker application.  The **Role Attribute Name** needs to be configured. + - If you select **_Database_** then authentication is performed using CAS and authorization (roles) content is retrieved from the database. This allows you to use username and password credentials from CAS while retrieving role content from a separate database.For role configuration using database [see here](/learn/app-development/app-security/authorization/#user-onboarding). + +:::note +These configurations are for the development profile of the app. Configuration for Deployment profiles needs to be made from the Config Profile. [Refer here for more](/learn/app-development/deployment/configuration-profiles/#deploy-profile). +::: + +## SAML + +**Security Assertion Markup Language (SAML)** is an XML-based standard for exchanging authorization and authentication data between security domains. SAML exchanges are between + +- an identity provider (IdP) – producer of assertions, and +- service provider (SP) – consumer of assertions. + +SAML Configuration in WaveMaker helps you configure the WaveMaker application with any SAML 2.0 compliant Identity provider. [Know more about SAML](/learn/app-development/app-security/saml-integration/). + +:::note +These configurations are for the development profile of the app. Configuration for Deployment profiles needs to be made from the Config Profile. [Refer here for more](/learn/app-development/deployment/configuration-profiles/#deploy-profile). +::: + +## Open ID + +**OpenID** is an open standard and decentralized authentication protocol. It allows you to use an existing account like Google, or Facebook, or Yahoo etc., to sign in to multiple websites, without needing to create new passwords. + +WaveMaker allows you to authenticate your apps with OpenID. Setting the Security Provider to OpenID will allow you to configure a Service Provider of your choice. [![](/learn/assets/OpenID_config1.png)](/learn/assets/OpenID_config1.png) This involves the following details: + +### Identity Provider Information +- **Provider ID** is the Service Provider, it can be Google, Facebook or anything. +- **Authorization Url**, **Token Url**, **JWKS Url**, and **User Info Endpoint** of the authorization service provider for obtaining the authorization and access to the service. For Google provider, these fields are pre-populated by WaveMaker. + +### Service Provider Information +- **Redirect URL** is pre-populated by WaveMaker and is not editable. You need to copy this link and use it to as the callback URL in Provider app settings page when you register the app. +- If the application is deployed outside of WaveMaker then the redirect URL for the deployed applications will be in the below format. + **"https:////oauth2/code/{providerid}"**. + +### Integration Information +- Client Credentials issued once your app is registered with the Provider. It will be in the form of **Client ID** and **Client Secret**. +- **Scopes** defines what the access token can do and what resources it can access. Check with the selected service provider to understand how to further configure this field, usually, it will be email, username, etc.. +- **User Name Attribute**: Attribute name used to access the user's name from the user info response. + +### Role Mapping +- **Search User Role**: Select this option for authorization role mapping +- **Select User Role Provider**: + - If you select **OpenId** then both authentication and authorization (roles) will be retrieved from the OpenId security provider. You need to provide **Role Attribute** - the role parameter configured in the Identity Provider. + - If you select **Database** then authentication is performed using OpenId and authorization (roles) content is retrieved from the database. This allows you to use username and password credentials from OpenId while retrieving role content from a separate database. For role configuration using database [see here](/learn/app-development/app-security/authorization/#user-onboarding). + + +:::note +These configurations are for the development profile of the app. Configuration for Deployment profiles needs to be made from the Config Profile. [Refer here for more](/learn/app-development/deployment/configuration-profiles/#deploy-profile). +::: + +## Custom + +To set up authentication using Java Services, choose **Custom** as the **Security Provider**. + +[![sec_user_custom](/learn/assets/sec_user_custom.png)](/learn/assets/sec_user_custom.png) + +When you choose **Custom** as the **Security Provider**, you need to specify the _fully qualified Java Class_ name, if this does not exist a sample implementation will be generated at the location as shown below. + +[![](/learn/assets/sec_user_custom_java.png)](/learn/assets/sec_user_custom_java.png) + +This Java Class should: + +1. implement the `WMCustomAuthenticationManager`, whose signature is given below: + +```java + /** + * Copyright © 2015 WaveMaker, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.wavemaker.runtime.security; + + import org.springframework.security.core.AuthenticationException; + + public interface WMCustomAuthenticationManager { + + /** + * should return WMUser object if the authentication details can be extracted from authRequestContext. + * Otherwise the method should return null. + * @param authRequestContext + * @return + */ + public WMUser authenticate(AuthRequestContext authRequestContext) throws AuthenticationException; + } +``` + +The AuthRequestContext has the following structure. + +```java +package com.wavemaker.runtime.security; + +import javax.servlet.http.HttpServletRequest; +import java.io.Serializable; + +public class AuthRequestContext implements Serializable { + + private String username; + + private String password; + + private HttpServletRequest httpServletRequest; + + public AuthRequestContext(HttpServletRequest httpServletRequest) { + this(null, null, httpServletRequest); + } + + public AuthRequestContext(String username, String password, HttpServletRequest httpServletRequest) { + this.username = username; + this.password = password; + this.httpServletRequest = httpServletRequest; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public HttpServletRequest getHttpServletRequest() { + return httpServletRequest; + } +} +``` +You can handle exceptions by throwing [subclasses of AuthenticationException](http://docs.spring.io/autorepo/docs/spring-security/3.2.3.RELEASE/apidocs/org/springframework/security/core/AuthenticationException.html). + +2. and returns a **WMUser** object which can be initialized by a call to the following constructor: +``` +public WMUser(String userName, String password, Collection roles) +``` + +For example, the following sample implementation extracts the **user** value from the **ticket** parameter from the Http header data and adds the roles of user and admin, accordingly. + +:::note +You can use any parameters returned by the HttpServletRequest, here we are showing username and password fields. +::: + +```java +import java.util.List; +import java.util.List; +import java.util.ArrayList; + +import javax.servlet.http.HttpServletRequest; + +import com.wavemaker.runtime.security.WMCustomAuthenticationManager; +import com.wavemaker.runtime.security.WMUser; +import com.wavemaker.runtime.security.AuthRequestContext; + +public class SecureService implements WMCustomAuthenticationManager { + @Override + public WMUser authenticate(AuthRequestContext authRequestContext) { + String username = authRequestContext.getUsername(); + String password = authRequestContext.getPassword(); + HttpServletRequest httpServletRequest = authRequestContext.getHttpServletRequest(); + if(username.equals("John") && password.equals("John123")) { + List roles = new ArrayList(); + roles.add("admin"); + return new WMUser(username,password,roles); + } else if(username.equals("Jane") && password.equals("Jane123")) { + List roles = new ArrayList(); + roles.add("user"); + return new WMUser(username,password,roles); + } + return null; + } +} +``` \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/authorization.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/authorization.md new file mode 100644 index 000000000..6df5ec448 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/authorization.md @@ -0,0 +1,52 @@ +--- +title: "Authorization" +id: "authorization" +--- +--- + +**Authorization** is a process through which the access to various aspects of the app such as services, widgets, and functionality is restricted to the specified app roles. + +Enabling authentication in an application makes all pages (except Common, Login) and services to be authenticated. Common and Login pages have permission set as ‘Everyone’ and this cannot be changed. For the other pages and services, WaveMaker allows you to control the application behavior based on the user's role. It is a three-step process of: + +1. _defining the roles_, +2. _assigning these roles to users_ and then +3. _setting the access levels_ to various pages, services and widgets of the app. + +## User Onboarding + +In order to use Role-based Access Control, you must have configured Security Providers and Roles. The configuration for user details should be set. + +[![](/learn/assets/sec_user_db.png)](/learn/assets/sec_user_db.png) + +_Role Configuration_ can be Basic or Custom. In the case of **Basic**, a HQL query will be built by default in read-only mode. In case of **Custom**, you can change the query to suit the app needs. + +:::note +Here we are talking about the database-based role configuration. For other role providers like LDAP, AD etc., refer to the corresponding section in [Authentication document](/learn/app-development/app-security/authentication/). +::: + +- In the case of **Basic Role Configuration**, set the _Role Column_ to the field within the user table where role information is stored. + +:::note +In case the role column is in a related table, use Custom query. +::: + +[![](/learn/assets/sec_user_db_role1.png)](/learn/assets/sec_user_db_role1.png) + +- In the case of **Custom Role Configuration**, Query Type can be set to HQL or SQL. By default, HQL is selected and a default query is generated, which can be modified. + +:::note +The username and role can reside in separate tables and you can write a query to retrieve the information. **The parameter to the query LOGGED_IN_USERNAME needs to be retained as it is, WaveMaker stores the username details in this variable**. +::: + +[![](/learn/assets/sec_user_db_role2.png)](/learn/assets/sec_user_db_role2.png) + +- As an example, if you select Database as Security Provider; sample hrdb as the Database; User as the Entity; Username, Userid and Password as themselves, then the sample query would be provided along with a text box to enter a sample value for username and test the query. + +[![](/learn/assets/sec_user_db_role3.png)](/learn/assets/sec_user_db_role3.png) + +## App Roles + +You need to add the roles that you want to use in your application as per the roles in the above-mentioned Security Providers and Roles in the **App Roles** tab. There are two App Roles - _admin_ and _user_ offered for all providers. They are for authorization and provided out of the box. Users can add/remove to suit their needs. Using the arrow keys, you can set the **role precedence** for multiple roles within an application. This is particularly useful when a single user has multiple roles with different overlapping functionality. For example, Manager has two roles – admin and user. And for admin the landing page is set as EmployeeDashboard, while user has the landing page as EmployeeProfile. Based on the role precedence the corresponding landing page takes priority, i.e., when Manager logs in, if admin role has higher precedence then EmployeeDashboard page is displayed, if user role has higher precedence then EmployeeProfile page is displayed. + +[![](/learn/assets/sec_roles.png)](/learn/assets/sec_roles.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/central-authentication-system.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/central-authentication-system.md new file mode 100644 index 000000000..dce8f4991 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/central-authentication-system.md @@ -0,0 +1,70 @@ +--- +title: "Central Authentication System" +id: "central-authentication-system" +--- +--- + +The Central Authentication Service (CAS) is a single sign-on protocol for the web. Its purpose is to permit a user to access multiple applications using the same underlying authentication service. For example, a company has HRIS system which authenticates using LDAP. Now we want to build a Leave application using WaveMaker. If we need to provide a single login to Leave App & HRIS, then CAS is the solution to enable single sign-on. + +CAS also allows web applications to authenticate users without gaining access to a user's security credentials, such as a password. The CAS protocol involves at least three parties: a client web browser, the web application requesting authentication, and the CAS server. It may also involve a back-end service, such as a database server, that does not have its own HTTP interface but communicates with a web application. + +When the client visits an application desiring to authenticate to it, the application redirects it to CAS. CAS validates the client's authenticity, usually by checking a username and password against a database (such as Kerberos, LDAP or Active Directory). If the authentication succeeds, CAS returns the client to the application, passing along a security ticket. The application then validates the ticket by contacting CAS over a secure connection and providing its own service identifier and the ticket. CAS then gives the application trusted information about whether a particular user has successfully authenticated. + +[Know more about CAS](https://wiki.jasig.org/display/CAS/Home). + +To set up authentication using a Central Authentication Service in WaveMaker apps, enable from the security dialog, choose _CAS_ as the **Security Provider**. + +[![](/learn/assets/sec_access.png)](/learn/assets/sec_access.png) + +[![](/learn/assets/sec_user_cas.png)](/learn/assets/sec_user_cas.png) + +When you choose _CAS_ as the **Security Provider**, you can perform the following configurations on the **Users** tab: + +## Server URL +This field specifies the context path of the CAS server. Example: http://mydomain.com:8080/cas +## Login URL +This fields specifies the login path relative to the server URL where login page will be shown. Example: http://mydomain.com:8080/login. + +:::note +This field will be auto-populated based upon the Server URL and it can be edited as per requirement. +::: + +## Validation URL +This fields specifies the URL where service ticket validation will happen. Example: http://mydomain.com:8080/serviceValidate. + +:::note +This field will be auto-populated based upon the Server URL and it can be edited as per requirement. +::: + +## Service Parameter Name +This fields helps configure the callback URL for CAS login. The default value is 'service'. For example, `cas-server-webapp/login? service=https%3A%2F%2Flocalhost%3A8443%2Fcassample-1.0%2Flogin%2Fcas` + +## Ticket Parameter Name +This fields helps configures the Request Parameter to look for when attempting to see if a CAS ticket was sent from the server. The default value is 'ticket'. For example, `/cassample-1.0/login/cas?ticket=ST-1-lCYeRuXfmhKid1auqdy2-cas01.example.org`. + +## Test Connection +Clicking on Test Connection will open a new window that redirects to CAS login page . After login, sample response will be shown in tabular format. The possible attributes for the role attribute name, in case of CAS authorization, will be extracted from here. + +## Role Mapping +This section can be used to define roles for the purpose of authorization. Your app might need authentication but no authorization, in such cases _un-check_ the **Search User Role** option. + +## Select User Role Provider +Choose the user role provider. + +1. If you select **CAS**, mention the attribute name returned by the CAS that contains the User Role values. The **Role Attribute Name** will be populated from the CAS authentication response, after successful Test Connection, you can choose from the list. In case you know the attribute name, you can enter it without testing the connection. +2. If you select **Database** then authentication is performed using CAS and authorization (roles) content is retrieved from the database. This allows you to use username and password credentials from CAS while retrieving role content from a separate database. + +### Database Authentication +- **Data Model**:  The Data Model (database) that contains the tables for the username and password fields. Choose the Data Model from the pull-down menu. (You have to import the database first. If you have imported the database and it does not appear in this list, try closing and reopening the project). +- **Entity**: Select the table that contains the columns for the usernames and passwords. +- **Username Field**: Select the column for the user (login) name. + +:::note +Ensure that the username values that are returned by the CAS authentication exist in the database, these will not be added automatically. +::: + +- **Userid Field**: The primary key for the table selected in Entity +- **Password Field**: Select the column for the password. +- **Role Field**: Select the column for the user's role. + +[![](/learn/assets/sec_user_cas_role.png)](/learn/assets/sec_user_cas_role.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/concurrent-sessions.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/concurrent-sessions.md new file mode 100644 index 000000000..21f618270 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/concurrent-sessions.md @@ -0,0 +1,24 @@ +--- +title: "Concurrent Sessions" +id: "concurrent-sessions" +--- +--- + +At WaveMaker, we constantly bring ways to make applications more secure. Configure application login settings to add an extra security layer by using concurrent sessions. By taking advantage of the Spring framework in WaveMaker generated application code, Spring Security prevents app users from concurrently authenticating to the same application more than a specified number of times. + +## How it works + +WaveMaker developers can easily enable maximum concurrent sessions in the Spring framework. It allows you to impose a setting and restrict their application users. You can create a policy to choose what happens when max concurrent sessions have reached. One of the policies is to invalidate the least recently used session. + +Max Concurrent sessions can be any positive number or -1 (for unlimited concurrent sessions) but not a zero. + +## Configuring Concurrent Sessions in WaveMaker Apps + +Concurrent Sessions feature is disabled by default and set to -1 for unlimited concurrent sessions. +The number of concurrent sessions can be configured from the Security dialog. + +1. Go to **Security** -> **Authentication** -> **Login Configuration** -> **Max Concurrent Sessions per User**. +2. Set the value for allowed **Max Concurrent Session per User**. + +[![concurrent-sessions](/learn/assets/concurrent-sessions.png)](/learn/assets/concurrent-sessions.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/hostheader-injection.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/hostheader-injection.md new file mode 100644 index 000000000..fab4effb7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/hostheader-injection.md @@ -0,0 +1,42 @@ +--- +title: "Prevent HostHeader Injection" +id: "hostheader-injection" +sidebar_label: "HostHeader Injection" +--- +--- + +At WaveMaker, we continuously bring ways to make applications more secure by ensuring the way applications are built and that it stands a better chance of not being breached. + +Handling HTTP host header in an unsafe way can lead to nasty host header attacks. These vulnerabilities typically occur due to our wrong assumption that the header is not user-controllable. We end up trusting Host headers, resulting in poor validation or escaping of values. + +## Potential Risks + +Typically, an attacker injects a harmful payload into host header, which can manipulate server-side behavior. Therefore, Host header attacks can lead to: + +- Web-cache poisoning +- Password reset poisoning + +For more information, see [OWASP in WaveMaker](/learn/app-development/app-security/owasp). + +## Preventing HostHeader Injection + +In reality, Hostheader is user-controllable and can be manipulated by using tools like Burp Proxy. Therefore, it is necessary to: + +- Validate the Hostheader +- Whitelist permitted hostname or domains + +## How WaveMaker Prevents HostHeader Injection + +Hostnames are domain names through which you run your application. You can specify the Hostnames where the WaveMaker application is deployed to prevent HTTP Host header injection attacks. + +Here you can determine which Hostnames should be allowed. The platform will reject HTTP requests with different Host header values than the specified list. The default behavior is to allow any hostname if not configured. + +## How to configure Allowed Hosts + +In a WaveMaker application, the list of allowed Hostnames can be configured from **Security** -> **Safeguards** dialog, as shown below. + +- In the Safeguards dialog, go to **Allowed Hosts** section, +- Add the permitted hostnames or domains in the **Hosts** field and click **Save**. + +[![hostheader-injection](/learn/assets/allowed-hosts.png)](/learn/assets/allowed-hosts.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/login-configuration.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/login-configuration.md new file mode 100644 index 000000000..73a00cc25 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/login-configuration.md @@ -0,0 +1,69 @@ +--- +title: "Login Configuration" +id: "login-configuration" +--- +--- + +**Login Configuration** defines the login behavior once authentication is enabled. + +There are two behaviors that can be defined: + +- login page and +- landing page. + +You can also configure the session timeout behavior. + +## Setting Login Page + +1. **How** the Login should be handled: using a **login page** - you can use the default login page provided by Studio or create your own page; + +[![](/learn/assets/security_loginpage_1.png)](/learn/assets/security_loginpage_1.png) + +2. or using a **login dialog** pop-up provided by Studio. This dialog is present in the _Common page_ as "_CommonLoginDialog_" and can be customized. + +[![](/learn/assets/security_logindialog.png)](/learn/assets/security_logindialog.png) + +## Setting Landing Page + +1. **Where** the user should land: **Landing page** can be defined to be different for different roles the user is assigned. For example, an admin might want to start with the employee management page, while a user would start with their profile page. In such cases, the employee management page would be the Landing Page for the admin role and the employee profile page would be the Landing Page for the user role. +2. Few things that you need to be aware of regarding the landing page configured here and the home page configured in the [Project Settings](/learn/app-development/wavemaker-overview/product-walkthrough#project-settings) dialog ([Settings accessed from the Project Configurations of Workspace](/learn/app-development/wavemaker-overview/product-walkthrough#project-workspace)): + - In case the app is not secure, user is redirected to the Home page configured in the project settings. + - In case the app is secure but the Home Page is not (permission set to everyone), user is redirected to the Home page configured in the project settings. + - In case the app and Home Page are secure (permission set to specific user role), user is redirected to the configured login page as per the user role. + +[![](/learn/assets/security_landingpage.png)](/learn/assets/security_landingpage.png) + +## Session Timeout + +Session timeout behavior can also be defined. Session timeout occurs due to session inactivity or deletion of browser cookies. The re-login mechanism in the app can be configured as follows: + +- Page: On session timeout, the user is redirected to the configured login page. Any page can be configured to redirect the user on session timeout. +- Dialog: On session timeout, a dialog pops-up, for re-logging in the app. + +[![](/learn/assets/security_reloginpage.png)](/learn/assets/security_reloginpage.png) + +In both the cases, on re-login, redirection occurs based upon the user login: + +- same user (last logged-in), the user is redirected to the last page(session timeout through Page) or remains in the same state(session timeout through Dialog). +- different user, the user is redirected to the Landing Page against the user role + +Control comes to the _onSessionTimeout callback_ function as soon as session timeout is detected by the app. You can perform a custom action like clearing sensitive data, etc in this callback. This function can be invoked from **app.js** file: + +``` +App.onSessionTimeout = function () { + +}; +``` +This function can be invoked from any **page.js** file: +``` +Page.onSessionTimeout = function () { + +}; +``` + +## Setting session timeout + +By default, the session timeout is set to 30 minutes. You can choose to change it. + +[![](/learn/assets/security_timeout.png)](/learn/assets/security_timeout.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/openid-auth.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/openid-auth.md new file mode 100644 index 000000000..d35a3581f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/openid-auth.md @@ -0,0 +1,113 @@ +--- +title: "Configuring Open ID authentication providers - Google, Okta, Auth0" +id: "openid-auth" +sidebar_label: "Open ID Authentication" +--- + +In this document, we will be describing about how to use Open ID authentication in WaveMaker application. + +--- + +Using Open ID, WaveMaker applications can let their customers login using their already existing identity such as Google Account, Okta, or AuthO. It is also possible to implement SSO by setting up multiple applications use the same Open ID provider. Some well-known Open ID providers include Google, Okta, and AuthO. For example, Twitter uses Open ID authentication where you can select Identity Provider like Google to login. + +## How Open ID Authentication Helps + +Open ID Authentication helps verify the user identity with the Identity Providers. Following are some points how it helps: + +- **Easy maintainance of usernames and passwords**: Open ID stops proliferation of username, passwords enabling reuse of identify from providers such as Google, Apple & Facebook. Developers also benefit from not needing store usernames and passwords. + +- **Lower Password security risks**: Open ID providers do not share passwords with any website and protect online identity. + +- **Simple Sign-up process**: With WaveMaker, developer delegates authentication to Open ID providers like Google, Facebook, Okta, Auth0 or any other Open ID standards. You login with a single click, avoiding the efforts and time to feed the redundant information to use an application. + +Here is more information on Open ID Authentication + +## Open ID Authentication Workflow + +1. **User** accesses the **Application**. +2. **Application** displays options to choose from available **Identity Providers**. +3. **User** gets directed to the **Identity Provider** to provide necessary details for authentication and authorization. +4. **Identity Provider** verifies the user’s identity and validates the user details. +5. **User** successfully logs into the application and the role is assigned to the user +6. Session gets established between **User** and **Application**. + +[![Open ID architecture](/learn/assets/OpenID_Architecture.png)](/learn/assets/OpenID_Architecture.png) + +## Configuring Open ID + +1. Go to **Project** > **Security**. +[![Open ID security](/learn/assets/wm_openid_f_1.png)](/learn/assets/wm_openid_f_1.png) + +2. Go to **Authentication & Authorization**. + +3. Enable **Authentication**. + +4. Go to **Security Providers** > **Open ID**. + +5. Select **Provider ID** from the drop-down menu. For example Google or Custom (Okta, AuthO). + +[![Open ID configuration](/learn/assets/wm_openid_f_2.png)](/learn/assets/wm_openid_f_2.png) + +Once the Open ID provider is selected, you can configure the security specifications based on the provider. + +:::note + +- For more information, see [Google as provider](/learn/how-tos/implement-openid-google-provider) +- For more information, see [Okta as provider](/learn/how-tos/implement-openid-okta-provider) + +::: + +## Properties + +Below are the Open ID Authentication security specifications used to configure the application with the Open ID Identity Provider. + +[![Open ID properties](/learn/assets/wm_openid_f_3.png)](/learn/assets/wm_openid_f_3.png) + +### Identity Provider Information + +This section contains configuration properties for Identity Provider. + +- **Provider ID:** Allows User to select the Identity Provider +- **Authorization URL:** Endpoint that initiates the authentication of the end user +- **Token URL:** Endpoint used to communicate Access token, ID token and refresh token +- **JWKS URL:** Json Web Key Set (JWKS) endpoint stores the information on public keys used to verify the Json Web tokens + +:::note + +JWKS property can also be configured using a certificate file that contains a public key instead of fetching the keys from the JWK set URL. Users can upload the certificate file into the application src/main/resources folder and use classpath:filename, or if the file is in a file system use file:filepath. +The JWKS property can be configured with both file and URL separated with a `;`. The public key is read from the file path and in case of any failures it will fall back to the URL. + +::: + +- **User Info Endpoint:** User Info endpoint allows the client application to fetch the required claims about the authenticated end user +- **Logout URL:** Endpoint used by the client application to erase provider-side session and related cookies + +### Service Provider Information + +This section contains configuration properties for service provider. + +- **Redirect URL:** Redirect endpoint is the URL to which the client receives the response + +### Integration Information + +This section contains configuration properties for integration between Service Provider and Identity Provider. + +- **Client ID:** Unique identity for the registered client +- **Client Secret:** Client specific information that is only known to application and the authorization server. This is application's password +- **Scopes:** Scope parameter is used to authorize access to user information +- **User Name Attribute:** Allows to configure the attribute value associated with user name fetched from Identity Provider + +### Role Mapping + +Role Mapping is used to assign you with security roles during login. You are given access and assignements based on the assigned role. + +**Search User Role**: Enable this option to select the user role provider. You are provided with two options: + +1. Open ID +2. Database + +**Open ID**: When you select **Open ID**, both authentication and authorization will be retrieved from the Open ID security provider. You need to provide: + +- **Role Attribute**: This field allows you to assign the required role. + +**Database**: When you select **Database**, authentication is performed using Open ID and authorization content is retrieved from the database. This allows you to use username and password credentials from Open ID while retrieving role content from the database. For role configuration using database, [see here](https://docs.wavemaker.com/learn/app-development/app-security/authorization/#useronboarding). diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/owasp.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/owasp.md new file mode 100644 index 000000000..3ecf5b05c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/owasp.md @@ -0,0 +1,64 @@ +--- +title: "OWASP" +id: "owasp" +--- +--- + +[OWASP](https://www.owasp.org/index.php/About_OWASP) is an open community dedicated to enabling organizations to conceive, develop, acquire, operate, and maintain applications that can be trusted. The OWASP Top 10 provides a list of the [10 Most Critical Web Application Security Risks](https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project) + +XSS (Cross-site scripting) and CSRF (Cross-Site Request Forgery) attacks are listed in the OWASP top 10 security. + +[XSS](https://www.owasp.org/index.php/Top_10_2013-A3-Cross-Site_Scripting_(XSS)) flaws occur whenever an application takes untrusted data and sends it to a web browser without proper validation or escaping. XSS allows attackers to execute scripts in the victim’s browser which can hijack user sessions, deface web sites, or redirect the user to malicious sites. + +A [CSRF](https://www.owasp.org/index.php/Top_10_2013-A8-Cross-Site_Request_Forgery_(CSRF)) attack forces a logged-on victim’s browser to send a forged HTTP request, including the victim’s session cookie and any other automatically included authentication information, to a vulnerable web application. This allows the attacker to force the victim’s browser to generate requests which the vulnerable application thinks are legitimate requests from the victim. + +The same-origin policy is an important security concept implemented by web browsers to prevent Javascript code from making requests against a different origin (e.g., different domain) than the one from which it was served. Although the same-origin policy is effective in preventing resources from different origins, it also prevents legitimate interactions between a server and clients of a known and trusted origin. [Cross-Origin Resource Sharing (CORS)](https://spring.io/understanding/CORS) is a technique for relaxing the same-origin policy, allowing Javascript on a web page to consume a REST API served from a different origin. + +--- + +## Preventing XSS Attacks + +XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end-user. For example, attacker can write the following script in a text box ` ` which gets executed. + +[![](/learn/assets/security_OWSP_XSS.png)](/learn/assets/security_OWSP_XSS.png) + +In WaveMaker Security dialog provides three strategies to handle XSS: + +### NONE +In this case, all the scripts will be executed, this is the default setting. + +### ENCODE +In this case, the scripts will be encoded so that they cannot be executed in data access. For example, the script code:` ` will be converted to `< ; script > ; alert(document.cookie) < ; /script > ;`, thus rendering the script invalid. +### WHITE LIST +In this case, the scripts will be filtered based on +- **Policy file**: this will implement XSS protection based on the rules defined in `/src/main/webapp/WEB-INF/wm-xss-policies.xml`. The default policy file is `wm-xss-policies.xml`. According to this default policy file, script tags will be removed. However, you can upload your own policy file which will be uploaded to WEB-INF folder. Clicking on to the file name will open it in the editor. Go through the [document](/learn/app-development/app-security/xss-antisamy-policy-configuration/) for more descriptions on AntiSamy rules. + +[![](/learn/assets/security_OWSP_XSSpolicy.png)](/learn/assets/security_OWSP_XSSpolicy.png) + +- **Manual tags**: Custom tag rules can be specified in terms of HTML tags which are categorized based on their actions. The possible actions are Validate, Remove, Truncate and Filter. These rules are used while handling the tags in the XSS attacks. You can add or delete tags against an action. We can specify the action for all Unknown tags also. + +[![](/learn/assets/security_OWSP_XSStags.png)](/learn/assets/security_OWSP_XSStags.png) + +## Preventing CSRF Attacks + +CSRF is an attack that tricks the victim into submitting a malicious request. This security attack exploits the trust a user has for a particular site. Attacks are launched by placing malicious actions on their site so that browsers of people visiting these pages would open them with/without user action. + +Angular provides a mechanism to counter CSRF. When performing XHR requests, the _$http_ service reads a token from a cookie (by default, `XSRF-TOKEN`) and sets it as an HTTP header (`X-XSRF-TOKEN`). Since the only JavaScript that runs on your domain can read the cookie, your server can be assured that the XHR came from JavaScript running on your domain. The header will not be set for cross-domain requests. + +WaveMaker Defaults: Cookie Name: `wm_xsrf_token`. This cookie gets set at run-time during the Login process. Header Name: `X-WM-XSRF-TOKEN` (User can customize it through security dialog) + +[![](/learn/assets/security_OWSP_CSRF.png)](/learn/assets/security_OWSP_CSRF.png) + +## Enabling CORS + +Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources (e.g. fonts) on a web page to be requested from another domain outside the domain from which the first resource was served. A web page may freely embed cross-origin images, stylesheets, scripts, iframes, and videos. + +CORS defines a way in which a browser and server can interact to determine whether or not it is safe to allow the cross-origin request. When CORS is enabled, following options are provided to configure: + +1. **Allow Credentials**: This option is to allow users to include credentials (including cookies and auth data) to be sent with the XHR requests. +2. **Max Age**: This option is used to set the validity, in seconds, of the pre-flight request response. +3. **Path**: Only the resources (in the WaveMaker app) in the mentioned path can be exposed. +4. **Origins**: WaveMaker app resources can be exposed only to these origins. + +[![](/learn/assets/security_OWSP_CORS.png)](/learn/assets/security_OWSP_CORS.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/remember-me.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/remember-me.md new file mode 100644 index 000000000..c3fc84b1f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/remember-me.md @@ -0,0 +1,42 @@ +--- +title: "Remember Me" +id: "remember-me" +--- +--- +Remembers me retains the session details and has a default expiry/lifetime cookie. This cookie is valid for 15 days or the user explicitly signing-out out of the application whichever comes first. + +## How it works +If user login with “remember me” checked in the application’s login page, the system will create & store a “remember me” cookie in the requested browser. Subsequent attempts to open the application with a valid “remember me” cookie will automatically allows the user to be logged-in into the application without asking for credentials again. + +Remember-Me is all about automated login to take place in your application by adding “remember me” cookie in the request header. + +## Remember-Me in WaveMaker Apps + +- Remember-Me feature will be enabled by default if the security is enabled in the WM application. +- While login into the application the authentication request will send the `j_rememberme` parameter with a value “true/on” to enable the remember me for that user/request. +- After successful authentication, WM application will send a remember cookie with name `remember-me` if remember_me is requested by the user. The cookie value is uniquely identifies the user on subsequent attempts. +- WM Application validate the remember me cookie with respect to username and cookie expiry. + +[![remember-me-login](/learn/assets/remember-me-login.png)](/learn/assets/remember-me-login.png) + +### Request with j_rememberMe enabled + +[![remember-me-login](/learn/assets/j_rememberme-enabled.png)](/learn/assets/j_rememberme-enabled.png) + +## Remember Me Configuration + +The following properties can be configured for each application. + +### Enable or Disable Remember Me support +Remember-me functionality is enabled by default, it can be turned off by updating the auth-info.json and also the profile properties files. + +### Expiry Interval +The default expiry/lifetime for all remember me cookies is 15 days from it’s creation. The expiry value can be changed by updating the auth-info.json and also the profile properties files. + +[![remember-me-configuration](/learn/assets/remember-me-configuration.png)](/learn/assets/remember-me-configuration.png) + +## Remember Me Cookie Expiry +The cookie is valid for 15 days or user explicitly signing-out out of the application whichever comes first. + +## Limitations +This feature works only for **Demo, Database** and **LDAP** security providers. \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/saml-integration.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/saml-integration.md new file mode 100644 index 000000000..bd2e74cc7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/saml-integration.md @@ -0,0 +1,219 @@ +--- +title: "SAML Integration" +id: "saml-integration" +--- +--- + +**Security Assertion Markup Language (SAML)** is an XML-based open standard for exchanging authentication and authorization data between different parties. The SAML exchanges are usually between + +- identity provider (IdP) - producer of assertions, and +- a service provider (sp) - the consumer of assertions. + +The identity provider could be any vendor like ADFS, OneLogin, Okta etc. which supports SAML-based Single Sign-On (SSO). The service provider is your WaveMaker application which makes use of Identity Provider to enable single sign-on across all your WaveMaker applications. + +The advantages of SAML SSO + +- Each and every application do not need to maintain the authentication info (such as user accounts, credentials etc) +- The application user does not need to enter credentials for logging into each & every application + +To configure SAML SSO, the Service Provider (SP) needs to know about the identity provider metadata (URL) and the identity provider needs to know about the service provider metadata URL and SSO endpoint URL. + +WaveMaker application can be integrated with SAML 2.0 complaint Identity Provider. However, it supports only two profiles - **Web Browser SSO Profile** and **Single Logout Profile** as explained in the sections below. + +## SAML Profiles + +A SAML profile outlines the set of rules that describe how to embed assertions and extract them from a framework or protocol. Profiles can also define a set of constraints on the use of general SAML protocol or SAML assertions in particular contexts. + +### SAML Web Browser SSO Profile + +Web Single Sign-On (SSO), as a subset of identity and access management, was proposed to tackle the usability, security, and management issues. With SSO, a user authenticates once to a trusted third-party, called Identity Provider (IdP), and subsequently gains access to all federated websites (i.e. Service Providers) he/she is entitled to – without being prompted with another login dialog. + +In an SSO flow (see the figure below) user U navigates user agent U-A (e.g.a browser) and tries to access a restricted resource on SP (1). The user is not authenticated yet, SP generates a token request (2) and redirects U-A with the token request to IdP (3,4). In the following step, U authenticates himself to IdP (5) according to the supported authentication mechanisms. Subsequently, the security token is issued and sent through U-A to SP, where the integrity and authenticity are verified and the content is evaluated (6,7). + +[![saml_sso1](/learn/assets/saml_sso1.png)](/learn/assets/saml_sso1.png) + +### Single Logout Profile + +Once a principal has authenticated to an identity provider, the authenticating entity may establish a session with the principal (typically by means of a cookie, URL re-writing, or some other implementation-specific means). The identity provider may subsequently issue assertions to service providers or other relying parties, based on this authentication event; a relying party may use this to establish its own session with the principal. + +In such a situation, the identity provider can act as a session authority and the relying parties as session participants. At some later time, the principal may wish to terminate his or her session with all session participants in a given session managed by the session authority. This case may be satisfied using this profile of the SAML Single Logout protocol. + +Note that a principal (or an administrator terminating a principal's session) may choose to terminate this "global" session either by contacting the session authority, or an individual session participant. Also, note that an identity provider acting as a session authority may itself act as a session participant in situations in which it is the relying party for another identity provider's assertions regarding that principle. The SSO flow is shown below. + +[![saml_sso](/learn/assets/saml_sso.png)](/learn/assets/saml_sso.png) + +## SAML Integration with WaveMaker App + +### Steps Involved + +1. Register WaveMaker application with Identity Provider +2. Configure the Identity Provider information in WaveMaker application +3. Configure Keystore +4. Configure Role Mapping + +### Registering WaveMaker app with Identity Provider + +Each and every application that wants to integrate with Identity Provider (IdP) for SAML SSO has to be registered with that IdP by providing application endpoint URL. Once the application is registered with IdP, the IdP provides a metadata URL that contains the IdP certificate, sso endpoint URL etc. + +While registering the application with IdP, some IdP providers ask for Service Provider’s (SP) endpoint URL which can be obtained as mentioned in the below section. + +### Configure IdP with WaveMaker application + +[![](/learn/assets/sec_access.png)](/learn/assets/sec_access.png) + +After enabling Security and on selecting SAML as the Security Provider for your app: + +1. In the 1st section, Service Provider (Application) Information, three read-only URLs are displayed which are required for application registration with IdP (as mentioned in the above section). They are: + + - Metadata URL – the metadata URL of the service provider which gives information about the service provider. + + ``` + {app-hosted-url} + /saml2/service-provider-metadata/saml + ``` + + - Audience URL – the service provider endpoint where the assertions are received. + + ``` + {app-hosted-url} + /login/saml2/sso/saml + ``` + + - Single Logout URL – This logs out the user from the IdP i.e global log out. + + ``` + {app-hosted-url} + /logout/saml2/slo + ``` + +[![](/learn/assets/saml_config.png)](/learn/assets/saml_config.png) + +2. In the 2nd section - Identity Provider Configuration, enter the Metadata URL of the application registered with IdP as obtained from the above section. + + - Enter the metadata URL of the app and select the load button. + - Once the load button is clicked, the metadata URL is valid & the IdP endpoint URL should be loaded. This validates the IdP metadata URL. + + [![](/learn/assets/saml_config2.png)](/learn/assets/saml_config2.png) + + - You can also choose to upload the Metadata file. + + [![](/learn/assets/saml_config2_file.png)](/learn/assets/saml_config2_file.png) + +3. In the 3rd section: the service provider configuration options are shown: + +#### Configure Keystore  + +The SAML message exchange requires a public/private key pair for every participating entity in the message exchange. The Idp key pair is maintained by the IdP provider, but the Service Provider’s key pair should be maintained by the service provider, in this case, the WaveMaker application. In most of the production deployments, a valid key pair is recommended to be used, but during application development, WaveMaker helps in auto-generating a key pair for you which should be used only for demo purposes, but not for actual deployment.  + +Below configuration gives information about configuring key pair for your application. In this, the user is prompted to choose auto-generate option or upload a valid key pair in JKS format. + +- The user can auto-generate or import a Java KeyStore (JKS). +- Auto-Generate - If the user chooses to auto-generate a keystore, WaveMaker will generate a self-signed private-public key pair and store it in the keystore with the following details as input + - Alias - This is required for the self-signed public key which is generated and imported into the keystore + - Password - this is the keystore password. This should be a minimum of 6 characters + - Subject Name - This is the Subject name of the self-signed certificate. + +[![](/learn/assets/saml_config3.png)](/learn/assets/saml_config3.png) + +- Import - The user can import a java keystore into WaveMaker. The inputs required are + - Alias - the alias of the public key for the service provider. + - Password - this is the keystore password. This should be a minimum of 6 characters + +[![](/learn/assets/saml_config3_import.png)](/learn/assets/saml_config3_import.png) + +4. In the 4th section - Role Mapping: The roles of an application user logged in through SAML SSO can be mapped using a SAML attribute or database-backed roles. A SAML attribute that maintains the roles can be configured by selecting the SAML as the user role provider as shown below. + +[![](/learn/assets/saml_config4.png)](/learn/assets/saml_config4.png) + +In case if the DB is selected as the user role provider, then each and every SAML user must pre-exist in the specified user’s table with the roles. You can follow the [steps given here](/learn/app-development/app-security/authorization/#user-onboarding) for the same. + +## Configuration Files + +The SAML Configuration done will be stored in a saml-options.json file under project option in Files tab as shown below : + +[![](/learn/assets/saml_file.png)](/learn/assets/saml_file.png) + +The keystore.jks file is also available in the project option under the files tab as shown under and it can be downloaded: + +[![](/learn/assets/saml_keystore.png)](/learn/assets/saml_keystore.png) + +Once the configuration is done you can run the app and you will be logged into your app. You will see the message “Redirecting to sso login…” + +## Deployment of Application that is Configured with SAML + +During the app development in WaveMaker, application URLs like Metadata, Audience and Single Signout URL are configured with any of the Identity Provider (for instance- Okta, Onelogin, ADFS, Pingone, etc.). However, these URLs being run URLs are temporary in nature, as such cannot be used for the deployed application. When the WaveMaker application is deployed in the container, the hostname/tenant_id changes and therefore, the URLs that are to be _configured/registered in the SAML IdP_ should change. For Example, in WaveMaker Studio, + +- The **Metadata URL** during development would look like this: + + ```https://wavemakeronline.com/studio/services/saml2/service-provider-metadata/saml``` + + whereas, for deployment app, the URL should typically look like: + + ```(http/https)://{hostname}/{appname}/saml2/service-provider-metadata/saml``` + +- The **Audience URL** during development would look like this: + + ```https://wavemakeronline.com/{tenantid}/{appname}/login/saml2/sso/saml``` + + whereas, for deployment app, the URL should typically look like: + + ```(http/https)://{hostname}/{appname}/login/saml2/sso/saml``` + +- The Single Signout URL during development would look like this: + + ```https://wavemakeronline.com/studio/services/logout/saml2/slo``` + + whereas, for deployment app, the URL should typically look like: + + ```(http/https)://{hostname}/{appname}/logout/saml2/slo``` + + +:::note +You can get the {hostname} by looking at the URL of any deployed app from your account. It will typically be of the format: `tenant_id.cloud.wavemakeronline.com` for apps deployed to WaveMaker Cloud (ref [Managed Deployed App](/learn/app-development/deployment/manage-deployed-apps/) for details). +::: + +## Collaboration in Application that is configured with SAML + +When multiple users are collaborating to develop an application that is configured with SAML SSO, each and every user of that application has to configure the SAML authentication every time they pull the changes. As the application endpoint URL is different for every user, they need to register their URLs with the Identity provider as well. + +## TroubleShooting + +**Time Synchronization**: Processing of SAML messages and assertions is often limited to a specific time window which e.g. prevents possibilities of replay attacks. Validation of messages can fail when internal clocks of the IDP and SP machines are not synchronized. Make sure to use a time synchronization service on all systems in the federation. + +## Integration with Third Party Identity Providers + +Here you can find steps for SAML integration with: + +- [OneLogin](/learn/how-tos/saml-integration-onelogin/), and +- [AD FS](/learn/how-tos/saml-integration-adfs/) + +:::note +When the app is run with SSO configuration, assuming that there is no session present with third-party identity providers, the third-party IdP login dialog will show up. As our WaveMaker Run Toolbar is within iframe which may not be safe for third parties, we remove the toolbar before the Login dialog of the third-party identity provider appears. +::: + +## Reverting to OpenSAML 3 + +SAML upgraded to use OpenSAML 4.3.0 library from [WaveMaker 11.3](/learn/wavemaker-release-notes/v11-3-0), which includes a third-party repository **[Shibboleth](https://shibboleth.atlassian.net/wiki/spaces/IDP4/overview)** in the pom.xml file. + +However, if required, you can remove the repository and revert to the OpenSAML 3.4.6 version by following the steps below. + +### Steps to revert Opensaml version + +1. Remove the below repository from the pom.xml. + +```xml + + + Shibboleth + Shibboleth + https://build.shibboleth.net/nexus/content/repositories/releases/ + + +``` + +2. Add the `opensaml.version` property in the pom.xml in the properties section, as shown below. + +```xml +3.4.6 +``` + +3. Add the property `security.providers.saml.useOpenSaml3=true` in the `development.properties` file. +4. Add the property `security.providers.saml.useOpenSaml3=${security.providers.saml.useOpenSaml3}` + diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/secure-connection-deployed-apps.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/secure-connection-deployed-apps.md new file mode 100644 index 000000000..dd0924c13 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/secure-connection-deployed-apps.md @@ -0,0 +1,271 @@ +--- +title: "Secure Connection for Deployed Apps" +id: "secure-connection-deployed-apps" +--- +--- +Authentication is a process by which the access to the app is restricted to known/authentic users. + +A WaveMaker application can include a login page that requires users to sign on in order to gain access to the application. In order to set up user authentication, you need to configure a data source that stores the user IDs and passwords. You have the following options for storing this data: + +- Any **database** supported by WaveMaker +- Lightweight Directory Access Protocol (**LDAP**) +- Active Directory (**AD**) +- Central Authentication Service (**CAS**) +- Security Assertion Markup Language (**SAML**) +- Custom Java Service +- WaveMaker Studio also provides a simple **Demo** data source. You can use this data source to set up and test your login page during development. We do not recommend the Demo data source for production applications. + +[![sec_prov](/learn/assets/sec_prov.png)](/learn/assets/sec_prov.png) + +### Selecting Security Providers + +You can choose any of the following security providers for your WaveMaker applications: + +## Demo + +When the WaveMaker developer enables security, the demo is the default option. This option, as the name suggests, is for demo purpose, ease the user into security features. Demo option provides by default two out of box users called “admin” and “user” with password same as username. Developers can add/remove users. + +The Demo data source provides a great design-time tool for authentication. With this data source, you can quickly define a few usernames and passwords to use while creating and testing the login functionality for your application. It is recommended that you set up a more robust data source for authentication before you deploy your application into production. + +By default, the Demo data source provides two users - _user_ and _admin_. These users are assigned to the _user_ and _admin_ role respectively. You can create roles on the **Roles** tab. You can add new users and assign them roles created in the **Roles** tab. You can also delete existing users by clicking the **Delete** icon next to a user row. + +## Database + +You can use a database to store your authentication data. The database must include a table that provides a column for usernames and passwords. The usernames and passwords must be stored in the same table in the database. + +When you choose _Database_ as the **Security Provider**, you can perform the following configurations on the **Users** tab: + +- **Database Configuration**: + - _Database_: The Database that contains the tables for the username and password fields. Choose the Database from the pull-down menu. (You have to import the database first. See [Database Integration](/learn/app-development/services/database-services/working-with-databases/). If you have imported the database and it does not appear in this list, try closing and reopening the project). + - _User Table_: Select the table that contains the columns for the usernames and passwords. +- **User**: + - _User Id Column_: Select the column for the user id + - _Username Column_: Select the column for the user (login) name + - _Password Column_: Select the column for the password. +- **Role Mapping**: This will build the query to fetch the role values from the user table based on the logged in user details. See [User Onboarding](/learn/app-development/app-security/authorization/#user-onboarding) for more information. + +## LDAP + +**LDAP** (Lightweight Directory Access Protocol) is a software protocol for enabling anyone to locate organizations, individuals, and other resources such as files and devices in a network, whether on the public Internet or on a corporate intranet. + +To set up authentication using an LDAP data source, choose _LDAP_ as the **Security Provider**. + +When you choose _LDAP _as the **Security Provider**, you can perform the following configurations: + +- _LDAP URL_: This field specifies the host name and port number of the LDAP server. This is the root node of which security will be able to use - ldap://localhost:389/dc=wavemaker,dc=com. For deployment profile, you can specify _multiple LDAP server URLs_, if required, by providing the multiple LDAP URLs as space-separated values, from the security tab of the [Profile Configuration](/learn/app-development/deployment/configuration-profiles/). + +[![](/learn/assets/sec_user_ldap_url.png)](/learn/assets/sec_user_ldap_url.png) + +- _Manager DN_: Distinguished Name for admin access, this is an optional field +- _Manager Password_: Password in case admin access is mentioned above, this is an optional field +- _User Search Pattern:_ Filter used to find the user in the directory, relative to the root specified above. The only valid variable is {0} which is replaced with the user's login name. For example: "cn={0},ou=people" +- _Test user DN:_ Full DN of the user account for testing connection URL. Example: someUser +- _Test user Password:_ The password for the test account that you use to test the LDAP URL. + +Once you have configured the security provider, click the **Test Connection** button.  The **Test Connection** button only verifies that the _Test User DN_ and _Password_ can be used to "bind" using the URL. You must specify a full DN for the _Test User DN_. A search is not performed for **Test Connection** as is normally done for login. + +### Role Mapping + +Role Mapping for logged in users can come from the configured LDAP security provider or an imported Database. + +[![sec_user_ldap_role](/learn/assets/sec_user_ldap_role.png)](/learn/assets/sec_user_ldap_role.png) + +- _Search User Role_: Check this box to select the user role provider - Database or LDAP. + - If you select _**LDAP** _then both authentication and authorization (roles) will be retrieved from the LDAP security provider. You need to provide: + - _Group Search Base_ the search base from which the search for group membership should be performed. Eg: ou=roles, where ou is organizational unit + - _Group Name Attribute_ the attribute that holds data about the role name for a group. Eg: cn (common name) + - _User Group Filter_ the search filter used to search through the LDAP directory to find the roles to which an authenticated user belongs. {0} would be substituted with the user's DN. Eg: (member={0}) + - If you select _**Database** _then authentication is performed using LDAP and authorization (roles) content is retrieved from the database. This allows you to use username and password credentials from LDAP while retrieving role content from a separate database. For role configuration using database [see here](/learn/app-development/app-security/authorization/#user-onboarding). + +## Active Directory + +**Active Directory Domain Service** is Microsoft's Directory Server. It provides authentication and authorization mechanisms as well as a framework within which other related services can be deployed (AD Certificate Services, AD Federated Services, etc). It is an **LDAP** compliant database that contains objects. + +To set up authentication using an Active Directory data source, choose _Active Directory_ as the **Security Provider.** + +When you choose _Active Directory _as the **Security Provider**, you can perform the following configurations: + +- _URL:_ This field specifies the protocol and hostname of the AD server. Example: _ldap://ad.mydomain.com_ +- _Domain:_ The fully qualified domain name (FQDN) of the Active Directory domain is an optional field. For instance: example.com +- _Root Dn:_ It will be automatically populated based on domain entry only the first time. The user can change this later and subsequent changes to the domain will have no effect on rootDn. Example: When Domain is example.com; then RootDn is automatically updated as  dc=example, dc=com. +- _User Search Pattern_ is a filter which is prepopulated by default. Users can change it, as per their requirement. +- _Test username:_ Full DN of the user account for testing connection URL. Example: user1. If the domain is provided, then simply enter the username. On the other hand, if a domain is not provided, then username must be appended to the domain name. +- _Test user password:_ The password for the test account that you use to test the AD URL. + +Once you have configured the security provider, click the **Test Connection** button, test user credentials are authenticated in this step. Keep in mind, during runtime, the authentication will happen based on user credentials and user search pattern. [See here for more use cases](/learn/how-tos/active-directory-use-cases/). + +### Role Mapping + +Role Mapping for logged in users can come from the configured Active Directory security provider or an imported Database. [![sec_user_ad_role](/learn/assets/sec_user_ad_role.png)](/learn/assets/sec_user_ad_role.png) + +- _Search User Role_: Check this box to select the user role provider - Database or AD. + - If you select _**AD** _then both authentication and authorization (roles) will be retrieved from the AD security provider. You need to configure the _Group Role Attribute._ + - If you select _**Database** _then authentication is performed using AD and authorization (roles) content is retrieved from the database. This allows you to use username and password credentials from AD while retrieving role content from a separate database. For role configuration using database [see here](/learn/app-development/app-security/authorization/#user-onboarding). + +## CAS + +The **Central Authentication Service** (**CAS**) is a single sign-on protocol for the web. Its purpose is to permit a user to access multiple applications while providing their credentials (such as user id and password) only once. It also allows web applications to authenticate users without gaining access to a user's security credentials, such as a password. + +To set up authentication using a Central Authentication Service, choose _CAS_ as the **Security Provider**. [Know more about single sign-on using CAS](/learn/app-development/app-security/central-authentication-system/). + +When you choose _CAS _as the **Security Provider**, you can perform the following configurations on the **Setup** tab: + +- _Server URL_: This field specifies the protocol and hostname of the CAS server. Example: http://mydomain.com:8080/cas +- _Login URL_: This field is the login URL of the CAS server +- _Validation URL_: This field specifies the URL used for validating the service ticket issued by the CAS server. +- _Service Parameter Name_: This field configures the request parameter to look for when sending request to CAS E.g./cas-server-webapp-4.0.0/login?service=https%3A%2F%2Flocalhost%3A8443%2Fcassample-1.0%2Flogin%2Fcas +- _Ticket Parameter Name_: This field configures the Request Parameter to look for when attempting to see if a CAS ticket was sent from the server. The default value is “ticket”. Eg. /cassample-1.0/login/cas?ticket=ST-1-lCYeRuXfmhKid1auqdy2-cas01.example.org + +### Role Mapping + +Role Mapping for logged in users can come from the configured CAS security provider or an imported Database. [![sec_user_cas_role](/learn/assets/sec_user_cas_role.png)](/learn/assets/sec_user_cas_role.png) + +- _Select User Role Provider_: Choose the user role provider. There are two role providers - CAS and Database. + - The user can configure **CAS** role attribute and the same role can be configured in the WaveMaker application.  The _Role Attribute Name_ needs to be configured. + - If you select **_Database_** then authentication is performed using CAS and authorization (roles) content is retrieved from the database. This allows you to use username and password credentials from CAS while retrieving role content from a separate database.For role configuration using database [see here](/learn/app-development/app-security/authorization/#user-onboarding). + +## SAML + +**Security Assertion Markup Language (SAML)** is an XML-based standard for exchanging authorization and authentication data between security domains. SAML exchanges are between + +- an identity provider (IdP) – producer of assertions, and +- service provider (SP) – consumer of assertions. + +SAML Configuration in WaveMaker helps you configure the WaveMaker application with any SAML 2.0 compliant Identity provider. [Know more about SAML](/learn/app-development/app-security/saml-integration/). + +## Custom + +To set up authentication using Java Services, choose _Custom_ as the **Security Provider**. + +[![sec_user_custom](/learn/assets/sec_user_custom.png)](/learn/assets/sec_user_custom.png) + +When you choose _Custom _as the **Security Provider**, you need to specify the _fully qualified Java Class_ name, if this does not exist a sample implementation will be generated at the location as shown below. + +[![sec_user_custom_java](/learn/assets/sec_user_custom_java.png)](/learn/assets/sec_user_custom_java.png) + +This Java Class should: + +1. implement the _WMCustomAuthenticationManager_, whose signature is given below: + +```java +/** + * Copyright © 2015 WaveMaker, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.wavemaker.runtime.security; + +import org.springframework.security.core.AuthenticationException; + +public interface WMCustomAuthenticationManager { + + /** + * should return WMUser object if the authentication details can be extracted from authRequestContext. + * Otherwise the method should return null. + * @param authRequestContext + * @return + */ + public WMUser authenticate(AuthRequestContext authRequestContext) throws AuthenticationException; +} + +The AuthRequestContext has the following structure + +package com.wavemaker.runtime.security; + +import javax.servlet.http.HttpServletRequest; +import java.io.Serializable; + +public class AuthRequestContext implements Serializable { + + private String username; + + private String password; + + private HttpServletRequest httpServletRequest; + + public AuthRequestContext(HttpServletRequest httpServletRequest) { + this(null, null, httpServletRequest); + } + + public AuthRequestContext(String username, String password, HttpServletRequest httpServletRequest) { + this.username = username; + this.password = password; + this.httpServletRequest = httpServletRequest; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public HttpServletRequest getHttpServletRequest() { + return httpServletRequest; + } +} +``` +You can handle exceptions by throwing [subclasses of AuthenticationException](http://docs.spring.io/autorepo/docs/spring-security/3.2.3.RELEASE/apidocs/org/springframework/security/core/AuthenticationException.html). +2. and returns a _WMUser_ object which can be initialized by a call to the following constructor: + +```java +public WMUser(String userId, String userName, Collection roles) + +For example, the following sample implementation extracts the _user_ value from the _ticket_ parameter from the Http header data and adds the roles of user and admin, accordingly. **Note**: You can use any parameters returned by the HttpServletRequest, here we are showing username and password fields. + +import java.util.List; +import java.util.List; +import java.util.ArrayList; + +import javax.servlet.http.HttpServletRequest; + +import com.wavemaker.runtime.security.WMCustomAuthenticationManager; +import com.wavemaker.runtime.security.WMUser; +import com.wavemaker.runtime.security.AuthRequestContext; + +public class SecureService implements WMCustomAuthenticationManager { + @Override + public WMUser authenticate(AuthRequestContext authRequestContext) { + String username = authRequestContext.getUsername(); + String password = authRequestContext.getPassword(); + HttpServletRequest httpServletRequest = authRequestContext.getHttpServletRequest(); + if(username.equals("John") && password.equals("John123")) { + List roles = new ArrayList(); + roles.add("admin"); + return new WMUser("John", username, roles); + } else if(username.equals("Jane") && password.equals("Jane123")) { + List roles = new ArrayList(); + roles.add("user"); + return new WMUser("Jane", username, roles); + } + return null; + } +} +``` + +### JWS + +Json Web Signature (JWS) is a type of Json Web Token (JWT) which is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. + +In WaveMaker studio, we have introduced JWS as a secondary provider that accepts JWS tokens during API authentication. + +For example, any Open ID server after a successful authentication returns an ID token that is of type JWS and can be accepted by the JWS secondary provider. + +### Opaque Token + +Opaque tokens, unlike JWS, cannot be decoded to read any user information, and are represented by a random, unique string of characters. They are identifiers that are mapped to user information stored on the server. These tokens can be validated only by the server which has issued them using the introspection endpoint. + +In WaveMaker studio, we have introduced the Opaque token as a secondary security provider to accept opaque tokens during authentication. + +For example, few Open ID servers after a successful authentication return an access token which is of type Opaque. diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/securing-server-side-properties-rest-services.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/securing-server-side-properties-rest-services.md new file mode 100644 index 000000000..1dff8d7c8 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/securing-server-side-properties-rest-services.md @@ -0,0 +1,46 @@ +--- +title: "Securing Server Side and App Environment Properties in REST Services" +id: "securing-server-side-properties-rest-services" +sidebar_label: "Secure Server-side Properties" +--- +--- + +When working with REST Services, it is essential to protect your API keys and passwords and ensure your app sensitive information hides from the UI and network calls. You can do this by using proxy server when configuring REST Services. For this, you should use App Environment Properties or Server Side Properties for Header and Query params. + +## What are App Environment Properties and Server-Side Properties and how to use them? + +App Environment properties and Server Side Properties are similar. However, Server Side Properties are implicit variable or standard WaveMaker variables. It contains dynamic information, for examples, current time, current date, a logged-in user’ data which changes based on the user. + +Whearas App Environment Properties are explicit variable. You create App Environment Properties once and you can use them any number of times across the project. Configure different values for different environments, and store API keys, passwords, imported services, and more. To learn how to create an App Environment Property, see [Using App Environment Properties](/learn/how-tos/using-app-environment-properties/). + +:::important +When adding App Environment Properties, ensure to click the “+” button after each entry. When done, click the immediate “Save” button, followed by the next “Save” button of the Config Profile window. +::: + +When you create App Environment Properties, they should appear in Web Services window under the Header and Query param types. + +## Configuring Proxy Server + +When configuring REST API, you add parameter name, data type and test value depending on the service requirements. To learn how to add REST services, see [Third Party REST Services](/learn/app-development/services/web-services/rest-services/). Following are the three types of Properties for using Header and Query params data types: + +1. App Environment Properties +2. Server Side Properties +3. UI Type + +After you add the Endpoint URL, to use the Proxy Server, slide the toggle to enable the Use Proxy setting. The Server Side Properties and App Environment Properties enforces you to use the Proxy server by default. This is to protect app sensitive information from viewing via network calls and UI. + +[![](/learn/assets/ServerSidePropertiesHeader.png)](/learn/assets/ServerSidePropertiesHeader.png) + +[![](/learn/assets/ServerSidePropertiesQuery.png)](/learn/assets/ServerSidePropertiesQuery.png) + +## How it impacts UI + +When you add REST service and bind them with the Header and Query param, the param values could essentially carry app-sensitive data. It should be hidden from the UI and network calls. However, in the Variables dialog, you can view param data in the input fields. Thus, it allows you to bind the data to any widget or variable, and it can potentially make it viewable to the client-side environment. + +To hide the params data that passes to Variable and network call, you must enable the Proxy server. By doing this, the data transfers from a Proxy Server instead of making a direct call. + +## Things to be aware of + +- If you do not see any App Environment Properties in the Header Param or Query Param, you should add them. For more information, see [Adding App Environment Properties](/learn/how-tos/using-app-environment-properties/). +- Without enabling **Use Proxy**, you cannot set the properties to Server Side Properties or App Environment Properties. +- If you make any changes to the URL when configuring the web service, you should test it before you save the service. diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/security-variables.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/security-variables.md new file mode 100644 index 000000000..d90e64d9c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/security-variables.md @@ -0,0 +1,31 @@ +--- +title: "Security Variables" +id: "security-variables" +--- +--- + +Whenever Authentication is enabled for an app, one variable and two actions are created by default and these are used in conjunction with the default _login page and logout button_ (in topnav) given by WaveMaker. If you decide to design your own login page and define the login and logout behavior, you can still use these variables to handle the login and log out behavior, by appropriate bindings. + +## `loggedInUser` +**loggedInUser** contains the details of the logged in user based upon the fields set in the User details + +## `loginAction` +**loginAction** is used to capture the login values entered by the user and take appropriate action. Of special interest is the **useDefaultSuccessHandler**, which will implement the login configuration of post-login behavior, i.e. the landing page selection. + +:::note +For the _onSuccess_ event for loginAction to take precedence over this default handler, you need to uncheck the useDefaultSuccessHandler. +::: + +**loginAction** takes as **parameters** - username, password and remember me. These fields are bound to the respective widget values in the default login page. The **username and password** values as entered by the user are matched against the values from the security provider configuration. + +**Remember Me**, when selected by the user, retains the session details and has a default expiry/lifetime cookie. This cookie is valid for 15 days or the user explicitly signing-out out of the application whichever comes first. + +:::note +Re-run of the application while testing creates a new session and as such the cookies are not retained. +::: + +For more information, see [Remember Me](/learn/app-development/app-security/remember-me). + +## `logoutAction` +**logoutAction** is invoked when the user logs-out of the application. Of interest is the **Redirect To** property, which by default is set to the login page but can be changed to any other page in your application. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/session-persistence.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/session-persistence.md new file mode 100644 index 000000000..3941e21f1 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/session-persistence.md @@ -0,0 +1,75 @@ +--- +title: "Session Persistence - Scaling Application" +sidebar_label: "Session Persistence" +--- +--- + +Session persistence is a configuration where you can store sessions. You should configure session persistence to enable Horizontal Scaling. + +Horizontal Scaling replicates the application with multiple nodes and servers. With this approach, the load is distributed among these nodes. Typically, Horizontal scaling can serve more users and requests and there is no limit on the number of nodes that can serve the same application. + +## How to Configure Session Persistence + +1. Connect to the [Database](/learn/assets/db_new.png). +2. Go to the **Security** menu. + +![app-security](/learn/assets/sec_access.png) + +3. Navigate to the **Authentication and Authorization** tab and enable **Authentication**. + +![authentication-authorization](/learn/assets/authentication-authorization.png) + +4. Go to **Login configuration** from the left navigation. +5. Scroll down to **Session Persistence**. +6. Select **Type** from the following: + + 1. **In-Memory** + 2. **REDIS** + 3. **JDBC** + 4. **MONGODB** + +### In-Memory + +In-Memory is the default selected option; this will work fine for a single node application. + +### REDIS + +When you select REDIS, you have to provide the following information: + +1. Host +2. Port +3. Password +4. Database + +For more information, see [Host, port, password and database](https://redis.io/topics/rediscli#host-port-password-and-database). +The Database is 0 by default. You can configure this according to the REDIS setup. + +![REDIS session persistence](/learn/assets/redis-session-persistence.png) + +### JDBC + +For JDBC, it displays a dropdown of all the imported databases in the project. The application typically has multiple logins and it stores multiple login sessions, and those sessions and their timeout information is stored in the table. + +![jdbc session persistence](/learn/assets/jdbc-session-persistence.png) + +1. Select the Database from the dropdown to configure session persistence. + +:::note +Ensure the selected database should be in editable mode and not read-only. +::: + +2. **Save** the settings. + + +### Mongo DB + +You can configure a MongoDB database for storing sessions. + +1. From the Security window, choose **Session Persistence** +2. Choose the **Type** `MONGODB` from the dropdown. +3. Provide all the required details, such as Database name, Port, Host, Username, and Password. +4. Click **Save**. + +The required driver and the configuration files gets automatically imported into the project, and the application can connect to MongoDB. + +![mongodb security configuration](/learn/assets/session-persistence/mongodb-security-window.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/ssl-encryption.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/ssl-encryption.md new file mode 100644 index 000000000..5a5d457bf --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/ssl-encryption.md @@ -0,0 +1,16 @@ +--- +title: "SSL Encryption" +id: "ssl-encryption" +--- +--- + +A WaveMaker application can be accessed through _https_ protocol to ensure higher level of security in place. + +If the user enables SSL, it means that the user will be redirected to the same URL but protected by SSL. For eg. if user inputs [www.wavemakeronline.com](http://www.wavemakeronline.com/), SSL filter will redirect the user to [https://www.wavemakeronline.com](https://www.wavemakeronline.com/) + +SSL Encryption can be set at the [**Profile Configuration**](/learn/app-development/deployment/configuration-profiles/) which can be accessed from the [Settings Secondary Action in Project Workspace](/learn/app-development/wavemaker-overview/product-walkthrough/#project-workspace). + +For Development Profile SSL Encryption is set by default. You can choose to change the setting for  Deployment Profile. + +[![](/learn/assets/config_deploy_sec.png)](/learn/assets/config_deploy_sec.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/token-based-authentication.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/token-based-authentication.md new file mode 100644 index 000000000..bf5509ff5 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/token-based-authentication.md @@ -0,0 +1,96 @@ +--- +title: "Token Based Authentication" +id: "token-based-authentication" +--- +--- +## Overview + +The interaction between front-end and back-end for WaveMaker applications goes through REST APIs exposed by the back-end. For every service such as DB, Java, SOAP etc created/imported into WaveMaker application, the corresponding functionality is exposed through REST APIs. These REST APIs can be invoked from the application front-end or they can be integrated with other applications (non-WaveMaker applications). Invocation from the application front-end goes through the login page flow wherein a cookie is provided post authentication, which will be sent while invoking the back-end REST APIs. + +[![app_flow](/learn/assets/app_flow.png)](/learn/assets/app_flow.png) + +If the REST APIs are invoked from a third-party application, the same login flow with cookie will not work. The other alternative is to send the credentials for each and every REST API call through Basic Authentication Header. Though this option does work, it is not recommended for security reasons as every request will be carrying the credentials of the user. To avoid such problems, WaveMaker applications supports **Token Based authentication mechanism** for the REST APIs. + +## How it works + +Token-based authentication is an authentication mechanism mostly used for authentication of API requests. In this mechanism, the user is issued an API access token upon successful authentication, which will be used while invoking any API request. In this process, a cookie will never be issued by the server. All requests are stateless and must include the token in a HTTP header or a query param. + +[![token_app_flow](/learn/assets/token_app_flow.png)](/learn/assets/token_app_flow.png) + +## What is a token? + +A token is a piece of data created by the server containing information to uniquely identify the user. A new token is created for every token request, therefore there could be multiple tokens for the same user. + +Example: `cc7112734bbde748b7708b0284233419`. + +The token should be sent as a Header with the name “_wm_auth_token_” when making API requests to the WaveMaker applications. + +Token has a lifetime. It is valid for 1800 seconds from its creation(configurable). Expired tokens are not valid and will be discarded. + +## Token Repository + +Tokens issued by the server are stored in the token repository. WaveMaker runtime only supports In-Memory token repository, hence they will be lost if the server gets restarted. Clients planning to use tokens must be resilient and expect token expiry. They are expected to handle token expiry gracefully and get a new token in such scenarios. + +## Token Request + +To obtain the Token an HTTP GET request has to be made to the following URL: GET [app-hosted-url]/services/security/token by passing the credentials through Basic auth request. In Basic authentication approach, the credentials are encoded with Base64 and sent in the header with the name “Authorization” as shown below + +Header as: +``` +Authorization : Basic +``` +Continuing with the above example, the service URL would be: +``` +http://e1d52cdd8ecf.cloud.wavemakeronline.com/Demo/services/security/token +``` +and for username as _admin_ and password as _admin_ the header would be: +``` +Authorization : Basic YWRtaW46YWRtaW4=. +``` +If your authentication credentials are correct, you will get the following message with the token: +```JSON +{"wm_auth_token":"ZXJpYy5saW46MTQ1ODE5MDcyNDU5NTpmZGQwYjUzMDNjMzRiZDgyZmUyZTBhZTQyYTM1NzJjYw"} +``` +If user is not authenticated, you will get an error message as shown below along with the Http Response Code of 401: +``` +{ + "errors": { + "error": [{ + "id": null, + "messageKey": "com.wavemaker.studio.json$UnexpectedError", + "message": null, + "parameters": ["Require authentication to generate access token"] + }] + } +} +``` +## Invoke API using Token + +Once a token is issued, the APIs can be accessed, by passing the token in HTTP Header or as a query param. The following example shows to access the User table from the sample hrdb: Token based authorization using HTTP header parameter: +``` +http://[application context url]/services/hrdb/User/ +Header : +wm_auth_token : YWRtaW46MTQ1NzY3NjY1ODMzNzo2NmY4NjJkZTY2MGQ5NjhlMDdhMTk0YWFjMTNhNzY4Mg +``` +Token based authorization using query parameter: +``` +http://[application context url]/services/hrdb/User/?wm_auth_token=YWRtaW46MTQ1NzY3NjY1ODMzNzo2NmY4NjJkZTY2MGQ5NjhlMDdhMTk0YWFjMTNhNzY4Mg +``` + +:::note +- If token exists both as query parameter and header, then query parameter takes precedence. Though the token can be sent in either Header or Parameter, we recommend the Header approach for security reasons. +- If the token is invalid, then 401 unauthorized error will be sent in response. +::: + +## Token Validity + +By default, a token is valid for 1800 seconds since its creation. You can customize token validity seconds in project-security-provider.xml by editing below bean, before deploying the app. +``` + +``` +The API requests with an invalid/expired token will be returned with the 401 response code. + +## Renewing the token after expiry + +When a token has expired and 401 response code is returned, a fresh token needs to be obtained. Refer to section on "Token request" in this page on documentation obtaining new token. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/xss-antisamy-policy-configuration.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/xss-antisamy-policy-configuration.md new file mode 100644 index 000000000..22103d6e3 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/xss-antisamy-policy-configuration.md @@ -0,0 +1,264 @@ +--- +title: "XSS antisamy policy configuration" +id: "xss-antisamy-policy-configuration" +--- +--- + +AntiSamy is an HTML, CSS and JavaScript filter for Java that sanitizes user input based on a policy file. AntiSamy is not an HTML, CSS and JavaScript validator. It is merely a way to make sure HTML, CSS and JavaScript input strictly follows rules defined by a policy file. + +AntiSamy is a sanitization framework; it is up to the user how it does its sanitization. Using AntiSamy does not guarantee to filter of all malicious code. AntiSamy simply does what is described by the policy file. + +## Configuring Your AntiSamy Policy + +If the default policy file `wm-xss-policies.xml` doesn’t meet your needs, you can tweak your policy file to your needs and upload. Each section of the policy file is broken down in the next few sections to give the developer background on tweaking the output. + +## Policy File Directives + +**`[]`** + +The following table shows the directives, their default values, and their impact on the AntiSamy filtering process. + +
DirectiveTypeDefaultDescription
useXHTMLbooleanfalseWhen this feature is on, AntiSamy will output the sanitized data in XHTML format as opposed to just regular HTML
omitXMLDeclarationbooleantrueWhen "omitXMLDeclaration" is turned on, AntiSamy will automatically prepend the XML header to output. Enabling this feature will tell AntiSamy not to do that.
omitDoctypeDeclarationbooleantrueWhen this feature is enabled, AntiSamy will automatically prepend the HTML doctype declaration. By default, AntiSamy will not prepend this header.
formatOutputbooleanfalseWhen enabled, AntiSamy will automatically format the output according to some basic rules and indentation. Kind of like "pretty print."
maxInputSizeint100000This directive specifies the maximum size (in bytes) of user input before it's validated.
embedStyleSheetsbooleantrueWhen the developer chooses to allow CSS, this directive will specify whether or not remote style sheets found referenced in the user's input will be pulled down and embedded into the current user input.
maxStyleSheetImportsint1This feature allows developers to specify how many remote style sheets can be downloaded from any one input.
connectionTimeoutint1000When "embedStyleSheets" is enabled, this timeout value (in milliseconds) will be used when fetching the offsite resource in question. This should be used to prevent validation threads from blocking when connecting to 3rd party systems that may purposefully act really, really slowly.
preserveCommentsbooleanfalseWhen enabled, AntiSamy will keep HTML comments supplied in the input.
nofollowAnchorsbooleanfalseWhen enabled, AntiSamy will append rel="nofollow" attributes to all anchor ( <a> ) tags supplied in the input. This is useful for telling search engines not to associate your site with sites that are under the control of your users
validateParamAsEmbedbooleanfalseWhen enabled, AntiSamy will treat attributes of <param> tags in the policy the same as any tags nested inside the <embed>. This allows users to, according to policy, pass in data in either of those two methods with equal security. This is needed for sites that allow users to supply videos, etc.
preserveSpacebooleanfalseWhen enabled, this feature is intended to preserve spaces as specified in the input without normalization.
onUnknownTagStringremoveWhen this directive is set to "encode," it will encode the tag using HTML entities, instead of removing the tag, which is the default behavior.
+ +## Common Regular Expressions + +**`[ ]`** + +You can declare regular expressions here that can be used in the rest of the Policy File. + +### Examples + +```js + +``` + +This regular expression is used to determine whether the text in an id attribute is valid or not. + +```js +0-9a-fA-F]{6}|[0-9a-fA-F]{3}))"/> +``` + +We can define any number of regular expressions and each regex has its unique name to refer to other sections for validating over regex. + +The regexes defined here can be used to. + +## Common Attributes + +**`[ ]`** + +Here you can declare attributes here that are common to many different tags. Antisamy will match the attribute that encountered on any tag with regexes / literal-list defined for that attribute in this section. If doesn’t match then Antisamy will apply the action defined for that attribute with the **onInvalid** attribute. + +Below the schema structure. + +```xhtml +onInvalid=""> +``` + +### Attribute + +- Name - The name of the attribute (required). +- Description - Description of the attribute (optional ). +- onInvalid - Defines the action to be taken if the value of attribute fails matching (optional, Default : removeAttribute ) and possible actions are [ removeAttribute, encodeTag, filterTag, removeTag ]. + - removeAttribute - Remove the attribute only + - encodeTag - Encode the tag in which the attribute constitute. + - filterTag - Remove the tag and children but keep the contents. + - removeTag - Remove the tag along with the content. + +### Regexp-list + +Value of the attribute should match all the regexp defined here. + +- Regexp + - Name - The name of the regex that already defined in Common Regular Expressions. + - Value - Value of regex instead of defining int Common Regular Expressions. + +### Literal-list + +The value of the attribute should be one of the literal constants defined here. + +- Literal + - Value - Defines the literal constant value of the attribute. + +### Example-1 + +```xhtml + + + + + +``` + +And sample html text as follows +``` +

Test Me

+``` +As id attribute contains `$` it doesn’t match the regex htmlId so it will result as follows for different actions. + +**removeAttribute** +``` +

Test Me

+``` +**encodeTag** +``` +

Test Me

+``` +**filterTag** +``` + Test Me +``` +**removeTag** +``` + +``` +### Example-2 + +``` + + + + + + + + +``` + +Here the media attribute should match the regular expression and it should be in specified literal as well. + +:::note +In order to apply these validations on an attribute of the given tag, the attribute should be declared in section OR in under section otherwise that attribute will be removed without applying the attribute validation that defined in common-attributes. +::: + +## Global Tag Attributes + +**`[ ]`** + +You can declare attributes here that are global to all different tags. + +**Example:** +``` + +``` +The id attribute is global to many different tags. + + +## Tags to Encode + +**`[ ]`** + +You can declare tags here that will not be removed, filtered, validated or truncated, but encoded using HTML entities. + +**Example:** + +``` + g +``` +The g tag doesn’t actually do anything, but it isn’t malicious either so we can encode it, rather than remove it. + +## Tag Rules + +**`[ ]`** + +You can define parsing rules here that will be used for each tag individually. The following section shows what happens to tags according to what actions AntiSamy has decided to perform on it. This will help understand how to build your own tag-rules rules. + +- **remove** - Will remove entire tag when it encountered. +- **validate** - Validate the tag attributes based on defined rules. +- **filter** - Filter out the tag and children and preserve the content. +- **truncate** - Remove the content and children but keep the tag. + +### Default + +Behavior when the tag is not listed in <tag-rules> + +**Input**: +``` +Text goes **here**. +``` +**Output**: +``` +
Text goes here.
+``` + +### Remove + +Behavior when the tag-rule action is set to “remove” for given tag. Tag is deleted with all of its child text. + +**Input**: +``` +Text goes **here**. +``` +**Output**: +``` +
+``` + +### Filter + +Behavior when the tag-rule action is set to “filter” for given tag. Delete tag, but keep its child text. + +**Input**: +``` +Text goes **here**. +``` +**Output**: +``` +
Text goes here.
+``` + +### Validate + +Behavior when the tag-rule action is set to “validate” for given tag. Verify that its attributes and children elements follow rules defined in policy file. + +**Input**: +``` +Text goes **here**. +``` +**Output**: +``` +
Text goes here.
+``` + +### Truncate + +Behavior when the tag rule action is set to “truncate” for given tag. Keep the element, but remove all attributes. + +**Input**: + +``` +
Text goes here.
+``` +**Output**: +``` +
Text goes here.
+``` +**Example**: +``` + +``` +The html tag is included in the clean output after it has been validated that it has been properly used. + +## CSS Rules + +**`[ ]`** + +You can define parsing rules here that will be used for each CSS property individually. Only CSS defined in this section is allowed. + +**Example:** +``` + + + + + + + + + + + + + +``` + +The CSS width property is allowed only when it matches these rules when used. The value of the width element must be a length, percentage or one of the two literal values “auto” or “inherit”. diff --git a/website/versioned_docs/version-v11.8.5/app-development/app-security/xss-prevention.md b/website/versioned_docs/version-v11.8.5/app-development/app-security/xss-prevention.md new file mode 100644 index 000000000..7b0eaa23e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/app-security/xss-prevention.md @@ -0,0 +1,107 @@ +--- +title: "XSS Prevention" +id: "xss-prevention" +sidebar_label: "XSS Prevention" +--- +--- + +[Cross Site Scripting (XSS)](https://owasp.org/www-community/attacks/xss/) is a type of security attack, which injects malicious scripts into web applications to execute, generally in the form of a browser side script to an end-user. + +Typically, WaveMaker handles all XSS attacks using [Angular Sanitization](https://angular.io/api/platform-browser/DomSanitizer). Therefore, the apps are not vulnerable to XSS attacks by default. Sanitization handles untrusted values turning them into a safe value to insert into the generated code. However, in some cases, developers may want to include executable code, such as HTML (Hypertext Markup Language) content, giving developers the flexibility to bypass the code. + +In this document, you will learn how to configure UI (User Interface) to render data in HTML, or plain text while understanding the risk of XSS. + +- Rendering HTML in Datatable +- Using Formatters, such as trustAs in widgets + +## Sanitization in Datatable widget + +:::note +From [WaveMaker 10.13.0](/learn/wavemaker-release-notes/v10-13-0), Datatable columns render plain text to prevent XSS attacks. Before this change, the content was rendering HTML format. +::: + +In the following example, Datatable contains employee details and their current status. The **status** column uses HTML with inline styles, posing a potential XSS attack threat. + +WaveMaker sanitizes the Datatable widget, and when HTML is found in any column, it renders plain text as a result (see the image below). + +[![](/learn/assets/xss_datatable1.png)](/learn/assets/xss_datatable1.png) + +### Rendering HTML in Datatable + +To render HTML content in Datatable, we recommend configuring the **status** column to view as Label, making it safe to render HTML in Datatable. + +### How-to Steps + +1. Go to **Advanced Settings** of the Datatable -> **Columns** tab. +2. Select the **Status** column. +3. Go to **View Mode** and select **Label** from the **Widget** dropdown. (see the image below) + +[![](/learn/assets/xss_datatable3.png)](/learn/assets/xss_datatable3.png) + +The **status** column renders HTML without displaying inline styles to the column data; this is because WaveMaker applies sanitization to the Label widget. + +[![](/learn/assets/xss_datatable2.png)](/learn/assets/xss_datatable2.png) + +## Using Formatters + +The default behavior of WaveMaker UI widgets is to sanitize the content rendered inside them, preventing any possibility of an XSS vulnerability in the app. However, if the developer wants to bypass sanitization in the widgets, the Formatters `trustAs` can be used at the time of binding data to the widgets. + +### trustAs + +**trustAs** flag disables built-in sanitization for the values that pass through the widget, given the [security context](https://angular.io/guide/security#sanitization-and-security-contexts). + +You can access **trustAs** Formatters from: + +1. Use Expression dialog +2. Value Expression dialog + +#### Use Expression + +Configure the **trustAs** flag from the **Use Expression** tab of the Variable binding dialog. + +[![](/learn/assets/xss_datatable7.png)](/learn/assets/xss_datatable7.png) + +#### Value Expression + +Configure the **trustAs** flag from the **Value Expression** dailog of the Datatable's **Advanced Settings**. + +### Supported Widgets + +**trustAs** formatter with `html` context can be applied to the following widget properties. + +| Widget Properties | Widgets | +|---|---| +|**Caption** of | Label Anchor Button Message Checkbox File upload Spinner | +| **Title** of | Form-field | +|**Title** and **Sub Heading** of | Panel Charts Datatable Form Accordion-pane List | +| **Content** of | HTML | + +:::caution +This action can be malicious and introduce security risks to your app. Use this flag with caution and understand the risks of XSS attacks. [Read more.](https://angular.io/guide/security#sanitization-and-security-contexts) +::: + +### How-to Steps + +In the following example, we are looking at the same example used for Datatable to render HTML, which is [employee's current **status**](#sanitization-in-data-table-widget). + +1. Go to **Advanced Settings** of the Datatable -> **Columns** tab. +2. Select the **Status** column. +3. Go to the **Basic** tab and navigate to the **Value Expression** field. +4. Add the **trustAs** formatter with `html` context to bypass sanitization. + +Following example shows the **Value Expression** field configuring `trustAs` formatter for the **status** column. + +```html + +``` + +[![](/learn/assets/xss_datatable4.png)](/learn/assets/xss_datatable4.png) + +When you add the **trustAs** formatter, it renders HTML with the inline styles while disabling the sanitization for the **status** column (see the image below). + +[![](/learn/assets/xss_datatable5.png)](/learn/assets/xss_datatable5.png) + +:::warning +When using this flag, ensure you thoroughly follow [security context](https://angular.io/guide/security#sanitization-and-security-contexts). Else, the content may not render appropriately. Plus, it can put your app at risk of XSS vulnerability. +::: \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/core-implementation/core-and-implementation-projects.md b/website/versioned_docs/version-v11.8.5/app-development/core-implementation/core-and-implementation-projects.md new file mode 100644 index 000000000..52acfd87a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/core-implementation/core-and-implementation-projects.md @@ -0,0 +1,207 @@ +--- +title: "Core and Implementation Projects" +id: "core-and-implementation-projects" +sidebar_label: "Core and Implementation Projects" +--- +--- + +WaveMaker is here with Core and Implementation (IMPL) projects where, + +### Core Project + +- Acts as the base with all the common functionalities. This allows multiple teams to work collectively on top of it. + +### Implementation Project + +- Created as child projects of the Core project to add more features or customizations. Changes made to the Core project can be pulled into the IMPL projects periodically, making reusability seamless and boosting team collaboration. + +Core and IMPL projects primarily help in code reusability, maintenance, and steady upgrades. + +:::note +[Core](#core-project) and [IMPL](#implementation-project) project creation is applicable for [Teams](/learn/teams/overview/) users only. This is enabled for WaveMaker Online (WMO) teams only on demand. +::: + +## Example + +To understand working of [Core](#core-project) and [IMPL](#implementation-project), you can refer to the example where the core application is designed to start with onboarding a user and creating an account. Later credit and debit transactions through physical or virtual cards are enabled to make any purchase. + +![Core Application Flow](/learn/assets/core-impl-projects/core-app-example.png) + +After publishing Core application, you can proceed with IMPL creation on top of the Core application and modify the flow so that purchases use a beneficiary account for credit and debit transactions instead of physical or virtual cards. + +![IMPL Application Flow](/learn/assets/core-impl-projects/impl-app-example.png) + +## Enabling Core and IMPL Project + +[Core](#core-project) and [IMPL](#implementation-project) projects can be created by enabling the App Customization option for each user type in a team. Enabling App Customization is a restricted privilege, done by the [super admin](/learn/on-premise/configure/config-users-auth-providers/#make-user-as-a-super-admin) of the project. + +Super admins can enable it in Team Portal where they can view the Launch Pad option. + +1. Go to Team Portal > **Launch Pad** > Teams section to view the team details like Team Name, Created Date, Last Modified details, and configuration action items. +2. In the **Teams** section, click the **key** icon under Actions to edit the permissions for team members. +3. You get directed to **Manage Permissions** where you switch to **Product Role**. User roles and specific permissions are listed here for configuration. Click **Edit**. +4. Go to each role, and enable **App Customization** allowing users to create [Core](#core-project) and [IMPL](#implementation-project) projects. Click **Save**. + + + + + +## Publishing Core Project + +You can create a [Core](#core-project) project that would become the foundation for the [IMPL](#implementation-project) projects. It includes three major steps to get started with using Core Application. + +- [Creating Core Project](#creating-core-project) +- [Publishing Core Project](#publishing-core-project-to-teams-portal) +- [Approving Core Application](#approving-core-application) + +A Core project can be used across the teams by publishing it to Marketplace. Once published to Marketplace it will be visible in [ProjectsHub](/learn/blog/2024/03/04/wavemaker-11-6-release#introducing-projectshub) to all the teams in the environment. + +### Creating Core Project + +You can create a blank project with fundamental functionalities to become the base for the [IMPL](#implementation-project) projects. + +1. In [ProjectsHub](/learn/blog/2024/03/04/wavemaker-11-6-release#introducing-projectshub), click **Create App**. +2. Create Application dialog opens with Web and Mobile as application creation options. Select the type of application and click **Create a blank project**. Click **Continue**. +3. The next screen is Create application details, enter **Application name** and **Repo name**. Click **Continue**. +4. Invite your team members is the next screen, add **Team Member email IDs** and **Assign roles** like Project Admin, and Contributor. Click **Create Application**. + + + +### Publishing Core Project to Team Portal + +Once created, the project is published as [Core](#core-project) for the team members to access the application. + +1. You get redirected to WaveMaker studio where you can click the **Publish** icon to publish the project as core. +2. Publish Application To Teams As Core dialog opens. In the Information screen mainly enter the project **Category**, **New Version**, and **Change Log**. Click **Next**. +3. In the Configuration screen, add applicable **Tags** and click **Next**. +4. Verify the project details in the Summary screen and click **Publish**. This publishes the application in the Team Portal. + + + +### Approving Core Application + +The projects can only be published as [Core](#core-project) after approval. Once approved, the [Core](#core-project) project can be viewed and accessed by team members. + +1. Go to Team Portal > Core Apps, verify the provided information, and click **Approve**. +2. You get redirected to the **Approve core application** dialog where you add the Remarks and click **Confirm**. You can go to ProjectsHub to find the published Core application. + + + +## Creating Implementation Project + +[IMPL](#implementation-project) project is created on top of the base [Core](#core-project) project with added features and customizations. + +1. In the [ProjectsHub](/learn/blog/2024/03/04/wavemaker-11-6-release#introducing-projectshub), click **Create**. +2. Create Application dialog opens with Web and Mobile as application creation options. Select the type of application then select **Create from Core**. Click **Continue**. +3. In the next screen, Choose core & version, select a **Core application** on top of which the [IMPL](#implementation-project) project is created. +4. Create application details is the third screen, enter the **Application Name** and click **Continue**. +5. In the final screen, Invite your team members, add **Team Member email IDs** and **Assign roles** like Project Admin, and Contributor. Click **Create Application** to finish IMPL project creation. + + + +## Linking Existing IMPL Project to Core + +You can now link the previously created project, referred to as the IMPL project, to any base project, referred to as the Core project. You can analyze the existing project and link it to the suitable Core project. + +:::note + +Applicable for the Teams users who already use this flow outside WaveMaker Studio. Super admin is required to enable **Link To Core** permission for the team members in Launch Pad. + +::: + +1. Go to [ProjectsHub](/learn/blog/2024/03/04/wavemaker-11-6-release#introducing-projectshub) and hover over the existing project that can be considered as IMPL. +2. Click **View branch & project details** to open App overview. +3. Go to the Menu icon and click **Link_to_core App** to view the list of Core applications. +4. You land on the **Link project to core** dialog. Select suitable Core application and version details. Click Save to assign Core Application to the IMPL application. + + + + +## Fetching Core Upgrades in IMPL Project + +The added advantage of using [Core](#core-project) and [IMPL](#implementation-project) projects is, you can always fetch the [Core](#core-project) upgrades in the [IMPL](#implementation-project) project without necessarily creating a new [IMPL](#implementation-project) project with the upgraded [Core](#core-project) project. Whenever the [Core](#core-project) is updated, [IMPL](#implementation-project) projects created on top of the specific [Core](#core-project) project get an upgrade icon to fetch the Core changes in [IMPL](#implementation-project) without causing any code breakage. + +You can implement this using two steps +- [Creating branch with changes](#creating-branch-with-changes) +- [Merging upgrade changes](#merging-upgrade-changes) + +### Creating Branch with Changes + +While fetching the Core changes to IMPL, a temporary branch gets created to contain all the upgrade changes. + +1. Once an updated [Core](#core-project) version is available, you can view an upgrade icon in the [IMPL](#implementation-project) project. Click the Upgrade icon to start fetching the Core application upgrades in the [IMPL](#implementation-project) application. +2. The **Upgrade core** dialog opens where you can view the new features added in [Core](#core-project). Click **Upgrade** to create a temporary branch to contain Core upgrades. +3. Now, go to [ProjectsHub](/learn/blog/2024/03/04/wavemaker-11-6-release#introducing-projectshub) and hover over the IMPL project to view and click the **View branch & project details**. +4. The Branch details of the [IMPL](#implementation-project) project pop up automatically where you can click **Open Branch in studio**. This opens the temporary branch containing upgrades fetched from the Core. + + + +### Merging Upgrade Changes + +After the temporary branch creation, the upgraded changes are reviewed and the conflicts are resolved. + +1. You get redirected to the **Merge Changes** screen where you can find [Core](#core-project) upgrade changes in **Review Merge**. +2. You can view and resolve conflicts caused due to Core changes in **Resolve Conflicts**. +3. Click **Finish Merge** to remove the temporary branch and merge the [Core](#core-project) changes in [IMPL](#implementation-project) project. +4. You can now view the **Finish Merge** dialog, and enter commit message for merge. +5. Once your branch is successfully merged, click **Go Back To Projects List**. This redirects you to Projectshub, where you can find the [IMPL](#implementation-project) with [Core](#core-project) upgrades. + + + +## Publishing Core Prefab Project + +Prefab can also be published as a Core Prefab project with base properties. This allows the creation of Implementation (IMPL) Prefab with required customization on top of Core Prefab project. To make the Prefab a Core Project that can be accessed by every team member, you need to + +- [Publishing Prefab to Team](#publishing-prefab-to-team) +- [Approving Prefab as Core](#approving-prefab-as-core) + +:::note + +Users can publish a Prefab as Core along with the Prefab artifact during the approval process. There is no separate option available to publish from the Prefab Project. + +::: + +### Publishing Prefab to Team + +It is necessary to publish the Prefab as a Core Project for you to use it as a foundation for IMPL Prefab projects. + +1. Go to Prefabs and click **Open in Studio**. This opens the Prefab project in studio. +2. Click the **Publish** icon and select **To Team** to publish the Prefab project to a specific team. +3. Publish Prefab To Team dialog opens. In the Information screen mainly enter the Prefab **Category**, **New Version**, and **Change Log**. Click **Next**. +4. In the Configuration screen, add applicable **Tags** and click **Next**. +5. Verify the project details in the Summary screen and click **Publish**. This publishes the Prefab to the Team Portal. + + + +### Approving Prefab as Core + +You can view a **Prefab as Core** toggle that publishes the Prefab Core Project and Prefab artifact. You can next approve the publication and make it accessible for team members to create IMPL Prefab project on top of it. + + +:::note +Upon disabling the **Prefab as Core** toggle, you approve publishing the Prefab artifact that does not support the creation of IMPL Prefabs on top of the Prefab artifact. To know more on how to publish Prefab as an artifact, see [Publish Prefab to Team](/learn/app-development/custom-widgets/creating-prefabs/#publish-prefab-to-team). +::: + +1. Go to Team Portal > Prefab Artifacts to view the list of Prefabs to be approved for publication. +2. Select the Prefab that redirects you to **testPrefabCore** dialog. +3. Enable **Prefab as Core** toggle to publish the Prefab Core Project. +4. Verify the provided information, and click **Approve**. +5. You get redirected to the **Approve Prefab** dialog where you add the Remarks and click **Confirm**. You can go to ProjectsHub > Prefabs section to find the published Core Prefab Project. + + + +## Creating Implementation Prefab Project + +Similar to IMPL application, you can create IMPL Prefab project. This would include additional customizations on top of the existing Core Prefab project. + +1. In the [ProjectsHub](/learn/blog/2024/03/04/wavemaker-11-6-release#introducing-projectshub), go to Prefabs and click **Create**. +2. Create Application dialog opens with Web and Mobile as application creation options. Select the type of application then select **Create from Core**. Click **Continue**. +3. In the next screen, Choose core & version, select a **Core application** on top of which the [IMPL](#implementation-project) project is created. +4. Create application details is the third screen, enter the **Application Name** and click **Continue**. +5. In the final screen, Invite your team members, add **Team Member email IDs** and **Assign roles** like Project Admin, and Contributor. Click **Create Application** to finish IMPL project creation. + + + +:::note +Fetching Core Prefab project upgrades in the IMPL Prefab project involves the same steps as [fetching Core application upgrades in the IMPL application](#fetching-core-upgrades-in-impl-project). +::: \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/creating-prefabs.md b/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/creating-prefabs.md new file mode 100644 index 000000000..e081f5d7e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/creating-prefabs.md @@ -0,0 +1,312 @@ +--- +title: "Creating Prefabs" +id: "creating-prefabs" +sidebar_label: "Create Prefab" +--- +--- + +Prefabs are reusable application parts that interact with APIs and data on the web. Prefabs can be embedded and integrated into your applications with ease. You can create your own Prefabs using WaveMaker. + +To learn more, see [Prefabs Overview](/learn/app-development/custom-widgets/prefabs-overview). + +## Build your own Prefabs + +**Prefabs** are reusable application parts that interact with APIs and data on the web. Prefabs can be embedded and integrated into your applications with ease. You can create your own Prefabs using WaveMaker. + +[![](/learn/assets/prefab_create.png)](/learn/assets/prefab_create.png) + +1. From the [**Project Dashboard**](/learn/assets/ext_import.png), select **Prefab** tab and click **Create** +2. Enter a **Name**, set an **Icon** for the Provatar and enter **Description** +3. Review the **Package** and **Copyright** information and **Save** to continue. Make changes if needed. + +## Prefab Configuration + +To **Configure Prefab**, from [Project Configurations](/learn/assets/project_workspace.png) click **Settings** to select **Config Prefab** option. The various configurations are grouped under various headings for developer convenience + +[![](/learn/assets/prefabsettings_resources.png)](/learn/assets/prefabsettings_resources.png) + +### Resources + +Under this tab, you can set the following resource references as needed by your Prefab. Before setting the details, you will need to [Import Resource](/learn/assets/ext_import.png) into your Prefab project. + +1. `Style`: The CSS style associated with the project will be applied to this prefab. You can add your own style file. +2. `Script`: Any scripts that need prior execution can be added here. + +## Properties + +Users can add Prefab properties, which are exposed to the developers using the Prefab. These properties can take some input from the app(inbound) or give some output to the app(outbound) or both. These properties are defined in the Prefab scope. These properties will be displayed in the properties panel when the user uses the Prefab. The properties are further classified into UI and Server properties. + +### `UI Properties` +These are the properties that can be set from the front-end by the app developer using the Prefab. + +### General +- `Name`: a meaningful name in small characters, +- `Display Name`: property for setting the display name of the property in the properties panel, +- `Description`: This property can be used to set the help text for the property in the properties panel. This will also be used when generating Documentation for the Prefab while publishing the same + +### `Data` +- `Data Type`: of the value that can be entered for this property, +- `Default Value`: value given to the property, in case the user does not enter any value, +- `Binding Type`: specifies the binding behavior of the property: + +#### Binding Type +- `in-bound` allows binding for input value for the property by giving a bind icon next to it, +- `out-bound` allows for the value of this property to be bound to another widget by exposing it in the binding dialog, +- `in-out-bound`: allows both input and output binding. + +### `Widget` +Widgets to be displayed in the properties panel  - only for inbound properties +- `Type`: of widget for display; +- `Data Options`: list of values for user selection. +- `Show At`: If a prefab is used in another app or prefab, all UI properties of the prefab are shown when the prefab element is selected in studio design canvas (by default). If a widget is selected in 'Show At' list, then this UI property is shown only if that widget is selected. + +#### Data Options +:::note +Available only for the select, checkbox set, radioset widget type and can be bound to a variable. +::: + +This can be set to the following: +1. `Custom` - Dataset property can be populated with comma-separated values or bound to a variable. +2. `Depends on UI property` - Property Name can be set to the already declared in-bound property. If the selected property has an object structure the same will be retained. + +- `Show`: whether the property is visible or not, can be conditional if bound to a variable returning a boolean value; +- `Disabled`: whether the property is disabled or not, can be conditional if bound to a variable returning a boolean value. + +### `Server Properties` +These are the properties that need to be set from the back-end (using Java service) by the app developer using the Prefab. These would typically include the token for authorization, and more. +- `Name`: of the property +- `Default Value`: for the property + +[![](/learn/assets/prefabsettings_props.png)](/learn/assets/prefabsettings_props.png) + +## Events + +You can define events that can be handled by the developers using the Prefab. These events will be exposed under the events tab when the developer uses the Prefab, the developer can handle these events as per their requirements. By default, two events are defined - `onLoad` and `onDestroy` which will be triggered when the Prefab is loaded and deleted, respectively, from the app. Each Event will have the following properties that can be set: + +- `Name` of the event. It should be lower case and without any special characters. The event name gets prefixed with `on` and the first alphabet will get capitalized. For example, if you name an event `test` the event variable created would be `onTest` +- `Description` of the event. This will be used in the generatation of the documentation for the Prefab while publishing. + +[![](/learn/assets/prefabsettings_events.png)](/learn/assets/prefabsettings_events.png) + +### Events Flow + +Following are the pre-defined events for every Prefab. + +- **on Load**: this event is triggered whenever the page containing the Prefab loads or when the Prefab is dragged and dropped onto a page. This event is exposed to the Prefab user and can be further customized. It is displayed in the Events tab of the Prefab properties panel, after drag and drop in the project page. +- **on Property Change**: is triggered when any Prefab property is changed. This event is available only to the Prefab developer and is not exposed to the Prefab user. +- **on Destroy**: is triggered when the page containing the Prefab is closed or the Prefab is deleted from the page. This event is exposed to the Prefab user and can be further customized. It is displayed in the Events tab of the Prefab properties panel, after drag and drop in the project page. + +Apart from these, Prefab developer can define **custom events**, as mentioned in the previous section. These events are displayed in the Events tab of the Prefab properties panel, after drag and drop in the project page. Note that these custom events need to be triggered from within the Prefab. Actions assigned to these events from the project containing the Prefab will be performed only when the event is triggered. Events can be triggered using the following code (parameters $event and $data are optional): + +``` +Prefab.($event, $data) +``` + +[![](/learn/assets/prefab_event_method.png)](/learn/assets/prefab_event_method.png) + +## Methods + +You can define functionality in JavaScript which can be used by the developer. The developer can choose to invoke these methods in any way within the application using the Prefab as follows: +``` +Page..() +``` + +- `Name` of the method; +- `Description` of the method. This will be used in the generation of the documentation for the Prefab while publishing; +- `Return Type` of the method; +- `Parameters` required by the method. + +If the method does not exist, a function definition for the method will be generated in the JavaScript which can be accessed from the Script tab of the Prefab. [![](/learn/assets/prefabsettings_methods.png)](/learn/assets/prefabsettings_methods.png)[Click here to see the creation of a Prefab using Events and Methods](/learn/how-tos/create-prefab-using-jquery-plugin/) + +### Packaging + +These define how the Prefab appears in the Widget Toolbox in the apps + +1. `Name:` display name for the Prefab. +2. `Icon`: The icon displayed on the project dashboard for this Prefab can be changed by uploading it. + +[![](/learn/assets/prefabsettings_packagint-1.png)](/learn/assets/prefabsettings_packagint-1.png) + +## Testing Prefab + +The preview option on Prefab allows you to test your Prefab. The following options are available from the Preview screen: + +1. The In-bound Properties are listed and you can enter the test values. [![](/learn/assets/Prefab_preview1.png)](/learn/assets/Prefab_preview1.png) +2. The result is displayed from the Out-bound Properties tab. [![](/learn/assets/Prefab_preview2.png)](/learn/assets/Prefab_preview2.png) +3. The various methods included in the Prefab can be viewed and invoked from the Methods tab. [![](/learn/assets/Prefab_preview3.png)](/learn/assets/Prefab_preview3.png) +4. The various events invoked can be viewed from the Events Tab. [![](/learn/assets/Prefab_preview4.png)](/learn/assets/Prefab_preview4.png) + +## Publish Prefab + +Publishing a Prefab has the following options: + +- **Publish to Project:** Prefab can be made available to a specific project in your project workspace or network for testing purposes only. + - The Prefab will only appear in the specified project's widgets panel for use + - The Project which is using a test Prefab cannot be pushed to VCS. In order to push changes to VCS, the test prefab needs to be either [published to Teams](#publish-prefab-to-team) or [published to EDN](#publish-prefab-to-edn) (for Enterprise Version). + - When a published test Prefab releases a newer version, which is already published to Team or EDN earlier, opening that project will be prompt you with the following dialog. You can choose a version and click **update/revert** for using a published version in the project or continue with the modified, unpublished version. + + [![](/learn/assets/update-test-prefab-case1.png)](/learn/assets/update-test-prefab-case1.png) + + - If the test prefab is not published to Team or EDN, it should be **imported** into the selected project from Prefabs dialog. Go to **Artifacts** dropdown and click **Prefabs**. Once imported, refresh the project. + + [![](/learn/assets/import_team_prefab_step1.png)](/learn/assets/import_team_prefab_step1.png) + + + +- **Publish to Workspace** (non-enterprise version): + - The Prefab will appear in the Widget Panel for all projects within your workspace [![](/learn/assets/prefab_publish_ws.png)](/learn/assets/prefab_publish_ws.png) +- **Publish to EDN** (enterprise version)**: **Approval needed by EDN Admin + - You can publish the Prefab to EDN, and make it available to the entire enterprise + - After Admin approval, the Prefab will be listed in the artifact repository listing + - Import the Prefab to see it in the Widget Panel for drag and drop usage. [![](/learn/assets/prefab_publish.png)](/learn/assets/prefab_publish.png) + +Once the published Prefab is imported it will be available in the Widget Toolbox for drag and drop usage. You can use the refresh icon to check for any modification/updates in the Prefab. [![](/learn/assets/prefab_publish_toolbox.png)](/learn/assets/prefab_publish_toolbox.png) + +## Publish Prefab to Workspace + +##### Only for non-Enterprise Version + +Using the Publish to Workspace option from the Main Menu listed under the app name, you can make your Prefab available across all projects within your workspace. [![](/learn/assets/prefab_publish_ws.png)](/learn/assets/prefab_publish_ws.png) Once Published the Prefab will be displayed in the Prefab section of the Widgets Panel under the category specified at the time of publishing. [![](/learn/assets/prefab_publish_ws2.png)](/learn/assets/prefab_publish_ws2.png) If you want to share the Prefab with another WaveMaker Developer, Export the Prefab as Zip. This zipped file can be imported from the Prefab section of the Project Workspace. [![](/learn/assets/prefab_export.png)](/learn/assets/prefab_export.png) + +## Publish Prefab to EDN + +##### Only for Enterprise Version + +Using the Publish to EDN option from the Main Menu listed under the app name, you can make your Prefab available across all projects. Refer to [Artifacts Publishing Mechanism](/learn/app-development/wavemaker-overview/artifacts-repository/#publishing) for more details. [![](/learn/assets/prefab_publish1.png)](/learn/assets/prefab_publish1.png) + +Once approved, these Prefabs will be available for Import from the Artifacts List. **IMP**: To use the Prefab in a project, the developer must Import the prefab into the project from the artifact repository and refresh the Prefab panel. + +[![](/learn/assets/Artifacts_prefab_list.png)](/learn/assets/Artifacts_prefab_list.png) + +## Publish Prefab to Project + +Sometimes a Prefab may be used within a single project for testing purposes while it is still in development stages or changes made to a Prefab needs to be incorporated into a single project. In such cases, you can choose to **Publish Prefab to Project**. You can choose the project to which the Prefab needs to be updated, by selecting from the list. The Prefab will be displayed in the Widget Panel under Prefab section with a tag to indicate that it is an unpublished Prefab. + +[![](/learn/assets/prefab_bundle_proj.png)](/learn/assets/prefab_bundle_proj.png) + +You need to remember the following: + +- This version of the Prefab will not be available to other projects within your Project Workspace, nor will it appear in the Artifacts list (if not published). +- If it is an already published Prefab: + - When you open the selected project, you will be prompted either to **revert** to the published Prefab or **continue** with the modified, unpublished version. + - Choose to continue, when you want to test the Prefab for any changes before Publishing the changes. +- If the Prefab is not published + - You have published the Prefab directly to the project, or, + - You have imported a project zip file and it uses a Prefab that does not exist in your workspace, or, + - You have deleted the Prefab from the Artifacts dialog. + +## Publish Prefab to Team +- You can publish the Prefab to Team, and make it available to the entire team. + [![](/learn/assets/prefab_publish_team.png)](/learn/assets/prefab_publish_team.png) + +- Select a category and fill the required details and publish. + [![](/learn/assets/prefab_publish_team1.png)](/learn/assets/prefab_publish_team1.png) + +- Once the prefab is published, it needs to be approved by the Team Admin from Team Portal. + [![](/learn/assets/prefab_publish_team2.png)](/learn/assets/prefab_publish_team2.png) + +- After the Admin's approval, these Prefabs will be available for import from Prefabs dialog under Artifacts dropdown. + [![](/learn/assets/import_team_prefab_step1.png)](/learn/assets/import_team_prefab_step1.png) + + [![](/learn/assets/import_team_prefab_step2.png)](/learn/assets/import_team_prefab_step2.png) + + +## Update Prefab + +In continuous development scenario, Prefabs may be enhanced to incorporate new functionality. In such cases you need to Publish the Prefab, changing the version number. + +:::note +Prefab editing inside the application is disabled from [11.7.1](/learn/wavemaker-release-notes/v11-7-1). + +To streamline the development process, editing Prefabs directly within the application is not allowed. Developers should make code changes to the Prefab project itself and then publish the updated project to see the changes reflected in the application. +::: + +**Updated Prefabs**: By updating the Prefab version while publishing the Prefab will update the version and the latest version will be available across all the projects. When a project using this Prefab is opened,  the developer will be prompted to update the same within the project. When you open a project using the Prefab (i.e the Prefab was dragged and dropped onto the canvas) you will see a dialog asking you to update the Prefab You can choose to update or continue with the previous version. In case you choose to continue with the previous version, whenever you try to drag and drop the Prefab, you will be prompted to update the same. + +## Version Mismatches + +Conflicts can arise when different versions of Prefabs are in use. Consider the following cases: + +### Case-1 + +- Project P is using Prefab A (ver 1.0). +- Drag and drop Prefab B which internally uses Prefab A (ver 2.0). +- Conflict arises over the version of Prefab A. + +[![](/learn/assets/prefab_conflict1.png)](/learn/assets/prefab_conflict1.png) + +### Case-2 + +- Project P is using Prefab A which internally uses Prefab C (ver 1.0). +- Drag and drop Prefab B which internally uses Prefab C (ver 2.0). +- Conflict arises over the version of Prefab C. + +[![](/learn/assets/prefab_conflict2.png)](/learn/assets/prefab_conflict2.png) + +### Case-3 + +- Project P is using Prefab A ver 1.0 and Prefab B which internally uses Prefab A (ver 1.0). +- Update on Prefab A (ver 2.0) is available. +- Project P tries to update Prefab A. +- Conflict arises over the version of Prefab A. + +[![](/learn/assets/prefab_conflict3.png)](/learn/assets/prefab_conflict3.png) + +### Case-4 + +- Project P is using Prefab A and Prefab B +- Both the Prefabs use Prefab C (ver 1.0). +- Prefab A (ver 2.0) is updated with Prefab C ver 2.1. +- Project P tries to update Prefab A. +- Conflict arises over the version of Prefab C. + +[![](/learn/assets/prefab_conflict4.png)](/learn/assets/prefab_conflict4.png) + +In all of the above cases, WaveMaker gives you an option of the following. + +### Proceed Anyway +Update the Prefab in conflict. This might break the functionality of the other Prefab which uses the conflict Prefab. + +### OK +This will retain the older version of the Prefab in conflict and cancel the current action which resulted in the conflict - drag and drop of Prefab B in Case 1 & 2 or update Prefab A in Case 3 & 4. + +[![](/learn/assets/prefab_conflict.png)](/learn/assets/prefab_conflict.png) + +## Versioning Special Case + +In case an updated dependent Prefab is deleted that the force update will be reverted in the conflict Prefab. Revisiting the Case 4 above: + +### Case-4 + +- Project P is using Prefab A and Prefab B +- Both the Prefabs use Prefab C (ver 1.0). +- Prefab A (ver 2.0) is updated with Prefab C ver 2.1. +- Project P tries to update Prefab A. +- Conflict arises over the version of Prefab C. + +[![](/learn/assets/prefab_conflict4.png)](/learn/assets/prefab_conflict4.png) + +Assume that the Project P developer choose to update Prefab C + +- Both Prefab A and Prefab B are working with Prefab C ver 2.1. +- Consider that Prefab A is updated to ver 2.1 wherein the Prefab C has been deleted +- If Project P updates Prefab A to ver 2.1, then the Prefab C in Prefab B will be reverted to the original ver 1.0. + +[![](/learn/assets/prefab_conflict5.png)](/learn/assets/prefab_conflict5.png) + +## Deleting Prefab + +You can delete a custom Prefab from your project using the delete icon in the [Studio Artifacts](http://[supsystic-show-popup id=120]) listing dialog. + +[![](/learn/assets/prefab_publish_artefacts.png)](/learn/assets/prefab_publish_artefacts.png) + +## Accessing Prefab through Scripting + +- Once the Prefab properties are set, a **onPropertyChange** event is created, which can be programmed from the Script. + +[![](/learn/assets/Prefab_Script.png)](/learn/assets/Prefab_Script.png) + +- The exposed properties are defined on the Prefab scope. They can be accessed/modified in the Prefab script using: `Prefab.[propertyname]` + +We have seen the basics of creating a Prefab including the configuration settings, and various publishing options. Check out various use cases for Prefab creation by [clicking this link](/learn/app-development/custom-widgets/use-cases-prefabs/). + diff --git a/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/enterprise-marketplace.md b/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/enterprise-marketplace.md new file mode 100644 index 000000000..1141b115b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/enterprise-marketplace.md @@ -0,0 +1,98 @@ +--- +title: "Enterprise Marketplace" +id: "enterprise-marketplace" +sidebar_label: "Enterprise Marketplace" +--- +--- + + +Enterprise marketplace allows artifacts to be published by teams to be used across multiple teams. WaveMaker already has the feature to publish artifacts within the team where the members of the team can share and use the published artifacts. Now, with this feature teams will be able to share any artifact over marketplace and improve collaboration, reusability, while using new or existing Prefabs. + +:::note +Enterprise Marketplace is available only with WaveMaker Enterprise version of the product and not available on wavemakeronline.com +::: + +![Enterprise Marketplace](/learn/assets/wm_enterprisemarketplace.png) + +:::note +To know more about publishing **Artifacts**, see [Artifacts Repository](/learn/teams/import-vcs-project) +::: + +## Publish Prefab to Marketplace + +:::note +Only the team portal admin has the permission to publish any artifacts to "Enterprise marketplace". +::: + +- Go to [Teams Portal](/learn/teams/overview) > [Manage Prefabs](/learn/teams/manage-prefabs). +- Go to the **Pending Approval** tab. +- Select the Prefab, which is ready for review. Admin can Approve or Reject the Prefab submission request. +- Once approved, Prefab is listed in **Approved Prefabs** tab, which makes it available for team members to consume. +- Click **Publish to Marketplace**. A dailog opens to verify the details of the Prefab. Check the consent and click **Publish**. + +![Enterprise Marketplace](/learn/assets/wm_publishtomarketplace.png) + +- Once published, go to the **Marketplace Prefabs** tab. You can view the list of Prefabs available, which are ready to consume. + +![Marketplace Prefabs](/learn/assets/wm_marketplaceprefabs.png) + +### Publisher Information + +The identity of the published Prefab information is shown where the Prefab is listed. This includes the team name, as shown in the image below. + +![Publisher Information](/learn/assets/wm_artifactpublisherdetails.png) + +:::note +Versioning of the Prefabs follow semantic versioning scheme. +::: + +### Semantic Versioning + +WaveMaker supports versioning system to name the releases. Semantic versioning is a globally accepted versioning scheme that is already followed by many software publishers. + +:::note +With WaveMaker 11.3, the support extends to follow semantic versioning for Artifacts, including Prefabs. +::: + +An example of semantic versioning is as shown below. + +![Semantic Versioning](/learn/assets/wm_semanticversion.png) + +**Example**: + +In a timeline of three months, the following versions can be published: + +- Major - **1**.0.0 , **2**.0.0, **3**.0.0 +- Minor - 1.**1**.0, 2.**1**.0, 3.**1**.0 +- Patch - 1.0.**1**, 1.0.**2**, 1.0.**3**, 2.0.**1**, 2.0.**2** + +![Semantic Versioning](/learn/assets/wm_artifactversion.png) + +### Full Semantic Version Support for Prefabs Publishing + +We've now extended this support to include pre-release and build details from [release 11.7.1](/learn/wavemaker-release-notes/v11-7-1). + +For example, a version might look like **`1.2.1-beta+1234`**, where: + +- `1`: Major version +- `2`: Minor version +- `1`: Patch version +- `-beta`: Pre-release identifier (lowercase hyphen followed by a pre-release label) +- `+1234`: Build metadata (optional identifier prefixed with a plus sign) + +## Consume Prefab from Marketplace + +Developers can consume Prefab from WaveMaker Studio. + +- Go to a project. +- To consume a Prefab published to Marketplace, go to the Pages tab. +- Locate **Prefabs** and click the '+' icon. This opens a dialog, listing all the Prefabs that are ready to consume. +- Go to the **Marketplace** tab. Select the Prefab and click **Import**. + +![Enterprise Marketplace](/learn/assets/wm_enterprisemarketplace.png) + +- To locate the imported Prefab, expand the Prefabs section. + +![Marketplace Prefab Imported](/learn/assets/marketplace-prefab-imported.png) + +Drag and drop the Prefab onto the canvas to use. diff --git a/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/prefab-with-partials.md b/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/prefab-with-partials.md new file mode 100644 index 000000000..6302bb8b2 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/prefab-with-partials.md @@ -0,0 +1,72 @@ +--- +title: "Prefabs with Partials" +id: "prefab-with-partials" +sidebar_label: "Prefab with Partials" +--- +--- + +[Prefabs](/learn/app-development/custom-widgets/prefabs-overview) are reusable application parts that you can integrate into applications easily. [Partial](/learn/app-development/ui-design/page-concepts/partial-pages) is a part of a page associated with components within a page. It can be implemented as a single Partial and used across all app pages. To learn how to create Prefabs, see [Creating Prefabs](/learn/app-development/custom-widgets/creating-prefabs). + +With Partials inside a Prefab, you can create higher abstraction levels, and reuse functions across the web and mobile projects. You can use several other features, including organizing UI, using form-factor for enabling different screen size compositions. Additionally, benefit from using features like [Data Table with Row Expansion](/learn/how-tos/how-to-configure-row-expansion-in-a-data-table) and [Page Dialogs](/learn/app-development/widgets/modal-dialogs/modal-windows-dialogs#page-dialog) for on-demand content loading. + +## Creating Partials + +You can create two types of Partials, including **Partials** and **Widget Templates**. + +1. **Partials**: Use widgets such as Containers, Popovers, Page Dialogs, and more. + +2. **Widget Templates**: Create [Widget Templates](/learn/how-tos/custom-widget-template) with widgets, including Search, Radioset, Checkboxset to customize the look and feel. + +![PartialTypes](/learn/assets/partialTypes.png) + +You can import [template bundles](/learn/app-development/ui-design/page-concepts/creating-template-bundles) of Partials and Widget Templates into a Prefab Project. Choose the **Platform Type** when using the **Import Template** option to import for web and mobile projects separately. + +## Prefab Properties in Partial + +Like how you can access Prefab properties from the Main Page, you can access them from Partials. To create a property, go to the Config Prefab section and add them, as shown below. + +1. Go to **Settings** -> select **Config Prefab** -> switch to the **Properties** tab. +2. From the **UI Properties**, add new properties. To learn more, see [How to add Prefab Properties](/learn/app-development/custom-widgets/creating-prefabs/#properties). +3. The following Prefab example contains two properties, Prop1 and Prop2. + +![PrefabPropertiesDialog](/learn/assets/prefabpropertiesdialog.png) + +4. When you create a Partial, you can use these properties when binding it to an object. + +For example, add a Label widget. From the **Properties** section, go to **Caption** and click *Bind Property* to open the following dialog, and find all the created **Prefab Properties**, as shown below. + +![PartialBindDialog](/learn/assets/prefabpropertiesinsidepartial.png) + +## Script Tab + +Prefab Properties, Events, and Methods can be accessed inside the Partial script as shown below. + +```js + +Partial.onReady = function () { + // Prefab object is exposed to the Partial as Partial.Prefab + console.log(Partial.Prefab); + // this is how Prefab Properties can be accessed within Prefab Partials + console.log(Partial.Prefab.prop1); + // this is how Prefab methods can be accessed within Prefab Partials + console.log(Partial.Prefab.myMethod()); +}; +``` + +## Use Expression Tab + +When you declare a JavaScript function in the `Main.js` file, access it from the **Use Expression** tab. + +```js +Prefab.myJSFunction() +``` + +![prefab partial use expression](/learn/assets/use-expression-partial.png) + + +## Use Cases + +Learn how to use Partials in a Prefab. + +1. [Partials in Web and Mobile](/learn/how-tos/create-prefab-with-partials#partials-in-web-and-mobile) +2. [Using Partial for Data Table with Row Expansion](/learn/how-tos/create-prefab-with-partials#data-table-with-row-expansion) diff --git a/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/prefabs-overview.md b/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/prefabs-overview.md new file mode 100644 index 000000000..27a72a928 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/prefabs-overview.md @@ -0,0 +1,126 @@ +--- +title: "Prefabs - Custom Widgets & Extensions" +id: "prefabs-overview" +sidebar_label: "Prefabs Overview" +--- +--- +**Prefab** is a reusable, distributable component of an application, which can be tested independently. It can interact with APIs and data on the web. Prefabs can be embedded and integrated into your applications with ease. + +[![](/learn/assets/prefab2.png)](/learn/assets/prefab2.png) + +In this document the following topics related to Prefabs are covered: + +- the [What](#prefabs-example), [Why](#prefab-benefits) and [How](#prefab-anatomy) of a Prefab, +- [various features](#prefab-features) of a Prefab, +- using Prefabs in your application by [publishing](#publishing-prefabs) and [importing](#importing-prefabs), and +- [structure](#files-prefabs) of the Prefab code. + +## Understanding Prefabs - An Example + +The following example is a document collaboration use case, where multiple users can annotate, comment and collaborate changes to a document. A Prefab can be built which shows all comments made on the document, retrieving them from an API. Prefab can be associated with the context of the document and organization/user to which the document is associated. Within this app or other apps wherever file comments are shown, this prefab could be simply reused. + +[![](/learn/assets/prefab_ex1.png)](/learn/assets/prefab_ex1.png) + +This Prefab can be made to tightly integrate with specific APIs as shown below. Prefab parameters can be defined to externalize configurations such as email, organization account, etc. to carry the content. + +[![prefab_ex2](/learn/assets/prefab_ex2.png)](/learn/assets/prefab_ex2.png) + +## Prefabs & API Integration + +Prefabs make API integration a lot easier. You can + +1. integrate with REST API by importing API as a Service +2. secure the transaction via the built-in OAuth 2.0 handshake without the need to write additional code +3. manipulate the JSON responses by binding them to UI elements or widgets +4. configure input parameters through Prefab settings +5. expose data output and events for client-side integration + +[![](/learn/assets/prefab_api.png)](/learn/assets/prefab_api.png) + +## Why Prefabs + +Benefits of Prefabs are multifold. To list a few: + +1. They are reusable, API-integrated components that can be used across apps. +2. Prefabs encapsulate functionality, interaction & data. +3. New widgets can be built by composing from existing widgets – Extensions. +4. New widgets can be built by wrapping 3rd party JavaScript frameworks – jQuery extensions, d3 visualization components etc. +5. Re-usable backend Services can be built leveraging 3rd party Java Libraries – Jasper reports, Apache POI, etc. + +## Prefab Anatomy + +Prefabs leverage all the features available to a WaveMaker app, completely encapsulating them into one reusable component. Their UI Layer is composed of multiple widgets and acts as a single component, which is integrated with corresponding back-end services and they expose events & methods for integration with the enclosing app. + +[![](/learn/assets/prefab_anatomy.png)](/learn/assets/prefab_anatomy.png) + +## Prefab Types + +Prefabs can be applied in many situations, Broadly, they fall into following categories: + +1. **as widget extensions**: they can be built on top of 3rd party JS libraries and extend these libraries' functionality; [![prefab_widget](/learn/assets/prefab_widget.png)](/learn/assets/prefab_widget.png) +2. **as API integrated components**: WaveMaker UI components can be made to interact with the Prefab APIs to customize the Prefab behavior; [![prefab_apicomp](/learn/assets/prefab_apicomp.png)](/learn/assets/prefab_apicomp.png) +3. **as Backend service extensions**: reusable backend services can be built by leveraging 3rd party Java libraries. [![prefab_backent](/learn/assets/prefab_backent.png)](/learn/assets/prefab_backent.png) + +## Prefab Features + +Prefabs, like any widget, have the following features that can be set: + +1. **Properties**: If a Prefab exposes properties, you can set them using the Properties Panel. Depending upon the complexity of the Prefab, you may need to integrate the Prefab into your page using code. +2. **Events**: There are two default events which can be handled - on Load and on Destroy. These events get triggered when the Prefab is loaded or removed, respectively, from the page containing the Prefab. Any other events that have been defined by the Prefab developer will also be listed and these can be handled by the user. +3. **Methods**: Any methods that have been written and exposed by the Prefab developer will be available for invocation by binding them to an event of any widget. + +[Know more about Prefab settings](/learn/app-development/custom-widgets/creating-prefabs/#prefab-settings). + +[![prefab_frontend](/learn/assets/prefab_frontend.png)](/learn/assets/prefab_frontend.png) + +## Publishing Prefabs + +Once you have created a Prefab, it needs to be published in order for the apps to use it. [Know more about Publishing Prefabs](/learn/app-development/custom-widgets/creating-prefabs/#publish-prefab). + +[![](/learn/assets/prefab_publish.png)](/learn/assets/prefab_publish.png) + +## Importing Prefabs + +1. To use a prefab for the first time, you should import the Prefab into your app. To import, click the **+** from the **Prefabs** section. + + ![prefabs import](/learn/assets/prefab-import.png) + +2. Upload the `.zip` file. + + ![upload zip file](/learn/assets/prefab-zip-import.png) + +3. Once imported, you can find the prefab in the **Prefabs** section of the **Pages Resources**. These prefabs are grouped into categories like Basic, Media, Location, and more, as defined in the properties of the Prefab at the time of creation. +4. You can use prefabs in any of your projects by simply dragging and dropping them from the  **Prefabs** section to your page like any other widget. Once, embedded into the page, all the functionality of the prefab becomes a part of that page. +5. You can find the list of available Prefabs from the [Studio Artefacts](/learn/assets/artefacts.png) page. + +![](/learn/assets/artifact-sharing/artifacts-access.png) + +:::note + +1. All Published Prefabs will be available under Prefabs, without needing to Import. Just click the refresh icon if you don't find the Prefab. +2. To incorporate any changes made to an already imported prefab, it needs to be re-imported to an updated version of the project. Use the refresh icon for the same. +3. Deleting a prefab already incorporated into a project will not affect the project. +4. When using a Prefab in your applications, ensure that the widget names in the application do not conflict with the widgets names used in the Prefab. +::: + +## File Structure for Prefabs + +When a prefab is imported into a project, it places the prefab content into the folder: `src/main/webapp/WEB-INF/prefabs/{prefab-name}.` For each Prefab imported a separate folder is created, with the same name as that of the Prefab. + +:::note +Deleting this folder will delete the Prefab from the project. +::: + +[![](/learn/assets/Prefab_Files.png)](/learn/assets/Prefab_Files.png) + +For each Prefab you will find 3 subfolders: + +- `config` - consisting of the configuration files +- `lib` - any library files like jar files uploaded while Prefab creation +- `webapp` - contains the pages comprising the Prefab and any resources imported + + +## See Also +[Predefined Prefabs](/learn/app-development/widgets/widget-library/#prefabs-custom-widgets-extensions) +[Create your own Prefabs](/learn/app-development/custom-widgets/creating-prefabs/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/use-cases-prefabs.md b/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/use-cases-prefabs.md new file mode 100644 index 000000000..a22466417 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/custom-widgets/use-cases-prefabs.md @@ -0,0 +1,15 @@ +--- +title: "Use Cases - Prefabs" +id: "use-cases-prefabs" +--- + +The following Use Cases explain in detail how to create Prefabs: + +- [Create a simple Prefab to compare two strings](/learn/how-tos/create-simple-prefab/) +- [Create Prefab using 3rd Party UI Widgets](/learn/how-tos/create-prefab-using-third-party-ui-widgets/) +- [Create Prefab Using D3 & NVD3 Charts](/learn/how-tos/create-prefab-using-d3-nvd3-charts/) +- [Create Prefab Using D3 Library (DataMaps)](/learn/how-tos/create-prefab-using-d3-library-datamaps/) +- [Create Prefab Using JQuery Plugin – showcases using Events and Methods](/learn/how-tos/create-prefab-using-jquery-plugin/) +- [Partials in Web and Mobile](/learn/how-tos/create-prefab-with-partials#partials-in-web-and-mobile) +- [Using Partial for Data Table with Row Expansion](/learn/how-tos/create-prefab-with-partials#data-table-with-row-expansion) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/app-integration-with-aws-cdn.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/app-integration-with-aws-cdn.md new file mode 100644 index 000000000..22c723392 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/app-integration-with-aws-cdn.md @@ -0,0 +1,91 @@ +--- +title: "Deploy static content to AWS CDN for WaveMaker Apps" +id: "app-integration-with-aws-cdn" +sidebar_label: "App Integration with AWS CDN" +--- +--- + +The frontend code of any WaveMaker application can be configured to deploy onto a CDN. This improves the end-user experience of the WaveMaker application because of dramatic gains made in the page load times. In this document, you will learn how to setup the deployment of WaveMaker frontend artifacts to CDN. While the instructions here deal with AWS, similar steps can be followed to deploy onto CDNs provided by any other cloud infrastructure providers. + +- [Create an Amazon S3 bucket](#create-an-amazon-s3-bucket) +- [Configure Origin Access Identity](#configure-origin-access-identity) +- [Create an Amazon CloudFront distribution](#create-an-amazon-cloudfront-distribution) +- [Build and Deploy static Content to S3](#build-and-deploy-static-content-to-s3) + +## Create an Amazon S3 bucket + +- Sign in to the AWS Management Console and open the [Amazon S3 console](https://console.aws.amazon.com/s3/.) . +- Choose Create bucket, Next Enter Bucket Name, and Select the region for the bucket. +- In Bucket settings for Block Public Access, choose the Block Public Access settings that you want to apply to the bucket. +- Go to bucket properties, enable static website hosting. +[![static website enable](/learn/assets/wme-setup/s3-static-website-enable.png)](/learn/assets/wme-setup/s3-static-website-enable.png) + +- If the web application loaded in one domain and the frontend code in s3 loaded with a different CDN domain, then the end-user will receive error No 'Access-Control-Allow-Origin' header which is present on the requested resource. So, to selectively allow cross-origin access to your Amazon S3 resources, add CORS rules in the bucket permission section. If website content requires CORS, then add rules in the bucket permission section. For more details, visit [aws s3 cors](https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html). + +```json +CORS example +[ + { + "AllowedHeaders": [ + "*" + ], + "AllowedMethods": [ + "GET", + "POST", + "HEAD" + ], + "AllowedOrigins": [ + "http://example.mydomain.com" + ], + "ExposeHeaders": [], + "MaxAgeSeconds": 300000 + } +] +``` + +## Configure Origin Access Identity + +- An Origin Access Identity (OAI) is used for sharing private content via CloudFront. The OAI is a special CloudFront user and OAI has read permissions to the bucket. CloudFront will use the OAI to access the files in your bucket and serve them to end-users. +- When end-users access your Amazon S3 files through CloudFront, the CloudFront origin access identity gets the files on behalf of end-users. If end users request files directly by using Amazon S3 URLs, they're denied access. The origin access identity has permission to access files in your Amazon S3 bucket, but users don't. For more details visit [private content restriction in s3](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html) +- Sign in to the AWS Management Console and open the [CloudFront console](https://console.aws.amazon.com/cloudfront/.), at security section select origin access identity and create Origin Access Identity by providing comment. + +## Create an Amazon CloudFront distribution + +- Sign in to the AWS Management Console and open the [CloudFront console](https://console.aws.amazon.com/cloudfront/.), select Create Distribution +- On the first page of the Create Distribution Wizard, in the `Web` section, choose Get Started. +- At Origin Domain Name select previously created S3 Bucket, if you want to store content in any specific directory provide an origin path. +- select restrict buckets access as `yes` and select previously created existing Identity. +- At Grant Read Permissions on Bucket select `yes` for update bucket policy ,it will provide read permission to the origin access identity when you create the distribution. +[![CDN origin settings](/learn/assets/wme-setup/cdn-origin-setting.png)](/learn/assets/wme-setup/cdn-origin-setting.png) + +- Provide Cache behavior configuration details +[![CDN cache behaviour](/learn/assets/wme-setup/cdn-cache-behaviour-settings.png)](/learn/assets/wme-setup/cdn-cache-behaviour-settings.png) + +- At distribution settings select Default CloudFront certificate or import custom SSL certificate , then click on create distribution by providing required values for creation. +[![CDN distribution settings](/learn/assets/wme-setup/cdn-distribution-setting.png)](/learn/assets/wme-setup/cdn-distribution-setting.png) + +- Wait for few minutes to create distribution and after creating distribution note down the domain name of CloudFront distribution. + +## Build and Deploy static Content to S3 + +- Check Build Process [Maven Build Process to Support CDN Deploy](/learn/app-development/deployment/building-with-maven#build-war-file-and-static-content-to-deploy-them-separately) + +```shell +mvn clean install -Pdeployment +``` + +- Ensure that the selected profile has the `build.ui.mode` property set to `angular`. +- The above command generates two deployable artifacts: `ui-artifacts.zip`, `project.war`. Both these files can be found in the `target` folder. +- Use the following commands to unzip and upload to S3. +- To unzip the file and store contents in a specific folder. + +```shell +unzip ui-artifacts.zip -d +``` + +- Upload files to AWS S3 bucket + +```shell +aws s3 sync / S3_BUCKET +``` +- For instructions on configuring the CDN URL in your application see [Configuring CDN URL](/learn/app-development/deployment/building-with-maven/#configuring-cdn-url). diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/app-integration-with-azure-cdn.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/app-integration-with-azure-cdn.md new file mode 100644 index 000000000..5069d39db --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/app-integration-with-azure-cdn.md @@ -0,0 +1,74 @@ +--- +title: "Deploy static content to Azure CDN Profile for WaveMaker Apps" +id: "app-integration-with-azure-cdn" +sidebar_label: "App Integration with Azure CDN" +--- +--- + +The frontend code of any WaveMaker application can be configured to deploy onto a CDN. This improves the end user experience of the WaveMaker application because of dramatic gains made in the page load times. In this document, you will learn how to setup the deployment of WaveMaker frontend artifacts to CDN. While the instructions here deal with AZURE, similar steps can be followed to deploy onto CDNs provided by any other cloud infrastructure providers. + +- [Create Storage Account](#create-storage-account) +- [Create Storage Containers](#create-storage-containers) +- [Create Azure CDN profile](#create-azure-cdn-profile) +- [Build and Deploy static Content to Azure Storage Container](#build-and-deploy-static-content-to-azure-storage-container) + +## Create Storage Account + +- For a CDN profile users need to create a Storage account or can use an existing one for store static content.at create resource search for the storage account and provide project details and resource groups. + +[![storage account basic](/learn/assets/wme-setup/storageaccount-basic.png)](/learn/assets/wme-setup/storageaccount-basic.png) + +- At the networking section select connectivity method and .routing preference + +[![storage account networking](/learn/assets/wme-setup/storage-account-networking.png)](/learn/assets/wme-setup/storage-account-networking.png) + +- In the data protection method select data recovery and tracking methods. + +[![storage account data protection](/learn/assets/wme-setup/storage-account-dataprotection.png)](/learn/assets/wme-setup/storage-account-dataprotection.png) + +- In the advanced section select blob access and security options, next provide tags for the storage account and review the details and create a storage account. + +[![storage account adavance details](/learn/assets/wme-setup/storage-account-advance.png)](/learn/assets/wme-setup/storage-account-advance.png) + +## Create Storage Containers + +- Navigate to the storage account in the Azure portal and at the left menu for the storage account, scroll to the Blob service section, then select Containers. +- Select the **+ Container** button and provide name and at the public access level select `Blob(anonymous read access for blobs only`. + +- Enable CORS If the web application is loaded in one domain and the frontend code in the Azure storage container is loaded with a different CDN domain.In the Azure storage account select CORS under settings to enable. + + [![Blob CORS](/learn/assets/wme-setup/azure-blob-cors.png)](/learn/assets/wme-setup/azure-blob-cors.png) + +## Create Azure CDN profile + +- select Create a resource (on the upper left),Search for CDN and select CDN Profile, then select **+ Add** for create. +- Provide name,select subscription , resource and pricing tier and select create. + +[![CDN profile creation](/learn/assets/wme-setup/cdn-profile-creation.png)](/learn/assets/wme-setup/cdn-profile-creation.png) + +- On the CDN profile page, select **+ Endpoint** for create a CDN endpoint. +- Next provide name , select origin type as storage and select a previously created container for origin hostname. Provide origin host header and click Add . + +[![CDN endpoint](/learn/assets/wme-setup/cdn-endpoint-creation.png)](/learn/assets/wme-setup/cdn-endpoint-creation.png) + +- Note down the endpoint hostname to provide to maven command for integration + - example endpoint hostname + + ```bash + https://wavemaker-app-cdn-integration.azureedge.net + ``` + +## Build and Deploy static Content to Azure Storage Container + +- Check Build Process [Maven Build Process to Support CDN Deploy](/learn/app-development/deployment/building-with-maven#build-war-file-and-static-content-to-deploy-them-separately) + +```shell +mvn clean install -Pdeployment +``` +- Ensure that the selected profile has the `build.ui.mode` set as `angular`. +- Upload unzipped ui-artifatcs.zip files to AZURE storage container + +```shell +az storage blob upload-batch -s / -d --account-name +``` +- For configuring the cdn url in the application, see [Configuring CDN URL](/learn/app-development/deployment/building-with-maven/#configuring-cdn-url) diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/build-options.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/build-options.md new file mode 100644 index 000000000..a9332d5fb --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/build-options.md @@ -0,0 +1,56 @@ +--- +title: "Build Options for App Deployment" +id: "build-options" +sidebar_label: "Build Options" +--- +--- + +Build options are a part of configure profile settings. You can choose from the following build options to deploy your app. There are two build options you can choose from. + +1. Angular Build +2. WaveMaker Build (deprecated) + +## Angular Build + +With [WM 10.0](/learn/wavemaker-release-notes/v10-0-ga), the projects will contain generated Angular 7 code. Thus, you can choose the Angular build option to deploy your project. The Angular build further supports the following two build modes. + +1. Development mode +2. Production mode + +### Development + +This mode will have a minimum build time for the compilation, but the optimization mode does not include in this build. Thus, the execution load depends on the client/browser, which makes the application heavier at the runtime. + +### Production + +This mode takes longer than the **Development** mode as the compilation of templates, optimization mode, i.e., minification, uglification, dead code elimination/tree shaking, etc. handles during the build time. So the runtime performance will be superlatively better in this mode. + +## Choosing Angular Build Option + +**Angular Build** supports the Angular-generated project, and it offers several benefits over the classic **WaveMaker Build**. The Angular build option provides: + +- Angular 7 CLI compatible build process. +- Reduced size of build output files. +- Optimized output with Dead Code Elimination/Tree shaking, Uglification, and minification. +- Reduction in Application & Page Load times as parsing & execution times are reduced. + +## Setting Build Option + +To access the build options, click the **Settings** icon and select the **Config Profile** option from the drop-down. See the image below. + +[![config profile](/learn/assets/Config-profile.png)](/learn/assets/Config-profile.png) + +The **Config Profiles** opens the **Profile Configuration** window. Go to the **Build Options** tab, as shown in the image below: + +[![build options](/learn/assets/Locate-build-options.png)](/learn/assets/Locate-build-options.png) + +The Build Options are Read-Only for ‘Development’ build profile of the WaveMaker build. For other profiles such as ‘Deployment’ or the custom ones, you can choose from the above-specified modes. + +## WaveMaker Build (deprecated) + +This build option follows the classic WaveMaker build process which was used in the earlier versions of WaveMaker; for example, WM 9.4. WaveMaker build follows Maven build process. For more information, see [WaveMaker profiles](/learn/app-development/deployment/configuration-profiles#development-configuration-profile) + +## See Also + +[One-Click Deployment](/learn/app-development/deployment/one-click-deployment) +[Building a War file from a WaveMaker Project](/learn/app-development/deployment/building-with-maven) diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/build-with-docker.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/build-with-docker.md new file mode 100644 index 000000000..dc1426823 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/build-with-docker.md @@ -0,0 +1,193 @@ +--- +title: "Build with Docker" +id: "build-with-docker" +--- +--- + +WaveMaker supports micro-service-enabled architecture. This allows you to build and deploy applications using container-based technology. Docker is a platform as a service that uses virtualization to deliver software in packages called containers. Containers are isolated from one another and bundle their own software, libraries, and configuration files. + +For creating a Docker container, you create a Docker image by building a Dockerfile. For this, you require node and npm as prerequisites for building an application with maven and java. + +## System prerequisites + +- You can find the System prerequisites from [Angular Web and Mobile 11](/learn/wavemaker-release-notes/v11-1-2#angular-web-and-mobile-11) + + +## Build Docker Image + +Export the project to your local, or you can directly clone from a repository. You should keep the Dockerfile in the root directory of the project. + +### Creating a Dockerfile + +To create a Dockerfile, use the following command. + +```bash +vi Dockerfile +``` + +You can use the following Dockerfile for building Docker images and create Docker containers by using multi-stage Dockerfile. You can decrease the size of the Docker image and can create lightweight containers as well. + +```Dockerfile +FROM maven:3.9.5-eclipse-temurin-11 as maven-java-node +ENV MAVEN_CONFIG=~/.m2 +RUN mkdir -p /usr/local/content/node +WORKDIR /usr/local/content/node +ADD https://nodejs.org/dist/v18.16.1/node-v18.16.1-linux-x64.tar.gz . +RUN tar -xzf node-v18.16.1-linux-x64.tar.gz \ + && ln -s /usr/local/content/node/node-v18.16.1-linux-x64/bin/node /usr/local/bin/node \ + && ln -s /usr/local/content/node/node-v18.16.1-linux-x64/bin/npm /usr/local/bin/npm \ + && chown -R root:root /usr/local/content/node \ + && rm -fR node-v18.16.1-linux-x64.tar.gz + +FROM maven-java-node as webapp-artifact +RUN mkdir -p /usr/local/content/app +ADD ./ /usr/local/content/app +WORKDIR /usr/local/content/app +ARG build_profile_name +ENV profile=${build_profile_name} +RUN mvn clean install -P${profile} + +FROM tomcat:9.0.83-jdk11-temurin +COPY --from=webapp-artifact /usr/local/content/app/target/*.war /usr/local/tomcat/webapps/ +``` + +Save the above Docker file. + +### Create Docker Image + +Build a Docker image by using the below Docker command with different build profiles. You can choose to build with the following build profiles, including `development` and `deployment`. + +```Docker +docker image build --build-arg build_profile_name= -t +``` + +```bash +Example: docker image build --build-arg build_profile_name=deployment -t wmimage:1.0 . +``` + +For more information, see [Development Profile](/learn/app-development/deployment/configuration-profiles#development-configuration-profile) and [Deployment Profile](/learn/app-development/deployment/configuration-profiles#deployment-configuration-profile). + +Check [Handling Build Failures](/learn/app-development/deployment/building-with-maven#handling-build-failures) if build failed. + +### Run Docker Container + +For creating a Docker container, use the below Docker command. + +:::note +You can provide any `host_port`. For example, `80`. The internal port of the container is fixed and not changeable. +::: + +```Docker +docker container run --name -d -p :8080 +``` + +```bash +example: docker container run --name wmapp -d -p 80:8080 wmimage:1.0 +``` + +### Access Application + +If Docker is running on the Host network, use the Host IP address to access the application on the web. Get an Instance IP Address using the following command to access the application on the web. Please run the below command in the web application hosting Instance. + +```bash +ifconfig +``` + +- Above command will provide the network interfaces and their respective IP Address in Instance. Please use the respective IP Address to access the application on the web. You can access the application with `http:////`. + +## Build War File Using Docker + +- Export the project to your local, or you can directly clone from a repository. You should keep the Dockerfile in the project's root directory and mount the application directory location to `/usr/local/content/app` during container creation for generating application war. + +### Create Docker File + +To create a wm app builder Dockerfile, use the following command. + +```bash +vi Dockerfile.build +``` + +You can use the following Dockerfile to build Docker images and create Docker containers for creating project war files. + +```Dockerfile +FROM maven:3.9.5-eclipse-temurin-11 as maven-java-node +ENV MAVEN_CONFIG=~/.m2 +# installing node 18.16.1 and npm 9.5.1 in docker container +RUN mkdir -p /usr/local/content/node +WORKDIR /usr/local/content/node +ADD https://nodejs.org/dist/v18.16.1/node-v18.16.1-linux-x64.tar.gz . +RUN tar -xzf node-v18.16.1-linux-x64.tar.gz \ + && ln -s /usr/local/content/node/node-v18.16.1-linux-x64/bin/node /usr/local/bin/node \ + && ln -s /usr/local/content/node/node-v18.16.1-linux-x64/bin/npm /usr/local/bin/npm \ + && chown -R root:root /usr/local/content/node \ + && rm -fR node-v18.16.1-linux-x64.tar.gz + +# stage for build the code +FROM maven-java-node +RUN mkdir -p /usr/local/content/app \ + && chown -R root:root /usr/local/content/app +WORKDIR /usr/local/content/app +CMD mvn clean install -P${profile} && mkdir -p dist && cp -fr target/*.war dist/ +``` + +Save the above Dockerfile.build. + +### Create Docker Image + +Build the Docker image using the below command + +```bash +docker image build -t :1.0 -f Dockerfile.build +``` + +```bash +example: docker image build -t wavemaker/wm-app-builder:1.0 -f Dockerfile.build . +``` + +### Build Project war + +Create a Docker container to generate a war. Please use the below command. + +```bash +docker container run --rm -it --name -v $HOME/.m2:$HOME/.m2 -v $HOME/.npm:$HOME/.npm -v :/usr/local/content/app -e profile= -e MAVEN_CONFIG=$HOME/.m2 +``` + +```bash +example: docker container run --rm -it --name wmapp -v $HOME/.m2:/root/.m2 -v $HOME/.npm:/root/.npm -v /home/user/MySampleApp:/usr/local/content/app -e profile=deployment -e MAVEN_CONFIG=$HOME/.m2 wavemaker/wm-app-builder:1.0 +``` + +### Run Container + +- After Completing the build, it will create a project war file in the `/dist` folder. Users can use the war file to deploy in the Host tomcat or Tomcat Docker container. +- For deploying project war using Tomcat Docker container, please use the below command. + +```bash +docker container run -d --name -v /dist/:/usr/local/tomcat/webapps/ -p :8080 tomcat:9.0.83-jdk11-temurin +``` + +```bash +example: docker container run -d --name wm-app -v /home/user/MySampleApp/dist/:/usr/local/tomcat/webapps/ -p 80:8080 tomcat:9.0.83-jdk11-temurin +``` + +### Access Application + +If Docker is running on the Host network, use the Host IP address to access the application on the web. Get an Instance IP Address using the following command to access the application on the web. Please run the below command in the web application hosting Instance. + +```bash +ifconfig +``` + +- Above command will provide the network interfaces and their respective IP Address in Instance. Please use the respective IP Address to access the application on the web. You can access the application with `http:////`. + +## wm-rn-web-preview + +This Docker image is configured to allow users to execute [`wm-reactnative-cli`](https://github.com/wavemaker/wm-reactnative-cli) commands and it is used to preview the react-native applications locally. To know more about creating, installing, and setting up wm-rn-web-preview docker image, see [Docker Image for local Web preview](/learn/react-native/web-preview-docker-image). + +## Build War File Using wm-app-builder Docker Image + +The wm-app-builder Docker image is packed with required software packages and libraries to deploy WaveMaker Application in Docker containers. + +- Using the app-build Docker image, users can generate war files for WaveMaker applications. +- Using the wm-rn-web-preview image, users can preview the react native WaveMaker applications in their local. +- Find WaveMaker wm-app-builder Docker image at [wm-app-builder Docker Image in Docker Hub](https://hub.docker.com/r/wavemakerapp/app-build). +- Find WaveMaker wm-rn-web-preview Docker image at [wm-rn-web-preview Docker Image in Docker Hub](https://hub.docker.com/r/wavemakerapp/wm-rn-web-preview). diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/building-with-maven.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/building-with-maven.md new file mode 100644 index 000000000..8e658af1f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/building-with-maven.md @@ -0,0 +1,121 @@ +--- +title: "Building Project with Maven" +id: "building-with-maven" +--- +--- +This guide helps to create a war file for deploying the project in your local machine or a web server like Apache Tomcat. It also provides the required information to host static content and web applications separately. + +## System prerequisites + +- You can find the System prerequisites from [Angular Web and Mobile 11](/learn/wavemaker-release-notes/v11-1-2#angular-web-and-mobile-11). + +## Go to Source Location + +- WaveMaker Project sources can be fetched in two ways. + +### Clone VCS Repository + +- Clone Project into your pipeline or your local machine using git clone ``. +- You can clone only if you have configured custom VCS or push to your own repo (in both WaveMaker Enterprise Setups, WaveMaker Online Teams). For more information, see [Configure Custom VCS](/learn/app-development/deployment/build-options). + +### Download Zip from Studio + +- Export the project as zip. + +[![export project](/learn/assets/ExportProjectasZip.png)](/learn/assets/ExportProjectasZip.png) + +- Extract the downloaded zip file. + +- Get the project location path. + +- In the command line, go to the project path. See the image below. + +```shell +cd +``` + +[![locate project](/learn/assets/LocateProjectIncmdline.png)](/learn/assets/LocateProjectIncmdline.png) + +## Choose Profile to Build + +- WaveMaker project has two default profiles, including **development** and **deployment**. Prefix the profile name with a **P**. If you do not prefix the profile name; the system selects a **development** profile by default. You can add Custom Profiles from the **[Config Profiles](/learn/app-development/deployment/configuration-profiles)** section in the **Project Settings** options. +- Use `` in the next sections from  **default_profile/custom_profile**. + +## Build War file + +- Use the below command to do a maven build with the profile. + +```shell +mvn clean install -P +``` + +**For example** + +```shell +mvn clean install -Pdeployment +``` + +- This command will generate a `project war` file in the target directory. The `project war` file has both frontend artifacts (HTML, CSS, JS, images, etc), and backend artifacts (Java Classes). +- This war file can be deployed into any webserver like Tomcat. For more information, see [App Deployment to Tomcat](/learn/how-tos/wavemaker-application-deployment-tomcat). + +## Build War file and Static Content to Deploy them Separately + +WaveMaker app consists of frontend artifacts (HTML, CSS, JS, images, etc), and backend artifacts (Java Classes). It is recommended to host frontend artifacts in Static Content Server like Nginx, apache, etc, or Content Delivery Network (CDN), and backend artifacts can be hosted on any web server like Tomcat. + +### Generating Deployable Artifacts + +To generate frontend and backend artifacts from a WaveMaker application, follow these steps: + +1. Ensure that the selected profile has the `build.ui.mode` set as `angular`. +2. Execute the following Maven command: + +```shell +mvn clean install -P +``` + +**For example** + +```shell +mvn clean install -Pdeployment +``` + +This command generates two deployable artifacts: `ui-artifacts.zip` and `project.war`, both located in the target folder. +Both the WAR file and ui-artifacts must be deployed for the application to function correctly. Simply deploying the frontend artifacts on a CDN is insufficient. + +### Upload frontend artifacts to CDN + +Unzip the file `ui-artifacts.zip` and upload it to CDN origin (S3 bucket in AWS Cloudfront case, storage container in AZURE CDN Profile case, or put it into Nginx or apache). For specific instructions on how to use different CDNs, see [WaveMaker apps integration with AWS CDN](/learn/app-development/deployment/app-integration-with-aws-cdn) to configure CDN in AWS, and for Azure, see [WaveMaker apps integration with AZURE CDN Profile](/learn/app-development/deployment/app-integration-with-azure-cdn). + +### Configuring CDN URL + +The CDN URL can be passed to the application by setting the property `app.cdnUrl` in one of the following ways: + +1. Environment/System property. For specific instructions on how to set environment/system property, see [Using Environment Properties](/learn/app-development/deployment/configuration-management/#using-environment-properties). +2. Maven build parameter. + +**For example** + +```shell +mvn clean install -Pdeployment -Dapp.cdnUrl=https://mydomain.cloudfront.net/my_app>/1234/ +``` +3. Profile property. + +The priority order for reading the CDN URL is also the same as above. + +## Handling Build Failures + +- WaveMaker build may fail due to: + - Insufficient memory to Node Process. + - Compilation issues. +- On build failure due to the out-of-memory error, the profile property called **`build.ui.node.args`** should be adjusted; this configures the build. Increase the **`max-old-space-size`** memory value where the default value is 1024 MB. The build should be triggered again after increasing the memory value. There are two ways to do this: + + 1. Go to WaveMaker Studio -> **File Explorer** -> **profiles** -> open the file ``. + 2. Or, go to the Project folder -> profiles -> open the file ``. As shown in the image below: + +[![profile location](/learn/assets/profile-location.png)](/learn/assets/profile-location.png) + +- Adjust the value of **`build.ui.node.args`**. See the image below: + +[![adjusting space on failure](/learn/assets/adjusting-space-on-failure.png)](/learn/assets/adjusting-space-on-failure.png) + +- Re-do build. diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/configuration-management.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/configuration-management.md new file mode 100644 index 000000000..df93bdece --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/configuration-management.md @@ -0,0 +1,296 @@ +--- +title: "Configuration Management" +id: "configuration-management" +--- +--- + +## Introduction + +Each service in a WaveMaker application externalizes its configuration properties through [Config Profiles](/learn/app-development/deployment/configuration-profiles/). This externalized configuration helps isolate the code from the configuration. Therefore, the application/service configuration can be updated without changing the code. + +For example, the configuration of a DB service includes the hostname, DB credentials. In contrast, the configuration of a REST service can include hostname, context path, and more. + +In this section, learn how you can externalize configuration through Config Profiles, which works out of the Maven Profile concept. You provide the configuration values during the application build time through the maven profile property, i.e., when generating the war file. For more information about managing the config profiles, see [Configuration Profiles](/learn/app-development/deployment/configuration-profiles/). + +### Background + +In a typical scenario, the users maintain multiple profiles, including Development, QA, Stage, and Production, containing different configuration values. You build a war file for the respective environment by passing the profile to use for the configuration values. + +:::important +However, there are some concerns with this approach. + +1. The war file has to be rebuilt for every environment using a different profile file. + +2. The secrets, such as DB password, API keys, etc., are checked in the source code, which ideally should be managed only by Ops teams. +::: + +## Configuration Profile Management + +:::note +This is a new approach applicable from the [release 10.8.0](/learn/wavemaker-release-notes/v10.8.0). +::: + +The new generation of DevOps follows the cloud-native strategy [12-factor app](https://12factor.net/) wherein the war file is built only once, called an immutable war file. The immutable war file does not have the configuration values packaged in it. Instead, they will have placeholders that should be provided at the time of deployment; this enables the use of Docker images and versioning them based on the application version. + +## Building an Immutable War + +To build an immutable war file, you need the profile name to input the maven command, as shown below. + +``` +shell>mvn clean install -P +``` + +## Ways to Build an Immutable War + +Here you have multiple options: + +### Using an Existing Deployment Profile + +Use an existing deployment profile, called Deployment. It is the default profile that comes with the application. You can use it to build the immutable war file. In this approach, the default values for all properties are already defined in the profile. These profiles will be used if the configuration values are not provided during the Deployment time. + +:::note +However, using this approach can leave users confused about whether configured values are picked up during the application start. +::: + +### Create a New Immutable Profile + +:::note +We recommended using this approach. +::: + +Create a new profile called “immutable” and use it to build the war file. We recommend that you create a new profile and make the configuration values, including properties containing secrets information, empty in the profile file. This way, you control all the other non-secret configuration values through the profile and the secret values through Deployment. + +### Using Custom Placeholders + +You can use custom placeholders in the profile file. For example, if the profile property name is `DB.hrdb.password`, you can map the property name to your own custom property name such as `db_password`, you should mention the same as `${db_password}`. + +:::note +Assuing you are using the sample `HRDB` database in the following example. +::: + +**Example**: + +``` +db.hrdb.password=${db_password} +``` + +When the application starts, the WaveMaker application will try to resolve the `db_password` by applying one of the options when deploying an Immutable war. + +## Deploying an Immutable War + +When the immutable war file gets deployed with placeholders, the placeholder values should be resolved to actual values. You can achieve this in multiple ways, as given below. + +- Using Environment Properties +- Using System Properties +- Using Custom Property Sources + +### Using Environment Properties + +The configuration values for the property placeholders can be provided using the Operating System specific environment properties. This will override the property values already present in the war file. + +For example, if you want to set the database password through the environment property, you need to add the following property to the OS Environment. + +``` +db..password= +``` + +For HRDB database: + +``` +db.hrdb.password=mypassword +``` + +:::important +The environment property names cannot contain a dot (“.”) in its name, and it should be full lower case or completely upper case. Hence you need to normalize the key before setting it on the environment. So It can be written as `db_hrdb_password`, or `DB_HRDB_PASSWORD`. +::: + +So, it can be written as specified below: + +For Windows: + +``` +SET hrdb.password=mypassword +``` + +For Linux: + +``` +EXPORT hrdb.password=mypassword +``` + +### Using System Properties + +The configuration values for the property placeholders can be provided using the Java System properties using the “-Dkey=value” pairs. This will override the property values already present in the war file. + +For example, if you want to set the database password through the system property, you need to add the following property to the Java command of the respective web server. + +``` +-Ddb..password= +``` + +For HRDB: + +``` +shell>java -Ddb.hrdb.password=mypassword +``` + +### Using Custom Property Sources + +The use of Environment Properties or System Properties makes your war file immutable and can achieve compliance with 12-factor app deployment. However, it is not suitable for cases, particularly where you want to programmatically retrieve the configuration from external sources when the application starts. + +## What's Not Supported by Environment Properties and System Properties + +:::important +To address the following cases, WaveMaker introduced Custom Property Sources, such as [BootStrap Property Source](#bootstrap-property-source) and [Dynamic Property Source](#dynamic-property-source) explained in the next section. +::: + +Note that Environment Properties and System Properties do not support the following cases. + +### Configuration Managed in a Database + +In some cases, the developer wants to retrieve the configuration from a database and use it as an application configuration when the application starts. + +### Configuration through an API + +In some cases, you may have to call an external API to retrieve the application's configuration. + +### Encrypted Sensitive Information or Control via Encryption + +In some cases, you want to decrypt the encrypted values provided via profile properties, environment variables, or system properties based on the customer's requirements. + +### Controlling the Refreshing Properties + +There are few properties that you would like to refresh periodically without redeploying the application. + +### Contextual Configuration based on Logged-in User + +When you want to add configuration based on the logged-in user's context, such as multi-tenancy, provide different configuration values based on the caller context. + +## BootStrap Property Source + +WaveMaker introduced a class called [AbstractBootstrapPropertySource](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/core/props/AbstractBootstrapPropertySource.java) which should be extended and should provide the implementation for `getProperty()`. + +### Sample Snippet + +```java +public class MyAppBootstrapPropertySource extends AbstractBootstrapPropertySource { +@Override +public Object getProperty(String key) { + if(key.equals(“hrdb.password”)) { + //read the password from system properties and decrypt the value + String encPassword = System.getProperty(“hrdb.password”); + String password = MyEncryptionUtils.decrypt(encPassword); + return password; + } + return null; //return null if you cannot handle a property... +} +} +``` + +The name of the class should be added as context param to the `web.xml` file as given file: + +```xml + + bootstrapPropertySource + com.myapp.core.props.MyAppBootstrapPropertySource + +``` + +### Points to Note + +1. When configured, this property source is registered as the first property source in the spring environment and this property source will be called during the bootstrap of the application. +2. The property source's `getProperty()` may be called multiple times for the same property key every time it uses it. Hence it would be best if you cached the properties in case the property values are retrieved using a database or an API request. +3. Since this property source is started or called even before spring context is initialized, you cannot use any spring beans inside this implementation. + +## Dynamic Property Source + +WaveMaker introduced another property source called Dynamic Property Source, which provides the configuration based on application runtime context such as Logged in user's context. + +Dynamic Property Source is useful to multi-tenant applications where you want to route the user to different REST API servers based on the logged-in user's tenant or role. However, not all properties can be multi-tenantable. As of the [10.8 release](/learn/wavemaker-release-notes/v10.8.0), only the REST service-based properties can be provided through this property source. + +You should extend the [AbstractDynamicPropertySource](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/core/props/AbstractDynamicPropertySource.java) and provide the implementation for the `getProperty()` method as given below. + +```java +public class MyAppDynamicPropertySource extends AbstractDynamicPropertySource { +@Autowired +private SecurityService securityService; + + @Override +public Object getProperty(String key) { + if ("myRestService.host".equals(key) && securityService.isAuthenticated()) { + String userName = securityService.getUserName(); + if ("user".equals(userName)) { + return "dev.myappdomain.com"; + } else { + return "prod.myappdomain.com"; + } + } + if ("app.environment.key1".equals(key)) { + return "updateVal1"; + } + return null; +} +} +``` + +:::note +In the above sample implementation, you override the property value for the keys `myRestService.host` and `app.environment.key1`. For other keys, it will fall back to other property sources defined in the environment. +::: + +Define the bean `user-spring.xml` file as given below: + +```java + +``` + +### Points to Note + +1. When configured, this property source is registered as the first property source in the spring environment and this property source. +2. The property source's `getProperty()` may be called multiple times for the same property key every time it uses it. Hence it would be best if you cached the properties in case the property values are retrieved using a database or an API request. +3. Since this property source starts after the spring context is initialized, you can Autowire any spring-managed beans and use them in your implementation. +4. Since this property source is started or called after the spring context is initialized, you will not be called for properties required in the Bootstrap process. + +## Bootstrap vs Dynamic Property Source + +Both the property sources will help in dynamically assigning the configuration values to the application. However, you need to understand the following differences. + +1. Bootstrap should be used to pass the values required when the application starts. In contrast, the Dynamic property source should be used only when the configuration values could be different based on the caller context. +2. Both of these property sources can be invoked multiple times for the same property key. Hence you need to cache those values and use them in subsequent calls. +3. When both property sources are configured, the priority is given to the Dynamic Property Source, then the Bootstrap Property. Following that, precedence is given to the System and Environment Variables, respectively. +4. If the property source is unaware of the key, it should `return null` for the given property to check the property in the next available source, similar to the following order. + 1. Dynamic Property Source + 2. BootStrap + 3. System Property + 4. Environment Variable. + +## Consuming Properties in Java Services + +In this section, you will understand how to use configuration properties in the application Java code. + +There are two ways to do it. + +1. Using [@Value](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Value.html) for fields is a convenient way to read configuration properties. These values are set during application bootstrap, so they cannot be used for reloadable or dynamic properties. + +For example, if you need a configuration property to read numberOfWorkerThreads, it can be read using the code below. + +```java +@Value(“app.environment.numberOfWorkerThreads”) +private int numberOfWorkerThreads; // This value is not going to change even if the value is updated in the property sources +``` + +2. Using the [PropertyResolver](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/env/PropertyResolver.html) methods. PropertyResolver is the superclass of the environment. + +For reloadable or dynamic properties supported using the above **bootstrapPropertySource** or **dynamicPropertySources**, the configuration property can be fetched every time on-demand using the `environment.getProperty` methods. + +For example, reading from the [environment](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/env/Environment.html). + +```java +@Autowired +Environment environment; + +public void process() { + String remoteHost = environment.getProperty(“app.environment.remoteHost”); + Integer remotePort = environment.getProperty(“app.environment.remotePort”, Integer.class, 80); + // ... +} +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/configuration-profiles.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/configuration-profiles.md new file mode 100644 index 000000000..70d05e2c3 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/configuration-profiles.md @@ -0,0 +1,60 @@ +--- +title: "Configuration Profiles" +id: "configuration-profiles" +--- +--- + +**Configuration Profiles** allow you to run the same application under different environments with different settings, and this configuration information is stored in the form of profiles. + +If you need to configure a profile to provide lots of custom settings to suit third-party tools, services, network settings, or certificates, you can do it with the help of **Config Profiles**. This is in line with _[Maven Configuration Profiles](https://maven.apache.org/guides/mini/guide-building-for-different-environments.html)_. The profile can be accessed from the **Settings** option as shown in the image below. + +[![config settings](/learn/assets/config_settings.png)](/learn/assets/config_settings.png) + +You can configure Database, REST Servers, and more. By default, two profiles are generated for every application. + +1. **Development**, which is used with the **Run** option, +2. **Deployment**, which is used with the **Deploy** option, +3. Or, Create a new **Custom** environment. + +:::note +Before you select the environment, you should set the build option mode. For more information, see [Build Options in WaveMaker](/learn/app-development/deployment/build-options). +::: + +## Development Configuration Profile + +The **Development Configuration Profiles,** used with the **Run** option, are not editable. The values are set from the configuration of the underlying services at the time of import/creation. If you want to change these values, go the respective service configuration dialog and make the changes. + +[![](/learn/assets/config_dev.png)](/learn/assets/config_dev.png) + +- Under Security tab, Configuration SSL is disabled by default. +- There is no provision to configure X-Frame options. It is by default set to “Same Origin”. +- The App Environment properties can be added, deleted or modified. When you click on Save button, the properties get synchronized with all the profiles. For more information, see [Using App Environment Property](/learn/how-tos/using-app-environment-properties/). + +## Deployment Configuration Profile + +The **Deployment Configuration Profiles,** used with the **Deploy** option, are editable. The values are set from the configuration of the underlying services at the time of import/creation. You can change them according to the Deployment Environment settings. + +[![config deploy](/learn/assets/config_deploy.png)](/learn/assets/config_deploy.png) + +For more information, see [Deployment Profile](/learn/app-development/deployment/deployment-profile). + +## Prefab Configuration Profile + +If your app is using Prefab which has services imported, you can configure the same here. Same as with the app profiles, only Deployment Profile is configurable. Also, for Prefabs, you cannot change the Security settings. + +[![config prefab](/learn/assets/config_prefab.png)](/learn/assets/config_prefab.png) + +## Creating Configuration Profile + +You can choose to **add different configuration profiles** as per the need of the application. These profiles can be deleted. + +:::note +This custom profile can be used when exporting the project as a WAR file. +::: + +[![config custom](/learn/assets/config_custom.png)](/learn/assets/config_custom.png) + +## See Also + +[One-Click Deployment](/learn/app-development/deployment/one-click-deployment) +[Building a War file from a WaveMaker Project](/learn/app-development/deployment/building-with-maven) diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/configure-pipelines.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/configure-pipelines.md new file mode 100644 index 000000000..f447a39fa --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/configure-pipelines.md @@ -0,0 +1,40 @@ +--- +title: "Configure Pipeline in WME" +id: "configure-pipelines" +--- +--- + +:::note +This documentation applies to WME users only. +::: + +WaveMaker Enterprise supports a three-phased pipeline configuration, which includes **QA**, **Stage**, and **Live** phases. You can configure each phase with different profile configuration settings. + +- Use the same steps to configure both Stage and Live phases. +- Add instances for Stage and Live phases _before_ configuration. For more information, see [Adding Instances](/learn/on-premise/configure/add-apps-capacity). + +## Deploy to QA Phase + +By using one-click deployment, the application deploys to the QA phase by default. You should configure the release pipeline before deploying the application. For more information, see [Pipeline Configuraton](/learn/on-premise/configure/config-pipeline) for App Deployment. + + +## Configure Stage and Live Phases + +Before pushing the application to the next phase, you have to configure the phases in the Launchpad in the App Deployment section. WaveMaker supports all major cloud providers. + +- [AWS configuration](/learn/app-development/deployment/deployment-to-aws/) +- [Azure configuration](/learn/app-development/deployment/deployment-to-azure/) +- [Google Cloud configuration](/learn/app-development/deployment/deployment-google-cloud/) +- [Digital Ocean configuration](/learn/app-development/deployment/deployment-to-digital-ocean/) + +After configuring the phase, you push the application from one phase to another and configure each stage with profiles for deploying the application. For more information, see [Configuration Profiles](/learn/app-development/deployment/configuration-profiles). + +[![manage live app](/learn/assets/manage_apps_live.png)](/learn/assets/manage_apps_live.png) + +Selecting *Provider* will initiate Live Pipeline setup and will auto-configure the phase and you can push the app to the Live phase. + +## Push to Stage and Live + +Once the app is tested and the live phase has been configured, you can push the app from QA to Stage to Live. + +![WME phases](/learn/assets/ptl_cloud_done.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/default-pipelines.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/default-pipelines.md new file mode 100644 index 000000000..eed4e2111 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/default-pipelines.md @@ -0,0 +1,34 @@ +--- +title: "Default Pipelines in WMO" +id: "default-pipelines" +--- +--- + +WaveMaker Online supports a two-phased pipeline configuration which includes **Demo** and **Live** phases. You can configure each phase with different [profile configuration settings](/learn/app-development/deployment/configuration-profiles). + +## Deploy to Demo Phase + +For deploying to a Demo phase, WaveMaker provisions instance by default. You just need to deploy the application using the [One-click deployment](/learn/app-development/deployment/one-click-deployment). + +## Deploy to Live Phase + +For the **Live** phase, you have to provision your own instances for deploying the application. + +### Configuring Live Phase + +After deploying the application to a **Demo** phase with [One-click deployment](/learn/app-development/deployment/one-click-deployment), you can configure the **Live** phase by going to **[Managed Deployed Apps](/learn/app-development/deployment/manage-deployed-apps)**. + +![WMO Demo phase](/learn/assets/demo_phase_in_wmo.png) + +You can configure each stage with different profiles for deploying an application. For more information, see [Profile Configurations](/learn/app-development/deployment/configuration-profiles). + +### Cloud Providers + +For **Live** phase, you can configure with different major cloud providers. + +- [AWS configuration](/learn/app-development/deployment/deployment-to-aws/) +- [Azure configuration](/learn/app-development/deployment/deployment-to-azure/) +- [Google Cloud configuration](/learn/app-development/deployment/deployment-google-cloud/) +- [Digital Ocean configuration](/learn/app-development/deployment/deployment-to-digital-ocean/) + +After pushing the application to the **Live** phase, it automatically builds and deploys in its respected cloud provider. diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-google-cloud.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-google-cloud.md new file mode 100644 index 000000000..f48e61c54 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-google-cloud.md @@ -0,0 +1,40 @@ +--- +title: "Configuring for Google Cloud Deployment" +id: "deployment-google-cloud" +sidebar_label: "Google Cloud" +--- +--- +WaveMaker allows you to deploy your app to your Google Cloud account for Live (and Stage for WME users) phase. [Know more about App Phases from here](/learn/app-development/deployment/release-management/). + +To deploy your app to Google Cloud account, you need to configure the Live (Stage) phase. + +:::note +This document covers the Live Phase configuration for your AWS account and is a part of the [Manage Deployed Apps](/learn/app-development/deployment/manage-deployed-apps/). +::: + +## Prerequisites + +1. You are expected to have a [Google Cloud Account](https://console.cloud.google.com/). +2. You need to create a [Service Account](https://cloud.google.com/iam/docs/creating-managing-service-accounts#creating_a_service_account) with the following settings: + - Role set to Project Owner i.e. full access to all resources, + - From the API Dashboard ensure that the following APIs are Enabled: + + - Google Compute Engine API and + - Google Cloud Resource Manager API + + (**following shows the screen from the Google Developer Console dialog. This dialog might differ from the actual one**) [![](/learn/assets/google_account_enable.png)](/learn/assets/google_account_enable.png) + - A downloaded file containing Private Key in JSON format (**following shows the setting from the Google Create Service Account dialog. This dialog might differ from the actual one**) [![](/learn/assets/google_account_settings.png)](/learn/assets/google_account_settings.png) + +## Steps in Configuring Google Cloud + +1. From Apps Portal, select the project. +2. Click Configure on the Live Phase option. +3. While configuring the Live phase choose to host your app on Google Cloud +4. Enter your Google Cloud account credentials to proceed with the configuration. [![](/learn/assets/deploy_google_account.png)](/learn/assets/deploy_google_account.png) You need to enter + - **Google Project Id**: It is the project created by you on Google Cloud Platform. All resources are referenced with this project. ([see here for details](https://cloud.google.com/resource-manager/docs/creating-managing-projects)) + - **Service Account Id**: You will get this when creating a Service account. This account should have **Role** set to _Owner_ and **Key Type** as _JSON_ ([see here on how to obtain it](https://cloud.google.com/compute/docs/access/service-accounts)) + - The region/zone in which you wish to provision the instance. + - Client Credentials: This is a private key in a JSON file to authenticate the service account. You need to copy the entire content of the JSON file including the braces - {}.([see here on how to obtain it](https://cloud.google.com/compute/docs/access/service-accounts)) +5. Select the appropriate instance size based upon the resources and database utilized by your app ([see here for pricing details](https://cloud.google.com/compute/pricing)) +6. and enter the key-value instance tags ([see here for best practices for instance tagging](https://cloud.google.com/compute/docs/storing-retrieving-metadata)) [![](/learn/assets/deploy_google_instance.png)](/learn/assets/deploy_google_instance.png) +7. Once the setup is done, you can push the app from Demo to Live. ([Continue from here](/learn/app-development/deployment/manage-deployed-apps/#push-to-live)) diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-overview.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-overview.md new file mode 100644 index 000000000..0568840c8 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-overview.md @@ -0,0 +1,52 @@ +--- +title: "Deployment Overview" +id: "deployment-overview" +sidebar_label: "Overview" +--- +--- + +WaveMaker provides a quick and easy-to-deploy solution. You can deploy an app to the WaveMaker Demo Cloud infrastructure with just a single click. + +![one-click deployment](/learn/assets/one-click-deployment.png) + +## One-click Deployment + +![deploy icon](/learn/assets/deploy-app.png) + +With One-click Deployment, you can test or demo your application in the early stages of the development. Also, this is the first step to deploy an application to the cloud when your app is in the process of setting up a private cloud or an on-premise environment. + +:::important +One-click deployment is available for Project Admins only. +::: + +For more information, see [step-by-step instructions for One-click Deployment](/learn/app-development/deployment/one-click-deployment). + +## CI-CD Pipelines + +WaveMaker release pipeline enables you to setup application deployment phases for easy delivery of CI-CD process by leveraging Docker containerization. There are different stages for the release management process depending on the [WaveMaker Studio Editions](/learn/documentation-reference#wavemaker-studio-editions). + +### WaveMaker Enterprise + +WaveMaker Enterprise (WME) consists of the following three stages. + +1. QA +2. Stage +3. Live + +To learn more about how to configure these pipelines, see [Configure Pipeline for WME +](/learn/app-development/deployment/configure-pipelines). + +### WaveMaker Online + +WaveMaker Online (WMO) consists of the following three stages. + +1. Demo +2. Live + +To learn more about how to configure these pipelines, see [Configure Pipeline for WMO](/learn/app-development/deployment/default-pipelines). + +### Automation + +Automate the CI-CD pipelines to configure a private cloud provider, including AWS (Amazon Web Services), Azure, GCP (Google Cloud Provider), Digital Ocean, and on-premise environments like VMware or Hyper-V. To learn more about configuring your application to a CI-CD pipeline, see [WaveMaker Release Management](/learn/app-development/deployment/release-management). + +![deploy to cloud](/learn/assets/deploy-to-cloud.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-profile.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-profile.md new file mode 100644 index 000000000..24b4681bd --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-profile.md @@ -0,0 +1,111 @@ +--- +title: "Configure Deployment Profile" +id: "deployment-profile" +sidebar_label: "Deployment Profile" +--- +--- + +You can configure Database, REST Servers, and more. By default, two profiles are generated for every application. + +1. **[Development](/learn/app-development/deployment/configuration-profiles#development-configuration-profile)**, which is used with the **Run** option, +2. **Deployment**, which is used with the **Deploy** option, +3. Or, Create a new **Custom** environment. + +:::note +For more information about each profile, see [Configuration Profiles](/learn/app-development/deployment/configuration-profiles). +::: + +To configure the deployment profile, go to **Setting**, click **Config Profiles**. + +[![config settings](/learn/assets/config_settings.png)](/learn/assets/config_settings.png) + +## Deployment Configuration Profile + +The **Deployment Configuration Profiles,** used with the **Deploy** option, are editable. The values are set from the configuration of the underlying services at the time of import/creation. You can change them according to the Deployment Environment settings. + +[![config deploy](/learn/assets/config_deploy.png)](/learn/assets/config_deploy.png) + +## Database Settings + +- **Records per request:** Max Results can be set for Database configuration. This option will restrict the number of rows returned by any Variable associated with the database. The REST API calls will impose this restriction. +- You can also specify the minimum and maximum **Pool size** to limit the number of connections to a database. + +## REST + +- **REST** service settings for Protocol, Host and Application path can be modified. + +## SOAP + +- **SOAP** service settings especially those related to the connection and request timeout can be modified. + +## Web Socket + +- **Web Socket** settings can also be modified. + +## Security + +Security settings allow enabling SSL encryption, XSS Protection, and X-Frame-Options. + +### X-Frame-Options + +X-Frame-Options is an HTTP response header, that indicates how the browser should handle rendering of embedded pages within frame or iframe or as objects. + +With **X-Frame-Options**, you can do the following: + +- **Disable** hence allowing all pages to be displayed in any frame, or +- **Enable** the option. Once enabled, the X-Frame options are available to be set as per application needs. + +By selecting **Enable**, you get the following three options: + +- **Deny:** This option restricts the page from getting displayed in any frame, irrespective of the site accessing it. +- **Same Origin:** This option displays the page in a frame of the same origin as the page. This is the default behavior. +- **Allow From:** The page can only be displayed in a frame of a specified origin. With this option, the browser makes a decision on whether to display the response in the iframe based on the scheme, host and port values.  The “Allow From” header will automatically be converted to the Content Security Policy header, based on the target browser, thus ensuring cross-browser support. Multiple URLs can be set using comma-separated notation. + +## Session Configuration + +**Session Configuration** like Session Timeout and persistent login feature can be set. + +## Token Based Authentication + +Token-based Authentication is an authentication mechanism, that authenticates API request. The user is issued an API access token upon successful authentication, which will be used while invoking any API request. For more information on generating a Token [see here](/learn/app-development/app-security/token-based-authentication/). + +To modify token related details, click on Security tab. Under deployment check for Token-Based Authentication. Token Based Authentication consists of three options: + +1. **Enable Tokens:** This option enables the token parameter and token validity options. +2. **Token Parameter:** The API's can be accessed once the token is issued. It is done by passing the token in the Request Header or Parameter. +3. **Token validity:** Default valid time for a token is 1800 sec (30 mins). However, you can customize the token valid time as required. + +Click Apply to set the modified token details. **Note:** The user can modify only the token valid time and not the token parameter value. + +- **CORS:** You can enable cross-origin resource sharing so that websites from different domains can access resources in a WaveMaker app. From here you can set: + + 1. **Allow Credentials**: This option is to allow users to include credentials (including cookies and auth data) to be sent with the XHR requests. + 2. **Max Age**: This option is used to set the validity, in seconds, of the pre-flight request response. + 3. **Path**: Only the resources (in WaveMaker app) with the mentioned path can be exposed. + 4. **Origins**: WaveMaker app resources can be exposed only to these origins. + +- **Security Provider Configuration**: Various details for service providers like LDAP, AD, SAML can be configured. + +:::note +When changing the deployment profile in Studio for a deployed app, will not have any effect on the deployed version until you re-deploy the app to the Demo phase. +::: + +## App Environment + +**App Environment** settings can only be configured/updated, but not added or deleted. In other words, you are allowed to change the property values, but restricted to add or delete properties. [More on App Env property usage](/learn/how-tos/using-app-environment-properties/). + +## OAuth 2.0 + +- **OAuth 2.0** provider settings can be modified by changing the Access Token URL, Authorization URL, Client Id and Client Secret. + +## Build Options + +Build options are a part of configure profile settings. You can choose from the following build options to deploy your app. There are two build options you can choose from. + +WaveMaker Build (deprecated), Angular Build. For more information, see [Build Options](/learn/app-development/deployment/build-options). + +## See Also + +[Configuration Profiles](/learn/app-development/deployment/configuration-profiles) +[One-Click Deployment](/learn/app-development/deployment/one-click-deployment) +[Building a War file from a WaveMaker Project](/learn/app-development/deployment/building-with-maven) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-to-aws.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-to-aws.md new file mode 100644 index 000000000..dcc33a440 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-to-aws.md @@ -0,0 +1,29 @@ +--- +title: "Configuring for AWS Deployment" +id: "deployment-to-aws" +sidebar_label: "AWS" +--- +--- + +WaveMaker allows you to deploy your app to your AWS cloud account for Live (and Stage for WME users) phase. +For more information, see [Release Management](/learn/app-development/deployment/release-management/). + +To deploy your app to AWS account, you need to configure the Live (Stage) phase. + +:::note +This document covers the Live Phase configuration for your AWS account and is a part of the [Manage Deployed Apps](/learn/app-development/deployment/manage-deployed-apps/). +::: + +## Prerequisites + +- [AWS Account](https://aws.amazon.com/). +- While setting up the AWS account care should be taken to ensure that the IAM key has the permissions as listed in the configuration dialog. [![](/learn/assets/deploy_aws_perms.png)](/learn/assets/deploy_aws_perms.png) **Steps in AWS Configuration**: +- From Apps Portal, select the project. +- Click Configure on the Live Phase option. +- While configuring the Live phase choose to host your app on AWS +- Enter your AWS account credentials to proceed with the configuration. You need to enter [![](/learn/assets/deploy_aws_account.png)](/learn/assets/deploy_aws_account.png) + - access key and secret key ([see here for details](https://aws.amazon.com/developers/access-keys/)) + - AWS Account id ([see here on how to obtain it](http://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html)), and + - the region hosting your AWS account +- Select the appropriate instance size based upon the resources and database utilized by your app and enter the [key-value instance tags](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html) ([see here for best practices for instance tagging](https://aws.amazon.com/premiumsupport/knowledge-center/ec2-resource-tags/)) [![](/learn/assets/deploy_aws_instance.png)](/learn/assets/deploy_aws_instance.png) +- Once the setup is done, you can push the app from Demo to Live. ([Continue from here](/learn/app-development/deployment/manage-deployed-apps/#push-to-live)) diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-to-azure.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-to-azure.md new file mode 100644 index 000000000..8491bc168 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-to-azure.md @@ -0,0 +1,60 @@ +--- +title: "Configuring for Azure Deployment" +id: "deployment-to-azure" +sidebar_label: Azure +--- +Learn how to deploy your app to Azure server. + +--- + +WaveMaker allows you to deploy your app to your Azure cloud account for Live (and Stage for WME users) phase. [Know more about App Phases from here](/learn/app-development/deployment/release-management/). + +To deploy your app to Azure account, you need to configure the Live (Stage) phase. + +:::note +This document covers the Live Phase configuration for your AWS account and is a part of the [Manage Deployed Apps](/learn/app-development/deployment/manage-deployed-apps/) +::: + +## Prerequisites + +- You are expected to have an [Azure account](https://azure.microsoft.com/en-in/free/). +- You must set up an Active Directory application and assign the required permissions to it. The permissions include access to _Microsoft.compute_, _Microsoft.network_ and _Microsoft.storage_. [See here to create AD app](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal). +- Once the application is created, get the authentication details. + + 1. Click on the Configure tab to configure your application's password. + 2. Copy the CLIENT ID. + 3. If the application will run under its own credentials, scroll down to the Keys section and select how long you would like your password to be valid. + 4. The saved key is displayed and you can copy it. You will not be able to retrieve the key later so you will want to copy it now. + +:::important +WME users need to request the copying of the deployment vhd ([Virtual Hard Disk](https://docs.microsoft.com/en-us/azure/storage/storage-about-disks-and-vhds-linux)) to their Azure account.   + +For this, you need to write to [support@wavemaker.com](mailto:support@wavemaker.com) with the storage account name and sas ([shared access signature](https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-shared-access-signature-part-1)) token. To obtain Shared Access Signature, you need to: + +1. [Create a Storage Account](https://docs.microsoft.com/en-us/azure/storage/storage-create-storage-account), +2. From the Storage Account access Blob and create a Container named **_vhds_** +3. Obtain the [shared access signature token](https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-shared-access-signature-part-1). +::: + +**Steps in Azure Configuration**: + +- From Apps Portal, select the project. +- Click Configure on the Live Phase option. +- While configuring the Live phase choose to host your app on your Azure account. +- Enter your Azure account credentials to proceed with the configuration. You need to enter: + + [![](/learn/assets/deploy_azure_account.png)](/learn/assets/deploy_azure_account.png) + + - Subscription ID ([see here for details](https://blogs.msdn.microsoft.com/mschray/2016/03/18/getting-your-azure-subscription-guid-new-portal/)) + - Tenant ID, Client ID, and Client Secret ([see here on how to obtain it](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal#get-tenant-id)) + - Resource Group Name ([see here for details](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-portal)) + - Azure region where the app needs to be deployed + - A new storage account at Azure will be created with the name you provide. Make sure you enter a unique name. + - If you already have a storage account ([see here on how to create the same](https://docs.microsoft.com/en-us/azure/storage/storage-create-storage-account)) you can give the details, test the connection before proceeding to the next step. +- Select the appropriate instance based on your app requirements. You can choose from the three options provided ([see here for size comparisons](https://docs.microsoft.com/en-in/azure/virtual-machines/windows/sizes-general#a-series)) and enter the [Username and Password](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/classic/tutorial#1-basics-blade) details. [See here](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/faq) for more information regarding setting up of Azure VM like username, password, etc.. +[![](/learn/assets/deploy_azure_instance.png)](/learn/assets/deploy_azure_instance.png) + +:::note +Please make sure your Azure subscription should allow launching an instance with Standard_A1, Standard_A2, and Standard_A3 +::: +- Once the setup is done (this could take **upto 30 minutes** in case the storage account has to be created), you can push the app from Demo to Live ([Continue from here](/learn/app-development/deployment/manage-deployed-apps/#push-to-live)). diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-to-digital-ocean.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-to-digital-ocean.md new file mode 100644 index 000000000..b48ca7c7e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-to-digital-ocean.md @@ -0,0 +1,127 @@ +--- +title: "Configuring DigitalOcean Deployment" +id: "deployment-to-digital-ocean" +sidebar_label: "DigitalOcean" +--- +--- + +DigitalOcean Kubernetes (DOKS) is a DigitalOcean managed Kubernetes service that lets you deploy Kubernetes clusters without the complexities of handling the container infrastructures. This is the first Kubernetes deployment provider supported by the WaveMaker platform. + +Following are the few benefits of Kubernetes deployments: + +- Auto Scaling +- Auto Recovery +- Service Discovery + +WaveMaker allows you to deploy your app to your DigitalOcean account for Live phase and Stage phase for WME users. For more information about app phases, see [Release Management](/learn/app-development/deployment/release-management/). + +To deploy your app to the DigitalOcean account, you should configure the Live phase, or Stage phase for WME. + +:::note +This document covers the Live Phase configuration for your DigitalOcean account and is a part of the [Manage Deployed Apps](/learn/app-development/deployment/manage-deployed-apps/) +::: + +#### Stages in DigitalOcean Deployment + +1. Configuration of DigitalOcean cluster +2. Deployment of application to DigitalOcean cluster + +## Stage-1: Configuration of DigitalOcean cluster + +1. From Apps Portal, select the project. +2. Click Configure on the Live Phase option. +3. While configuring the Live phase choose to host your app on the DigitalOcean cloud provider. + + [![](/learn/assets/manage_apps_live.png)](/learn/assets/manage_apps_live.png) + + After choosing the DigitalOcean cloud provider, you observe a configuration dialog comprising of multiple steps. Let's talk in detail about each step below. + +## DigitalOcean account and cluster details + +Enter your **DigitalOcean access token** to proceed with the configuration. For more information, see [How to Create a Personal Access Token](https://www.digitalocean.com/docs/apis-clis/api/create-personal-access-token/). + +![](/learn/assets/deploy_do_setup.png) + +After providing your access token, you can see options to configure a new cluster or use an existing cluster. + +### Process 1: Creation of a cluster + +![](/learn/assets/deploy_do_new_cluster.png) + +You should provide the following details to launch a cluster. +1. Cluster Name +2. The region for launching the cluster +3. Cluster Capacity using: + - Cluster Node Size - This defines the type of memory, hard disk and CPU size that you would want to allocate to the worker node created. + - Cluster Node Count - This determines the number of worker nodes to be launched with the above-chosen node size in the cluster. The default value for this is set to `1`. + +### Process 2: Use an existing cluster + +![](/learn/assets/deploy_do_existing_cluster.png) + +You can choose from a pre-populated list of clusters present in your account. These fetch based on the access token that you provide. + +## Registry Details + +Since the deployment flow involves image-based deployment, you should to have a registry account to push the application image to the registry and pull the same at the time of deployment of an application to the DigitalOcean cluster. + +![](/learn/assets/deploy_do_registry_details.png) + +1. **Registry Url**: Currently this is fixed to `registry.hub.docker.com` as we are supporting only the docker hub registry for now. +2. **Repository Name**: To enable only private push and access of images, you should provide a private repository name. To create a private repo in Docker Hub account, see [Private repositories](https://docs.docker.com/docker-hub/repos/#private-repositories). +3. **Username** of Docker Hub account +4. **Password** of Docker Hub account + +## Application Configuration + +You need to provide Application-specific deployment configuration in this step. + +[![](/learn/assets/deploy_do_app_configuration.png)](/learn/assets/deploy_do_app_configuration.png) + +1. **Application Replica**: Scaling of an application is accomplished by changing the number of replicas in a Deployment. + This value determines the number of pods that must be running within the worker nodes at any given point of time. + +2. **Application Memory**: This is the amount of memory that needs to be allocated to deployed application. In case of a new cluster created, this value should never exceed the memory specified for the worker node size. + +Once you enter the configuration details, click **Configure** to trigger the cluster configuration process. + +In case you have configured a **new cluster**, the phase creation is initiated and you can track the progress of the cluster creation process under the jobs section of the respective project in Studio. + +![](/learn/assets/deploy_do_configure_new_cluster.png) + +![](/learn/assets/deploy_do_configuring.png) + +![](/learn/assets/deploy_do_jobs_cluster_configuration.png) + +On clicking the **Configure** button, for **existing cluster**, the Live phase is associated with already chosen cluster details. + +![](/learn/assets/deploy_do_configure_existing_cluster.png) + + +## Stage-2: Deployment of application to DigitalOcean cluster + +Once the live phase configuration is completed, you can trigger the deployment to DigitalOcean cluster by clicking **Push** option in the Demo phase. + +For the deployment process, we depend on the [**HyScale tool**](https://github.com/hyscale/hyscale). + +![](/learn/assets/deploy_do_cluster_configured.png) + +Once you click the **Push** button, you observe a [config profile window](/learn/app-development/deployment/configuration-profiles). Configure the details as per your requirement and click **Next** and then **Push**. + +![](/learn/assets/deploy_do_push_to_live.png) + +![](/learn/assets/deploy_do_deploying.png) + +The deployment progress can be tracked in the Jobs section of the respective project as shown below. + +![](/learn/assets/deploy_do_jobs_deployment.png) + +After successful deployment, you can see options to view the deployment details, or go to the deployed URL. + +![](/learn/assets/deploy_do_deployment.png) + +On clicking of the **View Details** tab, you can view the deployment and Live phase-specific information like ImageName, the namespace at which the application is deployed, the default storage class, cluster details, and more. You can use these details to perform registry, or cluster-specific operation, or debugging. + +![](/learn/assets/deploy_do_providerinfo1.png) + +![](/learn/assets/deploy_do_providerinfo2.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-using-docker-compose.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-using-docker-compose.md new file mode 100644 index 000000000..f8f3e8f12 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-using-docker-compose.md @@ -0,0 +1,95 @@ +--- +title: "Deploy using Docker Compose" +id: "deployment-using-docker-compose" +--- +--- + +Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application services. For installation of docker compose, see [docker-compose-install](https://docs.docker.com/compose/install/). + +## Application Deployment using DB + +WaveMaker application deployment requires DB for its operation. For example, deployment using `mysqldb`. + +- Use the below Docker-compose file for deploying multi-container WaveMaker application. + +```Docker compose +version: "3.3" +services: + db: + image: mysql:5.6 + environment: + MYSQL_ROOT_PASSWORD: root_password + volumes: + - /wavemakerapp/mysql/:/var/lib/mysql + networks: + - wmo_app + + webapp: + image: ./wavemaker-application/ + environment: + wm.mysqlCloudHost: db:3306 + wm.mysqlCloudUsername: root + wm.mysqlCloudPassword: root_password + volumes: + - /wavemakerapp/tomcat-logs:/usr/local/tomcat/logs + networks: + - wmo_app + + nginx: + build: + context: ./nginx/ + ports: + - "80:80" + volumes: + - /wavemakerapp/nginx-logs:/var/log/nginx + networks: + - wmo_app +networks: + wmo_app: + driver: bridge + +``` + +- WaveMaker-application folder consists of Dockerfile and application code for building WaveMaker app. For Dockerfile, see [WaveMaker Dockerfile](/learn/app-development/deployment/build-with-docker), and use the Dockerfile for building WaveMaker application. + +- The `nginx` folder consists of a `nginx` Dockerfile and a `conf` file for reverse proxy operations. + +## nginx Dockerfile + +```Dockerfile +FROM nginx:1.16 +COPY ./default.conf /etc/nginx/conf.d/ + +``` + +The nginx `default.conf` file for reverse `proxy.user` can modify the `conf` file based on their requirements. + +```conf +upstream webapp_wm { + server webapp:8080; + +} + +server { + listen 80; + listen [::]:80; + + location / { + proxy_pass http://webapp_wm; + } + underscores_in_headers on; + proxy_ssl_server_name on; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-SSL-Request 1; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Port $server_port; +} +``` + +- For creating multi-container WaveMaker application using above configuration, run the following command. + +```shell +docker-compose -f docker-composefile-name up -d +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-web-server.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-web-server.md new file mode 100644 index 000000000..fdd414762 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/deployment-web-server.md @@ -0,0 +1,57 @@ +--- +title: "Deployment to Application Server" +id: "deployment-web-server" +sidebar_label: "Application Server Overview" +--- +Overview document for deploying your app to a web server. + +--- + +Applications built with WaveMaker can be deployed to a number of environments. In this document, we walk through the process of WaveMaker app deployment to Web Server. + +## Web Server Installation +You will need a valid Web Server installation. The following is a list of Web Servers where the WaveMaker apps can be deployed. + +:::note +This list is for reference purpose. Apart from these, you can use any standard Java Web Server running on JDK 11 and Servlet Framework version 4.0.1 +::: + +| **Web Server** | **Versions** | **Instructions** | +| --- | --- | --- | +|[![](/learn/assets/tomcat.jpg)](/learn/assets/tomcat.jpg)| 9.x | [Deployment Instructions](/learn/how-tos/wavemaker-application-deployment-tomcat/) | +|[![](/learn/assets/websphere.png)](/learn/assets/websphere.png)| 19.0.0.1+ Liberty Profile| [Deployment Instructions](/learn/how-tos/wavemaker-application-deployment-websphere-liberty-profile/) | +|[![](/learn/assets/jboss.png)](/learn/assets/jboss.png) | WildFly 15+ | [Deployment Instructions](/learn/how-tos/wavemaker-application-deployment-jboss/) | +|[![](/learn/assets/weblogic.png)](/learn/assets/weblogic.png) WebLogic | 14c (14.1.1.0.0) | [Deployment Instructions](/learn/how-tos/wavemaker-application-deployment-weblogic-application-server/) | + +## Profile Configuration + +Set up the **configuration profile**. You can choose to use the [default profile](/learn/app-development/deployment/configuration-profiles/) configured by WaveMaker based upon the services incorporated within the app, or build a [custom profile](/learn/app-development/deployment/build-options). + +## Generate a WAR file + +You need to generate a **WAR file** of the WaveMaker app you want to deploy. WAR file can be generated either by +- Using **Export** -> select **Project as WAR** option, or +- Use **Export** -> select **Project as ZIP** and use this file to generate WAR file through [Maven Build](https://maven.apache.org/). + +:::note +Before generating the WAR file for deployment to WebSphere (for apps with JNDI profile) and WebLogic, follow the pre-processing instructions before proceeding. +::: + +[![](/learn/assets/deploy_web.png)](/learn/assets/deploy_web.png) + +Once a WAR file is generated, deploy it to [Tomcat](/learn/how-tos/wavemaker-application-deployment-tomcat/), [JBoss](/learn/how-tos/wavemaker-application-deployment-jboss/), [WebLogic](/learn/how-tos/wavemaker-application-deployment-weblogic-application-server/), or [WebSphere](/learn/how-tos/wavemaker-application-deployment-websphere-liberty-profile/).  + +## Deploy to Private or Cloud Server + +Alternatively, the WAR file may also be deployed to public or private cloud servers. To deploy an application to one of the supported clouds you will need to: + +- Acquire an account (public cloud) or install the software (private cloud) +- Create a cloud instance - a virtual machine with a standard operating system +- Install a Java web server - for example, Tomcat +- Deploy the WaveMaker WAR to the Java web server + +:::note +Instead of above steps you can instantly deploy to Amazon Web Service or to WaveMaker Demo Cloud with just a single click. [Learn about one-click deployment](/learn/app-development/deployment/one-click-deployment/). +::: + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/export-wavemaker-application.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/export-wavemaker-application.md new file mode 100644 index 000000000..5037bbe4c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/export-wavemaker-application.md @@ -0,0 +1,19 @@ +--- +title: "Export WaveMaker Application" +id: "export-wavemaker-application" +--- +--- + +When you create a WaveMaker application, you can export the application to your local machine for local development and testing purposes. You can export the project in a ZIP file and a WAR file. + +## Export project as ZIP file + +To export the project in zip, click **Export** and select **Project as ZIP**; the project files will download. + +[![project as zip](/learn/assets/project-as-zip.png)](/learn/assets/project-as-zip.png). + +## Export project as WAR file + +To export the project in war, click **Export** and select **Project as WAR**. Next, select the [configured profile](/learn/app-development/deployment/configuration-profiles). For example, WaveMaker displays default profiles; select [development profile](/learn/app-development/deployment/configuration-profiles#development-configuration-profile), or [deployment profile](/learn/app-development/deployment/configuration-profiles#deployment-configuration-profile). If you create a custom profile, select the custom profile name which displays under the **Select Profile** option. On clicking the profile, the project files will download. + +[![project as war](/learn/assets/project-as-war.png)](/learn/assets/project-as-war.png). diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/integration-with-custom-vcs-provider.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/integration-with-custom-vcs-provider.md new file mode 100644 index 000000000..13d9e2dde --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/integration-with-custom-vcs-provider.md @@ -0,0 +1,46 @@ +--- +title: "Integration with Custom VCS provider" +id: "integration-with-custom-vcs-provider" +sidebar_label: "Custom VCS Integration" +--- +--- + +:::note +Integration with custom VCS provider is only available for [WaveMaker Online Teams](/learn/teams/overview) (WMOT) and WaveMaker Enterprise (WME) users. It is not available for WaveMaker Online (WMO) single users. +::: + +## Custom VCS integration in WMO Teams + +In WMO, the custom VCS integration is available for [WMOT plan](/pricing/). During the time of app development in collaborative-development, tracking code changes and synchronizing the changes are essential. WaveMaker provides Version Control Services for this purpose. By default, WaveMaker Studio comes with a version control system that is based on Gitlab. In WMOT, you can integrate your Own VCS as Code Repository. For adding custom VCS in the code repository section, select **Add Code Repository**. + +## Supported Providers + +- [Gitlab](https://about.gitlab.com/) +- [Bitbucket](https://bitbucket.org/product) +- [Github](https://github.com/) +- [Azure](https://azure.microsoft.com/en-us/services/devops/repos/) + +- Select the TEAM PORTAL section on the top right corner. + +[![wmo-launchpad-teams](/learn/assets/wmo-launchpad-teams.png)](/learn/assets/wmo-launchpad-teams.png) + +- Select on Setup Team. + +[![wmo-wavemaker-team-portal](/learn/assets/wmo-wavemaker-team-portal.png)](/learn/assets/wmo-wavemaker-team-portal.png) + +- Select on Next. + +[![wmo-launchpad-team-profile-configure](/learn/assets/wmo-launchpad-team-profile-configure.png)](/learn/assets/wmo-launchpad-team-profile-configure.png) + + +- Select Code Repository that you want to store all your code and provide the required details. Select Save to save the changes. + +[![wmo-configure-code-repo](/learn/assets/wmo-configure-code-repo.png)](/learn/assets/wmo-configure-code-repo.png) + +- After selecting **Add Code Repository**, select the repository type and provide the required details for adding the repository. As default providers, WaveMaker supports Gitlab, Bitbucket, Github and Azure for external VCS configuration. Select Save to save the changes. + +[![wmo vcs](/learn/assets/wmo-adding-vcs-repo.png)](/learn/assets/wmo-adding-vcs-repo.png) + +## Custom VCS configuration in WME + +WME also supports External VCS as code repository. For confguring your own VCS, see [VCS configuration in WME](/learn/on-premise/configure/config-vcs). diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/jenkins-integration.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/jenkins-integration.md new file mode 100644 index 000000000..ac59b8a29 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/jenkins-integration.md @@ -0,0 +1,23 @@ +--- +title: "Jenkins Integration" +id: "jenkins-integration" +--- +--- + +WaveMaker applications are flexible for Jenkins Integrations. For setting up Jenkins as ci-cd provider for WaveMaker deployment, follow the procedure as described below. + +- For automatically pulling code during operation, integrate your code repository. +- Integrate code repository with jenkins at **Manage Jenkins** > **Configure** > *code-repository-provider*, for example, code repository-providers are Gitlab, Github, and Bitbucket. +- In the code-repositoy-providers section, provide the host URL and credentials for Gitlab repository. + +:::note +If your code repository does not exist in Jenkins, download the plugin of that respective code repository. +::: + +- Create Job for building the code and creating Docker images using Dockerfile. Keep your Dockerfile in the root folder of your application repository. For creating Docker images and container, see [WaveMaker docker build](/learn/app-development/deployment/build-with-docker). +- For creating Job select New item and select Freestyle Job. For example, we are taking a freestyle job, based on your requirements, you can choose any job. +- At source code management, select Git and configure the code repository. +- For building Docker image and pushing to Docker repository, write add your code or executable file in Execute shell for freestyle project. For pipeline project, you have to write pipeline script for the operation. If you want to build and deploy in different servers you need to push images to the repository. Build and deploy application in the same server, and no need to push to Docker repository. +- Create another job for deployment of applications. For deployment of application, use single container deployment or combination of mysql, nginx for proxy and application [using docker compose](/learn/app-deelopment/deployment/deployment-using-docker-compose), or you can use Kubernetes for deploying highly scalable and highly available application using the Kubernetes spec files. +- For automating the build and deployment process of the application, create one pipeline project and add your pipeline code at pipeline section or provide pipeline script location at remote code repository. +- We can trigger the pipeline periodically using the Build periodically option or we can trigger our pipeline based on our code pushing and commit operation to the repository by using the poll scm and webhooks triggers. diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/manage-deployed-apps.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/manage-deployed-apps.md new file mode 100644 index 000000000..ae2f72325 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/manage-deployed-apps.md @@ -0,0 +1,115 @@ +--- +title: "Manage Deployed Apps" +id: "manage-deployed-apps" +--- +--- + +WaveMaker **Apps Portal** is a place for you as the project owner to manage the deployed apps. The one-click deployment from Studio hosts the app on WaveMaker Demo Cloud using the [Deployment Profile](/learn/app-development/deployment/configuration-profiles/). Apps Portal will enable the project owner to configure phases and push the apps from one phase to the next. From this portal you can: + +1. Configure the deployment environment for each phase - Stage (WME) and Live. The configurations involves setting the various services like Database, Web Services, Security, REST Services +2. Push the app from one phase to another without the need to modify the app. Push will deploy the app into the new deployment environment. A separate URL is generated for each phase. You can version the apps for easy tracking. + +## Apps Portal + +You can access the Apps Portal in two ways: + +1. By selecting **Manage Deployed Apps** button from the Project Dashboard, +2. By using the **Manage App** option under Deploy from the Project Workspace Main Menu - this will open the app for management. + +### Manage Deployed Apps + +[![](/learn/assets/ap_opt1.png)](/learn/assets/ap_opt1.png) + +By selecting **Manage Deployed Apps** button from the Project Dashboard, you will see a list of deployed apps. + +[![](/learn/assets/apps_portal.png)](/learn/assets/apps_portal.png) + +- one the right side you can find + - the total number of apps owned by you that can be deployed; + - number of apps deployed in Demo and Live Phases; + - recent deployment activity +- you will also find cards for the deployed apps, + - the last deployment activity for that app, + - if live, the version that is live and the date it was deployed to live +- you can select any app from the listing for management for more details.[know more](#manage-deployed-app). + +### SSL Enabled Demo Cloud + +:::note +From [10.14.0 release](/learn/wavemaker-release-notes/v10-14-0), WaveMaker introduced SSL for Deployed Apps to [Demo Cloud](/learn/app-development/deployment/pipelines-phases#deployment-environment). +::: + +Demo and QA deployments in WaveMaker use secure protocol HTTPS, which is SSL enabled, and therefore, the app is accessible with a URL pattern as follows. + +### SILO workspace (WMO Personal workspace) + +**URL**: `http://cloud.wavemakeronline.com/pk8888888n45/TestApp` + +**Updated to**: In the URL, `pk8888888n45` is a Project key. + +### Teams and Enterprise (WMO/WME) + +**URL**: `http://cloud.wavemakeronline.com/wmshowcase/TestApp` + +**Updated to**: `wmshowcase` is the WaveMaker Online team's name and WaveMaker Enterprise's name in the URL. + +:::important +**Impact**: With this change, the existing app URLs do not work. Thus, the users can get updated URL from the Apps portal or deployed apps. You are required to update app URL in all the places where it is used for redirection. For example, when configured as OAuth redirect URL, or when used in other apps as API URL. +::: + +### Manage App + +By using the **Manage App** option under Deploy from the Project Workspace Main Menu - this will open the app for management. + +:::note +This option will be available only for deployed apps. +::: + +[![](/learn/assets/ap_opt2.png)](/learn/assets/ap_opt2.png) + +## Deployed Apps Management + +Selecting an app from the App Portal or Manage App from Project Workspace will give you the details about the app. You can view the deployed app details. + +[![](/learn/assets/MA_deploy_details.png)](/learn/assets/MA_deploy_details.png) + +At DB shell user can perform database operations. +[![](/learn/assets/DB-shell.png)](/learn/assets/DB-shell.png) + +1. From the header you can + - **open** the deployed app URL + - **stop** the deployed app, this will disable the deploy URL + - **restart services** like Tomcat etc.. +2. view the **logs** with an option to view the entire log or download it. +3. connect to **DB shell** and export/import database. +4. view the app configuration **profile**, you will be able to view the configurations of all the services used within the app like the database, web services, security etc. +5. Open **Integration Tests** if user have test coverages. +6. At **webhook** user can add integrate external tools like jenkins for ci/cd +7. At **history** user can check the deployment history + +## Release History + +Once application is deployed, you can view the current release along with release notes and the latest history. You can view all releases/history. + +[![](/learn/assets/ptl_cloud_done.png)](/learn/assets/ptl_cloud_done.png) + +Hover over the Live card to visit the Details page or launch the app. Selecting the **Details** page allows you to: +- view the app details. Here, you can further: + - **open** the deployed app URL + - **stop** the deployed app, this will disable the deploy URL + - **restart services** like Tomcat etc.. + - **delete** your apps association with the provider + - **CPU** and **Memory Usage**of the app + - **view a brief history** with the option to view complete history + - view the app configuration profile, you will be able to view the configurations of all the services used within the app like the database, web services, security etc. +- view the logs with an option to view the entire log or download it. +- view the provider details. For AWS/Azure/Google Cloud provider you can download the key pair .pem file. You can also edit the key pair by uploading a new .pem file. **Note:** this option is available for phases configured on AWS or Azure Cloud or Google Cloud. +- connect to DB shell and export/import database. +- view the deployment history + +## App Versioning + +Once you have deployed and pushed the app to Stage and Live Phase, for various reasons like enhancements or due to requirement changes, your app can undergo changes. You can deploy the app with a change in version number. **Note** this will overwrite the previous version in Stage phase. +[![](/learn/assets/apver_update.png)](/learn/assets/apver_update.png) + [![](/learn/assets/apver_portal.png)](/learn/assets/apver_portal.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/one-click-deployment.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/one-click-deployment.md new file mode 100644 index 000000000..1c76f9e3d --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/one-click-deployment.md @@ -0,0 +1,77 @@ +--- +title: "One-Click Deployment" +id: "one-click-deployment" +sidebar_label: "One-click Deployment" +--- +--- + +One-click Deployment deploys an app to the cloud setup with just a single click which deploys to the WaveMaker demo cloud. Before you deploy an app, you should ensure the build and the application security settings are properly configured by following the below two checks. + +1. [Configure Deployment Profile](/learn/app-development/deployment/deployment-profile/) +2. [Push to VCS](#push-to-vcs) + +## Configure Deployment Profile + +Deployment configuration profile uses various service configurations like the database, REST, SOAP, Web Socket, and Security. These settings can be modified from [Deployment Profile](/learn/app-development/deployment/deployment-profile/) under the **Project Settings** dialog. Check these settings before deploying an app. + +## Push to VCS + +Apps are deployed only under the version control system. If you have not pushed your apps changes to the VCS, you will be prompted to do so. You cannot proceed with deployment until you commit your changes. + +## Deploying an App + +By clicking on the **Deploy** icon; it initiates the deployment process and starts [checking for errors](/learn/app-development/dev-integration/inspection-framework) in the application. + +[![deploy icon](/learn/assets/deploy.png)](/learn/assets/deploy.png) + +:::note +Ensure to push your latest changes to VCS before **One-click deployment**. Also, if you are deploying the app for the first time, check the configuration profile settings. For more information, see [Deployment Overview](/learn/app-development/deployment/configuration-profiles). +::: + +## Deployment Flow + +Once you initiate the deployment, the deployment runs in the background. You can choose to **close** the Deployment progress dialog and continue working with Studio. + +### Deployment Status + +You can see the status of the deployment through the `toaster UI`. If you work on the same project, after the deployment, you get notified by an email. + +### Deployment Progress + +The progress of the Deployment is indicated by the change of deployment icon on the header as shown below, and by clicking the icon, you can see an option to **Check Deployment Status** allowing you to open the dialog again. + +![deployment-status](/learn/assets/Check-deployment-status-Click-e1554896395542.png) + +### Deployment Failed + +If the deployment fails, you can fix the code errors by using [Inspection Framework](/learn/app-development/dev-integration/inspection-framework) and [redeploy](#redeploy) the app. + +![deploy failed](/learn/assets/deploy-failed.png) + +### Deployment Success + +After [successfully deployment](/learn/app-development/deployment/one-click-deployment#deployment-flow), you can access the app via the application demo URL. Deployed apps host on WaveMaker [Demo](/learn/app-development/deployment/release-management#demo) cloud. You can [Manage Deployed Apps](/learn/app-development/deployment/manage-deployed-apps/#apps-portal), or **View the Deployed App**. To further configure release pipelnes, see [CI/CD Pipeline in WaveMaker](/learn/app-development/deployment/release-management). + +![Deployment-flow-changes](/learn/assets/Deployment-flow-changes.png) + +## Deployment to Cloud + +After the deployment, you can perform the following three actions. + +### Redeploy + +You can redeploy the app if needed. Any redeployments will be directed to the [Demo (QA) phase](/learn/app-development/deployment/release-management/#demo). + +### Launch Deployed App + +Launches the app in a browser. + +### Manage App + +You can push the deployed app to live and other phases. This option opens the [Apps Portal](/learn/app-development/deployment/manage-deployed-apps#deployed-apps-management) page. + +![cloud post deploy](/learn/assets/cloud_postdeploy.png) + +## See Also + +[One-click Deployment Flow](/learn/app-development/one-click-deployment-process) diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/phase-configuration.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/phase-configuration.md new file mode 100644 index 000000000..06c78061e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/phase-configuration.md @@ -0,0 +1,33 @@ +--- +title: "Phase configurations" +id: "phase-configuration" +--- +--- + +WaveMaker supports two phases for WMO and three phases for WME customers. One-click deployment by default deploys to Demo or QA phase. To deploy an application on different phases, you should push the application from one phase to the other phase. For pushing the application to the next phase, you have to configure the phases. Firstly, you should select a cloud provider and configure that for each phase. + +:::note +Before configuring the phases, you should configure the pipeline. For WMO, see [WMO default pipeline configuration](/learn/app-development/deployment/default-pipelines). For WME, see [WME pipeline configurations](/learn/app-development/deployment/configure-pipelines). +::: + +## Configure Phases + +During the process of pushing from one phase to the other phase, you can configure different Databases for different phases and also configure Rest, Soap, and Web socket services as shown in the image below. + +[![phase Database configurations](/learn/assets/ptl_configure.png)](/learn/assets/ptl_configure.png). + +## Phases Configuration Profile + +You can enable and disable SSL configuration at the security settings page and also configure necessary security options. Additionally, you can configure Outh2, App Environment, and Build options. For more information, see [Configuration Profiles](/learn/app-development/deployment/configuration-profiles) and [Deployment Profile](/learn/app-development/deployment/deployment-profile). + +[![phase security configurations](/learn/assets/phase-security-config.png)](/learn/assets/phase-security-config.png). + +:::tip +You can also mention the version number and release notes for tracking purposes. +::: + +[![versioning](/learn/assets/ptl_version.png)](/learn/assets/ptl_version.png) + +For more information, see [Manage Deployed Apps](/learn/app-development/deployment/manage-deployed-apps). + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/pipelines-phases.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/pipelines-phases.md new file mode 100644 index 000000000..febb327f1 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/pipelines-phases.md @@ -0,0 +1,70 @@ +--- +title: "Pipelines and Phases" +id: "pipelines-phases" +sidebar_label: "Pipelines and Phases" +--- +--- + +WaveMaker **Release Pipeline** enables setting up the App deployment phases for easier delivery by leveraging Docker containerization. Setting up an App deployment phase requires the following. + +- Provisioning of the infrastructure +- Installing the required software components +- Setting up the network +- Configuring the services +- Scripts to automate the service startups and app deployment + +Release Pipeline combines the power of Docker-based WaveMaker Cloud to configure app deployment phases cutting down on the work involved in DevOps and making the App Delivery rapid. + +## Deployment Environment + +All of the above-mentioned release management tasks are facilitated within WaveMaker through a **Deployment Environment**. A deployment environment is provisioned with all the required services, such as Web Services, database services, and the dependent services, for the application to be fully functional and available. Each deployment environment requires a bunch of containers to be provisioned and setup. + +WaveMaker Platform offers a pre-defined set of App delivery phases which enables App progression through multiple phases. At each phase, App is accessible using a unique URL. Each App phase can be setup to use WaveMaker Cloud leveraging Docker containerization or for Stage and Live phases to run on a public cloud like AWS. + +:::note +For WME, [Configure Pipeline](learn/on-premise/configure/config-pipeline) before doing deploying an app. For WMO, use [WaveMaker Inbuilt Pipeline](/learn/app-development/deployment/default-pipelines) configuration with default phases including **Demo** and **Live**. +::: + +## WaveMaker Online (WMO) + +### Demo + +This is the phase where the app gets deployed when you click **Deploy** from your Project Workspace. It uses the deployment configuration profile for the services set at the time of app development. + +### Live + +This phase can be set up as per your app requirements and would ideally contain the live deployed app. It needs to be configured from **Apps Portal** before the app can be deployed or pushed. + +## WaveMaker Enterprise (WME) + +### QA + +This is the phase where the app gets deployed when you click **Deploy** from your Project Workspace. It uses the deployment configuration profile for the services set at the time of app development. + +### Stage + +This phase can be set up as per your app requirements. It needs to be configured from Apps Portal before the app can be deployed/pushed to this phase. + +### Live + +This phase can be set up as per your app requirements and would ideally contain the live deployed app. It needs to be configured from **Apps Portal** before the app can be deployed or pushed. + +:::tip +With **one-click deployment**, **apps portal** and **versioning of deployed apps** the various aspects of the release pipeline specified in the above sections are made simple and easy to implement. +::: + +## One-Click Deployment + +Using the Deploy option from Project Workspace, your app is deployed to WaveMaker Cloud. It takes care of the configuration for all the required services needed for deploying to the Demo or the QA phase. For more information, see [One-click Deployment](/learn/app-development/deployment/one-click-deployment/). + +## Apps Portal + +Apps Portal provides a platform to manage the deployed apps. By default, there are two phases - Demo and Live. These are provided for any WaveMaker app. WME users can utilize an additional Stage phase. Each phase can have its own infrastructure and versioning configuration. Before pushing the deployed app to the next phase, the phase configuration profiles can be set, or else the profiles from the previous phase are retained. For more information, see [Apps Portal](/learn/app-development/deployment/manage-deployed-apps/#apps-portal). + +## App Versioning + +Most app development is incremental which means different phases will be hosting the app in various levels of the development. The developer will be working on the latest version, while the **Live** version would be at least one step behind. In such cases, the versioning system comes in handy. + +In WaveMaker, the app in the **Demo** phase will be the last version deployed from the Studio. When pushing from **Demo** to other phases, you have the option to change the version for better tracking and control of the system. + +For more information, see [App Versioning](/learn/app-development/deployment/manage-deployed-apps/#app-versioning). diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/pull-request-flow.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/pull-request-flow.md new file mode 100644 index 000000000..b502e01ff --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/pull-request-flow.md @@ -0,0 +1,73 @@ +--- +title: "Pull Request Flow for Custom VCS" +id: "pull-request-flow" +sidebar_label: "Pull Request (PR) Flow" +--- +--- + +Pull Request (PR) Flow is a process used in collaborative software development where a contributor submits changes to a project's main codebase for review before merging them. + +Now, in WaveMaker, you can enable the same PR Flow to get your project changes pushed to the development branch of the Version Control System (VCS) like, Bitbucket, GitHub, and GitLab. PR Flow mainly contributes to better teamwork and code maintainability. + +:::note +PR Flow is applicable for the [Teams](/learn/teams/overview/) users only. +::: + +In this case, we use two user roles to implement PR Flow. + +### Developer + +- [Enables the PR Flow for VCS](#enabling-the-pr-flow). +- [Creates Pull Request](#creating-pull-request). +- [Addresses Reviewer's comments](#addressing-feedback). + +### Reviewer + +- Verifies changes in the pull request and provides necessary feedback. +- Once feedback comments are addressed by the developer, the reviewer approves and merges changes to the Remote Tracking Branch (RTB). + +## Enabling PR Flow + +[Developer](#developer) enables the PR Flow option to allow merging changes to the main branch. This option is disabled by default, which pushes changes to the remote branch. + +1. Go to [Team Portal](/learn/teams/overview/). +2. Navigate to the [Code Repository](/learn/teams/code-repository) page. +3. Click **Settings** option to open the settings dialog for the configured Code Repository. +4. Enable **Pull Request** and provide a value for **Pull Request Developer Branch Pattern** for creating a developer branch. For example, the default branch pattern is `dev-{EMAIL_PREFIX}-{TENANT_DOMAIN_NAME}/{REMOTE_BRANCH_NAME}`. Click Save. + + + +Assuming that the [developer](#developer) makes changes in the project within WaveMaker studio after enabling PR Flow; a pull request is created to push those changes. + +## Creating Pull Request + +[Developer](#developer) creates a pull request for local changes made in the project by pushing them to the development branch. + +1. Go to the project with changes and click **Push Changes** from the VCS drop-down menu. This creates a temporary developer branch with project changes. +2. Add Commit Message and click **Ok** to confirm. +3. After a successful push action **Pull Request Submission** dialog will be opened, click **Proceed**. +4. [Developer](#developer) gets redirected to the **Create Pull Request** page of the selected Code Repository. In our case, we can see in Bitbucket where we first confirm the **Source** branch details and click **Continue**. +5. Click **Create** to submit the Pull Request. +6. Go to WaveMaker studio > VCS drop-down. Click the **Commit History** option to view **Pending Pull Request Changes** and **Merged Changes** in the Commit History dialog. + + + +After successful pull request creation, [Reviewer](#reviewer) verifies the changes committed in the pull request and provides the necessary feedback. + +## Addressing Feedback + +[Developer](#developer) addresses the feedback from the [reviewer](#reviewer) by making fixes in the studio and pushing the changes to the development branch. + +1. Go to WaveMaker > VCS drop-down > **View Changes**. +2. In the **View Project Changes** dialog, you can compare the **Workspace changes** with the **Last Pushed Changes**; this shows the changes that are not pushed to the development branch. You can also compare the **workspace changes** to the **master** branch; this comparison with Remote Tracking Branch (RTB) displays all the changes done so far. + + + +:::note + +[Developer](#developer) can restore the workspace to the main branch, RTB, by navigating to VCS > View Changes > **View Project Changes** dialog. Click the **Restore to Remote Branch** to discard the changes that were pushed after the previously merged changes. + +![Restore to Remote Branch](/learn/assets/pr-flow/restore-to-remote-branch.png) +::: + +Once the comments are addressed the [reviewer](#reviewer) approves the changes and merges them to the main branch, RTB. diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/push-code-to-external-repo.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/push-code-to-external-repo.md new file mode 100644 index 000000000..da752011a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/push-code-to-external-repo.md @@ -0,0 +1,19 @@ +--- +title: "Push Code to External repo" +id: "push-code-to-external-repo" +--- +--- + +WaveMaker provides a default code repository from Gitlab. For convenience, you can choose to have a copy of your project code in an external repository. For pushing code to an external repository, select the **VCS** option from the studio page, and click **Push to External Repo** as shown in the image below. + +[![external repo](/learn/assets/external-repo.png)](/learn/assets/external-repo.png) + +## Configuring Code Repositories + +WaveMaker supports different code repositories on cloud and non-cloud environments. For pushing code to an external repository, you should configure a repository with details including username, password, URL, and branch to push. For pushing the code to an external repository, create a repository for an application before pushing it to an external repo. + +:::important +To learn more about the configuraton, see [Push to External Repo Configuration](/learn/app-development/dev-integration/developer-collaboration/#push-to-external-repo). +::: + +[![external repo config](/learn/assets/external-repo-config.png)](/learn/assets/external-repo-config.png) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/release-management.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/release-management.md new file mode 100644 index 000000000..be1fbc630 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/release-management.md @@ -0,0 +1,31 @@ +--- +title: "Release Management" +id: "release-management" +sidebar_label: "Overview" +--- +--- + +**Release management** is a software engineering process for managing the application development, testing, deployment, and support of the application version release. Release Management helps you to plan, schedule, and control the movement of releases to test and live environments. It ensures the delivery of the new enhanced app services while also protecting the integrity of the existing services. + +[![release_pipeline](/learn/assets/release_pipeline.png)](/learn/assets/release_pipeline.png) + +A typical app life cycle involves various phases including development, testing, and deployment before the App is live. A **Deployment** or **Release Pipeline** requires setting up these phases to the respective teams to prepare the app for the delivery process. + +The following phases involve different roles within an app engineering team for successful app delivery. + +1. **Dev** - Used by the developers while building the app for testing. +2. **QA or Demo** – Normally used for integrating test cases allowing collaborators to add their integration pieces or to do a demo of an app to stakeholders or to get an approval of the application features. It can also be used for end-to-end testing of the app by the QA team, verifying feature completeness, run automated tests and more. +3. **Stage** – Used for pre-live demos, approvals from business teams, performance, and User Acceptance Testing (UAT). +4. **Live** – The environment where the App is accessible to the end-users. + +Each App phase as depicted above requires its own infrastructure components to run the services accessible to the different roles within the app development team. That is, each App phase requires different configuration for databases, environment, varying sizing needs, and more. These infrastructure needs are the responsibility of the DevOps team; therefore, it is their responsibility to set the following requirements. + +- Set up an appropriate infrastructure for each phase +- Set roles and have access to each phase +- Secure each phase +- Ensure the smooth transition of the project between phases with minimum app changes +- Control versioning during the transition + +## See Also + +[Pipeline and Phases](/learn/app-development/deployment/pipelines-phases) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/tests-integration.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/tests-integration.md new file mode 100644 index 000000000..4a8993f23 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/tests-integration.md @@ -0,0 +1,13 @@ +--- +title: "Tests Integration" +id: "tests-integration" +--- +--- + +Using the integration tests, you can trigger test automation for your application. To configure test automation, select **Details** at the application phase, and select the **Integration Test** tab. + +[![test integration](/learn/assets/test-integration.png)](/learn/assets/test-integration.png) + +To configure the integration, select **Configure** and then select **Add Provider** for providing the Name, URL, and API token/password. WaveMaker inbuilt supports **Ghost Inspector** and **Jenkins** integration. + +[![test integration configure](/learn/assets/test-integration-configure.png)](/learn/assets/test-integration-configure.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/deployment/webhooks-integration.md b/website/versioned_docs/version-v11.8.5/app-development/deployment/webhooks-integration.md new file mode 100644 index 000000000..32c5ca6c2 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/deployment/webhooks-integration.md @@ -0,0 +1,18 @@ +--- +title: "Webhooks Integration" +id: "webhooks-integration" +--- +--- + +For automated communication with other applications or resources, you can integrate webhooks for your application. Find webhook integration at your application details of each phase. + +[![webhook integration](/learn/assets/webhook-integration.png)](/learn/assets/webhook-integration.png) + +To configure webhook at configure option, select **Add Webhook**. WaveMaker supports two types of webhooks. + +1. WaveMaker +2. Custom + +For configure webhooks, you have to provide required at webhook configuration details as shown in the image below. + +[![webhook configuration](/learn/assets/webhook-configuration.png)](/learn/assets/webhook-configuration.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/dev-integration/chrome-developer-tool.md b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/chrome-developer-tool.md new file mode 100644 index 000000000..9d9920cab --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/chrome-developer-tool.md @@ -0,0 +1,72 @@ +--- +title: "Google Chrome Extension: WaveMaker Devtool" +id: "chrome-developer-tool" +sidebar_label: "Chrome Extension: Devtool" +--- +--- + +**WaveMaker Devtool** is a Google Chrome extension, an addition to the existing Google Chrome developer tools that allow you to debug and monitor WaveMaker applications in preview mode. Accessible via the **Inspect** option. + + +:::note +WaveMaker Devtool supports [WaveMaker 10.14.0](/learn/wavemaker-release-notes/v10-14-0) and later. +::: + +## Devtool Installation + +**Devtool Extension: [Devtool](https://chrome.google.com/webstore/detail/wavemaker-devtool/niakeolhkmomhekokhdbfiaebkganjnk)** + +### Prerequisites + +- Google Chrome browser +- Be Logged into WaveMaker to view the logs + +### Who can use WaveMaker Devtool + +All WaveMaker users who use Google Chrome to preview the application can install the **WaveMaker Devtool** extension and use it. + +## Why WaveMaker Devtool + +Typical challenges that WaveMaker application developers experience while debugging include: + +1. Developers have to go through many application logs when an issue is observed; for example, when adding new changes to the application, the page does not load. +2. Developers often miss immediate details of the issue to determine which variables are responsible for the request and fix the encountered issue. + +[![](/learn/assets/extension.png)](/learn/assets/extension.png) + +## How Devtool can help + +WaveMaker Devtool Chrome extension helps ease the debugging process and improve the application performance. Once you install the extension and preview a WaveMaker application on Preview mode, you can: + +1. View the duplicate requests triggered on the page using the **Show only duplicates** option. +2. Find the **Variable** associated with each request along with the request URL. +3. You can switch to **All APIs** to view all the requests triggered by the page. By default, the page shows **App APIs**. + +[![](/learn/assets/show-only-duplicates.png)](/learn/assets/show-only-duplicates.png) + +## Enabling Logs + +To enable logs, include the following code snippet in the `log4j2.xml` file in the src folder under the **FileExplorer** panel. + +```js + + + + + + + + +``` + +[![](/learn/assets/log4j2.png)](/learn/assets/log4j2.png) + +## Enabling WaveMaker Devtool in Incognito mode + +WaveMaker Devtool can be accessed in Incognito mode with 2 simple steps + +1. To enable Incognito mode at extension level, refer [here](https://support.google.com/chrome/a/thread/140546132?hl=en&msgid=141422566) + +2. To enable WaveMaker Platform cookie for WaveMaker Devtool, refer **Allow or block cookies for a specific site** section [here](https://support.google.com/chrome/answer/95647?hl=en&co=GENIE.Platform%3DDesktop#zippy=%2Callow-or-block-cookies-for-a-specific-site) + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/dev-integration/debugging.md b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/debugging.md new file mode 100644 index 000000000..9902bb330 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/debugging.md @@ -0,0 +1,84 @@ +--- +title: "Debugging" +id: "debugging" +--- +--- + +Many times you might get stuck with a situation wherein your app does not respond the way you intended it to or throws an error that is particularly difficult to solve. In such cases debugging comes in handy. There are two ways to debug a WaveMaker app: + +- using logs or +- using debug option from JavaScript. + +## Using Logs for Debugging + +Log files can be accessed from the project workspace footer area. There are types of logs that are recorded - Server, and Application. These can be accessed from the [Developer Utilities](/learn/app-development/wavemaker-overview/product-walkthrough/#project-workspace) menu for an application. + +[![](/learn/assets/logs.png)](/learn/assets/logs.png) + +### Server Logs + +Server logs consist WaveMaker designer backend logs while developing the app. For example: On importing/updating database, sometimes a message saying `error while updating/importing database please see server logs `is displayed. In such cases, Server logs contain stack trace of error, along with the cause. + +You can download the log files using the download icon in the far right corner of the logs window. This option is available for both server and application logs. + +[![](/learn/assets/logs_server.png)](/learn/assets/logs_server.png) + +## Debugging with HAR files + +Sometimes, in order to debug a problem WaveMaker support team may ask you to send the HAR file. To obtain the HAR file: + +1. From the app runtime window, open the **Developer Tools**.  Access to the Developer Tools varies from browser to browser. + For example, in Chrome Browser you will be using the Chrome menu **(:)** -> **More tools** -> or use a key pattern `Ctrl + Shift + I`. +2. From the Developer Tools panel select the **Network tab**. +3. Select the option to **Preserve Log** +4. Refresh the page +5. Right-click on any Network call and choose the option **Copy** -> **Copy all as HAR** + +[![](/learn/assets/logs_har.png)](/learn/assets/logs_har.png) + +6. Open any editor like Notepad and paste the content. +7. Save the file and send it to the support team along with the name of the Service call that is failing. + +## JavaScript Debugging + +To debug the JavaScript code of the pages, add keyword _debugger_ in the script part of the page. Example: Suppose we want to debug the function on click of a button ‘button2’. +``` +Page.button2Click = function ($event, widget) { + var postion = $event.pageX; + debugger; +}; +``` +Instead, if you want to just print the results in the console use the method ‘console.log()’. Example: Suppose we want to print the results of a dataset. +``` +Page.button2Click = function ($event, widget) { + console.log(Page.Variables.HrdbEmployeeData.dataSet) +}; +``` +There are more methods of how you want to print the results in the console. For more detailed information refer to the product documentation of the browser you are running your app on. + +Once you have the debugger in place, run the app and open the developer tools. The method of accessing developer tools differs from browser to browser. + +For example, in **Chrome** use Function Key 12 (F12) or use the key pattern ‘_Ctrl + Shift + i_’ to open the developer tools. + +### For debugging + +In the developer tools window select on ‘_Sources_’ tab. During the script execution when the script reaches that line containing the debugger statement, it would stop the script execution and provide us options to debug the script. F10 will move the script execution to next method and F11 will move the script execution to next step. + +### Console logs +Click on the `console` tab, to see the results printed when the script is executed. + +## Debugging Deployed Apps + +In case you want to debug deployed apps or to send logs for the deployed app to WaveMaker support team you might have to download the logs for deployed apps. In such cases + +1. Open Apps Portal + - by selecting Manage Deployed Apps button from the Project Dashboard, or + - by using the Manage App option under Deploy from the Project Workspace Main Menu and then selecting the app in question. +2. Once you have opened the app, hover over the phase for which you want the logs, select DETAILS. + +[![](/learn/assets/apps_portal_liveapp.png)](/learn/assets/apps_portal_liveapp.png) + +3. Select the Logs tab and locate the download button to download the logs. + +[![](/learn/assets/logs_deployed.png)](/learn/assets/logs_deployed.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/dev-integration/developer-collaboration.md b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/developer-collaboration.md new file mode 100644 index 000000000..17b9020eb --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/developer-collaboration.md @@ -0,0 +1,146 @@ +--- +title: "Developer Collaboration" +id: "developer-collaboration" +--- +--- + +Developer Collaboration includes two steps: + +1. Sharing the project and dividing the work between multiple contributors, and +2. Tracking and keeping up to date with the changes made by these collaborators. + +In this document, we will be seeing how this can be achieved for WaveMaker. + +## Project Sharing + +Project Sharing ensures that you do not lose any changes made by the developer network by tying your app into a version control system. You can start collaborative development, by, from the **Project Dashboard**. + +- Click on Members link on the Project card to view the App Member Details, add and remove **Members** having access to the project. + +[![](/learn/assets/user_management_add.png)](/learn/assets/user_management_add.png) + +## Add members + +- By default, the owner of the project is assigned the role of a Project Admin. +- Project Admin can add members to the Project, these new members are assigned the Default role which gives them read access. +- Enter the email id of the Member you want to add as Project Admin or Contributor in the appropriate text box and click the **Add** button. This feature is available only to the Project Admins. +- **Multiple Project Admins and contributors** can be added to the project. + +:::note +One need not be on the same email domain to collaborate on the project. +::: + +## Change Roles + +- Once the user is added as Project Admin/Contributor, the role can be changed. To change the role of the existing member, click on More options and select Add as Project Admin/Add as Contributor option. +- It opens a  confirmation dialog saying `` role will be changed from `` to in ``. Click OK button to confirm. + +[Refer here](/learn/app-development/wavemaker-overview/project-user-management/#roles) to know more about the Roles. + +:::note +Only the Project Admins are allowed to change the roles. +::: + +## Delete a member + +- The Project Admin can remove a member from the project using Remove option. The owner, who created the project cannot be deleted. However, the owner's role can be changed to a contributor. +- It gives a confirmation dialog box, stating whether the `` needs to be removed from the `` + +## Delete project + +- From the Project card, you can leave or delete the project from the Leave project/Delete option on the project. + +## Code Sharing - VCS + +When multiple developers are working on the same application, tracking code changes and synchronizing the changes is of the essence. WaveMaker provides Version Control Services for this purpose. + +**Version control** is the process of tracking and controlling changes to a project's files, which includes source code, documentation, and web pages. Subversion and Git are examples of such version control systems. + +WaveMaker includes an integrated version control system. When you open a project it is checked out from the version control repository. You can pull, push, revert and merge changes back to the repository. WaveMaker version control system by default is hosted on **GitLab**. You can choose to push your code to an external VCS, too. + +From the Project Listing page, you have the option to **restore** your project to the repo version, thus replacing your local copy of the project with the one in the repo. + +Also, in the project workspace, you will find that a **VCS Menu** is displayed for projects. + +[![](/learn/assets/vcs_menu.png)](/learn/assets/vcs_menu.png) + +## Version Control System + +### Checkout Project + +Once you start working on a project, i.e. open it from the Project Dashboard, the project is checked out from the repository. Any changes made to the project will be saved on your local machine. To ensure that the changes are reflected in the repository, one needs to explicitly push the changes to the repository. + +### Pull Changes + +1. On your project listings page, a notification will indicate when your team collaborator has pushed any changes to the shared project. +2. On the project workspace of a checked out project, from the **VCS** menu, select **Pull Changes**. +3. This will ensure that your local copy of the project gets the latest copy of the project. + +### Push Changes + +1. On the project workspace of a checked out project, from the **VCS** menu, select **Push Changes**. +2. The **Push Changes** dialog is displayed, where you need to enter the Commit Message. + + There are two parts to the Commit Message. + + 1. Mandatory commit message to be entered by the developer, and + 2. Auto-populated message based on New Files Added, Files modified and Removed files categories. Any of these categories will be shown if there are any files related to that category. When there are no changes in the project, the auto-populated message will be displayed. + +3. Enter a Commit Message summarizing your changes and click on **OK** to check in the changes you have made to the project code back to the repository. + +### View Changes + +View Changes enables you to see the code difference. If you wish to undo the changes that you have performed on a project that you have checked out, you can revert changes to all or some of the files using the revert changes option. + +1. On the project workspace of a checked out project, From the **VCS** menu, select **View Changes**. + + The changes made to your project will be displayed: + + - categorized, based upon the functionality and folder structure, into Pages, Services, Prefabs, Folders and standalone files; + - you can choose the category to revert the changes. All the files in the categorized sections will follow the atomicity rules - the action can be taken in all or no files for both ADDED and DELETE operations. However, for cases where the files are modified, the user is provided an option to REVERT the files individually within the category. + +2. Click the **Show Diff** icon against the file you to see the code changes, with conflicts clearly marked. You can choose to revert or save the changes. +3. You can also select the files that you want to revert changes for and click **Revert**. The project reloads after reverting your changes. You can also use the select-all option on the dialog to revert all the changes across the project. + +### Merge Changes + +When you perform a pull or a push operation, you may have to merge files and resolve conflicts resulting from the changes by other team members or developers. WaveMaker will prompt you with a **Merge Files** dialog to merge files and resolve conflicts when you try to Push changes. You can also click on **Merge Files** from the **VCS** menu to merge files and resolve conflicts. + +The **Merge Files** dialog displays a list of files which need to merge. For each file, it displays the changes from the server, local changes and a merged result alongside to compare the differences. The merged result is shown in the center. The dialog also displays conflicting and non-conflicting changes in different colors to make merging easier. You can select multiple files and apply the same behavior to all. You can choose to Discard Pull Changes and revert back to the original version. + +There are three ways to merge files: + +- **Accept only server changes**: Review the changes and click **Accept Theirs** button to accept only server changes. +- **Accept only your changes**: Review the changes and click **Accept Yours** button to accept only local changes. +- **Resolve Conflicts**: Each change has a corresponding region next to it which links it to the merged result. You can click on a region to exclude the corresponding changes from the merged results. You can even edit the merge results to make changes to the code manually. Once you are satisfied with the merged result (displayed in the center), click **Apply** to accept the merged result. + +:::note +Currently, Merge Files supports code level merges and the user is expected to know about the generated code of the project. +::: + +### Commit History + +**Commit History**  option under VCS shows history (git log) of last 10 commits with the following information: + +- Commit Time and Date, +- Author, +- Commit Message + +You can navigate through the older and newer commits by 10 commits each time by clicking on Older and Newer buttons. + +### Push to External Repo + +You can choose to have a copy of your project code in an **External Repo**. WaveMaker supports GitHub, Bitbucket and any Git repository. This functionality is available only for Project Admins. + +Select the **Push to External Repo** option from the **VCS Menu**. You will be prompted to choose from three options: **GitHub**, **Bitbucket** or **Git Repo**. Provide the credentials of the selected repo and the project code will be **pushed** to that repo using the credentials provided. + +[![](/learn/assets/VCS_ExtRepo.png?v=20)](/learn/assets/VCS_ExtRepo.png?v=20) + +You can specify the branch to which the project needs to be pushed. In case the branch does not exist, one will be created. When using an existing branch, keep in mind that the folder structure of the selected branch should match the code being pushed. You can optionally choose the branch from the list provided. + +:::important + +- This option is available only to PUSH to the external repo, it does not update the project on WaveMaker with the code from the external repository. +- For using GitHub or Bitbucket, you should be having an account by registering with either of them. If no URL is provided one will be created for you. +- To work with the **Git Repo** Repository URL is mandatory, you have to create the repo and provide the URL. +::: diff --git a/website/versioned_docs/version-v11.8.5/app-development/dev-integration/developer-tools.md b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/developer-tools.md new file mode 100644 index 000000000..f5bc140a7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/developer-tools.md @@ -0,0 +1,32 @@ +--- +title: "Test and Run (Preview) Apps" +id: "developer-tools" +--- +--- + +Once the design and building an app is completed, it needs to be tested. The easiest way to test an application is to click the **Preview** button from WaveMaker Studio. When you click **Preview**, you are given a URL for the web application that can be accessed by anyone in your network (e.g., by anyone inside your network firewall). + +## Preview Application + +### Preview + +**Preview** is recommended only for test or trial purpose as the application is deployed to the WaveMaker server provided with WaveMaker Studio. When you stop WaveMaker Studio, using the WaveMaker console, the application stops too. + +- Click **Preview** will run the application in a new browser window. +- The app will open the page within the app from where you clicked the Preview button. In case the app is secured, then you will be prompted to login and based on the permissions you will be redirected to the appropriate page. +- An **Application Preview** will be displayed, where one can select the **target device** to run the app. This will give you an idea of how the app looks on various devices like various laptop, tablet, and phone sizes. +- **QR code** is also displayed which can be used to access the app on a mobile device with ease. You can choose to remove this preview toolbar if not needed. + +[![](/learn/assets/app_preview.png)](/learn/assets/app_preview.png) + +### Application Runtime + +The application will then open with a URL in the following format: `https://www.wavemakeronline.com/unique-id/app-name/login.html#/login` Here are the elements of the generated URL: + +- **www.wavemakeronline.com**: URL of WaveMaker Cloud where applications are hosted. +- **unique-id**: Name of the application space that you provide while registration. It is unique to a user. +- **app-name**: Name of your application, which is the same as the name of your WaveMaker project. You can change this by setting the _context root_ parameter during the application deployment +- **login.html**: A default start page for applications with security enabled. If you are not using security, this will not be part of the URL. Instead, your URL would be: `https://www.wavemakeronline.com/unique-id/app-name/#/Main` + +As long as your project is running in WaveMaker Studio, it will be available to other users. If you close the project or log out of WaveMaker Studio, it will become unavailable. When you open a new project within WaveMaker Studio the current project is closed. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/dev-integration/extending-application-using-ides.md b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/extending-application-using-ides.md new file mode 100644 index 000000000..84b7cdb24 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/extending-application-using-ides.md @@ -0,0 +1,88 @@ +--- +title: "Extending the Application using IDEs" +id: "extending-application-using-ides" +--- +--- + +When you want to extend and maintain your code, you may want to work on a local machine text editor, make changes and import these changes back into your application. Or, you may want to work on an IDE of your choice and take advantage of its Java code editing, testing and debugging features. In WaveMaker all this can happen easily as a modular client-side code (AngularJS, CSS, and HTML) incorporating industry best practices. In this section, we list the steps for the same. + +:::note +Alternatively, you can use the WorkSpace Sync Plugin to ease this process. [See here for details](/learn/how-tos/synchronizing-wavemaker-apps-ides-beta). +::: + +[![](/learn/assets/export_project1.png)](/learn/assets/export_project1.png) + +[![](/learn/assets/export_project3.png)](/learn/assets/export_project3.png) + +## Steps in working with IDEs + +1. **Export** your project as a _ZIP_ file. +2. After exporting the project Unzip the downloaded zip file to a folder. +3. Extraction of the files shows you a _pom.xml_ file indicating it is [Maven complaint](http://maven.apache.org/index.html). + +[![](/learn/assets/Maven_Export.png)](/learn/assets/Maven_Export.png) + +4. Open the command shell in extracted file system and install the project using Maven Clean Install, by running the command: mvn clean install + +[![](/learn/assets/maven_build.png)](/learn/assets/maven_build.png) + +:::note +You need to have Maven and Java installed in the system. This downloads all external dependencies needed by the project and creates a WAR file. +::: + +[![](/learn/assets/Maven_Deploy.png)](/learn/assets/Maven_Deploy.png) + +This war file can be deployed to any web server like Apache Tomcat. + +5. Copy the above generated war file into the Tomcat folder “webapps“. +6. Now change directory to the Tomcat bin folder from terminal and type the below command (catalina.sh for Mac/Linux or catalina.bat for Windows) to Start Tomcat in debug mode: + + `./catalina.sh jpda start` + + [![](/learn/assets/tomcat_start_cmd.png)](/learn/assets/tomcat_start_cmd.png) + + We can see from tomcat logs: `Listening for transport dt_socket at address: 8000` + +Note: Using the option “jpda” starts Tomcat in debug mode with all options set to default values and By default `JPDA_ADDRESS` is defined as "localhost:8000" in catalina.sh +Change to a different port as need. + +7. After the successful deploy, open the IDE which you need to import ex: `IntelliJ` and click on import project and set as Maven. + +8. In IntelliJ IDE,Set Run or Debug configurations as follows: + + Click Run > Edit Configurations + + Click + icon on the top-left toolbar + + Click Remote + + Enter a name you want in Name input box. + + Enter 8000 in Port input box under Settings section. + + Click Apply, then OK. + + Run > Debug..., Click the configuration you just created + + [![](/learn/assets/run_debug_configrations.gif)](/learn/assets/run_debug_configrations.gif) + + Refer to below doc for more information: https://cwiki.apache.org/confluence/display/TOMCAT/Developing#Developing-Q1 + +9. Now launch the deployed application in browser. +10. To debug any DB/Java service used in the app you need enable debug point in service and run it. + +[![](/learn/assets/debug_IDE.png)](/learn/assets/debug_IDE.png) + +11. Once you are done with all the changes, run Maven Clean Install which will generate a ZIP file in _target/exports_ folder. + +[![](/learn/assets/Maven_Export_Target.png)](/learn/assets/Maven_Export_Target.png) + +12. This file can be re-imported into Studio using the **Update Source** option from the project **Developer Utilities** Menu. The changes will be incorporated into your Studio application. + +## Integration with Jenkins + +Ref for installing Jenkins [https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins](https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins) WaveMaker provides two profiles development, production by default. To execute profiles user needs to execute the command as: mvn clean install -Pdevelopment for development configuration and mvn clean install -Pproduction for production configuration. Install Jenkins and create a job and set windows batch command as maven command(mvn clean install -Pdevelopment) + +[![](/learn/assets/IDE_jenkins.png)](/learn/assets/IDE_jenkins.png) + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/dev-integration/import-export-update-apps.md b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/import-export-update-apps.md new file mode 100644 index 000000000..a1a6cff9a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/import-export-update-apps.md @@ -0,0 +1,79 @@ +--- +title: "Import, Export & Update Apps" +id: "import-export-update-apps" +--- +--- + +## Overview + +[Collaborated development](/learn/app-development/dev-integration/developer-collaboration/) experience can be extended to include developers outside your network by using the following options: + +- Import, +- Export, and +- Update + +## Export Project + +- Export Project allows you to create a ZIP or a WAR file including the project along with the resources used. The projects are [Maven compliant](/learn/app-development/dev-integration/extending-application-using-ides/ "Extending the Application"). +- Here we will be using the ZIP option. WAR option can be used for deployment to a Web Server, [see here for more](/learn/app-development/deployment/deployment-web-server/). [![](/learn/assets/export_project1.png)](/learn/assets/export_project1.png) +- You can also use the ZIP icon from the Project Dashboard to export the project without opening the same. [![](/learn/assets/export_project3.png)](/learn/assets/export_project3.png) +- Once a ZIP file is created you can download it to your machine. + +**Note:** For security reasons, the export project option is restricted to the projects you own. **Note:** In case the project is using a database, only the data model is exported, data is not included in the export. + +## Import Project + +You can import a project or a prefab in the ZIP format using the **Import **from the Project Dashboard. Choose the file from the import dialog and click on Import. These are the files that were created from the Export option of WaveMaker Studio as discussed above. + +- On the **Project Dashboard**, click the **Import** button. [![](/learn/assets/import_project1.png)](/learn/assets/import_project1.png) +- Select the ZIP file from your machine to import and give it an appropriate name. You can retain the original name or change it. +- Now this project will be available on your Project Dashboard for selection. + +## Updating Projects + +You will use this option when you want to incorporate the changes made to the project after export i.e. when you want to "re-import" the project. + +- Open the Project that you want to update. +- Select **Update Source** option from the **Developer Utilities.** [![](/learn/assets/update_project1.png)](/learn/assets/update_project1.png) +- Select the location of the ZIP file with the updates. Keep in mind, this operation will overwrite the project source file from your local copy. + +## Project Recovery + +In the previous section, we have seen how WaveMaker provides options to export the project as zip using _Export_ menu and provides _Update Source_ option to update the project sources back. Sometimes projects may fail to open because of conflicts or some corrupt files. In such cases, Export & Update Source options without opening the project itself come in handy. This will help to export the project in conflict/corrupt state, fix the project outside of WaveMaker using an IDE and update the content. + +### Implementation Details + +Each project tile in the **Project Dashboard** shows + +- an _Export_ option for exporting the project as zip, and +- a _Restore_ option further provides the following options: + - restore from the Previous Snapshot + - restore from Project zip +- a _Delete_ option to delete the project + +We will be looking at each of these options in the following sections. + +### Export Project + +Export option downloads project as a ZIP file. Using this option you can export the project (.zip) without opening the project and make changes if any required by [working on it using an IDE](/learn/app-development/dev-integration/extending-application-using-ides/#steps) of your choice and [update the project](#update-project) with new changes. + +[![](/learn/assets/export_project3.png)](/learn/assets/export_project3.png) + +### Restore Project options + +[![](/learn/assets/restore_project1.png)](/learn/assets/restore_project1.png) Restore opens a dialog with two sub-options: + +- Restore to last stable state +- Restore from project ZIP + +#### Restore to last stable state + +The last stable state is picked from the snapshot of the project. This option will work only if there is a previous snapshot available, i.e. when there is a VCS conflict. Every time user makes a [VCS pull request](/learn/app-development/dev-integration/developer-collaboration/#pull-changes), WaveMaker takes a snapshot of the project content before making a pull request. If the pull is successful (i.e no conflicts after the pull), the snapshot will be deleted, thus there will not be any previous snapshots for certain cases. Also if there are conflicts the snapshot will be deleted after resolving all conflicts. In such cases, you will get a message to the effect. After applying the Restore from the previous snapshot, your source may be behind the VCS status. In such case, you need to pull the changes again from the VCS to be in sync with the latest status of the VCS server. + +#### Restore from project ZIP + +Upon selecting this option you will be asked to upload the zip file (exported from export option) to update the project sources with the zip file content. The entire content in the project workspace will be updated with the new content thus losing any changes done post the export. + +To prepare the zip file for upload, we recommend using the “mvn clean install” command which prepares the zip for uploading in the “target/export” directory of the project sources where you extracted the zip file that you downloaded through Export option. + +This option also clears the VCS conflict state if any. But any changes to the files (added/deleted/modified) will be reflected in the VCS status. diff --git a/website/versioned_docs/version-v11.8.5/app-development/dev-integration/inspection-framework.md b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/inspection-framework.md new file mode 100644 index 000000000..f76412741 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/inspection-framework.md @@ -0,0 +1,732 @@ +--- +title: "Inspection Framework" +id: "inspection-framework" +--- +--- +Inspection framework is available since WaveMaker 10.0. Inspection Framework helps you locate errors, custom code or any unsupported methods in your project. For example, you can use this feature for the project migration process to identify unsupported methods. Using the inspection framework, you can perform tests and include this feature in your QA cycle to help you find code errors. Also, with this, you can point to the project’s custom code and edit and fix any code errors you may have.  + +## How to use Inspection Framework + +You can locate **Inspection framework** from the More options menu of the project. See the image below: + +![](/learn/assets/inspectionframeworklowcode.png) + +To initiate the inspection framework, you click the More options menu and click Run. When you run the inspection framework from your project, if there are any unsupported methods or errors in your code, it shows them on the screen immediately. The following guide helps you with each rule that the Inspection Framework will help you identify and fix the issues in your project. + +## Handle Script errors for Widgets Configured with Show in device + +This rule attempts to catch and prevent any usage of Widgets that have `showindevice` configured for them and are being accessed in the script without checking if the element exists or not. + +### Rule Details + +As of 10.7, If a widget has `showindevice` configured as something other than `all`, then it won't be rendered in any other viewport other than the specified one. Hence, before accessing properties of that Widget, a sanity check is required to see if it exists or not. This has been done for performance optimization as it prevents unnecessary Network calls. + +#### Examples of incorrect code for this rule + +```js +Page.Widgets.EmployeeTable.currentItem.name = "John Doe"; + +var selectedItem = Page.Widgets.DepartmentList.selecteditem; +Page.Variables.FilterDepartments.dataSet.filter(function(employeeObj) { + return employeeObj.id === selectedItem.empID +}); +``` + +#### Examples of correct code for this rule + +```js +if (Page.Widgets.EmployeeTable) { + Page.Widgets.EmployeeTable.currentItem.name = "John Doe"; +} + +if (Page.Widgets.DepartmentList) { + var selectedItem = Page.Widgets.DepartmentList.selecteditem; + Page.Variables.FilterDepartments.dataSet.filter(function(employeeObj) { + return employeeObj.id === selectedItem.empID + }); +} +``` + +The above checks will ensure that there are no script errors when widgets which may not be present in the DOM are being accessed. Without the above check, `selectedItem.empID` in the return statement will throw a script error if we have configured `showindevice` as `Mobile` for DepartmentList and are trying to access it in a Web Application. + +## No Missing Page Elements + +This rule attempts to validate all the Pages & Partial elements. + +### Rule Details + +Each Page or Partial in WaveMaker is composed of Markup, Style, Scripts, Variables and each of it is stored as seperate file in the filesystem as HTML,CSS, JS & JSON files respectively. + +![](/learn/assets/inspection-no-missing-page-elements-details.png) + +If any of the files is deleted, the page cannot be formed completely & will cause Deployment failure. Inorder to resolve this error, the user can revert the changes causing the deletion of reported file. + +## No Invalid Partials + +This rule attempts to validate all the Partial references in the project code. + +### Rule Details + +If the Page or Partial needs to load another partial as it's content, the markup needs to have a partial container widget with its `content` attribute set to partial name. There are couple of usecases where such partial references can be invalid as listed below, + +* If the partial referred in the markup is deleted, the deployment can fail citing the invalid reference. +* If a given partial trying to load itself as its content, the deployment can fail citing recursive reference. + + eg: Partial named `testPartial` can have markup as below, + + ```html + + ``` + +Inorder to resolve errors caused by above listed cases, the user can update the markup to set `content` attribute with valid partial references. + +## No Invalid Fontpath + +This rule attempts to validate font paths updated in the project CSS files. + +### Rule Details + +If the project needs to use specific fonts, it can be achieved by adding `@font-face` entry in the `CSS` files. The path of source font file is updated in the `src` property as shown below, + +```css +@font-face { + font-family: 'Glyphicons Halflings'; + src: url('fonts/glyphicons-halflings-regular.eot'); + src: url('fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('fonts/glyphicons-halflings-regular.woff') format('woff'), url('fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +``` + +if the path mentioned in the `src` property is not resolved relatively to the `CSS` file, the deployment can fail citing invalid path error. Inorder to fix this issue, the user needs to update the `src` with valid path. + +## No Declaration Block Trailing Semicolon + +This rule attempts to validate CSS files for trailing Semicolons + +### Rule Details + +This rule ensures that the trailing semicolon is required within the decleration block as shown below + +```css +.testClass {height: 200px; width: 100px;} +``` + +# Inspecting No AngulaJS +--- + +## No AngularJS Service + +This rule attempts to catch and prevent any usage of AngularJS Service. + +### Rule Details + +If you want to remove AngularJS service this rule can help you by warning you of any usage of AngularJS service in your app. + +#### That includes: + +```js +Application.service(‘myService’, function() {}); +``` + +For replacing AngularJS service, we can use objects defined on the App. + +#### Examples of incorrect code for this rule + +```js +Application.service(‘myService’, function($rootScope) { +this.someFunction = function() { + ... + $rootScope.x + ... +} +}); +``` + +### Use + +```js +Application.$controller(‘$scope’, ‘myService’ function($scope, myService) { +myService.someFunction(); +}); +``` + +#### Examples of correct code for this rule + +```js +App.myService = { + someFunction: function() { + … + App.x //$rootScope to be replaced with App + ... + } +} +``` + +### Use + +``` +App.myService.someFunction(); +``` + +## No AngularJS Controller + +This rule attempts to catch and prevent any usage of the AngularJS controller. + +### Rule Details + +If you want to remove AngularJS controller this rule can help you by warning you of any usage of AngularJs controller in your app. + +#### That includes: + +```js +Application.controller(‘myController’, function() {}); + +For replacing the AngularJS controller, we can use Prefabs. +Examples of incorrect code for this rule: +Application.controller("myCtrl", function ($scope) { + $scope.firstName = "Alex"; + $scope.lastName = "Bob"; +}); +``` + +### Use + +``` +{{firstName}} +``` + +#### Examples of correct code for this rule: + +Create a prefab with all the properties and methods. Export the prefab to the project where it needs to be used. + +### Use + +```js +MyPrefab.firstName +``` + +## No AngularJS Factory + +This rule attempts to catch and prevent any usage of AngularJS Factory. + +### Rule Details + +If you want to remove AngularJS Factory this rule can help you by warning you of any usage of AngularJS factory in your app. + +#### That includes: + +```js +Application.factory(‘myFactory’, function() {}); +``` + +For replacing the AngularJS factory, we can use objects defined on the App. + +#### Examples of incorrect code for this rule: + +```js +Application.factory(‘myFactory’, function() { +return { + displayMethod: function () { + console.log(‘in display method’); + } +}; +}); +``` + +### Use + +```js +Application.$controller(‘$scope’, ‘myFactory’, function($scope, myService) { +‘myFactory’.displayMethod(); +``` + +#### Examples of correct code for this rule: + +Define the factory in app.js. Any AngularJS dependency being used in the factory will NOT work. That has to be defined separately in app.js before defining the factory. + +```js +App.myFactory = { + someFunction: function() { + … + App.x //$rootScope to be replaced with App + ... + } +} +``` + +### Use + +```js +App.myMethod.displayMethod(); +``` + +## No AngularJS Config + +This rule attempts to catch and prevent any usage of AngularJS config. + +### Rule Details + +If you want to remove AngularJS config this rule can help you by warning you of any usage of AngularJS config in your app. + +#### That includes: + +```js +Application.config(function() {}); +``` + +#### Examples of incorrect code for this rule: + +```js +Application.config(function ($httpProvider) { + $httpProvider.interceptors.push('myHttpInterceptor'); +}); +``` + +#### Examples of correct code for this rule: + +Not supported in WaveMaker 10.x. + +## No AngularJS Run + +This rule attempts to catch and prevent any usage of AngularJS run. + +### Rule Details + +If you want to remove AngularJS run this rule can help you by warning you of any usage of AngularJS run in your app. + +#### That includes: + +```js +Application.run(function() {}); +``` + +#### Examples of incorrect code for this rule: + +```js +Application.run(function (editableOptions) { + editableOptions.theme = “default”; +}); +``` + +#### Examples of correct code for this rule: + +Not supported in WaveMaker 10.x. + +## No AngularJS Constant + +This rule attempts to catch and prevent any usage of AngularJS constant. + +### Rule Details + +If you want to remove AngularJS constant this rule can help you by warning you of any usage of AngularJS constant in your app. + +#### Examples of incorrect code for this rule: + + +```js +Application.constant('MY_CONSTANT1', 'The Constant Text Value'); +``` + +### Use + +```js +Application.$controller(‘$scope’, ‘myService’ function($scope, myService) { +$scope.testValue = MY_CONSTANT1; +}); +``` + +#### Examples of correct code for this rule: + +```js +Create constants object in script file +App.constants = { + ‘name’: ‘Alex’ +} +``` + +## No AngularJS Value + +This rule attempts to catch and prevent any usage of AngularJS value. + +### Rule Details + +If you want to remove AngularJS value this rule can help you by warning you of any usage of AngularJS value in your app. + +#### Examples of incorrect code for this rule: + +```js +Application.value(‘Test_Value’, ‘Test’); +``` + +### Use + +```js +Application.$controller(‘$scope’, ‘myService’ function($scope, myService) { +$scope.testValue = Test_Value; +}); +``` + +#### Examples of correct code for this rule: + +Create constants object in script file + +```js +App.values = { + ‘Test_Value’: ‘Test’ +} +``` + +## No AngularJS $scope + +This rule attempts to catch and prevent any usage of AngularJS $scope. + +### Rule Details + +If you want to remove AngularJS $scope this rule can help you by warning you of any usage of AngularJS $scope in your app. + +#### That includes: + +```js +$scope.testValue = ‘test’; +$scope.display = function () { + console.log($scope.testValue); +} +``` + +For replacing AngularJS $scope, we can context for defining variables and methods. + +#### Examples of incorrect code for this rule: + +```js +Application.controller("myCtrl", function ($scope) { + $scope.firstName = "Alex"; + $scope.lastName = "Bob"; +}); +``` + +### Use + +```js +{{firstName}} {{lastName}} +``` + +#### Examples of correct code for this rule: + +`$scope` is not supported in 10.x. Instead of `$scope`, current context can be used. + +```js +Page.title = ‘First Page’ +Page.newFunction = function() { + console.log(‘welcome’); +} +``` + +### Use + +```js +Page.title; +Page.newFunction(); +``` + +## No AngularJS Arrow Function + +This rule attempts to catch and prevent any usage of AngularJS Arrow functions. + +### Rule Details + +If you want to remove AngularJS Arrow functions this rule can help you by warning you of any usage of AngularJS arrow functions in your app. + +#### That includes: + +```js +Var x = ()=>{return 10;} +``` + +For replacing the AngularJS arrow function, we can normal functions. + +#### Examples of incorrect code for this rule: + +```js +var func => () {console.log(‘in arrow function’);} +``` + +### Use + +```js +func(); +``` + +#### Examples of correct code for this rule: + +Arrow functions are not supported in 10.x. Normal functions can be defined and used. + +```js +var func = function() { + console.log(‘normal function’); +} +``` + +### Use + +```js +func(); +``` + +## No AngularJS $location + +This rule attempts to catch and prevent any usage of AngularJS $location. + +### Rule Details + +If you want to remove AngularJS $location, this rule can help you by warning you of any usage of AngularJS $location in your app. + +#### Examples of incorrect code for this rule: + +```js +$location.path(‘/page1’); +``` + +#### Examples of correct code for this rule: + +```js +Window.location(‘/MainPage’); +``` + +## No AngularJS `$apply` + +This rule attempts to catch and prevent any usage of AngularJS `$apply`. + +### Rule Details + +If you want to remove AngularJS `$apply` this rule can help you by warning you of any usage of AngularJS ``$apply`` in your app. + +#### Examples of incorrect code for this rule: + +```js +$scope.`$apply`(function () { + $scope.val1 = ‘test’; +}); +``` + +#### Examples of correct code for this rule: + +Not supported in WaveMaker 10.x. + +## No AngularJS $watch + +This rule attempts to catch and prevent any usage of AngularJS $watch. + +### Rule Details + +If you want to remove AngularJS $watch this rule can help you by warning you of any usage of AngularJS $watch in your app. + +#### Examples of incorrect code for this rule: + +```js +$scope.$watch(‘testVal’, function (nv) { + If (nv) { + console.log(‘new value’, nv); +} +}); +``` + +#### Examples of correct code for this rule: + +Widget/ Variable events can be used instead of $watch. + +## No AngularJS $filter + +This rule attempts to catch and prevent any usage of the AngularJS $filter. + +### Rule Details + +If you want to remove AngularJS $filter this rule can help you by warning you of any usage of AngularJS $filter in your app. + +#### Examples of incorrect code for this rule: + +```js +$scope.fullDate = $filter('date')(today, 'fullDate'); +``` + +#### Examples of correct code for this rule: + +Not supported in WaveMaker 10.x + +## No AngularJS $window + +This rule attempts to catch and prevent any usage of AngularJS $window. + +### Rule Details + +If you want to remove AngularJS $window this rule can help you by warning you of any usage of AngularJS $window in your app. + +#### Examples of incorrect code for this rule: + +```js +$window.alert(‘hello world’); +``` + +### Use + +```js +Application.$controller(‘$scope’, ‘$window’ function($scope, myService) { +$window.alert(‘hello world’); +}); +``` + +#### Examples of correct code for this rule: + +$window is not supported in 10x. “Window” can be used in 10x instead of $window. + +```js +window.alert(“hello world”); +``` + +## No AngularJS Component + +This rule attempts to catch and prevent any usage of AngularJS components. + +### Rule Details + +If you want to remove AngularJS components this rule can help you by warning you of any usage of AngularJS components in your app. + +#### Examples of incorrect code for this rule: + +```js +Application.component(‘greetUser’, { + template: ‘Hello, {{$ctrl.user}}!’, + controller: function GreetUserController() { + this.user = ‘world’; +} +}); +``` + +### Use + +#### Examples of correct code for this rule: + +Components are not supported in WaveMaker 10.x. You can yse Prefabs instead of the component. Drag and drop the prefab where you want to use instead of the component. + +## No AngularJS Directive + +This rule attempts to catch and prevent any usage of AngularJS directives. + +### Rule Details + +If you want to remove AngularJS directives this rule can help you by warning you of any usage of AngularJS directives in your app. + +#### Examples of incorrect code for this rule: + +```js +Application.directive.directive('helloWorld', function() { + return { + restrict: 'E', + scope: { + name: '=' + }, + template: 'Hello {{name}}' + } +}); +``` + +### Use + +#### Examples of correct code for this rule: + +Directives are not supported in WaveMaker 10.x. You can use Prefabs instead of a directive. Drag and drop the prefab where you want to use instead of a directive. + +## No AngularJS Provider + +This rule attempts to catch and prevent any usage of AngularJS providers. + +### Rule Details + +If you want to remove AngularJS Provider this rule can help you by warning you of any usage of AngularJS Provider in your app. + +#### Examples of incorrect code for this rule: + +```js +Application.provider(“test”, function () { + var type; + return { + setType: function (value) { + type= value; +}, +$get: function () { + return { + title: type + “!!” +}; +} +}; +}); +Application.config(function (testProvider) { + testProvider.setType(“Greeting”); +}); +Application.controller(“AppCtrl”, function ($scope, test) { + $scope.title = test.title; +}); +``` + +#### Examples of correct code for this rule: + +Not supported in 10x. You can use Prefabs with outbound properties. + +## No AngularJS $parent + +This rule attempts to catch and prevent any usage of AngularJS $parent. + +### Rule Details + +If you want to remove AngularJS $parent this rule can help you by warning you of any usage of AngularJS $parent in your app. + +#### Examples of incorrect code for this rule: + +```js +$scope.$parent.testValue = ‘test’; +``` + +### Use + +```js +$scope.$parent.testValue; +``` + +#### Examples of correct code for this rule: + +$parent is not supported in WaveMaker 10.x. Use App or App.activePage based on the requirement. + +## No AngularJS RouteParams + +This rule attempts to catch and prevent any usage of AngularJS RouteParams. + +### Rule Details + +If you want to remove AngularJS RouteParams this rule can help you by warning you of any usage of AngularJS RouteParams in your app. + +#### Examples of incorrect code for this rule: + +```js +Application.config(function($routeProvider, $locationProvider) { + $locationProvider.hashPrefix(''); + $routeProvider + .when('/page', { + template: 'Page' + }) + .when('/about/:paramOne/:paramTwo', { + template: 'ABOUT', + controller: 'aboutCtrl' + }) + .otherwise({ + template: 'Not Found' + }); +}); + +Application.controller('aboutCtrl', function($routeParams) { + $scope.paramOnePrint = $routeParams.paramOne; + $scope.paramTwoPrint = $routeParams.paramTwo; +}); +``` + +#### Examples of correct code for this rule: + +Not supported in WaveMaker 10.x + diff --git a/website/versioned_docs/version-v11.8.5/app-development/dev-integration/printing-logger-statement.md b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/printing-logger-statement.md new file mode 100644 index 000000000..72d6a443e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/dev-integration/printing-logger-statement.md @@ -0,0 +1,63 @@ +--- +title: "Printing Logger Statement in Java Service using SLF4J" +id: "printing-logger-statement" +sidebar_label: "Print Logger Statement" +--- +--- + +Logs are statements written to record events or any activity in an application. Logs help in debugging, monitoring, and analyzing the behavior of an application or system. + +The SLF4J (Simple Logging Facade for Java) logging framework, with its simple and consistent API, provides a flexible and efficient way to print logger statements in Java services. It acts as a facade, allowing developers to choose from various logging implementations (example: Logback, Log4j2) without modifying the application's code. This decoupling ensures portability and simplifies the process of switching or configuring logging frameworks based on specific requirements or deployment environments. + +Below are the steps to print logger statements in a Java service using the SLF4J logging framework. + +## Import the Necessary Classes + +```java +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +``` + +## Declare Logger Object in Java Service + +```java +private static final Logger logger = LoggerFactory.getLogger(MyJavaService.class); +``` + +[![](/learn/assets/logger-declaration.png)](/learn/assets/logger-declaration.png) + + +## Ways to Print Logger Statement + +When a Java service is created, it by default has the logger statement in the Java code. But to print a logger statement in a log file, you can make any one of the following changes. + +### 1. Update the log4j2.xml file + +- Open the `log4j2.xml` file. +- Include the following line, replacing `PackageName.JavaServiceName` with the actual package name and Java service name: + +```xml + +``` + +[![](/learn/assets/log4j2-add-statement.png)](/learn/assets/log4j2-add-statement.png) + +- This will configure the logger to print Debug-level statements for the specified Java service. + +To know more about the `log4j2.xml` file, see [Enabling logs](/learn/app-development/dev-integration/chrome-developer-tool/#enabling-logs). + +### 2. Modify the logger statement in Java service + + +- Find the existing logger statement in your Java service, such as `logger.debug("Statement")`. +- Replace `debug` with `info` to change the log level from DEBUG to INFO. +- This change aligns with the root level specified in the `log4j2.xml` file, which is set to INFO by default in WaveMaker's generated `log4j2.xml`. + +```java +logger.info("Statement"); +``` + +[![](/learn/assets/logger.info-javaservice.png)](/learn/assets/logger.info-javaservice.png) + +To know more about **Log4j2** and Log levels, see [Log4j2](https://logging.apache.org/log4j/2.x/index.html). + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/3rd-party-libraries.md b/website/versioned_docs/version-v11.8.5/app-development/services/3rd-party-libraries.md new file mode 100644 index 000000000..898f59c09 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/3rd-party-libraries.md @@ -0,0 +1,33 @@ +--- +title: "Resources and Third-party Libraries" +id: "3rd-party-libraries" +--- +--- + +With the Angular code generation in place, the users can see the generated code in parallel to their application development in the **File Explorer** Section. + +## File Explorer + +The file explorer contains a folder called the ‘**generated-angular-app**’ folder at the root of the application folder structure. + +The ‘**generated-angular-app**’ is Angular 7 compliant project structure of the WaveMaker application as shown in the image below. The content in this section is Read-only. + +[![](/learn/assets/Build-start.png)](/learn/assets/Build-start.png) + +## Including Resource Files + +There will be times when you want to use external resources in your application. These may be in the form of images, audio files, video files, JavaScript files, UI designs etc. WaveMaker understands these needs and facilitates the usage. + +[![](/learn/assets/ext_import.png)](/learn/assets/ext_import.png) + +[![](/learn/assets/ext_resources.png)](/learn/assets/ext_resources.png) + + +1. From the **Developer Utilities** option select **File Explorer**. Here you will find the option to import resources to your app. +2. Click **+** to open the **Import Resource** dialog box +3. Select the appropriate folder, and **Upload Files** that need to be imported. You can select multiple files to import. **Note**: Be sure you select the proper folder, this will be used by the binding dialog to filter the files. For example, if you are using an Image widget, you will be selecting the Image type resource and WaveMaker will display only the files from the Images folder. [![](/learn/assets/ext_resources_binding.png)](/learn/assets/ext_resources_binding.png) +4. You can create your own sub-folders. You can also create a nested folder structure by using / as the file separator. For example, to create images sub-folder under style folder in resources, select resources enter _images/style_ under folder name field. +5. Depending upon the resource imported its usage would differ. + - In the case of media resources like images, audio files or video files, you can bind them to the appropriate widgets. + - In the case of JavaScript resource, entry into the _index.html_ file and invoking the script function would require some JavaScript knowledge. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/3rd-party-libraries/using-3rd-party-jar-files.md b/website/versioned_docs/version-v11.8.5/app-development/services/3rd-party-libraries/using-3rd-party-jar-files.md new file mode 100644 index 000000000..00a5e3eb0 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/3rd-party-libraries/using-3rd-party-jar-files.md @@ -0,0 +1,83 @@ +--- +title: "Using 3rd party jar files" +id: "using-3rd-party-jar-files" +--- +--- + +You can import external JAR files and use them in your apps, just like how you would use a Java Service written in your app. Following are the steps to incorporate an external jar file: + +1. From _Developer Utilities_, access **File Explorer** + +[![](/learn/assets/ext_import.png)](/learn/assets/ext_import.png) + +2. **Import Resource**, and select the **Lib** folder to place the jar file to be imported. As an example, we are using a [mail](/learn/assets/mail.zip) file. + +[![](/learn/assets/jar_folder.png)](/learn/assets/jar_folder.png) + +3. Add the **import** statements for the required classes in your Java Service file. In this example, we have used the _mail.jar_, the package details of which can be found at [https://javamail.java.net/nonav/docs/api/](https://javamail.java.net/nonav/docs/api/). To use this jar file to send emails we will be using the following code in the Java Service file after adding the import statements for the required class files: +``` + import java.util.Properties; + import javax.mail.Message; + import javax.mail.MessagingException; + import javax.mail.Session; + import javax.mail.Transport; + import javax.mail.internet.InternetAddress; + import javax.mail.internet.MimeMessage; + +public String sendEmail(String userName, String password, String toEmailAddress, String emailSubject, String emailMessage) { + try { + // Use javamail api, set parameters from registration.properties file + // set the session properties + Properties props = System.getProperties(); + props.put("mail.smtp.starttls.enable", "true"); + props.put("mail.smtp.host", "smtp.gmail.com"); + props.put("mail.smtp.port", "587"); + props.put("mail.smtp.auth", "true"); + props.put("mail.smtp.starttls.required", "true"); + Session session = Session.getDefaultInstance(props, null); + + // Create email message + MimeMessage message = new MimeMessage(session); + message.setFrom(new InternetAddress(userName)); + + // message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmailAddress)); + + String[] recipientList = toEmailAddress.split(","); + InternetAddress[] recipientAddress = new InternetAddress[recipientList.length]; + int counter = 0; + for (String recipient: recipientList) { + recipientAddress[counter] = new InternetAddress(recipient.trim()); + counter++; + } + message.setRecipients(Message.RecipientType.TO, recipientAddress); + + message.setSubject(emailSubject); + message.setContent(emailMessage, "text/html"); + // Send smtp message + Transport tr = session.getTransport("smtp"); + tr.connect("smtp.gmail.com", 587, userName, password); + message.saveChanges(); + tr.sendMessage(message, message.getAllRecipients()); + tr.close(); + + return "Mail sent successfully."; + + } catch (MessagingException e) { + return "Error in method sendEmailNotification: " + e; + } +} +``` + +[![](/learn/assets/jar_java.png)](/learn/assets/jar_java.png) + +4. To invoke the Java Service create a new Variable for Java Service: + +[![](/learn/assets/jar_sv.png)](/learn/assets/jar_sv.png) + + +5. The _input parameters_ can be accessed from the **Data** tab and can be bound or set to static values +6. The Java Service can be executed either + - by setting the **Update data on input change** to true thus triggering whenever the input values change or + - by triggering the Variable created for any event on a widget for example on Mouse Click event of a Button. +7. The result from the execution of this service can be bound to any widget. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/3rd-party-libraries/using-3rd-party-javascript-files.md b/website/versioned_docs/version-v11.8.5/app-development/services/3rd-party-libraries/using-3rd-party-javascript-files.md new file mode 100644 index 000000000..ca28d10ef --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/3rd-party-libraries/using-3rd-party-javascript-files.md @@ -0,0 +1,52 @@ +--- +title: "Using 3rd party JavaScript files" +id: "using-3rd-party-javascript-files" +--- +--- + +In this section, we will look at the usage of **external JavaScript and CSS** files. + +The basic steps would involve: + +1. **Importing** the files and placing them in the appropriate folder. +2. Making an entry in the **index.html** file giving the location of the files imported. +3. Using the imported files, via **script** in your application. + +We will explain the process with the help of an example. We want to add a multiple date selection facility to our application. The current calendar widget allows selection of a single date. + +We will use [MultiDatesPicker v1.6.3](/learn/assets/MultiDatesPicker-v1.6.3.zip) jQuery UI downloaded from [http://multidatespickr.sourceforge.net/](http://multidatespickr.sourceforge.net/). + +We will also be needing [jquery-ui-1.12.0.custom](/learn/assets/jquery-ui-1.12.0.custom.zip) file. Download and unzip both the files. + +## Importing Files + +From **Developer Utilities**, select File Explorer and **Import Resource**. We need to import two files: + 1. a **js file** - `jquery-ui.multidatespicker.js` with the code and + 2. a **CSS file** - `mdp.css` for the UI. The js file will be placed in the `resources/javascript` folder and the CSS file in the `resources/css` folder. Create the appropriate folders + +[![](/learn/assets/js_import.png)](/learn/assets/js_import.png) + +## Specify Paths + +In the _index.html_ file make the following entries specifying the path for script and CSS files: + +[![](/learn/assets/js_index.png)](/learn/assets/js_index.png) + +- On the main page mark the position for the display of the date-picker using a `div` tag. + +[![](/learn/assets/js_markup.png)](/learn/assets/js_markup.png) + +## Scripting + +In the script tab attach the `mulitdatespicker` function from the js file imported to the `div` created + +``` + $(function() { + $('#multidatepicker').multiDatesPicker(); + }); +``` + +[![](/learn/assets/js_script.png)](/learn/assets/js_script.png) + +When you run the application you will see the calendar displayed and you can select multiple dates. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/api.md b/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/api.md new file mode 100644 index 000000000..8b65ee25b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/api.md @@ -0,0 +1,29 @@ +--- +title: "Application Programming Interface (API)" +id: "api" +sidebar_label: "API Designer" +--- +--- + +**Application Programming Interfaces** or APIs are the building blocks of the modern web. APIs enable simplifying the access to a program’s internal functions by an external application through a set of request and response messages. WaveMaker uses an API-driven app development approach wherein [REST APIs](http://www.restapitutorial.com/lessons/whatisrest.html) are generated automatically for the application. Every service, be it Database Service or Java Service, that is imported into an application generates REST APIs. These are available for modification and consumption through the **API Designer**. + +## API Designer + +From WaveMaker's API Designer, one can view the various Database and Java Service APIs that are available to your application. You can access the API Designer from the Resources Panel. You can use this designer for: + +1. exploring the various APIs generated by the platform, their description, and usage; +2. test the APIs using the test tab, without having to access URL; +3. and in case of Java Services customize the APIs. + +[![](/learn/assets/API_Access.png)](/learn/assets/API_Access.png) + +## Application APIs + +These APIs are generated for the services imported/written in the current application. + +### Core APIs + +Core APIs are APIs generated from the Database, Java and Security Services. + +[![](/learn/assets/API_DB.png)](/learn/assets/API_DB.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/database-service-apis.md b/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/database-service-apis.md new file mode 100644 index 000000000..4e8d4d829 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/database-service-apis.md @@ -0,0 +1,41 @@ +--- +title: "Database Service APIs" +id: "database-service-apis" +--- +--- + +REST APIs generated for CRUD, searching and listing operations for each [Database table integrated](/learn/app-development/services/database-services/working-with-databases/) within the app can be viewed from API Designer. For easy usability, these APIs are categorized under various heads. They are grouped by the database, then entities, queries, and procedures. + +## Endpoint + +Selecting an _endpoint_ will display the details of the APIs pertaining to that endpoint. + +[![](/learn/assets/API_DB_access.png)](/learn/assets/API_DB_access.png) + +### Method Type + +- **GET** - methods which retrieve resources, +- **POST** - methods which create new resources, +- **PUT** - methods which update resources, or +- **DELETE** - methods which delete a resource + +### URL +- The URL for that particular REST API service. +- a brief description +### Visibility + +- **Public** - this is the default setting and would enable user access to the API at runtime; +- **Unavailable** - this setting can be used when you want to disable a particular API method. For example, you want to ensure that records from employee table are not deleted, then making the DELETE method Unavailable will ensure that it does not happen by mistake. + +### API Method Details + +API method details can be viewed by selecting the method. + +- **Define -** this tab gives the definition of the selected method: + - The _Description_ field which can be customized. + - The _Request Parameters_ including the name, type, the parameter type and the description of the parameter. + - The _Response Format_ shows the fields returned along with the type and description. +- **Test -** this tab allows you to test an API. Giving a test value for the request parameter and clicking on the test button, displays the result in the Response window. + +[![](/learn/assets/API_DB_test.png)](/learn/assets/API_DB_test.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/import-rest-apis-swagger.md b/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/import-rest-apis-swagger.md new file mode 100644 index 000000000..00fbc1b5b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/import-rest-apis-swagger.md @@ -0,0 +1,72 @@ +--- +title: "Import API Services" +id: "import-rest-apis-swagger" +sidebar_label: "Import APIs" +--- +--- + +WaveMaker automatically generates UI functionality for create, read, update, delete (CRUD) operations if you import REST API endpoints via Swagger/OpenAPI. Most of the backend frameworks like Spring Boot, .NET core already support an automatic generation of Swagger documentation for the REST APIs. + +You can develop a WaveMaker app by importing REST APIs that have Swagger/OpenAPI support. Import REST services via Swagger to get access to the required information to consume and integrate with your app. + +### Supported Widgets + +**Web**: DataTable, Form, Cards (read-only), List (read-only). + +**Mobile**: List with Form. + +## Importing Swagger + +Go to **APIs** section, and select **Imported APIs**. + +![import swagger](/learn/assets/import-swagger.png) + +Import Swagger from a URL or a File. + +- **File**: Supports `.json`,`.yaml` +- **URL**: The service URL that hosts the REST service. + +For example, see [Swagger Petstore Project](http://petstore.swagger.io/). +`https://petstore.swagger.io/v2/swagger.json` + +![import swagger with url or file](/learn/assets/upload-file-url-swagger.png) + +### Entity and Endpoints + +When you import an API, all endpoints group into Entities. +An Entity contains multiple endpoints. For example, CRUD endpoints, including Create, Read, Update, and Delete methods group into a single entity. + +|HTML Verb |CRUD | Swagger | +|---|---|---| +|POST|Create |CREATE| +|GET|Read| LIST| +|PUT |Update |UPDATE| +|DELETE|Delete|DELETE| + +From the left navigation, view all the identified **Entities**. Click the Entity name to see its endpoints, which categorize as **CRUD endpoints** and **Other endpoints**. You can modify these if needed. + +![import swagger url](/learn/assets/import-swagger-url.PNG) + +:::note +If you cannot find an entity for a path, look for the **Others** entry from the **Entities** list. You can use them as a Variable; however, it does not support CRUD operations. +::: + +After verifying the details in the **Import APIs** dialog, click **Import** to add the service. + +## Configuring Authentication + +Next, in the following dialog configure, API authentication. Swagger supports OAuth 2.0. Click **OAuth Provider** to enter provider details. + +![oauth config for swagger](/learn/assets/oauth-swagger-congif.PNG) + +![oauth config for swagger](/learn/assets/oauth-swagger-config.png) + +In **OAuth Provider Configuration** dialog, enter the values for **Access Token URL**, **Client ID** and **Client Secret** of the imported REST service. To know how to configure these properties, see [OAuth Provider Configuration for REST Services](/learn/app-development/services/web-services/oauth-2-0-rest-services#oauth-provider-configuration). + +For more information, see [REST Services using OAuth 2.0](/learn/app-development/services/web-services/oauth-2-0-rest-services), and see the list of Supported OAuth 2.0 Providers, [here](/learn/app-development/services/web-services/oauth-2-0-rest-services#supported-oauth-20-providers). + +## Consuming Imported REST Services + +When you successfully import a REST service, you can drag-and-drop the [supported](#supported-widgets) widgets to configure for CRUD-ready operations. To learn how to create a CRUD variable, see [Creating a CRUD Variable for REST Services](/learn/app-development/variables/crud-variable). + +Also, you can create a service variable, and integrate it with widgets to perform one operation at once using **Other Endpoints**. For more information, see [Service Variable for Imported APIs](/learn/app-development/variables/web-service#service-variable-for-imported-apis). diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/java-service-apis.md b/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/java-service-apis.md new file mode 100644 index 000000000..133139bcf --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/java-service-apis.md @@ -0,0 +1,18 @@ +--- +title: "Java Service APIs" +id: "java-service-apis" +--- +--- + +REST APIs are generated for the user defined [Java Service](/learn/app-development/services/java-services/java-service/) Classes which can be viewed from the API Designer. + +[![Screenshot](/learn/assets/API_java.png)](/learn/assets/API_java.png) + +- Selecting the _endpoint_ will display the details of the Java Service which include description and methods +- Selecting a method would display the details of the method including: + - the URL can be edited, + - method type can be POST for create methods, PUT for update methods, GET for retrieve methods or DELETE for delete methods, + - description of the method, + - request parameters - parameter name, type, parameter type, and description + - response format includes return parameters, type, and description. +- The user can also test the API from the test tab, by passing values to the parameters and using the TEST button. diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/reimport-rest-apis-swagger.md b/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/reimport-rest-apis-swagger.md new file mode 100644 index 000000000..53b913e27 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/reimport-rest-apis-swagger.md @@ -0,0 +1,86 @@ +--- +title: "Re-import API Services" +id: "reimport-rest-apis-swagger" +sidebar_label: "Re-import APIs" +--- +--- + +API Re-import and Impact Analysis streamlines the process of reimporting REST APIs into the application. It evaluates potential issues when you are reimporting the API itself. This real-time analysis identifies potential problems and offers solutions for immediate rectification, ensuring a smoother and more stable development experience. + +## Impact Analysis + +The API re-import and Impact analysis feature is to assist developers in identifying potential issues that could affect their projects when re-importing an API service. By using this feature, you can proactively identify and resolve potential problems before they lead to application disruptions. This ensures smoother development processes and enhances the overall stability of your applications. + +There are two ways to access the impact analysis report: + +1. **At the time of re-importing the API.** For more information, see [Re-importing API - Swagger/OAS](#re-importing-api---swaggeroas) +2. **Go to the More option (three dots).** Navigate to the **API Issues** tray to view issues of specific pages and variables. For more information, see [Viewing API Impact on Pages and Variables](#viewing-api-impact-on-pages-and-variables). + +:::info +**Limitation**: Currently, API re-import impact analysis focuses on identifying issues related to UI development, such as design and variables. +::: + +:::note +Issue evaluation generates an impact analysis report that shows the number of identified problems. To ensure an accurate report for large applications, it's recommended to disable the **Enable API Composition** option in **Settings**. +::: + +![Import Swagger](/learn/assets/enable-api-composition.png) + +## Re-importing API - Swagger/OAS + +Following procedure describes re-importing an API using Swagger. It allows you to view changes before importing the API and access application breaking issues once you agree to import the API. + +1. Go to the **APIs** section, and click **Re-import API** at the screen's top right to re-import the selected API service. + +![Import Swagger](/learn/assets/api-reimport.png) + +2. Import the updated Swagger using either the URL option or the File option and click **Next**. + +- **File**: Supports `.json`,`.yaml` . +- **URL**: The service URL that hosts the REST service. + +![Import Swagger with URL or File](/learn/assets/url-file-next.png) + +### Changed API Endpoints and Application Breakages + +Upon uploading the Swagger, you can view the count of changes in Swagger Endpoints and any Application Breakages that were caused because of these changed endpoints. + +1. After verifying the details in the **Re-Import API** dialog, click **Next**. + +![Reimport Swagger URL](/learn/assets/api-endpoints-next.png) + +### Confirming Re-import + +1. Click **Re-import** to go ahead with re-importing the API. + +![Reimport Swagger URL](/learn/assets/confirm-reimport-api.png) + +You can view the application breakage issues within the **API Issues** tray. + +![Reimport Swagger URL](/learn/assets/api-issues-tray.png) + +## Viewing API Impact on Pages and Variables + +View API impact and identify application failure issues associated with specific pages and variables. + +1. To view API issues, navigate to the Issues framework within the project's **More** options menu, represented by three dots in the bottom left corner. + +:::note +Also, after reimporting the Swagger, you will be redirected to the inspection framework of the selected API swagger automatically. +::: + +2. To start the inspection framework, access the More options menu and navigate to the **Issues** tab to view all issues related to the reimported API. + +![Reimport Swagger URL](/learn/assets/api-issues-tray.png) + +### Selecting API Service + +Upon selecting the API, the issue location dropdown will be filtered to display affected page names. + +![Reimport Swagger URL](/learn/assets/apiselection-issues-tray.png) + +### Selecting Page + +1. Choose the page name from the issue location dropdown list to view issues specific to that page. + +![Reimport Swagger URL](/learn/assets/pageselection-api-issues-tray.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/security-service-apis.md b/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/security-service-apis.md new file mode 100644 index 000000000..194d57dbf --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/security-service-apis.md @@ -0,0 +1,10 @@ +--- +title: "Security Service APIs" +id: "security-service-apis" +--- +--- + +When you [enable Security](/learn/app-development/app-security/app-security) for your application, the Security Services are created. You can view the various methods and their functionality from API Designer. + +[![](/learn/assets/API_security.png)](/learn/assets/API_security.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/web-service-apis.md b/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/web-service-apis.md new file mode 100644 index 000000000..676edd47b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/api-designer/web-service-apis.md @@ -0,0 +1,21 @@ +--- +title: "Imported SOAP APIs" +id: "web-service-apis" +--- +--- + +The APIs generated by [importing a SOAP Service](/learn/app-development/services/web-services/web-services/) are listed in API Designer. + +- Selecting the _service_ will display the details of the methods which include the API URL, description, and the visibility. +- Selecting a method would display the details of the method including: + - the URL can be edited, + - method type can be POST for create methods, PUT for update methods, GET for retrieve methods or DELETE for delete methods, + - description of the method, + - request parameters - parameter name, type, parameter type, and description + - response format includes return parameters, type, and description. + +[![](/learn/assets/API_soap.png)](/learn/assets/API_soap.png) + +- The user can also test the API from the test tab, by passing values to the parameters and using the TEST button. + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/backend-architecture.md b/website/versioned_docs/version-v11.8.5/app-development/services/backend-architecture.md new file mode 100644 index 000000000..afe87350c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/backend-architecture.md @@ -0,0 +1,55 @@ +--- +title: "Backend Services Architecture" +id: "backend-architecture" +--- +Get an overview of backend services in WaveMaker and see how it works. + +--- + +[![](/learn/assets/backend_model.png)](/learn/assets/backend_model.png) + +## Micro-Services enabled Architecture + +To support micro-services architecture, WaveMaker uses an API-driven app development approach wherein REST APIs are generated automatically for the application. Every backend service such as Database Entity, Queries or Custom Java code, that is integrated into an application generates REST APIs. Some of these APIs are available for further customization based on the app integration needs. + +[![](/learn/assets/services_concept.png)](/learn/assets/services_concept.png) ORM Layer is auto-generated from DB schema using Hibernate & JPA. Services Layer is auto-generated using Spring. Custom queries, procedures, and Java Services can be used to extend the app functionality. For all these services, REST API is auto-generated using Spring-REST/Swagger. Variables interact with REST API layer to access the services. + +## Accessing Data - Variables + +A **Variable** is a non-visual component that is used to call web services, custom database queries and Java methods. Variables can be invoked by Service Calls and by handling the call events. Using variable events ensures: + +- The service call has returned. +- Errors returned from the service calls are handled. +- The result set is available. + +### Life-cycle of Variable + +The graphic below represents the life-cycle of the variable. + +[![](/learn/assets/sevice_var_lifecycle.png)](/learn/assets/sevice_var_lifecycle.png) + +1. A user invokes the variable call through an action. For example, click a button. +2. An event is emitted and event controller watches over the event. +3. Event controller requests the variable information from the base service. +4. Event controller calls the update method on the “Variable” service. +5. The Service makes a call to the rest service along with the parameters passed. +6. The response is returned which is handled by the Service. It also invokes the events after getting the data. +7. The response data is updated in the variable +8. The widgets listening to the data change on the variable gets updated. + +## Manipulating Data - Variable Events + +### Life-cycle Events of Variable + +Given the life cycle of a variable, next step would be to capture and control the flow to include validation, pre and post processing of data. + +A typical event flow when a variable is used to update data would be as follows: + +[![](/learn/assets/LSV_eventcycle.png)](/learn/assets/LSV_eventcycle.png) + +## REST APIs + +As mentioned earlier, each of the services integrated into your app is converted to a RESTful service and are consumed through their respective REST APIs.These REST APIs are exposed via the [API Designer](/learn/assets/API_Access.png) and can be re-configured as per the application needs. + +We have given an overview of how Backend services are handled in WaveMaker. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/blob-support-queries-procedures.md b/website/versioned_docs/version-v11.8.5/app-development/services/blob-support-queries-procedures.md new file mode 100644 index 000000000..12596da99 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/blob-support-queries-procedures.md @@ -0,0 +1,56 @@ +--- +title: "Blob Support for Queries and Procedures" +id: "blob-support-queries-procedures" +--- + +BLOB datatype being large in size and amorphous in nature need to be handled separately. + +In WaveMaker, the Database services generated for each table provides an additional API for downloading the content for each BLOB column in the table and this support has been extended to Queries and Procedures post 8.5 release. + +## Use Cases for BLOB + +The following use cases are discussed in this section: + +- [Uploading BLOB data as a query parameter](#query_blob_param) +- [Handling BLOB content in query results](#query_blob_return) (single or paginated results) +- [Uploading the BLOB data as procedure parameter](#proc_blob_param) +- [Handling BLOB content as output parameter of a procedure](#proc_param_return) + +## Limitations + +- Procedures returning more than one response field and simultaneously containing BLOB field are not supported. In other words, if Blob exists in response, then no other fields should be returned. +- HQL queries with the response containing Blob columns are not supported. +- Blob response in CURSOR fields is ignored for procedures. + +### Support for uploading the BLOB data as a query parameter + +- A new param type "Blob" can be found in the Parameter section of the Query Editor. +- **Note**: This Blob type is enabled only for Insert and Update queries. +- Each Blob type column supports single file upload, i.e. not as a list. However, there can be multiple Blob params for a single query. [![](/learn/assets/blob_query_param.png)](/learn/assets/blob_query_param.png) +- When a Blob parameter exists in a query, then the generated API for such query will accept Multipart data and POST method is used irrespective of query type. + +### Handling Blob content in query results (single or paginated results) + +- When query tested in design mode has resultant data with Blob content it is depicted as a file icon and the content is not visible or available for download. +- Queries returning a PAGINATED response containing Blob field should provide **Identifier** while saving the query + - An identifier is required to uniquely identify the column in the query result. + - You can select multiple columns as Identifier. + - **Note:** You cannot save the query without Identifier. [![](/learn/assets/blob_query_save.png)](/learn/assets/blob_query_save.png) +- Separate API will be generated for each Blob field with a _Downloadable_ return type in addition to the executeQueryAPI. The response of the execute query's Blob field's value will contain the absolute URL to the Blob content. It will be null for the rows which do not have a value for that field. [![](/learn/assets/blob_query_api.png)](/learn/assets/blob_query_api.png) + +**Notes:** + +- Identifier is not required for Queries returning SINGLE response. +- HQL queries are  not  supported if they contain Blob fields in response. + +### Support for uploading the blob data as Procedure Param + +- A typical procedure with Blob input is as shown below: [![](/learn/assets/blob_proc_param.png)](/learn/assets/blob_proc_param.png) +- When param type of Blob is IN in a procedure, then the generated API for such procedure will be accepted as multipart data and the remaining fields are expected as one part with the content type `application/json`. There can be multiple Blob inputs parameters. + +### Handling Blob content as output param of a procedure + +- Procedures returning more than one response field and simultaneously containing BLOB field are not supported. In other words, if Blob exists in response, then no other fields should be returned. +- Blob response is supported only for OUT parameters. If Blob field exists in Cursor data, then it is ignored. +- If procedure consists of BLOB field in OUT param, then the generated API will return _Downloadable_ response otherwise <procedureName> Response object. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/creating-backend-services.md b/website/versioned_docs/version-v11.8.5/app-development/services/creating-backend-services.md new file mode 100644 index 000000000..f44206245 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/creating-backend-services.md @@ -0,0 +1,30 @@ +--- +title: "What are Backend Services?" +id: "creating-backend-services" +sidebar_label: "What are Backend Services?" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) section for WaveMaker app development. + +--- + +In WaveMaker, you can create an independent backend service which can be used multiple times across your app. + +A backend service can be of any type. It can be a data service, web service, java service, security service, or using a third party API. Or, even extending a feature with your own code. + +Thus, you can consider external data as a service. Based on the underlying data, you can categorize backend services as _Web Services_, _Database Services_, _Java Services_ and _Security Services_. Each service is converted to a RESTful service and is consumed through their respective REST APIs. + +## Get started with each service type + +|No.| To | See | +|---|---|---| +|1.|Get started with Database Services|[Database Services](/learn/app-development/services/database-services/database-services)| +|2.|Get started with Web Services|[Web Services](/learn/app-development/services/web-services/web-services)| +|3.|Get started with Java Services|[Java Services](/learn/app-development/services/java-services/java-service)| +|4.|Get started with Security Services|[Security Services](/learn/app-development/app-security/app-security)| + + +## REST APIs + +Services integrated into your app is converted to a RESTful service and are consumed through their respective REST APIs. These REST APIs are exposed via the [API Designer](/learn/app-development/services/api-designer/api#api-designer) and can be re-configured as per the application needs. + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-access.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-access.md new file mode 100644 index 000000000..631dd25f1 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-access.md @@ -0,0 +1,12 @@ +--- +title: "Database Access" +id: "database-access" +sidebar_label: "Accessing Database" +--- +--- +Once you have integrated a database into your application, you need a way to access the data within the database and use it from within the app. There are many ways to achieve this: + +1. Create a Variable for the Database CRUD APIs auto-generated for each table within the database. This is the easiest and most efficient way to handle the database. This Variable will be of the same structure as the table and can act as a liaison between the app and the database. [Know more about variables](/learn/app-development/variables/database-crud/). +2. [Queries](/learn/app-development/services/db-services/working-with-queries/), [Stored Procedures](/learn/app-development/services/database-services/working-stored-procedures) and [Database Views](/learn/app-development/services/database-services/database-views) can be used to manipulate data. These can be used for getting custom data, work with multiple tables and much more. +3. [Database Tools](/learn/app-development/services/database-tools/) help you in accessing the DB Shell to work with the database directly. It also has provision to run scripts to import/export database. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-crud-event-listeners.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-crud-event-listeners.md new file mode 100644 index 000000000..db10db59d --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-crud-event-listeners.md @@ -0,0 +1,216 @@ +--- +title: "Database CRUD Operations Event Listeners" +id: "database-crud-event-listeners" +sidebar_label: "CRUD Event Listeners" +--- +--- + +When you create a new database or import an existing database in WaveMaker, the WaveMaker platform generates the database service inside the WaveMaker application. + +The database service code that gets generated inside the application is layered, as shown below. + +![layered architecture](/learn/assets/event-listeners.png) + + +## Layered Architecture + +1. Controller Layer + + The Controller Layer is responsible for the HTTP request and response processing, converting to and from JSON to Java Object, etc. The Controller layer code is annotated with the Spring REST API annotations. + +2. Service Layer + + The Service layer is responsible for static validations, transactional boundaries and invokes the respective DAO methods for object persistence. + +3. DAO layer + + The DAO layer is responsible for communicating with the database. It maintains a pool of connections with the database and uses Hibernate ORM for persistence. + +### Generated Code and Syncing Database + +The generated code is always in sync with the database schema. If any changes are made externally to the database schema, the respective database must be reimported, thus making the code regenerated to keep the code & schema in sync. + +:::note +The platform manages the generated code, and therefore it does not allow any modifications to it or add the custom business logic. +::: + +### Database CRUD Operations + +In most cases, the application developers should have control on the database CRUD operations to perform the following scenarios: + +1. Dynamic Validations +2. Custom Business Logic +3. Authorization checks / Row-level security +4. Encrypt or Decrypt the field values +5. Set default/override values during insert/update +6. Invoke additional services for integration +7. Audit history for the data changes etc + +:::note +The generated code is not editable to include the above use-cases when performing database operations. +::: + +To address all the above use-cases, WaveMaker introduces Event Listeners for the typical database operations. + +## Listen and Handle Events + +WaveMaker’s application runtime framework publishes the entity CRUD event during the respective database operation. Each of the operations, aka Create, Read, Update and Delete, publishes two events - they are pre and post-operation events. The WaveMaker application developer should listen to the “interested” events and handle the respective events in a Java Service. + +Each event extends [EntityCRUDEvent](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/data/event/EntityCRUDEvent.java). The class has methods to get the serviceId and entityClass for which the event is generated. + +The events can be listened to using the [@EventListener](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/event/EventListener.html) or [@TransactionalEventListener](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/event/TransactionalEventListener.html) annotations. + +## List of Events for CRUD Operations + +### [EntityPreCreateEvent](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/data/event/EntityPreCreateEvent.java) + +Published before creating an entity in the database. This event will get the handle of the entity object being created. + +### [EntityPostCreateEvent](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/data/event/EntityPostCreateEvent.java) + +Published after creating the entity in the database. This event will get the handle of the entity object created. + +### [EntityPreUpdateEvent](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/data/event/EntityPreUpdateEvent.java) + +Published before updating the entity in the database. This event will get the handle of the entity object being updated. + +### [EntityPostUpdateEvent](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/data/event/EntityPostUpdateEvent.java) + +Published after updating the entity in the database. This event will get the handle of the updated entity object. + +### [EntityPreDeleteEvent](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/data/event/EntityPreDeleteEvent.java) + +Published before deleting an entity from the database. This event will get the handle of entityid, which is to be deleted. + +### [EntityPostDeleteEvent](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/data/event/EntityPostDeleteEvent.java) + +Published after deleting the entity from the database. This event will get the handle of the entity that is deleted. + +### [EntityPreFetchListEvent](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/data/event/EntityPreFetchListEvent.java) + +Published before fetching the list of records from the database. This event will get the handle of the query string used for filtering the entities. + +### [EntityPostFetchListEvent](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/data/event/EntityPostFetchListEvent.java) + +Published after retrieving the list of records from the database. This event will get the handle of the pageable response. + +### [EntityPreFetchEvent](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/data/event/EntityPreFetchEvent.java) + +Published before fetching a record from the database. This event will get the handle of the entity ID. + +### [EntityPostFetchEvent](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/data/event/EntityPostFetchEvent.java) + +Published after fetching a record from the database. This event will get the handle of the entity object. + + +## Imports + +Below are some of the class imports used in the examples shown below + +``` +import [org.springframework.context.event.EventListener;](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/event/EventListener.html) +import [org.springframework.transaction.event.TransactionEventListener;](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/event/TransactionalEventListener.html) +import [org.springframework.transaction.event.TransactionPhase;](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/event/TransactionPhase.html) +import [com.wavemaker.commons.WMRuntimeException;](https://github.com/wavemaker/wavemaker-commons/blob/master/wavemaker-commons-util/src/main/java/com/wavemaker/commons/WMRuntimeException.java) +import [com.wavemaker.commons.MessageResource;](https://github.com/wavemaker/wavemaker-commons/blob/master/wavemaker-commons-util/src/main/java/com/wavemaker/commons/MessageResource.java) +``` + +## Events Listeners with Examples + +Below are some examples of listening to events, assuming sample HRDB is added into the project, with four tables, including User, Department, Employee, and Vacation. You can include the code snippet given below in any of the Java services in the application. + +### Handling Business Logic During User Creation Process + +```java +@EventListener +public void beforeUserEntityCreate(EntityPreCreateEvent entityPreCreateEvent) { + User user = entityPreCreateEvent.getEntity(); + if (user.getRole().equals("0")) { // validations + throw new WMRuntimeException(MessageResource.create("invalid_role")); //invalid_role is a key added in project 18n list + } + if (StringUtils.isBlank(user.getPassword())) { + user.setPassword("wavemaker123"); // Updating entity values + } + logger.info("Inside user {} pre create event listener for {}", user, entityPreCreateEvent.getEntityClass()); //Logging + } +``` + +:::important +1. To listen to each entity, you need to write a separate method using the respective Generic as the parameter in the method. +2. Any exception thrown from the above method will stop the create operation, and the error message will be sent to the caller. +::: + +### Listen to User Post Creation Event + +```java +@EventListener +public void afterUserEntityCreate(EntityPostCreateEvent entityPostCreateEvent) { + User user = entityPostCreateEvent.getEntity(); + logger.info("Inside user {} post create event listener for {}", user, entityPostCreateEvent.getEntityClass()); //Logging +} +``` + +:::important +1. To listen to each entity, you need to write a separate method using the respective Generic as the parameter in the method. +2. The code written in the EventListener for postCreateEvent will participate in the same transaction as the create operation. Hence any exception thrown from this method will roll back the create operation, and the exception message will be sent to the caller. +::: + +### Listen to User Creation Event only on Successful Transaction Commit + +```java +@TransactionEventListener(phase = TransactionPhase.AFTER_COMMIT) +public void afterUserEntityCreate(EntityPostCreateEvent entityPostCreateEvent) { + User user = entityPostCreateEvent.getEntity(); +emailService.sendMailWithSimpleMessage("","new user", "new user joined"); // Calling other services in the project +} +``` + +:::important +1. To listen to each entity, you need to write a separate method using the respective Generic as the parameter in the method. +2. The code is written in the @TransactionEventListener(phase = TransactionPhase.AFTER_COMMIT) for postCreateEvent will be executed only after the successful transaction commit of the create operation. +3. Any exception thrown from this method will not have any impact on the create operation. However, the exception message will be sent to the caller. +::: + +### Listen to All Entities Creating Event Listeners with Exception for Generic Types + +To listen on all entities creating event listeners, remove the generic type in the Event Listener’s method declaration. This can be helpful to achieve cross-cutting concerns like operations logging or metrics collection or common validations across all entities. + +```java +@EventListener +public void beforeEntityCreate(EntityPreCreateEvent entityPreCreateEvent) { + logger.info("Inside generic pre create event listener for {}", entityPreCreateEvent.getEntityClass(), entityPreCreateEvent); +} +``` + +:::important +1. This listener will be called when an entity of any type is created in the database. +2. In case if there are multiple databases imported, this method will be called for all those entities across all the imported databases. +3. It is recommended to use the respective entity-specific events unless you want to handle the common logic same across all entities. +4. Any exception thrown from this method will stop the create operation and the exception message will be sent to the caller. +::: + +### Listen to Events with Different Event Listener Annotation Declaration + +Suppose you have multiple database services in the application and want to listen to only one of the service’s all entity events with only different event listener annotation declarations. In that case, you can add a new condition attribute to event listener annotation. + +```java +@EventListener(condition = "#entityPreCreateEvent.serviceId eq 'hrdb'") +``` + +:::important +This listener will be called when an entity of any type is created in the database that matches the given condition. +It is recommended to use the respective entity-specific events unless you want to handle the common logic same across all entities. +Any exception thrown from this method will stop the create operation, and the exception message will be sent to the caller. +::: + +:::note +Update and delete events work similarly with update having the entity information in its event object and deleting the entityId information in its pre-event object. + + +::: + +## Use Cases + +[Record Transactional History of an Entity](/learn/how-tos/audit-history-using-crud-listeners) +[Performing Dynamic Validations using CRUD Listeners](/learn/how-tos/validations-using-crudListeners) +[Custom Business Logic using DB CRUD Event Listeners](/learn/how-tos/custom-business-logic-using-crud-event-listeners) diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services.md new file mode 100644 index 000000000..4247a5092 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services.md @@ -0,0 +1,67 @@ +--- +title: "Database Services" +id: "database-services" +--- +--- + +A _database_ is the most common form of data storage for any enterprise and apps need to interact with these databases to define the workflow. + +WaveMaker makes it easy to create web-based forms that are connected to an underlying database. To access a database from your WaveMaker application, you first create a new data model or import an existing data model into the project. + +Import or creation of database within a WaveMaker app results in the generation of REST APIs. Each of the services integrated into your app is converted to a RESTful service and is consumed through their respective REST APIs. These REST APIs are exposed via the [API Designer](/learn/assets/API_Access.png) and can be tested and reconfigured as per the application needs. + +## WaveMaker DB Integration Process + +The following figure gives an overview of the Database integration process within WaveMaker App.[![](/learn/assets/db_concepts.png)](/learn/assets/db_concepts.png) + +1. Database Schema from an external RDBMS is imported into the app. This import includes the Data Model consisting of Tables, Columns, Relationships between tables and Constraints. +2. An ORM layer is auto-generated from the above DB Schema using Hibernate and JPA. A service layer is also auto-generated using Spring. +3. You, as an App Developer, can access the Entities from the ORM Layer, write custom queries, procedures and Java Services to extend the database functionality. +4. For each entity, query, procedure and Java service, a REST API is auto-generated using Spring-REST and Swagger. +5. Variables need to be created to interact with the REST API layer to access the database services. These variables will, in turn, be bound to Widgets to allow user interaction with the data. + +## DB Workflow + +When you integrate your WaveMaker app with any database, you set up the connection details and enable your app to interact with the Database. There are two forms of Database interaction: + +- during design time to generate files for use within the app, and +- during runtime to access the data and work with it. + +[![](/learn/assets/db_integrate_process.png)](/learn/assets/db_integrate_process.png) **Design Time Studio App behavior**: From the WaveMaker app: + +1. when you add DB to WaveMaker app, it results in a request for metadata to the corresponding external Database, based upon the connection settings, +2. the external Database returns the metadata, +3. this returned metadata is used to generate files which will be used within the app. + +**Note**: The database is not replicated or copied into the Studio. + +**Run Time Studio App behavior**: During the run mode, when database call is triggered by user interaction: + +1. a database call in the form of a CRUD operation is made by the app +2. the call is forwarded to the external Database with the help of the generated files + +For an in-depth understanding of the ORM layers generated, their functionality and code generated for the Database Integration, refer to [ORM Artifacts](/learn/app-development/services/database-services/orm-artifacts/). + +## WaveMaker Supported Databases and their Versions + +WaveMaker supports the following databases and versions and the same can be used within your app. + +| Database Name | Version | Driver Jar | +| --- | --- | --- | +| [![](/learn/assets/MariaDB.png)](/learn/assets/MariaDB.png) | 10.2 | Available in Maven Repo | +| [![mysql](/learn/assets/mysql.png)](/learn/assets/mysql.png) | 5.5 | Available in Maven Repo | +| 5.6 | +| 5.7 | +| [![PostgreSQL](/learn/assets/PostgreSQL.png)](/learn/assets/PostgreSQL.png) PostgreSQL | 9.4 | Available in Maven Repo | +| 9.5 | +| [![Oracle](/learn/assets/Oracle.png)](/learn/assets/Oracle.png) | 11.2 | [download ojdbc6.jar from here](http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html) | +| 12.1 | [download ojdbc7.jar from here](http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html) | +| 12.2 | [download ojdbc8.jar from here](http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html) | +| [![SQLServer](/learn/assets/SQLServer.png)](/learn/assets/SQLServer.png) SQL Server | 2014 | [Steps to Download sqljdbc4.2.jar](/learn/app-development/services/database-services/download-jdbc-driver-jar/) +(you can use JDBC driver 4.2, 6.0, 6.1 or 6.2, ensure that you import  **sqljdbc42.jar** or any Java ver 8 compatible jar file) | +| Azure SQL Database [Connect to Azure](/learn/how-tos/connect-azure-sql-server/) | +| [![DB2](/learn/assets/DB2.png)](/learn/assets/DB2.png) | 10.1 | [db2jcc4.jar](http://www-01.ibm.com/support/docview.wss?uid=swg21363866) | +| 11.1 | +| [![HSQLDB](/learn/assets/HSQLDB.png)](/learn/assets/HSQLDB.png) | 2.3.3 | Available in Maven Repo | +| 2.3.4 | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services/blob-support-queries-procedures.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/blob-support-queries-procedures.md new file mode 100644 index 000000000..804f1e62e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/blob-support-queries-procedures.md @@ -0,0 +1,76 @@ +--- +title: "Blob Support for Queries and Procedures" +id: "blob-support-queries-procedures" +sidebar_label: "Blob Queries and Procedures" +--- +--- + +BLOB datatype being large in size and amorphous in nature need to be handled separately. + +In WaveMaker, the Database services generated for each table provides an additional API for downloading the content for each BLOB column in the table and this support has been extended to Queries and Procedures post 8.5 release. + +## Use Cases for BLOB + +The following use cases are discussed in this section: + +- Uploading BLOB data as a query parameter +- Handling BLOB content in query results +- Uploading the BLOB data as procedure parameter +- Handling BLOB content as output parameter of a procedure + +## Limitations + +- Procedures returning more than one response field and simultaneously containing BLOB field are not supported. In other words, if Blob exists in response, then no other fields should be returned. +- HQL queries with the response containing Blob columns are not supported. +- Blob response in CURSOR fields is ignored for procedures. + +## Uploading the BLOB data as a query parameter + +- A new param type "Blob" can be found in the Parameter section of the Query Editor. + +:::note +This Blob type is enabled only for Insert and Update queries. +::: + +- Each Blob type column supports single file upload, i.e. not as a list. However, there can be multiple Blob params for a single query. + +[![](/learn/assets/blob_query_param.png)](/learn/assets/blob_query_param.png) + +- When a Blob parameter exists in a query, then the generated API for such query will accept Multipart data and POST method is used irrespective of query type. + +## Handling Blob content in query results (single or paginated results) + +- When query tested in design mode has resultant data with Blob content it is depicted as a file icon and the content is not visible or available for download. +- Queries returning a PAGINATED response containing Blob field should provide **Identifier** while saving the query + - An identifier is required to uniquely identify the column in the query result. + - You can select multiple columns as Identifier. + +:::note +You cannot save the query without Identifier. +::: + +[![](/learn/assets/blob_query_save.png)](/learn/assets/blob_query_save.png) + +- Separate API will be generated for each Blob field with a _Downloadable_ return type in addition to the executeQueryAPI. The response of the execute query's Blob field's value will contain the absolute URL to the Blob content. It will be null for the rows which do not have a value for that field. + +[![](/learn/assets/blob_query_api.png)](/learn/assets/blob_query_api.png) + +:::note +- Identifier is not required for Queries returning SINGLE response. +- HQL queries are  not  supported if they contain Blob fields in response. +::: + +## Support for uploading the blob data as Procedure Param + +- A typical procedure with Blob input is as shown below: + +[![](/learn/assets/blob_proc_param.png)](/learn/assets/blob_proc_param.png) + +- When param type of Blob is IN in a procedure, then the generated API for such procedure will be accepted as multipart data and the remaining fields are expected as one part with the content type `application/json`. There can be multiple Blob inputs parameters. + +## Handling Blob content as output param of a procedure + +- Procedures returning more than one response field and simultaneously containing BLOB field are not supported. In other words, if Blob exists in response, then no other fields should be returned. +- Blob response is supported only for OUT parameters. If Blob field exists in Cursor data, then it is ignored. +- If procedure consists of BLOB field in OUT param, then the generated API will return _Downloadable_ response otherwise <procedureName> Response object. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services/data-modelling.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/data-modelling.md new file mode 100644 index 000000000..13a025796 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/data-modelling.md @@ -0,0 +1,72 @@ +--- +title: "Data Modelling" +id: "data-modelling" +--- +--- +A **data model** describes the structure of the database: the tables, columns, keys, and relationships. The data model for imported databases can be viewed from within the app using **DB Designer**. DB Designer for a specific database can be accessed by selecting the _database_ from the **Databases** Resource option**.** + +[![](/learn/assets/db_designer_open.png)](/learn/assets/db_designer_open.png) + +## Configuration Settings + +**Settings tab** can be used to interact with the database and ensure that the data model is in sync with the database. It shows the connection settings of the selected database. + +:::note +- All these options are available **ONLY** for Data Model in **Edit Mode**. +- DB Schemas for HSQL and for databases categorized as "Other Databases" at the time of import cannot be edited and hence are rendered as Read-Only schemas. +::: + +From this tab you can: + +| Action | Description | +| --- | --- | +| | **Re-import** enables you to build the data model from the database again. This would bring in changes made to the database and will revert all changes done by the database designer. | +| | **Export** will move the data model to the database of your choice. You can choose to export to the current database or to a different database. **NOTE: You can only export to the same database system as the original import, you can change the database but not the database system.** | +| | **Save** Database will save the db in your app workspace, this is the draft copy of the database solely available to your app. | +| | **Delete** would delete the data model from the app. | + +## Advanced Settings + +Apart from the basic Database settings like host details, schema name etc., WaveMaker provides some **advanced database configuration options**. + +| Setting | Description | +| --- | --- | +| **Java Package** | WaveMaker generates Java classes for you when you import a database. If you want a different Java package name than the default name we generate, type it in here. | + +## Database Designer + +**Design tab** renders the database components – tables, columns, and relationships. [![](/learn/assets/db_designer_schema.png)](/learn/assets/db_designer_schema.png) + +Using this tab, you can: + +| Action | Description | +| --- | --- | +| +Table | **Add** tables | +| | **Delete** tables | +| | **Search** for tables within the designer | +| | **Update DB** with the changes made from the DB Designer. A preview dialog will open which will list all the changes made to the DB. Script tab will show the same changes in script format. | +| | **Revert DB** designer to undo any changes made. **Note** this will not get any changes made to the database, use Re-Import for that. | +| | **Re-import** enables you to build the data model from the database again. This would bring in changes made to the database and will revert all changes done from the database designer. | +| | **Save** database will save the changes to your workspace. **Note** to save it to the database use the Update DB option. | +| **Table Modification** upon selecting a table | +| Name | change the name of the tables | +| ADD COLUMN | add columns, [know more](/learn/app-development/services/database-services/working-database-schema/#add-tables-columns) | +| **Primary Key** configuration | +| Type | can be single or composite | +| Select Column | Column (columns in case of composite key) to be set as primary key | +| Generator Type | how the primary key columns gets its values - assigned - user entry or auto increment - for integer type, [know more](/learn/app-development/services/database-services/working-database-schema/#identity-generators) | +| **Unique Constraints** | +| Name | Columns whose values need to be restricted as unique | +| **Column modifications** for selected column | +| Name | | +| SQL and Java Types | It is advisable to make changes to Java Types rather than SQL Types unless you want the changes to be reflected in the database, in which case you need to export the database. You can review the type conversion from Java to SQL type from this document: [Java Types vs SQL Data Types](/learn/assets/JavaTypesVsDBTypes-Sheet.pdf) | +| Constraints | Nullable or not. NOTE: Primary Key and Unique Kay constraints need to be modified at the Table level. Foreign Key constraint can be modified from the respective Relation | +| **Relations** between tables | +| | Relations cannot be modified, you need to delete and add a new relation if needed, [know more](/learn/app-development/services/database-services/working-database-schema/#database-relationships). | + + +:::note +- Any changes made to the database design, needs to be **Exported/Updated** for the changes to be synced with the database. Save alone does not ensure syncing. +- Design changes are restricted to Data Model in Edit Mode. For Read-Only DBs, HsqlDB, DB2 and other databases design modifications are restricted to Java Type changes and virtual relation settings. [Know more about import modes from here](/learn/app-development/services/database-services/database-schema-import-modes/) +::: + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services/database-schema-import-modes.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/database-schema-import-modes.md new file mode 100644 index 000000000..42022129c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/database-schema-import-modes.md @@ -0,0 +1,58 @@ +--- +title: "DataBase Schema Import Modes" +id: "database-schema-import-modes" +sidebar_label: "DataBase Schema Modes" +--- +--- +## Introduction + +When importing a database into WaveMaker, it connects to database, reads the schema, generates the sources and shows all the tables/views along with their relations in the Database Designer. Apart from displaying, the DB designer has a provision to make changes to the schema and update the underlying Database. + +There are cases where the database schema has to be managed outside of the WaveMaker by a DBA or someone else. In such cases, the DB designer should not allow the changes to the Database. To ensure the read-only schema behavior for the imported database, WaveMaker provides an option to import the schema in READ-ONLY mode. + +## Schema Import Modes + +There are two modes in which the database schema can be imported: + +- Read-Only Mode +- Editable Mode + +You can import the database in any mode according to the requirement. Read-Only is the default mode for all the newly imported databases. However, you have an option to set the mode at the time of DB import or change it at a later time from the settings tab. + +:::note +The credentials (password) that is used while importing DB schema is encoded using WaveMaker specific algorithm and is saved to the development profile. +::: + +### Read-Only Mode + +Once the database is imported in this mode, the DB designer will be opened in the read-only and will not permit any schema changes that affect the database. + +[![](/learn/assets/db_import_readonly.png)](/learn/assets/db_import_readonly.png) + +However, there are certain features that are allowed that do not affect the underlying schema such as but are reflected in the code generation: + +- Virtual Primary key +- Virtual Relations +- Java Type Changes etc. + +### Editable Mode + +In this mode, the database designer will allow the developer to make changes to the imported schema and these changes are captured. If there are any changes that are local (not reflected in the database), a message will be displayed prompting you to update the DB. + +When the DB designer has some changes in the draft, then you have two options: + +#### 1. Update the Database +If you choose the **Update** the database with the draft changes, it will list all the changes done by the user and also shows the SQL script that will get executed. You can review the changes before update. + +#### 2. Revert the changes +On clicking **Revert** the draft changes will be discarded and the DB designer & source code will be in sync with the database schema. + +## Changing schema mode post import + +For databases in Edit Mode, the schema mode can be changed anytime from the settings tab after importing the database and then click on save to enable the Database Designer in the selected mode. + +### Limitations + +- Import schema mode is given for avoiding accidental changes to the database. Any user either owner/developer can change the mode at any point of time from the **Settings** tab as shown in the previous section. +- There are certain databases for which WaveMaker itself does not allow editing of the importing database such as HQL, DB2, and any other custom database. For those databases, the default mode is READ-ONLY and cannot be changed. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services/database-services.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/database-services.md new file mode 100644 index 000000000..7d2e06f02 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/database-services.md @@ -0,0 +1,66 @@ +--- +title: "Database Services Overview" +id: "database-services" +--- +--- + +A database is the most common form of data storage for any enterprise and apps that need to interact with these databases to define the workflow. + +[![](/learn/assets/db_new.png)](/learn/assets/db_new.png) + +WaveMaker makes it easy to create web-based forms that are connected to an underlying database. To access a database from your WaveMaker application, you first create a new data model or import an existing data model into the project. + +Import or creation of database within a WaveMaker app results in the generation of REST APIs. Each of the services integrated into your app is converted to a RESTful service and is consumed through their respective REST APIs. These REST APIs are exposed via the [API Designer](/learn/assets/API_Access.png) and can be tested and reconfigured as per the application needs. + + +## Database Integration Process + +The following figure gives an overview of the Database integration process within WaveMaker App.[![](/learn/assets/db_concepts.png)](/learn/assets/db_concepts.png) + +1. Database Schema from an external RDBMS is imported into the app. This import includes the Data Model consisting of Tables, Columns, Relationships between tables and Constraints. +2. An ORM layer is auto-generated from the above DB Schema using Hibernate and JPA. A service layer is also auto-generated using Spring. +3. You, as an App Developer, can access the Entities from the ORM Layer, write custom queries, procedures and Java Services to extend the database functionality. +4. For each entity, query, procedure and Java service, a REST API is auto-generated using Spring-REST and Swagger. +5. Variables need to be created to interact with the REST API layer to access the database services. These variables will, in turn, be bound to Widgets to allow user interaction with the data. + +## Database Workflow + +When you integrate your WaveMaker app with any database, you set up the connection details and enable your app to interact with the Database. There are two forms of Database interaction: + +- during design time to generate files for use within the app, and +- during runtime to access the data and work with it. + +[![](/learn/assets/db_integrate_process.png)](/learn/assets/db_integrate_process.png) **Design Time Studio App behavior**: From the WaveMaker app: + +1. when you add DB to WaveMaker app, it results in a request for metadata to the corresponding external Database, based upon the connection settings, +2. the external Database returns the metadata, +3. this returned metadata is used to generate files which will be used within the app. + +:::note +The database is not replicated or copied into the Studio. +::: + +### Run Time Studio App behavior +During the run mode, when database call is triggered by user interaction: + +1. a database call in the form of a CRUD operation is made by the app +2. the call is forwarded to the external Database with the help of the generated files + +For more understanding of the ORM generated layers, their functionality and code generated for the Database Integration, see [ORM Artifacts](/learn/app-development/services/database-services/orm-artifacts/). + +## Supported Databases and Versions + +WaveMaker supports the following databases and versions and the same can be used within your app. + +| Database Name | Version | Driver Jar | +| --- | --- | --- | +|[![](/learn/assets/MariaDB.png)](/learn/assets/MariaDB.png)| 10.2.8 | Available in Maven Repo. The dependency is automatically added in the pom.xml file. | +|[![mysql](/learn/assets/mysql.png)](/learn/assets/mysql.png)|- 5.7 - 8.0.21 | Available in Maven Repo. The dependency is automatically added in the pom.xml file. | +|[![PostgreSQL](/learn/assets/PostgreSQL.png)](/learn/assets/PostgreSQL.png) PostgreSQL |- 9.6 - 10 - 11 - 12 - 13 | Available in Maven Repo. The dependency is automatically added in the pom.xml file. | +| [![Oracle](/learn/assets/Oracle.png)](/learn/assets/Oracle.png) |- 12c - 18c - 19c |Refer [recommended JDBC driver versions here](/learn/app-development/services/database-services/download-jdbc-driver-jar#oracle).| +| [![SQLServer](/learn/assets/SQLServer.png)](/learn/assets/SQLServer.png) SQL Server | - 2016 - 2017 - 2019 - Azure SQL [Connect to Azure](/learn/how-tos/connect-azure-sql-server/) | Refer [recommended JDBC driver versions here](/learn/app-development/services/database-services/download-jdbc-driver-jar#sqlserver).| +| [![DB2](/learn/assets/DB2.png)](/learn/assets/DB2.png) |- 10.5 - 11.1 - 11.5|Refer [recommended JDBC driver versions here](/learn/app-development/services/database-services/download-jdbc-driver-jar#db2). | +| [![Redshift](/learn/assets/Redshift.png)](/learn/assets/Redshift.png) |- 8.0.2 | Available in Maven Repo. The dependency is automatically added in the pom.xml file. | +| [![SAP HANA](/learn/assets/SAP_HANA.png)](/learn/assets/SAP_HANA.png) |- 4 | Available in Maven Repo. The dependency is automatically added in the pom.xml file. | +| [![HSQLDB](/learn/assets/HSQLDB.png)](/learn/assets/HSQLDB.png) |- 2.4.1 - 2.5.1 | Available in Maven Repo. The dependency is automatically added in the pom.xml file. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services/database-views.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/database-views.md new file mode 100644 index 000000000..cb1347da4 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/database-views.md @@ -0,0 +1,13 @@ +--- +title: "Database Views" +id: "database-views" +--- + +WaveMaker provides support for importing Database Views into WaveMaker applications with some limitations. + +1. Views imported into Database Designer are _read-only_ hence their metadata cannot be altered or modified i.e. no support for adding/editing/deleting of columns or their metadata. +2. Views _do not have a primary key_, hence hibernate marks all the columns as primary keys thus making it composite key. You can overcome this situation by defining Virtual Primary Key. [Know more about Virtual Primary Keys](/learn/app-development/services/database-services/working-database-schema/#virtual-primary-keys). +3. If any _non-numeric column is null_, then the whole row is returned as an empty row. This is a limitation with Hibernate. ([https://hibernate.atlassian.net/browse/HHH-177](https://hibernate.atlassian.net/browse/HHH-177)). Again, Virtual Primary Keys help you handle such situations. [Know more about Virtual Primary Keys](/learn/app-development/services/database-services/working-database-schema/#virtual-primary-keys). +4. Care should be taken when using Views to _insert/update rows_ into the underlying tables, especially when the View is formed as a join of multiple tables. It is recommended that you handle such cases at the database level using triggers, etc.. +5. _Changes made to the underlying tables_ are not reflected in Views automatically and since there is no provision to update a view from DB Designer, you have to manually make such updates to the View in the database and re-import the database. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services/download-jdbc-driver-jar.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/download-jdbc-driver-jar.md new file mode 100644 index 000000000..b6f3ad49d --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/download-jdbc-driver-jar.md @@ -0,0 +1,50 @@ +--- +title: "Recommended JDBC Driver Versions for Databases" +id: "download-jdbc-driver-jar" +--- +--- + +This document provides you with the recommended Java Database Connectivity (JDBC) driver versions for the respective database versions supported for Studio integration. + +## Download JDBC Drivers + +:::important +- The following download URLs will redirect you to an external page, i.e., the JDBC driver download page for the respective database. +- Please ensure that you import any Java 8 compatible jar file. +::: + +### Oracle + +| Oracle Database Versions | Download Driver | +| ---| --- | +| Oracle 12c | [ojdbc7.jar](https://www.oracle.com/database/technologies/jdbc-drivers-12c-downloads.html)| +| Oracle 18c | [ojdbc8.jar](https://www.oracle.com/database/technologies/appdev/jdbc-ucp-183-downloads.html)| +| Oracle 19c |[ojdbc8.jar](https://www.oracle.com/database/technologies/appdev/jdbc-ucp-19-6-c-downloads.html) | + +### SQLServer + +| SQL Server Database Versions | Download Driver | +| --- | --- | +| SQL Server 2016| [Driver 9.2](https://docs.microsoft.com/en-us/sql/connect/jdbc/download-microsoft-jdbc-driver-for-sql-server?view=sql-server-2016)| +| SQL Server 2017| [Driver 9.2](https://docs.microsoft.com/en-us/sql/connect/jdbc/download-microsoft-jdbc-driver-for-sql-server?view=sql-server-2017) | +| SQL Server 2019| [Driver 9.2](https://docs.microsoft.com/en-us/sql/connect/jdbc/download-microsoft-jdbc-driver-for-sql-server?view=sql-server-ver15) | +| Azure SQL | [Driver 9.2](https://docs.microsoft.com/en-us/sql/connect/jdbc/download-microsoft-jdbc-driver-for-sql-server?view=sql-server-ver15) | + + +### DB2 + +|DB2 Database Versions| Download Driver | +| --- | --- | +| v10.5 | [db2jcc4.jar](https://www.ibm.com/support/pages/db2-jdbc-driver-versions-and-downloads) | +| v11.1 | [db2jcc4.jar](https://www.ibm.com/support/pages/db2-jdbc-driver-versions-and-downloads) | +| v11.5 | [db2jcc4.jar](https://www.ibm.com/support/pages/db2-jdbc-driver-versions-and-downloads) | + +:::note +- All the above download URLs will redirect you to an external page to download the respective driver zip. +- Once you download them, extract the downloaded file. + +For example, select and upload **`mssql-jdbc-9.2.1.jre8.jar`** +Typically, located in: `/sqljdbc_9.2/enu/` +::: + +Please see the [document](/learn/app-development/services/database-services/database-services#supported-databases-and-versions) to learn about the supported database versions to integrate them into your application. diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services/invoking-queriesprocedures-java-services.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/invoking-queriesprocedures-java-services.md new file mode 100644 index 000000000..40efec28c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/invoking-queriesprocedures-java-services.md @@ -0,0 +1,35 @@ +--- +title: "Invoking Queries/Procedures from Java Services" +id: "invoking-queriesprocedures-java-services" +sidebar_label: "Queries & Procedures - Java Services" +--- +--- +As mentioned in previous documents, there will be a service method generated for each query and procedure. See here for [query service methods](/learn/app-development/services/database-services/working-with-queries/#query-architecture) and [procedure service methods](/learn/app-development/services/database-services/working-stored-procedures/#procedure-architecture). We can use these methods to invoke those in java services. + +## Autowiring of Services +You can inject query and procedure services using spring dependency injection. + +Example: +``` +@Autowired +private HrdbQueryExecutorService queryExecutor; +``` +## Invocation of Services +As specified each query and procedure have a method in the service layer. You can call these methods to execute the query or procedure. + +[![](/learn/assets/queryproc_java.png)](/learn/assets/queryproc_java.png) + +## Securing Query/Procedure APIs + +There are two ways to configure API visibility: + +### Security +You can configure API permissions from Security dialog. Here you can configure which user can access a particular API depending on User Roles. + +[![](/learn/assets/queryproc_security.png)](/learn/assets/queryproc_security.png) + +### API Designer +From API Designer you can configure API visibility by changing Visibility options. + +[![](/learn/assets/queryproc_api.png)](/learn/assets/queryproc_api.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services/orm-artifacts.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/orm-artifacts.md new file mode 100644 index 000000000..57d7ff4a1 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/orm-artifacts.md @@ -0,0 +1,303 @@ +--- +title: "ORM Artifacts" +id: "orm-artifacts" +--- +--- + +Integration of WaveMaker app with database generates few files, services, and APIs. These are used internally by WaveMaker to achieve the seamless integration. This information is for advanced developers who want more control or need more information for academic interests. + +## Layered Architecture + +When a database is integrated into a WaveMaker app, it generates the source code for CRUD operations for each entity within the database. In addition to the CRUD APIs, the filter, count, and export APIs are also generated. Associated APIs in the case of related tables are also generated. + +The source code is generated with the ORM, Service Layer & REST APIs with each layer having a specific responsibility: + +- **Layer 1: REST Controller** is responsible for transporting the data between client and server, authorization of APIs & marshaling and unmarshaling of the model to JSON etc. +- **Layer 2: Service Layer** is responsible for validating the inputs and transaction management +- **Layer 3: DAO Layer** is responsible for interacting with the underlying database + +The following diagram depicts the Layered Architecture mentioned above: + +[![](/learn/assets/db_architecture.png)](/learn/assets/db_architecture.png) + +## Generated Files + +The folder structure for the generated code is as follows: + +1. Controllers generated for entities (one for each entity), queries and procedures: + +[![](/learn/assets/db_files_controller.png)](/learn/assets/db_files_controller.png) + +2. Data Access Objects (DAO) for each of the entities: + +[![](/learn/assets/db_files_dao.png)](/learn/assets/db_files_dao.png) + +3. Service Interfaces and Service Implementations for entities, queries, and procedures + +[![](/learn/assets/db_files_services.png)](/learn/assets/db_files_services.png) + +4. POJOs for each entity + +[![](/learn/assets/db_files_pojo.png)](/learn/assets/db_files_pojo.png) + +Each of the layers performs its function and delegates the call to the next layer in the chain. For example, after the unmarshaling of the JSON data to the model, and authorization checks, the REST layer delegates the call to the service layer, and more. + +### Design time Configuration Files + +It contains files required for designing database. + +- **`db-connection-settings.json`**: it contains connection properties. +- **`servicename_API.json`**: Generated API specification (swagger) of given service. +- **`servicename_procedure.json`**: contains information regarding procedures for that service. +- **`servicename_query.json`**: contains information regarding query for that service. +- **`servicename_published_datamodel.json`**: contains database schema information. It plays a major role while updating DB changes. Whenever you do manual changes in the database you have to re-import to update this file. +- **`servicename_draft_datamodel.json`**: Contains user modifications. It’ll delete when we do update/re-import database. +- **`servicedef.xml`**: contains types information for this service. + +[![](/learn/assets/dbfiles.png)](/learn/assets/dbfiles.png) + +## Generated APIs for Database Services + +Import or creation of database within a WaveMaker app results in the auto-generation of ORM artifacts from the Database Schema and as such each Schema needs to have a Primary key either single or composite. + +In case your external database schema comes without a primary key, you need to assign a column(s) as virtual primary key else all the columns are treated as part of a composite primary key. For each entity imported, a REST API is generated for each of the CRUD operations, Filter and Count functionalities. These REST APIs are exposed via the API Designer and can be tested and reconfigured as per the application needs. + +[![](/learn/assets/db_apis.png)](/learn/assets/db_apis.png) + +As an example, we are using the following Employee-Department Database Schema (Sample hrdb that can be imported into Studio) with a unique constraint for `Dept_code` on the department table: + +[![](/learn/assets/db_apis_db.png)](/learn/assets/db_apis_db.png) + +**Request Mapping:** + +``` +[PROJECT_ID]/[PROJECT_NAME]/services/[SERVICE_NAME]/[ENTITY_NAME]/ +``` +#### Example: + +## CRUD APIs + +### Create +Inserts a record into the table. + +- **URL**: / +- **Request Type**: `POST` +- **Path Variables**: `None` +- **Request Parameter**: `None` +- **Request Body**: `object in JSON format ` +- **Method Name Example**: `createEmployee` + +[![](/learn/assets/db_apis_create.png)](/learn/assets/db_apis_create.png) + +### Read (primary key based) + +Retrieves the data associated with given ID value. + +- **URL**: `/{id}` +- **Request Type**: `GET` +- **Path Variables**: `primary key column value ` +- **Request Parameter**: `None` +- **Request Body**: `none` +- **Method Name Example**: `getEmployee` + +[![](/learn/assets/db_apis_readpk.png)](/learn/assets/db_apis_readpk.png) + +### Read (unique key based) +Retrieves the data associated with given unique key value. + +- **URL**: `/[UNIQUE_KEY]/{unique_key_value}` +- **Request Type**: `GET` +- **Path Variables**: `unique key column value` +- **Request Parameter**: `None` +- **Request Body**: `none` +- **Method Name Example**: `getByDeptCode` (unique key for department entity) + +[![](/learn/assets/db_apis_readuk.png)](/learn/assets/db_apis_readuk.png) + +### Read (foreign key based) +Retrieves the data associated with given ID value from the related table. +- **URL**: `/{id..+}/[relation_field]` +- **Request Type**: `GET` +- **Path Variables**: `primary key column value` +- **Request Parameter**: + - Page, + - Size, + - Sort +- **Request Body**: `none` +- **Method Name**: `findAssociatedEmployees` (employee foreign key for department entity) + +[![](/learn/assets/db_apis_readfk.png)](/learn/assets/db_apis_readfk.png) + +### READ (foreign key based - self-referential) + +Retrieves the data associated with given ID value +- **URL**: `/{id..+}/[relation_field]` +- **Request Type**: `GET` +- **Path Variables**: `primary key column value` +- **Request Parameter**: + - Page, + - Size, + - Sort +- **Request Body**: `none` +- **Method Name**: `findAssociatedEmployeesForManagerId` (foreign key) + +[![](/learn/assets/db_apis_readsr.png)](/learn/assets/db_apis_readsr.png) + +### Update +Updates entity record associated with the given id value +- **URL**: `/{id} ` +- **Request Type**: `PUT` +- **Request Type**: `primary key column value` +- **Request Parameter**: `None` +- **Request Body**: `object in JSON format` +- **Method Name Example**: `editEmployee` + +[![](/learn/assets/db_apis_update.png)](/learn/assets/db_apis_update.png) + +### Delete +Deletes entity record associated with the given id. +- **URL**: `/{id}` +- **Request Type**: `DELETE` +- **Request Type**: `primary key column value` +- **Request Parameter**: `None ` +- **Request Body**: `None` +- **Method Name Example**: `deleteEmployee` + +[![](/learn/assets/db_apis_delete.png)](/learn/assets/db_apis_delete.png) + +## Query APIs + +:::note +Though the following APIs are available in POST and GET type, GET APIs might fail if the request URL is longer than 2048. It is advisable to use POST request type. +::: + +### FILTER +Returns the list of entity instances matching the filter criteria (all values if query is not given). +- **URL**: `filter` +- **Request Type**: `POST/GET` +- **Request Type**: `None` +- **Request Parameter**: + - custom query (optional, see here for [query syntax](#custom-query-syntax)), + - Page, + - Size, + - Sort +- **Request Body**: `None` +**Method Name**: `findEmployees` + +[![](/learn/assets/db_apis_search.png)](/learn/assets/db_apis_search.png) + +### COUNT +Returns the count of filtered entity instances (total count if query not given) + +- **URL**: `/count` +- **Request Type**: `POST/GET` +- **Request Type**: `None` +- **Request Parameter**: `custom query` (optional, see here for [query syntax](#custom-query-syntax)) +- **Request Body**: `None` +- **Method Name**: `countEmployees` + +[![](/learn/assets/db_apis_count.png)](/learn/assets/db_apis_count.png) + +### EXPORT +Returns the downloadable file url for the filtered data + +- **URL**: `/export` +- **Request Type**: `POST` +- **Request Parameter**: pageable - pagination and sorting options, [see here for more](http://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/Pageable.html), + - Size, + - Sort +- **Request Body**: ExportOptions (Body) + - custom query (optional, see here for [query syntax](#custom-query-syntax)), + - fields list (optional): + ``` + [{ “header”:””, “field”:””, “expression”:”” (eg: (${field_name} (or) )) }] + ``` + - exportType - data format for export can be EXCEL or CSV + - fileName: exported file name +- **Method Name Example**: `exportEmployees` + +[![](/learn/assets/db_apis_export.png)](/learn/assets/db_apis_export.png) + +## Custom Query Syntax + +The APIs generated by WaveMaker for all the imported tables will have methods that take a query as input. Here we will look at the usage of such query in APIs. + +**APIs that use HQL Queries**: The Filter, Count and Export API in every Table Controller will use the HQL query, which is an optional parameter, for retrieving the data. These APIs can be found in respective tables’ controller class file. + +#### Filter API +This API returns the list of Entity objects that matches the given filter conditions in the query. If query param is empty, API returns all the Entity objects. + +#### Count API +Returns the count of Entities that matches the given filter conditions in the query. For an empty query, it returns the count of all Entity objects. + +#### Export API +Returns a downloadable file with the list of Entities that matches the given filter conditions in the query. For an empty query, we get all the Entity objects. + +### Query Composition +The HQL query mainly consists of four types of parameters. + +- Field Name +- Value Expression +- Value +- Logical Expression + +:::note +Aggregate functions (avg(), sum(), min(), max()) in HQL query are currently not supported with these APIs. +::: + +### FieldName parameter + +- The fieldName refers to the name of the field associated with the column in the respective table. The field name is derived from the column name in the table and usually camelCased. + +[![](/learn/assets/db_apis_fields.png)](/learn/assets/db_apis_fields.png) + +- The name of the field for a given column can be seen from DB Designer or the respectively generated model class. Field Name of a column can be found in DB designer on the selection of respective column in the properties panel. + +[![](/learn/assets/db_apis_fieldname.png)](/learn/assets/db_apis_fieldname.png) + +- Relational field names - In order to filter values with respect to an entity in relation, fieldname must be given as _entityfield.fieldname_. This is applicable only for ManyToOne and OneToOne Relations. Eg: `department.name = ‘Engineering’`, the name is the fieldname of `Department.java` + +[![](/learn/assets/db_apis_fieldsrel.png)](/learn/assets/db_apis_fieldsrel.png) + +### Value Expression parameter + +Supported value expression types are listed in below table + +| **Operation** | **Expression** | **Supported Value Types** | **Result** | **Examples** | +| --- | --- | --- | --- | --- | +| equals | = | Number or String | Values that equals to given value | - `empId=1` - `firstname=’Eric’` | +| not equals | `!=` (or) `< >` | Number or String | Values that are not equal to given value | - `zip!=02127` - `jobTitle< >‘Engineer’` | +| between | between | Date or Number | Values between given range | - birthdate between '1973-10-21' and '1986-06-18' (using date format - YYYY-MM-DD) - zip between 14231 and 15922 | +| less than | < | Number | Values less than given value | - empId<6 | +| greater than | > | Number | Values greater than given value | - deptId>10 | +| less than or equal to | <= | Number | Values less or equal to given value | - empId<=4 | +| greater than or equal to | >= | Number | Values greater than or equal to given value | - zip>=11 | +| pattern matching | like | String | Values matching the given pattern |- street like ‘4%Houston%’ | +| starts with | like | String | Values starting with the given string | - firstname like ‘E%’ | +| ends with | like | String | Values ending with the given string | - lastname like ‘%e’ | +| containing | like | String | Values containing the given string | - lastname like ‘%e%’ | +| in | in | Number or Date or String | Values in the given set | - zip in (‘14231’, ‘02127’, ‘11212’) - birthdate in ('1973-10-21' ,'1986-06-18') - firstname in ( 'Sally' , 'William' , ‘Amanda’ ) | +| null | is null | String | Values satisfying given condition | - role is null | +| not null | is not null | String | Values satisfying given condition | - date is not null | +| empty | = | String | Values satisfying given condition | - lastname = ‘’ | +| not empty | != (or) <> | String | Values satisfying given condition | - lastname <> ‘’ - lastname != ‘’ | + +### Value parameter +The “Value” parameter is the comparison value for the given field name. The value should be single quoted for non-numeric types. The format for the value of type date is ‘YYYY-MM-DD’. + +### Logical Expressions + +- A logical expression in HQL does one of the following: + - joins two or more conditions to form a complex query + - alters the logic of the conditions +- Supported logical expressions with examples are listed below +- Order of execution of conditions can be controlled using parenthesis. Eg: (empId=4 AND zip=02127 ) OR (city like 'New York%' OR birthdate between '1991-01-01' and '1999-12-31' ) + +| **Logical Expression** | **Results** | **Examples** | +| --- | --- | --- | +| AND/and | Result set satisfying both conditions | empId>5 AND firstname like ‘A%’ | +| OR/or | Result set satisfying either of the conditions | empId=5 OR deptId=1 | +| NOT/not | Result set satisfying negation of the conditions | NOT ( firstname like ‘A%’ AND empId=4) | + +For further reference to HQL query [http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch16.html](http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch16.html) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services/temporal-support.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/temporal-support.md new file mode 100644 index 000000000..78ae1fd86 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/temporal-support.md @@ -0,0 +1,154 @@ +--- +title: "Temporal Support" +id: "temporal-support" +--- +--- + +DB2 has an inbuilt support for temporal or time-based data management. The temporal features in the DB2 product enable you to accurately track information and data changes over time and provide an efficient and cost-effective way to address auditing and compliance requirements, without having to specifically code for the same. + +WaveMaker extends support for auditing and history using DB2 Temporal. You can seamlessly integrate the temporal functionality within WaveMaker apps and take advantage of DB2’s in-built time-based data management. In this document, we elaborate how WaveMaker achieves this support. For a use case example, [refer to this document](/learn/how-tos/working-with-temporals/). + +## Understanding Temporal + +Temporal allow the insertion, update, deletion, and query of data in the past, the present, and the future while keeping a complete history of "what you knew" and "when you knew it". + +There are three types of temporal tables supported by DB2: + +### System-period temporal tables +System-period temporal tables to allow for tracking the updates and deletes to the table rows over a period of time. This is achieved through: + - A master table with a system time period defined - the table includes additional timestamp columns to hold the system time period start and end points and transaction timestamps. + - An associated history table created as a duplicate of the master table. + - This history table is entirely managed by the database to track and manage multiple versions of data from the master table. + - System Temporal are mostly used for scenarios wherein you need to track, say, the policy updates for a vehicle over a period of time. + +### Application-period temporal tables +Application-period temporal tables help in tracking business time i.e. when certain business conditions are, were, or will be valid. This is achieved through: + - The table itself maintains business period information with additional business start and end time columns to track the business times. + - Without a need to maintain a separate history table. + - Queries allowing time range clauses like As Of a given date, Between and From-to two dates on the business period. + - Application Temporal can be used to trace, say the interest rates applicable over a period of time in past or future. + +### Bitemporal tables +Bitemporal tables manage both system time and business time and combine all the capabilities of system-period and application-period temporal tables. + +For more details on DB2 Temporal refer to [A matter of time: Temporal data management in DB2 10](https://www.ibm.com/developerworks/data/library/techarticle/dm-1410temporal-tables-db2zos/index.html). + +## Temporal Support in WaveMaker + +When a DB2 database is imported, WaveMaker identifies the data tables with Temporals and allows for extraction of history data for those tables. + +Two types of APIs are generated for temporal tables: + +1. **The standard APIs** for CRUD operations and other functionalities like count, find, filter etc. These APIs can be used to deal with data that is valid at the current time i.e. at the time of application run. +2. **The period APIs** to fetch data for + - a time different from the current time, or + - for a specific time period. + +[![](/learn/assets/dbtemp_apis.png)](/learn/assets/dbtemp_apis.png) + +## Database Designer + +- In DB designer a table property specifies the table **Temporal Type** as: + + - System Temporal, + - Application Temporal, or + - Bi Temporal + +[![](/learn/assets/dbtemp_tables.png)](/learn/assets/dbtemp_tables.png) + +- A column property, **Temporal Column Type**, specifies the temporal type and the period type. The values can be: + - System Period Start + - System Period End + - Application Period State + - Application Period end +- A clock icon will be displayed against columns which are part of temporals. These fields will not be displayed in the query results. You can uncheck the Hidden property in order to view these fields in the UI. + +[![](/learn/assets/dbtemp_columns.png)](/learn/assets/dbtemp_columns.png) + +- By default system period columns and transaction id are marked as Database defined. The values need not be entered by the user, they will be auto-populated by the database. + +[![](/learn/assets/dbtemp_datavalue.png)](/learn/assets/dbtemp_datavalue.png) + +## Generated REST APIs + +Two types of REST APIs are generated for the DB2 Temporal tables: + +### Standard CRUD and additional functionalities. + +Following conditions are applied for application temporal tables while requesting database. + - findAll, count, export, aggregations: Along with the given query filter, the entities AS OF current time are listed. +### Period APIs + +In addition to the standard APIs generated for the imported databases, the tables with temporals will have an additional period APIs auto-generated. This can be used to access the temporal data. + +_periods_ This API returns the history data for the temporal table by applying given filters. + +### Method: GET or POST Parameters + +1. systemPeriodStart [optional]: exists in case of system temporal tables; period value should be in Timestamp format, default value: 01-01-1901. +2. systemPeriodEnd [optional]: exists in case of system temporal tables; period value should be in Timestamp format, default value: 31-12-9999. +3. applicationPeriodStart [optional]: exists in case of system temporal tables; period value should be in Timestamp format, default value: 01-01-1901. +4. applicationPeriodEnd [optional]: exists in case of system temporal tables; period value should be in Timestamp format, default value: 31-12-9999. +5. q [optional]: query to filter the history data. +6. Pageable [optional]: pagination information.  + +- _/periods/{id} (or) /periods/composite-id_ This Api returns the history data for given id and by applying given filters. + +### Method: GET Parameters +1. Id columns information as specified for normal findById API. +2. systemPeriodStart [optional]: exists in case of system temporal tables; period value should be in Timestamp format, default value: 01-01-1901. +3. systemPeriodEnd [optional]: exists in case of system temporal tables; period value should be in Timestamp format, default value: 31-12-9999. +4. q [optional]: query to filter the history data. +5. Pageable [optional]: pagination information. + +### Update & Delete API +For tables having Application temporals, these APIs will be generated. These API’s will make use of DB2 portion of syntax to update/delete the history. + +- _/periods_ Method: PUT This API used to update the history data for Entity with given application temporal clause and q to filter. + +#### Parameters: + +1. applicationPeriodStart [optional]: exists in case of system temporal tables; period value should be in Timestamp format, default value: 01-01-1901. +2. applicationPeriodEnd [optional]: exists in case of system temporal tables; period value should be in Timestamp format, default value: 31-12-9999. +3. q [optional]: query to filter the history data. +4. Type: Body: Entity data to update. + +#### Returns: +This API returns IntegerWrapper, with affected rows count. Method: DELETE This API used to delete the history data for Entity with given application temporal clause and q to filter. Parameters: +1. applicationPeriodStart [optional]: exists in case of system temporal tables; period value should be in Timestamp format, default value: 01-01-1901. +2. applicationPeriodEnd [optional]: exists in case of system temporal tables; period value should be in Timestamp format, default value: 31-12-9999. +3. q [optional]: query to filter the history data.Returns: This API returns IntegerWrapper, with affected rows count. + +- _composite-id/periods_ Method: PUT This API used to update the history data for Entity with given application temporal clause. + +#### Parameters: + +1. id’s [optional]: Id columns as specified in normal Update API. +2. Type: Body: Entity data to update. + + +#### Returns: +This API returns IntegerWrapper, with affected rows count. Method: DELETE This API used to delete the history data for Entity with given application temporal clause. + +#### Parameters: +1. id’s [optional]: Id columns as specified in normal Update API. + +#### Returns: +This API returns IntegerWrapper, with affected rows count. + +## Library Enhancements + +To achieve the above functionality, a **@TableTemporal** annotation is added, specifying the table temporal types on that Entity/Table. This information is used while making the database request. This annotation requires temporal types array. Temporal Types can be: + +- SystemTemporal - Tables having System Temporal will be annotated with this annotation. +- ApplicationTemporal - Tables having Application Temporal will be annotated with this annotation. + +[![](/learn/assets/dbtemp_java.png)](/learn/assets/dbtemp_java.png) + +Though there are no API changes in WMGenericDao, while processing request the above annotation will be used. + +## Limitations + +1. DB2 database is imported as a Read-Only schema. As such, no changes to the table schema is allowed from the platform. Any changes need to be made to the database and the database re-imported for the changes to be reflected in your WaveMaker app. +2. Update of rows for Portion of a business time period is not currently supported. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services/versioning-queries-procedures.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/versioning-queries-procedures.md new file mode 100644 index 000000000..8ef7b8306 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/versioning-queries-procedures.md @@ -0,0 +1,45 @@ +--- +title: "Versioning of Queries and Procedures" +id: "versioning-queries-procedures" +sidebar_label: "Version Queries & Procedures" +--- +--- +In 8.4.1 release, WaveMaker has changed field naming strategy for result columns of queries and procedures. This has resulted in two versions of Queries and Procedures for backward compatibility: + +- v1 for older/existing query/procedures and +- v2 for query/procedure created post-release 8.4.1 + +## Versions + +Following is how WaveMaker implements these two versions: + +- New service layer with suffix **_V1** is generated for all services having old query or procedures to handle backward compatibility due to method signature changes in the new service layer. + For example, `HrdbQueryExecutorService_V1` Changes: + + - Old service always returned `Page` for select query. But new service returns `Page<Response>`. + - In old service, all parameters were configured as method arguments but in the new service, for **INSERT**/**UPDATE** parameters, are wrapped in Request class. + +- The controller always uses latest service layer i.e `QueryExecutorService`. +- All existing Java services are migrated to use V1 service layer instead of the new service to handle backward compatibility. + - In most of the cases existing Java, services will work as before but there might be a chance of `ClassCastExceptions due` to Runtime type casts i.e casting returned column value to the desired type. + - To fix above-mentioned _ClassCastException_ we recommend migration of all existing Java services to use latest Query/Procedure Executor service instead of V1. + +### Advantages +Because of design time POJO generation, if any query/procedure meta is updated then the execution will fail at compile time rather than at Runtime. This will save a lot of testing and debug time. + +You can easily read the response data with the help of POJO classes. All properties can be accessed using getters instead of map.get.s + +## Migration to V2 + +Steps for manual Java Service Migration/Using latest Services + +1. Inject query/procedure service class (i.e `Query/ProcedureExecutorService`) by using `@Autowired`. +2. For existing Java services, you can either modify the class name from `Query/ProcedureExecutorService_V1` to `Query/ProcedureExecutorService` or inject a new field. + +Execute query/procedures in the same way as following: + +- Response type changed to Page instead of `Page` for **SELECT** queries. +- Request type changed for INSERT/UPDATE queries to `Request`. +- For **SELECT** queries Pageable argument moved to last. +- For Procedures return type changed to `Response` instead of `List` +- Request type changed for methods starting `create`, `add`, `build`, `edit`, `set`, `update` with `Request`. diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services/working-database-schema.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/working-database-schema.md new file mode 100644 index 000000000..daf0c6b30 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/working-database-schema.md @@ -0,0 +1,272 @@ +--- +title: "Working with Database Schema" +id: "working-database-schema" +sidebar_label: "Working with DB Schema" +--- +--- +The **Database Designer** workspace allows you to create tables, columns, and relationships. + +[![db_designer_schema](/learn/assets/db_designer_schema.png)](/learn/assets/db_designer_schema.png) + +Click to enlarge + +## Adding Tables and Columns + +:::note +These actions are restricted to [Schemas in Editable mode](/learn/app-development/services/database-services/database-schema-import-modes/). +::: + +### Adding Table + +Click the **+Table** button to add a new table to the database. You can set the name of the table from the **Properties**. + +- WaveMaker requires tables to have primary key value, hence a default column as a primary key is provided. You can change the name or assign another column as primary key, but primary key is a must for all the tables. +- For tables created, you have the option of assigning it to any Schema which has been imported into the app. This feature is not available for MySQL databases. + + +### Adding Column + +Click **Add Column** to add columns to the table. For each column, you can specify the following: + +- **Name** - The name of the column. + +- **SQL and Java Types** – It is advisable to make changes to Java Types rather than SQL Types unless you want the changes to be reflected in the database, in which case you need to export the database. You can review the type conversion from Java to SQL type from this document: [Java Types vs SQL Data Types](/learn/assets/JavaTypesVsDBTypes-Sheet.pdf). + +- **Length** - Precision and scale for number type; length for string type; +- **Hidden** - You can also choose to hide the column using **Hidden** option. These columns will not be available for user manipulation. You can set the values of these hidden columns during insert/update operations: + - by setting the Value from the Data Value tab, or + - by passing the value during the insert operation from a widget. +- **Value Type** - From the Data tab, set the Value Type as ([click here for more](#column-metadata-configuration)): + - User Defined which can take a Default Value; + - Server  Defined in which case the column can be further set to Server Properties and when the Value needs to be set - at Insert, Update or both; + - Database Defined which uses database trigger or the default values +- Column level constraints like + - Null + - Primary key + - Unique key + - Foreign key +- **Primary Key** - In case of primary key column, the value can be set to ([see here for more](#identity-generators)) + - Assigned lets user enter the primary key values, + - Auto-generated will assign the primary key values  or + - Sequence will assign the values based on the generator name given. + +:::note +WaveMaker supports **Composite Keys** that is multiple columns can be specified as Primary Keys. +::: + +[![](/learn/assets/db_schema.png)](/learn/assets/db_schema.png) + +## Database Relationships + +Relations are a way to establish a connection between tables within a given database. It takes care of the consistency while linking two tables. In WaveMaker, there are two ways of creating **relationships**: + +1. Select and hover over the column to build a relationship on. Select from `One to One` or `One to Many`. Click the second column of the relationship. +2. For each column, on select and hover, a **Create Relation** icon displays. By clicking it, a dialog opens. +3. In the dialog the source table and column are already selected and not editable. +4. Select the **cardinality** of the relation: + - One-to-One Composite relation is possible between the tables which have the same number of composite keys. + - One-to-Many Composite relation is possible when Table 1 has the composite keys and Table 2 has at least one non-Composite key column selected. + - Many-to-One Composite relation is possible when Table 1 has at least one non-Composite key column selected and Table 2 has the composite keys. +5. It is possible to add **Virtual Relations**. This feature can be used to establish relations without changing the DB Schema. This will enable one to enforce DB level constraints without having to write any scripts or queries. Clicking on CREATE will create the virtual relation. This will be indicated by a dotted line and the virtual flag is set in the relationship property. +6. It is possible to add **Relations involving Composite Keys**. You can **add columns** to the relation by using the **Add Relationship** button. Clicking on CREATE will create the composite relation. This will be indicated by a double-pronged line between the tables in the DB Designer. + +[![](/learn/assets/DB_cr_relation.png)](/learn/assets/DB_cr_relation.png) + +## Relationship Fetch Options + +Fetching data from a database table involves retrieving data for all the related tables. This could lead to performance issues, especially when your app does not need all the columns from the related tables. For example, your database contains Employee-Department schema but your app uses just the department name and not the other fields from the Department table. In such cases, you can restrict the data from the related table, Department, while fetching rows from Employee table. + +From the relations tab, for the particular relation (one-one, many-one), you can: + +1. choose not to fetch the related data, or +2. select the columns from the related table that need to be fetched. + +:::note +- Primary Key column from the related table will be fetched. +- By default, all columns from the related table will be fetched. +::: + +[![](/learn/assets/DB_fetch_relations.png)](/learn/assets/DB_fetch_relations.png) + +## Identity Generators for Primary Keys + +An identity generator defines the value of the primary key column in database table while inserting new records into it. Identity generators can be defined only for primary key columns. Every database has its own way of defining identity generators that should be mapped while creating a new database table in WaveMaker DB Designer. + +WaveMaker presently supports following generator types. These can be accessed from the DB designer from the Properties panel for a Table. + +- Auto Increment +- Sequence (only for SQL Server, Oracle, PostgreSQL databases) +- Unique ID (only for SQL Server) +- Assigned + +### Auto ­Increment + +An identity generator of type “Auto Increment” automatically sets the value for the column while the record is being inserted, and increments its counter for next insertion. This type is used only for “_integer_” types. Auto-­increment implementation is left to the database. Usually, database implicitly uses sequences for automatically inserting values for such columns. The auto-­increment column in WaveMaker is mapped to the database column as follows: + +### Sequence + +Sequences are created in database explicitly. Unlike auto-­increment, the sequence will have its own configuration such as _starts with_, _increment by_ value, and _recycle_ etc. DBA/Developer creates sequences in DB and provides the name of the sequence in the DB Designer for the column. Sequences will be mapped only to _integer_ type columns. When choosing Sequence, an additional option is provided to accept the sequence name. _This is currently supported only for MS SQL server, Oracle, and PostgreSQL_ databases. Sequence information is never directly mapped with a column in the database schema and while reading the database schema, WaveMaker does not associate the table with the sequence name. Hence the application developer has to explicitly map the sequences with the table columns after the DB is imported and perform **Update DB**. + +### Unique ID + +Generates a unique identifier based on the MS SQL Server’s NEWID() approach. It generates 128-bit string unique string value. _This is currently supported only for MS SQL server_. + +### Assigned + +An identity generator of type “Assigned” will not be managed by the database. The user has to set a value for such column while performing insert operation. This type can be used by columns with any database type. + +## Column Metadata Configuration + +Data Value Types define the value of column while performing insert/update operations in Database. This is particularly useful for adding auditing of information about the creation and modification of records. + +[![](/learn/assets/db_col_data.png)](/learn/assets/db_col_data.png) There are three types of Data Values: + +- User Defined +- Server Defined +- Database Defined +- App Environment Defined + +### How it works + +These properties are available in the DB designer, at column level under the group **Data Value**. The Value Type field enables you to select one of the types mentioned above. The definition & configuration of each type is defined in below sections. After choosing the data value types, the developer has to invoke **Update DB** to get the changes reflected. + +:::note +Changes to Data Value types will not alter the underlying schema, however, the Java code will get regenerated on Update DB. +::: + +### User Defined + +This is the default behavior. In this case, the value provided by the end-user will be persisted while performing insert/update operations. The Default value when set will be used if you do not provide a value for that column. Validations can be enforced by setting Validators for the User defined columns. [More on validators](#validators). + +### Server Defined + +In this mode, the value provided by the end-user will not be honored. It will be replaced with the server defined property that is configured. This column will not be shown in Live Form or in the Live Variables Data tab. Based upon the column data type, the following are the server defined properties available: + +- For string data type: + - Logged-in User Id (also for integer data type) + - Logged-in User Name +- for date data type: + - Current Date + - Current Time + - Current Date & Time + +### Database Defined + +In Database Defined mode, the application will never send any value for this column while performing insert/update operations. It is left to the database to set a value post insert/update operations. Developers can write database trigger or use database default values to set the column values. If there is no database default and the column does not accept null values, then the insert/update operation might fail. This column will not be shown in Live Form or in the Live Variables Data tab. + +### App environment Defined + +App environment properties are custom server side properties defined by the app developer to externalize certain properties into configuration profiles, so that those property values can differ for different environment. The app environment properties can be defined from the config profile dialog ([know more](/learn/how-tos/using-app-environment-properties/)). + +## MetaData Value Settings + +The Data Value specified for each column can be set either at the time of row creation and/or updating. For every database operation such as create/update of a record for a table, the insert/update statements include each and every column of the table in the respective query. There might be cases where the insert/update may not pass values for some columns to the database and thus leaving the decision to the database for insert or update value for the respective columns. + +#### Example +Consider a table with columns for date of creation and date of modification. The date of creation needs to be entered only once at the time of record creation, subsequent updates to that row should not change its value. Whereas, the date of modification will be set to null at the time of row creation but updated everytime the row values are updated. + +To support such cases where you want to control whether to include a particular column value in the insert/update statement, WaveMaker has **Insertable** and **Updatable** options for table columns in the _Database Designer_. In the above example, the insertable option will be set to true for the date of creation column and the updatable option will be set for the date of modification column. + +### Insertable +If the insertable option is selected, then the values will be passed at the time of new record creation. If only the insertable option is selected (updatable option unchecked) the value will be passed to the database during insert. The value will not be changed for that column during the update. If the _insertable option is not selected_, then the value of the column during the creation of a new record will be based on the following scenarios: + +- If a default value is configured in the database then the default value is inserted. +- If a default value is not configured in the database and the column is nullable, then the value will be set to null. +- If there are any triggers written for that column, those values are considered while inserting data into that column. + +#### Example: +Considering hrdb sample database. Let's say you want to assign default `ROLE` or `NULL` while creating new USER. To achieve this un-select the insertable option for `ROLE` column in the `USER` table. _Generated Code_: In `User.java` that column’s insertable property marked as false + +``` +@Column(name = "`ROLE`", nullable = true, insertable = false, length = 20) +public String getRole() { + return this.role; +} +``` +Insert SQL: ROLE column was ignored in the insert script so that the value will be assigned with configured default value or NULL. +``` +insert into PUBLIC."USER" ("USER_ID", "PASSWORD", "TENANT_ID", "USERNAME") values (default, ?, ?, ?) +``` + +### Updatable +If the updatable option is selected, then the values will be passed at the time of updating the record in the database. If updatable option alone is selected (insertable option unchecked) the value will be passed to the database during an update. The value will not be passed for that column during insert. If the _updatable option is not selected_, then the value of the column during the update of the record, will be based on the following rules: + +- The value passed to the column during insert doesn’t change +- If there are any triggers written for that column, those values are considered while inserting data into that column + +#### Example +Considering hrdb sample database. Let's say you don’t want to change the `USERNAME` column while updating USER table. So to do that we have to un-select the updatable option for `USERNAME` column in the USER table. _Generated Code_: In `User.java` that column’s updatable property marked as false + +``` +@Column(name = "`USERNAME`", nullable = true, updatable = false, length = 20) +public String getUsername() { + return this.username; +} +``` + +Update SQL: USERNAME column was ignored in update script. + +``` +update PUBLIC."USER" set "PASSWORD"=?, "ROLE"=?, "TENANT_ID"=? where "USER_ID"=? +``` + +## Data Validators + +There may be situations where you might want to set validations for user-defined columns. This can be achieved by an option to select the validation from the list of default validators list for the column based on the data type. This option is available on the properties panel for the selected column. + +[![](/learn/assets/db_col_validator.png)](/learn/assets/db_col_validator.png) + + +| Validator | Column Data Type | Description | Values | +| --- | --- | --- | --- | +| Length | String | It defines the number (minimum and maximum) of input characters that are allowed for the column. | It expects two integer values: - Min - Max >br> | +| Email | String | If email validator is given, the value given to that column tested for default email pattern. You can enhance the validation by specifying a regular expression, for example, allow emails for a specific domain. | RegExp: optional | +| Credit Cart Number | String | This column expects 16 digits numeric number. Basic mod 10 checksum validation is performed. | | +| Pattern | String | It checks for the particular pattern present in that column value else throws a validation error. | RegExp | +| AssertTrue | Boolean | The value of that column must be provided as true. | | +| AssertFalse | Boolean | The value of that column must be provided as false. | | +| Min | Byte, Integer, Long, Short, BigInteger | The minimum value allowed. | | +| Max | Byte, Integer, Long, Short, BigInteger | The maximum value allowed. | | +| Range | Byte, Integer, Long, Short, BigInteger | The value of the column should be between a minimum and maximum values. | It expects two integer values: - Min - Max | +| DecimalMin | Double, BigDecimal | The minimum value allowed. | | +| DecimalMax | Double, BigDecimal | The maximum value allowed. | | +| DecimalRange | Double, BigDecimal | The value of the column should be between a minimum and maximum values. | It expects two integer values: - Min - Max | +| Future |  Date, Time, Timestamp | The value in this column should be ahead of current (runtime) date/time/timestamp | | +| Past |  Date, Time, Timestamp | The value in this column should be behind current (runtime) date/time/timestamp | | + +## Implementation in WaveMaker + +The _Insertable_ and _Updatable_ options can be configured for **User Defined** and **Server Defined** value types for Database columns. For **Database Defined** value type these are implicitly set to false. **Insertable** and **Updatable** options are provided under _Data Value_ group for the columns in the **Database Designer**. + +[![](/learn/assets/db_col_settings.png)](/learn/assets/db_col_settings.png) + +- If the Value Type is selected as _User Defined or Server Defined_, both Insertable and Updatable options are selected by default. You can edit the options, but **at least one option** has to be selected. + - If you select _Insertable option alone_, the column value will be inserted only at the time of creating a new record. The inserted value will not be updated at any point of time if the Updatable option is unchecked. + - If you select the _Updatable option alone_, the column value will be set to the default value if provided or null at the time of creation and will be updated subsequently. +- If the Value Type is selected as _Database Defined_, by default both the options are deselected and disabled. That is, the column acts as a read-only column. + +## Virtual Primary Keys and Relationships + +### Virtual Primary Keys + +In case you are using a database table which has no primary keys and either you do not have the access to change the DB design or do not want to change the original database design, you can still use it in your WaveMaker apps despite Hibernate constraints. + +You can designate one or more columns as a Virtual Primary Key. This will be used within the WaveMaker to enforce integrity constraints without having to change the database. The original database schema remains untouched, even after Update DB. This will ensure that the APIs are clear and you can perform CRUD operations on your existing database views as well. + +Designation of Virtual Primary Key can be done at the time of Database Import or later from the Table Properties. + +[![](/learn/assets/DB_vpk_table.png)](/learn/assets/DB_vpk_table.png) + +### Limitations of using virtual primary key + +- Since the external database is not updated with the virtual key, the data in the table may have duplicates if any external app is also using the same table for CRUD operations. +- Though CRUD operations are possible in views having virtual primary keys, the database may have its own limitations to support the same. (esp when the view is joined with multiple tables) + +### Recommendations + +This feature should be used with existing databases only, we would not recommend creating a table with no or virtual primary key. + +### Virtual Relationships + +Similar to Primary Keys, there might arise a situation where you want to enforce referential integrity in your app where none exist in the database. In such cases, Virtual Relations are of help. This feature can be used to establish relations without changing the DB Schema. This will enable you to enforce database level constraints without having to write any scripts or queries. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services/working-stored-procedures.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/working-stored-procedures.md new file mode 100644 index 000000000..271f5cfb6 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/working-stored-procedures.md @@ -0,0 +1,210 @@ +--- +title: "Working with Stored Procedures" +id: "working-stored-procedures" +--- +--- + +There will be times when you want to display data from multiple tables or update/insert values into multiple tables. Queries and Stored Procedures come in handy in such instances. WaveMaker provides editors for Queries & Procedures for integrating them with the WaveMaker applications. Each query & procedure used in the WaveMaker application will be exposed as a REST API for the UI to consume and render the data. + +A _stored procedure_ is a prepared SQL code that you save in your database so you can reuse the code over and over again. + +Procedure tab from WaveMaker Database Designer can be used to execute procedures that are written in and imported from the database using the `call` command. Execute the procedure calls and save them for the usage within the app [by creating Variable using the generated APIs](/learn/app-development/variables/database-apis/). + +[![](/learn/assets/db_procs.png)](/learn/assets/db_procs.png) + +## Procedure Parameters + +Calling Procedure will add the specified parameters. You can select the appropriate Parameter Type: + +- IN for input parameter; +- OUT for output parameter; and +- IN-OUT for a combination parameter. + +### Parameter Type + +- You can specify the **data type** for each of the parameter. + +:::note +Some data types might be specific to the underlying database being implemented, for example, cursor data type is available only for Oracle database. +::: + +- You can also set the parameter type as one of **Server Side Properties**. +When you select this option while executing the procedure, the appropriate value is taken from the application rather than from user. + +Currently supported server defined properties are: +- Logged in User Id +- Logged in User Name +- Current Date +- Current Time +- Current Date Time + +[See here on how Blob types are handled.](/learn/app-development/services/database-services/blob-support-queries-procedures/) + +:::note +Parameters can also be set to App Environment Properties which can be configured differently for different runtime environments ([learn more](/learn/how-tos/using-app-environment-properties/)). +::: + +### Defined & Undefined Cursors (Resultset) + +Along with the configured OUT parameters, procedures can also return ResultSet (cursor), which is referred to as Undefined Cursor. When any procedure is returning Undefined Cursor, in Response an extra property is generated with name Content. A POJO also will be generated for that Response. + +WaveMaker supports the execution of procedures/functions written using PL/SQL. You can find out more about [Stored Procedures here](http://www.oracle.com/technetwork/database/application-development/plsql/overview/index.html). In this section, we will be seeing how WaveMaker supports Stored Procedures with the help of an example. We are using a MySQL database. + +There are two aspects to stored procedure usage - Creation and Invocation: + +### Creation of Procedures and Functions + +Procedure/Function needs to be created in the database itself. For MySQL DBs, you can use the **DB Shell** tab of [DB Tools](/learn/assets/db_tools.png). Any procedures you have in a database that you [import](/learn/assets/db_new.png) will be available for use. + +1. The database we used contains an Employee table with Emp_ID, Name and City details. Here is the _Employee_ table that we have designed using the [DB Designer](/learn/assets/db_designer_schema.png). + +[![](/learn/assets/employee_schema.png)](/learn/assets/employee_schema.png) + +2. The procedure entered in the DBShell under [DB Tools](/learn/assets/db_tools.png) would be: + +```sql +DELIMITER ;; +CREATE PROCEDURE emp_in_out(IN in_city varchar(255), OUT total integer) + BEGIN SELECT COUNT(Emp_ID) + INTO total + FROM Employee + WHERE City = in_city; + END;; +DELIMITER ; +``` + +A function would be: + +```sql +DELIMITER ;; +CREATE FUNCTION emp_in_out(in_city varchar(255)) RETURNS integer + BEGIN DECLARE emp_tot INT; + SELECT COUNT(Emp_ID) + INTO emp_tot + FROM Employee + WHERE City = in_city; + RETURN emp_tot; + END;; +DELIMITER ; +``` + +### Invocation of Procedures Functions from WaveMaker app + +Procedures created in a DB can be accessed by creating a live service variable and associating it with the invocation of the procedure. Follow the steps given below to do the same: NOTE: This post explains the usage of stored procedures/functions in WaveMaker using the MySQL code. For the usage in different databases [check here](#db-specific-invocation). + +1. In the **Database Designer,** select the **Procedure** tab, use the following code to invoke the above procedure. + +```sql +call emp_in_out(:city, :total) +``` + +Use the following code to invoke the function: + +```sql +{{:total = call emp_in_out(:city) +``` + +2. Post 8.4.1 release, you can use CTRL+space to select from a list of Procedures available in the database. +3. This will add the parameters. Select the appropriate options - + + - **IN** for input parameter; + - **OUT** for output parameter; and + - **IN-OUT** for a combination parameter. + +4. Specify the data type for each of the parameter.  +See [here](/learn/app-development/services/database-services/blob-support-queries-procedures/) for handling Blob types. + +:::note +Some data types might be specific to the underlying database being implemented, for example, cursor data type is available only for Oracle database. +::: + +5. **Save** the procedure. + +6. [Create a variable](/learn/assets/var_sel.png) using the Database API generated on the save of the procedure. This variable will expose the parameters for binding. [More on Variable Creation](/learn/app-development/variables/database-apis/) +7. To use the Procedure, create a page with + - an input text box - to accept the city name to be bound to the input parameter of the above procedure and + - label to display the result. +8. The _in_ parameter is bound to the _datavalue_ property of the _text box_ from the **Variables** dialog +9. The _out_ parameter for display by binding to any widget property variable, here we are binding to the caption of a label. +10. Preview the app. + +### DB Specific Invocation + +- **MySQL/DB2** - the above documentation uses MySQL. +- **Oracle** - same as MySQL. In case, procedures are bundled in a package, need to prefix the package name to the proc_name. +- **PostgreSQL** - can be same as above or + +```sql +SELECT proc_name(:param_value1, :param_value2); +``` + +- **MSSQL & SQLServer**- Invoking Procedures: + +```sql +EXEC [Schema_name].[proc_name](:param_value1, :param_value2) +``` + +Invoking Functions: + +```sql +SELECT * FROM function_name(:param_value1, :param_value2) +``` + +## Procedure Architecture + +For all queries and procedures, there will be a Rest API generated with the Service layer. Along with the API, depending on the query or procedure type, request and response POJO classes are generated. + +**Understanding generated Code** _File structure_ + +[![](/learn/assets/queryproc_files.png)](/learn/assets/queryproc_files.png) + +### Models + +Both _Request_ and _Response_ POJO classes are generated as: `Request/Response` + +1. These classes are generated in a package: `` class with given property name. In the above-mentioned case, it will be marked with type `GetStudentsReponseMarks`. + +- In the case of Undefined cursor returned i.e cursor not specified in parameters section. + - using the field as `content` the POJO class will be generated as per the above case. + +[![](/learn/assets/proc_cursor.png)](/learn/assets/proc_cursor.png) + +- Request classes will be generated for all procedures, with names starting `create`, `build`, `add`, `update`, `edit`, `set`. + +### Services + +This layer exposes the methods related to the configured query and procedures. Controller layer uses these methods to complete the user requests. + +We recommend using methods from this layer in custom Java services. + +- Class with name ProcedureExecutorService is generated in the .service package. For eg: for service hrdb, class name will be HrdbProcedureExecutorService. +- Method with name execute <procedureName> will be generated for all configured procedures. + +:::important +- As mentioned in Models -> Procedures naming convention, if Request type generated for that procedure it will expected as argument otherwise all IN parameters expects as arguments. +- Response type will be <procedureName> Response. In case of procedure not returning any properties it uses Void +::: + +[![](/learn/assets/proc_services.png)](/learn/assets/proc_services.png) + +### Controller + +- Controller class with name ProcedureExecutorController in package .controller. +- Rest API is generated for each configured query and procedure. Generated method signature will be same as service layer method signature. + +[![](/learn/assets/proc_controller.png)](/learn/assets/proc_controller.png) + + \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services/working-with-databases.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/working-with-databases.md new file mode 100644 index 000000000..c9dfea80f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/working-with-databases.md @@ -0,0 +1,109 @@ +--- +title: "Working with Databases" +id: "working-with-databases" +--- +--- + +## Adding Database + +**Databases** can be accessed from the Resource Menu. Clicking the **+** will allow you to add a database to your app. + +[![](/learn/assets/db_new.png)](/learn/assets/db_new.png) + +There are various ways of adding a database to your app: + +[![](/learn/assets/add_db.png)](/learn/assets/add_db.png) + +## Connect to a DB + +Using this option you can add an external database. You can import the database as Read-Only or as Editable. For more information, see [Schema Import Modes](/learn/app-development/services/database-services/database-schema-import-modes/). + +With Connect to a DB option, you get the following options to work with: + +#### 1. MariaDB +Host a MariaDB database on WaveMaker Cloud. + +#### 2. Sample DB +You can import this database into your app and try various scenarios, it is a great place to get started on DB services. +This is an HSQL database `hrdb` with four tables: +- **Department** table with `deptid`, `name`, `code`, `location` and `budget figures`. +- **Employee** table with employee details like `id`, `name`, `address`, `picture`, `date of birth`, `job title`, `department id` (foreign key), `manager id` (self-referential key) and `username` and `password`. +- **Vacation** table giving the vacation details like `start date`, `end date`, `leave status` and `type`, and details related to `Employee table` via `empid`. +- **User** table with `name`, `password` and role information. + +#### 3. External Database +Connect to an external database. For more information, see [Supported Databases and Version Matrix](/learn/app-development/services/database-services/database-services#supported-databases-and-versions). + +## Upload MySQL files +This option lets you create a database by importing a DB Script. This option is available for hosting the database on WaveMaker Cloud. + +## Create your own DB +You can create your own database using the database designer. Using this option you can create MySQL, PostgreSQL, or SQL Server database and host them on WaveMaker Cloud (for MariaDB) or your external database. + + +### Advanced Settings (only for External Databases) + +Apart from the basic Database settings like host details, schema name etc., **advanced database configuration options** need to be provided, when using an External Database. Based upon the basic settings the Advanced Settings are auto-populated but can be modified. Each Database System provides different options so you will see a portion of the options listed below, tailored to the Database System you are using. + +:::note +For connecting to an external database, you need to **Test Connection** before proceeding. +::: + +| Setting | Description | +| --- | --- | +| **Service Name** | Name used to reference the imported database. By default, this is same as the Database Name, defined in Database Info section (not available for HSQL). Also,the database service name can only be given at the time of importing the database.| +| **Port** | The port number for the database. Typically this is set automatically when the database type is selected and should not be changed (not available for HSQL and MariaDB). | +| **Connection URL** | When you import a database using the standard configuration options on the Import Database screen, WaveMaker creates a JDBC URL for you. This URL is shown here in the Connection URL field. These are usually specific to the database type. For example with MySQL some character set usage could require adding “?useUnicode=true&characterEncoding=UTF-8” to the URL to characters to display correctly. If you know what you are doing and want to change this JDBC URL, you can do it here. | +| **Java Package** | WaveMaker generates Java classes for you when you import a database. If you want a different Java package name than the default name we generate, type it in here. | +| **Table Filter** | By default WaveMaker imports all the tables in the database. If you want to import only a subset of the tables, type in a comma-delimited list of regular expressions here (not available for HSQL and MariaDB). | +| **Schema Filter** | When you are importing a database that supports schemas, WaveMaker imports only the tables for the default schema. If you want to import tables from other schemas, add the schema names in this field. | +| **Driver Class** | JDBC driver class name. WaveMaker creates a JAR file for each database that uses a specified driver. If you want to use a different JAR file for connecting, specify it here (the JAR file must be in the Application Server’s classpath). | +| **Dialect** | Hibernate dialect. See Hibernate documentation for details, including the list of available dialects. | +| **Naming Strategy** | Most users should leave this blank. Enter the name of a Java class you created for handling the naming strategy (not available for HSQL and MariaDB) | + +### Configuring Virtual Primary Key + +##### 10.0 release + +When connecting to an external Database, if the tables do not have Primary Key, you will be given an option to assign a Virtual Primary Key. + +:::tip +It is strongly recommended that you assign Virtual Primary Key to avoid any runtime issues. +::: + +While connecting or importing the Database, select the Configure option to assign Virtual Primary Key. + +[![](/learn/assets/DB_import2.png)](/learn/assets/DB_import2.png) + +You can select column or columns whose values are unique and assign them to be the Virtual Primary Key. This assignment is specific to the app and will not impact the Database. + +:::note +After importing, you can always assign Virtual Primary key from the Database Designer Table properties. For more information, see [Virtual Primary Keys and Relationships](/learn/app-development/services/database-services/working-database-schema#virtual-primary-keys). +::: + + +[![](/learn/assets/DB_import3.png)](/learn/assets/DB_import3.png) + +### Map Sequences + +For databases that support sequences (Oracle, SQL Server, PostgreSQL, DB2, etc.) for the Primary Key generation, the mapping of Primary Key columns to the respective Sequences can be done at the time of connecting to Database. + +You also have the option to change the assigned type to sequence and then assign a sequence to the same. + +[![](/learn/assets/map_sequences.png)](/learn/assets/map_sequences.png) + +## Database Actions + +Once you have your app integrated with a database, schema information will be persisted in the WaveMaker. While you can access the data through Variables, any changes made to the database at the schema level to the local database or external database has to be synced with its counterpart. The various ways to achieve this are: + +| Action | Description | +| ---- | --- | +| **Re-Import Database** |Re-Import Database will rewrite the db in your workspace with the actual db thus reverting any changes. It deletes the draft and generates the data model with given database details. | +|**Export Database** |Export Database will update the db with the changes from your workspace ie the draft database. | +|**Save Database** |Save Database will save the db in your app workspace, this is the draft copy of the database solely available to your app. | +|**Update Database** | Update Database will update the db with the changes from your workspace and incorporate changes made by any other collaborator (provided they have exported the changes).
This option is available after you make changes to the database schema from the design tab of the database designer. | +|**Revert Database** | Revert Database will revert the db and delete the changes from your workspace. This option is available after you make changes to the database schema from the design tab of the database designer. | + +## Increasing Database Transaction Timeout + +Property in profile profiles - development.properties called ``db.databasename.transactionTimeout`` can be used to increase the timeout for database transaction diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-services/working-with-queries.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/working-with-queries.md new file mode 100644 index 000000000..657fd4521 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-services/working-with-queries.md @@ -0,0 +1,218 @@ +--- +title: "Working with Queries" +id: "working-with-queries" +--- +--- + +There will be times when you want to display data from multiple tables or update/insert values into multiple tables. Queries and Stored Procedures come in handy in such instances. WaveMaker provides editors for Queries & Procedures for integrating them with the WaveMaker applications. Each query & procedure used in the WaveMaker application will be exposed as a REST API for the UI to consume and render the data. + +In this section, we will be seeing how WaveMaker supports Query usage with the help of an example. + +## Query Editor + +From the Database Designer, use the Query tab to build custom database queries for custom reports and dashboards. + +[![](/learn/assets/query_tab.png)](/learn/assets/query_tab.png) + +- The editor supports IntelliSense, use **CTRL-Space** to see suggestions for the table and column names. +- The queries can be in **HQL or Native SQL**. These queries can be saved and used via the Database APIs generated. +- Parameterised queries are also supported. **Parameters** can be marked as Required. If marked as required, the Variable associated with this query operation will not be invoked until all the required parameter values are set to the variable input. +- No DB-specific changes, apart from the syntax of the query, needs to be taken care of. +- If the schema name is not the default name, then the table names need to be prefixed with the schema names. +- [See here for support on fields of type Blob/CLOB](/learn/app-development/services/database-services/blob-support-queries-procedures/) +- You have to **Execute** the query successfully to be able to save the query. The **Save icon** will be active only after a successful run of the query. +- Once you save the query, you can see the entry under Database Resources. You can use it to reopen and modify the query if need be. To modify the query, open the query, make the changes, run and save the query. You can also Delete the query using the **delete** icon. +- When a query is saved, it generates a **paginated API** that returns a list of objects paginated. In cases where the query returns at most one record, setting the **Records** to _Single_ will ensure that the generated API returns one object instead of paginated objects. The default is set to _Paginated._ +- In addition, every API generated for query exposes an additional API for exporting the query results to Excel/CSV. However, in case the query returns a single result, the export API will not be generated. The list of APIs generated can be viewed from the [API Designer](/learn/assets/API_Access.png). +- To execute and access the results of the query within the app, you need to [create a Variable based on Database APIs](/learn/app-development/variables/database-apis/) and bind the results to a widget of your choice. [Variable Access](/learn/assets/var_sel.png). + +### Limitations + +- Internal pagination is implemented, as such LIMIT clause in queries WILL NOT be supported + +## Types of Query + +WaveMaker supports two types of queries. They are: + +1. **Native SQL**: You can execute Database-specific SQL queries using this option. The same query directly executed in the underlying database. You have to manually escape query in case of spaces, special characters and SQL keywords in the query. +2. **Hibernate Query Language (HQL)**: HQL queries depends on Java entities instead of native tables. For more info please [refer here](http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/#queryhql). + +You can select the appropriate type from the **Type** option in the designer. + +:::note +This post explains the usage of queries in WaveMaker using the Native SQL code. +::: + +### Query Creation + +In this example, we will build a query to list the number of vacation days availed by employees from each department. We will be using the _hrdb sample database_ that ships with the product. + +1. Import the **sample database** into your project. [Database Integration](/learn/app-development/services/database-services/working-with-databases/). +2. Select **hrdb** from the **Databases** Resource to open the Data Designer window. +3. Click the **Query** tab of the **data designer** window. +4. Select **Native SQL** as the query type and enter the following code in the Query Editor: + ``` + select d.NAME, sum(ENDDATE - STARTDATE ) as days + from VACATION v, EMPLOYEE e, DEPARTMENT d + where e.EID = v.EMPID + and e.DEPTID = d.DEPTID + group by d.NAME + ``` +5. **Execute** the query and see the results in the result box below the query window. Save the query as _vacation_days_ with appropriate description. + +### Query Usage + +We will see how to use the query results by using a **Data Table **to display the results (you can use any of the Data Widgets for this purpose): + +On any page of the project, drag and drop a **Data  Table** widget. + +1. set **Retrieve Data from** to _Services_, this will create a new variable for us +2. **Select a service type** as **Database APIs** which are auto-generated when you save the query +3. **Select a service** to be _hrdb_ (the database name) +4. select **Operation/Type** as the _query_ saved in the previous step, you will find it under Query Execution group (you might have to scroll down to get to this option). +5. **Records per request** will set the Pagination related options automatically +6. Setting the **Request data on page load** for the Variable ensures that the call to the service is triggered whenever the page is loaded. Setting **Update data on input change** will ensure the call when the data changes (as seen in the next section). +7. Since the query is a select query, the layout option available is **Readonly Simple View Data Table**. +8. You can choose the **Pagination style** or go with the default. +9. You have the option of **choosing the fields** to be displayed in the grid. Here we will retain the default of displaying all the fields. + +Run the project and see the results displayed in the table format. + +### Create Parameterized Query + +Instead of hardcoding values, you have a choice to declare Named parameters in the query. While executing queries these values get replaced with given values. Named parameters can be declared using ":" (colon) prefix. WaveMaker internally uses Hibernate for matching and replacing the named parameters. + +For example, let us modify the query above to accept the department name as input and display the results for the specified department name. + +1. Modify the query created in the previous step to include the parameter for department id. Or you may create a. new query thus: + ``` + select d.NAME, sum(ENDDATE - STARTDATE ) as days + from VACATION v, EMPLOYEE e, DEPARTMENT d + where e.EID = v.EMPID + and e.DEPTID = d.DEPTID + and d.DEPTID = :did + group by d.NAME + ``` +2. The parameter entry is made in the **Parameters** section. +3. Since this query will return a single record set Records to **Single**. +4. Select the appropriate data type for the parameter using _Type_ field, enter a _Test Value_ and _Execute_ the query. Use _List_ in case your parameter takes multiple array value, the test values in such a case should be comma-separated values without spaces. For example, in this example if _did_ were a list then the test values would be _1,2_. +5. The parameters can be set to server-side properties like _current date, time, id, or username_ by picking the same for Type from under the **Server Side Properties** drop-down. When you select this option while executing the query the appropriate value is taken from the application rather than from the user. + For example, if you have a query: + ``` + select FIRSTNAME + from EMPLOYEE where EMP_ID = :id + ``` + You can, in the Parameter section, set the **parameter id Type** to _LoggedIn UserId_ from under the _Server Side Properties_. When you enable security using the database as the service provider and employee as the User table, then setting the id to _LoggedIn UserId_ will get the user id of the current logged in user. You need not bind the parameter again, explicitly. +6. Parameter values can also be set to App Environment properties and be defined separately for different app environments ([know more](/learn/how-tos/using-app-environment-properties/)). +7. To execute and access the results of the query within the app, you need to [create a Variable based on Database APIs](/learn/app-development/variables/database-apis/) and bind the results to a widget of your choice. [Variable Access](/learn/assets/var_sel.png) + +### Using Parameterized Query + +1. Create a [Database Crud Variable](/learn/app-development/variables/database-crud/) for Department table. [Variable Access](/learn/assets/var_sel.png) +2. Add a **Select** widget to the page and bind it to the _Variable dataset_ created in the previous step with the _department name_ as the _Display field_ and _department id_ as the _Data field_. This will serve as input to the Query. Know more about [Select Widget usage](/learn/how-tos/configuring-select-widget-database-fields/). +3. On the same page below the Select Widget, drag and drop a **Data  Table** widget + 1. set **Retrieve Data from** to _Services_, this will create a new variable for us + 2. **Select a service type** as **Database APIs** which are auto-generated when you save the query + 3. **Select a service** to be _hrdb_ (the database name) + 4. select **Operation/Type** as the _query_ saved in the previous step, you will find it under Query Execution group. Make a note of the Variable name generated. + 5. **Records per request** will set the Pagination related options automatically + 6. Check **Update data on input change** and uncheck Request data on page load, since we want the query to be executed after the user has selected a department. + 7. Since the query is a select query, the layout option available is **Readonly Simple View Data Table**. + 8. You can choose the **Pagination style** or go with the default. + 9. You have the option of **choosing the fields** to be displayed in the grid. Here we will retain the default of displaying all the fields. +4. [Access the variable](/learn/assets/var_sel.png) created during the configuration of the Data Table. It will have **Data tab** which can be used to bind the input value for the parameter. Bind it to the _datavalue_ of the select widget created in step 3, while Data Table drag and drop. +5. Run the project. +6. Select various departments and see the values in the Data Table change. + +## Query Operation Type + +For all queries, there will be a Rest API generated. Depending on the type of the query, the appropriate HTTP method will be generated. You can access them from the [API Designer](/learn/assets/API_Access.png). Here is the mapping for the type of query vs operation type: + +- **SELECT**: `GET` +- **INSERT**: `POST` +- **UPDATE**: `PUT` +- **DELETE**: `DELETE` + +:::note +When you use Test in filter API, you must follow the exact naming convention as specified on column names used in the query params of generated APIs. +::: + +**Example:** + +1. Go to API designer, select hrdb (from sample databases), and click Department table. +2. Select POST/filter API. +3. In the Test tab, for the q parameter, the sample value should be as follows: + - Correct way: + `name = 'Engineering'` + - Incorrect way: + `Name = "Engineering"` + +:::note +Boolean values should either be '**true'** or '**false'**, and it cannot be '**1'** and '**0'** respectively. +::: + +**Example:** + +Sample Input query params in the filter API for a Data Table that contains Boolean type should be as follows: + +Correct way: +``` +- patientId = 1313 and status = true +- patientId = 1313 and status = false +``` +Incorrect way: +``` +- patientId = 1313 and status = 1 +- patientId = 1313 and status = 0 +``` +## Query Architecture + +For all queries and procedures, there will be a Rest API generated with the Service layer. Along with the API, depending on the query or procedure type, request and response POJO classes are generated. + +**Understanding generated Code** _File structure_ + +[![](/learn/assets/queryproc_files.png)](/learn/assets/queryproc_files.png) + +### Models +Both _Request_ and _Response_ POJO classes are generated as: `Request/Response` + +- These classes are generated in a package: .models.query +- Response class is generated only for SELECT queries. The return type for Non-Select queries will be integer hence POJO class is not generated. + **Example**: + query with name **getAllEmployees** will generate **GetAllEmployeesResponse** class with all returned columns. +- For HQL queries existing Model classes will be used if possible, else a Response model similar to Native queries will be generated. + - **Example-1** + query `from Employee;` + This will return only Employee object hence it will use the existing Employee type (as generated for Data table) instead of creating a new one. + - **Example-2** + `select e.empId, e.department from Employee` + In this case, the response contains different fields so a new type will be created as <queryName>Response with fields `empId` and `department`. + +:::note +Here, `department` is a related field with type Department, so generated POJO uses existing Department type. +::: + +- Request class is generated only for INSERT and UPDATE queries. + +### Services +This layer exposes the methods related to the configured query and procedures. Controller layer uses these methods to complete the user requests. We recommend using methods from this layer in custom Java services. + +- Class with name `QueryExecutorService` is generated in the package `.service` For eg: for Service `hrdb`, class name will be `HrdbQueryExecutorService` +- Method with name `execute` will be generated for all configured queries + - For **SELECT** and **DELETE** queries, all parameters are configured as arguments for that method. In the case of Paginated request Pageable argument is added to the method signature. + - For **INSERT** and **UPDATE** queries, `Request` is the argument. + - For all **SELECT** queries `Response` object is returned. In case of Paginated, returns `Page<Response>`. + - In the case of HQL query and queries returning existing types, the return type will be the existing type. + - For non-select queries, it returns INT. +- Export API is added for queries which will return Paginated data. Method name will be `export` and which takes same arguments as execute method (as mentioned above). + +[![](/learn/assets/query_files_service.png)](/learn/assets/query_files_service.png) + +### Controllers + +- Separate controller classes are generated for query and procedures with names as `QueryExecutorController` and `ProcedureExecutorController` respectively in package `.controller`. +- Rest API is generated for each configured query and procedure. Generated method signature will be same as service layer method signature. +- For methods returning INT type, controller layer returns `IntegerWrapper`. + +[![](/learn/assets/query_files_controller.png)](/learn/assets/query_files_controller.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/database-tools.md b/website/versioned_docs/version-v11.8.5/app-development/services/database-tools.md new file mode 100644 index 000000000..8433bd6aa --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/database-tools.md @@ -0,0 +1,75 @@ +--- +title: "Database Tools" +id: "database-tools" +--- +Learn what database tools you can use to work with database services in WaveMaker. + +--- +WaveMaker provides database tools to connect to your development and deployment database servers in the cloud. You can execute scripts and run the commands supported by the database server. To access the database tools, click on DB Tools located at the bottom of your project workspace, when in the Databases Resource page. + +[![](/learn/assets/db_tools.png)](/learn/assets/db_tools.png) + +## DB Shell + +DB Shell is one of the database tools which simplify the management of your development and deployment databases. DB Shell is a command-line interface to execute DDL (Data Definition Language) and DML (Data Modification Language) commands supported by the database server. + +:::note +DB Shell can be used only for the database hosted on Cloud supporting MariaDB ver 10.2. +::: + +Upon clicking DB Tools from Databases Resource page, you will be shown the DB Shell- MariaDB Cloud tab which connects to the development database server and displays a command-line interface to execute database commands. + +[![](/learn/assets/dbtools_shell.png)](/learn/assets/dbtools_shell.png) + +## DB Scripts + +WaveMaker also makes it simple to execute SQL scripts on your database servers. + +1. From the **DB Tools** dialog, click the **Script** tab. +2. You can either **Import** or **Export** DB. + +:::note +Script execution does not work on IE9 browsers +::: + +[![](/learn/assets/dbtools_script.png)](/learn/assets/dbtools_script.png) + +## Import Database + +Import Database can be used to import an external data source into the WaveMaker and work with it. A data source will be replicated within WaveMaker. Importing an existing database will result in overwriting of the WaveMaker copy with the original data source, i.e. any changes made to the database within WaveMaker will be lost. In order to retain the changes made within WaveMaker, an export is essential. + +:::note +Note that once you run the script, you need to physically Import the Database from the **Databases Resource + icon** or use the link from the success screen. +::: + +### Things to be aware of +Key things to note while importing databases include: + +- WaveMaker supports major SQL data types. In case the imported database uses any other data type, those will be converted to the closest matching data type. +- Sequence-generated primary key columns will not be mapped during database import. It will be converted to assigned generator type. To retain the original sequence-generation, you need to manually change the generator type to sequence; give a generator name, save and re-import the database. +- The configuration fields should be entered based on the type of database used. + +## Script Execution + +Click on the **Import** tab and use the following steps to execute a script: + +1. Select the database server on which the script needs to be executed by selecting from the options in the **Host** field. Currently, the only server option is _MariaDB Cloud_ database server. +2. Enter the **Database Name**. + +:::note +A database with this name must exist in the selected database server. You can create one using the DB Shell if the database doesn't exist. +::: + +3. Click **Choose File** to locate and upload the script file to be executed. Make sure you choose a valid script file. +4. Click on the **Execute** button. After the script executes, the status of the script execution is displayed. +5. Once you have executed the script, the database is ready for import. Import the Database from the **Databases Resource + icon** or use the link from the success screen. + +## Export Database + +Export Database can be used to export the database within WaveMaker to an external data source. Click on the **Export** tab and use the following steps to execute a script: + +1. Select the database server on which the script needs to be executed by selecting from the options in the **Host** field. Currently, the only server option is _MariaDB Cloud_ database server. +2. Enter the **Database Name**. Select from the list provided. +3. Select **Schema Only** to export the Schema without data. To get the data and schema – do not check Schema only option – click GET Data Dump will get the schema and data. +4. Click on the **Get Data Dump** button. After the script executes, the status of the script execution is displayed. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/db-services/orm-artifacts.md b/website/versioned_docs/version-v11.8.5/app-development/services/db-services/orm-artifacts.md new file mode 100644 index 000000000..a206b15e4 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/db-services/orm-artifacts.md @@ -0,0 +1,236 @@ +--- +title: "ORM Artifacts" +id: "orm-artifacts" +--- + +Integration of WaveMaker app with database generates few files, services, and APIs. These are used internally by WaveMaker to achieve the seamless integration. This information is for advanced developers who want more control or need more information for academic interests. + +## Layered Architecture + +When a database is integrated into a WaveMaker app, it generates the source code for CRUD operations for each entity within the database. In addition to the CRUD APIs, the filter, count, and export APIs are also generated. Associated APIs in the case of related tables are also generated. + +The source code is generated with the ORM, Service Layer & REST APIs with each layer having a specific responsibility: + +- **Layer 1: REST Controller** is responsible for transporting the data between client and server, authorization of APIs & marshaling and unmarshaling of the model to JSON etc. +- **Layer 2: Service Layer** is responsible for validating the inputs and transaction management +- **Layer 3: DAO Layer** is responsible for interacting with the underlying database + +The following diagram depicts the Layered Architecture mentioned above: [![](/learn/assets/db_architecture.png)](/learn/assets/db_architecture.png) + +## Generated Files + +The folder structure for the generated code is as follows: + +1. Controllers generated for entities (one for each entity), queries and procedures: [![](/learn/assets/db_files_controller.png)](/learn/assets/db_files_controller.png) +2. Data Access Objects (DAO) for each of the entities: [![](/learn/assets/db_files_dao.png)](/learn/assets/db_files_dao.png) +3. Service Interfaces and Service Implementations for entities, queries, and procedures [![](/learn/assets/db_files_services.png)](/learn/assets/db_files_services.png) +4. POJOs for each entity [![](/learn/assets/db_files_pojo.png)](/learn/assets/db_files_pojo.png) + +Each of the layers performs its function and delegates the call to the next layer in the chain. For example, after the unmarshaling of the JSON data to the model, and authorization checks, the REST layer delegates the call to the service layer etc.**Design time Configuration Files**: It contains files required for designing database. + +- _db-connection-settings.json_: it contains connection properties. +- _servicename_API.json_: Generated API specification (swagger) of given service. +- _servicename_procedure.json_: contains information regarding procedures for that service. +- _servicename_query.json_: contains information regarding query for that service. +- _servicename_published_datamodel.json_: contains database schema information. It plays a major role while updating DB changes. Whenever you do manual changes in the database you have to re-import to update this file. +- _servicename_draft_datamodel.json_: Contains user modifications. It’ll delete when we do update/re-import database. +- _servicedef.xml_: contains types information for this service. + +[![](/learn/assets/dbfiles.png)](/learn/assets/dbfiles.png) + +# Generated APIs for Database Services + +Import or creation of database within a WaveMaker app results in the auto-generation of ORM artifacts from the Database Schema and as such each Schema needs to have a Primary key either single or composite. In case your external database schema comes without a primary key, you need to assign a column(s) as virtual primary key else all the columns are treated as part of a composite primary key. For each entity imported, a REST API is generated for each of the CRUD operations, Filter and Count functionalities. These REST APIs are exposed via the API Designer and can be tested and reconfigured as per the application needs. + +[![](/learn/assets/db_apis.png)](/learn/assets/db_apis.png)As an example, we are using the following Employee-Department Database Schema (Sample hrdb that can be imported into Studio) with a unique constraint for Dept_code on the department table: + +[![](/learn/assets/db_apis_db.png)](/learn/assets/db_apis_db.png) + +**Request Mapping:** _[PROJECT_ID]/[PROJECT_NAME]/services/[SERVICE_NAME]/[ENTITY_NAME]/_ + +**Example:** + +### CRUD APIs + +1. **CREATE** Inserts a record into the table _URL_: / _Request Type_: POST _Path Variables_: None _Request Parameter_: None _Request Body_: object in JSON format _Method Name Example_: createEmployee [![](/learn/assets/db_apis_create.png)](/learn/assets/db_apis_create.png) +2. **READ (primary key based)** Retrieves the data associated with given ID value _URL_: /{id} _Request Type_: GET _Path Variables_: primary key column value _Request Parameter_: None _Request Body_: none _Method Name Example_: getEmployee [![](/learn/assets/db_apis_readpk.png)](/learn/assets/db_apis_readpk.png) +3. **READ (unique key based)** Retrieves the data associated with given unique key value _URL_: /[UNIQUE_KEY]/{unique_key_value} _Request Type_: GET _Path Variables_: unique key column value _Request Parameter_: None _Request Body_: none _Method Name Example_: getByDeptCode (unique key for department entity) [![](/learn/assets/db_apis_readuk.png)](/learn/assets/db_apis_readuk.png) +4. **READ (foreign key based)** Retrieves the data associated with given ID value from the related table _URL_: /{id..+}/[relation_field] _Request Type_: GET _Path Variables_: primary key column value _Request Parameter_: + + - Page, + - Size, + - Sort + + _Request Body_: none _Method Name_: findAssociatedEmployees (employee foreign key for department entity) [![](/learn/assets/db_apis_readfk.png)](/learn/assets/db_apis_readfk.png) +5. **READ (foreign key based - self-referential)** Retrieves the data associated with given ID value _URL_: /{id..+}/[relation_field] _Request Type_: GET _Path Variables_: primary key column value _Request Parameter_: + + - Page, + - Size, + - Sort + + _Request Body_: none _Method Name_: findAssociatedEmployeesForManagerId (foreign key) [![](/learn/assets/db_apis_readsr.png)](/learn/assets/db_apis_readsr.png) +6. **UPDATE** Updates entity record associated with the given id value _URL_: /{id} _Request Type_: PUT _Path Variables_: primary key column value _Request Parameter_: None _Request Body_: object in JSON format _Method Name Example_: editEmployee [![](/learn/assets/db_apis_update.png)](/learn/assets/db_apis_update.png) +7. **DELETE** Deletes entity record associated with the given id _URL_: /{id} _Request Type_: DELETE _Path Variables_: primary key column value _Request Parameter_: None _Request Body_: None _Method Name Example_: deleteEmployee [![](/learn/assets/db_apis_delete.png)](/learn/assets/db_apis_delete.png) + +### Query APIs + +**NOTE**: Though the following APIs are available in POST and GET type, GET APIs might fail if the request URL is longer than 2048. It is advisable to use POST request type. + +1. **FILTER** Returns the list of entity instances matching the filter criteria (all values if query is not given) _URL_: /_filter_ _Request Type_: POST/GET _Path Variables_: None _Request Parameter_: + + - custom query (optional, see here for [query syntax](#custom-query-syntax)), + - Page, + - Size, + - Sort + + _Request Body_: none _Method Name_: findEmployees [![](/learn/assets/db_apis_search.png)](/learn/assets/db_apis_search.png) +2. **COUNT** Returns the count of filtered entity instances (total count if query not given) _URL_: /count _Request Type_: POST/GET _Path Variables_: none _Request Parameter_: custom query (optional, see here for [query syntax](#custom-query-syntax)) _Request Body_: none _Method Name_: countEmployees [![](/learn/assets/db_apis_count.png)](/learn/assets/db_apis_count.png) +3. **EXPORT ** Returns the downloadable file url for the filtered data _URL_: /export _Request Type_: POST _Request Parameter_: + + - pageable - pagination and sorting options, [see here for more](http://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/Pageable.html), + - Size, + - Sort + + _Request Body_: + + - ExportOptions (Body) + - custom query (optional, see here for [query syntax](#custom-query-syntax)), + - fields list (optional): [{ “header”:””, “field”:””, “expression”:”” (eg: (${field_name} (or) <any string>)) }] + - exportType - data format for export can be EXCEL or CSV + - fileName: exported file name. + + _Method Name Example_: exportEmployees [![](/learn/assets/db_apis_export.png)](/learn/assets/db_apis_export.png) + +### Custom Query Syntax + +The APIs generated by WaveMaker for all the imported tables will have methods that take a query as input. Here we will look at the usage of such query in APIs. + +**APIs that use HQL Queries**: The Filter, Count and Export API in every Table Controller will use the HQL query, which is an optional parameter, for retrieving the data. These APIs can be found in respective tables’ controller class file. + +1. **Filter API** This API returns the list of Entity objects that matches the given filter conditions in the query. If query param is empty, API returns all the Entity objects. +2. **Count API** Returns the count of Entities that matches the given filter conditions in the query. For an empty query, it returns the count of all Entity objects. +3. **Export API** Returns a downloadable file with the list of Entities that matches the given filter conditions in the query. For an empty query, we get all the Entity objects. + +**Query Composition**: The HQL query mainly consists of four types of parameters. + +- Field Name +- Value Expression +- Value +- Logical Expression + +**Note**: Aggregate functions (avg(), sum(), min(), max()) in HQL query are currently not supported with these APIs. + +**FieldName parameter** + +- The fieldName refers to the name of the field associated with the column in the respective table. The field name is derived from the column name in the table and usually camelCased. [![](/learn/assets/db_apis_fields.png)](/learn/assets/db_apis_fields.png) +- The name of the field for a given column can be seen from DB Designer or the respectively generated model class. Field Name of a column can be found in DB designer on the selection of respective column in the properties panel. [![](/learn/assets/db_apis_fieldname.png)](/learn/assets/db_apis_fieldname.png) +- Relational field names - In order to filter values with respect to an entity in relation, fieldname must be given as _entityfield.fieldname_. This is applicable only for ManyToOne and OneToOne Relations. Eg: department.name = ‘Engineering’, the name is the fieldname of Department.java [![](/learn/assets/db_apis_fieldsrel.png)](/learn/assets/db_apis_fieldsrel.png) + +**Value Expression parameter** Supported value expression types are listed in below table + +| **Operation** | **Expression** | **Supported Value Types** | **Result** | **Examples** | +| --- | --- | --- | --- | --- | +| equals | = | Number or String | Values that equals to given value | +- empId=1 +- firstname=’Eric’ + + | +| not equals | != (or) < > | Number or String | Values that are not equal to given value | + +- zip!=02127 +- jobTitle< >‘Engineer’ + + | +| between | between | Date or Number | Values between given range | + +- birthdate between '1973-10-21' and '1986-06-18' (using date format - YYYY-MM-DD) +- zip between 14231 and 15922 + + | +| less than | < | Number | Values less than given value | + +- empId<6 + + | +| greater than | > | Number | Values greater than given value | + +- deptId>10 + + | +| less than or equal to | <= | Number | Values less or equal to given value | + +- empId<=4 + + | +| greater than or equal to | >= | Number | Values greater than or equal to given value | + +- zip>=11 + + | +| pattern matching | like | String | Values matching the given pattern | + +- street like ‘4%Houston%’ + + | +| starts with | like | String | Values starting with the given string | + +- firstname like ‘E%’ + + | +| ends with | like | String | Values ending with the given string | + +- lastname like ‘%e’ + + | +| containing | like | String | Values containing the given string | + +- lastname like ‘%e%’ + + | +| in | in | Number or Date or String | Values in the given set | + +- zip in (‘14231’, ‘02127’, ‘11212’) +- birthdate in ('1973-10-21' ,'1986-06-18') +- firstname in ( 'Sally' , 'William' , ‘Amanda’ ) + + | +| null | is null | String | Values satisfying given condition | + +- role is null + + | +| not null | is not null | String | Values satisfying given condition | + +- date is not null + + | +| empty | = | String | Values satisfying given condition | + +- lastname = ‘’ + + | +| not empty | != (or) <> | String | Values satisfying given condition | + +- lastname <> ‘’ +- lastname != ‘’ + + | + +**Value parameter** The “Value” parameter is the comparison value for the given field name. The value should be single quoted for non-numeric types. The format for the value of type date is ‘YYYY-MM-DD’. + +**Logical Expressions** + +- A logical expression in HQL does one of the following: + - joins two or more conditions to form a complex query + - alters the logic of the conditions +- Supported logical expressions with examples are listed below +- Order of execution of conditions can be controlled using parenthesis. Eg: (empId=4 AND zip=02127 ) OR (city like 'New York%' OR birthdate between '1991-01-01' and '1999-12-31' ) + +| **Logical Expression** | **Results** | **Examples** | +| --- | --- | --- | +| AND/and | Result set satisfying both conditions | empId>5 AND firstname like ‘A%’ | +| OR/or | Result set satisfying either of the conditions | empId=5 OR deptId=1 | +| NOT/not | Result set satisfying negation of the conditions | NOT ( firstname like ‘A%’ AND empId=4) | + +For further reference to HQL query [http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch16.html](http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch16.html) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/db-services/working-with-queries.md b/website/versioned_docs/version-v11.8.5/app-development/services/db-services/working-with-queries.md new file mode 100644 index 000000000..19a9bf7b6 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/db-services/working-with-queries.md @@ -0,0 +1,189 @@ +--- +title: "Working with Queries" +id: "working-with-queries" +--- + +There will be times when you want to display data from multiple tables or update/insert values into multiple tables. Queries and Stored Procedures come in handy in such instances. WaveMaker provides editors for Queries & Procedures for integrating them with the WaveMaker applications. Each query & procedure used in the WaveMaker application will be exposed as a REST API for the UI to consume and render the data. + +In this section, we will be seeing how WaveMaker supports Query usage with the help of an example. + +## Query Editor + +From the Database Designer, use the Query tab to build custom database queries for custom reports and dashboards. + +[![](/learn/assets/query_tab.png)](/learn/assets/query_tab.png) + +- The editor supports IntelliSense, use **CTRL-Space** to see suggestions for the table and column names. +- The queries can be in **HQL or Native SQL**. These queries can be saved and used via the Database APIs generated. +- Parameterised queries are also supported. **Parameters** can be marked as Required. If marked as required, the Variable associated with this query operation will not be invoked until all the required parameter values are set to the variable input. +- No DB-specific changes, apart from the syntax of the query, needs to be taken care of. +- If the schema name is not the default name, then the table names need to be prefixed with the schema names. +- [See here for support on fields of type Blob/CLOB](/learn/app-development/services/database-services/blob-support-queries-procedures/) +- You have to **Execute** the query successfully to be able to save the query. The **Save icon** will be active only after a successful run of the query. +- Once you save the query, you can see the entry under Database Resources. You can use it to reopen and modify the query if need be. To modify the query, open the query, make the changes, run and save the query. You can also Delete the query using the **delete** icon. +- When a query is saved, it generates a **paginated API** that returns a list of objects paginated. In cases where the query returns at most one record, setting the **Records** to _Single_ will ensure that the generated API returns one object instead of paginated objects. The default is set to _Paginated._ +- In addition, every API generated for query exposes an additional API for exporting the query results to Excel/CSV. However, in case the query returns a single result, the export API will not be generated. The list of APIs generated can be viewed from the [API Designer](/learn/assets/API_Access.png) +- To execute and access the results of the query within the app, you need to [create a Variable based on Database APIs](/learn/app-development/variables/database-apis/) and bind the results to a widget of your choice. [Variable Access](/learn/assets/var_sel.png). + +**Limitations**: + +- Internal pagination is implemented, as such LIMIT clause in queries WILL NOT be supported + +### Types of Query + +WaveMaker supports two types of queries. They are: + +1. **Native SQL**: You can execute Database-specific SQL queries using this option. The same query directly executed in the underlying database. You have to manually escape query in case of spaces, special characters and SQL keywords in the query. +2. **Hibernate Query Language (HQL)**: HQL queries depends on Java entities instead of native tables. For more info please [refer here](http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html_single/#queryhql). + +You can select the appropriate type from the **Type** option in the designer. + +**NOTE**: This post explains the usage of queries in WaveMaker using the Native SQL code. + +### Query Creation + +In this example, we will build a query to list the number of vacation days availed by employees from each department. We will be using the _hrdb sample database_ that ships with the product. + +1. Import the **sample database** into your project. [Database Integration](/learn/app-development/services/database-services/working-with-databases/). +2. Select **hrdb** from the **Databases** Resource to open the Data Designer window. +3. Click the **Query** tab of the **data designer** window. +4. Select **Native SQL** as the query type and enter the following code in the Query Editor: + + select d.NAME, sum(ENDDATE - STARTDATE ) as days + from VACATION v, EMPLOYEE e, DEPARTMENT d + where e.EID = v.EMPID + and e.DEPTID = d.DEPTID + group by d.NAME + +5. **Execute** the query and see the results in the result box below the query window. Save the query as _vacation_days_ with appropriate description. + +### Query Usage + +We will see how to use the query results by using a **Data Table **to display the results (you can use any of the Data Widgets for this purpose): + +- On any page of the project, drag and drop a **Data  Table** widget + 1. set **Retrieve Data from** to _Services_, this will create a new variable for us + 2. **Select a service type** as **Database APIs** which are auto-generated when you save the query + 3. **Select a service** to be _hrdb_ (the database name) + 4. select **Operation/Type** as the _query_ saved in the previous step, you will find it under Query Execution group (you might have to scroll down to get to this option). + 5. **Records per request** will set the Pagination related options automatically + 6. Setting the **Request data on page load** for the Variable ensures that the call to the service is triggered whenever the page is loaded. Setting **Update data on input change** will ensure the call when the data changes (as seen in the next section). + 7. Since the query is a select query, the layout option available is **Readonly Simple View Data Table**. + 8. You can choose the **Pagination style** or go with the default. + 9. You have the option of **choosing the fields** to be displayed in the grid. Here we will retain the default of displaying all the fields. +- Run the project and see the results displayed in the table format. + +### Parameterized Query Creation + +Instead of hardcoding values, you have a choice to declare Named parameters in the query. While executing queries these values get replaced with given values. Named parameters can be declared using ":" (colon) prefix. WaveMaker internally uses Hibernate for matching and replacing the named parameters. + +For example, let us modify the query above to accept the department name as input and display the results for the specified department name. + +1. Modify the query created in the previous step to include the parameter for department id. Or you may create a new query thus: + + select d.NAME, sum(ENDDATE - STARTDATE ) as days + from VACATION v, EMPLOYEE e, DEPARTMENT d + where e.EID = v.EMPID + and e.DEPTID = d.DEPTID + and d.DEPTID = :did + group by d.NAME + +2. The parameter entry is made in the **Parameters** section. +3. Since this query will return a single record set Records to **Single**. +4. Select the appropriate data type for the parameter using _Type_ field, enter a _Test Value_ and _Execute_ the query. Use _List_ in case your parameter takes multiple array value, the test values in such a case should be comma-separated values without spaces. For example, in this example if _did_ were a list then the test values would be _1,2_. +5. The parameters can be set to server-side properties like _current date, time, id, or username_ by picking the same for Type from under the **Server Side Properties** drop-down. When you select this option while executing the query the appropriate value is taken from the application rather than from the user. For example, if you have a query: + + select FIRSTNAME + from EMPLOYEE where EMP_ID = :id + + You can, in the Parameter section, set the **parameter id Type** to _LoggedIn UserId_ from under the _Server Side Properties_. When you enable security using the database as the service provider and employee as the User table, then setting the id to _LoggedIn UserId_ will get the user id of the current logged in user. You need not bind the parameter again, explicitly. +6. Parameter values can also be set to App Environment properties and be defined separately for different app environments ([know more](/learn/how-tos/using-app-environment-properties/)). +7. To execute and access the results of the query within the app, you need to [create a Variable based on Database APIs](/learn/app-development/variables/database-apis/) and bind the results to a widget of your choice. [Variable Access](/learn/assets/var_sel.png) + +### Parameterized Query Usage + +1. Create a [Database Crud Variable](/learn/app-development/variables/database-crud/) for Department table. [Variable Access](/learn/assets/var_sel.png) +2. Add a **Select** widget to the page and bind it to the _Variable dataset_ created in the previous step with the _department name_ as the _Display field_ and _department id_ as the _Data field_. This will serve as input to the Query. Know more about [Select Widget usage](/learn/how-tos/configuring-select-widget-database-fields/). +3. On the same page below the Select Widget, drag and drop a **Data  Table** widget + 1. set **Retrieve Data from** to _Services_, this will create a new variable for us + 2. **Select a service type** as **Database APIs** which are auto-generated when you save the query + 3. **Select a service** to be _hrdb_ (the database name) + 4. select **Operation/Type** as the _query_ saved in the previous step, you will find it under Query Execution group. Make a note of the Variable name generated. + 5. **Records per request** will set the Pagination related options automatically + 6. Check **Update data on input change** and uncheck Request data on page load, since we want the query to be executed after the user has selected a department. + 7. Since the query is a select query, the layout option available is **Readonly Simple View Data Table**. + 8. You can choose the **Pagination style** or go with the default. + 9. You have the option of **choosing the fields** to be displayed in the grid. Here we will retain the default of displaying all the fields. +4. [Access the variable](/learn/assets/var_sel.png) created during the configuration of the Data Table. It will have **Data tab** which can be used to bind the input value for the parameter. Bind it to the _datavalue_ of the select widget created in step 3, while Data Table drag and drop. +5. Run the project. +6. Select various departments and see the values in the Data Table change. + +## Query Operation Type + +For all queries, there will be a Rest API generated. Depending on the type of the query, the appropriate HTTP method will be generated. You can access them from the [API Designer](/learn/assets/API_Access.png) Here is the mapping for the type of query vs operation type: + +- SELECT -> GET +- INSERT -> POST +- UPDATE -> PUT +- DELETE -> DELETE + +**NOTE-1:** When you use Test in filter API, you must follow the exact naming convention as specified on column names used in the query params of generated APIs. + +**Example: ** + +1. Go to API designer, select hrdb (from sample databases), and click Department table. +2. Select POST/filter API. +3. In the Test tab, for the q parameter, the sample value should be as follows: + - Correct way: **name = 'Engineering'** + - Incorrect way: **Name = "Engineering"** + +**NOTE-2:** Boolean values should either be '**true'** or '**false'**, and it cannot be '**1'** and '**0'** respectively. + +**Example: ** + +Sample Input query params in the filter API for a Data Table that contains Boolean type should be as follows: + +Correct way: + +- patientId = 1313 and status = true +- patientId = 1313 and status = false + +Incorrect way: + +- patientId = 1313 and status = 1 +- patientId = 1313 and status = 0 + +## Query Architecture + +For all queries and procedures, there will be a Rest API generated with the Service layer. Along with the API, depending on the query or procedure type, request and response POJO classes are generated. + +**Understanding generated Code** _File structure_ [![](/learn/assets/queryproc_files.png)](/learn/assets/queryproc_files.png)_Models_: Both _Request_ and _Response_ POJO classes are generated as: <queryName> Request/Response + +- These classes are generated in a package: .models.query +- Response class is generated only for SELECT queries. The return type for Non-Select queries will be integer hence POJO class is not generated. Eg: query with name **getAllEmployees** will generate **GetAllEmployeesResponse** class with all returned columns. +- For HQL queries existing Model classes will be used if possible, else a Response model similar to Native queries will be generated. + - Eg: query `from Employee;` + - will return only Employee object hence it will use the existing Employee type (as generated for Data table) instead of creating a new one. + - Eg2: `select e.empId, e.department from Employee` + - In this case, the response contains different fields so a new type will be created as <queryName> Response with fields _empId_ and _department_. **Note**: Here, _department_ is a related field with type Department, so generated POJO uses existing Department type. +- Request class is generated only for INSERT and UPDATE queries. + +_Services_: This layer exposes the methods related to the configured query and procedures. Controller layer uses these methods to complete the user requests. We recommend using methods from this layer in custom Java services. + +- Class with name QueryExecutorService is generated in the package .service For eg: for Service **hrdb**, class name will be **HrdbQueryExecutorService** +- Method with name **execute<queryName>** will be generated for all configured queries + - For SELECT and DELETE queries, all parameters are configured as arguments for that method. In the case of Paginated request Pageable argument is added to the method signature. + - For INSERT and UPDATE queries, **<queryName>Request** is the argument. + - For all SELECT queries **<queryName>Response** object is returned. In case of Paginated, returns **Page<<queryName>Response>**. + - In the case of HQL query and queries returning existing types, the return type will be the existing type. + - For non-select queries, it returns INT. +- Export API is added for queries which will return Paginated data. Method name will be **export<queryName>** and which takes same arguments as execute method (as mentioned above). + +[![](/learn/assets/query_files_service.png)](/learn/assets/query_files_service.png)_Controllers_: + +- Separate controller classes are generated for query and procedures with names as **QueryExecutorController** and **ProcedureExecutorController** respectively in package **.controller**. +- Rest API is generated for each configured query and procedure. Generated method signature will be same as service layer method signature. +- For methods returning INT type, controller layer returns **IntegerWrapper**. + +[![](/learn/assets/query_files_controller.png)](/learn/assets/query_files_controller.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/java-service.md b/website/versioned_docs/version-v11.8.5/app-development/services/java-service.md new file mode 100644 index 000000000..343619c8c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/java-service.md @@ -0,0 +1,41 @@ +--- +title: "Java Service" +id: "java-service" +--- + +## **Overview** + +Java Services allow app developers to write custom business logic or enable integration with 3rd party libraries and tools and are deployed on the Server side. For every Java Service created in WaveMaker, its REST API contract is auto-generated and is ready for integration with front-end layer (web or mobile). + +Variables are required to invoke Java Service methods, each Variable can be configured to take the necessary method parameters required as data inputs and return JSON response. Variables internally perform the necessary conversion to invoke the equivalent REST API endpoint/resource for the Java Service methods. + +When you create a Java Service in WaveMaker, Java sample file is created. You can access this file from the _Java Services_ Resources. You can edit the file and even delete the service. + +[![](/learn/assets/Java_services.png)](/learn/assets/Java_services.png) + +A Java method can have input and output in the form of an individual or a set of parameters. These parameters can be of the following types: **Input parameters** can be of the type: + +- primitive objects, +- POJO classes, +- a collection of POJO classes and primitives, +- page +- Http servlet response/request which can be passed as URL-based header params or in the form of cookies +- a pageable object with values pertaining to the page to be retrieved, the size of each page and sort field name + +**Output parameters** can be of the type: + +- primitive objects, +- POJO classes, +- a collection of POJO classes and primitives, +- page + +# Java Services framework + +Creating a Java Service generates multiple files, of which the following are of importance: + +[![](/learn/assets/JS_files.png)](/learn/assets/JS_files.png) + +1. **Spring Controller File**: MyJavaController.java, in this example - This file contains the details related to the Java Service. Public methods in the controller class are wrappers of the underlying Java Service code, acting as an endpoint which can be invoked as REST API. The methods can be hidden or exposed to the client using the directives: @HideFromClient and @ExposeToClient, respectively. Request JSON object from the invoking client is automatically converted to POJOs in the method parameter for POST/PUT/DELETE. Similarly, the response POJOs get converted to JSON object. +2. **API JSON File**: MyJavaService_API.json, in this example - contains the file structure and details as used by the API Documentation. This is available only during the design time. +3. **Spring Bean Configuration File**: MyJavaService.spring.xml, in this example - Bean classes for service/method lookup + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/java-services/api-composer-toolkit.md b/website/versioned_docs/version-v11.8.5/app-development/services/java-services/api-composer-toolkit.md new file mode 100644 index 000000000..b52d7f711 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/java-services/api-composer-toolkit.md @@ -0,0 +1,72 @@ +--- +title: "API Orchestration using API Composition Toolkit" +id: "api-composer-toolkit" +sidebar_label: "API Orchestration" +--- + +Backend for Frontend Empowered API Orchestration with the API Composition Toolkit + +--- + +API Composition toolkit can be your playground to compose an API or an object using multiple API endpoints. This means you can combine any Service in [Java Service](/learn/app-development/services/java-services/java-service) and write custom business logic that you can use as a variable and bind to any UI widget. + +It generates Java code for each imported service, which contains services and its methods into a package that Java understands, i.e., Service and Model (see image below). WaveMaker makes it easy to access these generated packages: service and model into the backend API designer. + +![api composer](/learn/assets/api-composer.png) + +You can discover these dependencies and enable them with a single click, which automatically generates the Java code for you to @Autowire the Service class of that particular entity. You can then extend or use the service APIs or methods based on business logic. + +## Supported Services + +- REST Service +- Imported APIs +- Database +- Java Service + +## Discover Dependencies + +When you import a service, for example, a REST API, these generated services can be accessed when you create a [Java Service](/learn/app-development/services/java-services/java-service). You can discover dependencies and the available methods from the right panel, as shown in the image below. + +![api composer discover dependencies](/learn/assets/api-composer-discover-dependencies.png) + +To use the rendered services and model, expand the desired service by clicking the service. + +![api composer disover methods](/learn/assets/api-composer-discover-method.png) + +Select the method from the service, which then adds an Import statement and the Autowired annotation to the Java Service, as shown in the image below. + +![api composer import statement](/learn/assets/api-composer-import.png) + +![api composer method added](/learn/assets/api-composer-method-added.png) + +We can use the @Autowire variable and their methods to design business logic and then use the API to integrate it with the UI layer, including widgets. + +## Controlling API Composition + +You can take control of enabling or disabling the **API Composition** flag if you do not want to generate Java code for the services, these typically auto-generates Java code for the Imported APIs and REST Services. + +:::note +The default setting is enabled for **API Composition**. +::: + +### API Composition for New Projects + +When you create a new WaveMaker project, the user can choose to enable or disable API Composition. + +![](/learn/assets/api-composer-enable-project-creation.png) + +### API Composition for Existing Projects + +For existing projects or after creating a project, you can go to the **Project Settings** dialog and enable or disable API Composition as required. + +1. Click **Settings** +2. Select **Project Settings**—opens the following dialog. +3. Enable or Disable API Composition. + +![](/learn/assets/api-composer-enable-after-project-creation.png) + +After changing these settings, you would require to reload the project and perform the action on the Project Update dialog. + +:::warning +If you disable API Composition and already depend on the service, you will get compilation errors. +::: \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/java-services/generated-rest-apis-api-designer.md b/website/versioned_docs/version-v11.8.5/app-development/services/java-services/generated-rest-apis-api-designer.md new file mode 100644 index 000000000..4d4039cc8 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/java-services/generated-rest-apis-api-designer.md @@ -0,0 +1,9 @@ +--- +title: "Generated REST APIs (API Designer)" +id: "generated-rest-apis-api-designer" +--- +--- + +Once the Java Service is saved, it is available as REST API in the API Designer under Core APIs. For each method in the Java controller, an API endpoint is generated. The Type of API is auto-assigned based upon the name of the method. In case the method takes input parameters, it is converted to a POST method. This can be modified by the API Designer. + +You can test your Java Services from the **API Designer**. Changing the definition would result in changes in all the files generated. You can choose to test the service from here. diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/java-services/java-integration-database-service.md b/website/versioned_docs/version-v11.8.5/app-development/services/java-services/java-integration-database-service.md new file mode 100644 index 000000000..62fcee728 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/java-services/java-integration-database-service.md @@ -0,0 +1,166 @@ +--- +title: "Integrate Database Service in JavaServices" +id: "java-integration-database-service" +sidebar_label: "DB Service Integration" +--- +--- + +WaveMaker generates REST API when a database is imported. However the lower level database access can be used inside a Java class to execute custom business logic. In case if you want more control on database service methods or if you would like to extend or use the database service API's or methods based on business logic then you can `@Autowire` the Service class of that particular database entity. + +The **autowiring feature of spring framework** enables you to inject the object dependency implicitly. The advantage of autowiring is, it requires the less code because we don't need to write the code to inject the dependency explicitly. + +## Accessing Database services using Java Service + +To access a database table from a [Database Integrated](/learn/app-development/services/database-services/working-with-databases/) into your app, In +the JavaService Navigate to the Dependencies panel on the right side expand the service you would like to use click on any of its methods and select +add particular service to this Java Service as shown below. + +[![](/learn/assets/database-service-import.png)](/learn/assets/database-service-import.png) + +### Where to find DB Services + +You can find a list of methods for User table on expanding `UserService` like `create`, `delete`, `find`, `update`, query service, procedure service, and +more. + +### Accessing DB Services + +For working with the **Database table operations** such as insert, get, update in Java Service, from the dependencies dialogue select the service method and +click on add particular service to this Java Service, so that the required import and autowired will be added we can make use of the autowired variable and +call any of its methods + +[![](/learn/assets/database-service-add.png)](/learn/assets/database-service-add.png) + +Here we are trying to access the User table from the sample `hrdb` +### Accessing different DB Services with the same name + +If there are two or more beans for same class type, you need to use `@Qualifier` annotation along with `@Autowired` annotation and pass the bean name in annotation parameter. + +For example, you have more than one implementation of `UserService`, then use qualifier to inject the specific implementation of User service. + +```Java +import org.springframework.beans.factory.annotation.Autowired; + +import com..hrdb.service.UserService; +import com..hrdb.User; + +@ExposeToClient +public class MyJavaService { + + @Autowired + @Qualifier("hrdb.userService"); + public UserService userService; + + public User getmyUser(int userid) { + User user = userService.findById(userid); + return user; + } +} +``` +## Database Transactions from Java Service + +### Transactions for related entities + +Transactions can be used in cases where you have multiple independent statements which need to be linked together. A transaction can end in two ways: with a commit or with a rollback. When a transaction commits, the data modifications made by its statements are saved. If a statement within a transaction fails, the transaction rolls back, undoing the effects of all statements in the transaction. + +Let us see a simple example of interacting with the hrdb database in Java service using Transactions. + +- Define an API that creates employee and retrieves the same from the database. +- Create employee and retrieving employee are two independent calls to the database. When we enclose it with the transaction it will ensure that either both actions occur or neither action occurs. +- In the below transaction code, if _createEmployee_ is successful but retrieve employee fails, then created employee will be reverted from the database. + +```Java +package com.wavemaker.hrdbexample; + +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; + +import com.wavemaker.runtime.data.exception.EntityNotFoundException; +import com.wavemaker.runtime.security.SecurityService; +import com.wavemaker.runtime.service.annotations.ExposeToClient; +import com.wavemaker.runtime.service.annotations.HideFromClient; + +import com.hrdb.Department; +import com.hrdb.Employee; +import com.hrdb.service.EmployeeService; + +import java.util.Date; + +@ExposeToClient +public class HrdbManager { + + private static final Logger logger = LoggerFactory.getLogger(HrdbManager.class); + + @Autowired + private EmployeeService employeeService; + + /** + * Objective of the api is to create employee and retrieve same from database. + * + * As create employee and retrieving employee are two independent calls to database.If we enclose it with transaction which will ensure that either both actions occur or neither action occurs. + * + * Example : If createEmployee is successful but retrieve employee fails, then created employee will be reverted from database. + * + **/ + @Transactional(rollbackFor = EntityNotFoundException.class, value = "hrdbTransactionManager") + public Employee createEmployee() + { + //creating employee object + Employee employee = new Employee(); + employee.setFirstname("John"); + employee.setLastname("Smith"); + employee.setStreet("45 Houston Street"); + employee.setCity("New York"); + employee.setState("NY"); + employee.setZip("10106"); + employee.setBirthdate(new Date(1471355649751L)); + employee.setPicurl("http://dev.wavemaker.com/examples/salesrep/john-kim.png"); + employee.setJobtitle("Development Manager"); + employee.setUsername("john"); + employee.setPassword("john"); + employee.setTenantid(1); + + //every employee should be part of some department + Department department = new Department(); + department.setDeptid(1); + department.setName("Engineering"); + department.setBudget(1936760); + department.setQ1(445455); + department.setQ2(522925); + department.setQ3(426087); + department.setQ4(542293); + department.setDeptcode("Eng"); + department.setLocation("New York"); + department.setTenantid(1); + + //setting department to employee + employee.setDepartment(department); + + //persisting employee + Employee persistedEmployee = employeeService.create(employee); + + //retrieve persisted employee object + return employeeService.getById(persistedEmployee.getEid()); + + } +} +``` + +To see the rollback in action replace the last line with: + +```Java +//retrieve non existing object +return employeeService.getById(71236); +``` + +### Accessing Query services using Java Service + +**Named Queries** or queries that are written, tested and saved in query editor of Database Designer. [Query Editor](/learn/app-development/services/database-services/working-with-queries). + +For each and every named query, there will be a rest service generated from query execution controller and exposed under APIDesigner panel. Here we are seeing two queries - EmpCountByState and which were created from the query editor. + +[![](/learn/assets/autowired_queries.png)](/learn/assets/autowired_queries.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/java-services/java-integration-services.md b/website/versioned_docs/version-v11.8.5/app-development/services/java-services/java-integration-services.md new file mode 100644 index 000000000..9c210e581 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/java-services/java-integration-services.md @@ -0,0 +1,84 @@ +--- +title: "Java Integration Services" +id: "java-integration-services" +--- +--- + +If you want more control or you are more comfortable working with Java, you can invoke various services like DB, Feed, SOAP and Security services from Java using `@Autowired` the service files. + +The **autowiring feature of spring framework** enables you to inject the object dependency implicitly. It internally uses setter or constructor injection. The advantage of autowiring is, it requires the less code because we don't need to write the code to inject the dependency explicitly. + +:::note +REST Services cannot be invoked. +::: + +## Accessing current logged in user details + +To access the Logged in user details in an app that is secured, you need to import the security service. The **Security Service** import can be done using the following code snippet. + +``` +import com.wavemaker.runtime.security.SecurityService; + +@Autowired +public SecurityService securityService; + +public String getLoggedUser() { + String loggedUser = securityService.getUserName (); + return loggedUser ; +} +``` +## Accessing external Java libraries + +There are two ways in which this can be achieved: + +1. Exporting the project to an IDE of your choice and changing the code as per your requirements and importing it to WaveMaker. This is possible since the code generated for WaveMaker projects is **Maven** complaint. [Export Project](/learn/app-development/dev-integration/import-export-update-apps/#export-project) +2. Importing the **jar** files as external resource and using them within your app. [Import Resource](/learn/app-development/services/3rd-party-libraries) + +### Invoking Imported Web Services + +Various [Web Service can be Integrated](/learn/app-development/services/web-services/web-services/) into WaveMaker apps. These services can be invoked from Java Services. + +For **Soap Service** import following is the code snippet. + +:::note +Calculator is WSDL service which was imported. +::: + +``` +import com.wavemaker..services.calculator.*; +import com.wavemaker..services.calculator.services.*; + +@ExposeToClient +public class MyJavaService { + + @Autowired + public CalculatorService calculatorService; + + public AddResponse wsdlfromjava(float x,float y){ + Add add = new Add(); + add.setX(x); + add.setY(y); + return calculatorService.add(add); + } +} +``` +For **Feed Service** import following is the code snippet +``` +import com.wavemaker.runtime.feed.service.FeedService; +import com.wavemaker.runtime.feed.model.Feed; + +@Autowired +FeedService feedService; + +public Feed feedfromJavaService(String feedUrl) { + Feed myFeed = feedService.getFeed(feedUrl); + return myFeed; +} +``` +For **Feed With Auth Service** import following is the code snippet +``` +public Feed authFeedfromJavaService(String feedURL, String username, String password, int connectionTimeout) { + Feed authFeed = feedService.getFeedWithHttpConfig(feedUrl,username,password,connectionTimeout); + return authFeed ; +} +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/java-services/java-service.md b/website/versioned_docs/version-v11.8.5/app-development/services/java-services/java-service.md new file mode 100644 index 000000000..e0fd5bddd --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/java-services/java-service.md @@ -0,0 +1,53 @@ +--- +title: "Java Service" +id: "java-service" +--- +--- + +## Overview + +Java Services allow app developers to write custom business logic or enable integration with 3rd party libraries and tools and are deployed on the Server side. For every Java Service created in WaveMaker, its REST API contract is auto-generated and is ready for integration with front-end layer (web or mobile). + +Variables are required to invoke Java Service methods, each Variable can be configured to take the necessary method parameters required as data inputs and return JSON response. Variables internally perform the necessary conversion to invoke the equivalent REST API endpoint/resource for the Java Service methods. + +## Creating a Java Service + +When you create a Java Service in WaveMaker, Java sample file is created. You can access this file from the _Java Services_ Resources. You can edit the file and even delete the service. + +[![](/learn/assets/Java_services.png)](/learn/assets/Java_services.png) + +A Java method can have input and output in the form of an individual or a set of parameters. These parameters can be of the following types: + +### Input parameters +Input parameters can be of the type: + +- primitive objects, +- POJO classes, +- a collection of POJO classes and primitives, +- page +- Http servlet response/request which can be passed as URL-based header params or in the form of cookies +- a pageable object with values pertaining to the page to be retrieved, the size of each page and sort field name + +### Output parameters +Output parameters can be of the type: + +- primitive objects, +- POJO classes, +- a collection of POJO classes and primitives, +- page + +## Java Services framework + +Creating a Java Service generates multiple files, of which the following are of importance: + +[![](/learn/assets/JS_files.png)](/learn/assets/JS_files.png) + +### Spring Controller File +MyJavaController.java, in this example - This file contains the details related to the Java Service. Public methods in the controller class are wrappers of the underlying Java Service code, acting as an endpoint which can be invoked as REST API. The methods can be hidden or exposed to the client using the directives: @HideFromClient and @ExposeToClient, respectively. Request JSON object from the invoking client is automatically converted to POJOs in the method parameter for POST/PUT/DELETE. Similarly, the response POJOs get converted to JSON object. + +### API JSON File +`MyJavaService_API.json`, in this example - contains the file structure and details as used by the API Documentation. This is available only during the design time. + +### Spring Bean Configuration File + +`MyJavaService.spring.xml`, in this example - Bean classes for service/method lookup diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/java-services/variables.md b/website/versioned_docs/version-v11.8.5/app-development/services/java-services/variables.md new file mode 100644 index 000000000..2f05b6c62 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/java-services/variables.md @@ -0,0 +1,18 @@ +--- +title: "Variables for Invocation" +id: "variables" +--- +--- + +Java Service can be accessed from within your app using Variables. These variables allow one to trigger the methods within the Java Service, pass the necessary parameters to the method and access the results from the method. + +[![](/learn/assets/Var_create.png)](/learn/assets/Var_create.png) + +For each method within the Java Service, a service variable can be generated using the appropriate option from the **Operation** property; with the **input parameters** available within the **_Data_ tab** and the **output** available as the **datavalue for binding**. + +You can invoke the Java Service by triggering a call to the Service Variable generated. In case you have multiple public class methods in your Java Service, you will see multiple Operation options. + +[![](/learn/assets/JS_var_create.png)](/learn/assets/JS_var_create.png) + +[Know more about Variables from here](/learn/app-development/variables/data-integration/). [Know how to Create Variables from here](/learn/app-development/variables/java-services/). + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/mock-services/mock-imported-apis.md b/website/versioned_docs/version-v11.8.5/app-development/services/mock-services/mock-imported-apis.md new file mode 100644 index 000000000..e81aff20d --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/mock-services/mock-imported-apis.md @@ -0,0 +1,48 @@ +--- +title: "MockingBird - Mock REST APIs" +id: "mock-imported-apis" +sidebar_label: "Mock REST API" +--- +--- + +API MockingBird can mock REST APIs with live authentic responses for your application, allowing you to simultaneously design the frontend, while the backend team can develop the APIs. This helps you keep the development flow continuous when you need APIs with live data during the UI development or testing phase. Also, in cases when the API breaks often, such as in the time zones when backend developers may not be able to offer support. + +MockingBird provides a convenient way to switch between mocked API and the orginal API from the Studio. To get started with MockingBird, when the API contract is made, the developer can import the OpenAPI/Swagger spec to mock APIs. + +## How it works + +In WaveMaker Studio, you can mock API at the time of importing the REST API by simply enabling the API MockingBird flag. It simulates actual APIs where MockingBird can generate requests and get realistic responses that an actual API would return. + +API MockingBird is smart to understand the data types of each field in your API response and choose mock data intelligently. This recognizes 100s of data types starting from First Name, Last name, Address, zip code, and Credit Card number for mocking the API data. + +## Create Mock Server for Imported API + +1. A Swagger should be successfully imported into the **Importing APIs** section. +2. Mock Imported APIs. + +### Enabling API Mocking + +1. After importing the API, go to **APIs** resources and select **Imported APIs** to be mocked. + +[![create mock api](/learn/assets/imported-apis.png)](/learn/assets/imported-apis.png) + +3. Navigate to the **Settings** tab and click **Create Mock Server** to create a mock server for the first time. + +[![create mock api](/learn/assets/apis-settings.png)](/learn/assets/apis-settings.png) + +4. Once the mock server is created successfully, you will see a **Mock** tag attached to the imported API, as shown below. + +[![create mock api](/learn/assets/moked-apis.png)](/learn/assets/moked-apis.png) + +5. All the variables associated with this imported API will be pointing to the mocked service. + +### Disabling API Mocking + +1. Select the mocked API, which displays a Mock tag. +2. Navigate to the **Settings** tab, and toggle the **Mock APIs** button to disable. + +[![create mock api](/learn/assets/enabled-moked-apis.png)](/learn/assets/enabled-moked-apis.png) + +3. After disabling API mocking, the Imported APIs look as shown below. It is a click away to mock the service back again. + +[![create mock api](/learn/assets/diable-moked-apis.png)](/learn/assets/diable-moked-apis.png) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/web-services/oauth-2-0-rest-services.md b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/oauth-2-0-rest-services.md new file mode 100644 index 000000000..2807ee622 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/oauth-2-0-rest-services.md @@ -0,0 +1,85 @@ +--- +title: "REST Services using OAuth 2.0" +id: "oauth-2-0-rest-services" +--- +--- + +**OAuth 2** is an authorization framework that enables applications to obtain limited access to user accounts on an HTTP service, such as Facebook, GitHub, etc.. OAuth 2 focuses on client developer simplicity by providing secured delegated access for web and desktop applications. It works by delegating user authentication to the service that hosts the user account and authorizing third-party applications to access the user account. + +## Device Flow + +The device flow is illustrated in the below image. + +[![](/learn/assets/instagram-design-flow.png)](/learn/assets/instagram-design-flow.png) + +### Device Flow Steps Explained + +1. The client requests the authorization server to give the access. The request includes the client identifier in it. +2. The authorization server provides a verification code, an end- user code, and the end-user verification URI. +3. The client instructs the end-user to use its user-agent (elsewhere) and visit the provided end-user verification URI. The client provides the end-user with the end-user code that is necessary to enter, in order to gain access. +4. The authorization server authenticates the end-user (via the user-agent) and prompts the end-user to grant the client's access request. If the end-user accepts the client's request, then the end-user enters the end-user code provided by the client. The authorization server validates this end-user code. +5. While the end-user authorizes (or denies) the client's request (D), the client continuously polls the authorization server to verify if the end-user authorization step is successfully accomplished. The client's request includes the verification code and its client identifier. +6. Assuming that the end-user has granted access, the authorization server validates the verification code provided by the client and eventually responds with the access token. + +### API Integration + +Configuring an app to use these Web Services can be an uphill task. WaveMaker abstracts OAuth and offers API integration without the need for writing code. + +WaveMaker integrates the OAuth 2.0 configuration while [importing a REST Service](/learn/assets/Web_Service1.png) by: + +- providing the  **URL** of  the  API to be invoked within the app, +- setting **HTTP Authentication** to OAuth 2.0, +- providing **OAuth Provider**, and +- completing the **Provider Configuration**. + +## WaveMaker Implementation + +You can [add a REST service](/learn/assets/Web_Service1.png) to your app from the Web Services Resource Explorer. In the Web Service dialog + +1. Enter the URL that you want to invoke. +2. Select OAuth ProviderSet **HTTP Authentication** to OAuth 2.0 + +[![](/learn/assets/rest_oauth.png)](/learn/assets/rest_oauth.png) + +## OAuth Configuration + +For OAuth configuration, you can do the following. + +WaveMaker provides support for most OAuth providers. [Select a provider](#supported-oauth-20-providers) from the list and add a provider. + +### OAuth Provider Configuration + +When you select an OAuth Provider, fill in the prompted details in the **OAuth Provider Configuration** dialog. + +[![](/learn/assets/rest_oauth_config.png)](/learn/assets/rest_oauth_config.png) + +- **Provider ID** is the OAuth 2.0 Service Provider, selected from the list or enter the name if you are adding your own. +- **Callback URL** is pre populated by WaveMaker and is not editable. You can copy this link and use it to as the callback URL in OAuth Provider app settings page. +- **Authorization URL** and **Access Token URL** of the OAuth service provider for obtaining the authorization and access to the service. These fields are auto-populated in case of the selected providers, else you need to enter them manually. +- Client Credentials issued once your app is registered with the Provider. It will be in the form of **Client ID** and **Client Secret**. +- **Send Access Token As** Header or Query. Usually, the OAuth providers need the access token to be sent as a part of Header, few might require it as a Query parameter. Check with your OAuth provider and select the appropriate option. It is set to Header by default. +- **Scope** defines what the access token can do and what resources it can access. For the listed Providers the popular Scopes are listed for you to select. Check with the selected OAuth 2 service provider to understand how to further configure this field. + +### Testing Configuration + +When you have configured the OAuth 2 Provider, **Test** the configuration to complete the Import process. While testing, you will be prompted to enter the login credentials. This is to obtain the Access Token details and to set the various configuration settings. + +[![](/learn/assets/rest_oauth_test.png)](/learn/assets/rest_oauth_test.png) + +- Set the Headers, Query Params and Path Parameters, as needed. +- You have the option to change the provider details and provider itself. +- From the [Project Settings](/learn/app-development/wavemaker-overview/product-walkthrough/#project-workspace) under [Profile Configuration](/learn/assets/configAccess.png) you can modify OAuth 2.0 configurations. These can be configured seperately for Deployment profile to be used while deploying the app. Remember to register the call back url provided therein with the oauth server. + +[![](/learn/assets/rest_oauth_prof.png)](/learn/assets/rest_oauth_prof.png) + +## Runtime Behavior + +- Just like any REST Service, you need to create a variable to access the OAuth APIs. See, [Variable Creation](var_sel.png). +- When the service is invoked through the variable, the user will be prompted to enter their credentials. + +## Supported OAuth 2.0 Providers + +WaveMaker provides few OAuth 2 service providers out of the box. When selected the provider details are pre-populated and need to be further configured. These providers include: + +
Developer Link
Developer Link
Developer Link
Developer Link
Developer Link
Developer Link
Developer Link
Developer Link
Developer Link
Developer Link
+ diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/web-services/rest-request-timeouts.md b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/rest-request-timeouts.md new file mode 100644 index 000000000..846c906a1 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/rest-request-timeouts.md @@ -0,0 +1,19 @@ +--- +title: "REST Request Timeouts" +id: "rest-request-timeouts" +--- +--- + +You can override REST properties for proxy REST calls configuration by sending these properties as system env/system property. Alternatively, you can also add them in the `app.properties` for proxy REST calls configuration. + +## Properties + +| Properties | Default Value | Description | +|---|---|---| +| **`app.rest.useSystemProperties`** | `false` | If set to true, uses the system properties like http.proxyHost, http.proxyPort, http.nonProxyHosts for making underlying http request for rest service api calls. | +| **`app.rest.connectionSocketTimeout`** | 360 | Maximum time to wait between two packets of data. It is mainly used for the first-byte response to come back for the request made. It throws a timeout exception if the time exceeds. | +| **`app.rest.connectionTimeout`** | 30| Maximum time to wait for the HTTP/HTTPS connection to be established with the target server. It throws a timeout exception if the time exceeds.| +| **`app.rest.maxTotalConnections`** | 100 | Maximum total connections in the pooling connection manager.| +| **`app.rest.maxConnectionsPerRoute`** | 50 | Maximum total connections per route in the pooling connection manager. +| **`app.rest.connectionRequestTimeout`** | 5 | Maximum time to acquire a connection from the pooling connection manager. It throws a timeout exception if the time exceeds. | +| **`app.rest.tlsVersions`** | TLSv1.3,TLSv1.2 | It allows configuring the TLS versions that the application will utilize for establishing secure connections while invoking REST APIs. TLSv1.3 abd TLSv1.2 are enabled by default. | diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/web-services/rest-services.md b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/rest-services.md new file mode 100644 index 000000000..6496ead0c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/rest-services.md @@ -0,0 +1,96 @@ +--- +title: "3rd Party REST Services" +id: "rest-services" +sidebar_label: "REST Services" +--- +--- + +While REST stands for Representational State Transfer, which is an architectural style for networked hypermedia applications, it is primarily used to build Web services that are lightweight, maintainable, and scalable. A service based on REST is called a RESTful service. REST is not dependent on any protocol, but almost every RESTful service uses HTTP as its underlying protocol. + +## Configuring API + +WaveMaker allows configuring the following fields while importing a REST Service: + +### Method +A method can be GET, POST, PUT, HEAD, PATCH, or DELETE. + +### Url +The service URL hosting the REST service. + +### Use Proxy + +#### Web Application +For Web Applications, while importing the service, Use Proxy flag can be turned off if you do not want to hit the service through the proxy server. + +:::note +while testing the REST API without proxy if a CORS related issue is observed, you will be notified of the same and you can proceed only by enabling proxy. +::: + +#### Mobile Application +For Mobile Applications, there is no option to configure proxy settings. By default, the request made to the target REST service will be a direct hit. However, while testing the service in the WaveMaker, a direct call is made. If a CORS failure is encountered, then the call is made through proxy behind the scenes and the service is imported with the proxy as true for WEB. In the mobile app, however, the call will be a direct one. + +### Authorization +**HTTP Authentication** can be set to +- None is the default setting +- Basic can be used for basic authentication using a User Name and Password +- OAuth 2.0 will allow you to integrate with an OAuth Provider. WaveMaker provides support for most OAuth providers. By selecting from the list, a semi-populated Configuration dialog is displayed. Complete the Configuration by giving the Client Id, Client Secret, etc. You can add a new provider too. +[Know more](/learn/app-development/services/web-services/oauth-2-0-rest-services/). + +### REST Configuration + +Usually, the publisher of a REST service provides information on the input and output of the REST service. You can use that information to configure the REST service definition. + +1. The `query parameters` will be set as per the requirement of the REST service within curly brackets eg ?`param = value` and multiple query params separated by `&`, in the below example the origin and destination; +2. The path param can be set by adding the parameter at the end of the URL within curly brackets ie `{path_param}`, and +3. The `header param` can be set by adding the appropriate details like the parameter name and type. + +:::note +These parameters can be seen as the `Input Fields` in the `data` section of the service variable when created and can be bound appropriately. +::: + +- **Response** format can be edited to suit your app needs. + +Following are the steps to import and use a REST web service within a WaveMaker app. + +## Test REST Service API + +1. From **Resources** choose **Web Services** and click the **"+"** button. [![](/learn/assets/Web_Service1.png)](/learn/assets/Web_Service1.png) +2. From the **Web Service** dialog, select **REST** icon. +3. **Test**. + +For testing, do the following: + +1. Enter the REST service URL, +2. Configure to set the HTTP Authentication and click **Test** to verify the response, proceed with the default setting of NONE. +3. Configure the Headers for the name and test value parameters for the same +4. Configure the query, path and header parameters etc. if needed. +5. Click **Import** to proceed. + +:::note +IMPORT button will be activated only on the success of the TEST. +::: + +[![](/learn/assets/rest_import.png)](/learn/assets/rest_import.png) + +## Configure REST Service + +1. The new service created can be accessed from the **Web Services** under `Rest Service` section. +2. Click on the service name listed under the `Web Service` section and the **Service Settings** are displayed. +3. You can make changes to the service settings. Once you make the changes, **Test** the changes before **saving** them. This is particularly helpful when the REST service has undergone any changes or when it needs additional input parameters. You can see the Response Format from the REST service in the JSON format as required by the platform. `Post ver 9.1 release`, you can make changes to the Authentication option, too. + +[![](/learn/assets/rest_settings.png?v=20)](/learn/assets/rest_settings.png?v=20) + +### REST Services with Input Data + +When importing REST Service which requires string or file as input, set the **Content Type** from Body tab to `multipart/form-data` to see the options for the Request Body parameters. The type of these parameters can be set to: + +- File for file or blob type data (Provision is there to upload a test file). +- Text for string type data. +- Text (text/plain) and JSON (application/json) for invoking WaveMaker generated internal REST APIs. + +[![](/learn/assets/rest_formdata.png?v=20)](/learn/assets/rest_formdata.png?v=20) + +## REST Service Usage + +To use the Service data within the app, you need to create a Variable. See, [Variable Access](/learn/assets/var_sel.png). In this article, we covered how to import and use a 3rd Party REST service in a WaveMaker app. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/web-services/web-services.md b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/web-services.md new file mode 100644 index 000000000..0ae0cef9a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/web-services.md @@ -0,0 +1,41 @@ +--- +title: "Web Services" +id: "web-services" +sidebar_label: "Web Services Overview" +--- +Introduction to web services in WaveMaker. Learn how to implement web services in this section. + +--- + +A Web service is a software system designed to support interoperable machine-to-machine interaction over a network. It has an interface described in a machine-processable format (specifically WSDL). Other systems interact with the Web service in a manner prescribed by its description using SOAP-messages, typically conveyed using HTTP with an XML serialization in conjunction with other Web-related standards. For more information, see [Web Services Glossary](https://www.w3.org/TR/2004/NOTE-ws-gloss-20040211/#webservice). + +WaveMaker makes it easy to integrate external web services within your app. You need to import and configure a web service and invoke the same using a variable which can be bound to a widget for data rendering. + +## Types of Web Services + +You can use the following types of web services: +- [REST Services](/learn/app-development/services/web-services/rest-services) +- [SOAP Services](/learn/app-development/services/web-services/working-with-soap-services) +- [WebSocket Services](/learn/app-development/services/web-services/working-with-websockets) + +[![](/learn/assets/web_types.png)](/learn/assets/web_types.png) + +### REST Services +A REST (Representational State Transfer) web service is composed of resources accessed through unique URLs (requests) and returned as XML or JSON responses. An XML Schema typically defines the structure of those XML responses. +### SOAP Services +SOAP (Simple Object Access Protocol) is a standard XML protocol for exposing and calling web services. A SOAP service is described by a Web Services Definition Language (WSDL) document, often available through a URL from the service itself. +### WebSocket Services +WebSockets represent the next evolution of web communications a full-duplex, bidirectional communications channel that operate through a single socket over the Web. It provides a true standard that you can use to build scalable, real-time web applications. It provides full-duplex communication channels over a single TCP connection. Its only relationship to HTTP is that its handshake is interpreted by HTTP servers as an Upgrade Request. + +## Invoke as Variable + +After importing a web-service, a **Variable** should be created for each method of the service. It triggers the service in the RUN mode of the app and stores the data returned by the service in its _dataSet_ property (_variableName.dataSet_). You can use this _dataSet_ as any other variable. + +While binding a widget with a variable’s _dataSet_, it is assumed that the binding chain follows JSON structure and there is no array on any of the nodes. Any deviations to this structure should be addressed from the markup manually. In some cases, modification with _dataSet_ may be required, which needs to be done at the variable level. + +For more information about about working with variables, see [Variables](/learn/app-development/variables/variables). And, see [How to create Variables for Web Service](/learn/app-development/variables/web-service/). + +[![](/learn/assets/Var_create.png)](/learn/assets/Var_create.png)[![](/learn/assets/soap_var.png)](/learn/assets/soap_var.png) + +WaveMaker supports various types of web services and these services can be invoked and results can be captured through Variables. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/web-services/web-services/working-with-soap-services.md b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/web-services/working-with-soap-services.md new file mode 100644 index 000000000..b502f6ff1 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/web-services/working-with-soap-services.md @@ -0,0 +1,182 @@ +--- +title: "Working with SOAP Services" +id: "working-with-soap-services" +--- + +SOAP (Simple Object Access Protocol) is a standard XML protocol for exposing and calling web services. A SOAP service is described by a Web Services Definition Language (WSDL) document, often available through a URL from the service itself. + +We will see how within a WaveMaker app: + +- SOAP Service can be [set up](#SOAP-service-setup), +- SOAP Service [settings](#SOAP-service-settings) can be configured, +- corresponding [REST APIs](#generated-rest-apis) are generated, and +- SOAP Service can be [accessed](#SOAP-service-usage). + +In order to import a SOAP service into your WaveMaker application, you need the WSDL (.wsdl) file that describes the service. You can see here for some [free web services](http://free-web-services.com/). + +Once you have located the WSDL file, follow these steps to import the same: + +## SOAP Service Setup + +1. From Resources, choose Web Service and click **+** [![](/learn/assets/Web_Service1.png)](/learn/assets/Web_Service1.png) +2. From the **Web Service** dialog, click the **SOAP** icon +3. Give the Soap Service details: + + 1. Provide the WSDL source in one of the following ways: + - **URL**: Toggle _WSDL Source_ to _URL_ and enter the URL of the WSDL, like: http://www.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL + - **File**: Toggle _WSDL Source_ to _File_ and click _Choose File_ to upload the .wsdl file from your local machine. _T_he file can be an individual file or a group of files packaged into a zip file. + 2. Advanced Settings include the optional items: + - option to import bindings (.xjb) file to map Java classes to XML representations. + - service name, if not entered it will be generated by the platform + - package name, if not entered it will be set to the project package + + See here for more on the [Import Settings](#import-settings). [![](/learn/assets/soap_import.png)](/learn/assets/soap_import.png) + +**Note:** Only Doc - Literal  and DOC-Encoded communication style models  are supported within WaveMaker + +## SOAP Service Settings + +1. Clicking **Import** will create a new service which is displayed under **Web Services**. +2. Select the service name listed under the SOAP _Service_ section and you can access the **WSDL File** and **Service Settings.** +3. You can choose to edit, save or delete the service. [![](/learn/assets/web_soap_service.png)](/learn/assets/web_soap_service.png) +4. The **HTTP Basic Auth settings** for the service can be configured by providing the _Username_ and _Password_. +5. **Connection Timeout** is a value specified in milliseconds used when opening a connection to a resource. If the timeout expires before the connection is established, then _java.net.SocketTimeoutException_ is thrown. The default value is 10000. Zero indicates infinite timeout value. +6. **Request Timeout** in milliseconds specifies the timeout when reading from an input stream after the connection is established to a resource. If the timeout expires before data is read, then _java.net.SocketTimeoutException_ is thrown. The default value is 10000. Zero indicates infinite timeout value. +7. You can view the WSDL code from the WSDL File tab. [![](/learn/assets/web_soap_wsdl.png)](/learn/assets/web_soap_wsdl.png) + +## Generated REST APIs + +For each method defined by the SOAP service, a REST API is generated. You can view the API definition, request and response formats and even test the same before using it within the app. You can achieve all this from the API Designer. + +[![](/learn/assets/web_soap_api.png)](/learn/assets/web_soap_api.png) + +## SOAP Service Usage + +To use the Service data within the app, you need to create Variable. [Variable Access](/learn/assets/var_sel.png) + +[![](/learn/assets/web_soap_var.png)](/learn/assets/web_soap_var.png) + +[![](/learn/assets/web_soap_data.png)](/learn/assets/web_soap_data.png)We have seen how SOAP service can be imported and used within a WaveMaker app. Learn more about Variables for the Web Services from [here](/learn/app-development/variables/web-service/). + +## Reimport of SOAP Service + +There might be a need when the SOAP Service you have been using has undergone some changes which you need to incorporate in your app. To cater for such situations, Re-import of SOAP Service has been introduced. [![](/learn/assets/soap_reimport.png)](/learn/assets/soap_reimport.png) Using this option, you can achieve the following: + +1. Change the WSDL Source +2. Remove the Bindings File, if provided +3. Upload a new Bindings File, if provided +4. Modify the Package Name +5. Download a previously uploaded WSDL File and Bindings File + +# SOAP Import Settings + +## Zip File import + +While importing the SOAP service you can upload the zip file that contains the WSDL file along with all its dependent schema files. The contents of the zip file should be: + +1. One WSDL at the root level folder. +2. Optional external dependent schema files at the same level or in child folders which are relatively referred in WSDL file. +3. Optionally xjb bindings file which helps in avoiding the model class collisions in code generating by separating the packages/altering the class names. Explained more in below sections. + +## Package Name Customization + +By default package name is set to the project base package name by the platform as <project-base-package-name>.services.<service-id-of-soap-being-imported>. You can provide an optional package name so that the generated sources will be created in that package. + +## Avoiding Name Collisions + +Name collisions happen while code generation when there is more than one schema definition with the same name that can be from two different external schema files. + +Following example depicts the collision of element “root”, because this element is defined twice in two different namespaces: + + + + + **** + + + + + + + + + + **** + + + + + + + + + +These collisions can be avoided either by implicit handling by the platform or manual handling using an xjb file. + +**Implicit handling of name collisions** + +In implicit handling, the system automatically resolves the bindings by providing the unique package name for each namespace, this package name is prefixed with service package name. However, there is a limitation in implicit handling that is it cannot handle the collisions that happen with definitions within (inline) the WSDL file. + +**Manual handling of name collisions** + +In manual handling, you have to write an _xjb_ file which defines the customization of packages/class names while code generation. This _xjb_ file can be included while importing the soap service using the following options (in the order of their priority): + +- Upload through the Bindings XML option from UI +- As a part of the uploaded zip file + +**Writing XJB files** + +XJB bindings can be customized by defining separate element for each namespace, which selects the node with given targetNamespace within the WSDL document. + + element should define which describes customization of package names/class names in code generation for selected node: + +1. Suffixing all the classes generated from the schema + ``` + + + + + + ``` +2. Changing the package name for generated classes from the schema + ``` + + + + ``` + +Example of custom xjb file +``` + + + + + + + + + + + + + + + + + +``` \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/web-services/working-with-feed-service.md b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/working-with-feed-service.md new file mode 100644 index 000000000..8f6e4af66 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/working-with-feed-service.md @@ -0,0 +1,36 @@ +--- +title: "Working with Feed service" +id: "working-with-feed-service" +--- + +A web feed is a document (often XML-based) whose discrete content items include web links to the source of the content. News websites and blogs are common sources for web feeds, but feeds are also used to deliver structured information ranging from weather data to top-ten lists of hit tunes to search results. The two main web feed formats are RSS and Atom. + +1. You can **import Feed Services** into your WaveMaker apps using the Import -> Web Services option. +2. Using the Feed service create a **generic Feed Service**. +3. Once a generic Feed service is imported a **Service Variable** has to be created using the getFeed operation to set the FeedUrl. +4. This Service Variable can then be bound to appropriate **widget** depending upon the response format of the service. + +# Importing Generic Feed Service + +You can import a feed service into your WaveMaker application by following these steps: + +1. From Main Menu, click Import Web Services [![Web_Service1](/learn/assets/Web_Service1.png)](/learn/assets/Web_Service1.png) +2. From the **Web Service** dialog, click the **Feed** icon. +3. Click **Import**. +4. A generic Feed Service is imported to your application and is displayed in the **Services** section of the **Files and  Services Panel** on the left under _Web Service_ section. + +# Service Variable for Generic Feed Service + +To use the Service data within the app, you need a Service Variable. + +1. From Main Menu, click **Create** and choose **Variables**. [![Var_create](/learn/assets/Var_create.png)](/learn/assets/Var_create.png) +2. In the **Variables** dialog, select _Service Variable_ and **ADD**; then select _FeedService_ as **Service** and _getFeed_ as the **Operation.** +3. Click the **Data** tab and set the _feedURL _the URL for your service. Configure other properties of the variable, if required. In this example, we are using the CNN Feed Service: http://rss.cnn.com/rss/edition.rss + +# Widget Binding to Display the Feed Response + +1. Drag and Drop a List onto the project canvas. +2. Use the Existing Variable option to select the Service Variable created in the previous step, and select the _entries_ node. +3. Select a Template and Pagination appropriately. We have selected Media List and Basic Pagination style. +4. Bind the fields appropriately. We have bound Name to the author, Time to updatedDate, and Description to description. From the canvas delete unwanted widgets, Picture in this case. +5. Run the app and see the content displayed. (Ensure that the Request Data on Page Load property is checked for the Service Variable) diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/web-services/working-with-soap-services.md b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/working-with-soap-services.md new file mode 100644 index 000000000..b98e589b9 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/working-with-soap-services.md @@ -0,0 +1,201 @@ +--- +title: "Working with SOAP Services" +id: "working-with-soap-services" +--- +--- + +SOAP (Simple Object Access Protocol) is a standard XML protocol for exposing and calling web services. A SOAP service is described by a Web Services Definition Language (WSDL) document, often available through a URL from the service itself. + +In order to import a SOAP service into your WaveMaker application, you need the `.wsdl` file that describes the service. You can see here for some [free web services](http://free-web-services.com/). + +Once you have located the WSDL file, follow these steps to import the same: + +## SOAP Service Setup + +1. From Resources, choose Web Service and click **+** + +[![](/learn/assets/Web_Service1.png)](/learn/assets/Web_Service1.png) + +2. From the **Web Service** dialog, click the **SOAP** icon +3. Give the Soap Service details. +4. Provide the WSDL source in one of the following ways: + - **URL**: Toggle `WSDL Source` to `URL` and enter the URL of the WSDL, for example: + `http://www.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL` + - **File**: Toggle `WSDL Source` to `File` and click `Choose File` to upload the `.wsdl` file from your local machine. The file can be an individual file or a group of files packaged into a zip file. +5. Advanced Settings include the optional items: + - option to import bindings `.xjb` file to map Java classes to XML representations. + - service name, if not entered it will be generated by the platform + - package name, if not entered it will be set to the project package + +See here for more on the [Import Settings](#import-settings). + +[![](/learn/assets/soap_import.png)](/learn/assets/soap_import.png) + +:::note +Only Doc - Literal  and DOC-Encoded communication style models  are supported within WaveMaker. +::: + +## SOAP Service Settings + +1. Clicking **Import** will create a new service which is displayed under **Web Services**. +2. Select the service name listed under the SOAP Service section and you can access the **WSDL File** and **Service Settings.** +3. You can choose to edit, save or delete the service. + +[![](/learn/assets/web_soap_service.png)](/learn/assets/web_soap_service.png) + +4. The **HTTP Basic Auth settings** for the service can be configured by providing the `Username` and `Password`. +5. **Connection Timeout** is a value specified in milliseconds used when opening a connection to a resource. If the timeout expires before the connection is established, then `java.net.SocketTimeoutException` is thrown. The default value is 10000. Zero indicates infinite timeout value. +6. **Request Timeout** in milliseconds specifies the timeout when reading from an input stream after the connection is established to a resource. If the timeout expires before data is read, then `java.net.SocketTimeoutException` is thrown. The default value is 10000. Zero indicates infinite timeout value. +7. You can view the WSDL code from the `WSDL File` tab. + +[![](/learn/assets/web_soap_wsdl.png)](/learn/assets/web_soap_wsdl.png) + +## Generated REST APIs + +For each method defined by the SOAP service, a REST API is generated. You can view the API definition, request and response formats and even test the same before using it within the app. You can achieve all this from the API Designer. + +[![](/learn/assets/web_soap_api.png)](/learn/assets/web_soap_api.png) + +## SOAP Service Usage + +To use the Service data within the app, you need to create Variable. + +[![](/learn/assets/web_soap_var.png)](/learn/assets/web_soap_var.png) + +[![](/learn/assets/web_soap_data.png)](/learn/assets/web_soap_data.png) + +We have seen how SOAP service can be imported and used within a WaveMaker app. Learn more about Variables for the Web Services from [here](/learn/app-development/variables/web-service/). + +## Reimport of SOAP Service + +There might be a need when the SOAP Service you have been using has undergone some changes which you need to incorporate in your app. To cater for such situations, Re-import of SOAP Service has been introduced. + +[![](/learn/assets/soap_reimport.png)](/learn/assets/soap_reimport.png) + +Using this option, you can achieve the following: + +1. Change the WSDL Source +2. Remove the Bindings File, if provided +3. Upload a new Bindings File, if provided +4. Modify the Package Name +5. Download a previously uploaded WSDL File and Bindings File + +## SOAP Import Settings + +### Zip File import + +While importing the SOAP service you can upload the zip file that contains the WSDL file along with all its dependent schema files. The contents of the zip file should be: + +1. One WSDL at the root level folder. +2. Optional external dependent schema files at the same level or in child folders which are relatively referred in WSDL file. +3. Optionally xjb bindings file which helps in avoiding the model class collisions in code generating by separating the packages/altering the class names. Explained more in below sections. + +### Package Name Customization + +By default package name is set to the project base package name by the platform as `.services.`. You can provide an optional package name so that the generated sources will be created in that package. + +## Avoiding Name Collisions + +Name collisions happen while code generation when there is more than one schema definition with the same name that can be from two different external schema files. + +Following example depicts the collision of element “root”, because this element is defined twice in two different namespaces: + +``` + + + + **** + + + + + + + + + + **** + + + + + + + + +``` + +These collisions can be avoided either by implicit handling by the platform or manual handling using an `xjb` file. + +### Implicit handling of name collisions + +In implicit handling, the system automatically resolves the bindings by providing the unique package name for each namespace, this package name is prefixed with service package name. However, there is a limitation in implicit handling that is it cannot handle the collisions that happen with definitions within (inline) the `WSDL` file. + +### Manual handling of name collisions + +In manual handling, you have to write an `xjb` file which defines the customization of packages/class names while code generation. This `xjb` file can be included while importing the soap service using the following options (in the order of their priority): + +- Upload through the Bindings XML option from UI +- As a part of the uploaded zip file + +### Writing XJB files + +XJB bindings can be customized by defining separate `` element for each namespace, which selects the node with given targetNamespace within the WSDL document. + +``` +``` element should define which describes customization of package names/class names in code generation for selected node: + +1. Suffixing all the classes generated from the schema + ``` + + + + + + ``` +2. Changing the package name for generated classes from the schema + ``` + + + + ``` + +#### Example + +Custom `xjb` file + +``` + + + + + + + + + + + + + + + + + +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/services/web-services/working-with-websockets.md b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/working-with-websockets.md new file mode 100644 index 000000000..d51061766 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/services/web-services/working-with-websockets.md @@ -0,0 +1,53 @@ +--- +title: "Working with WebSockets" +id: "working-with-websockets" +--- +--- + +WebSockets represent the next evolution of web communications a full-duplex, bidirectional communications channel that operate through a single socket over the Web. It provides a true standard that you can use to build scalable, real-time web applications. It provides full-duplex communication channels over a single TCP connection. Its only relationship to HTTP is that its handshake is interpreted by HTTP servers as an Upgrade Request. + +With WaveMaker you can integrate any third-party WebSocket Service into your app and build real-time apps. Just like a REST service, you can import a **WebSocket Service** and create a **Variable** to communicate with the service. The data received from the service at the client is held by the Variable, which can be further used to bind to Widgets like Charts, Data Table, Lists, etc and have them reflect data in real-time. + +## Data Handling +Data returned from the WebSocket Service can be handled in three different ways: + +### As data snapshot +By choosing to `refresh` the WebSocket service variable, you will be dealing with the latest data returned by the service. This option can be used when you want to deal the latest information. + +### Append data +By choosing to `add as last record`, you can append the data to the variable dataset. In such cases for performance and UI optimization, it is advisable to set a `limit` on the size of the data held by the variable. This option can be used when displaying tracking information in a chart format like stock performance, heart rate monitor graph, and more. + +### Prepend data +By choosing to `add as first record`, you can prepend the data to the variable dataset. In such cases for performance and UI optimization, it is advisable to set a `limit` on the size of the data held by the variable. This option can be used when displaying the data in a list or data table format, with the latest entry on the top of the list, like match scores or weather reports. + +## Importing a WebSocket Service + +Just like any web service, a WebSocket service can be imported into a WaveMaker app. + +[![](/learn/assets/Web_Service1.png)](/learn/assets/Web_Service1.png) + +1. Provide the WebSocket service URL, test the connection and import the service. +2. To leverage the full power of the platform, you should provide the sample request and response body while configuring the service. This helps the platform to generate request and response type metadata for the service, which can be utilized while binding the input to the corresponding Variable and the output of the Variable to a widget. + + [![](/learn/assets/socket_response.png)](/learn/assets/socket_response.png) + +3. WebSocket Service can be further configured by specifying the Query, Path, and Body Parameters as per the app requirements. +4. The newly created service will be visible under the Web Service +5. Select the service name listed under WebSocket Service to access the Service Settings. + + [![](/learn/assets/socket_settings.png)](/learn/assets/socket_settings.png) + +## Limitation + +Since WMO is hosted on https, a WebSocket service on `ws://` protocol cannot be tested because of security limitations on browsers. To cater this, the platform detects if the URL entered by the user is on `ws://` protocol and throws a warning to the user with a message. At this point the TEST button is disabled. You can still proceed, however, by checking the Proceed without Test option. You can check this flag, provide sample Request Body and Sample Response and proceed to config screen without testing. + +:::note +It is not recommended to use `ws://` URL as it may not work. Best practice is to use `wss://` URLs only. +::: + +## WebSocket Data Consumption + +To use the WebSocket Service within your app, you need to create a Variable. This is the interface for the app developer to interact with a WebSocket Service imported into a WaveMaker app. The Variable has methods to interact with the target service like opening and closing the connection, sending and receiving messages to and from the server. It also holds the data to be sent to the service and the data received from the service. + +[Click here to know more](/learn/app-development/variables/websocket-variable/). + diff --git a/website/versioned_docs/version-v11.8.5/app-development/sspa/micro-frontend.md b/website/versioned_docs/version-v11.8.5/app-development/sspa/micro-frontend.md new file mode 100644 index 000000000..76277531f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/sspa/micro-frontend.md @@ -0,0 +1,166 @@ +--- +title: "WaveMaker App as Micro Frontend Module" +id: "micro-frontend" +sidebar_label: "Micro Frontend App" +--- +--- + +[WaveMaker](https://www.wavemakeronline.com/) is a low-code platform enabling users to develop high-quality apps swiftly. Micro Frontends is a design practice that enables users to scale their development and produce composable independent modules that can serve in building a new app or progressively integrating features into an existing app. + +To support our customers' phased modernization methods, we wanted to build support for this cutting-edge design pattern in the microservices world. + +WaveMaker is the only low-code platform to support Micro Frontend modules extending low-code benefits to Micro Frontend development. It adopts the runtime integration approach for Micro Frontends and works with the **Single-spa** framework. + +[Single-spa](https://single-spa.js.org/) is a JavaScript framework for frontend microservices, supporting multiple framework modules. Compatible artifacts must be generated and integrated for any app to work with **Single-spa**. + +:::note +Read our developer's blog about how [Micro Frontend modules work and how it fits](/learn/blog/2020/02/25/wavemaker-micro-front-end-support) in your low-code development approach. +::: + +## WaveMaker Single SPA Framework + +WaveMaker has developed a node-based CLI to generate **Single-spa** compatible artifacts for a WaveMaker app. + +The CLI requires the exported project location and deployed URL as its input. The CLI and details are available in the link below. + +:::note +#### [**@wavemaker/wm-sspa-cli**](https://www.npmjs.com/package/@wavemaker/wm-sspa-cli) +::: + +[![screenshot](/learn/assets/wm-sspa-cli.png)](/learn/assets/wm-sspa-cli.png) + +## Generate Single-spa Artifact + +Follow the steps below to generate the **Single-spa** artifacts for a WaveMaker application. + +1. Ensure the node >=v12.22.x is installed on the machine. +2. Login to **[WaveMaker](https://www.wavemakeronline.com/)** and develop a project. +3. Deploy the project, and note the deployed URL. +3. Export the project from WaveMaker as a Zip, extract it into a folder, and note the location. + +## Invoke CLI + +1. Open the terminal and invoke CLI using the command below. + +```js + npx @wavemaker/wm-sspa-cli + ``` + +2. npx downloads CLI and prompts for the location of the WaveMaker project, deployed URL, and SSPA deployed URL. + +3. Alternatively, you can provide the location of the project, deployed URL, and SSPA deployed URL as parameters. + +```js + npx @wavemaker/wm-sspa-cli -p -d -s +``` + +:::note +- The usage of npx ensures execution of the latest version of CLI. +- The CLI validates the input before triggering the process. +::: + +4. Once the valid parameters are provided, the CLI generates **Single-spa** compatible artifacts and their location. + + +### Additional Parameters + +WaveMaker SSPA CLI provides additional optional parameters for more detailed artifact customization. The following shows how parameters can be passed to the CLI command besides the above-specified commands. + +```js + npx @wavemaker/wm-sspa-cli -p -d -s -l -c -m -r +``` + +#### Library Target + +`-l umd` or `-l system` + +Parameter helps build the library with a specified module format. By default, it considers the **umd** format when generating artifacts. WaveMaker SSPA CLI supports **umd** and **system** formats. + +#### Split Styles + +`-c true` or `-c false` + +When you set this parameter to `true`, it will generate **Base**, **Theme** and **App styles** separately (styles, wm-theme-styles, wm-app-styles respectively). By default, it is set to `false`. + +#### Mount Styles + +`-m true` or `-m false` + +If you want to handle the mounting or unmounting of styles on your own, then set this parameter to `false`. By default, it is set to `true`. + +#### Resource Hashing + +`-r true` or `-r false` + +If this parameter is set to `true`, it will enable hashing for **JS** and **CSS** files in the generated artifacts. By default, it is set to `false`. + +## Generated Artifacts + +The artifacts generated include: + +- **main-es2015.js** : the application code and need to be used for app registration. +- **scripts.js**: the global scripts modules required for the WaveMaker app. + +:::note +**Single-spa** needs the deployed location of all the artifacts, so ensure the files are hosted. +::: + +1. Once the artifacts are generated, you can use the artifacts to register it as an application in the **Single-spa** shell. +2. Validate the changes using the [**Single-spa shell project**](https://github.com/joeldenning/coexisting-angular-microfrontends). + +## Configure Script + +1. Once the project is downloaded, open the `index.html` in the folder *[folder-location]/root-html-file* + +2. Include the script below in the head section of the `index.html`. + +```html + + +``` + +3. Update one of the app target URLs in import maps as highlighted below in `index.html`. + +```html + +``` +:::note +If resource hashing (-r) is enabled, replace the file names with generated hash code. It applies after the sspa build as shown in the example below: + +**Example in #2**: `` +**Example in #3**: `"app2": "[ARTIFACTS_DEPLOYED_URL]/main-es2015.[HASH].js"` +::: + +4. Add a `.wm-app` class to the parent element of the route in `index.html`. + +```html + +``` + +Once the changes are done in `index.html`, follow the instructions in the `README.md` of the [**Single-spa shell project link**](https://github.com/joeldenning/coexisting-angular-microfrontends) to start. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/accessibility.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/accessibility.md new file mode 100644 index 000000000..ed9b3d6cc --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/accessibility.md @@ -0,0 +1,146 @@ +--- +title: "Accessibility Support in WaveMaker" +id: "accessibility" +sidebar_label: "Accessibility" +--- +--- + +Accessibility is essential for individuals and organizations that want to create high-quality websites and applications. It enables people with disabilities to use different Assistive Technologies (AT) and Adaptive Strategies for the business benefits of Web Accessibility. WaveMaker also focuses on enabling their product with international standards for Web Accessibility from World Wide Web Consortium (W3C), including Web Content Accessibility Guidelines (WCAG) and Web Accessibility Initiative - Accessible Rich Internet Applications (WAI-ARIA) as the first step in applying them. + +:::note +For more information, see the blog post about [Accessibility in WaveMaker](/learn/blog/2021/08/23/accessibility-feature). +::: + +## How it Works + +To make components accessible, all the text on the web page must be unique, along with its captions and roles. To make it possible, we have introduced **aria-labels** attributes for all the `wm-widgets` which are configurable and certain [Role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles) to identify every component as per their standard behavior. This ARIA "roles" and "attributes" will benefit the group of people using Assistive Technology Readers (ATR) to read the text and the purpose of the widget aloud to the users. + +WaveMaker Accessibility enhancements will cover Web Content Accessibility Guidelines (WCAG) "A" and "AA" compliance for all non-text content, including the following. + +Name Role & Value, Info & Relationships, Meaning Sequence, Sensory Characteristics, Identify Input Purpose, Non-Text Contrast, Page Titled, Headings and Labels, Label in Name, Language of Page, Status Messages, Error Prevention. + + + +### Steps to Follow + +#### Labels + +- On every drag and drop of a widget, check for the Accessibility section. +- Copy or Bind the captions of the label widgets to the **Hint** property from the properties tab below the Accessibility section. + +![Accessibility Section](/learn/assets/accessibility-section.png) + +:::note +All labels and texts will have a default hint value specified as "Label text", which you can edit. +::: + +- Manipulating the *Hint* will result in a "tooltip text" on-hover and "**aria-label**" attribute visible in the browser preview URL that only AT screen readers can understand. +- The "**aria-label**" attribute will be added to all widgets wherever text is bound from the **Hint** property. + +#### Images + +- Add proper description for the images used on a page under the **Hint** parameter. +- Modifying *hint* property with meaningful caption will add **aria-label** to make it accessible. + + +Other widgets are taken care of to make them accessible easier and faster with "aria-labels" like, **Page layouts**, **Dialogs**, **Form Fields**, **Anchors**, and **Live Forms**, etc. + + + +--- + +### Predefined ARIA Attributes + + +| Components | Aria Labels | Role | +| --- | --- | --- | +| App logo | aria-label="Image" | | +| Header | aria-label="Page header" | banner | +| Page | aria-label="Main page content" | | +| Mobile Navbar | aria-label="Title" | link | +| Mobile Tabbar | aria-label="Home" | link | +| Heading | aria-label="Label text" | heading | +| | aria-level="1" | | +| Login Input | aria-label="Text field" | | +| Login button | aria-label="Login" | | +| Validation Errors | aria-label="error message" | alert | +| | aria-hidden="true" | | +| | aria-live="polite" | | +| Anchors | aria-label="Link" | | +| Button | aria-label="Button" | | +| Checkbox | aria-label="Checkbox" | checkbox | +| | aria-checked="false" | | +| Toggle switch | aria-label="Toggle" | | +| | aria-checked="false" | | +| Rating | aria-label="1 out of 5 ratings" | radio | +| | aria-checked="true" | | +| | aria-multiselectable="true" | | +| Currency | aria-label="country currency" | | +| Datetime | aria-label="Date and time field" | | +| Time input | aria-label="Time field" | timer | +| | aria-atomic="true" | | +| Pagination | aria-label="Page 1" | | +| Calendar View | aria-label="Month view" | | +| Search input | aria-label="search field" | | +| Slider | aria-label="slider" | slider | +| | aria-orientation="Vertical/horizontal" | | +| Selectbox | aria-label="Select options" | listbox | +| | aria-expanded="false" | | +| | aria-hashpop="true" | | +| Selectbox options | | option | +| Accordion tabs | aria-expanded="true/false" | tab | +| List | | list, listitem | +| Datatable | | table | +| Panel | aria-label="panel" | | +| | aria-label="panel-header" | | +| | aria-label="panel-content" | | +| | aria-label="panel-footer" | | +| Charts | aria-label="pie chart" | | +| Left panel | aria-label="Left navigation" | navigation | +| Right panel | aria-label="Right navigation" | complementary | +| Top nav | aria-label="Second level navigation" | navigation | +| Footer | aria-label="Page footer" | contentinfo | +| Partials | | complementary | +| Spinner | aria-label="Loading..." | alert | +| | aria-live="assertive | | +| | aria-busy="true" | | +| Picture | aria-label="Placeholder Image" | | +| Icon | aria-label="user icon" | | +| Popover | aria-label="user icon" | menubar | +| Dialog | aria-modal="true" | dialog | +| Audio | | application | + + + + +### Appropriate Use of Headings + +To make good use of headings on a page, add CSS class name from the **Style** properties tab, for example .h1, .h2, .h3, etc. Using any of the above headings class name, an attribute **"aria-level"** will be assigned to the HTML structure to make the screen readers understand the text specificity while scanning a page. You can copy the heading caption to the *hint* property to make it ARIA accessible. + + +:::note +Classname with .h1 will set the *aria-level="1"*, and .h2 will set *aria-level="2"* attribute following the rest. +::: + + +### Keyboard Navigation + +To navigate well within a form, use the **Tab Index** property from the *Properties* tab. + +![Tab Index property](/learn/assets/tab-index-property.png) + +:::warning +For form inputs in a live form, the *hint* text will not only add an **aria-label** attribute but also a *Help Text* below the input field. +::: + + + +### Good Practices + +Effective use of color contrast is also an important aspect of making your app accessible. + +- WCAG 2.0 level "AA" requires a contrast ratio of at least **4.5:1** for normal text and **3:1** for large text. +- WCAG 2.1 requires a contrast ratio of at least **3:1** for graphics and user interface components (such as form input borders). +- WCAG Level "AAA" requires a contrast ratio of at least **7:1** for normal text and **4.5:1** for large text. [ + +For more information about the color contrast ratio before designing or developing any application, see [Contrast Checker](https://webaim.org/resources/contrastchecker/). diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/creating-themes.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/creating-themes.md new file mode 100644 index 000000000..83e3969e1 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/creating-themes.md @@ -0,0 +1,248 @@ +--- +title: "Creating Themes using the Manual Setup" +id: "creating-themes" +sidebar_label: "Manual Theme" +--- +--- + +Themes are used to apply a style to the entire application. WaveMaker app (web, and mobile) themes are based on the BootStrap CSS markup and it requires you to know HTML, CSS, LESS, and Grunt. + +### Styling Elements + +Mainly, themes contain the following styling for all the elements on a page. + +1. **Color**: Background, text color, border color, hover/active/focus colors, and more. +2. **Properties**: For text like text-align, text-decoration, font-size, font-weight, and more. +3. **Layout**: Includes margin, padding, border-radius, and more. + +:::tip +You can also develop themes instantly without needing to code; you can do this by using WaveMaker theme builder. For more information, see the [Theme Builder Editor Tool](/learn/app-development/ui-design/theme-builder). +::: + +## Using the Manual Setup + +In this document, see how to develop themes in WaveMaker using the manual approach which requires you to install the whole setup into the local environment. + +### Prerequisites + +Before creating a theme, make sure you have installed the following on your machine: + +- [Nodejs](https://nodejs.org/) +- [GIT](https://www.git-scm.com/) + +### Setup + +1. Open GIT Bash prompt +2. Install **grunt** using the following command + + ```shell + npm install -g grunt-cli + ``` + + For more information, see [Grunt](https://gruntjs.com/getting-started). + +3. Install **bower** using the following command: + + ```shell + npm install -g bower + ``` + + For more information on bower, see [click here](https://www.npmjs.com/package/bower). + +4. Setup the **WaveMaker Theme repository**. + + - For Git clone, see [Grunt WaveMaker Theme](https://github.com/wavemaker/grunt-wavemaker-theme.git). + + ```shell + cd grunt-wavemaker-theme + ``` + + ```shell + npm install + ``` + + Follow the instructions given at the [Git repository](https://github.com/wavemaker/grunt-wavemaker-theme). + +5. After setting up the repository, under the **src** folder you will find the following files that can be modified as per your needs. + + [![theme-web](/learn/assets/theme-web.png)](/learn/assets/theme-web.png) + +:::note +Themes for Web and Mobile (Android/iOS) apps are different, use the appropriate theme source file to generate the theme bundle. +::: + +## Theme Package Structure + +### Directory Structure + +1. **`Fonts`** folder: The web fonts can be copied here and referenced in the theme. There will be references to Roboto regular fonts in the variables.less (src/web), to avail them please download Roboto regular fonts and paste them in fonts directory (src/web/fonts). +2. **`.wmprojects.properties`**: This contains essential properties required to identify the theme. + + **`.wmprojects.properties`** + - **`name:`** for the theme, + - **`version`**: of the theme. Updated version will be used to replace the existing theme in the project. + - **`description`**: a short meaningful `description` of the theme, + - **`type:`** THEME (DO NOT CHANGE THIS), and + - **`author`**: name of the author for the theme. + +3. **`theme.png`**: Used to visually identify the Theme in the Theme dialog. The size of the image should be 160 x 120 px. +4. **`style.less`**: This less file includes styles for components like header, footer, leftnav, calendar etc., which are not defined in the bootstrap CSS. These components can be further customized in this file by using the variables defined at the beginning of the file eg header background color can be changed using the @wm-header-bg-color variable. +5. **`variables.less`**: This less file includes the styles defined by bootstrap. The values defined in this file are used by widgets like buttons, links, textbox, and more. For more information, see [Bootstrap documentation](http://getbootstrap.com/customize/) on LESS variables. + +### Web Responsive + +For creating a custom theme for a WaveMaker application, you need to understand the package structure. The theme package contains the following files: + +| Name | Description | | +| --- | --- | --- | +| Fonts | Folder containing web-based fonts used in the app. | Required | +| .wmproject.properties | Containing essential properties required to identify the theme which includes the name of the theme, version of the theme, a short meaningful description of the theme, the type should be THEME (DO NOT CHANGE THIS), and the name of the author for the theme. | Required | +| style.css | Containing styles related to the theme. | Required | +| theme.png | Theme icon. | Required | +| variables.less | LESS variables to define colors, sizes and more. | Required | + +### Hybrid Mobile + +In a hybrid app mobile theme, there can be different flavors for android and ios systems. Hence, in a theme bundle, there are different folders for android and ios. + +Following is the package structure: + +| Sub-Folder | Name | Description | | +| --- | --- | --- | --- | +| none | .wmproject.properties | Containing essential properties required to identify the theme which includes the name of the theme, version of the theme, a short meaningful description of the theme, the type should be THEME (DO NOT CHANGE THIS), and the name of the author for the theme. | Required | +| none | theme.png | Theme icon. | Required | +| Android | Fonts | Folder containing web-based fonts used in the app. | Required | +| | style.css | Containing styles related to the theme. | Required | +| | variables.less | LESS variables to define colors, sizes and more. | Required | +| ios | Fonts | Folder containing web-based fonts used in the app. | Required | +| | style.css | Containing styles related to the theme. | Required | +| | variables.less | Less variables to define colors, sizes and more. | Required | + +## Creating Theme for Web Apps + +Follow the steps below for creating a theme for a web app. + +1. After setting up the theme repository, navigate to the **web** folder. +2. Open `style.less` and `variables.less` in the editor of your choice. +3. To use the **web fonts** in the theme, copy the web fonts (.ttf,.eot, .woff) in the font folder and include the font definition in `variables.less`. + + ```css + @font-face { + font-family: 'robotoregular'; + src: url('fonts/Roboto-Regular-webfont.eot'); + src: url('fonts/Roboto-Regular-webfont.eot?#iefix') format('embedded-opentype'), + url('fonts/Roboto-Regular-webfont.woff') format('woff'), + url('fonts/Roboto-Regular-webfont.ttf') format('truetype'), + url('fonts/Roboto-Regular-webfont.svg#robotoregular') format('svg'); + } + ``` + +4. The `variables.less` contain variables which are used while building the bootstrap CSS.  For example, `@brand-primary` value change will affect all the styles using this specific property value. For more information on variables, see [Bootstrap customization](http://getbootstrap.com/customize/). + + ```css + //## Gray and brand colors for use across Bootstrap. + @brand-primary: #551C2B; + @brand-success: #088362; + ``` + + For more information, see [Styling App Components](/learn/how-tos/customizing-theme/). + +5. Replace the `theme.png` with your image in the web folder. +6. Update the `.wm-properties` to [provide theme information](#directory-structure). +7. [Build the theme](#build-theme). +8. The theme will be saved under `grunt-wavemaker-theme/dist` as **`web.zip`**. +9. [Import](/learn/app-development/ui-design/themes/#import-theme) and [Apply](/learn/app-development/ui-design/themes/#apply-theme) the Theme to your app. + +## Creating Theme for Web Apps - Bootswatch + +Bootswatch provides bootstrap themes that can be integrated into your WaveMaker web apps. The [prerequisites](#prerequisites) and [setup](#setup) for building the WaveMaker theme are the same as above. + +1. Select a theme from [Bootswatch](https://bootswatch.com/3/). +2. Download the `variables.less` and `bootswatch.less` files for the selected theme. +3. After [setting up theme repository](#using-the-manual-setup), navigate to the **bootswatch** folder. +4. Copy `bootswatch.less` and `variables`.less files to  `grunt-wavemaker-theme/src/bootswatch` folder. + +[![bootswatch_folder](/learn/assets/bootswatch_folder.png)](/learn/assets/bootswatch_folder.png) + +:::note +The variable files downloaded from bootswatch will fail if placed in any other theme folders like mobile or web. +::: + +5. You can further customize the theme in `style.less` specific to the header, footer, leftnav, etc. [See here for details](#creating-theme-for-web-apps). +6. Replace the `theme.png` with your image in the bootswatch folder. +7. Update the `.wm-properties` to [provide theme information](#directory-structure). +8. [Build the theme](#build-theme). +9. The theme will be saved under `grunt-wavemaker-theme/dist` as **`bootswatch.zip`** +10. [Import](/learn/app-development/ui-design/themes/#import-theme) and [Apply](/learn/app-development/ui-design/themes/#apply-theme) the Theme to your app. + +## Creating Theme for Mobile Apps + +Mobile Apps come in two flavors - Android and iOS. The theme renders differently on these platforms and as such the theme needs to be packaged differently. + +For example, below is the rendering of a Live Form within the List. + +### For Android + +[![theme-diff-android](/learn/assets/theme-diff-android.png)](/learn/assets/theme-diff-android.png) + +### For iOS + +[![theme-diff-ios](/learn/assets/theme-diff-ios.png)](/learn/assets/theme-diff-ios.png) + +As mentioned earlier in the [setup structure](#using-the-manual-setup), WaveMaker provides two folders for Mobile Themes - Android and iOS. The structure is a replica of that for Web with the content tailored for the specific platform. When building a theme for Mobile Apps, make sure that you use the appropriate files and make the same changes to both sets. DO NOT replicate the files, make changes only where needed. + +## Build Theme + +Once you have incorporated all your changes to the Theme files, you'll need to build it. + +1. From the command prompt, build the themes using the following commands: + + ```shell + cd grunt-wavemaker-theme + grunt themes + ``` + +2. A **`zip file`** `(web.zip/mobile.zip/bootswatch.zip)` for the theme will get generated in the **`grunt-wavemaker-theme/dist`** folder. +3. You can [import the theme](/learn/app-development/ui-design/themes/#import-theme) and [apply](/learn/app-development/ui-design/themes/#apply-theme) it to your application. + +## Testing the Theme + +You can test the custom theme, before import, by copying the `style.css` file directly into your app. From the left `Developer Utilities`, open `File Explorer` and you will find the `style.css` file under **`webapps -> current theme folder`**. Save and run the app. + +:::note +These changes are temporary, for the permanent change, you have to [import](/learn/app-development/ui-design/themes/#import-theme) the Theme. +::: + +:::warning +If you make changes to the default theme `style.css` file, and if you do not import it as your custom theme, updating the theme will erase those changes. +::: + +[![](/learn/assets/theme-css-folder.png)](/learn/assets/theme-css-folder.png) + +## Publishing the Theme + +:::important +Applies for Enterprise Version from [10.0 release](/learn/wavemaker-release-notes/v10-0-ga). +::: + +In order to make a custom theme available to developers across the enterprise, it needs to be published. Follow the steps below to publish a Theme. + +1. Once you have created a custom theme, import and test it in your application. +2. From the **Project Configurations**, under **Export** select the **Theme to EDN** option. + ![publish theme](/learn/assets/Theme_publish.png) +3. The theme publishing wizard with three steps will display as below. + + - **Information** regarding the **Category**, **Version**, **Description** and **Change Log**. + - **Configuration** allows you to add **Tags** for search and tracking purposes and also includes the **Metadata** populated automatically. + - **Summary** for a review before Publishing. + + [![theme publish dialog](/learn/assets/Theme_publish_dialog.png)](/learn/assets/Theme_publish_dialog.png) + +4. Note that the current Theme applied to the application will be selected for Publishing. +5. Once the EDN Admin approves the Theme, the same will be available in the Artifacts listing in the **Themes** dialog for other developers to select and apply. + +## See Also + +[Apply and Import Theme](/learn/app-development/ui-design/themes/) +[Customize an Existing Theme](/learn/how-tos/customize-existing-theme/) +[How to Customize Themes](/learn/how-tos/customizing-theme/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/design-overview.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/design-overview.md new file mode 100644 index 000000000..47050bfe9 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/design-overview.md @@ -0,0 +1,46 @@ +--- +title: Page Elements +id: "design-overview" +sidebar_label: "Design Elements" +--- +Learn how to design and navigate across pages and use rich themes to your WaveMaker apps. + +--- + +In this section, you wil learn about page components and how you can customize it. You can choose a **Page Layout** for a composition of Widgets or UI Elements. + +[![UI_design](/learn/assets/UI_design.png)](/learn/assets/UI_design.png) + +## Page Structure + +A page is divided automatically into different areas, with the content of all areas except the main area, repeated across all pages of the app. This helps achieve UI consistency throughout the app, easily. + +[![Page_responsive](/learn/assets/Page_responsive.png)](/learn/assets/Page_responsive.png) + +### Responsiveness +WaveMaker supports responsive design, i.e. the apps are rendered automatically based upon the device they are viewed on. + +### Grid Layout +The responsiveness of apps is achieved using the 12-column grid layout defined by bootstrap. For more information, see [Grid Layout](/learn/app-development/widgets/container/grid-layout/). + +[![Page_grid](/learn/assets/Page_grid.png)](/learn/assets/Page_grid.png) + +### Dragging-and-dropping of UI Components + +Widgets are the building block for any application. WaveMaker Pages are built using the drag-n-drop approach by placing widgets in the corresponding responsive layout grids.  Widgets enable users to interact with the App and can get their data (binding) from backend Services. + +They can be dropped into the Grids or Containers, making UI well-aligned and ready for consumption. + +### Page Layout +Based on the Page construction system WaveMaker provides different options for Page Layouts, which can be picked based on the interaction required for the app. Depending upon the app platform the layout will differ. + +Page Layout can be set a default one at the time of [Page Creation](./page-creation.md) and later can be changed from the Workspace Toolbar. + +For more information, see [Page Layouts](/learn/app-development/ui-design/page-concepts/page-layouts) + + + + + + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/designing-app.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/designing-app.md new file mode 100644 index 000000000..219bf0150 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/designing-app.md @@ -0,0 +1,52 @@ +--- +title: "Pages Overview" +id: "designing-app" +sidebar_label: "Pages Overview" +--- +--- + +WaveMaker app is a collection of pages. Pages load asynchronously on demand. Each page is composed of different UI elements and [widgets](/learn/app-development/widgets/widget-library). These UI elements enable user interaction and get data from the backend services. You can set navigation and interaction rules across pages. + +:::tip +To learn about page life cycle and architecture, see [Page Concepts](/learn/app-development/ui-design/page-concepts). To learn about widgets, see [Widgets Library](/learn/app-development/widgets/widget-library). +::: + +Navigate to the pages section to create a page. By default, the project generates a **Main** automatically. + +![Pages introduction in WaveMaker](/learn/assets/pages_introduction.png) + +## Main page + +The Main page comes with header, footer, top nav, left nav and right nav layout. You can change the layout can as per your needs. For more information, see [Layouts](/learn/app-development/ui-design/page-concepts/page-layouts). + +Each element of the page layout - header, footer, topnav, leftnav and rightnav can be edited and customized. The change will reflect in all pages that use the same element. Thus, it gives a unified look across all pages in the app. + +When you are editing, WaveMaker effectively generates the HTML code. You can access the code from the markup tab. + +[![screenshot](/learn/assets/page_layout_edit.png)](/learn/assets/page_layout_edit.png) + +## Types of Pages + +There are two types of pages that can be created in an application: + +1. **Page** – which can be loaded independently in the application. These act as a route within the application when associated with navigation events. +2. **Partial** - these have to be associated with a component within a page. Usually, a part of the page which is common across the app like a header or a left navigation, are implemented as a single partial and used across all app pages. +3. **Popover** - Popover, also known as pop-up, can be built as a portion of a page, reusable and contains UI elements with data binding (e.g.: drill down details, pop-up menus etc.). These can be built like a partial page, but have pop-up based interaction. + +## Page Title + +By default, WaveMaker provides the Main Page. When you add additional pages, it titles the pages as Page1, Page2, and so on. You can use the Page Title property to set the Page Title. + +[![screenshot](/learn/assets/page_title.png)](/learn/assets/page_title.png) + +You can use Page.pageTitle to change and access the page title. You can set the Page Title from Script tab using: Page.pageTitle = 'Profile'. Once set through Script any binding from the properties will be invalidated. + +## Page Operations + +You can duplicate, rename and delete a page using the page operations. These can be accessed from the more options against a given page or a partial page. + +[![page_operations](/learn/assets/page_operations.png)](/learn/assets/page_operations.png) + +- **Renaming** a page or a partial page leads to the page name being renamed, with the new name given by you. All the references are also renamed. +- **Duplicating** a page leads to a copy of the page or partial page being created, with the new name given by you. A new goTo action for that page is also created. +- **Deleting** a page removes all references to the selected page from the project. diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-artefacts.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-artefacts.md new file mode 100644 index 000000000..5223a18a9 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-artefacts.md @@ -0,0 +1,87 @@ +--- +title: "Page Artefacts" +id: "page-artefacts" +--- +--- +You would have witnessed by now that you can accomplish most of the tasks of creating an application in the **Design** mode itself - using intuitive drag and drop options and properties. However, some situations may require you to edit the code of your application pages. Also, some advanced users and experienced developers may prefer to code. Thus, WaveMaker provides different **Page Modes** - [**Markup**](#page-markup), [**Scripting**](#page-script), and [**Styles**](#page-style) - apart from the default **Design** mode. We will look at each of these modes separately. + +[![Screenshot showing page modes](/learn/assets/page_modes.png)](/learn/assets/page_modes.png) + +## Page Markup + +In the **Markup** mode, you can view a set of tags assigned to the elements of the page. Markup may also include attributes and other details of the elements. These details and attributes can also be set in the **Design** mode. + +The **Markup** mode gives the user an option to add widgets and customize the widget behavior programmatically. While building custom apps, it may be noted that WaveMaker generates custom markup automatically. This markup can be accessed via the “Markup” tab in the toolbar. The markup would make much more sense if you have an idea of “directives” in AngularJS. (In short, AngularJS is a JavaScript framework that helps in building Single Page Applications (SPA)). + +Each of the directives represents an element that has to exist at that point of time in the canvas. So for example, if you select a 3-column layout for your App, you will notice the following directives under the Markup tab - wm-page, wm-header, wm-top-nav, wm-content, wm-left-panel, wm-page-content, wm-right-panel, wm-footer. + +Custom markup can be added as needed directly in the code (if you are familiar with it). If not, WaveMaker automatically generates code when the elements are dragged on the canvas. This mode shows the styles that are associated with the particular widget. For instance, consider the **Button** widget. In the **Design** mode, drag and drop a **Button** widget and name it _formSubmitButton_. Set some of the properties of the _button_, say **Left Margin**, **Right Margin** and **Top Margin**, using the **Properties Panel**. + +Now, switch to **Markup** mode. You can see the corresponding markup for the _button _as shown below. + +```html + + +``` + +The **Button** widget is identified by name="formSubmitButton"  and some of the properties are margin="unset 0.5em" and caption="Button" . These properties can be modified in the markup. After saving the changes, the respective widget would get updated with the properties and values defined in the markup. + +## Page Script + +In the **Script** mode, you can define JavaScript functions that can be executed on specific events of user interaction. You can use JavaScript to further customize your WaveMaker application. The various methods and properties associated with each of the WaveMaker elements can be found in the [API Documentation](https://www.wavemakeronline.com/app-runtime/latest/docs). The various ways to access the variables, widgets etc. within an application can be [found here](/learn/app-development/variables/accessing-elements-via-javascript/ "Script Access to Widgets, Variables and more"). + +For instance, to call a JavaScript function for a widget event, choose the _JavaScript _option in the **Events** section of **Properties Panel**. WaveMaker automatically switches to **Script** mode. + +Here is an example to illustrate the process. Suppose you have a button named _formSubmitButton _and you want to create custom JavaScript to execute when the user clicks this button. To set up the JavaScript you follow these steps + +- In the **Design** mode, select the button named _formSubmitButton._ +- In the **Property Panel**, click on **Events**. +- Select _JavaScript_ from the **On Click** event drop-down menu. +- WaveMaker will switch to **Script** mode with the function that will be called when the button is clicked. +- Call the _alert_ function to display an alert when the user clicks _formSubmitButton_ as shown below. + +```javascript +Page.formSubmitButtonClick = function($event, widget) { + alert('Here is an alert from JavaScript'); +}; +``` + +Once you have saved these changes and run the application, clicking on the button will display an alert box with the above message. + +## Page Style + +There are four ways in which you can apply a custom style to your app: + +### Inline Styling + +This is the locally applied style for individual widget or container, used for alignment (padding, margin, border etc.) and applying custom style such as h2, btn-info etc. The class property for widgets is rendered as a **class picker**. This is a multi select drop down list with various classes that are contextual to the widget displayed. You can select classes and see the effect of those applied classes on the canvas with immediate effect. + +[![Screenshot showing styles](/learn/assets/styles.png)](/learn/assets/styles.png) + +A comprehensive list of the available classes can be [wm-widgets](/learn/assets/wm-widgets.pdf). In addition to the list, you can create your own classes and use them, as mentioned below. + +### Style editor + +In the **Style** mode, you can create and edit styles for the page using CSS. Let us create a CSS class for a button _formSubmitButton_. + +- In the **Design** mode, select the button named _formSubmitButton_. +- In the **Properties Panel** on the right side, click on **Styles**. +- Enter the class name, say _buttonSample_, for the property **ButtonClass**. This property defines the CSS class that is supposed to be associated _formSubmitButton_. +- Switch to **Style** mode and enter the following: + +```css +.wm-app .buttonSample { + color: red +}; +``` + +- This would make the _formSubmitButton_ appear red due to the properties mentioned in the _buttonSample_ CSS class. + +These style changes can be made at two levels: + +1. **Page Styling**: Page-only overrides can be applied by making entries to the corresponding _page.css_ file. This option can be used mostly for alignment and custom styles localized to the page. +2. **App Styling**: Styles over all pages of the App can be applied by making entries in the corresponding _app.css_ file. This can be used to override theme to apply a custom style to widgets. +3. **Theme**: These can be used across all widgets of the app. These can be reused over multiple apps for a standard look-n-feel. [More about Themes](/learn/app-development/ui-design/themes/). + +In this document, we have seen how Markup, Style and Script mode for a page can be used to customize the page components of your app. Be aware that this needs to be done with caution and it might result in breaking of the page if you are not well versed with HTML and CSS. diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts.md new file mode 100644 index 000000000..cb7b6fb95 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts.md @@ -0,0 +1,65 @@ +--- +title: "Pages Concepts" +id: "page-concepts" +--- +Introduction to Pages in WaveMaker low-code platform. + +--- +An application is a collection of pages. Each page is composed of different UI elements and Widgets. These UI elements enable user interaction with the app and can get data from the backend services. You can be set navigation and interaction rules across pages. + +:::tip +To design pages, see the [Design Overview](/learn/app-development/ui-design/design-overview) section. +::: + + You can navigate to the pages section as shown in the image below. + +![Pages introduction in WaveMaker](/learn/assets/pages_introduction.png) + +## How Pages work + +WaveMaker Pages are built using the drag-n-drop approach, by placing widgets in the corresponding responsive layout grids. + +[![](/learn/assets/UI_design-1.png)](/learn/assets/UI_design-1.png) + +## Page Architecture + +In this document, you will learn about the following: + +- WaveMaker apps as single-page applications. +- What a typical [page life cycle](#page-life-cycle) of a WaveMaker app looks like. + +## WaveMaker as a Single Page Application + +Single-Page Applications (SPAs) are Web apps that load a single HTML page and dynamically update that page as the user interacts with the app. This is achieved through a clear separation of front-end and backend through AJAX Service, thus cutting full roundtrip to the server to retrieve new presentation content (HTML) which is common to traditional page life cycle. + +[![](/learn/assets/spa_arch.png)](/learn/assets/spa_arch.png) + +A WaveMaker application is a single page application(SPA). Though an app is composed of multiple pages, these pages are loaded asynchronously on demand. At a given point of time, a single page is loaded in the browser for the user to see and interact. The structure of the page i.e. header, footer, left nav is retained across pages, causing no jitter. + +A **page** can be composed of: + +- [Widgets](/learn/app-development/widgets/widget-library) which are loaded as part of the page, or +- [Partial Pages](/learn/app-development/ui-design/page-concepts/partial-pages) as the content of container widgets like Panel, Tabs, Accordion, etc. + +## Page Life Cycle + +When the request for a page is made, it goes through the following life-cycle: + +1. The network request for the page content is made and the Markup, CSS, JavaScript and Variables for the page are loaded. +2. The Markup is then processed and compiled. During Markup compilation, if any Container widget with partial as content is found, then + 1. the resources corresponding to that partial are loaded, + 2. the **onPageReady** callback method in the _partial script_ is invoked. By this time the Widgets and Variables in the partial are loaded and can be accessed in the script. **Note**: the app scoped variables are loaded when the app starts, here we are referring to the page scoped variables alone. +3. The above step is repeated for all the partials and Prefabs found within the page. +4. Once all the partials are loaded, the **onPageReady** callback method in the _page script_ is invoked. At this point, all the Widgets and Variables in the page are ready. +5. Variables, in the page and in the loaded partials, with _Request data on page load_ set to true are triggered at this point. The Variables will not have any data at this point. They are only loaded in memory. The data fetched by these Variables can be accessed in their respective callback methods (_onSuccess_, _onResult_, etc.). + +### Flow Diagrams + +**Page without any partials or Prefabs** [![page-life-cycle](/learn/assets/Page-Life-Cycle.png)](/learn/assets/Page-Life-Cycle.png) **Page with partials and Prefabs** [![page-life-cycle-full](/learn/assets/Page-Life-Cycle-full.png)](/learn/assets/Page-Life-Cycle-full.png) + +## See More +[Creating a page](/learn/app-development/ui-design/page-creation/) +[Page Cache](/learn/app-development/ui-design/page-concepts/page-cache) +[Page layouts](/learn/app-development/ui-design/page-concepts/page-layouts/) +[Templates](/learn/app-development/ui-design/page-concepts/page-templates/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/creating-template-bundles.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/creating-template-bundles.md new file mode 100644 index 000000000..2ffd36a02 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/creating-template-bundles.md @@ -0,0 +1,49 @@ +--- +title: "Creating Template Bundles" +id: "creating-template-bundles" +sidebar_label: "Create Template" +--- +--- + +Template Bundles let you create and use templates across all applications in your enterprise. You can get a UI designer to design the Template Bundle. This document lists the steps in the creation of a Template Bundle. + +1. Select **Template Bundles** tab and select the Create option [![](/learn/assets/Create_TB_create.png)](/learn/assets/Create_TB_create.png) +2. Template bundle can be used on the web or mobile platform. **Choose platform** accordingly. +3. Enter the **Name** and **Description** for the Template Bundle +4. The **Main Page** is created which will be used as a landing page for the Template Bundle and will not be published as part of the Template. You can choose to publish the main page by changing the settings or create a new page for the Template for publishing, from Config Settings as shown in the later steps. +5. You can create and design a new page like any other page of an application. You can use an existing template and make changes. Here we have created a Dashboard page and are making changes to the existing Sales Dashboard template. [![](/learn/assets/Create_TB_template_page.png)](/learn/assets/Create_TB_template_page.png) +6. From the _Secondary Actions_ select **Settings** and then **Config Templates** to open the Template Configuration dialog [![](/learn/assets/template_config_select.png)](/learn/assets/template_config_select.png) +7. Select the page you want to publish. You can: + + - change the **Name** and **Description** + - specify the **Category** to which the Template belongs, you a can leave it blank + - select for **Publish** + - add **Keywords** used for search discovery + - add a **Thumbnail** to be displayed on the Templates selection dialog, and + - add **Screenshots** to be shown under Preview. + + [![](/learn/assets/template_config.png)](/learn/assets/template_config.png) + +8. You can see the Template Bundle in action using the **Preview** option +9. Export the Template Bundle as a zip file (Enterprise version users, refer to the [publishing section](#publishing-page-templates))[![](/learn/assets/template_export.png)](/learn/assets/template_export.png) +10. Create/Open an application to use this Template +11. From the New Page Dialog, you can **Import Template** and apply it to the page. You can see the Thumbnail and Preview the Template. [![](/learn/assets/template_import.png)](/learn/assets/template_import.png) + +## Publishing Template Bundles + +##### Enterprise Version post 10.0 release + +In order for the Template to be available for all developers within the enterprise, it needs to be published to the EDN and approved by the EDN Admin. + +[![](/learn/assets/Publish_template.png)](/learn/assets/Publish_template.png) + +Refer to [Artifacts Publishing Mechanism](/learn/app-development/wavemaker-overview/artifacts-repository/#publishing) for more details. + +[![](/learn/assets/Publish_template_edn.png)](/learn/assets/Publish_template_edn.png) + +After Admin's approval, the Template Bundle is listed in the artifact repository listing. To use the Template, the app developer needs to select it from the Template Dialog while adding a Page to the app, or by using the Change Template option for an existing app. + +[![](/learn/assets/Artifacts_template_list.png)](/learn/assets/Artifacts_template_list.png) + +In this document, we have seen how Page Templates ease page design and how you can create your own templates. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-cache.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-cache.md new file mode 100644 index 000000000..6451251c9 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-cache.md @@ -0,0 +1,80 @@ +--- +title: "Page Cache" +id: "page-cache" +--- +--- + +When the user navigates away from a page, the page usually gets destroyed. Instead of destroying the page, if the page instance is stored in Cache, then the page instance can be used when the user revisits the same URL. This will make page rendering instantaneous in case of revisits. + +In the [10.6.0 release](/learn/wavemaker-release-notes/v10-6-0), WaveMaker implemented this strategy and introduced a new property called Cache at the page level. By default, the Cache property is disabled. Below, the Cache feature is explained in detail with a use case. + +## Usecase + +Let's take the case where an app has two pages: + +1) `Page1` +2) `Page2` + +For example, Cache is enabled on `Page1`, and Cache is disabled on `Page2`. As the user navigates in the app, states of page instances are depicted in the following table. + +### Labels + +**Initialized**: a new page instance is created. +**Attached**: a page instance is taken out from Cache and attached to dom. +**Detached**: a page instance is removed from DOM and is stored in the Cache for future use. +**Destroyed**: a page instance is destroyed completely. +**Page1 - n**: nth instance of page1. +**Page2 - n**: nth instance of page2. + +|Step|User navigated to|Initialized|Attached|Detached|Destroyed| +|-|-|-|-|-|-| +|1|#/Page1?param=value1| Page1 - 1 |||| +|2|#/Page2| Page2 - 1 | |Page1 - 1 || +|3|#/Page1?param=value2| Page1 - 2 | | |Page2 - 1 | +|4|#/Page2| Page2 - 2 | | Page1 - 2| | +|5|#/Page1?param=value1| | Page1 - 1 | | Page2 - 2| +|6|#/Page1?param=value2| | Page1 - 2 |Page1 - 1|| + +- In Cache, a page instance is mapped against the page name and its parameters (the order of parameters is not considered). As param value is changed in steps 1 and 2, two different instances of the same page are created. +- As the user moves from Page1, Page1 instances are added to the Cache (see steps 2, 4, 6). When the user comes back to the same Page1 URL, the cached page1 instance corresponding to the URL is rendered (see steps 5, 6). +- As Cache is disabled on Page2, Page2 instances are destroyed when the user navigates from the Page2 (see steps 3, 5). + +## Page Instance Lifecycle + +[![marked in red](/learn/assets/page-cache/page-lifecycle.png)](/learn/assets/page-cache/page-lifecycle.png) + +## How to Enable Cache + +1. Open the page in Design mode. +2. Select the page element. the page element can be selected by pressing 'ESC' button or from Page Structure, or from the bread crumb at the bottom of the WYSWYG editor. +3. Cache flag is shown in the properties panel on the right side. + +[![marked in red](/learn/assets/page-cache/page-cache.png)](/learn/assets/page-cache/page-cache.png) + +## Events + +Two events including **On Attach** and **On Detach** are added. The **On Attach** event gets triggered when a page instance is retrieved from Cache and added to the DOM tree. The **On Detach** event gets triggered when a page instance is removed from DOM and added to the Cache. + +In Studio, these events are visible on the page level, only if *Cache* is enabled. In case of partial or prefab, these events are always visible. + +:::note +`onPageReady` is triggered only when a page instance is initialized. **On Destroy** is triggered when the page instance gets destroyed. The same applies to Partial and Prefab. +::: + +## Data refresh + +A cached page may have data that needs to be refreshed. You can use the following options to refresh data. + +1. A property **Refresh data on attach** is added at the page level. If this flag is true, and the cached page instance is shown, then all start-up variables that have enabled **load data on page startup** of the page are invoked. If there are partials and prefabs in a page, then startup variables of partials and prefabs are also invoked. By default, this flag is set to true. + +2. You can use **On Attach** event to refresh data by invoking the required variables. + +## Cache Characteristics + +1. A page instance is stored in the cache for a maximum of 30 minutes. Age of page instance is reset to zero after each revisit. +2. Cache can store a maximum of *10-page* instances. When the Cache is full and a new instance is added, then the page instance of the longest age is removed. +3. When the user logs out, or session expires, all cached page instances are destroyed. + +## Recommended Usage + +As page instances are stored in memory, the memory usage of the app increases. Eventually, the app may not respond and may crash. So, there is a limit of 10 (which can be changed in the future) page instances to store in Cache. So, you should enable cache, only on those pages that their app user frequently revisits. After enabling Cache, you should check about data getting refreshed on revisit. If required, make appropriate changes as explained in the [Data Refresh](#data-refresh) section. diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-events.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-events.md new file mode 100644 index 000000000..75c2d7853 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-events.md @@ -0,0 +1,50 @@ +--- +title: "Page Events" +id: "page-events" +sidebar_label: "Events" +--- +--- + +Events provide a way for you to define the actions that take place when something occurs in your application. There are many events that occur within a WaveMaker application. The most common events are user interface events, such as when a user clicks a button. Events are also triggered when an editor's value changes, and even when a** Variable** gets new data from the server. You have several options for specifying what will happen when a button is clicked. + +[![](/learn/assets/event_types.png)](/learn/assets/event_types.png) + +## Mouse Events On-Click Properties + +### No Event +Take no action. + +### JavaScript +You can write your own event handler in JavaScript, providing unlimited flexibility to define the resulting action. + +### Stop Propagation +If applied for an event it stops event propagating to its parent. Ex: - Button is present inside a container. Both 'Container' and 'Button' have click events and you don't want to propagate click of the button to its parent ie. to trigger container click. You can add 'Stop Propagation' after the click of 'Button'. With 'Stop Propagation' only 'Button' click is triggered. Without 'Stop Propagation' both click events will be triggered. One exception is for 'List' widget as click on any widget inside list will trigger first the click of 'List' widget as it is being done in capturing stage. + +### New Variable +For example, a user clicks a _Search_ button. A Service is invoked whenever the button is pressed, causing the service to be executed and the data of the corresponding Variable is updated. Or the user clicks a _Save_ button, and the corresponding Variable you select for your event will automatically write its current source data to the database. + +### New Action +For example, a help dialog automatically displays when a help button is clicked. Or the user clicks a _Next Page_ button, and the _Navigation Action_you select for your event loads a new page. + +## Event Categorization + +The events are categorized as follows: + +|Events| Description | +|---|---| +|**Common events** | Triggered by multiple actions. These include _Change_, _Focus_, _Blur_, and more.| +|**Mouse Events** | Capture the mouse activity on your application. These include _Click_, _Double Click_, _Mouse Enter_, _Mouse Leave_, and more. | +| **Touch Events** | Gets triggered when running the app on a mobile or tablet or any other smart device. These events include: _Swipe Up_, _Swipe Down_, _Swipe Left_, _Swipe Right_, _Pinch In_, _Pinch Out_, and more.| +| **KeyBoard Events** | Capture the key strokes. These include _Enter Key Press_, and more.| +| **CallBack Events** | Widget-specific special events. For example, _Record Delete_, _on Select_, _on Deselect_ for a grid widget; _Before Records Update_ for Data Navigator. | + +## Multiple Actions on an Event + +WaveMaker supports multi-action event handling. This means you can assign a series of actions that can be triggered by a single event. Click on the "**+**" next to the event name to add more actions. When you use a series of variables to trigger on an event ensure that you handle eventualities like one callback was a success and other failed. + +We have seen how Page Layouts, Navigation, and Events help in defining the flow of the app. Check out these [use cases](/learn/app-development/ui-design/use-cases-ui-design/) to further your experience. + +## See Also + +[Page Navigation](/learn/app-development/ui-design/page-concepts/page-navigation) +[Prevent Leaving Page with Unsaved Changes](/learn/how-tos/prevent-user-leaving-page-unsaved-changes) diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-layouts.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-layouts.md new file mode 100644 index 000000000..95a46b892 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-layouts.md @@ -0,0 +1,50 @@ +--- +title: "Page Layout" +id: "page-layouts" +--- +--- + +**Page Layouts** help you design the structure of the page by demarcating the header, footer, navigation and one or more content columns. Based on the Page construction system, WaveMaker provides different options for Page Layouts, which can be picked based on the interaction required for the app. Depending on the app platform - web or mobile, the layout will differ. + +## Select Layout + +A layout can be set to a default one at the time of Page Creation and later can be changed from the Workspace Toolbar. + +[![](/learn/assets/layout_change.png)](/learn/assets/layout_change.png) + +## Web Responsive + +A **Page Layout** has the following containers - a header, navigation bar, content, and footer. The content can have one, two or three columns. To change the layout of a page, simply click on the desired layout to see it take effect on the design canvas. + +[![](/learn/assets/page_layout.png)](/learn/assets/page_layout.png) + +There are four Page Layout options: + +- **Blank Layout** - without any header or a footer. +- **Header, content, and footer**: The content along with a header and a footer. +- **Header, topnav, content and footer**: The content along with a header, a footer, and a top navigation bar. +- **Header, content, leftnav and footer**: The content along with a header, a footer, and a left navigation bar. +- **Header, topnav, leftnav, content, and footer**: The content along with a header, a footer and a top and left navigation bar. +- **Header, leftnav, content, rightnav and footer**: The content along with a header, a footer and a left and right navigation bar. +- **Header, topnav, leftnav, content, rightnav and footer**: The content along with a header, a footer and a top, left and right navigation bar. + +A typical page layout with header, footer, topnav, leftnav and rightnav has the following structure, as can be seen from the _Page Structure_ for the selected page: + +[![](/learn/assets/page_layout_files.png)](/learn/assets/page_layout_files.png) + +Widgets can be added to the _content._ The header, footer, top-nav, left and right panels are partial pages and can be customized using the edit button on each of the panels. + +:::note +WaveMaker automatically adjusts the layout rendering for mobile devices. +::: + +## Hybrid Mobile + +Similarly for Mobile apps, each page can be designed by selecting an appropriate layout and arranging widgets in it. For more information, see [Hybrid Mobile Page Layout](/learn/hybrid-mobile/mobile-page-concepts/). + +[![page_layout_mobile](/learn/assets/page_layout_mobile.png)](/learn/assets/page_layout_mobile.png) + +## Container Widgets + +You can use the **Container Widgets** to arrange the widgets on a web page. For more information, see [Container Widgets](/learn/app-development/widgets/widget-library/#container-widgets). + diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-navigation.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-navigation.md new file mode 100644 index 000000000..e8a25b91b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-navigation.md @@ -0,0 +1,51 @@ +--- +title: "Page Navigation" +id: "page-navigation" +sidebar_label: "Navigation" +--- +--- + +There are several ways for the user to move from one page to another. A **Navigation Action** is triggered when an event occurs. You can change what is displayed when an event occurs, for example: + +- Button click – Use the button’s _On click_ event to trigger a move to a new page. +- Grid selection – Use the grid’s _On select_ event to trigger a navigation. Navigation Action specifies exactly how the user should move from one page to another when an event occurs. + +Navigation Action is a component you can add to your project and provide the following options: + +- _Page_ – Navigates to the specified page. +- _Previous Page_ – Navigates to the previous page. +- _Accordion_ – Navigates to the specified accordion of the specified page. +- _Tab_ – Navigates to the specified tab of the specified page. + +## Navigation Action + +Navigation in the application happens using a **Navigation Action**. Whenever a page is created a corresponding _gotoPage_ navigation action is generated or one can create the action manually. + +[![](/learn/assets/call_var.png)](/learn/assets/call_var.png) + +## Configuration + +Navigation can be to a page or to a component like a tab or accordion pane on a page. Navigation Action can be invoked in two ways: + +### Using Widget Properties + +Binding the Navigation Action to a Widget event - For example Button click – Use the button’s onClick event to trigger a Navigation Action to move to a new page or view. + +[![](/learn/assets/call_event.png)](/learn/assets/call_event.png) + +### Customization +Manually invoking the Navigation Action used when you want to validate the user action or state of the application before allowing the navigation. For example: Assume a scenario, to allow the navigation only when the user selects a subscriptionType, then the onClick event can trigger a JavaScript function: + +``` + Page.subscribe = funtion($event, widget){ + //navigate to subscribe page only when subscriptionType is provided + if (Page.Widgets.subscriptionType.datavalue) { + Page.Actions.goToPage_subscription.navigate(); + } + }; +``` + +## See Also + +[Prevent Leaving Page with Unsaved Changes](/learn/how-tos/prevent-user-leaving-page-unsaved-changes) +[Page Events](/learn/app-development/ui-design/page-concepts/page-events) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-parameters.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-parameters.md new file mode 100644 index 000000000..66256ac72 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-parameters.md @@ -0,0 +1,45 @@ +--- +title: "Page Parameters" +id: "page-parameters" +sidebar_label: "Page Parameters" +--- +Page parameters is an important concept. It helps passing data across pages. + +--- +Pass data from one page to another page within an app by defining the **Page Params**. This applies to pages and partial pages. There can be many scenarios where you will need to pass data to a specific page. For example: + +- displaying the employee details working in a selected department, +- displaying profile for a specific user based on some dynamic constraint, or +- loading a personalized page like for activation links etc.. + +## How parameters work + +A typical page URL for a given app would be like this: https://www.app.com/#pagename Once the Page Param has been defined the URL changes to https://www.app.com/#pagename?param1=1¶m2=abc This URL format will allow the data to be retained on browser refresh and reload. As is evident from the above example, multiple parameters are also supported. + +## Steps to adding Page Params + +There are two aspects to adding Page Params. + + + +1. **Parameterized Page**: Page needing input to render the data on the page needs to _define_ page-level parameters to hold this input and _access_ the param value within the page. +2. **Calling Page**: Page calling the above parameterized-page needs a way to _pass the value_ to the parameter + +For example, `test_page` needs an id to render the data and it has to be invoked from Main Page with the needed value for id. + +### Parameterised Page +- Add the parameter fields to the parameterized page (in this case, _test_page_) by giving it a Name and specifying the Type. Currently, the supported types for page param are string, integer, boolean and date.⁣ + +[![](/learn/assets/pp_params.png)](/learn/assets/pp_params.png) + +- Page Params are available on the page/partial scope and can be used in the same. These parameters can be accessed from the Page Param tab on the binding dialog. + +[![](/learn/assets/pp_bind.png)](/learn/assets/pp_bind.png) + +### Calling Page +- The Application-scoped Navigation Action generated by default by WaveMaker for test_page can be used to bind a value for the id field from the Main Page. The param will be available in the data tab of the Actions (goToPage_test_page). You can also create another Navigation Action and use it in a different navigation flow. + +[![](/learn/assets/pp_navvar.png)](/learn/assets/pp_navvar.png) + +We have seen how a page can be added to WaveMaker app, it's title and layout set. We also saw how page parameters can be used to pass information to pages. Learn more about [Partial Pages](/learn/app-development/ui-design/page-concepts/partial-pages/), [Page Layouts](/learn/app-development/ui-design/page-concepts/page-layouts/), and [Page Templates](/learn/app-development/ui-design/page-concepts/page-templates/). + diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-templates.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-templates.md new file mode 100644 index 000000000..e9d4fa4c3 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/page-templates.md @@ -0,0 +1,27 @@ +--- +title: "Templates" +id: "page-templates" +sidebar_label: "Templates" +--- +--- + +Templates are editable pages with the layout and content defined. These can be used by the developer as a foundation on which the application pages can be built. + +## Default Page Templates + +WaveMaker provides some default Templates for the ease of app development process. The templates are categorized under various heads like Travel, Sales, Healthcare, Finance, Human Resources etc.. Binding the various widgets on these templates to the various data sources will provide the required functionality. For Hybrid Mobile Apps these templates are categorized as a card, chart, dashboard, menu etc. + +- Page Templates are available for _selection_ when adding a new page to an application. +- A _preview_ of each template can be seen by hovering over the template and clicking on the **Preview** button. +- For developer convenience, the Templates are _categorized_ as Travel, Basic, Sales, Healthcare, General, Finance, Human Resources, Social, Admin, and E-Commerce. For Hybrid Mobile Apps these templates are categorized as a card, chart, dashboard, menu etc. +- Each of the Templates has default values set, so the developer can get an idea of how the page would look like. Each of the content and widgets on the canvas _needs to be bound_ to live data for actual rendering of the page. + +## Web Responsive +--- +[![](/learn/assets/template_selection.png)](/learn/assets/template_selection.png) + +## Hybrid Mobile +--- +[![](/learn/assets/template_selection_mobile.png)](/learn/assets/template_selection_mobile.png) + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/partial-pages.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/partial-pages.md new file mode 100644 index 000000000..953336897 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-concepts/partial-pages.md @@ -0,0 +1,38 @@ +--- +title: "Partial Page" +id: "partial-pages" +--- +--- +A part of the page which is common across the app like a header or a left navigation can be implemented as a single partial and used across all app pages. These partial pages have to be associated with a component within a page. Here we will be seeing where partial pages can be used, how to create the same and the various types of partial pages available. + +The partial pages are loaded asynchronously on the page. Partial pages are loaded on-demand when the content is required to be rendered. For example, if the tabs are loading partial content, then the partial content will be loaded only on the visible tab. + +**Partials** are useful for the following reasons: + +- In selecting a template which is designed for a particular purpose. For example, header template can be used for header type of partial. +- In allowing us to select a partial for a component/widget. For example, a left panel can include only partial of type leftnav. +- In styling the components specific to the context. For example, links in the left panel should look different from the ones in the right panel. + +Partial Pages are created like Pages and can be designed similar to any other Page. + +**Step-1**: Choose the template for partial. +[![](/learn/assets/partial_page_step1.png)](/learn/assets/partial_page_step1.png) + +**Step-2**: Name your partial and create. +[![](/learn/assets/partial_page_step2.png)](/learn/assets/partial_page_step2.png) + +# Types of Partials + +Partials can be further sub-categorised as: + +- **Default** comes without any layout; +- **Header** which can be used to include logo, app name, search bar; +- **Topnav** which can be used for navigation purpose to be placed at the top of the page, below header; +- **Leftnav** which can be used for navigation purpose to be placed on the left of the page; +- **Rightnav** which can be used for navigation purpose to be placed on the right of the page; +- **Footer** to have the copyright and other information at the bottom of page; +- **Popover** to be used to display notifications on click of an anchor widget. +- For Hybrid Mobile, the available options are - partial or default, leftnav and popover. + +We have seen how common parts of pages can be developed using Partial pages. Learn how [page layouts](/learn/app-development/ui-design/page-concepts/page-layouts/) help associate these with a component within the pages. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-creation.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-creation.md new file mode 100644 index 000000000..dbe81cecc --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/page-creation.md @@ -0,0 +1,42 @@ +--- +title: "Create a Page" +id: "page-creation" +sidebar_label: "Creating a Page" +--- +WaveMaker app is a collection of pages. Learn how to create a page. + +--- + +New pages can be created to segregate the functionality of the app. Ideally, each page would cater to one business need of the app. New pages can use pre-built templates and layout. + +## Creating a Page + +1. To create a new page, click the **+** button. + +![new page](/learn/assets/page_new.png) + +2. A new page creation dialog opens. Enter a page name and click **Choose Template**. + +![create page flow](/learn/assets/create-page-flow.png) + +### Validations for Page name + +When creating a page, the following naming conventions should to be followed. + +1. The page name should contain at least one character, and it cannot be a number. +2. The page name cannot contain special characters. +3. The page name cannot start with a number. + +![select template](/learn/assets/template_selection.png) + +3. Filter template types from the left navigation, or choose **Black Template**. + +:::note +To learn more about templates, see [Templates](/learn/app-development/ui-design/page-concepts/page-templates). Or, to create a your own template, see [Create a Template](/learn/app-development/ui-design/page-concepts/creating-template-bundles) +::: + +4. Click **Create**. + +A page should be created. To navigate to a different page, see page title from the [Pages navigation](/learn/app-development/ui-design/page-concepts/page-templates). + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/project-shells.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/project-shells.md new file mode 100644 index 000000000..6e11457e9 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/project-shells.md @@ -0,0 +1,60 @@ +--- +title: "Project Shells" +id: "project-shells" +--- +--- + +**Project Shells** can be used as a starting point in app development and used as a foundation for multiple apps within an enterprise. In this document, we will be talking about: + +- the benefits of using a project shells, +- [default project shell](#default-shell), +- how to [create a project shell](#creating-shell), and +- how to [publish a project shell](#publishing-shell). + +Basically, a Project Shell is an app with functionality included. This functionality can be used as is or with some changes/enhancements, across multiple apps. + +For example, multiple apps in an organization could be using the same database or the same security mechanism. You can create an app with the database imported or the security applied and save as shell. Use this shell when you develop other apps, use this shell. Project Shell will ensure uniformity at the same time reducing the app development time and effort. + +You can select the project shell to apply when you create an application. **NOTE**: You will not be given an option to select a project shell unless you create and save (or publish to EDN for Enterprise Edition) a project as a shell within your workspace. The default project shell that comes with the platform will be applied. + +[![project_shell_apply](/learn/assets/project_shell_apply.png)](/learn/assets/project_shell_apply.png) + +## Default Page Shell + +Whenever you create an app using WaveMaker it is based out of a default project shell. This shell contains the following components: + +- the Main page, +- a Login page, and +- partials for + - header, footer, + - leftnav, rightnav, topnav and + - common dialogs for login, alert and confirm. + +## Creating Project Shell + +Like mentioned above, you can create and use your own project shells as per your app development needs. For this follow these steps: + +1. Create an app with the functionality, theme, and styles that you want to be applied in common to multiple apps. +2. Once you have created the app, Export it as Project Shell. [![](/learn/assets/Publish_shell_ws.png)](/learn/assets/Publish_shell_ws.png) +3. This shell will be available for selection when you create an app from your workspace. [![project_shell_apply](/learn/assets/project_shell_apply2.png)](/learn/assets/project_shell_apply2.png) + +## Publishing Project Shell + +##### Enterprise Version post 10.0 release + +In order for the Project Shell to be available for all developers within the enterprise, it needs to be published to the EDN and approved by the EDN Admin. Refer to [Artifacts Publishing Mechanism](/learn/app-development/wavemaker-overview/artifacts-repository/#publishing) for more details. [![](/learn/assets/Publish_shell.png)](/learn/assets/Publish_shell.png) + +Export as Shell to EDN will prompt you to enter the following details: + +- **Category**: this will be used for grouping purpose. Categories are typically defined by EDN Admin and developers associate the artifact with a given category at the time of publishing. +- **Version Number**: Each artifact is associated with a version (automatic versioning) at the time of the publishing process. +- **Change Log**: These include the comments that the developer needs to add before publishing the artifact. +- **Tag**: this will be useful for searching, each artifact can have multiple tags. + +[![](/learn/assets/shell_publish_edn.png)](/learn/assets/shell_publish_edn.png) + +- After Admin's approval, the Shell is listed in the artifact repository listing. [![](/learn/assets/Artifacts_shell_list.png)](/learn/assets/Artifacts_shell_list.png) +- To use the Shell, the app developer needs to select the Shell at the time of App creation. [![project_shell_apply](/learn/assets/project_shell_apply2.png)](/learn/assets/project_shell_apply2.png) + +In this document, we have seen how Project Shell can be used as a foundation for multiple applications without replicating the effort. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/theme-builder.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/theme-builder.md new file mode 100644 index 000000000..4fea2a0f3 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/theme-builder.md @@ -0,0 +1,83 @@ +--- +title: "Creating Themes using the Editor Tool" +id: "theme-builder" +sidebar_label: "Theme Editor" +--- +--- + +Themes are used to apply a style to the entire application. Develop themes for web apps instantly without needing to code; you can do this by using WaveMaker theme builder. + +:::note +Theme Builder is supported for web responsive themes only. +::: + +:::tip +You can also develop more advanced themes by installing the setup which requires you to know HTML, CSS, LESS, and Grunt. For more information on manual setup, see [Creating Themes using the Manual Setup](/learn/app-development/ui-design/creating-themes). +::: + +## Theme Builder + +**Theme Builder** is a WaveMaker application that allows you to build a theme by changing **colors**, **typography**, and **styles** of the components and elements without needing to edit the code. + +Follow the steps below to build a theme. + +- Go to the [WaveMaker Theme Builder](https://apps.wavemakeronline.com/Theme_Builder/#/Dashboard) app. +- Click the **Explore/Create** themes option. + + ![theme options](/learn/assets/theme-builder.png) + +- On the Editor page, you can customize the existing #HEX values with custom hex, rgba, rgb colors, choose font-family and sizes, and select styles for the component and elements in a few simple steps. + +### Step 1: Choose Colors + +Change the existing **#HEX** values by choosing colors from the color picker for primary, secondary, and additional colors that you want to modify for the pages. + +1. **`Colors`**: Set global colors for components and elements +2. **`LeftNav`**: Set colors for the left navigation +3. **`Header`**: Set colors to change the header styles +4. **`More options`**: Set the colors for the disabling, links, and alerting properties + +![apply colors](/learn/assets/Theme-builder-step1.png) + +### Step 2: Apply Font Styles + +Customize the typography for the header, body, and caption styles. You can choose the **font-family** from the options available in the dropdown. + +1. **`Heading font`**: Select the font-family for headers, which apply to H1, H2, H3, H4, H5, and H6 +2. **`Body font`**: Select the font-family for body and captions +3. **`More options`**: Set font-weight, font-size and case sensitive preferences + +![apply font](/learn/assets/Theme-builder-step2.png) + +### Step 3: Select Theme Variation Style + +Change the variation of theme style as per the aesthetics. Switching between themes will allow you to preview the relative changes instantly. You can select from the following options. + +- **Flat**: The flat-theme includes a solid background to the elements with active states. It also adds an outlined border for user inputs. + +- **Material**: The material-theme has a sleek finish with elevated shadows to understand each element's relative importance and focus their attention. + +- **Gradient**: The gradient theme fills the content blocks with a linear gradient shade starting from top to bottom. + +![apply theme style](/learn/assets/Theme-builder-step3.png) + +## Next Steps + +:::note +Step 4: Changing the behavior of icons (coming soon). +::: + +When you have made all the changes, you can proceed to save the theme. + +- Click **Done**, and your changes are ready to download. +- Provide a **Name** for your theme, and click **Download Theme**. + +[![download theme](/learn/assets/theme-builder-rename.png)](/learn/assets/theme-builder-rename.png) + +:::important +The theme will be downloaded as a `.zip` file. +::: + +- **Import** and **apply** the downloaded theme into any of your WaveMaker applications. + +For more information on how to import a theme, see [Importing Theme](/learn/app-development/ui-design/themes#import-theme). \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/themes.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/themes.md new file mode 100644 index 000000000..ff27c28ec --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/themes.md @@ -0,0 +1,90 @@ +--- +title: "Apply and Import Theme" +id: "themes" +sidebar_label: "Themes" +--- +--- + +**Themes** are style elements that work at the widget or UI component level. Themes help you provide a consistent look and feel to your application. + +In this document, see how to apply standard themes, and in the next section, see how to import and apply custom themes. + +## Applying Standard Themes + +To change the theme, click **Themes** from the Workspace toolbar. + +[![theme change](/learn/assets/theme_change.png)](/learn/assets/theme_change.png) + +### Supported Themes + +This will open a Theme dialog with a list of WaveMaker standard themes to choose from. + +- Dark +- Default +- Material +- Material-2.0 +- Passion +- Vintage + +[![themes](/learn/assets/Themes.png)](/learn/assets/Themes.png) + +:::note +WaveMaker provides a few default themes that can be applied to your apps. From time to time, these themes might undergo changes and you might be asked to update the theme when you open the project. +::: + +:::warning +Remember that the updates will re-write any changes you made directly to the CSS styles of the corresponding theme. +::: + +### Deprecated Themes + +These changes take effect from [Release-10.4](/learn/wavemaker-release-notes/v10-4-0). + +1. Graffiti +2. Mellow-yellow +3. Autumn +4. Cool-blue +5. Flyer +6. Retro +7. Vermillion + +:::warning +If you are using a deprecated theme, you will still be able to use it until you change it to another theme. Once the changes are made, you cannot go back to the old theme. +::: + + +## Import and Apply Custom Themes + +You can import a customized theme for your app by developing a theme with your own branding standards or styles. + +:::note +To develop a customized theme, you can go with either of these approaches. + +- First, by using a [Theme Builder](https://apps.wavemakeronline.com/Theme_Builder/#/Dashboard) without needing to code. For more information, see [Using the Theme Editor Tool](/learn/app-development/ui-design/theme-builder). +- And, second, by installing the setup and [Manually Developing a Theme](/learn/app-development/ui-design/creating-themes). + +If you want to use a custom theme, it is recommended to create a theme and come back to this section to import and apply a theme. +::: + +:::important +For the Enterprise version, the custom themes will be available once they are published to the EDN and approved by the EDN Admin, without needing to import. + +For more information, see [How to Publish a Theme to EDN](/learn/app-development/ui-design/creating-themes#publishing-the-theme). +::: + +### Import Theme + +- Go to **Themes**. + +[![theme change](/learn/assets/theme_change.png)](/learn/assets/theme_change.png) + +- From the **Themes** dialog, click **Import Theme**. + +![import theme](/learn/assets/import-theme.png) + +- A pop-up window displays to upload a WaveMaker theme zip file. + +### Apply Theme + +- Once the theme is imported, it appears in the **Theme** dialog window. +- Select the imported theme, and click **Apply**. \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/ui-design/use-cases-ui-design.md b/website/versioned_docs/version-v11.8.5/app-development/ui-design/use-cases-ui-design.md new file mode 100644 index 000000000..f45a767c7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/ui-design/use-cases-ui-design.md @@ -0,0 +1,30 @@ +--- +title: "Examples - UI Design" +id: "use-cases-ui-design" +sidebar_label: "Examples" +--- +--- + +Project workflow is defined by navigation and interaction between various pages that constitute an app. + +## Navigation +How to Navigate between Pages in +- [Web Responsive Apps](/learn/responsive-web/web-ui-design/#page-navigation) +- [Mobile Apps](/learn/hybrid-mobile/mobile-page-concepts/#page-navigation-actions) + +### Parameters + +- [How to pass parameters to pages](/learn/how-tos/passing-parameters-pages/) +- [How to pass parameters to partial pages](/learn/how-tos/passing-parameters-partial-page/) +- [How to use static variable to pass data between pages](/learn/how-tos/use-static-variable-pass-data-pages/) + +## Customizations +You can customize the look and feel of your app. Following links talk about few such cases: + +- [How to set home page, default language and display format for date and time fields](/learn/how-tos/setting-language-date-format/) +- [How to change the default app favicon](/learn/how-tos/changing-default-favicon/) +- [How to set the app logo](/learn/how-tos/changing-app-logo/) +- [How to change the page title](/learn/how-tos/changing-page-title/) +- [How to customize app styling](/learn/how-tos/customise-app-style/) +- [How to customize the app login page](/learn/how-tos/customise-login-page/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/accessing-elements-via-javascript.md b/website/versioned_docs/version-v11.8.5/app-development/variables/accessing-elements-via-javascript.md new file mode 100644 index 000000000..36932212c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/accessing-elements-via-javascript.md @@ -0,0 +1,107 @@ +--- +title: "Accessing Elements via JavaScript" +id: "accessing-elements-via-javascript" +sidebar_label: "JavaScript Access" +--- +--- + +A **Page** in WaveMaker application consists of Markup, Script & CSS files. In this document, we will go through the various functions/methods that are available in the script file. We will see how these methods can be created and modified. + +**Page script** can be accessed from the script tab on your project workspace. Using JavaScript, the functionality of your project can be enhanced. The various methods and properties associated with each of the Studio elements can be found in the [API Documentation](https://www.wavemakeronline.com/app-runtime/latest/docs/index.html). + +## Page Lifecycle + +When a Page is created, it has a single context object (singleton instance) called "**Page**" in the JavaScript. You can attach lifecycle methods, events, and callbacks to this object. When a new page is created it creates the "**onReady**" lifecycle methods where you can write the code to be invoked after the page is rendered completely. + +There are two more singleton instances used in the platform named "**Partial**" & "**Prefab**" which are used in Partial pages and Prefab page respectively. + +:::note +_onPageReady _function has been deprecated since 10.0 release, use Page.onReady instead. +::: + +[![](/learn/assets/pageScript.png)](/learn/assets/pageScript.png) + +In the following sections, we will be seeing how each element of the project can be accessed using the Script. + +## Widget Lifecycle + +For every Widget, there are a set of lifecycle methods and event callbacks that can be accessed from the JavaScript. + +The events can be accessed from the properties panel for the specific Widget and assigned to a JavaScript or any other actions. JavaScript can be written from the Script tab, as per the app requirements. For example, to display an alert message on click of a button, the following would be the code: + +``` +Page.button1Click = function($event, widget) { + alert("Hello") +}; +``` +For Widget Life Cycle Methods usage examples refer to the specific [Widget Documentation](/learn/app-development/widgets/widget-library/). + +## Custom Methods + +You can write your own custom functionality and access the methods from anywhere in the page. + +``` +Page.myMethod = function(parameters) { +// your code here +}; +``` + +## App Variables + +Variables created with Owner set to App can be accessed from all Pages, Partials, and Prefabs +``` +App.Variables.. +``` + +## Accessing the Page/Partial/Prefab Widgets and Variables + +The Widgets and Variables of a page can be accessed through the page script. The widgets and variables operate within the scope they are created in. Additionally, the widgets and variables defined in a Page can be accessed within the partial pages and vice versa. + +The Widgets and Variables of a page can be accessed through the page script. They are exposed as 'Widgets' and 'Variables' properties in the respective page scope. + +To access variables and widgets of a page named "Main" use following scripts in Main page controller: + +``` +/** to set "caption" property of a label widget (eg 'label1') **/ +Page.Widgets.label1.caption = "New Caption"; +/** to change a variable (eg 'userInfoVariable') dataSet property, use the script: **/ +Page.Variables.userInfoVariable.dataSet = {dataValue": "new value"}; +``` + +:::note +Replace Page with Partial or Prefab when working with in Partial or Prefab, respectively. +::: + +## Accessing the Widgets and Variables of Partial from Parent Page through Scripting + +The Widgets and Variables inside a partial page can be accessed from the parent page script through the 'Widgets' and 'Variables' property exposed in the scope of the partial container widget. + +``` +Page.Widgets.[container_name].Widgets.[widget_name].[widget_property]; +Page.Widgets.[container_name].Variables.[variable_name]; +``` + +**Example** +To access variables and widgets of a partial page loaded in a page named "Main". + +``` +/** to set the "caption" of a label widget (eg label1) of a partial page loaded as a content of panel widget (eg panel1) **/ +Page.Widgets.panel1.Widgets.label1.caption = "New Caption"; + +/** to access partial page's Variable (say staticVariable1) in the parent page 'Main' **/: +Page.Widgets.panel1.Variables.staticVariable1.dataSet = {"dataValue": "new value"}; +``` + +## App Level Access + +As with the Pages, App lifecycle events and variables can be accessed from the _app.js_ file. This file can be accessed from the File Explorer. + +[![](/learn/assets/appJS.png)](/learn/assets/appJS.png) + +The following methods are available: + +- **onAppVariablesReady** - this refers to the Variables created with App as Owner.  Variables can be accessed through 'App.Variables' property: e.g. App.Variables.staticVariable1.getData() +- **onSessionTimeout** - perform any action on session timeout here, e.g clearing some data, etc +- **onPageReady** - This application level callback function will be invoked after the invocation of PAGE level onPageReady function +- **onServiceError** - This application level callback function will be invoked after a Variable receives an error from the target service. Use this function to write common error handling logic across the application + diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/crud-variable.md b/website/versioned_docs/version-v11.8.5/app-development/variables/crud-variable.md new file mode 100644 index 000000000..7f2a96a5a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/crud-variable.md @@ -0,0 +1,268 @@ +--- +title: "CRUD Variable for REST Services" +id: "crud-variable" +sidebar_label: "CRUD Variable" +--- +--- + +For every service imported into the app, the APIs exposed by the service can be accessed to perform many operations with it. A variable needs to be created to invoke the service and store the results of that invocation. The Variable operations are restricted by the offerings of the underlying service. + +WaveMaker automatically generates UI functionality for create, read, update, delete (CRUD) operations if you import REST API endpoints via Swagger/OpenAPI. For more information, see [Import REST APIs via Swagger](/learn/app-development/services/api-designer/import-rest-apis-swagger). + +A comprehensive list of these APIs can be found from the [API Designer](/learn/assets/API_Access.png) after the import of the service. + +:::note +Since the service needs to be invoked to fetch the data, the widgets bound to these variables will display values only at run-time, not in Studio mode. +::: + +### Supported Widgets + +**Web**: DataTable, Form + +**Mobile**: List with Form + +## How to Create a CRUD Variable + +You can create a CRUD variable by using the following two approaches. + +1. Create a CRUD variable from a Variable Dialog. +2. Create a CRUD variable by drag-n-drop of the [supported widget](#supported-widgets). + +### Using Variable Dialog + +1. Select **Variable** from the workspace toolbar. + +![variable creation](/learn/assets/var_sel.png) + +2. Click **New Variable** from the Variable Dialog. + +![new variable](/learn/assets/var_new.png) + +3. Select **Imported APIs** as a target action for the Variable. + +![select imported api](/learn/assets/select-imported-api.png) + +4. In the new Variable dialog, configure the properties for the variable. + +![create crud variable](/learn/assets/create-crud-variable.png) + +:::note +You can create a service variable to perform one operation at once using **Other Endpoints**. For more information, see [Service Variable for Imported APIs](/learn/app-development/variables/web-service#service-variable-for-imported-apis). +::: + +- **Service**: Select the [Imported Service](/learn/app-development/services/api-designer/import-rest-apis-swagger#importing-swagger). +- **Type**: Select the **Type** as `Entities (CRUD)`. +- **Entity**: Select the entity from the dropdown. Create, Read, Update, and Delete methods group into a single entity. For more information, see [Entity and Endpoints](/learn/app-development/services/api-designer/import-rest-apis-swagger#entity-and-endpoints). +- **Name**: Set by default, but you can modify it. +- **Owner**: The scope of the Variable. **Page** is the default option. You can choose **Application** to make the variable available across the app. +- Click **Done** to complete the variable creation process. + +### Using Drag and Drop of Widget + +Drag and drop the [supported-widget](#supported-widgets) on the canvas. For example, in the following image, a Datatable widget is used to create a CRUD variable. + +![datatable crud variable](/learn/assets/datatable-crud-variable.png) + +- **Retrieve Data From**: Services is selected by default. +- **Select a Service type**: To use CRUD variable, select **All** from the dropdown. +- **Select a Service**: Select the entity from the drop-down which lists the services available in your application. +- **Variable Creation**: Once you select the service and table/Entity for the service, a default variable will be created. See the Variable Name field populated by default which will be holding the dataset of the service. You can change the Variable name. +- Select **Form As Dialog** or **Form Below**, and Click **Next**. +- Select pagination, click **Next**. +- Configure table columns. These fields can also be configured using **Advanced Settings** from the **Properties** panel. +- Select template. +- Configure Form fields. These fields can also be configured using **Advanced Settings** from the **Properties** panel. +- Click **Done**. + +For more information to create Datatable, see [Create a Datatable](/learn/app-development/widgets/datalive/datatable/data-table-basic-usage). + +### Variable Properties and Events + +![variable creation](/learn/assets/var_sel.png) + +You will be directed to the Variables page, with the new variable listed. You can see the following options. + +![crud variable properties](/learn/assets/crud-var-properties.png) + +1. **Name**: You can modify the variable name. +2. **Owner**: The scope of the Variable. Page is the default option. You can choose Application to make it available across the app. +3. A new **Imported APIs** Variable created with the default exposed method/selected method as a target. +4. The **Properties** tab contains all the properties like behavior and spinner behavior. [Learn more](#properties). +5. The **Data** tab contains the fields serving as **Input Fields** for the API. +6. The **Events** tab contains the events that can be configured to trigger any action. [Learn more](#events). + +## Properties + +| **Property** | **Description** | +| --- | --- | +| **Behavior** || +| Update data on input change | If checked, the component will be triggered automatically on the change of input data (as mentioned in the data tab) for the variable. | +| Request data on page load | If checked, 'Page' variable will be triggered on page load while 'Application' variable will be triggered on application load. | +| In Flight Behavior | This property determines the behavior when a call is fired through the variable with the previous call still pending. Variable queues all these calls, waits for the previous call completion and then based on the value of the `inFlightBehavior` property, decides what to do with all the queued calls: - doNotExecute - all the queued calls will be discarded, - executeAll - all the calls will be triggered one by one, or - executeLast - only the last call is triggered and the rest are discarded, this is the default behavior| +| **Spinner** | +| Spinner Context | This property specifies on which UI widget the spinner should show. Leave empty if no spinner required. | +| Spinner Message | The message to be displayed below the spinner. Leave empty if no message is required below the spinner. Note: If multiple variables are fired then the spinner messages will be displayed as a list below a single spinner. | + +## Events + +During the life cycle of a Variable, a set of events are emitted by the Variable, thus giving you the option to control the behavior of the Variable such as input data validations, data processing, success/error handling, and more. + +- OnBeforeUpdate +- OnResult +- OnError +- OnBeforeDatasetReady +- OnCanUpdate +- OnSuccess + +To learn how to implement Events, see [Events Documentation](/learn/app-development/variables/events). + +## Methods + +Few Methods are exposed for Variables which can be used for achieving more control and accessing extra functionality. Listed here are the same. + +## `invoke()` + +This method updates the Variable’s dataSet with new data by making a call to the target service. There are four ways to call this method. + +#### `list.invoke()` +#### `create.invoke()` +#### `update.invoke()` +#### `delete.invoke()` + + +#### Parameters + +**options** (object) - It can have fields as: + +- `inputFields` (key-value pair of inputData) +- **success** (callback) +- **error** (callback) + +#### Return Value +none + +#### Example + +```js +var sv = Page.Variables.[variable_name]; + sv.list.invoke({ + "inputFields": { + "fname": "Steve", + "lname": "Rogers" + } + }, function(data) { + // Success Callback + console.log("success", data); + }, function(error) { + // Error Callback + console.log("error", error) + }); + +var sv = Page.Variables.[variable_name]; +sv.create.invoke(); + +var sv = Page.Variables.[variable_name]; +sv.update.invoke(); + +var sv = Page.Variables.[variable_name]; +sv.delete.invoke(); +``` + +## `setInput(key, value)` + +This method sets the input field value against the specified field(key) for the specified operation(list, create, update or delete) based on how we call it. There are four ways to call a setInput method. + +#### `list.setInput(key, value)` +#### `create.setInput(key, value)` +#### `update.setInput(key, value)` +#### `delete.setInput(key, value)` + +#### Parameters + +- **key**(string): name of the input field +- **value**(*): value for the input field + +#### Return Value +- Updated `inputFields` object + +#### Example + +```js +var sv = Page.Variables.[variable_name]; + sv.list.setInput("page", 1); + sv.list.setInput("size", 50); + sv.list.invoke(); + +var sv = Page.Variables.[variable_name]; + sv.create.setInput("Employee", { + "firstName": "John", + "lastName": "Doe" + }); + sv.create.invoke(); + +var sv = Page.Variables.[variable_name]; + sv.update.setInput("Employee", { + "firstName": "John", + "lastName": "Doe" + }); + sv.update.setInput("empId", 50); + sv.update.invoke(); +var sv = Page.Variables.[variable_name]; + sv.delete.setInput("empId", 50); + sv.delete.invoke(); + ``` + +## `setInput(object)` + +This method can also be used to set all the specified key-value pairs as input fields in the variable for a particular operation(list, create, update or delete) based on how we call it. There are four ways to call a setInput method. + +#### `list.setInput(object)` +#### `create.setInput(object)` +#### `update.setInput(object)` +#### `delete.setInput(object)` + +#### Parameters +- **Object**: key-value pairs {“key”: “value”,…} + +#### Return Value +- Updated `inputFields` object + +#### Example + +```js +var sv = Page.Variables.[variable_name]; + sv.list.setInput({ + "page": 1, + "size": 50 + }); + sv.list.invoke(); + + + +var sv = Page.Variables.[variable_name]; + sv.create.setInput({ + "Employee": { + "firstName": "John", + "lastName": "Doe" + } + }); + sv.create.invoke(); + + +var sv = Page.Variables.[variable_name]; + sv.update.setInput({ + "Employee": { + "firstName": "John", + "lastName": "Doe" + }, + "empId": 50 + }); + sv.update.invoke(); + + +var sv = Page.Variables.[variable_name]; + sv.delete.setInput({ + "empId": 50 + }); + sv.delete.invoke(); + ``` \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/custom-formatter.md b/website/versioned_docs/version-v11.8.5/app-development/variables/custom-formatter.md new file mode 100644 index 000000000..e0ee4890c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/custom-formatter.md @@ -0,0 +1,77 @@ +--- +title: "Custom Formatter" +id: "custom-formatter" +sidebar_label: "Custom Formatter" +--- +With Custom Formatter, customize data more specific to your audience. + +--- +WaveMaker provides a few default formatters like `numberToString` and `stringToNumber`, `prefix` and `suffix`, `timeFromNow`, `toCurrency` and `toDate`. These can be accessed from the **Use Expression** tab. Sometimes, when these do not meet your requirement, you can write your own custom formatters, depending on the role, phone number format with a region or country code and more. + +For example, John is a card-holder, he can view his card details without any restrictions, whereas the bank admin cannot see his card number which is masked with specific character as shown below. + +![Credit card number formatter](/learn/assets/credit-card.png) + +:::tip +To learn about the usage of this feature, see using [Custom Formatter for masking sensitive data](/learn/how-tos/using-custom-formatter). +::: + +## Accessing Custom Formatter + +You can add custom formatter from the **Use Expression** tab of the variable binding dialog. + +![Add custom formatter](/learn/assets/add-custom-formatter.png) + +## Syntax Definition + +The following is a sample custom formatter definition. For formatting custom data, you edit the `formatter.js` file. + +```js + myFormatter : { + formatter : function(data, param1, context){ + // your logic goes here + return data; + }, + config: { + param1: { + name: '', + widget: '', + value: '' + } + } + } +``` + +### `myFormatter` + +Name of the custom formatter. + +### `formatter` + +Here, you write a function containing the logic to format the data. The returned-value from this function applies to the property that this **formatter** is bound to. + +The first argument is always `data`, the rest of the arguments depend on the `config` where the user is set. The last argument will be the `context` for all iterable widgets (by default it gets passed as the last argument). + +### `config` + +Parameter information required during the design time. List down all the parameters required for your formatter function. + +Each param has the following information. + +**`name`** : Name of the parameter to display during design time. + +**`widget`** : Widget to take parameter input from the user. For example, text, select. + +If you use **Select** widget, you should provide the **options** property as the array of strings format. + +**`value`** : Set a default value that is used to mask or customize the data. + +**`context`** : If you bound the iterable modal object to a widget like List, Card, Table, Select, and Search widgets, the **context** (respective object from JSON) gets passed to the formatter function automatically. For a simple label widget, there is no context. + +:::note +WaveMaker does not support Custom Formatter for **Prefab** and **TemplateBundles**. +::: + +## See Also + +[Using Custom Formatter](/learn/how-tos/using-custom-formatter) diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/data-integration.md b/website/versioned_docs/version-v11.8.5/app-development/variables/data-integration.md new file mode 100644 index 000000000..a0e634996 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/data-integration.md @@ -0,0 +1,30 @@ +--- +title: "How to integrate service in WaveMaker?" +id: "data-integration" +sidebar_label: "How to integrate service in WaveMaker?" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) section for WaveMaker app development. + +--- + +The **binding layer** provides a _low-code approach_ to defining data flows, interaction, and integration of UI elements with the backend services. + +A major portion of the application’s code parts are auto-generated by the platform, leaving the business logic, rules and data flows to be coded by the WaveMaker App developers. UI layer is built such that, decisions to fetch or update the data to the backend services are made when the end-user interacts with widgets or other UI elements. Additionally, business logic functions either on the server-side or on the client-side are invoked at that time. + +[![](/learn/assets/binding_layer.png)](/learn/assets/binding_layer.png) + +This functionality is achieved through the Binding layer, using the following components. + +| To | See | +|---|---| +|Learn how to control, manage and synchronize data from any service type |[Variables](/learn/app-development/variables/variables)| +|Learn how to fetch data from the backend services|[Binding](/learn/app-development/variables/variable-binding)| +|Learn invoking a backend API, Database CRUD operation or navigation |[Actions](/learn/app-development/variables/variables-actions)| +|Learn controlling the behavior of the Variable such as input data validations, data processing, success/error handling|[Events](/learn/app-development/variables/events)| + + + + + + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/database-apis.md b/website/versioned_docs/version-v11.8.5/app-development/variables/database-apis.md new file mode 100644 index 000000000..03331a8f3 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/database-apis.md @@ -0,0 +1,228 @@ +--- +title: "Variable for Database APIs" +id: "database-apis" +sidebar_label: "Database APIs" +--- +--- + +For every database table imported into the app, APIs are generated. In addition to the CRUD operations, functionalities like Count, Filter, Get by field name, Get associated table data etc. can be accessed through the corresponding APIs. These Database APIs also include those corresponding to Queries and Procedures created within the data model. + +Variable can be created using these **Database APIs**. + +The operations include, a comprehensive list can be found from the [API Designer](/learn/assets/API_Access.png) after the import of the database: +- **Get** +- **Count** +- **Export** +- **Filter** +- **FindAssociated** in case of related tables + +Any REST APIs generated when [Queries](/learn/app-development/services/database-services/working-with-queries) and [Procedure Calls](http://[supsystic-show-popup id=118]) are saved. + +:::note +Since the queries/procedure needs to be executed to fetch the data, the widgets bound to these variables will display values only at run-time, not in Studio mode. +::: + +## Variable Creation + +The **data source** for these Variables comes from a _Database APIs_. There are two ways of creating variables: + +1. from [variable workspace toolbar](#variable-creation-direct-method) +2. at the time of [binding data and live widgets](#variable-creation-from-data-live-widgets); + +### Variable Creation - direct method + +1. Select Variable option from the Variables Workspace Toolbar. + +[![](/learn/assets/var_sel.png)](/learn/assets/var_sel.png) +2. Click New Variable from the Variable Dialog + +[![](/learn/assets/var_new.png?v=20)](/learn/assets/var_new.png?v=20) + +3. This will initiate Create Variable wizard with the following steps: + + 1. Since we are creating a variable to access database API operations, select **Database API** as the target operation + 2. Select: + - **Database** - database (already imported) name, + - **API Type** - choose between table, query or procedure API + - **Table/Query/Procedure** - choose the corresponding table, query or procedure. In the case of Table, you have to further select the specific API. + - **Name** - is set by default but can be modified + - **Owner** - the scope of the Variable being created. By default it is set to Page, you can change it to Application if you want this variable to be available across the app + 3. Click **Done** to complete the variable creation process + + [![](/learn/assets/dbapi_varcr_direct.png)](/learn/assets/dbapi_varcr_direct.png) + +4. You will be directed to the Variables page, with the new variable listed. +[![](/learn/assets/dbapi_varcr_direct_var.png)](/learn/assets/dbapi_varcr_direct_var.png) +As you can see: + 1. a **Database API** Variable is created, + 2. with the selected API/query/procedure as target + 3. the **properties tab** contains all the properties like _server options_, _behavior_ and _spinner_ behavior. [Know more about properties](#properties). + 4. the **data tab** will contain the fields serving as _input fields_ for the API + 5. the **events** tab will contain the events that can be configured to trigger any action. [Know more about events](#events). + +### Variable Creation - from Data & Live Widgets + +We will show the steps in creating Variable using the Data Table widget. The steps will be same for any Data Widgets + +1. Drag and drop a **Data Table** onto the canvas +2. Set **Retrieve Data** from _Service_ + +:::note +If you have not imported any database or web service in your application, you will be prompted to import the same. +::: + +3. Once you have imported the data source, choose _Database API _from the list of **service type** +4. Set the **service** to the desired _database_ and then select an **Operation/Type** from the list of APIs for tables within the selected database or query/procedure name. + +[![](/learn/assets/dbapi_varcr_dt.png)](/learn/assets/dbapi_varcr_dt.png) + +5. Once you have selected the service type and the service you can change the **name of the variable** generated. + +**Data Configuration** includes: + - You also have the option choose a particular data node. + - **Records per request** to be fetched, default set to 20 + - **Update data on input change** will ensure that the data content of the variable is refreshed when the value of the input parameter changes + - **Request data on page load** will ensure that the data is fetched when the page rendering the variable data is loaded + +6. This will be followed by steps to select the Data Table layout and columns to be displayed. +7. You can see the variable listed Variables dialog. As you can see: + - a **Database API** Variable for selected operation is created, + - which is a **page scoped variable,** + - with the selected database and API as target + - the **properties tab** contains all the properties like _server options_, _behavior_ and _spinner_ behavior. (Click on the Variable to view the Variable definition). [Know more about properties](#properties). + - the **data tab** will contain the fields serving as _filter fields_ for data fetch operation + - The **events** tab will contain the events that can be configured to trigger any action. [Know more about events](#events). + +## Properties + +**Server Options** Available only for Query APIs + +| **Property** | **Description** | +| --- | --- | +| **Records per request** (Available only for Query APIs) | This property sets the number of records to be fetched at runtime. It can be set to a value with 100 being maximum allowed value. 0 is invalid and entering the same will reset it to the default value. The default value is 20. In the Development profile, the maximum limit is set to 100 records for optimized performance. For Deployment profile, you can change this limit by changing the change the "Records per Request" for the Database from the Config Profiles for Deployment Profile. | +| **Order by** (Available only for Query APIs) | Property to use for ordering the data. Sorting can be in ascending or descending order. By default, it is set to the Primary Key Field ascending order. You can add more fields, or delete this setting. **Usage**: You can select the fields to which you want the data to be ordered from a drop-down list and click on + to add new order by field. By default, the order is set to descending which can be changed by a simple click operation. | +| **Behavior** || +| Update data on input change | If checked, the component will be triggered automatically on the change of input data (as mentioned in the data tab) for the variable. | +| **Request data on page load** | If checked, 'Page' variable will be triggered on page load while 'Application' variable will be triggered on application load. | +| **In Flight Behavior** | This property determines the behavior when a call is fired through the variable with the previous call still pending. Variable queues all these calls, waits for the previous call completion and then based on the value of the `inFlightBehavior` property, decides what to do with all the queued calls: - **doNotExecute** - all the queued calls will be discarded, - **executeAll** - all the calls will be triggered one by one, or - **executeLast** - only the last call is triggered and the rest are discarded, this is the default behavior | +| **Spinner** | +| **Spinner Context** | This property specifies on which UI widget the spinner should show. Leave empty if no spinner required. | +| **Spinner Message** | The message to be displayed below the spinner. Leave empty if no message is required below the spinner. Note: If multiple variables are fired then the spinner messages will be displayed as a list below a single spinner. | + +## Events + +During the life cycle of a Variable, a set of events are emitted by the Variable, thus giving you the option to control the behavior of the Variable such as input data validations, data processing, success/error handling, etc. [Know More](/learn/app-development/variables/variables-actions/#events-implementation). + +## Methods + +Few Methods are exposed for Variables which can be used for achieving more control and accessing extra functionality. Listed here are the same. + +
invokecancel
getDataclearDatasetInput
+ +### invoke() + +This method updates the Variable’s dataSet with new data by making a call to the target service. + +**Parameters**: + +- **options**(object) - It can have fields as: + - inputFields(key-value pair of inputData) + - page(pagination for Query Service Variable) + - size(pagination for Query Service Variable) + - orderBy(pagination for Query Service Variable) +- **success**(callback) +- **error**(callback) + +**Return Value**: none + +**Example**: +``` +var sv = Page.Variables.[variable_name]; + sv.invoke({ + "inputFields": { + "fname": "Steve", + "lname": "Rogers" + } + }, function(data) { + // Success Callback + console.log("success", data); + }, function(error) { + // Error Callback + console.log("error", error) + }); +``` +## cancel() + +This method aborts the current inflight variable request. + +**Parameters**: none **Return Value**: none + +**Example**: +``` +Page.Variables.[variable_name].cancel(); +``` +## getData() + +This method returns the variable’s dataSet, i.e., the current data stored in the variable through the listrecords method. + +**Parameters**: none + +**Return Value**: Array of record objects + +**Example**: +``` +var result = Page.Variables.[variable_name].getData(); +console.log("result:", result); +// Output: +// result: {data in the variable} +``` +## clearData() + +This method clears the variable dataSet. + +**Parameters**: none + +**Return Value**: Updated(empty) dataSet of the variable + +**Example**: +``` +var result = Page.Variables.[variable_name].clearData(); +console.log("result:", result); +// Output: +// result: {} +``` +## setInput(key, value) + +This method sets the input field value against the specified field(key). + +**Parameters**: + +- **key**(string): name of the input field +- **value**(*): value for the input field + +**Return Value**: Updated inputFields object + +**Example**: +``` +var sv = Page.Variables.[variable_name]; + sv.setInput("fname","Peter"); + sv.setInput("lname","Parker"); + sv.invoke(); +``` +## setInput(object) + +This method can also be used to set all the specified key-value pairs as input fields in the variable. + +**Parameters**: `inputData(object)` object or key-value pairs `{“key”: “value”,…}` + +**Return Value**: Updated inputFields object + +**Example**: +``` +var sv = Page.Variables.[variable_name]; + sv.setInput({ + "fname": "Peter", + "lname": "Parker" + }); + sv.invoke(); +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/database-crud.md b/website/versioned_docs/version-v11.8.5/app-development/variables/database-crud.md new file mode 100644 index 000000000..f6b8847c8 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/database-crud.md @@ -0,0 +1,429 @@ +--- +title: "Variable for Database CRUD" +id: "database-crud" +sidebar_label: "Database CRUD" +--- +--- + +**Database CRUD Variable** connects to an individual database entity through auto generated CRUD APIs. It contains the values from the specified database table and controls such as Live Form require a Database CRUD Variable as input. + +As the name suggests, operations include the CRUD operations on the database: + +- **Read** which can be used to fetch data from the database; +- **Insert/Update** which can be used to insert data to a database, this would require the fields from the data tab bound either to static default values or from widgets capturing and processing the input from the user. + +:::note +Any fields that are not bound will be set to NULL. If according to your use case user is prevented from updating a column value then you can uncheck the **Updatable** option for that column from the **Database Designer**. +::: + +[See here for more](/learn/app-development/services/database-services/working-database-schema/#metadata-implementation). + +- **Delete** which can be used to delete data from the database, the primary key value needs to be bound from the data tab. + +## Variable Creation + +The **data source** for these Variables comes from a _Database_. There are two ways of creating variables: + +1. from [variable workspace toolbar](#direct) +2. at the time of [binding data and live widgets](#widgets); + +## Variable Creation - direct method + +Here we list the steps to create a Variable for Database CRUD operations: + +1. Select the Variable option from the Variable Workspace Toolbar. + +[![](/learn/assets/var_sel.png)](/learn/assets/var_sel.png) + +2. Click New Variable from the Variable Dialog + +[![](/learn/assets/var_new.png?v=20)](/learn/assets/var_new.png?v=20) + +3. This will initiate the Create Variable wizard with the following steps: + + 1. Since we are creating a variable to perform database CRUD operations, select **Database CRUD** as the target operation + 2. Select: + - **Database** - database (already imported) name, + - **Table** - entity or table within the database and + - **Operation** - choose from read, insert, update or delete depending upon the purpose of the variable + - **Name** - is set by default but can be modified + - **Owner** - the scope of the Variable being created. By default it is set to Page, you can change it to Application if you want this variable to be available across the app + 3. Click **Done** to complete the variable creation process + + [![](/learn/assets/dbcrud_varcr_direct.png)](/learn/assets/dbcrud_varcr_direct.png) + +4. You will be directed to the Variables page, with the new variable listed. +[![](/learn/assets/dbcrud_varcr_direct_var.png)](/learn/assets/dbcrud_varcr_direct_var.png) +As you can see: + 1. a **Database CRUD** Variable for selected operation is created, + 2. with the selected database and table as target + 3. the **Properties tab** contains all the properties like _server options_, _behavior_ and _spinner_ behavior. + 4. the **Data tab** will contain the fields for which the values can be set/bound for Insert, Delete and Update operations. Note for Update operation all the fields need to be set irrespective of whether they are to be updated or not + 5. (for READ operation) the **Filter Criteria tab** will contain the fields serving as _filter fields_ for data fetch operation. [Know more about Filter Criteria usage](/learn/how-tos/using-filter-criteria-database-crud-variable/). + 6. the **Events** tab will contain the events that can be configured to trigger any action. [Know more about events](#events). + +## Variable Creation - from Data & Live Widgets + +We will show the steps in creating Variable using the Data Table widget. The steps will be same for any Data Widgets + +1. Drag and drop a **Data Table** onto the canvas +2. Set **Retrieve Data** from _Service_ + +:::note +If you have not imported any database or web service in your application, you will be prompted to import the same. +::: + +3. Once you have imported the data source, choose _Database CRUD_ from the list of **service type** +4. Set the **service** to the desired _database_ and then select a **Table/Entity** from the list of entities of tables within the selected database. [![](/learn/assets/dbcrud_varcr_dt.png)](/learn/assets/dbcrud_varcr_dt.png) +5. Once you have selected the service type and the service you can change the **name of the variable** generated. + +**Data Configuration** includes: + - You also have the option choose a particular data node. + - **Records per request** to be fetched, default set to 20 + - **Update data on input change** will ensure that the data content of the variable is refreshed when the value of the input parameter changes + - **Request data on page load** will ensure that the data is fetched when the page rendering the variable data is loaded. + +6. This will be followed by steps to select the Data Table layout and columns to be displayed. +7. You can see the variable listed Variables dialog + +[![](/learn/assets/dbcrud_varcr_dt_var.png)](/learn/assets/dbcrud_varcr_dt_var.png) + +As you can see: +1. a **Database CRUD** Variable for Read operation is created, +2. which is a **page scoped variable,** +3. with the selected database and table as target +4. the **properties tab** contains all the properties like _server options_, _behavior_ and _spinner_ behavior. (Click on the Variable to view the Variable definition). [Know more about properties](#properties). +5. the **filter criteria tab** will contain the fields serving as _filter fields_ for data fetch operation +6. The **events** tab will contain the events that can be configured to trigger any action. [Know more about events](#events). + +## Properties +--- +Variables created for Database CRUD are special variables that store the results of a database that was created or imported into the WaveMaker App. + +| **Property** | **Description** | +| --- | --- | +| **Server Options** | +| **Match Mode** | This property specifies how to apply the filter on fields under the Data tab. The options are: - **start**: match characters at the front of the string. For example, "Wa" would match "WaveMaker". - **end**: match characters at the end of the string. For example, "Maker" would match "WaveMaker". - **anywhere**: match characters anywhere in the string. For example, "ve" would match "WaveMaker". - **exact**: match all characters the string. For example, only "WaveMaker" would match "WaveMaker".| +| **Records per request** | This property sets the number of records to be fetched at runtime. It can be set to a value with 100 being maximum allowed value. 0 is invalid and entering the same will reset it to the default value. The default value is 20. In the Development profile, the maximum limit is set to 100 records for optimized performance. For Deployment profile, you can change this limit by changing the change the “Records per Request” for the Database from the Config Profiles for Deployment Profile. | +| **Design Max. Results** | The number of records that are returned when viewing data at design time. | +| **Order by** | Property to use for ordering the data. Sorting can be in ascending or descending order. By default, it is set to the Primary Key Field ascending order. You can add more fields, or delete this setting. **Usage**: You can select the fields to which you want the data to be ordered from a drop-down list and click on + to add new order by field. By default, the order is set to descending which can be changed by a simple click operation. | +| **Ignore Case** | If checked, the filter will ignore case. For example, "wa" will match "WaveMaker". | +| **Behavior** | +| **Update data on input change** | If checked, the component will be triggered automatically on the change of input data (as mentioned in the data tab) for the variable. | +| **Request data on page load** | If checked, 'Page' variable will be triggered on page load while 'Application' variable will be triggered on application load. | +| **In Flight Behavior** | This property determines the behavior when a call is fired through the variable with the previous call still pending. Variable queues all these calls, waits for the previous call completion and then based on the value of the _inFlightBehavior_ property, decides what to do with all the queued calls: - `doNotExecute` - all the queued calls will be discarded, - `executeAll` - all the calls will be triggered one by one, or - `executeLast` - only the last call is triggered and the rest are discarded, this is the default behavior | +| **Spinner** | +| **Spinner Context** | This property specifies the UI widget on which the spinner should show. Leave empty if no spinner required. | +| **Spinner Message** | The message to be displayed below the spinner. Leave empty if no message is required below the spinner. Note: If multiple variables are fired then the spinner messages will be displayed as a list below a single spinner. | + +## Events + +During the life cycle of a Variable, a set of events are emitted by the Variable, thus giving you the option to control the behavior of the Variable such as input data validations, data processing, success/error handling, etc. [Know More](/learn/app-development/variables/variables-actions/#events-implementation). + +## Methods + +Few Methods are exposed for Variables which can be used for achieving more control and accessing extra functionality. Listed here are the same. + +
listRecordscreateRecordupdateRecorddeleteRecord
getDataclearDatasetInputsetFilter
+ +### listRecords(options, successCallback, errorCallback) + +This method updates the Variable’s dataSet with new data by making a call to the Live DB Service. This is an asynchronous method that fetches data from target Live DB Service and updates it on the dataSet of the variable. The data can be accessed through the successCallback method. Error handling can be done in the errorCallback method. + +**Parameters**: + +- **options**(object): The object can have fields as `filterFields` - `key-value` pairs of fields for filtering read calls as `{“key”: “value”}` +- **successCallback**(method): callback method called on successful invocation of the variable. +- **errorCallback**(method): callback method called if an error is encountered while invocation. + +**Return Value**: None + +**Example**: +``` +var lv = Page.Variables.HrdbEmployeeData; +// Example 1: Get all data for Employees table +lv.listRecords({}, function(data) { + // Success Callback + console.log('success', data) + }, function(error) { + // Error Callback + console.error('error', error) +}); + +var lv = Page.Variables.HrdbEmployeeData; +// Example 2: Set custom page and size +lv.listRecords({ + "page": 2, + "pagesize": 5 + }, function(data) { + // Success Callback + console.log('success', data) + }, function(error) { + // Error Callback + console.error('error', error) + }); + +var lv = Page.Variables.HrdbEmployeeData; +// Example 3: Get data filtered on the table fields +lv.listRecords({ + filterFields: { + "city": { + "value": "New York" + } + } + }, function(data) { + // Success Callback + console.log('success', data) + }, function(error) { + // Error Callback + console.error('error', error) + }); +``` +We can also specify the filterFields and orderBy options while invoking the variable. In the below example, the variable will get all the records satisfying the condition deptId==1 & empId>1, and also with the specified sort order. Please refer the [Filter Conditions doc](/learn/how-tos/using-filter-conditions-variable) for the list of available matchModes. + +**Example**: + +``` +lv.listRecords({ + filterFields: { + "deptId": { + "value": 1, + "matchMode": "EQUALS" + }, + "empId": { + "value": 1, + "matchMode": "GREATER_THAN" + } + }, + orderBy: "empId desc, firstname desc" + }); + +``` +### updateRecord(object, success callback, error callback) + +This method makes a call to the Live Service to update the provided record in the target table. This is an asynchronous method that updates the record into the target table and updates it on the dataSet of the variable. The updated record is passed and can be accessed in the successCallback method as a parameter named "data". Error handling can be done in the errorCallback method. + +**Parameters**: + +- **options**(object): This object can have fields as a row - record object as `{"field": "value"}`. Complete record object should be passed along with the primary key. +- **successCallback**(method): callback method called on successful invocation of the variable. +- **errorCallback**(method): callback method called if an error is encountered while invocation. + +**Return Value**: None + +**Example**: +``` +var lv = Page.Variables.HrdbEmployeeData; + // Example 1: Update a record + lv.updateRecord({ + row: { + "empId": 11, + "firstname": "Steve", + "lastname": "Rogers", + "username": "captain.steve" + } + }, function(data) { + // Success Callback + console.log("successfully updated employee", data); + }, function(error) { + // Error Callback + console.error("error while updating employee", error) + }); +``` + +### createRecord(object, successCallback, errorCallback) + +This method makes a call to the Live Service to insert a new record into the target table. This is an asynchronous method that inserts the record into the target table and updates it on the dataSet of the variable. The newly created record can be accessed in the successCallback method. Error handling can be done in the errorCallback method. + +**Parameters**: + +- **options**(object): This object can have fields as row - record object as `{"field": "value",..}` +- **successCallback**(method): callback method called on successful invocation of the variable. +- **errorCallback**(method): callback method called if an error is encountered while invocation. + +**Return Value**: None + +**Example**: +``` +var lv = Page.Variables.HrdbEmployeeData; +// Example 1: Insert a record into Employee table +lv.createRecord({ + row: { + 'firstname': "Steve", + 'lastname': "Rogers", + "username": "steve.rogers" + } +}, function(data) { + // Success Callback + console.log("Successfully inserted employee:", data); + // Output: + // Successfully inserted employee: {empId: 11, firstname: “Steve”,...} +}, function(error) { + // Error Callback + console.error("error while inserting employee", error) +}); +``` +### updateRecord(object, success callback, error callback) + +This method makes a call to the Live Service to update the provided record in the target table. This is an asynchronous method that updates the record into the target table and updates it on the dataSet of the variable. The updated record is passed and can be accessed in the successCallback method as a parameter named "data". Error handling can be done in the errorCallback method. + +**Parameters**: + +- **options**(object): This object can have fields as a row - record object as `{"field": "value"}`. Complete record object should be passed along with the primary key. +- **successCallback**(method): callback method called on successful invocation of the variable. +- **errorCallback**(method): callback method called if an error is encountered while invocation. + +**Return Value**: None + +**Example**: +``` +var lv = Page.Variables.HrdbEmployeeData; +// Example 1: Update a record +lv.updateRecord({ + row: { + "empId": 11, + "firstname": "Steve", + "lastname": "Rogers", + "username": "captain.steve" + } +}, function(data) { + // Success Callback + console.log("successfully updated employee", data); +}, function(error) { + // Error Callback + console.error("error while updating employee", error) +}); +``` +### deleteRecord(options, successCallback, errorCallback) + +This method makes a call to the Live Service to delete the passed record in the target table. This is an asynchronous method that fetches data from target service and updates it on the dataSet of the variable. The data can be accessed in the successCallback method. Error handling can be done in the errorCallback method. + +**Parameters**: + +- **options**(object): This object can have optional fields as row - record object to be deleted as {"key":"value"} +- **successCallback**(method): callback method called on successful invocation of the variable. +- **errorCallback**(method): callback method called if an error is encountered while invocation. + +**Return Value**: None + +**Example**: +``` +var lv = Page.Variables.HrdbEmployeeData; +// delete a record +lv.deleteRecord({ + row: { + "empId": 11 // primary key + } + }, function(success) { + // Success Callback + console.log("successfully deleted employee (boolean)", success); + }, function(error) { + // Error Callback + console.error("error while deleting employee", error) +}); +``` + +### getData() + +This method returns the variable’s dataSet, i.e., the current data stored in the variable through the listrecords method. + +**Parameters**: none + +**Return Value**: Array of record objects + +**Example**: + +``` +var result = Page.Variables.HrdbEmployeeData.getData(); + console.log("result", result); + // Output: + result: [Object, Object, Object], // data in the table +``` + +### clearData() + +This method clears the variable dataSet. + +**Parameters**: none + +**Return Value**: Updated(empty) dataSet of the variable + +**Example**: +``` +var result = Page.Variables.HrdbEmployeeData.clearData(); +console.log("result:", result); +// Output: +// result: {} +``` +### setInput(key, value) + +This method sets the input field value against the specified field(key). + +**Parameters**: + +- **key**(string): name of the input field +- **value**(*): value for the input field + +**Return Value**: Updated inputFields object + +**Example**: +``` +var lv = Page.Variables.HrdbEmployeeData; + lv.setInput("firstname", "Tony"); + lv.setInput("lastname", "Stark"); + lv.createRecord(); +``` +### setInput(object) + +This method can also be used to set all the specified key-value pairs as input fields in the variable. + +**Parameters**: inputData(object) object or key-value pairs {“key”: “value”,…} + +**Return Value**: Updated inputFields object + +**Example**: +``` +var lv = Page.Variables.HrdbEmployeeData; + lv.setInput({ + "firstname": "Peter", + "lastname": "Parker" + }); + lv.createRecord(); +``` + +### setFilter(key, value) + +This method sets the filter field value against the specified field(key) + +**Parameters**: + +- key(string): name of the input field +- value(*): value for the input field + +**Return Value**: Updated filterFields object + +**Example**: +``` +var lv = Page.Variables.HrdbEmployeeData; + lv.setFilter("department.name", "Engineering"); // department is a related table + lv.setFilter("city", "New York"); + lv.listRecords(); +``` + +### setFilter(object) + +This method can also be used to set all the specified key-value pairs as filter fields in the variable. + +**Parameters**: inputData(object) object or key-value pairs {“key”: “value”,…} + +**Return Value**: Updated filterFields object + +**Example**: +``` +var lv = Page.Variables.HrdbEmployeeData; + lv.setFilter({ + "deptId": 1, // deptId is the foreign key reference to department table + "city": "New York" + }); + lv.listRecords(); +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/device-variables.md b/website/versioned_docs/version-v11.8.5/app-development/variables/device-variables.md new file mode 100644 index 000000000..c4aaa5557 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/device-variables.md @@ -0,0 +1,265 @@ +--- +title: "Device Variables" +id: "device-variables" +--- + +**Device Variables** are specific to Mobile App projects. These are useful in performing operations specific to a Mobile Device like taking a picture and getting its path, select a contact, add events to a calendar, etc. + +[![](/learn/assets/var_sel_mobile.png)](/learn/assets/var_sel_mobile.png) + +[![](/learn/assets/var_new_mobile.png)](/learn/assets/var_new_mobile.png) + +# Services + +**Service** specifies the target service to be used. Each service is targeted to perform a set of operations for a feature. Available services are: + +- **Calendar** – you can use this service to add, remove and list events in your phone calendar. The event details would include title, notes, location, start and end times. +- **Camera** – you can use this to capture an image or a video +- **Contacts** – you can use this variable to list the contacts on your phone. You can apply a filter on the list retrieved. +- **Datasync **- you can use this service to sync data +- **Device** – you can use this service to handle your mobile device features like vibrate, get connection type, model, OS, OS version etc. +- **File** – you can upload files to your mobile device +- **Scan** – can be used to access the barcode scanner. + +# Operations + +Based upon the service selected various operations are available. + +

Calendar Service Operations

createEventdeleteEventgetEvents

Camera Service Operations

captureImagecaptureVideo

Contacts Service Operations

getContacts

Datasync Service Operations

exportDBgetOfflineChangesimportDB
PullPush
lastPullInfolastPushInfo

Device Service Operations

getAppInfogetCurrentGeoPositiongetDeviceInfo
getNetworkInfovibrate
goOnlinegoOffline

File Service Operations

uploadOpenFile

Scan Service Operations

scanBarCode
+ +## Calendar Service Operations + +**createEvent**: Creates calendar event in device + +| **Input Parameter** (from Data Tab) | **Description** | **Sample** | +| --- | --- | --- | +| Event Title | specifies the event title | ‘Space Race’ | +| Event Notes | represents notes related to the event | ‘Bring Sandwiches’ | +| Event Location | specifies the event location | ‘The Moon’ | +| Event Start | specifies the start date and time of the event | 2016-09-20 10:35:38 AM (select value from date time input) | +| Event End | specifies the end date and time  of the event | 2016-09-25 08:35:38 PM (select value from date time input) | + +**deleteEvent**: Deletes the calendar event in device satisfying the provided input, any combination of the below-mentioned parameters + +| **Filter Parameter** (from Data Tab) | **Description** | **Sample** | +| --- | --- | --- | +| Event Title | specifies the event title | ‘Space Race’ | +| Event Notes | represents notes related to the event | ‘Bring Sandwiches’ | +| Event Location | specifies the event location | ‘The Moon’ | +| Start Date | specifies the start date of the event | 2016-09-20 10:35:38 AM (select value from date time input) | +| End Date | specifies the end date of the event | 2016-09-25 08:35:38 PM (select value from date time input) | + +**getEvents**: Retrieves the calendar events in device satisfying the provided input, any combination of the below-mentioned parameters. Returns array of objects, each object containing the same fields as input parameters. + +| **Behavior** | **Description** | **Sample** | +| --- | --- | --- | +| Update data on input change | If checked, the component will be triggered automatically on the change of input data (as mentioned in the data tab) for the variable. | checked or unchecked | +| Request data on page load | If checked, 'Page' variable will be triggered on page load while 'Application' variable will be triggered on application load | checked or unchecked | +| **Filter Parameter** (from Data Tab) | **Description** | **Sample** | +| Event Title | specifies the event title | ‘Space Race’ | +| Event Notes | represents notes related to the event | ‘Bring Sandwiches’ | +| Event Location | specifies the event location | ‘The Moon’ | +| Start Date | specifies the start date of the event | 2016-09-20 10:35:38 AM (select value from date time input) | +| End Date | specifies the end date of the event | 2016-09-25 08:35:38 PM (select value from date time input) | + +## Camera Service Operations + +**captureImage**: Capture image from the device camera + +| **Input Parameter** (from Data Tab) | **Description** | **Sample** | +| --- | --- | --- | +| Allow Edit | allows simple editing of image before selection | true (default), false | +| Quality | represents the quality of saved image, expressed as a range of 0-100, where 100 is typically full resolution with no loss of file compression. The default value is 80. | 80 | +| Encoding Type | set the returned image file’s encoding. | JPEG (default) or PNG | +| Correct Orientation | Rotate the image to correct for the orientation of the device during capture. | true(default) or false | +| Target Width* | width in pixels to scale image. | 100 (only when required to get small images) | +| Target Height* | height in pixels to scale image. | 100 (only when required to get small images) | + +:::note +To get smaller images, you can return a resized image by passing both targetHeight and targetWidth values. If these values are not set, it returns the original image captured by the camera. +::: + +**captureVideo**: to capture video using the device camera + +## Contacts Service Operations + +**getContacts**: Retrieves the device contacts list + +| **Input Parameter** (from Data Tab) | **Description** | +| --- | --- | +| Filter | This string field can be used as a search filter when querying the contacts database. If provided, a case-insensitive, partial value match is applied to each field specified in the contactsFields parameter. If there is a match for any of specified fields, the contact is returned. | +| **Behavior**: | **Description** | +| Update data on input change | If checked, the component will be triggered automatically on the change of input data (as mentioned in the data tab) for the variable. | +| Request data on page load | If checked, 'Page' variable will be triggered on page load while 'Application' variable will be triggered on application load. | + +**Output**: Returns array of objects, each object containing phoneNumber and displayName fields. **Example**: Sample Input: “Bob” (contact name) Result: Retrieves all the contacts containing string “Bob” + +## DataSync Service Operations + +**exportDB**: Offline database is saved as zip in ‘Downloads’ folder in Android. In IOS, zip is stored in ‘Documents’ folder so that one can export from iPhone via iTunes. For the file to be visible in iTunes, File sharing needs to be enabled for the app in iOS preferences. + +| **Behavior** | **Description** | +| --- | --- | +| Spinner Context | When the pull process is happening, a spinner will be shown in the container that is selected. By default, no context is selected and the spinner will not be shown | +| **Output** | **Description** | +| path | Location of file | + +**getOfflineChanges**: Retrieves the changes made when offline + +| **Output** | **Description** | +| --- | --- | +| total | number of changes while offline | +| pendingToSync | changes pending sync | +| failedToSync | changes for which sync failed | + +**importDB**: Upon invocation, a file browser opens up to choose the zip file to import. + +| **Behavior** | **Description** | +| --- | --- | +| Spinner Context | When the pull process is happening, a spinner will be shown in the container that is selected. By default, no context is selected and the spinner will not be shown | + +**Pull**: Pull changes from the server to the device + +| **Behavior** | **Description** | +| --- | --- | +| Clear offline data before pull | If checked, then the whole offline data (other than BUNDLED data) will be deleted before the pull. The default is true (checked). | +| Show Progress | When the pull process is happening, a progress bar will be shown. By default, the progress bar will not be shown. | +| **Output** | **Description** | +| totalTaskCount | number of entities data to pull | +| completedTaskCount | the number of entities data has been pulled so far. | +| inProgress | true when data pull process is going on, otherwise false | + +**Push**: Push changes to the server from the device + +| **Behavior** | **Description** | +| --- | --- | +| Show Progress | When the pull process is happening, a progress bar will be shown. By default, the progress bar will not be shown. | +| **Output** | **Description** | +| successfulTaskCount | Number of tasks/changes that were successfully pushed to the server. | +| failedTaskCount |  Number of changes that failed. | +| completedTaskCount | Number of completed tasks (both successful and failed). | +| totalTaskCount | The total number of local changes that need to be pushed to the server. | +| inProgress |  true only when data push process is going on, otherwise false. | + +**lastPullInfo**: to get the last pull details + +| **Behavior** | **Description** | +| --- | --- | +| Spinner Context | When the pull process is happening, a spinner will be shown in the container that is selected. By default, no context is selected and spinner will not be shown | +| **Output** | **Description** | +| entities | list of entity names and number of records pulled per entity | +| databases | list of database names, list of entities within the database, and the number of records pulled per database. | +| totalPulledRecordCount | The total number of records in the last pull. | +| startTime | Start time of pull operation. | +| endTime | End time of pull operation. | + +**lastPushInfo**: to get the last push details + +| **Behavior** | **Description** | +| --- | --- | +| Show Progress | When the pull process is happening, a progress bar will be shown. By default, progress bar will not be shown. | +| **Output** | **Description** | +| successfulTaskCount | Number of successful tasks (changes synced to server) | +| failedTaskCount | Number of failed tasks | +| completedTaskCount | Number of completed tasks includes tasks which were successful and failed. | +| totalTaskCount | Number of total tasks includes tasks completed and pending | +| startTime | Start time of push operation. | +| endTime | End time of push operation. | + +## Device Service Operations + +**getAppInfo**: Returns the version number of the app + +**getCurrentGeoPosition**: Returns the current location of the app + +| **Input Parameter** (from Data Tab) | **Description** | **Sample** | +| --- | --- | --- | +| Enable High Accuracy | provides a hint that the application needs the best possible results. By default, the device attempts to retrieve a ‘Position’ using network-based methods. Setting this property to true tells the framework to use more accurate methods, such as satellite positioning. | true (default), false | +| Maximum Age | specifies to accept a cached position whose age is no greater than the specified time in milliseconds. | any number, the default is 3 | +| Timeout | represents the maximum length of time (milliseconds) that is allowed to pass from the call to navigator.geolocation.getCurrentPosition until the corresponding geolocationSuccess callback executes. If geolocationSuccess callback is not invoked within this time, geolocationError callback passes a PositionError.TIMEOUT error code. | any number, the default is 5 | + +**getDeviceInfo**: Returns the followingdevice information + +| **Output** | **Description** | +| --- | --- | +| _deviceModel_ | name of the device’s model or product. The value is set by the device manufacturer and may be different across versions of the same product. | +| _OS_ | the device’s operating system name. | +| _OSversion_ | the operation system version. | +| _deviceUUID_ | the device’s Universally Unique Identifier (UUID) | + +**getNetworkInfo**: Provides information whether device has internet connection + +| **Output** | **Description** | +| --- | --- | +| _connectionType_ | determines the device’s connection type, eg: WIFI, ethernet | +| _isOffline_ | checks if phone network is offline | +| _isOnline_ | checks if phone network  is online | +| _isConnecting_ | checks if the app is trying to connect to backend service | +| _isNetworkAvailable_ | checks if network connection is available | + +**vibrate**: Vibrates the device programmatically + +| **_Input_ (from data tab)** | **Description** | +| --- | --- | +| _Vibration Time_ | seconds to vibrate the device. Default value is 2. | + +**goOffline**: Used to turn the mobile app to offline mode by blocking all network calls. + +**goOnline**: Used to turn the mobile app to online mode by blocking trying to connect to the backend server. + +## File Service Operations + +**OpenFile**: Opens files like pdf, document, excel and powerpoint. Note: A file can be opened if corresponding application is available on the mobile device. For example, a pdf file requires acrobat reader or another file that can open the pdf. When a remote file has to be opened for the first time, the file is downloaded. On subsequent calls to open the same file, the earlier downloaded file is just opened. + +| **Input Parameter** (from Data Tab) | **Description** | **Sample** | +| --- | --- | --- | +| _FileType_ | A string value that denotes the type of file to open. | The default value is pdf. Values can be pdf, doc, xls, ppt. | +| _FilePath_ | A string value that denotes the URL of the file. | http://www.pdf995.com/samples/pdf.pdf) | + +**upload**: Retrieves the device contacts list + +| **Input Parameter** (from Data Tab) | **Description** | +| --- | --- | +| _localFile_ | specifies the file path on the device. remoteFolder represents the folder path on the server to save the uploaded image. If empty, then images gets saved to `/wavemaker/appdata//uploads` | + +## Scan Service Operations + +**scanBarCode**: to access the barcode scanner. + +# Events + +1. **On Error**: The event is fired on the error of the device variable. +2. **On Success**: The event is fired on the success of the device variable. +3. **On Before:** This event is fired before starting the pull/push for the dataSync variable. +4. **On Progress:** This event is fired during the pull/push for the dataSync variable. + +# Methods + +## invoke(options) + +This method invokes the device variable + +_Parameters_: +``` +- **options**(object) +- success (callback) +- error (callback) +``` + +_Return Value_: None + +_Example:_ + +``` +// Example 1: Notify with default set properties +Page.Variables.myDeviceVariable.invoke(); + +// Example 2: Notify with callback handlers +Page.Variables.myDeviceVariable.invoke( + {}, + Function () { + console.log('success'); + }, function () { + console.log('error') +}); +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/events-overview.md b/website/versioned_docs/version-v11.8.5/app-development/variables/events-overview.md new file mode 100644 index 000000000..3cb513f77 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/events-overview.md @@ -0,0 +1,46 @@ +--- +title: "Events life cycle in WaveMaker" +id: "events-overview" +--- +--- + +In a typical life-cycle of Events: + +1. A user action triggers an event for the variable. +2. The event action talks to the data source via the API call. +3. The result from API call is reflected in the Data which in turn changes the user data view. + +[![var_lifecycle](/learn/assets/var_lifecycle.png)](/learn/assets/var_lifecycle.png) + +Four actions can be said to be responsible for triggering a variable life-cycle: + +- **Request data on page load** is a property that can be set for every variable. This can be used to initialize and fetch Live Variable data during page load. +- **Pagination** - Live Variable results are paginated and page size can be configured based on the app needs. +- **Events** - Widgets are updated/notified by user events like click, submit, or variable events like pre and post update, on error etc.. +- **Update data on input change** is a property which configures the ability to auto-reload Variable data, for example, if the data filter value changes dynamically from city = ‘New York’ to city = ‘Boston. + +[![var_triggers](/learn/assets/var_triggers.png)](/learn/assets/var_triggers.png) + +## Events Implementation + +During the life cycle of a Variable, a set of events are emitted by the Variable, thus giving you the option to control the behavior of the Variable such as input data validations, data processing, success/error handling, etc. + +You can set each of these events to trigger an action like Javascript, another variable, navigation or notification calls or a combination of these. + +Based on the application needs, a component can be assigned to these events like calling another Service/Live Variable, or a Call Variable for notification, or a JavaScript function for custom logic, etc. + +A typical event flow when a variable is used to update data would be: + +[![lsv_eventcycle](/learn/assets/LSV_eventcycle.png)](/learn/assets/LSV_eventcycle.png) + +:::note +The onBeforeUpdate event in the above diagram differs based upon the type of variable as explained in the table below. It is: + +- onBeforeListRecords for Database CRUD Variable with READ operation +- onBeforeUpdateRecord for Database CRUD Variable with UPDATE operation +- onBeforeInsertRecord for Database CRUD Variable with INSERT operation +- onBeforeDeleteRecord for Database CRUD Variable with DELETE operation +- onBeforeUpdate for all types of variables except Database CRUD Variable +::: + +For more information, see [Events](/learn/app-development/variables/events). \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/events.md b/website/versioned_docs/version-v11.8.5/app-development/variables/events.md new file mode 100644 index 000000000..e89a7a56e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/events.md @@ -0,0 +1,181 @@ +--- +title: "Events" +id: "events" +--- +Introducing Variable Events. Learn how it works in WaveMaker. + +--- + +During the life cycle of a Variable, a set of events are emitted by the Variable, thus giving you the option to control the behavior of the Variable such as input data validations, data processing, success/error handling, etc. + +:::note +To learn the life cycle of a variable, see [Events](/learn/app-development/variables/events-overview). +::: + +You can set each of these events to trigger an action like Javascript, another variable, navigation or notification calls or a combination of these. + +Based on the application needs, a component can be assigned to these events like calling another Service/Live Variable, or a Call Variable for notification, or a JavaScript function for custom logic, etc. + +A typical event flow when a variable is used to update data would be: + +[![lsv_eventcycle](/learn/assets/LSV_eventcycle.png)](/learn/assets/LSV_eventcycle.png) + +:::important +The onBeforeUpdate event in the above diagram differs based upon the type of variable as explained in the table below. It is: + +- onBeforeListRecords for Database CRUD Variable with READ operation +- onBeforeUpdateRecord for Database CRUD Variable with UPDATE operation +- onBeforeInsertRecord for Database CRUD Variable with INSERT operation +- onBeforeDeleteRecord for Database CRUD Variable with DELETE operation +- onBeforeUpdate for all types of variables except Database CRUD Variable +::: + +| Events | Description | +| --- | --- | +| **onCanUpdate** | This event is called as soon as the variable is ready to be triggered to hit the target service. | +| **onBeforeListRecords** (for READ operation of Database CRUD variable) | This event is called just before the variable is triggered to hit the target service. “dataFilter” contains an object based on the filter criteria set (that appear under the “Filter Criteria” tab of Variable definition dialog). Each criteria contains the following information - Field Name, Condition, and Value. You can retrieve the criteria using the following method: dataFilter.getCriteria(“field-name”) and make any changes. Allowed actions on the criteria are: - Retrieve/Validate data of a particular field. - Change the value of a particular field. | + +### Example 1: Filter +Change filter criteria as per your use case. + +``` +Page.HrdbEmployeeDataonBeforeListRecords = function(variable, dataFilter, options) { + // Validate or retrieve the data of a particular field + if (dataFilter.getCriteria("jobtitle")[0].value == "Product Manager") { + return true; + } else { + //Change value of a field + dataFilter.getCriteria("jobtitle")[0].value = "Product Manager"; + } + }; +}; +``` + +### Example 2: Stop execution + +``` +Page.HrdbEmployeeDataonBeforeListRecords = function(variable, dataFilter, options) { + // Validate or retrieve the data of a particular field + if (dataFilter.getCriteria("deptId")[0].value == 1) { + return false; + } else { + //Change value of a field + dataFilter.getCriteria("deptId")[0].value = 3; + } + }; +}; +``` +| Events | Description | +| --- | --- | +| For Database CRUD Variables | +|**onBeforeUpdateRecord** (for Update operation) **onBeforeInsertRecord** (for Insert operation) **onBeforeDeleteRecord** (for Delete operation) | These events are called just before the variable is triggered to hit the target service. “inputData” contains an object having key-value pairs of input fields (that appear under the “Data” tab of Variable definition dialog). The call to the target service from the variable can be prevented by assigning a JavaScript function to this event and returning false from this function. If input data needs modification or validation, it should be done at this place. | + +### Example 1 +Input data can be modified by simply modifying the “inputData” parameter passed to the function. Please note, calling setInput on the Variable from this event is not valid. “inputData” param should directly be modified. + +``` +Page.empInsertonBeforeInsertRecord = function(variable, inputData, options) { + // append/modify fields in the current input data + inputData.firstname = "Steve"; + inputData.lastname = "Rogers"; +}; +``` + +### Example 2 +Input data can also be modified by returning a new set of input data (object having key-value pair of input data) +``` +Page.empInsertonBeforeInsertRecord = function(variable, inputData, options) { + // return a new set of input data (old one is discarded) + var new_data = { + "firstname": "Steve", + "lastname": "Rogers" + }; + return new_data; +}; +``` + +### Example 3 +If the call to the target service is to be blocked due to any validation failure, return false +``` +Page.empInsertonBeforeInsertRecord= function(variable, inputData, options) { + // Validation Check for mandatory input fields + // example, block the call if input data does not have fields 'firstname' or 'lastname' + if (!inputData.firstname || !inputData.lastname) { + return false; + } +}; +``` + +| Events | Description | +| --- | --- | +| For all Variables |All Variables, except Database Crud Variables. | +| **onBeforeUpdate** | These events are called just before the variable is triggered to hit the target service. “inputData” contains an object having key-value pairs of input fields (that appear under the “Data” tab of Variable definition dialog). The call to the target service from the variable can be prevented by assigning a JavaScript function to this event and returning false from this function. If input data needs modification or validation, it should be done at this place. | + + +### Example 1 +Input data can be modified by simply modifying the “inputData” parameter passed to the function. Please note, calling setInput on the Variable from this event is not valid. “inputData” param should directly be modified. +``` +Page.MyJavaServiceVariableonBeforeUpdateRecord = function(variable, inputData, options) { + // append/modify fields in the current input data + inputData.firstname = "Steve"; + inputData.lastname = "Rogers"; +}; +``` + +### Example 2 +Input data can also be modified by returning a new set of input data (object having key-value pair of input data) +``` +Page.MyJavaServiceVariableonBeforeUpdate = function(variable, inputData, options) { + // return a new set of input data (old one is discarded) + var new_data = { + "firstname": "Steve", + "lastname": "Rogers" + }; + return new_data; +}; +``` + +### Example 3 +If the call to the target service is to be blocked due to any validation failure, return false +``` +Page.MyJavaServiceVariableonBeforeUpdate = function(variable, inputData, options) { + // Validation Check for mandatory input fields + // example, block the call if input data does not have fields 'firstname' or 'lastname' + if (!inputData.firstname || !inputData.lastname) { + return false; + } +}; +``` +| Events | Description | +| --- | --- | +| **onResult** | This event is triggered as soon as the variable receives a response from the target service. onResult is called whether or not there was an error generated. An additional last argument as the “operation-name” that holds the invoked operation is present for Database CRUD Variables. | +| **onBeforeDatasetReady** | This event is triggered just before the variable's dataSet property is updated with the data received from the target service (after onResult). This event handler gives you the opportunity to manipulate the data before your variable’s dataSet property is assigned this value. If you want to add rows to a Grid or List or Select, this is a good way to add in extra items into your results before your variable is set and your widget is updated. The new data can be returned from here in order to update the Variable’s dataSet. | +| **Usage Examples** | | +| | Example 1: “data” is the response received from the target service. This event gives a chance to process this data before it is assigned to the Variable’s “dataSet” property. Please note, calling setData on the Variable from this event is not valid. Modified “data” should be returned from this event. | +``` +Page.HrdbEmployeeDataonBeforeDatasetReady = function(variable, data) { + // the data has 'firstname' and 'lastname' + // add a new field 'fullname' into the data + var new_data = []; + if (data && data.length) { + data.forEach(function(datum) { + datum.fullname = datum.firstname + " " + datum.lastname; + new_data.push(datum); + }); + + return new_data; + } +}; +``` +| | | +| --- | --- | +| **onSuccess** | Allows you to trigger an action when the Variable has completed its life cycle. Any component bound to the resultant dataSet of this Variable will be updated just before this event is triggered. So, If you want to trigger another Variable which is dependent on the dataSet of this Variable, the Variable should be triggered by this event. An additional last argument as the “operation-name” that holds the invoked operation is present for Database CRUD Variables. | +| **onError** | This event is called if there is an error generated during the Service call. An additional last argument as the “operation-name” that holds the invoked operation is present for Database CRUD Variables. | + +:::note +WaveMaker supports binding multiple actions to a given event, i.e. a given event can trigger multiple actions. +::: + +## Methods + +Few Methods are exposed on Variables which can be used for achieving more control and accessing extra functionality. The methods differ based on the type of Variable, see the respective Variable document for the detailed listing. diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/integration-binding-layer.md b/website/versioned_docs/version-v11.8.5/app-development/variables/integration-binding-layer.md new file mode 100644 index 000000000..65f22e498 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/integration-binding-layer.md @@ -0,0 +1,16 @@ +--- +title: "Data Integration Architecture" +id: "integration-binding-layer" +sidebar_label: "Integration - Binding Overview" +--- +--- +A major portion of the application’s code parts are auto-generated by the platform, leaving the business logic, rules and data flows to be coded by the WaveMaker App developers. UI layer is built such that, decisions to fetch or update the data to the backend services are made when the end-user interacts with widgets or other UI elements. Additionally, business logic functions either on the server-side or on the client-side are invoked at that time. + +[![](/learn/assets/binding_layer.png)](/learn/assets/binding_layer.png) + +The **binding layer** provides a _low-code approach_ to defining data flows, interaction, and integration of UI elements with the backend services. This functionality is achieved through the Binding layer, using following components: + +1. **Variables:** Variables provide data integration for the widgets. Variables are the gateways for the users to control, manage and synchronize the data from the database/web service or any other service in the backend. +2. **Actions** assist in invoking a backend API, Database CRUD operation or navigation to another page when a UI event occurs. Events can be either user-initiated, notifications or a result of another task being performed. +3. **Binding** of these Variables to Widgets helps in capturing the data from the user or fetching data from the backend services. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/java-services.md b/website/versioned_docs/version-v11.8.5/app-development/variables/java-services.md new file mode 100644 index 000000000..5007122c5 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/java-services.md @@ -0,0 +1,177 @@ +--- +title: "Variable for Java Service" +id: "java-services" +--- +--- + +Java Services can be accessed from within your app using Variables. These variables allow one to trigger the methods within the Java Service, pass the necessary parameters to the method and access the results from the method. + +A comprehensive list of these APIs can be found from the [API Designer](/learn/assets/API_Access.png) after the import of the service. + +:::note +Since the service needs to be invoked to fetch the data, the widgets bound to these variables will display values only at run-time, not in Studio mode. +::: + +## Variable Creation + +The **data source** for these Variables comes from a _Java Service APIs_. + +1. Select the Variable option from the Variable Workspace Toolbar. + +[![](/learn/assets/var_sel.png)](/learn/assets/var_sel.png) + +2. Click New Variable from the Variable Dialog +[![](/learn/assets/var_new.png?v=20)](/learn/assets/var_new.png?v=20) + +3. This will initiate Create Variable wizard with the following steps: + 1. Since we are creating a variable to access Java Service, select **Java Service** as the target action + 2. Select: + - **Service** - service (already imported) name, + - **Method** - the method within the Java Service that you want to invoke, + - **Name** - is set by default but can be modified + - **Owner** - the scope of the Variable being created. By default it is set to Page, you can change it to Application if you want this variable to be available across the app + 3. Click **Done** to complete the variable creation process +4. You will be directed to the Variables page, with the new variable listed. As you can see: + 1. a **Java Service** Variable is created, + 2. with the selected method as target + 3. the **properties tab** contains all the properties like _behavior_ and _spinner_ behavior. [Know more about properties](#properties). + 4. the **data tab** will contain the fields serving as _input fields_ for the API + 5. the **events** tab will contain the events that can be configured to trigger any action. [Know more about events](#events). + +## Invoke as Variable Java Service + +[![](/learn/assets/Var_create.png)](/learn/assets/Var_create.png)[![](/learn/assets/JS_var_create.png)](/learn/assets/JS_var_create.png) + +For each method within the Java Service, a service variable can be generated using the appropriate option from the **Operation** property; with the **input parameters** available within the **_Data_ tab** and the **output** available as the **datavalue for binding**. You can invoke the Java Service by triggering a call to the Service Variable generated. In case you have multiple public class methods in your Java Service, you will see multiple Operation options. + +For more information on how variables work, see [Variables](/learn/app-development/variables/variables/). + +## Properties + +| **Property** | **Description** | +| --- | --- | +| **Behavior** | +| Update data on input change | If checked, the component will be triggered automatically on the change of input data (as mentioned in the data tab) for the variable. | +| Request data on page load | If checked, 'Page' variable will be triggered on page load while 'Application' variable will be triggered on application load. | +| In Flight Behavior | This property determines the behavior when a call is fired through the variable with the previous call still pending. Variable queues all these calls, waits for the previous call completion and then based on the value of the _inFlightBehavior_ property, decides what to do with all the queued calls: - doNotExecute - all the queued calls will be discarded, - executeAll - all the calls will be triggered one by one, or - executeLast - only the last call is triggered and the rest are discarded, this is the default behavior | +| **Spinner** | +| Spinner Context | This property specifies on which UI widget the spinner should show. Leave empty if no spinner required. | +| Spinner Message | The message to be displayed below the spinner. Leave empty if no message is required below the spinner. Note: If multiple variables are fired then the spinner messages will be displayed as a list below a single spinner. | + +## Events + +During the life cycle of a Variable, a set of events are emitted by the Variable, thus giving you the option to control the behavior of the Variable such as input data validations, data processing, success/error handling, etc. [Know more](/learn/app-development/variables/variables-actions/#events-implementation). + +## Methods + +Few Methods are exposed for Variables which can be used for achieving more control and accessing extra functionality. Listed here are the same. + +
invokecancel
getDataclearDatasetInput
+ +## invoke() + +This method updates the Variable’s dataSet with new data by making a call to the target service. + +**Parameters**: + +- **options**(object) - It can have fields as: + - inputFields(key-value pair of inputData) + - page(pagination for Query Service Variable) + - size(pagination for Query Service Variable) + - orderBy(pagination for Query Service Variable) +- **success**(callback) +- **error**(callback) + +**Return Value**: none + +**Example**: +``` +var sv = Page.Variables.[variable_name]; + sv.invoke({ + "inputFields": { + "fname": "Steve", + "lname": "Rogers" + } + }, function(data) { + // Success Callback + console.log("success", data); + }, function(error) { + // Error Callback + console.log("error", error) + }); +``` +## cancel() + +This method aborts the current inflight variable request. + +**Parameters**: none **Return Value**: none + +**Example**: +``` +Page.Variables.[variable_name].cancel(); +``` +## getData() + +This method returns the variable’s dataSet, i.e., the current data stored in the variable through the listrecords method. + +**Parameters**: none + +**Return Value**: Array of record objects + +**Example**: +``` +var result = Page.Variables.[variable_name].getData(); +console.log("result:", result); +// Output: +// result: {data in the variable} +``` +## clearData() + +This method clears the variable dataSet. + +**Parameters**: none + +**Return Value**: Updated(empty) dataSet of the variable + +**Example**: +``` +var result = Page.Variables.[variable_name].clearData(); +console.log("result:", result); +// Output: +// result: {} +``` +## setInput(key, value) + +This method sets the input field value against the specified field(key). + +**Parameters**: + +- **key**(string): name of the input field +- **value**(*): value for the input field + +**Return Value**: Updated inputFields object + +**Example**: +``` +var sv = Page.Variables.[variable_name]; + sv.setInput("fname","Peter"); + sv.setInput("lname","Parker"); + sv.invoke(); +``` +## setInput(object) + +This method can also be used to set all the specified key-value pairs as input fields in the variable. + +**Parameters**: inputData(object) object or key-value pairs {“key”: “value”,…} + +**Return Value**: Updated inputFields object + +**Example**: +``` +var sv = Page.Variables.[variable_name]; + sv.setInput({ + "fname": "Peter", + "lname": "Parker" + }); + sv.invoke(); +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/login-action.md b/website/versioned_docs/version-v11.8.5/app-development/variables/login-action.md new file mode 100644 index 000000000..574b1d1c2 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/login-action.md @@ -0,0 +1,62 @@ +--- +title: "Login Action" +id: "login-action" +--- +--- + +The purpose of **Login Action** is to authenticate a user at the server. A Login Action is created automatically when you [enable Security](/learn/app-development/app-security/app-security) in your application. Login Action makes a request to the server where the authentication process takes place, based on the selected Security Provider. On successful login, the user is redirected to the Landing page configured against the user role. + +You can edit the **Properties**, **Data** and **Events** of the **Login Action** from the **Actions** dialog. + +## Action Creation + +**Login Action** can be used to perform user login. + +1. To create a Login Action: + - Select the Action option from Variables on the Workspace Toolbar + +[![](/learn/assets/action_sel.png)](/learn/assets/action_sel.png) + +- and click New Action from the Actions dialog. + +[![](/learn/assets/action_new.png?v=20)](/learn/assets/action_new.png?v=20) + +2. A **New Action** wizard will open. + - Choose **Login** Type + - **Name** - set by default which can be modified + - **Owner** - the scope of the Action being created. By default it is set to Page, you can change it to Application if you want this action to be available across the app. + - You can set the **Properties** ([know more](#properties)) and **Data** fields ([know more](#data)). + - Click **Done** to create the Action. + +3. You will be directed to the Actions dialog, with the new action listed. As you can see: + - a Login Action is created, + - the properties tab contains all the properties like _behavior_ and _spinner_ behavior. [Know more about properties](#properties). + - the data tab will contain the fields serving as input fields, + - the events tab will contain the events that can be configured to trigger any action. [Know more about events](#events). + +## Properties + +| **Property** | **Description** | +| --- | --- | +| **Behavior** || +| Use default success handler | If checked, on successful login, the logged in user will be redirected to the Landing Page configured against the user role (refer to [Login Configuration](/learn/app-development/app-security/login-configuration/) under Security for more info). If a custom logic is required, uncheck this property and implement the logic under the onSuccess event of the Action. | +| Update data on input change | If checked, the component will be triggered automatically on the change of input data (as mentioned in the data tab) for the Action. | +| Request data on page load | If checked, 'Page' scoped will be triggered on page load while 'Application' scoped will be triggered on application load. | +| In Flight Behavior | This property determines the behavior when a call is fired through the action with the previous call still pending. Action queues all these calls, waits for the previous call completion and then based on the value of the _inFlightBehavior_ property, decides what to do with all the queued calls: - doNotExecute - all the queued calls will be discarded, - executeAll - all the calls will be triggered one by one, or - executeLast - only the last call is triggered and the rest are discarded, this is the default behavior | +| **Spinner** || +| Spinner Context | This property specifies on which UI widget the spinner should show. Leave empty if no spinner required. | +| Spinner Message | The message to be displayed below the spinner. Leave empty if no message is required below the spinner. Note: If multiple actions are fired then the spinner messages will be displayed as a list below a single spinner. | + +## Data + +| Data | Description | +| --- | --- | +| **Input Fields** || +| username | The username that is used to log in when security is enabled. | +| password | The password that is used to log in when security is enabled. | +| rememberme | The cookie used in the request header if it has been enabled. | + +## Events + +During the life cycle of an Action, a set of events are emitted, thus giving you the option to control the behavior such as input data validations, data processing, success/error handling, etc. [Know More](/learn/app-development/variables/variables-actions/#events-implementation) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/logout-action.md b/website/versioned_docs/version-v11.8.5/app-development/variables/logout-action.md new file mode 100644 index 000000000..b2687e9c7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/logout-action.md @@ -0,0 +1,49 @@ +--- +title: "Logout Action" +id: "logout-action" +--- +--- + +A **Logout Action** is automatically created when you [implement Security](/learn/app-development/app-security/app-security) in your application. You can edit the **Properties **and **Events** of the** Logout Action** from the **Actions **dialog. + +## Action Creation + +**Logout Action** can be used to perform user logout. + +1. To create a Logout Action: + - Select the Action option from Variables on the Workspace Toolbar + + [![](/learn/assets/action_sel.png)](/learn/assets/action_sel.png) + - and click New Action from the Actions dialog. + [![](/learn/assets/action_new.png?v=20)](/learn/assets/action_new.png?v=20) + +2. A **New Action** wizard will open. + - Choose **Logout** Type + - **Name** - set by default which can be modified + - **Owner** - the scope of the Action being created. By default it is set to Page, you can change it to Application if you want this action to be available across the app. + - Click **Done** to create the Action +3. You will be directed to the Actions dialog, with the new action listed. As you can see: + - a Logout Action is created, + - the properties tab contains all the properties like _behavior_ and _spinner_ behavior. [Know more about properties](#properties). + - the events tab will contain the events that can be configured to trigger any action. [Know more about events](#events). + +## Properties + +| **Property** | **Description** | +| --- | --- | +| **Behavior** | | +| Use default success handler | If checked, on successful logout, the user is redirected to the Home/Login page as configured. If custom logic is required, uncheck this property and implement the logic under the onSuccess event of the Action **NOTE**: If the property is checked, the configured events will not be triggered. | +| In Flight Behavior | This property determines the behavior when a call is fired through the variable with the previous call still pending. Action queues all these calls, waits for the previous call completion and then based on the value of the _inFlightBehavior_ property, decides what to do with all the queued calls: - doNotExecute - all the queued calls will be discarded, - executeAll - all the calls will be triggered one by one, or - executeLast - only the last call is triggered and the rest are discarded, this is the default behavior | +| Redirect To | Page to be displayed after logout, can be the main page or the login page | +| **Spinner** | | +| Spinner Context | This property specifies on which UI widget the spinner should show. Leave empty if no spinner required. | +| Spinner Message | The message to be displayed below the spinner. Leave empty if no message is required below the spinner. | + +:::note +If multiple actions are fired then the spinner messages will be displayed as a list below a single spinner. +::: + +## Events + +During the life cycle of a Variable, a set of events are emitted by the Variable, thus giving you the option to control the behavior of the Variable such as input data validations, data processing, success/error handling, etc. [Know More](/learn/app-development/variables/variables-actions/#events-implementation). + diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/model-variable.md b/website/versioned_docs/version-v11.8.5/app-development/variables/model-variable.md new file mode 100644 index 000000000..3cc3243f6 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/model-variable.md @@ -0,0 +1,303 @@ +--- +title: "Model Variable" +id: "model-variable" +--- +--- + +Model Variable can be used as storage model to store data on the client. + +These Variable store data on the page or at the project level. The data can be of various types: + +- Boolean value +- Date value +- Entry for name-value pairs +- Number value +- String value +- Database table object +- Service API request or response object + +Each of these types can further be in an array format by selecting the **isList** property. + +## Variable Creation + +The **data source** for these Variables is custom-defined. + +1. Select the Variable option from the Variable Workspace Toolbar. + +[![](/learn/assets/var_sel.png)](/learn/assets/var_sel.png) + +2. Click New Variable from the Variable Dialog + +[![](/learn/assets/var_new.png?v=20)](/learn/assets/var_new.png?v=20) + +3. This will initiate Create Variable wizard. + +### Steps in Variable Wizard + +1. Select **Model** as the target action +2. Select the **Type** based upon the type of data you want the Static variable to hold. +3. Based on the selection, the JSON structure will change + - for default types of  **boolean**, **number**, **string**, **date** types you will be allowed to enter the values + - for **entry** type, you can enter the name-dataValue pair + - **prebuilt variables** gives a pre-populated variable structure - these include country, days, month, and US states list + - for any **service** types selected, will give you the respective table object structure or request parameters or response format structure +4. Setting the **Is List** property will allow you to create an array structure of the type selected +5. You can choose to add values using the **text editor** instead of field editor +6. **Data tab** will let you set the values dynamically by binding it to a widget or another variable. For example, you can capture the data from a Live Form into an app-level static variable and use it in a different page +7. You will be directed to the Variables page, with the new variable listed. As you can see: + 1. a **Model** Variable is created, + 2. the **properties tab** contains all the properties. [Know more about properties](#properties). + 3. the **data tab** will contain the fields serving as _input fields_ for the Variable + +## Properties + +Static Variables help you store page or application level data. Using Static Variable you can even store data as cookies. + +| **Property** | **Description** | +| --- | --- | +| Type | Property to use to specify the data-type of the static variable. This includes live/service variables also. | +| Is List | Property to use if the data in the variable is of type array. | +| **JSON** | +| name (for Entry type) | Name of the data value in the name-datavalue pair | +| Data Value | Property to specify the value to be stored in the variable. You can use either the Field Editor or Text Editor to specify the values. | + +## Methods + +
getDatasetDataclearDatagetValuesetValue
getItemsetItemaddItemremoveItemgetCount
+ +### getData() + +This method returns the variable’s dataSet. + +**Parameters**: none + +**Return Value**: If the variable is of list type then returns an Array else it returns an Object + +**Example**: +``` +var result = Page.Variables.staticVariable1.getData(); +console.log("result:", result); + +// Output: +// result: {dataValue: “abc”} +``` + +### setData(object) + +This method sets the passed data on the dataSet property of the Variable. + +**Parameters**: Object or Array + +**Return Value**: Newly set dataSet on the variable + +**Example**: +``` +var result = Page.Variables.staticVariable1.setData({dataValue: “def”}); +console.log("result:", result); + +// Output: +// result: {dataValue: “def”} +``` +### getValue(key) + +This method returns the value against the specified key. If dataSet is an array returns the value against the specified key of the object at the specified index. + +**Parameters**: + +- key(string): +- index(number): required in case the static variable is an array + +**Return Value**: Value against the key + +**Example**: +``` +// Example 1: If variable is having dataSet as: {dataValue: “abc”} +var result = Page.Variables.staticVariable1.getValue(‘dataValue’); +console.log("result:", result); + +// Output: +// result: “abc” + +// Example 2: If variable is list type having data as: +// [{dataValue: “abc”}, {dataValue: “def”}, {dataValue: “ghi”}] +var result = Page.Variables.staticVariable1.getValue(‘dataValue’, 1); +console.log("result:", result); + +// Output: +// result: “def” +``` +### setValue(key, value) + +This method sets the value against the specified key. + +**Parameters**: + +- key(string) +- value(*) + +**Return Value**: Updated dataSet of variable + +**Example**: +``` +// Example1: If variable is having dataSet as: {dataValue: “abc”} +var result = Page.Variables.staticVariable1.setValue(‘dataValue’, “def”); +console.log("result:", result); + +// Output: +// result: {dataValue: “def”} + +// Example 2: using key parameter. If variable is list type having data as: +// [{dataValue: “abc”}, {dataValue: “def”}, {dataValue: “ghi”}] +var result = Page.Variables.staticVariable1.setValue('key’, “ghi”); +console.log("result:", result); + +// Output: +// result: {dataValue: “def”, key: “ghi”} +``` + +### getItem(index) + +This method returns the object against the specified index. + +:::note +This is only for array type variable, i.e. when the Is List property is set. +::: + +**Parameters**: index(number) + +**Return Value**: Object + +**Example**: +``` +// If variable is list type having data as: +// [{dataValue: “abc”}, {dataValue: “def”}, {dataValue: “ghi”}] +var result = Page.Variables.staticVariable1.getItem(1); +console.log("result:", result); + +// Output: +// result: {dataValue: “def”} +``` +### setItem(index, value) + +This method sets the value against the specified index. + +:::note +Only for array type variable, i.e. when the Is List property is set. +::: + +**Parameters**: + +- index(number) +- value(*) + +**Return Value**: Updated dataSet of variable + +**Example**: +``` +// If variable is list type having data as: +// [{dataValue: “abc”}, {dataValue: “def”}, {dataValue: “ghi”}] +var result = Page.Variables.staticVariable1.setItem(1, {dataValue: "jkl"}); +console.log("result:", result); + +// Output: +// result: [{dataValue: “abc”}, {dataValue: “jkl”}, {dataValue: “ghi”}] +``` +### addItem(value, index) + +This method adds an item at specified index. + +:::note +Only for array type variable, i.e. when the Is List property is set. +::: + +**Parameters**: + +- index(number) +- value(*) + +**Return Value**: Updated dataSet of variable + +**Example**: +``` +//Example1: If variable is list type having data as: +// [{dataValue: “abc”}, {dataValue: “def”}, {dataValue: “ghi”}] +var result = Page.Variables.staticVariable1.addItem({dataValue: "jkl"}); +console.log("result:", result); + +// Output: +// result: [{dataValue: “abc”}, {dataValue: “def”}, {dataValue: “ghi”}, {dataValue: “jkl”}] + +//Example2: If variable is list type having data as: +// [{dataValue: “abc”}, {dataValue: “def”}, {dataValue: “ghi”}] +var result = Page.Variables.staticVariable1.addItem({dataValue: "jkl"}, 1); +console.log("result:", result); + +// Output: +// result: [{dataValue: “abc”}, {dataValue: “jkl”}, {dataValue: “def”}, {dataValue: “ghi”}] +``` +### removeItem(index) + +This method updates the dataSet of variable + +:::note +Only for array type variable, i.e. when the Is List property is set +::: + +**Parameters**: index(number) + +**Return Value**: Updated dataSet of variable + +**Example**: +``` +// If variable is list type having data as: +// [{dataValue: “abc”}, {dataValue: “def”}, {dataValue: “ghi”}] +var result = Page.Variables.staticVariable1.removeItem(1); +console.log("result:", result); + +// Output: +// result: [{dataValue: “abc”}, {dataValue: “ghi”}] +``` +### clearData() + +This method empties the variable dataSet. + +:::note +Only for array type variable, i.e. when the Is List property is set. +::: + +**Parameters**: none + +**Return Value**: Updated dataSet of variable + +**Example**: +``` +// If variable is list type having data as: +// [{dataValue: “abc”}, {dataValue: “def”}, {dataValue: “ghi”}] +var result = Page.Variables.staticVariable1.clearData(); +console.log("result:", result); + +// Output: +// result: [] +``` +### getCount() + +This method returns the total number of items in the dataSet. + +:::note +Only for array type variable, i.e. when the Is List property is set. +::: + +**Parameters**: none + +**Return Value**: Number of items + +**Example**: +``` +// If variable is list type having data as: +// [{dataValue: “abc”}, {dataValue: “def”}, {dataValue: “ghi”}] +var result = Page.Variables.staticVariable1.getCount(); +console.log("result:", result); + +// Output: +// result: 3 +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/navigation-action.md b/website/versioned_docs/version-v11.8.5/app-development/variables/navigation-action.md new file mode 100644 index 000000000..57598ba22 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/navigation-action.md @@ -0,0 +1,100 @@ +--- +title: "Navigation Action" +id: "navigation-action" +--- +--- + +**Navigation Action** provides navigation capabilities to help in navigating from one page or view to another. By default, for every page added to the app, a navigation action is created with the name `goToPage__`. You can choose to create a new Navigation Action. + +## Action Creation + +**Navigation Action** can be used to redirect the user to another page. + +1. There are two ways of creating a Navigation Action: + - Select the Action option from Variables on the Workspace Toolbar + + [![](/learn/assets/action_sel.png)](/learn/assets/action_sel.png) + + and click New Action from the Actions dialog. + + [![](/learn/assets/action_new.png?v=20)](/learn/assets/action_new.png?v=20) + + - or, as a New Action event on any widget + + [![](/learn/assets/action_new1.png)](/learn/assets/action_new1.png) + +2. In both the cases, a **New Action** wizard will open. + +#### Steps in Action Wizard + +- Choose **Navigation** Type +- Set the **Navigation Target** to: + - _Previous Page_ to navigate to last visited page + - _Page_ to navigate to the page as selected in the Page Name field + - _Accordion_ to navigate to the specified Accordion pane created the selected Page + - _Tab_ to navigate to the specified Tab pane created on the selected Page +- **Name** - set by default which can be modified +- **Owner** - the scope of the Action being created. By default it is set to Page, you can change it to Application if you want this action to be available across the app. +- Click **Done** to complete the action creation process + +3. You will be directed to the Actions dialog, with the new action listed. As you can see: + - a Navigation Action is created, + - with the selected target, + - the properties tab contains Page Name. + +## Properties + +| **Property** | **Description** | +| --- | --- | +| **Inputs** | +| Page Name | The page name to navigate to. This option will not appear for goToPreviousPage Operation. | +| Tab/Accordion Name | The tab/accordion pane’s name to navigate to if the operation is selected. This option will not appear for goToPreviousPage and goToPage Operation. | + +## Methods + +
invokesetData
+ +### invoke(options) + +This method invokes the navigation action + +**Parameters**: + +**options**(object): This object can include fields like: + +- **data**: the key-value pair of data to be passed via the variable to the other page in the form of URL params + +**Return Value**: None + +**Example**: +``` + // Example 1: Navigate to TestPage +Page.Actions.goToPage_TestPage.invoke(); + +// Example 2: Navigate to TestPage with url params +Page.Actions.goToPage_TestPage.invoke({ + data: { + 'param1': "param value", + "param2": "param value 2" + } +}); +``` +### setData(object) + +This method sets the input fields on the Navigation Action. + +**Parameters**: object or key-value pair of data to be passed via the variable to the other page in the form of URL params + +**Return Value**: None + +**Example**: + +``` +// Example 1: Navigate to TestPage +Var nv = Page.Actions.goToPage_TestPage; +nv.setData({ + 'param1': "param value", + "param2": "param value 2" +}); +nv.invoke(); +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/notification-action.md b/website/versioned_docs/version-v11.8.5/app-development/variables/notification-action.md new file mode 100644 index 000000000..00f81ce78 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/notification-action.md @@ -0,0 +1,168 @@ +--- +title: "Notification Action" +id: "notification-action" +--- +--- + +**Notification Action** is an action to show UI notifications in the app in the form of a toaster, alert or a confirmation box. It provides message capabilities, a way for the app to notify the end users. Based on the operation selected app can notify the user through an Alert/Confirm dialog or a simple toaster message. This action can be useful in cases like error handling, confirm user action, etc. + +## Action Creation + +1. There are two ways of creating a Notification Action: + - Select the Action option from Variables on the Workspace Toolbar + + [![](/learn/assets/action_sel.png)](/learn/assets/action_sel.png) + + - and click New Action from the Actions dialog. + + [![](/learn/assets/action_new.png?v=20)](/learn/assets/action_new.png?v=20) + + - or, as a New Action event on any widget + + [![](/learn/assets/action_new1.png)](/learn/assets/action_new1.png) + +2. In both the cases, a **New Action** wizard will open. + +### Steps in Action Window + +Choose **Notification** Type. It can be from the following. + +#### Alert +For alert, you can further specify: + +1. Text: Message to be displayed +2. Title: for the alert pop-up +3. OK button text: message on the button to dismiss the alert pop-up +4. Alert Type: to be set to error, information, success or warning. + +#### Confirm +For confirm, you can further specify: + +1. Text: Message to be displayed +2. Title: for the alert pop-up +3. OK button text: message on the button to dismiss the alert pop-up +4. Cancel button text: message on the button to dismiss the alert pop-up. + +#### Toast +For toast, you can further specify: + +1. Content: Message to be displayed can be inline or from a partial page +2. Text/Page: Message to be displayed/Partial page containing the message to be displayed +3. Duration: number of milliseconds for which the toaster should be displayed +4. Class: type of toast message in case of inline content, can be success, error, warning or info +5. Toaster position: where the message should be displayed – a combination of top, center, bottom, left, right. + +#### Name +Set by default which can be modified. +#### Owner +The scope of the Action being created. By default it is set to Page, you can change it to Application if you want this action to be available across the app. + +Click **Done** to complete the action creation process + +3. You will be directed to the Actions dialog, with the new action listed. As you can see: + 1. a Notification Action is created, + 2. With the selected target, + 3. The properties tab with [action properties](#properties) + 4. The events tab containing the events that can be customised ([know more](#events)) + +## Properties + +| Property | Description | +| --- | --- | +| Operation | The type of notification to be performed through the Action. Options are: - _alert_ - a dialog with a message and button; - _confirm_ - a dialog with a message and two buttons (for positive and negative confirmations); - _toast_ - a toaster box with a message _Based upon the operation selected following properties are available_: | +| **Alert operation** | +| Text | The text message to be shown in the dialog. It can be a static text or can be bound to a component for dynamic behavior. | +| Title | Dialog’s header title | +| Ok button text | Text to be displayed on the OK button of the dialog | +| Alert type | Display type of the dialog. Available options are information, success, error and warning | +| **Confirm operation** | +| Text | The text message to be shown in the dialog. It can be a static text or can be bound to a component for dynamic behavior. | +| Title | Dialog’s header title | +| Ok button text | Text to be displayed on the OK button of the dialog. This button is to receive the positive response from the end user. E.g. “YES”, “YES, I AGREE”, “CONTINUE”, etc. | +| Cancel button text | Text to be displayed on the CANCEL button of the dialog. This button is to receive the negative response from the end user. E.g. “NO”, “NO, I DON’T AGREE”, “GO BACK”, etc. | +| **Toast operation** || +| Content | Type of content to be displayed in the toaster. It can be: - inline – plain text can be provided or bound for dynamic text; - page – a partial page can be loaded into the toaster area. This is for more customized display. | +| Text | Available if “Content” property is selected as inline. Text to be displayed in the toaster | +| Page | Available if “Content” property is selected as the page. Partial page to be loaded into the toaster area. | +| Duration | The time period (in milliseconds) after which the toaster should fade away once it is shown. Select 0 if the toaster should stay. | +| Class | Determines the display type of toaster. Available options are success, error, warning, info. | +| Toaster Position | Determines where to display the toaster in the app. Available options are a combination of top, center, bottom, left, center, right. | + +## Events + +#### Notification Action Events + +Based on the operation different events are available for a Notification Action. + +### Alert + +1. **OnOk**: The event is fired on click of the OK button of the alert dialog. The event receives action and data as params. This data can be useful in some validation where the dialog is opened from various places. [Click here](#invoke) for an example of passing data through invoke method and receiving it in the _onOk_ event of the action. + +### Confirm +1. **OnOk**: The event is fired on click of the OK button of the confirm dialog. Please note, this event takes the positive response from the user. +2. **OnCancel**: The event is fired on click of the CANCEL button of the confirm dialog. Please note, this event takes the negative response from the user. +3. **OnClose**: The event is fired on the close of the confirm dialog. + +### Toaster + +1. **OnClick**: The event is fired on click of the toaster box. +2. **OnHide**: The event is fired on the hide of the toaster box. + +## Methods + +
invoke
+ +### invoke(options) + +This method invokes the notification action + +**Parameters**: + +- **options**(object): This object can have optional fields like: + + - **data**: some data can be passed from here, which will be received in events like onOk, onCancel, onClose, onHide + +Options specific toaster type action include +- **message -** text to be displayed in the toaster. +- **position -** where to display the toaster. Possible values: + - "top left" + - "top center" + - "top right" + - "center left" + - "center center" + - "center right" + - "bottom left" + - "bottom center" + - "bottom right" +- **class -** type of toaster. Possible values: + - ‘success’ + - ‘error’ + - ‘Info’ + - ‘warning’ + +**Return Value**: None + +**Example**: +``` +// Example 1: Notify with default set properties +Page.Actions.notificationAction1.invoke(); + +// Example 2: Notify with dynamic properties +Page.Actions.notificationAction1.invoke({ + "class": "info", + "message": "My custom message", + "position": "bottom right" +}); + +// Example 3: Passing data through alert type notification action +Page.Actions.notificationAction1.invoke({ + "data": {“mode”: “edit} +}); + +// the data will be passed to the action events onOk, onCancel, onClose, onHide +Page.notificationAction1onOk = function(variable, data) { + console.log('data: ', data) + // Output: + data: {“mode”: “edit} +}; +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/security-service.md b/website/versioned_docs/version-v11.8.5/app-development/variables/security-service.md new file mode 100644 index 000000000..6229aa5e1 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/security-service.md @@ -0,0 +1,161 @@ +--- +title: "Variable for Security Service" +id: "security-service" +--- +--- + +Security Services can be accessed from within your app using Variables. By default, a **loggedInUser** Model Variable is created for all applications. In case you need access to more details, you can create a Variable using the appropriate API. + +A comprehensive list of these APIs can be found from the [API Designer](/learn/assets/API_Access.png) after the import of the service. These include APIs to: + +- get Access Token, Logged In User details, logged in Time, logged in User Id, Role etc., +- check security and authentication etc.. + +## Variable Creation + +The **data source** for these Variables comes from a _Security Service APIs_. + +1. Select the Variable option from Variable Workspace Toolbar. [![](/learn/assets/var_sel.png)](/learn/assets/var_sel.png) +2. Click New Variable from the Variable Dialog [![](/learn/assets/var_new.png?v=20)](/learn/assets/var_new.png?v=20) +3. This will initiate Create Variable wizard with the following steps: + 1. Since we are creating a variable to access Security Service, select **Security ****Service **as the target action + 2. Select: + - **Service** - security service (already set), + - **Method** - the security operation that you want to invoke, + - **Name** - is set by default but can be modified + - **Owner** - the scope of the Variable being created. By default it is set to Page, you can change it to Application if you want this variable to be available across the app + 3. Click **Done** to complete the variable creation process +4. You will be directed to the Variables page, with the new variable listed. As you can see: + 1. a **Security Service** Variable is created, + 2. with the selected operation as target + 3. the **properties tab** contains all the properties like _behavior_ and _spinner_ behavior. [Know more about properties](#properties). + 4. the **events** tab will contain the events that can be configured to trigger any action. [Know more about events](#events). + +## Properties + +| **Property** | **Description** | +| --- | --- | +| **Behavior** || +| Request data on page load | If checked, 'Page' variable will be triggered on page load while 'Application' variable will be triggered on application load. | +| In Flight Behavior | This property determines the behavior when a call is fired through the variable with the previous call still pending. Variable queues all these calls, waits for the previous call completion and then based on the value of the _inFlightBehavior_ property, decides what to do with all the queued calls: - doNotExecute - all the queued calls will be discarded, - executeAll - all the calls will be triggered one by one, or - executeLast - only the last call is triggered and the rest are discarded, this is the default behavior | +| **Spinner** || +| Spinner Context | This property specifies on which UI widget the spinner should show. Leave empty if no spinner required. | +| Spinner Message | The message to be displayed below the spinner. Leave empty if no message is required below the spinner. Note: If multiple variables are fired then the spinner messages will be displayed as a list below a single spinner. | + +## Events + +During the life cycle of a Variable, a set of events are emitted by the Variable, thus giving you the option to control the behavior of the Variable such as input data validations, data processing, success/error handling, etc. [Know More](/learn/app-development/variables/variables-actions/#events-implementation). + +## Methods + +Few Methods are exposed for Variables which can be used for achieving more control and accessing extra functionality. Listed here are the same. + +
invokecancel
getDataclearDatasetInput
+ +### invoke() + +This method updates the Variable’s dataSet with new data by making a call to the target service. + +**Parameters**: + +- **options**(object) - It can have fields as: + - inputFields(key-value pair of inputData) + - page(pagination for Query Service Variable) + - size(pagination for Query Service Variable) + - orderBy(pagination for Query Service Variable) +- **success**(callback) +- **error**(callback) + +**Return Value**: none + +**Example**: +``` +var sv = Page.Variables.[variable_name]; + sv.invoke({ + "inputFields": { + "fname": "Steve", + "lname": "Rogers" + } + }, function(data) { + // Success Callback + console.log("success", data); + }, function(error) { + // Error Callback + console.log("error", error) + }); +``` +### cancel() + +This method aborts the current inflight variable request. + +**Parameters**: none **Return Value**: none + +**Example**: +``` +Page.Variables.[variable_name].cancel(); +``` +### getData() + +This method returns the variable’s dataSet, i.e., the current data stored in the variable through the listrecords method. + +**Parameters**: none + +**Return Value**: Array of record objects + +**Example**: +``` +var result = Page.Variables.[variable_name].getData(); +console.log("result:", result); +// Output: +// result: {data in the variable} +``` +### clearData() + +This method clears the variable dataSet. + +**Parameters**: none + +**Return Value**: Updated(empty) dataSet of the variable + +**Example**: +``` +var result = Page.Variables.[variable_name].clearData(); +console.log("result:", result); +// Output: +// result: {} +``` +### setInput(key, value) + +This method sets the input field value against the specified field(key). + +**Parameters**: + +- **key**(string): name of the input field +- **value**(*): value for the input field + +**Return Value**: Updated inputFields object + +**Example**: +``` +var sv = Page.Variables.[variable_name]; + sv.setInput("fname": "Peter"); + sv.setInput("lname": "Parker"); + sv.invoke(); +``` +### setInput(object) + +This method can also be used to set all the specified key-value pairs as input fields in the variable. + +**Parameters**: inputData(object) object or key-value pairs {“key”: “value”,…} + +**Return Value**: Updated inputFields object + +**Example**: +``` +var sv = Page.Variables.[variable_name]; + sv.setInput({ + "fname": "Peter", + "lname": "Parker" + }); + sv.invoke(); +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/timer-action.md b/website/versioned_docs/version-v11.8.5/app-development/variables/timer-action.md new file mode 100644 index 000000000..1033dcb78 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/timer-action.md @@ -0,0 +1,183 @@ +--- +title: "Timer Action" +id: "timer-action" +--- + +**Timer action** can be used to trigger events repeatedly at timed intervals. + +## Action Creation + +1. To create a Timer Action: + - Select the Action option from Variables on the Workspace Toolbar [![](/learn/assets/action_sel.png)](/learn/assets/action_sel.png)and click New Action from the Actions dialog. [![](/learn/assets/action_new.png?v=20)](/learn/assets/action_new.png?v=20) +2. A **New Action** wizard will open. + 1. Choose **Timer **Type + 2. **Name** - set by default which can be modified + 3. **Owner** - the scope of the Variable being created. By default it is set to Page, you can change it to Application if you want this variable to be available across the app. + 4. You can set the **Properties** ([know more](#properties)) + 5. Click **Done** to create the Action +3. You will be directed to the Actions dialog, with the new action listed. [![](/learn/assets/action_timer.png)](/learn/assets/action_timer.png) As you can see: + 1. a Timer Action is created, + 2. the properties tab contains the _behavior_ properties. [Know more about properties](#properties). + 3. the events tab will contain the events that can be configured to trigger any action. [Know more about events](#events). + +## Properties + +Timer Variables are special variables that can be used to trigger a particular event at regular time intervals. + +| **Property** | **Description** | +| --- | --- | +| **Behavior** | +| Trigger on page load | Selecting this option will ensure that the timer starts at page load. | +| Trigger after a delay | Defines the time delay, in milliseconds, before triggering the specified event. | +| Repeat after delay | Specifies whether the timer is one-time or a repeating event. | + +# Events + +Once a Timer Action is triggered, if it is Page scoped, then the action (and its repeating event) is destroyed when you navigate away from the page. If it is App scoped, it has to be manually stopped through _cancel_ method. + +1. **on Timer Fire**: This event will be triggered on the completion of the timer. If the _Delay_ property on the Timer Action is set then the event is invoked after the milliseconds of time supplied in ‘delay’ property of the timer action. The event is invoked once if ‘_repeating_’ flag is off and repetitively after every ‘delay’ milliseconds if ‘repeating’ flag is on. The repeating Timer Action event can be stopped in either of the two ways: + + 1. Calling the _cancel_ method on the Timer Action through the script at any point in time. + 2. If it is Page scoped, the action (and its repeating event) is destroyed once you navigate away from the page. If it is App scoped, it has to be manually stopped through the above step. + + **Usage Examples:** + + You can assign a Variable (or multiple Variables) or a Javascript method with custom logic in for dynamic behavior as required. + +1. Call a Variable that fetches the updates from Employee database with the latest after every 30 seconds. [![](/learn/assets/var_timer_props.png)](/learn/assets/var_timer_props.png) [![](/learn/assets/var_timer_event.png)](/learn/assets/var_timer_event.png) +2. A Variable that gives Facebook-like feeds after a certain timestamp. Assign Javascript to the onTimerFire event and write following logic. Once the Timer Action is triggered, if repeating property is set, then the variable will be invoked after every delay milliseconds. + + Page.timerAction1onTimerFire = function(variable, data){ + // set the dynamic input on the variable + Page.Variables.WebServiceVariabe.setInput('timestamp', Date.now()); + Page.Variables.WebServiceVariabe.invoke(); + }; + +   + +# Methods + +
invokecancel
+ +## invoke(object, success callback, error callback) + +This method invokes the timer variable + +_Parameters_: + +- options: object with no fields, an empty object has to be passed +- success: callback +- error: callback + +_Return Value_: None + +_Example:_ + + Page.Actions.timerAction1.invoke(); + +## cancel() + +This method aborts the timer variable. + +_Parameters_: none + +_Return Value_: none + +_Example:_ + +Page.Actions.timerAction1.cancel(); + +< Variables & Actions + +6. Data Integration - Variables + +- 6.1 Binding Layer + - [i. Overview](/learn/app-development/variables/data-integration/) +- [6.2 Variables and Actions](/learn/app-development/variables/variables-actions/) + - [i. Overview](/learn/app-development/variables/variables-actions/#) + - [ii. Variables](/learn/app-development/variables/variables-actions/#variables) + - a. Database CRUD + - [○ Overview](/learn/app-development/variables/database-crud/) + - [○ Variable Creation](/learn/app-development/variables/database-crud/#creation) + - [○ Properties](/learn/app-development/variables/database-crud/#properties) + - [○ Events](/learn/app-development/variables/database-crud/#events) + - [○ Methods](/learn/app-development/variables/database-crud/#methods) + - b. Database API + - [○ Overview](/learn/app-development/variables/database-apis/) + - [○ Variable Creation](/learn/app-development/variables/database-apis/#creation) + - [○ Properties](/learn/app-development/variables/database-apis/#properties) + - [○ Events](/learn/app-development/variables/database-apis/#events) + - [○ Methods](/learn/app-development/variables/database-apis/#methods) + - c. Web Service + - [○ Overview](/learn/app-development/variables/web-service/) + - [○ Variable Creation](/learn/app-development/variables/web-service/#creation) + - [○ Properties](/learn/app-development/variables/web-service/#properties) + - [○ Events](/learn/app-development/variables/web-service/#events) + - [○ Methods](/learn/app-development/variables/web-service/#methods) + - d. Java Service + - [○ Overview](/learn/app-development/variables/java-services) + - [○ Variable Creation](/learn/app-development/variables/java-services/#creation) + - [○ Properties](/learn/app-development/variables/java-services/#properties) + - [○ Events](/learn/app-development/variables/java-services/#events) + - [○ Methods](/learn/app-development/variables/java-services/#methods) + - e. Security Service + - [○ Overview](/learn/app-development/variables/security-service/) + - [○ Variable Creation](/learn/app-development/variables/security-service/#creation) + - [○ Properties](/learn/app-development/variables/security-service/#properties) + - [○ Events](/learn/app-development/variables/security-service/#events) + - [○ Methods](/learn/app-development/variables/security-service/#methods) + - f. Model + - [○ Overview](/learn/app-development/variables/model-variable/) + - [○ Variable Creation](/learn/app-development/variables/model-variable/#creation) + - [○ Properties](/learn/app-development/variables/model-variable/#properties) + - [○ Events](/learn/app-development/variables/model-variable/#events) + - [○ Methods](/learn/app-development/variables/model-variable/#methods) + - g. Device Variables + - [○ Overview](/learn/hybrid-mobile/device-variables/#) + - [○ Services](/learn/hybrid-mobile/device-variables/#services) + - [○ Operations](/learn/hybrid-mobile/device-variables/#operations) + - [○ Events](/learn/hybrid-mobile/device-variables/#events) + - [○ Methods](/learn/hybrid-mobile/device-variables/#methods) + - [○ Usage](/learn/hybrid-mobile/device-variables/#usage) + - [iii. Actions](/learn/app-development/variables/variables-actions/#actions) + - i. Navigation + - [○ Overview](/learn/app-development/variables/navigation-action/#) + - [○ Action Creation](/learn/app-development/variables/navigation-action/#creation) + - [○ Properties](/learn/app-development/variables/navigation-action/#properties) + - [○ Methods](/learn/app-development/variables/navigation-action/#methods) + - ii. Login + - [○ Overview](/learn/app-development/variables/login-action/) + - [○ Action Creation](/learn/app-development/variables/login-action/#creation) + - [○ Properties](/learn/app-development/variables/login-action/#properties) + - [○ Data](/learn/app-development/variables/login-action/#data) + - [○ Events](/learn/app-development/variables/login-action/#events) + - iii. Logout + - [○ Overview](/learn/app-development/variables/logout-action/) + - [○ Action Creation](/learn/app-development/variables/logout-action/#creation) + - [○ Properties](/learn/app-development/variables/logout-action/#properties) + - [○ Events](/learn/app-development/variables/logout-action/#events) + - [iv. Timer](#) + - [○ Overview](#) + - [○ Action Creation](#creation) + - [○ Properties](#properties) + - [○ Events](#events) + - [○ Methods](#methods) + - v. Notification + - [○ Overview](/learn/app-development/variables/notification-action/) + - [○ Action Creation](/learn/app-development/variables/notification-action/#creation) + - [○ Properties](/learn/app-development/variables/notification-action/#properties) + - [○ Events](/learn/app-development/variables/notification-action/#events) + - [○ Methods](/learn/app-development/variables/notification-action/#methods) + - [iv. Scoping](/learn/app-development/variables/variables-actions/#scoping) + - [v. Variable Events](/learn/app-development/variables/variables-actions/#events) + - [vi. Error Handling](/learn/app-development/variables/variables-actions/#error-handling) +- 6.3 Variable Binding + - [i. Overview](/learn/variables/variable-binding/#) + - [ii. Data Binding](/learn/variables/variable-binding/#data-binding) + - [iii. Widget Binding](/learn/variables/variable-binding/#widget-binding) + - [iv. Binding Options](/learn/variables/variable-binding/#binding-options) +- 6.4 JavaScript Access + - [i. Overview](/learn/variables/accessing-elements-via-javascript/#) + - [ii. Widget Controllers](/learn/variables/accessing-elements-via-javascript/#widget-controllers) + - [iii. Page Scripting](/learn/variables/accessing-elements-via-javascript/#page-scripting) + - [iv. Script Access](/learn/variables/accessing-elements-via-javascript/#script-access) diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/variable-binding.md b/website/versioned_docs/version-v11.8.5/app-development/variables/variable-binding.md new file mode 100644 index 000000000..edb17cb02 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/variable-binding.md @@ -0,0 +1,117 @@ +--- +title: "Variable Binding" +id: "variable-binding" +--- +--- + +WaveMaker leverages the concept of Data Binding by Angular, to bind Widgets with Variables. Widgets can be configured to bind the UI Elements to specific fields of the Data Model. + +[![binding_concept](/learn/assets/binding_concept.png)](/learn/assets/binding_concept.png) + +Binding is used to serve two purposes: + +1. [Binding the value of variables to a component or widget](#binding-to-widgets) +2. [Binding to data from Variables](#binding-to-data-from-variables) + +## Binding to Widgets + +Once you have created the necessary variables ([Variable Access](/learn/assets/var_sel.png)), you can display the data or capture user input by binding data to a component/widget. The connection between a widget (or widget property) and a source of data is called the **binding**. + +1. To bind widgets to data, you need to use the **Bind** dialog. +2. In the **Properties Panel**, anything that can support data from a different source is marked with the _bind chain_ icon. You can edit or delete the bindings. Click the bind icon to display the **Bind** dialog. + +[![bind](/learn/assets/bind.png)](/learn/assets/bind.png) + +3. Clicking on the _bind chain icon_ next to any widget property will open a **Bind** dialog. From this dialog you can: + - see a listing the various binding options, fields along with the data types, + - do multiple bindings, that is all the fields can be bound at the same time, + - do a parent level binding using the objects + - understand the binding requirement. +4. The **Bind** dialog displays the binding options i.e. a list of everything that you can bind to, including all variables, widgets and so on. You can bind to widgets, variables that are defined on the current page, or that are defined at the app level. + +:::important +The compatible types are indicated by success or failure message once you select a field from the variable list. +::: + +- **Variable**:  List of available variables are listed here. +- **Widgets**: List of all the widgets on the current page. +- **Resource**:  List of resources included in the project, including images, HTML, CSS, and JavaScript. +- **Use Expression**: Any JavaScript expression. +- **Localized Messages**: Any of the application messages that you created in the Application Messages repository. + +5. Select the appropriate binding options and click **Bind**. + +[![widget_binding](/learn/assets/widget_binding.png)](/learn/assets/widget_binding.png) + +6. A **validation message** will be displayed to indicate whether the binding is valid or not. + +:::note +Along with the message, you will see the expected data type (Target) and your selection (Bound to). Based on this information, you may either choose to ignore the message or change the binding accordingly. +::: + +## Binding to Data from Variables + +Variables can be bound to each other. Usually, this is the requirement with Variables when the data needs to be filtered i.e. output limited by a constraint or when a Variable which needs parameters as input in order to process information from the data source. These input/filter parameters will be available from the _Data_ tab of the Variable. For example, the Variable corresponding to the Employee CRUD API from the sample hrdb can be filtered on any field of the dataset: + +[![var_bind](/learn/assets/var_bind1.png)](/learn/assets/var_bind1.png) + +Clicking on the _bind chain icon_ next to any parameter will open a **Bind** dialog. From this dialog you can: + +- see a listing the various binding options, fields along with the data types, +- do multiple bindings, that is all the fields can be bound at the same time, +- do a parent level binding using the objects +- understand the binding requirement. + +### Binding Options + +- **Variable**:  List of available variables are listed here. +- **Widgets**: List of all the widgets on the current page. +- **Resource**:  List of resources included in the project, including images, HTML, CSS, and JavaScript. +- **Expression**: Any JavaScript expression. +- **Localized Messages**: Any of the application messages that you created in the Application Messages repository. + +[![var_bind](/learn/assets/var_bind2.png)](/learn/assets/var_bind2.png) + +A **validation message** will be displayed to indicate whether the binding is valid or not. Along with the message, you will see the expected data type (Target) and your selection (Bound to). Based on this information, you may choose to ignore the message or change the binding accordingly. + +[![var_bind_warn](/learn/assets/var_bind2_warn.png)](/learn/assets/var_bind2_warn.png) + +## Binding Options + +### Binding to Variables + +We can use bind option to bind variables to appropriate widgets or another variable. **Note**: + +- When binding to Service Variables make sure that the _Request data on page load_ is selected to ensure the component/widget is initialized with data at the time of page (application in case of app owned variables) load. +- Use _Update data on input change_ to trigger the live variable automatically when the filter condition or the input parameter value changes. + +### Binding to Widgets + +You can bind a widget value to another widget value. For example, you can bind a **Text** widget to a selected value from the **Data Table** or **Live List**. + +### Binding to Resource + +You can bind your widgets to images, videos etc.. For this you have to [Import Resource](/learn/app-development/services/3rd-party-libraries) first. + +### Binding using Expression + +From the **Use Expression** tab, you can write a custom expression to change the display setting. The expression can be simple string concatenation expressions or HTML syntax following AngularJS conventions for binding. For complex expressions, it is advisable to [write a function](/learn/how-tos/using-javascript-binding/#js-function). For example, when displaying name you want the display to say _User Name is: some_value_, you can achieve this by using the expression: + +``` +"User Name is: " + datavalue +``` +You can also change the data format, combine various data fields and do much more using the **Expressions** to bind your widgets. You can select the variable you want to bind this text box from the left side panel. Using the arithmetic symbols you can build an expression involving multiple variables and the format you want it to be displayed. Currently, there are the following formatting options to choose from: + +- **numberToString** - formats number to a string. **Fraction Size** specifies the number of decimal places to round the number to. Eg: If the value is 12345.6789 and fraction size is 3, then the formatted value is 12,345.679. +- **prefix** - allows you to add a prefix to the expression, +- **stringToNumber** - formats string to a number. Eg: If value is '123', then formatted value is 123 +- **suffix** - allows you to add a suffix to the expression, +- **timeFromNow** - Formats date and time to a relative time. Eg: If the value is 5 PM and the current time is 6 PM, formatted value is 'an hour ago'. Moment library is used for this functionality. Moment supports localization. Moment locale files are bundled with the project. Thus at runtime, when the locale changes, the respective locale file is loaded and all-time conversions are localized accordingly. +- **toCurrency** - lets you define the type of currency thus giving the appropriate display symbol and specify the precision value, +- **toDate** - lets you select the date format, and +- **toNumber** - allows you to convert the text to number format for use in arithmetic operations and specify the precision value. + +### Binding to Localized Messages + +You can bind your custom Application messages and bind them to a widget. This is particularly useful when trying to implement localization in your app. [See here for more](/learn/how-tos/select-locale-usage/). + diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/variables-actions.md b/website/versioned_docs/version-v11.8.5/app-development/variables/variables-actions.md new file mode 100644 index 000000000..2afa51872 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/variables-actions.md @@ -0,0 +1,32 @@ +--- +title: "Actions" +id: "variables-actions" +--- +Introduction to Actions in WaveMaker. Learn how to implement actions. + +--- + +Variables and Actions form the glue between the frontend UI and the backend services. Variables provide data integration for the widgets, while Actions implement the business logic, rules and data flows. For more information about creating variables, see [Variables](/learn/app-development/variables/variables). + +Actions are the tasks performed such as invoking a backend API, database CRUD operation or navigating to another page etc. when a UI event occurs. Events could be either user-initiated or can occur as a result of another task being performed. + +## Action Types + +Actions can be categorized based on the triggering event: + +|No. | Action Types | Description | +|---|---|---| +|1. | **[Navigation](/learn/app-development/variables/navigation-action/)** |To pass control from one page to another passing data if needed. | +|2.|**[Login](/learn/app-development/variables/login-action/)** |To trigger at the time of user login.| +|3.|**[Logout](/learn/app-development/variables/logout-action/)** |To trigger at the time of user logout. | +|4.|**[Timer](/learn/app-development/variables/timer-action/)** | To trigger an action based on time interval.| +|5.|**[Notification](/learn/app-development/variables/notification-action/)** | To alert the user of any information. | + +## Error Handling + +WaveMaker Variables dealing with external services like Web, Database etc. may not always return with a successful response. Sometimes the Variable call may fail due to various reasons like server validation, request timeout, etc. To gracefully handle such scenarios, a default **Notification Action** (_toaster target_) named _appNotification_ is created in the app. By default, all Variables invoke this action on error response from the target service. This enables the app has a central point of error handling. + +The default appNotification Action can further be customized as per requirement. For example, if you want the app to display errors in an alert dialog, the appNotification action can be changed to alert type. To suppress the default error handling, simply delete the appNotification action. For more information, see [Error handling](/learn/how-tos/error-handling-wavemaker-app/). + +[![variable error](/learn/assets/vars_error.png)](/learn/assets/vars_error.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/variables.md b/website/versioned_docs/version-v11.8.5/app-development/variables/variables.md new file mode 100644 index 000000000..3a5721967 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/variables.md @@ -0,0 +1,74 @@ +--- +title: "Variables Overview" +id: "variables" +sidebar_label: "Variables Overview" +--- +Learn about Variables in WaveMaker low-code platform. See how it works and how to use them as services. + +--- +Variables form the glue between the frontend UI and the backend services. Variables provide data integration for the widgets. + +[![Variables introduction in WaveMaker](/learn/assets/variables_introduction.PNG)](/learn/assets/variables_introduction.PNG) + +## Scope of Variables + +Variables and Actions can be classified into two based on the scope of the Variable. The two types of variables are - **Application** and **Page** level variables. While both these types reside at the _client side_, the _application level_ variables share the data across multiple pages, whereas _Page level_ variables share the data within the page where they have been declared/created. Whenever you are switching from one page to another, all the previous page level variables are destroyed. + +[![var_scope](/learn/assets/var_scope.png)](/learn/assets/var_scope.png) + +:::note +It is advised to have unique names for any variable to avoid confusion. Whenever you try to create or rename a variable WaveMaker will throw an error if another variable of the same name exists either within the page or at the app level. +::: + +## How it works + +Variables function by invoking the associated REST APIs on the server-side, invoking the client-side JavaScript events that are associated or bound by configuration, after the response is obtained. Variables play a significant role in binding the UI and the backend services layer together through configuration and events, eliminating the necessity to write a lot of code. + +Variables can be represented using a block with 3 faces, as in the picture below, representing the APIs invoked, events processed and the Model or Entity objects returned by the APIs. + +[![](/learn/assets/var_representation.png)](/learn/assets/var_representation.png) + +## Variable Types +--- +Variables can be categorized based on the target action: + +|No.|Variable Types|See| +|---|---|---| +|1.|**Database CRUD** | [Database CRUD](/learn/app-development/variables/database-crud/) | +|2.|**APIs** |- [Database APIs](/learn/app-development/variables/database-apis/) - [Web Services](/learn/app-development/variables/web-service/) - [Java Services](/learn/app-development/variables/java-services/) - [Security Services](/learn/app-development/variables/security-service/)| +|3.|**Other Services**|- [Model Variable](/learn/app-development/variables/model-variable/) - [Device Variable](/learn/hybrid-mobile/device-variables/)| + + +## 1. Database CRUD +--- +The basic insert, read, update and delete operations on an imported database entities can be performed using the default CRUD APIs generated at the time of import by the platform. For more information, see [Database CRUD](/learn/app-development/variables/database-crud/). + + + +## 2. APIs +--- +Variables can be created to be based upon the various APIs exposed by the services integrated within the app. These can be further classified as as following. + +### Database APIs +Database import generates several APIs for functionalities like Count, Filter, Get by field name, Get associated table data etc. apart from the default CRUD APIs and can be used for more control over the database. These Database APIs also include those corresponding to Queries and Procedures created within the data model. For more information, see [Database APIs](/learn/app-development/variables/database-apis/). + +### Web Services +Variable can be created to access the APIs exposed by the imported web service. For more information, see [Web Services](/learn/app-development/variables/web-service/). + +### Java Services +For every Java Service created within WaveMaker, its REST API contract is auto-generated and the same can be accessed through a Variable. For more information, see [Java Services](/learn/app-development/variables/java-services/). + +### Security Services +In case security is enabled for the app, you have access to various security-related data. For more information, see [Security Services](/learn/app-development/variables/security-service/). + +## 3. Other Services +--- + +### Model Variable +To store data on the client side. For more information, see [Model Variable](/learn/app-development/variables/model-variable/). + +### Device Variable +For Mobile Apps, the various device information can be used to access the respective devices like camera, contacts, and more. For more information, see [Device Variable](/learn/hybrid-mobile/device-variables/). + + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/web-service.md b/website/versioned_docs/version-v11.8.5/app-development/variables/web-service.md new file mode 100644 index 000000000..53c23fe53 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/web-service.md @@ -0,0 +1,260 @@ +--- +title: "Service Variable" +id: "web-service" +sidebar_label: "Service Variable" +--- +--- + +For every service imported into the app, the APIs exposed by the service can be accessed to perform many operations with it. A variable needs to be created to invoke the service and store the results of that invocation. The Variable operations are restricted by the offerings of the underlying service. + +A comprehensive list of these APIs can be found from the [API Designer](/learn/assets/API_Access.png) after the import of the service. + +:::note +Since the service needs to be invoked to fetch the data, the widgets bound to these variables will display values only at run-time, not in Studio mode. +::: + +## How to Create a Service Variable + +The **data source** for these Variables comes from imported REST and SOAP services. You can create a Service variable by using the following two approaches depending on the source of the data. + +1. Service Variable for **[Web Service](/learn/app-development/services/web-services/web-services)** (REST APIs, SOAP, WebSocket) +2. Service Variable for **[Imported APIs](/learn/app-development/services/api-designer/import-rest-apis-swagger)** (Swagger/Open API) + +:::important +The process for creating a variable for WebSocket Service is the same as below, however, the properties and methods are different. For more information, see [WebSocket Variable](/learn/app-development/variables/websocket-variable/). +::: + +![select web services](/learn/assets/select-service-variable.png) + +### Service Variable for Web Services + +1. Select **Variable** from the workspace toolbar. + +![variable creation](/learn/assets/var_sel.png) + +2. Click **New Variable** from the Variable Dialog. + +![new variable](/learn/assets/var_new.png) + +3. Select **Web Services** as a target action for Variable. + +![select web services](/learn/assets/select-web-services.PNG) + +4. In the new Variable dialog, configure the properties for the variable. + +:::important +The data source for the Variable comes from the imported Services. +::: + +![web service variable](/learn/assets/web-service-variable.png) + +- **Service**: Select the service name from imported services. +- **Name**: Set by default, but you can modify it. +- **Owner**: The scope of the Variable. Page is the default option. You can choose Application to make it available across the app. +- Click **Done** to complete the variable creation process. + +### Service Variable for Imported APIs + +1. Select **Variable** from the workspace toolbar. + +![variable creation](/learn/assets/var_sel.png) + +2. Click **New Variable** from the Variable Dialog. + +![new variable](/learn/assets/var_new.png) + +3. Select **Imported APIs** as a target action for Variable. + +![select imported api](/learn/assets/select-imported-api.png) + +4. In the new Variable dialog, configure the properties for the variable. + +![swagger variable](/learn/assets/other-endpoints-variable.png) + +:::note +You can create a CRUD variable to perform create, read, update, delete operations using the **Entities (CRUD)** option. For more information, see [Service Variable](/learn/app-development/variables/web-service#service-variable-for-imported-apis). +::: + +- **Service**: Select the [Imported Service](/learn/app-development/services/api-designer/import-rest-apis-swagger#importing-swagger). +- **Type**: Select the **Type** as `Other Endpoints`. +- **Method**: If the API exposes multiple services, you can choose from the list. +- **Name**: Set by default, but you can modify it. +- **Owner**: The scope of the Variable. Page is the default option. You can choose Application to make it available across the app. +- Click **Done** to complete the variable creation process. + +### Variable Properties and Events + +![variable creation](/learn/assets/var_sel.png) + +You will be directed to the Variables page, with the new variable listed. You can see the following options. + +![crud variable properties](/learn/assets/service-variable-properties.png) + +1. **Name**: You can modify the variable name. +2. **Owner**: The scope of the Variable. Page is the default option. You can choose Application to make it available across the app. +3. A new **Web Service** variable created with the default exposed method/selected method as a target. +4. The **Properties** tab contains all the properties like behavior and spinner behavior. [Learn more](#properties). +5. The **Data** tab contains the fields serving as **Input Fields** for the API. +6. The **Events** tab contains the events that can be configured to trigger any action. [Learn more](#events). + +## Properties + +| **Property** | **Description** | +| --- | --- | +| **Behavior** | +| Update data on input change | If checked, the component will be triggered automatically on the change of input data (as mentioned in the data tab) for the variable. | +| Request data on page load | If checked, 'Page' variable will be triggered on page load while 'Application' variable will be triggered on application load. | +| In Flight Behavior | This property determines the behavior when a call is fired through the variable with the previous call still pending. Variable queues all these calls, waits for the previous call completion and then based on the value of the `inFlightBehavior` property, decides what to do with all the queued calls: - doNotExecute - all the queued calls will be discarded, - executeAll - all the calls will be triggered one by one, or - executeLast - only the last call is triggered and the rest are discarded, this is the default behavior| +| **Spinner** | +| Spinner Context | This property specifies on which UI widget the spinner should show. Leave empty if no spinner required. | +| Spinner Message | The message to be displayed below the spinner. Leave empty if no message is required below the spinner. Note: If multiple variables are fired then the spinner messages will be displayed as a list below a single spinner. | + +## Events + +During the life cycle of a Variable, a set of events are emitted by the Variable, thus giving you the option to control the behavior of the Variable such as input data validations, data processing, success/error handling, and more. + +- OnBeforeUpdate +- OnResult +- OnError +- OnBeforeDatasetReady +- OnCanUpdate +- OnSuccess + +To learn how to implement Events, see [Events Documentation](/learn/app-development/variables/events). + +## Methods + +Few Methods are exposed for Variables which can be used for achieving more control and accessing extra functionality. Listed here are the same. + +
invokecancel
getDataclearDatasetInput
+ +## `invoke()` + +This method updates the Variable’s dataSet with new data by making a call to the target service. + +#### `Parameters` + +**options** (object) - It can have fields as +- `inputFields` (key-value pair of inputData) +- `page` (pagination for Query Service Variable) +- `size` (pagination for Query Service Variable) +- `orderBy` (pagination for Query Service Variable) + +**success** (callback) + +**error** (callback) + +#### `Return Value` +none + +#### Example +``` +var sv = Page.Variables.[variable_name]; + sv.invoke({ + "inputFields": { + "fname": "Steve", + "lname": "Rogers" + } + }, function(data) { + // Success Callback + console.log("success", data); + }, function(error) { + // Error Callback + console.log("error", error) + }); +``` + +## `cancel()` + + +This method aborts the current inflight variable request. + +#### `Parameters` +none + +#### `Return Value` +none + +#### Example +``` +Page.Variables.[variable_name].cancel(); +``` + +## `getData()` + +This method returns the variable’s dataSet, i.e., the current data stored in the variable through the listrecords method. + +#### `Parameters` +none + +#### `Return Value` +Array of record objects + +#### Example + +``` +var result = Page.Variables.[variable_name].getData(); +console.log("result:", result); +// Output: +// result: {data in the variable} +``` + +## `clearData()` + +This method clears the variable dataSet. + +#### Parameters +none + +#### Return Value +Updated(empty) dataSet of the variable + +#### Example + +``` +var result = Page.Variables.[variable_name].clearData(); +console.log("result:", result); +// Output: +// result: {} +``` + +## `setInput(key, value)` + +This method sets the input field value against the specified field(key). + +#### Parameters + +- **key**(string): name of the input field +- **value**(*): value for the input field + +#### Return Value +Updated inputFields object + +#### Example +``` +var sv = Page.Variables.[variable_name]; + sv.setInput("fname", "Peter"); + sv.setInput("lname", "Parker"); + sv.invoke(); +``` +## `setInput(object)` + +This method can also be used to set all the specified key-value pairs as input fields in the variable. + +#### `Parameters` +``` +inputData(object) object, or +key-value pairs {“key”: “value”,…} +``` +#### `Return Value` +Updated `inputFields` object + +#### Example +``` +var sv = Page.Variables.[variable_name]; + sv.setInput({ + "fname": "Peter", + "lname": "Parker" + }); + sv.invoke(); +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/web-socket-variable.md b/website/versioned_docs/version-v11.8.5/app-development/variables/web-socket-variable.md new file mode 100644 index 000000000..654bce5eb --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/web-socket-variable.md @@ -0,0 +1,74 @@ +--- +title: "Web Socket Variable" +id: "web-socket-variable" +--- +--- +**Web Socket Variable** is the interface for the app developer to interact with a WebSocket Service imported into a WaveMaker app. The Variable has methods to interact with the target service like opening and closing the connection, sending and receiving messages to and from the server. It also holds the data to be sent to the service and the data received from the service. + +## Web Socket Variable Lifecycle + + + +We can create variables directly instead of through the Data & Live Widgets. Here we list the steps for the same: + +1. Select Variable option from the Create Menu + +[![Var_create](/learn/assets/Var_create.png)](/learn/assets/Var_create.png) + +2. Select the **type of Variable** to be created from the list provided in the Variable Main Page and click on **ADD** + + +3. Select Service - web/java service name and Operation - method/function + + + +4. the **properties tab** contains all the properties like _source_, _service_ and _server options_ in case of live variables, and _behavior_. + + + +5. the **data tab** will contain the fields serving as _filter fields_ while data fetch operation in case of Live Variable and as _input parameters_ for the Web Service call in case of Service Variables + + +6. The events tab will contain the events that can be configured to trigger any action + + + +## Properties + +| Property | Description | +| --- | --- | +| Service | The WebSocket service targeted for the Variable. | +| **Behavior** | +| Connect on page load | If set to true, the variable will open the connection between the client and target WebSocket service on: - page load, for a page variable - app load, for an app variable. | +| Append message to dataSet | A client once connected to a WebSocket service, can receive messages at any point in time and can receive a number of messages one after the other. - If this property is set to true, the messages received will keep getting appended to the variable dataSet. In this case, dataSet will always be a list of messages. - If not, variable dataSet will always have only the last message received from the WebSocket service. | +| Max Results in dataSet | Maximum number of messages that dataSet will hold. This is applicable only if Append message to dataSet property is set. E.g. if set to 10, dataSet will hold a maximum of 10 message received from the server. When a new message is received, the first message is removed from the dataSet and the new one is appended to the end. Set it to 0 if no such upper limit is required. | + +### Events + +Following events are triggered during the lifecycle of a WebSocket Variable. These events can be utilized to customize the behavior of the app through more complex logic. + +| **Event** | **Description** | +| --- | --- | +| onBeforeOpen | The event is triggered just before the Variable attempts to establish a connection between the client and target WebSocket service. **If returned false from here**, the connection establishment will be aborted. | +| onOpen | The event is triggered right after a successful connection is established between the client and the WebSocket service through the Variable. | +| onBeforeMessageSend | The event is triggered just before the Variable attempts to send a message to the target service through the existing connection. You have a chance at this point to validate and edit the data to be sent to the service. Returning false from this event will prevent the message to be sent to the service. | +| onMessageReceive | The event is triggered on the Variable when a message is received from the WebSocket service in an existing connection made by the Variable. | +| onError | Triggered if an error is encountered in establishing a connection with the server in the open phase. | +| onBeforeClose | Triggered before an existing connection(opened by the Variable) is closed. **Returning false from here will abort the closing of the connection**. | +| onClose | Triggered after the connection is closed. | + +### Methods + +The Variable has the following methods namely: + +| **Method** | **Description** | +| --- | --- | +| open() | Used to open up the connection between the client and the WebSocket service. This is the starting point of the Variable lifecycle. | +| send() | Used to send a message to the WebSocket service through the currently established connection. | +| close() | Used to close an existing WebSocket connection connected through the Variable. | +| onMessageReceive | The event is triggered on the Variable when a message is received from the WebSocket service in an existing connection made by the Variable. | +| onError | Triggered if an error is encountered in establishing a connection with the server in the open phase. | +| onBeforeClose | Triggered before an existing connection(opened by the Variable) is closed. **Returning false from here will abort the closing of the connection**. | +| onClose | Triggered after the connection is closed. | + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/variables/websocket-variable.md b/website/versioned_docs/version-v11.8.5/app-development/variables/websocket-variable.md new file mode 100644 index 000000000..f75c1c4bc --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/variables/websocket-variable.md @@ -0,0 +1,115 @@ +--- +title: "WebSocket Variable" +id: "websocket-variable" +--- +--- + +**WebSocket Variable** is the interface for the app developer to interact with a WebSocket Service imported into a WaveMaker app. The Variable has methods to interact with the target service like opening and closing the connection, sending and receiving messages to and from the server. It also holds the data to be sent to the service and the data received from the service. + +## Variable Lifecycle + +[![socket_lifecycle](/learn/assets/socket_lifecycle.png)](/learn/assets/socket_lifecycle.png) + +## Variable Creation + +The **data source** for WebSocket Variables comes from a **Web Service**. We will see steps in creating a WebSocket variable here. + +1. Select Variable option from the Create Menu + +[![](/learn/assets/var_sel.png)](/learn/assets/var_sel.png) + +2. Click New Variable from the Variable Dialog. + +[![](/learn/assets/var_new.png)](/learn/assets/var_new.png) + +3. For creating a variable to access WebSocket Web service APIs, select **Web Service** as the target action. +4. In the next dialog, enter details for the following properties. + - **Service** - service (already imported) name, + - **Name** - is set by default but can be modified + - **Owner** - the scope of the Variable being created. By default it is set to Page, you can change it to Application if you want this variable to be available across the app. + +5. Click **Done** to complete the variable creation process +6. You will be directed to the Variables page, with the new variable listed. As you can see: + - a **Web Service** Variable is created, + - with the default exposed method/selected method as target + - the **properties tab** contains all the properties like **behavior** and **dataset** behavior. [Know more about properties](#properties). + - the **data tab** will contain the fields serving as **input fields** for the API + - the **events** tab will contain the events that can be configured to trigger any action. [Know more about events](#events). + +## Properties + +WebSocket Variables are special variables that interact with the imported Web Socket service. + +| **Property** | **Description** | +| --- | --- | +| **Service** | +| Service | The WebSocket service targeted for the Variable. | +| **Behavior** | +| Connect on page load | If set to true, the variable will open the connection between the client and target WebSocket service on: - page load, for a page variable - app load, for an app variable. | +| **Dataset** | +| On New Data | A client once connected to a WebSocket service, can receive messages at any point in time and can receive many messages sequentially. This property determines what to do with data received from the variable. - **Refresh dataSet**: dataSet will be updated with the data received. - **Add as last record**: data will be appended at the end of dataSet. The latest data will be the last record in dataSet. - **Add as first record**: data will be prepended at the beginning of dataSet. The latest data will be the first record in dataSet. In the latter two cases, dataSet will always be a list of messages. | +| Data Limit | Maximum number of messages that dataSet will hold. This is applicable only if “On New Data” property is set to other than “Refresh”. E.g. if set to 10, dataSet will hold a maximum of 10 message received from the server. When a new message is received, the first message is removed from the dataSet and the new one is appended to the end. Set it to 0 if no such upper limit is required. | + +## Events + +Following events are triggered during the lifecycle of a WebSocket Variable. These events can be utilized by the end user application developer to customize the behavior of the app through more complex logic. + +| **Event** | **Description** | +| --- | --- | +| on Before Open | The event is triggered just before the Variable attempts to establish a connection between the client and target WebSocket service. If returned false from here, the connection establishment will be aborted. | +| on Open | The event is triggered right after a successful connection is established between the client and the WebSocket service through the Variable. | +| on Before Message Send | The event is triggered just before the Variable attempts to send a message to the target service through the existing connection. You have a chance at this point to validate and edit the data to be sent to the service. Returning false from this event will prevent the message to be sent to the service. | +| on Message Receive | The event is triggered on the Variable when a message is received from the WebSocket service in an existing connection made by the Variable. | +| on Error | Triggered if an error is encountered in establishing a connection with the server in the open phase. | +| on Before Close | Triggered before an existing connection(opened by the Variable) is closed. Returning false from here will abort the closing of the connection. | +| **onClose** | Triggered after the connection is closed. | + +:::note +WaveMaker supports binding multiple actions to a given event, i.e. a given event can trigger multiple actions. +::: + +## Methods + +
opensendclose
+ +### open() + +This method is used to open up the connection between the client and the WebSocket service. This is the starting point of the Variable lifecycle. + +**Parameters**: None +**Return Value**: None +**Usage:** + +```js +Page.Variables.webSocketVariable.open(); +``` + +### send() + +This method is used to send a message to the WebSocket service through the currently established connection. + +**Parameters**: + +- **message**(object): the message to be sent to the service. If not provided, whatever is assigned to Variable RequestBody will be sent + +**Return Value**: None + +**Usage:** + +```js +Page.Variables.webSocketVariable.send(message); +``` + +### close() + +This method is used to close an existing WebSocket connection connected through the Variable. + +**Parameters**: None + +**Return Value**: None + +**Usage:** + +```js +Page.Variables.webSocketVariable.close(); +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/app-development-using-rad.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/app-development-using-rad.md new file mode 100644 index 000000000..db3509fd5 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/app-development-using-rad.md @@ -0,0 +1,16 @@ +--- +title: "How does WaveMaker simplify app development using the RAD paradigm?" +id: "app-development-using-rad" +sidebar_label: "Simplify app development using the RAD paradigm" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) section for WaveMaker app development.    + +--- + +WaveMaker simplifies app development by combining the power of auto-generated code for backend services, with visual drag-n-drop based composition of UI. + +Boiler plate code comprising more than 60% of application’s code, such as the Object Relational Mapping (ORM) layer, integration code for invoking APIs, data conversions to JSON, parameter validations, widgets markup etc. is totally removed from developer’s responsibilities. While the platform takes care of code generation for the parts mentioned above, app developers can now focus on the business logic, business rules that define data flows, interaction, look-n-feel, and more. + +### See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[Integrating Backend Services](/learn/app-development/services/creating-backend-services/) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/application-stack-upgrades.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/application-stack-upgrades.md new file mode 100644 index 000000000..03c66fc9e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/application-stack-upgrades.md @@ -0,0 +1,29 @@ +--- +title: "How are the application stack upgrades done?" +id: "application-stack-upgrades" +sidebar_label: "Application Stack Upgrades" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- + +WaveMaker platform is frequently updated to incorporate the latest developments in the underlying technology stack such as Spring, Hibernate, Angular etc. WaveMaker Apps are automatically upgraded by the platform to the latest version of the stacks that the platform ships. This is a major advantage for developers, as they do not have to make any changes in the applications manually. + +Deployed apps will not be affected by platform upgrades, and in case the deployed app needs to be upgraded as well, then it can be re-deployed.   How does a WaveMaker App compare with traditionally built app? + +The benefits of Rapid Application Development have a direct bearing on the cost and schedule of enterprise application development. In fact, organizations that used WaveMaker RAD Platform have experienced: + +- 67% faster application development than traditional software delivery +- 80% lesser coding required compared to traditional software development +- 75% lower maintenance costs than traditional software life cycle + +[![](/learn/assets/rad_benefits.png)](/learn/assets/rad_benefits.png) + +The following chart depicts performance comparison of an app built following the RAD approach using WaveMaker and a traditionally built app using AngularJS framework. The functionality of the app is designed to load several database records from a backend service, exposed as REST API to the UI layer, where the UI layer renders these records using widgets such as list, image, label, panel etc. + +[![](/learn/assets/perf_graph.png)](/learn/assets/perf_graph.png) + +Metrics such as page load time, memory consumed on the client side, page interaction response times and the number of backend service calls are plotted. As indicated in the figure above, the delta is very minimal and the application built with WaveMaker performs at par on all counts in comparison to the app built traditionally.    + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/build-app-using-low-code-approach.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/build-app-using-low-code-approach.md new file mode 100644 index 000000000..3004ff124 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/build-app-using-low-code-approach.md @@ -0,0 +1,21 @@ +--- +title: "How to build app using low-code approach in WaveMaker?" +id: "build-app-using-low-code-approach" +sidebar_label: "Build app using low-code approach" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- + +A major portion of the application’s code parts are auto-generated by the platform, leaving the business logic, rules and data flows to be coded by the WaveMaker App developers. (see here) UI layer is built such that, decisions to fetch or update the data to the backend services are made when the end-user interacts with widgets or other UI elements. Additionally, business logic functions either on the server-side or on the client-side are invoked at that time. In WaveMaker, this functionality is achieved through the Binding layer, using components known as ‘Variables’. + +Variables function by invoking the associated REST APIs on the server-side, invoking the client-side JavaScript events that are associated or bound through configuration, after the response is obtained. Variables play a significant role in binding the UI and the backend services layer together through configuration and events, eliminating the necessity to write a lot of code. + +Variables can be represented using a block with 3 faces, as in the picture below, representing the APIs invoked, events processed and the Model or Entity objects returned by the APIs. + +Essentially, the code is written on the server-side (primarily in Java) to process or compute data and on the client-side business logic functions are written (in JavaScript) to process data before it is sent to or after the response is returned from the backend services. + +This model offers a true low-code approach eliminating the need to build an entire framework of UI, backend and binding layers, completely removing the burden from developers to maintain lot of code, frameworks, their upgrades and compatibility issues.   + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/build-responsive-ui-using-visual-rad-approach.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/build-responsive-ui-using-visual-rad-approach.md new file mode 100644 index 000000000..067889424 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/build-responsive-ui-using-visual-rad-approach.md @@ -0,0 +1,27 @@ +--- +title: "How to build responsive UI using Visual RAD approach in WaveMaker?" +id: "build-responsive-ui-using-visual-rad-approach" +sidebar_label: "Build Responsive UI using Visual RAD Approach" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- + +The responsive design facilitates the apps to automatically adjust to the device screen size with various UI components adjusting to the available real estate. In WaveMaker, this is achieved through Bootstrap styling using the 12-column layout. + +[![](/learn/assets/Page_grid.png)](/learn/assets/Page_grid.png) + +Widgets are dragged and dropped into the 12-column grid containers, whose sizes cumulatively aggregate to 12 within a row. The bootstrap layouting system automatically renders the widgets in different devices based on the available real estate, usually stacking them on a mobile device, while they appear side by side when viewed on a desktop screen. + +[![](/learn/assets/widget_concept.png)](/learn/assets/widget_concept.png) + +In WaveMaker, a Page has a flexible layout structure separated from the main content area where the widgets are dropped. Separation of the layout i.e. left panel, header, footer etc. helps not only in achieving UI consistency but also in simplifying the page rendering across devices. + +[![](/learn/assets/Page_responsive.png)](/learn/assets/Page_responsive.png) + +Also, WaveMaker widgets embrace Android Material Design specification for visual design and building interaction across multiple devices. Android Material Design provides standard design guidelines for user interaction across mobile apps and modern web apps. + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[Design Overview](/learn/app-development/ui-design/design-overview/#app-ui-design) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/building-widget-extension-custom-widget.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/building-widget-extension-custom-widget.md new file mode 100644 index 000000000..843b94b11 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/building-widget-extension-custom-widget.md @@ -0,0 +1,31 @@ +--- +title: "How to build widget extensions or custom widgets?" +id: "building-widget-extension-custom-widget" +sidebar_label: "Building Widget Extension or Custom Widgets" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- + +In WaveMaker, widget extensions or custom widgets are built using specialized components known as Prefabs. Prefabs are reusable and distributable components that can be used across applications. + +#### Concept of Prefab + +Prefabs are like the pieces of the jigsaw puzzle or equivalent of lego blocks, which when put together offer powerful extended features of existing widgets or build an altogether new UI element by integrating with 3rd party libraries. + +[![](/learn/assets/prefab_concepts.png)](/learn/assets/prefab_concepts.png) + +Prefab may consist of all 3 layers of a WaveMaker App, combining the power of custom widgets with any integrated service, as shown below. + +[![](/learn/assets/prefab_layeredarch.png)](/learn/assets/prefab_layeredarch.png) + +Prefabs can be used: + +- As widget extensions by extending 3rd party JS libraries or UI widgets. For example, DataMaps built on top of d3 library can be used to build new widgets for doing geographic projections which will allow integration of data from any data source or backend service to the DataMaps. Or integrate Lightbox Image Viewer into WaveMaker App to preview images within the App. +- As API integrated components by combining with a WaveMaker UI component to customise built-in behavior. For example, WaveMaker List widget can be combined with Google Maps Prefab to form a composite UI component for marking the location of a selected item from the List. +- As backend service extensions by leveraging 3rd party Java libraries, for example, to work with JasperReports. + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[Prefab - Custom Widgets](/learn/app-development/custom-widgets/prefabs-overview)    + diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/customizing-app-to-your-own-branding.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/customizing-app-to-your-own-branding.md new file mode 100644 index 000000000..005ee645b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/customizing-app-to-your-own-branding.md @@ -0,0 +1,25 @@ +--- +title: "Can I customize the look and feel of the App to match the branding of my choice?" +id: "customizing-app-to-your-own-branding" +sidebar_label: "Customizing your app to your own branding standards" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- +Yes. WaveMaker Themes are based upon Bootstrap CSS markup. App developer can choose from a wide range of inbuilt Themes provided with WaveMaker. With a working knowledge of HTML, CSS, LESS and Grunt, app developer can build their own themes and import them into WaveMaker platform. These imported Themes will be available for use across the apps. + +Themes can be built either by + +- modifying an existing WaveMaker Theme as per requirements (WaveMaker Themes are available on WaveMaker Git repository), or +- using the bootstrap themes provided by Bootswatch. + +There are two ways Theme can be handled within WaveMaker apps: + +- At the App level, apply a selected Theme either inbuilt or custom built. This will allow for a consistent look and feel to your apps. +- At the Widget level, app developer can apply style properties to change the color, margins, alignment and much more. This can be applied for a specific, one-instance styling. + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[Applying Themes](/learn/app-development/ui-design/themes/#apply-theme) +[Creating Themes](/learn/app-development/ui-design/themes/#create-theme) +[Importing Themes](/learn/app-development/ui-design/themes/#import-theme) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/database-in-wavemaker.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/database-in-wavemaker.md new file mode 100644 index 000000000..659f5dc6e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/database-in-wavemaker.md @@ -0,0 +1,15 @@ +--- +title: "How to work with database in WaveMaker?" +id: "database-in-wavemaker" +sidebar_label: "What are Databases?" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) section for WaveMaker app development.   + +--- + +By importing database schema, WaveMaker automatically detects the entities, their associated relationships and generates the Entity-Relational model for building the business logic. CRUD APIs for entities and relationships are automatically generated, including relationship accessor APIs such as orders placed by customer, employees belonging to a department, and more. + +For more information, see [Integrating Web Services](/learn/app-development/services/web-services/web-services/#overview). + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/databases-supported-by-wavemaker-platform.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/databases-supported-by-wavemaker-platform.md new file mode 100644 index 000000000..1a8a52a44 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/databases-supported-by-wavemaker-platform.md @@ -0,0 +1,21 @@ +--- +title: "What databases are supported by WaveMaker Platform?" +id: "databases-supported-by-wavemaker-platform" +sidebar_label: "Databases Supported by WaveMaker Platform" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- +Following Databases can be used to build WaveMaker Apps: + +- MySQL +- PostgreSQL +- Oracle +- SQL Server +- DB2 +- HSQL + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[Supported Technologies](/learn/app-development/wavemaker-overview/supported-technologies/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/editing-generated-code-outside-platform.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/editing-generated-code-outside-platform.md new file mode 100644 index 000000000..f64d63e7b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/editing-generated-code-outside-platform.md @@ -0,0 +1,18 @@ +--- +title: "Can WaveMaker apps be modified outside the platform by manually editing the generated code?" +id: "editing-generated-code-outside-platform" +sidebar_label: "Editing the Generated code outside the Platform" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development. + +---      + +For WaveMaker apps a modular client-side code (AngularJS, CSS, and HTML) incorporating industry best practices is generated, thus making it Maven complaint. As such, for any WaveMaker app, a zip file can be generated which includes a pom.xml file. This zip file can be imported to any IDE like IntelliJ or Eclipse. The backend artifacts included in the zip file can be modified from the IDE. + +The app updated outside of WaveMaker can be reimported into WaveMaker to update the existing project or as a new project. + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[Extending Apps using IDEs](/learn/app-development/dev-integration/extending-application-using-ides/) + +   diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/index.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/index.md new file mode 100644 index 000000000..1749e2ccd --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/index.md @@ -0,0 +1,92 @@ +--- +title: "Frequently Asked Questions" +id: "index" +sidebar_label: "FAQs" +--- +Frequently asked questions cover everything you need to know about WaveMaker so you can develop apps like a pro.      + +## General +--- +#### [1. What is a WaveMaker App?](/learn/app-development/wavemaker-app-development-faqs/what-is-wavemaker-app) + +#### [2. What skills you need to build a WaveMaker app?](/learn/app-development/wavemaker-app-development-faqs/skills-need-to-build-wavemaker-app) + +#### [3. How does WaveMaker simplify app development using the RAD paradigm?](/learn/app-development/wavemaker-app-development-faqs/app-development-using-rad) + +#### [4. How to build app using low-code approach in WaveMaker?](/learn/app-development/wavemaker-app-development-faqs/build-app-using-low-code-approach) + +#### [5. Does WaveMaker use the model-first approach or the UI-first approach for RAD development?](/learn/app-development/wavemaker-app-development-faqs/model-first-or-UI-first-rad-development) + +#### [6. Can the App’s look and feel be modified or customized to match the branding of my choice?](/learn/app-development/wavemaker-app-development-faqs/customizing-app-to-your-own-branding) + +## Architecture +--- + +#### [7. What application architectures does WaveMaker Apps support?](/learn/app-development/wavemaker-app-development-faqs/wavemaker-application-architecture) + + +#### [8. Explain the WaveMaker Architecture.](/learn/app-development/wavemaker-app-development-faqs/wavemaker-architecture) + + +#### [9. How does WaveMaker support Micro-Services enabled architecture?](/learn/app-development/wavemaker-app-development-faqs/micro-services-enabled-architecture) + + +## Widgets and Services +--- + +#### [10. What are Widgets in WaveMaker?](/learn/app-development/wavemaker-app-development-faqs/widgets-in-wavemaker)    + +#### [11. How to build widget extensions or custom widgets?](/learn/app-development/wavemaker-app-development-faqs/building-widget-extension-custom-widget) + +#### [12. What are backend services?](/learn/app-development/services/creating-backend-services) + +#### [13. How to work with databases in WaveMaker?](/learn/app-development/wavemaker-app-development-faqs/database-in-wavemaker) + +#### [14. What databases are supported by WaveMaker Platform?](/learn/app-development/wavemaker-app-development-faqs/databases-supported-by-wavemaker-platform) + +#### [15. How Web Services work in WaveMaker?](/learn/app-development/wavemaker-app-development-faqs/web-services) + +#### [16. How Java Services work in WaveMaker?](/learn/app-development/wavemaker-app-development-faqs/java-services-in-wavemaker)   + +#### [17. How to integrate service in WaveMaker?](/learn/app-development/variables/data-integration) + + + +## Security +--- + +#### [19. How to enable Security for WaveMaker apps?](/learn/app-development/wavemaker-app-development-faqs/security-in-wavemaker) + + +#### [20. What type of security is provided for WaveMaker Apps?](/learn/app-development/wavemaker-app-development-faqs/security-provided-for-wavemaker-apps) + +## Mobile App +--- + +#### [21. How to build responsive UI using Visual RAD approach in WaveMaker?](/learn/app-development/wavemaker-app-development-faqs/build-responsive-ui-using-visual-rad-approach) + +#### [22. Can I build a mobile app with installer using WaveMaker and publish it to any App Store?](/learn/app-development/wavemaker-app-development-faqs/publishing-app-to-app-store)  + +#### [23. Can I publish the Mobiles apps built on WaveMaker to App Stores without any limitations?](/learn/app-development/wavemaker-app-development-faqs/publish-to-app-store-without-any-limitations) + + + +## Development and code +--- + +#### [24. Can multiple developers work on a WaveMaker app?](/learn/app-development/wavemaker-app-development-faqs/working-with-multiple-developers) + +#### [25. What libraries are used to build WaveMaker App runtime?](/learn/app-development/wavemaker-app-development-faqs/libraries-used-app-runtime) + +#### [26. Can WaveMaker apps be modified outside the platform by manually editing the generated code?](/learn/app-development/wavemaker-app-development-faqs/editing-generated-code-outside-platform) + +#### [27. Is the platform generated code readable and maintainable?](/learn/app-development/wavemaker-app-development-faqs/platform-generated-code) + + +## Licenses and other + +#### [28. Are there any licensing restrictions in re-distributing WaveMaker apps?](/learn/app-development/wavemaker-app-development-faqs/redistributing-licensing) + +#### [29. How are the application stack upgrades done?](/learn/app-development/wavemaker-app-development-faqs/application-stack-upgrades) + +#### [30. Is WaveMaker App scalable in terms of usage?](/learn/app-development/wavemaker-app-development-faqs/is-wavemaker-app-scalable) diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/is-wavemaker-app-scalable.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/is-wavemaker-app-scalable.md new file mode 100644 index 000000000..87a294d21 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/is-wavemaker-app-scalable.md @@ -0,0 +1,17 @@ +--- +title: "Is WaveMaker App scalable in terms of usage?" +id: "is-wavemaker-app-scalable" +sidebar_label: "Is WaveMaker App scalable" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- + +WaveMaker Apps are built to use stateless architectures making them ready for large scale container-based deployments. Large scale deployments needing high number concurrent requests and low response times can be achieved, by scaling apps to deploy on container based systems. + +[![](/learn/assets/scal_graphic.png)](/learn/assets/scal_graphic.png) + +WaveMaker App acts as a micro service with the REST APIs exposed and load-balanced when deployed on multiple containers. Since, there is no state associated on the server-side, the architecture allows for a high-scalable deployment with client-managed state (on the Angular side). + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/java-services-in-wavemaker.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/java-services-in-wavemaker.md new file mode 100644 index 000000000..68af7ea63 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/java-services-in-wavemaker.md @@ -0,0 +1,15 @@ +--- +title: "How Java Services work in WaveMaker?" +id: "java-services-in-wavemaker" +sidebar_label: "Java Services in WaveMaker" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) section for WaveMaker app development.    + +---    + +Custom backend services can be built in Java or Spring framework in the form of POJO objects. WaveMaker automatically generates REST APIs for every method exposed and takes care of JSON conversions when the data or the model objects are returned from these APIs and vice versa. + +For more information, see [Integrating Java Services](/learn/app-development/services/java-services/java-service/#overview). + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/libraries-used-app-runtime.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/libraries-used-app-runtime.md new file mode 100644 index 000000000..f9a804a48 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/libraries-used-app-runtime.md @@ -0,0 +1,22 @@ +--- +title: "What libraries are used to build WaveMaker App runtime?" +id: "libraries-used-app-runtime" +sidebar_label: "Libraries used to build WaveMaker App runtime" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- + +To build WaveMaker app, following libraries are used: + +- **AngularJS 1.x** version is used for front-end of an app. It constitutes the user interface, data binding, and events. Bootstrap provides diverse responsive design layouts for various form factors. +- **Hibernate and JPA** provide standardized ORM layer and Entity model for database interaction. +- **Spring Framework** enables the back-end service layer in Java to facilitate dependency injection, REST controllers, security, etc. +- **Cordova Framework** provides easy access to mobile device features and native installer creation using the appropriate SDK’s. + +[![](/learn/assets/OS_Technology_Stack.png)](/learn/assets/OS_Technology_Stack.png) + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[Technology Stack](/learn/app-development/wavemaker-overview/platform-overview/#technology-stack) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/micro-services-enabled-architecture.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/micro-services-enabled-architecture.md new file mode 100644 index 000000000..33f08f090 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/micro-services-enabled-architecture.md @@ -0,0 +1,19 @@ +--- +title: "How does WaveMaker support Micro-Services enabled architecture?" +id: "micro-services-enabled-architecture" +sidebar_label: "Micro-Services enabled architecture" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- +[![](/learn/assets/services_concept.png)](/learn/assets/services_concept.png) + +To support micro-services architecture, WaveMaker uses an API-driven app development approach wherein REST APIs are auto-generated for the application. Every backend services such as Database Entity, Queries or Custom Java code, that is integrated into an application generates REST APIs. Some of these APIs are available for further customization based on the app integration needs. + +Custom queries, procedures, and Java Services can be used to extend the app functionality. For all these services, REST API is auto-generated using Spring-REST/Swagger. + +UI components via Variables interact with REST API layer to access these services. + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[API Designer](/learn/app-development/services/api-designer/api/) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/model-first-or-UI-first-rad-development.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/model-first-or-UI-first-rad-development.md new file mode 100644 index 000000000..1f9f06be8 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/model-first-or-UI-first-rad-development.md @@ -0,0 +1,29 @@ +--- +title: "Does WaveMaker use the model-first approach or the UI-first approach for RAD development?" +id: "model-first-or-UI-first-rad-development" +sidebar_label: "Model First or UI First" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- + +A WaveMaker App is built in 3 layers, i.e. front-end UI layer, binding layer and the backend services layer. Apps can be built using model-first approach and generating the needed backend services and then composing the User Interface. Alternatively, UI widgets can be put together as a template and later be bound to the backend services to complete the business logic flows. + +However, there are certain advantages with the model-first approach as the UI layer can be auto-generated from the model, cutting the development time further down. For example, a Data Table widget is auto-generated by integrating the UI actions like New, Update, Delete to automatically invoke the generated CRUD APIs of the Entity, say Employee. + +## A. Model-first Approach + +In the Model-first approach, backend services such as Entities, and CRUD operations are auto-generated along with the source files, metadata, schema etc. The corresponding REST APIs are also generated, and the same can be used for binding. [![](/learn/assets/backend_model.png)](/learn/assets/backend_model.png) + +After the backend services and the model are generated, UI layer is built by creating pages. Pages are composed with widgets and the Page Layout defines the structure of a page i.e. header, left panel, top navigation etc. + +[![](/learn/assets/UI_design-1.png)](/learn/assets/UI_design-1.png) + +Now these widgets are integrated with the backend services using data components known as ‘Variables’. Variables can be configured to work with any backend service supported by WaveMaker. Variables are client-side components residing within the browser or client-runtime, and make use of the underlying REST APIs of the application to talk to the backend services. + +## B. UI-first Approach + +In the UI-first approach, UI layer is composed with the widgets first and then the backend services are created to be bound with the front-end component. UI-first approach is closer to the traditional way of development, separating the UI from the backend services development. However, the low-code advantages are still applicable by using the binding approach, where UI widgets are bound to the backend services without writing any code.    + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/platform-generated-code.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/platform-generated-code.md new file mode 100644 index 000000000..050386abe --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/platform-generated-code.md @@ -0,0 +1,30 @@ +--- +title: "Is the platform generated code readable and maintainable?" +id: "platform-generated-code" +sidebar_label: "Maintaining Platform Generated Code" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- + +WaveMaker App is built by drag-n-drop of Widgets, a simple HTML markup is generated. Any changes to the look-n-feel can be done using the Style properties exposed for each Widget. Though not necessary or advisable, the page markup can be further tweaked to suite app requirements. + +Similarly, when a Backend Service, like a database, is integrated into a WaveMaker App, ORM artifacts are auto-generated. The source code is generated following the design best practices, consisting of the DAO, Service Layer & REST APIs with each layer having a specific responsibility: + +- Layer 1: REST Controller is responsible for transporting the data between client and server, authorization of APIs & marshaling and unmarshaling of the model to JSON etc. +- Layer 2: Service Layer is responsible for validating the inputs and transaction management +- Layer 3: DAO Layer is responsible for interacting with the underlying database + +Following is the code snippet of the generated Entity DAO object, a JPA entity model using the standards based annotations, getter & setter methods. + +Additional artifacts, such as API definitions in standard Swagger notation, configuration files as Spring XML files and properties files and Maven pom.xml that defines application dependencies are all auto-generated and available for maintenance outside the platform.   Can the apps built using WaveMaker be deployed on any App Server? + +WaveMaker platform generates a standards based WAR file, which can be used to deploy App to any Java web server such as Tomcat, WebSphere, WebLogic, Pramati Server, JBoss etc. + +By default, WaveMaker Apps can be deployed to WaveMaker Cloud platform. Optionally you can configure your app to be deployed to your AWS or Azure or Google Cloud accounts. + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[Deployment to Web Server](/learn/app-development/deployment/deployment-web-server/) + +   diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/publish-to-app-store-without-any-limitations.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/publish-to-app-store-without-any-limitations.md new file mode 100644 index 000000000..faf31a98b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/publish-to-app-store-without-any-limitations.md @@ -0,0 +1,18 @@ +--- +title: "Can I publish the Mobiles apps built on WaveMaker to App Stores without any limitations?" +id: "publish-to-app-store-without-any-limitations" +sidebar_label: "Can I Publish to App Store without any Limitations?" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- +The Mobile Themes give native look-n-feel of the same page based on the Platform (IOS, Android etc.). Most importantly themes adhere to design guidelines of the Platform, for example, the Page Title in Android platform needs to be left aligned while for iOS it needs to be centered or the menu tab needs to be rendered differently. + +[![](/learn/assets/mobile_native_UIlooknfeel.png)](/learn/assets/mobile_native_UIlooknfeel.png) + +Similarly, various widgets like date picker, drop down menu need to be rendered differently based on the platform. All these aspects are taken care of by the inbuilt Mobile Themes provided by WaveMaker. [![](/learn/assets/mobile_native_UIcontrols.png)](/learn/assets/mobile_native_UIcontrols.png) + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[Native Device Support](/learn/hybrid-mobile/native-device-support/)    + diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/publishing-app-to-app-store.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/publishing-app-to-app-store.md new file mode 100644 index 000000000..013094690 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/publishing-app-to-app-store.md @@ -0,0 +1,22 @@ +--- +title: "Can I build a mobile app with installer using WaveMaker and publish it to any App Store?" +id: "publishing-app-to-app-store" +sidebar_label: "Publishing an app to App Store" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- +The Automated Build process for a mobile application within WaveMaker can be used to generate a .apk (Android application package) or .ipa file (iOS App Store package). Downloading Cordova/PhoneGap compatible .zip files can be used to build systems manually for Android/iOS platforms. + +[![](/learn/assets/Hybrid_App_Installer.png)](/learn/assets/Hybrid_App_Installer.png) + +WaveMaker supports the build for mobile applications in the following three ways: + +- Build for Android to generate APK files which can be signed and hosted on PlayStore. +- Send to PhoneGap for a complete package needed to build both apk/ipa files for Android and iOS platforms. +- Manual Build for a downloadable zip file which can be further developed to be hosted on any mobile platform. + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[Building Mobile Apps](/learn/hybrid-mobile/building-hybrid-mobile-apps/)    + diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/redistributing-licensing.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/redistributing-licensing.md new file mode 100644 index 000000000..19dc57ed7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/redistributing-licensing.md @@ -0,0 +1,13 @@ +--- +title: "Are there any licensing restrictions in re-distributing WaveMaker apps?" +id: "redistributing-licensing" +sidebar_label: "Licensing Restrictions for re-distributing" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- + +WaveMaker App contains distributable components which are completely conforming to the open-standards based licenses such as Apache 2.0, MIT etc. WaveMaker platform’s runtime components are all open-sourced under Apache 2.0 license giving complete control to the app developer for distributing rights.    + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/security-in-wavemaker.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/security-in-wavemaker.md new file mode 100644 index 000000000..ec9599cfa --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/security-in-wavemaker.md @@ -0,0 +1,15 @@ +--- +title: "How to enable Security for WaveMaker apps?" +id: "security-in-wavemaker" +sidebar_label: "Enabling security for WaveMaker apps" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development. + +--- +     +Apps can be configured to authenticate using standard identity providers like LDAP, Active Directory or a database. Role based access control can be configured for accessing backend services, APIs, UI widgets etc. Additionally, web apps are protected against top 10 OWASP vulnerabilities, such as CSRF, XSS, SQL injection attacks etc. It takes a lot of effort and time for app developers to build all of these security integrations into an app built using traditional development approach. + +For more information, see [Security Services](/learn/app-development/app-security/app-security/). + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/security-provided-for-wavemaker-apps.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/security-provided-for-wavemaker-apps.md new file mode 100644 index 000000000..27452dafe --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/security-provided-for-wavemaker-apps.md @@ -0,0 +1,23 @@ +--- +title: "What type of security is provided for WaveMaker Apps?" +id: "security-provided-for-wavemaker-apps" +sidebar_label: "Security Provided for WaveMaker Apps" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.   + +--- +The WaveMaker security feature offers comprehensive security solutions to secure the apps developed. WaveMaker offers application level security and the two major areas are “Authentication, who has access and “Authorization”, who can access what. In practice, once WaveMaker security is enabled, both authentication and authorization are available to be taken advantage of and are intertwined. + +By the process of “Onboarding,” end-users data is retrieved from various providers like DB, LDAP, AD or any custom provider. This data includes roles and role groups information. Then, Authentication is done based on user credentials, which are obtained from the security provider; and Authorization or role-based access control (RBAC) can be set up for various app resources such as widgets, pages, data, and APIs through configuration. + +Apart from the above-mentioned security providers, WaveMaker supports Single Sign-On using Central Authentication Service (CAS), any Security Assertion Markup Language (SAML) 2.0 compliant provider and Token-based authentication for API requests. Cross-site Scripting (XSS) and Cross-Site Request Forgery (CSRF) attacks, listed on OWASP top 10 security, can also be prevented on WaveMaker Apps. + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[App Authentication](/learn/app-development/app-security/authentication/) +[App Authorization](/learn/app-development/app-security/authorization/) +[Single Sign-On using CAS](/learn/app-development/app-security/central-authentication-system/) +[OWASP Support](/learn/app-development/app-security/owasp/) +[SAML Integration](/learn/app-development/app-security/saml-integration/) +[Token Based Authentication](/learn/app-development/app-security/token-based-authentication/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/skills-need-to-build-wavemaker-app.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/skills-need-to-build-wavemaker-app.md new file mode 100644 index 000000000..57270f06d --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/skills-need-to-build-wavemaker-app.md @@ -0,0 +1,30 @@ +--- +title: "What skills you need to build a WaveMaker app?" +id: "skills-need-to-build-wavemaker-app" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) section for WaveMaker app development.    + +--- + +To build a WaveMaker app, the first time developer needs to inherit the following skills: + +## Technical Skills + +- Basic understanding of HTML, CSS and JavaScript +- Basic knowledge of Database, SQL syntax, relationships etc. +- REST API basics, AJAX +- Basic app design, understanding of various artifacts etc. +- Java syntax, class, methods and annotation for building backend services + +## Analytical Skills + +To develop an application it is essential to analytically think in terms of functionality, design, and implementation. In order to build an app, it is crucial to have answers to the following questions: + +- What is the purpose of the application? +- Who is the end-user of the application? +- What level of security is required for the application? + +### See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[Pre-Requisites](/learn/app-development/wavemaker-overview/pre-requisites/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/wavemaker-application-architecture.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/wavemaker-application-architecture.md new file mode 100644 index 000000000..3724b2189 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/wavemaker-application-architecture.md @@ -0,0 +1,27 @@ +--- +title: "What application architectures does WaveMaker Apps support?" +id: "wavemaker-application-architecture" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- + +WaveMaker built applications use the modern application architectures such as: + +## Micro Services enabled architecture +Micro Services enabled architecture allowing a large application to be built as smaller scalable services, which are integrated through REST APIs. WaveMaker applications use session-less architecture allowing them to be scaled up as the app needs or the number of users grow using docker containers [Micro Services](https://martinfowler.com/articles/microservices.html). + +## Single Page Applications (SPA) +Single Page Applications (SPA) load a single HTML front-end with interaction built using JavaScript & AJAX. For more information, see [single page applications](https://msdn.microsoft.com/en-us/magazine/dn463786.aspx). Front-end is clearly separated from the back-end services using REST APIs. + +A typical application can be demarcated into three parts: +- Client-side app component that works on the device used. +- Central/remote Server component that provides backend services. +- Both these components separated by well-defined REST API contract. + +## Hybrid Mobile App +Hybrid Mobile App for building mobile Apps using Cordova which provides the native wrapper for interacting with the device capabilities and an installer for the device. WaveMaker developers build Mobile apps just the way they build web apps using drag-n-drop visual RAD approach and integrating the mobile front-end with the backend services using REST APIs. + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/wavemaker-architecture.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/wavemaker-architecture.md new file mode 100644 index 000000000..81f46ee79 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/wavemaker-architecture.md @@ -0,0 +1,14 @@ +--- +title: "Explain the WaveMaker Architecture" +id: "wavemaker-architecture" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development. + +--- +      +Apps built in WaveMaker follow modern application architectures, separating the UI and the backend layers with well-defined REST APIs. This model gives the needed scalability as the application grows and follows best practices in terms of design and performance. In a traditional development model, such best practices need to be acquired by the development teams and a certain level of expertise is needed to build apps to meet industry standards. + +For more information, see [Integrating Web Services](/learn/app-development/services/web-services/web-services/#overview)    + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/web-services.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/web-services.md new file mode 100644 index 000000000..adb8e242b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/web-services.md @@ -0,0 +1,15 @@ +--- +title: "What are WaveMaker Web Services?" +id: "web-services" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) section for WaveMaker app development.      + +--- + +External Web Services such as REST, WSDL or WebSocket can be imported into the App by just providing the URL, parameters and any additional configuration. WaveMaker takes care of type conversions such as Java to JSON, XML to JSON and model object creation for the web service returned responses, making these services readily available for integration with widgets and other business logic components. + +For more information, see [Integrating Web Services](/learn/app-development/services/web-services/web-services/#overview). + + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/what-is-wavemaker-app.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/what-is-wavemaker-app.md new file mode 100644 index 000000000..c8f355b51 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/what-is-wavemaker-app.md @@ -0,0 +1,23 @@ +--- +title: "What is a WaveMaker App?" +id: "what-is-wavemaker-app" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) section for WaveMaker app development.    + +--- + +**WaveMaker App** can either be a web responsive application or a hybrid mobile application built using the low-code or rapid app development approach. WaveMaker App is built as a single HTML Web App, with clear separation of User Interface (UI) layer and the backend services layer using REST APIs. The UI layer is built using the visual RAD approach, with drag-n-drop of widgets onto the Canvas. Later, these widgets are integrated with the backend services, to fetch and update data. [![](/learn/assets/3layered_arch.png)](/learn/assets/3layered_arch.png) WaveMaker App is composed of 3 layers: + +## UI Layer** + +UI layer is built with Pages, which are composed with widgets using visual drag-n-drop approach. + +## Binding Layer +Binding layer integrates backend services with the front-end UI layer through REST APIs. + +## Services Layer +Service layer represents backend services auto-generated from databases, external web services or custom Java services, and more. + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[Platform Overview](/learn/app-development/wavemaker-overview/platform-overview/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/widgets-in-wavemaker.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/widgets-in-wavemaker.md new file mode 100644 index 000000000..079b11a75 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/widgets-in-wavemaker.md @@ -0,0 +1,14 @@ +--- +title: "Widgets in WaveMaker" +id: "widgets-in-wavemaker" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) section for WaveMaker app development. + +--- + +Most of the HTML and JavaScript code required to build widgets such as Form, List, button, date etc. is generated by the platform. Each widget exposes dataset for “binding”, and this dataset can be bound to any backend services such as database entities, queries, external web services, custom backend services, and more, without having to write any code. + +For more information, see [Widgets](/learn/app-development/widgets/widget-library/) + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/working-with-multiple-developers.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/working-with-multiple-developers.md new file mode 100644 index 000000000..ae71e872a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-app-development-faqs/working-with-multiple-developers.md @@ -0,0 +1,16 @@ +--- +title: "Can multiple developers work on a WaveMaker app?" +id: "working-with-multiple-developers" +sidebar_label: "Working with Multiple Developers" +--- +See the [FAQs](/learn/app-development/wavemaker-app-development-faqs) for WaveMaker app development.      + +--- +Collaborated and continuous development is part of WaveMaker platform. WaveMaker Apps can be shared with multiple users. WaveMaker’s integrated Version Control System (Git) allows pulling changes, merging and resolving conflicts. Apps can also be pushed to External Repos like GitHub or Bitbucket. + +Unlike the conventional method where every file or artifact goes through the review/merge process, all the generated code artifacts are auto-merged by the platform, eliminating this responsibility from the developer. As the major portion of the auto-generated code is auto-merged, the developer needs to only review/merge the files which are related to business logic or other files which are modified manually. + +## See Also +[FAQs](/learn/app-development/wavemaker-app-development-faqs) +[Developer Collaboration](/learn/app-development/dev-integration/developer-collaboration/#project-sharing) +[Code Sharing](/learn/app-development/dev-integration/developer-collaboration/#vcs) diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/artifacts-repository.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/artifacts-repository.md new file mode 100644 index 000000000..eb3eb0a0e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/artifacts-repository.md @@ -0,0 +1,198 @@ +--- +title: "Artifacts Repository" +id: "artifacts-repository" +--- +--- + +**Artifact Repository** is a collection of Artifacts or resources used across application development lifecycle in WaveMaker platform. It allows for easy exploration and discovery of Artifacts available to the developer network. These Artifacts include: + +- **Prefabs**: Prefabs are a collection of one or more widgets that are bound to APIs or services. +- **Project Shell**: Project Shell is an app with functionality that is common to multiple apps across the teams. This can be used as a starting point in app development. +- **Core Project**: These projects act as the base with all the common functionalities. This allows multiple teams to work collectively on top of it. To know more, see [Core and IMPL Projects](/learn/app-development/core-implementation/core-and-implementation-projects/). +- **Implementation (IMPL) Project**: These projects are created as child projects of the Core project to add more features or customizations. Changes made to the Core project can be pulled into the IMPL projects periodically, making reusability seamless and boosting team collaboration. To know more, see [Core and IMPL Projects](/learn/app-development/core-implementation/core-and-implementation-projects/). +- **Template Bundles**: A template bundle is a collection of templates - a re-usable arrangement of one or more widgets in the page content that together capture the purpose of the page. +- **Themes**: Themes are style elements that work at the widget or UI component level. Themes help provide a consistent look and feel to your application. + + +Each of the above Artifacts has a workspace to develop the Artifact and then publish it for other developers across the team to import/use them. + +## Artifact Publishing Mechanism + +There are three ways in which an Artifact can be published: + +1. **Publish to Project**: This will allow the Artifact developer to send it to a specific project for testing purposes. +2. **Publish to Team** (only for team version): To make the Artifact available for the entire team for all applications to use, it needs to be published to the Team. After publishing, the Team Admin or Product Owner approves the Artifact for use within the team. +3. **Publish to Workspace** (only for non-team version): Once tested and verified, it can be used for any project under development. This is done by publishing the Artifact to the developer's workspace and made available for any project he/she is currently working on. + +Each of the Artifacts has a slightly different publishing flow as described in the sections for [Prefab](#prefab-publishing), [Project Shell] +(#project-shell-publishing), [Core](#core-publishing), [Template Bundle](#template-bundle-publishing), and [Themes](#theme-publishing). + +Once published the Artifacts can be viewed from the Artifacts dialog inside project settings. + +![](/learn/assets/artifact-sharing/artifacts-access.png) + +## Prefab Publishing + +Prefab is developed from the Project Workspace, similar to any other app development, and then made available to other developers. ![](/learn/assets/artifact-sharing/prefab-publish-1.png) Publishing states for a Prefab include: + +- **Publish to Team** (only for team version) – Approval by Team Admin. Once approved, Prefab has to be explicitly be imported for use within an application. +- **Publish to Workspace** (only for non-team version) - Once published to workspace the Prefab will implicitly be available for use across all projects within the developer's workspace. +- **Publish to Project** (both team and non-team versions)– This will result in the Prefab appearing in the specified project with a MOD tag. This can be used for testing purposes before publishing the Prefab. + +For more information, see [Creating and Publishing Prefabs](/learn/app-development/custom-widgets/creating-prefabs/). + +## Project Shell Publishing + +A project shell is created by the App Owner from the studio workspace, by exporting the project being developed as a shell. + +![](/learn/assets/artifact-sharing/publish-shell.png) + +### Export Project As Shell + +Export Project As Shell behaves differently for the team and non-team versions: + +- **Team version**: Once the developer exports a project as Shell to Team, they will be prompted to enter the publishing information, see [Artifact features](#artifact-features) for more information. The Team Admin has to [approve or reject](#artifact-states) the Shell as with any other Artifact. Once approved, developers can select the Shell when creating new projects. + +- **Non-Team version**: Export Project as Shell to Workspace will allow the developer to select the Shell when creating new projects within their workspace. + +For more information, see [Creating and Publishing Project Shell](/learn/app-development/ui-design/project-shells/). + +## Core Publishing + +A Core project is created by the application owner in the studio workspace by publishing an application to teams as Core. This becomes the base for many IMPL projects that can be created by team members. + +For more information, see [Core and Implementation Projects](/learn/app-development/core-implementation/core-and-implementation-projects/). + +:::note +For teams with the App Customization option enabled, which allows the creation of Core and IMPL projects, shells will no longer be supported. Existing shells must be manually published as Core projects. +::: + +## Template Bundle Publishing + +Template Bundle can be created from the Project Workspace using the Template Bundles tab. The Template Bundles publishing process is different for the team and non-team versions: + +- **Team version**: Once developed, Template Bundles can be published **To Team**. + +![](/learn/assets/artifact-sharing/publish-template.png) + +The developer will be prompted to enter the publishing information, see [Artifact features](#artifact-features) for more information. The Team Admin has to +[approve or reject](#artifact-states) the Shell as with any other Artifact. Once approved, the Template Bundle will appear in the Page Creation dialog for selection by the developers. +- **Non-team version**: The developer needs to export the Template Bundle as zip file and then import it in any application within their Dashboard. + +![](/learn/assets/artifact-sharing/publish-template-ws.png) + +To know more about creating and publishing Template Bundles, [click here](/learn/app-development/ui-design/page-concepts/page-templates/) + +## Theme Publishing + +Themes can be built by setting up WaveMaker Theme Repository and using Grunt commands. + +- **Team Version**: Themes can be published using the Export > Theme to Team option: + +![](/learn/assets/artifact-sharing/theme-publish.png) + +- **Non-team Version**: There is no Theme publish option for non-team version, the theme zip file generated needs to be imported from the Themes dialog. + +To know more about creating and publishing Themes, [click here](/learn/app-development/ui-design/themes/) + +## Artifact Flow in Team Version + +Artifact flow includes creating, publishing, and sharing Artifacts and applies only to the Team version of WaveMaker. + +### Artifact States + +When publishing to Team Artifact goes through several stages: + +![](/learn/assets/artifact-sharing/artifact-publishing.png) + +- **In Development**: Only the developer can work on it. It could be a new Artifact or a new version of the existing Artifact. +- **UnPublished**: The developer has published an artifact and applied for approval. EDN admin takes the next action. +- **Rejected**: Rejected by the EDN Admin, the developer can rectify/modify the Artifact and re-publish it. +- **Approved**: Once approved by the EDN Admin, the Artifact is available in the Artifact repository. + +![](/learn/assets/artifact-sharing/artifacts-pending.png) + +### Artifact Features + +Each Artifact needs the following information for proper tracking and identification from within the repository: + +![](/learn/assets/artifact-sharing/artifact-repository.png) + +- **Tag**: this will be useful for searching. Each Artifact can have multiple tags. +- **Category**: this is used for grouping and is typically defined by EDN Admin and developers associate the Artifact with a given category at the time of publishing. The category can be selected from the available list or a new category can be entered. A new category needs to be approved by the EDN admin. +- **Version Number**: Each Artifact is associated with a version automatically during publishing. +- **Change Log**: These include the comments that the developer needs to add before publishing the Artifact. + +### Artifact Publishing + +Artifacts are created and published to make them available in the [ProjectsHub](/learn/blog/2024/03/04/wavemaker-11-6-release#introducing-projectshub). You can update the Artifact and publish it with updated version details. + +1. In ProjectsHub, go to Prefabs and create or open a Prefab. +2. Click **Publish** and enter the Category, Version, and Change Log. In case this Artifact has a dependency on other Artifacts like, Project Shell using a Prefab, the dependencies are listed here. +3. Next, add Tags to aid in the discovery process of the Artifact. It also lists the Metadata like the platform version it was developed on. This information is generated by the platform by default. +4. Details in **Documentation** are populated automatically by the platform, from the configuration settings entered at the time of the Prefab development. Any changes to this need to be done at the Prefab development time. +5. In **Summary**, verify the details before proceeding with publishing. Click **Publish**. + + + +Once published the Artifacts can be viewed from the Artifacts dialog. + +![](/learn/assets/artifact-sharing/artifacts-access.png) + +#### Artifacts Dialog + +Artifacts dialog will list all the Artifacts available with details like + +- **Basic**: Includes the category, publisher, changelog, tags, dependency information, and metadata information +- **Version History**: Includes version history of the Artifact. +- **Documentation**: Includes properties, methods, and event details. + +Prefabs can be imported from this dialog. Other Artifacts are available for use as soon as EDN Admin approves the Artifact. + +#### Artifact Updates + +Every time there is a change or modification in an Artifact, it needs to be published again with updated version number. When a developer opens a project using the updated Artifact, Artifact updates are prompted. The developer can choose to update, downgrade, or ignore. Alternatively, notifications will be pushed for the developer within the studio to take action on Artifact upgrades. + +![](/learn/assets/artifact-sharing/artifacts-updates.png) + +### Artifact Management + +You can create and share Artifacts on your device and with your team members. This feature is now enhanced by allowing you to share Artifacts across different environments. + +With this enhancement, you can create an Artifact in your environment, and after exporting it, you can access the Artifact in your [Enterprise Marketplace](/learn/app-development/custom-widgets/enterprise-marketplace/). This process helps in improving collaboration across environments. + +Artifact Management starts from creating an Artifact to accessing it in a different environment. This process can be categorized into two stages. + +- **Pre-development**: This involves defining the Categories, Custom Metadata, and importing Artifacts. These activities are accessed from Launchpad by the [Super admin](/learn/on-premise/configure/config-users-auth-providers/#make-user-as-a-super-admin). + +- **Post-development**: This involves reviewing, approving/rejecting, and exporting Artifacts. These activities are accessed from the Team Portal by the team admin. + +#### Exporting Artifact To Another Environment + +You can export the approved Artifacts and publish its Core project in the Team Portal. It can be shared with any environment by providing the WaveMaker Enterprise (WME) domain address and its access token. This ensures secure collaboration between environments. + +:::note +Sharing Artifacts is supported for only WME users. +::: + +1. Go to **Menu** icon > **Team Portal** to find the Artifacts. +2. In **Prefab Artifacts**, go to the **Approved Artifacts** where we can select the Artifact to share. +3. Click the **Export** icon to export the Artifact to another environment. Select the version that you wish to export. +4. Add the WME host address. You can get the Access token from the prompted page. +5. Click Export which exports the selected version to the provided WME environment. + +:::note +In case of dependent Prefabs, you can export a Prefab only after its dependencies are exported previously to the target WME environment. +::: + + + +#### Importing Artifact + +Artifacts exported from other WME environments will be available in the [Enterprise Marketplace](/learn/app-development/custom-widgets/enterprise-marketplace/) and can be accessed by all the teams in the environment. + +- **Prefabs**: These are listed in the studio Artifacts section under Marketplace. +- **Core projects**: Core projects are listed along with other Core projects in the Core Selection section during the application creation. + +Once a new version is imported the update flow is triggered. To understand the steps to update, see [Fetching Core Upgrades](/learn/app-development/core-implementation/core-and-implementation-projects/#fetching-core-upgrades-in-impl-project). + diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/faqs-11.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/faqs-11.md new file mode 100644 index 000000000..d20a20780 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/faqs-11.md @@ -0,0 +1,159 @@ +--- +title: "FAQs of WaveMaker 11" +id: "faqs-11" +sidebar_label: "FAQs 11" +--- +--- + +WaveMaker Studio is now available as WaveMaker 11 GA. Since the release, we have received many questions about the release. We have tried our best to cover some frequently asked questions here. If you still have more questions, write to us at support@wavemaker.com. + +## General + +--- + +### What is Multi-version Studio? + +Multiple versions of Studio in a single environment allow you to simultaneously build applications in either of the Studio versions, including WaveMaker 10.x and WaveMaker 11.x. Application cards in Studio show Platform Version. + +![multi-version studio](/learn/assets/converts-into-two-project-cards.png) + +### Why do we include Multi-versioned Studio? + +With the WaveMaker 11 release, we moved to Java 11 from Java 8, which impacts your apps' CI/CD pipelines. + +Therefore, your CI/CD infrastructure must be migrated to Java 11 to build and deploy WaveMaker 11 apps. + +For this reason, we introduced a multi-version Studio to give you the time it may take from your end, giving you an explicit option to Migrate Apps to 11.x. + +### Did WaveMaker stop supporting Cordova apps? + +We Introduced React Native framework as part of the WaveMaker 11 release. However, please note that Web and Cordova Mobile frameworks are stable and working just like in the earlier versions and we continue to support them. + +### Can we start building Web and Cordova App in 11.x? + +Yes. WaveMaker 11 is as stable as other releases of Web and Cordova mobile app development platforms. + +### How can we migrate our projects to the 11.x version? + +Follow this migration guide: +https://docs.wavemaker.com/learn/how-tos/upgrade-guide-wavemaker-10-to-11 + +### Can multiple developers work on migration? + +Yes. The migration project can be shared with contributors, and any of your team members can fix migration issues. +However, actions like **Start Migration** and **Finish Upgrade** can only be done by **Project Admins**. + +## Projects and Applications + +--- + +### Will the WaveMaker 11 release impact the existing projects? + +No, it will not impact, but the projects will still run on Java 8. Migration has to be initiated explicitly. Your existing deployments, including Demo and Phase, will continue to work like before. + +Follow the migration guide for more information. + +### Which version project gets created when creating a new project? + +From WaveMaker 11 onwards, when you create a new project: + +1. It creates a WaveMaker 11.x project by default. +2. Default Mobile Apps are React Native. +3. You can create Cordova-based apps by using the link in the project creation dialogue. + +### Can we create 10-version projects? + +No. You can use the existing WaveMaker 10.x apps but can't create a new 10.x app. + +### What happens when you import WaveMaker 10.x application zip? + +WaveMaker 10.x application imports as 10.x project only. Migration to 11.x has to be initiated explicitly. + + +## Prefabs and Template Bundles and Project Shells + +--- + +### Do we need to migrate Prefabs/Project Shell/Template Bundles? + +Yes, just like any application. + +### Can I use WaveMaker 10.x published prefabs in 11.x applications? + +Yes, WaveMaker 11 apps can consume 10.x prefabs, but not vice versa. + +### Should I migrate Prefab projects first or applications? + +We suggest migrating applications first and then Prefabs. This is because you can use 10.x prefabs in WaveMaker 11.x app projects. + +### Naming versions when publishing a Prefab from an ongoing Migration project? + +The Studio will prompt an incremental version always. So, we recommend starting with a new Major version for an ongoing migration project. + +For example, if 10.x latest published version is 1.6, we suggest using 2.0 when publishing from the ongoing migration project. + +### Should you continue to publish Prefabs to the Team from 10.x Project while Migration is going on? + +Yes, however, implicitly provide different versions for both 10.x and 11.x published Prefabs as specified in the [previous point](#naming-versions-when-publishing-a-prefab-from-an-ongoing-migration-project). + +For example: if the latest published version of the 10.x app is 1.6, continue as 1.7 for 10.x Prefabs. + +### How to use migrated Prefabs in the project? + +A new version will be published in Teams. + +- When opening a project, the dialogue will show a new version option to upgrade. +- Or, in Studio, go to **Prefabs** -> **Import** dialogue. + +## Project Branches + +--- + +### What is the impact on Project Branches? + +Nothing. + +- Project branches will remain on the same platform version, 10.x. +- Migration can be initiated for the Master branch project only. + +:::note +Ensure merging all feature branches into master before initiating the project migration. +::: + +- Once the migration is completed, recreate project branches or merge branches outside Studio. + +### I have the Prefab project branch for a hotfix. What happens to it? + +Similar to applications, you can continue to patch it by pushing fixes from Studio. But, we recommended merging/recreating after the migration of the master Project. + +## Deployments + +--- + +### What happens to the existing deployments Demo/QA/External Cloud? + +They will continue to work like before. The same will be connected after the migration is complete. + +### Can I deploy an application to Demo/A Phase during migration? + +Yes, that helps in integration testing. + +### Should you make any changes to the deployment lifecycle or CI-CD pipeline? + +No changes are needed for 10.x applications. + +However, 11.x applications must use Java 11 and Servlet 4.0 (Tomcat 9, etc.) in their CI/CD environment. + +Therefore, both build and runtime environments must be changed. + +### I have deployed my application into AWS/GCP/Azure from Appsportal. What happens to it? + +It will continue to work. You can patch by pursuing fixes to the 10.x project. When the migration completes, it will connect to the same Instance. + +## Support and GA + +--- + +### How long you'd get support for 10.x projects? Will the projects be migrated to 11 automatically? + +If you do not update your projects within the given three months, the projects automatically upgrade to WM 11.0, and the older version projects move to the archived location. Therefore, you could lose the opportunity to manage individual versions of your app with our multi-version Studio. \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/localization.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/localization.md new file mode 100644 index 000000000..d4e6d7f1f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/localization.md @@ -0,0 +1,134 @@ +--- +title: "Localization" +id: "localization" +--- +--- +Localization is the adaptation of a product or service to meet the needs of a particular language, culture or desired populations’ look and feel. In WaveMaker, localization can be achieved at two levels: + +1. **Application Localization** which is the process of rendering your app in multiple languages. This is supported in the following ways: + + - From Project Settings, by setting the **default language** and date time formats, you can ensure that the app user gets to work in the set language and locale. For more information, see ([click here for more](/learn/how-tos/setting-language-date-format/)). + - Using the **Select Locale** widget end user can choose the language to render the application in ([click here for more](/learn/app-development/widgets/form-widgets/select-locale-usage/)). + + For more information, see [App Localization](/learn/how-tos/localization-wavemaker-apps/). + +2. **Platform Localization** can be used to enable the app developers to develop in their native language. This feature is available only in the Enterprise version. This process is discussed in detail in this document ([click here for more](#platform_locale)); + +## Platform Localization + +:::note +Available only for Enterprise Version from 10.GA release. +::: + +### Setting Language Preference + +- You can set your personal preference, from Studio, by opening the Account Profile. [![](/learn/assets/locale_profile.png)](/learn/assets/locale_profile.png) +- Edit Profile and choose the preferred language. [![](/learn/assets/locale_profile_edit.png)](/learn/assets/locale_profile_edit.png) +- The Default Language for all users will be set from Launchpad by the Admin. [![](/learn/assets/locale_default.png)](/learn/assets/locale_default.png) + +### Adding Language Bundles + +:::note +This is for the Advanced Developers only. To enable Locale support for Studio, language bundles need to be added to the following locations. By default, English and German language bundles are already bundled with the platform. +::: + +#### For Launchpad & EDN + +To add a new locale support: +1. Copy the `en.properties` file. Pick any file from any one location given below. +2. Rename it to `localeId` properties. The `localeId` represents the language to support. For example, **en** for English and **de** for German. +3. Make the appropriate changes to the content. +4. Add the file at the following locations: + +| Module | File name with path | +| --- | --- | +| **wavemaker-framework** | `wavemaker-core/src/main/resources/locale/fwk_exception_messages_.properties` | +| **login-service** |`wavemaker-login/wavemaker-login-portal/src/main/resources/locale/login_exception_messages_.properties` | +||`wavemaker-login/wavemaker-login-portal/src/main/resources/locale/login_messages_.properties` | +||`wavemaker-login/wavemaker-login-portal/src/main/resources/locale/login_validation_error_messages_.properties` +|| `wavemaker-login/wavemaker-login-portal/src/main/resources/locale/login_validation_messages_.properties`| +| **edn-service** | `wavemaker-edn/wavemaker-edn-server/src/main/resources/locale/edn_activity_messages_.properties`| +|| `wavemaker-edn/wavemaker-edn-server/src/main/resources/locale/edn_exception_messages_.properties` | +|| `wavemaker-edn/wavemaker-edn-server/src/main/resources/locale/edn_notification_messages_.properties` | +| **wavemaker-cloud-commons** | `wm-cloud-file-store/src/main/resources/locale/wm_fs_exception_messages_.properties`| +|| `wm-cloud-ssl/src/main/resources/locale/wm_ssl_exception_messages_.properties` | + + +#### For Studio Frontend +This language bundle is used to change the Studio user interface. To add a new locale support: +1. Copy the `en.json` file. Pick any file from any one location given below. +2. Rename it to `localeId.json`. The `localeId` represents the language to support. For example, **en** for English and **de** for German. +3. Make the appropriate changes to the content. +4. Add the file at the following locations: + +| Module | File name with path | +| --- | --- | +| **wavemaker-studio** | ` wavemaker-studio/wavemaker-studio-editor/src/main/webapp/editor/scripts/modules/i18n/messages` | +| **login-service** | ` wavemaker-login/wavemaker-login-portal/src/main/resources/locale/login_exception_messages_.properties` | +||` wavemaker-login/wavemaker-login-portal/src/main/resources/locale/login_messages_.properties`| +||` wavemaker-login/wavemaker-login-portal/src/main/resources/locale/login_validation_error_messages_.properties`| +||` wavemaker-login/wavemaker-login-portal/src/main/resources/locale/login_validation_messages_.properties`| +|**edn-service** | `wavemaker-edn/wavemaker-edn-server/src/main/resources/locale/edn_activity_messages_.properties`| +||` wavemaker-edn/wavemaker-edn-server/src/main/resources/locale/edn_exception_messages_.properties`| +||` wavemaker-edn/wavemaker-edn-server/src/main/resources/locale/edn_notification_messages_.properties`| +| **wavemaker-cloud-commons** | ` wm-cloud-file-store/src/main/resources/locale/wm_fs_exception_messages_.properties`| +||` wm-cloud-ssl/src/main/resources/locale/wm_ssl_exception_messages_.properties`| + + +#### For Studio Backend +Studio makes use of module APIs to work with backend services. These language bundles contain mostly the error or success messages from the service. To add a new locale support: +1. Copy the `en.json` file. Pick any file from any one location given below. +2. Rename to `localeId.json`. The `localeId` represents the language to support. For example, **en** for English and **de** for German. +3. Make the appropriate changes to the content. +4. Add the file at the following locations: + +| Module | File name with path | +| --- | --- | +| **wavemaker-framework** | `wavemaker-core/src/main/resources/locale/fwk_exception_messages_.properties` | +| **login-service** | `wavemaker-login/wavemaker-login-portal/src/main/resources/locale/login_exception_messages_.properties`| +||`wavemaker-login/wavemaker-login-portal/src/main/resources/locale/login_messages_.properties`| +||`wavemaker-login/wavemaker-login-portal/src/main/resources/locale/login_validation_error_messages_.properties`| +||`wavemaker-login/wavemaker-login-portal/src/main/resources/locale/login_validation_messages_.properties`| +| **edn-service** | `wavemaker-edn/wavemaker-edn-server/src/main/resources/locale/edn_activity_messages_.properties`| +||`wavemaker-edn/wavemaker-edn-server/src/main/resources/locale/edn_exception_messages_.properties`| +||`wavemaker-edn/wavemaker-edn-server/src/main/resources/locale/edn_notification_messages_.properties`| +| **wavemaker-cloud-commons** | `wm-cloud-file-store/src/main/resources/locale/wm_fs_exception_messages_.properties`| +||`wm-cloud-ssl/src/main/resources/locale/wm_ssl_exception_messages_.properties`| + + + +### Update Build Scripts + +Once you add the language bundles, update the flyway script and initiate the build process for the languages to take effect. + +New locale has to be inserted to the PostgreSQL Database, by adding the insert statement to the flyway script file. + +Following are the instructions: +- Go to the directory: + +`wavemaker-login-service/wavemaker-login/wavemaker-login-portal/src/main/resources/db_scripts/postgresql/` + +- Add a flyway script file incrementing the version number. +For example, if you have the recent version of flyway script as + +`wmlogin_v74__RBAC_model_permissions.sql`, + +Create a new file with the following name: + +`wmlogin_v75__new_locale_.sql` + +:::note +There are two underscores after the version number **v75**. +::: + +- Add the following statement in the above newly created file, after replacing the placeholders for `localeId`, `DisplayName`, and `Language`. +``` +INSERT INTO SUPPORTED_LOCALE (LOCALE_ID, DISPLAY_NAME, LANGUAGE) values (`'localeId'`, `'DisplayName'`, `'Language'`); +``` +For example to insert German locale: +``` +`INSERT INTO SUPPORTED_LOCALE (LOCALE_ID, DISPLAY_NAME, LANGUAGE)` +Values as `('de', 'German', 'German');` +``` +- Initiate the platform build. +- Post-build, when developers log into the platform they will be able to see the language in their profiles for selection. diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/platform-overview.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/platform-overview.md new file mode 100644 index 000000000..099926e5a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/platform-overview.md @@ -0,0 +1,88 @@ +--- +title: "WaveMaker Platform Architecture" +id: "platform-overview" +sidebar_label: "Platform" +--- +Learn how WaveMaker modern apps work. + +--- +Application architectures have been constantly evolving, embracing changes in the technology trends like AJAX, cloud, mobile etc. Modern Web application development demands an understanding of these trends and adopting the architectural aspects into development practices. + +For Enterprise developers, the challenge is mounting to make a shift from legacy application systems, where they interact with desktop-based monolithic software apps to modern web and mobile apps. The skills required for understanding the fast-paced technology changes are very high and making the right technology choices to be able to build apps for future is quite a daunting task. + +WaveMaker RAD platform combines the ease of development, with the right architecture and technology choices to be able to build apps for the future. Here give you an overview of WaveMaker Platform in terms of the architecture, technology and as a RAD tool. + +[![app components](/learn/assets/Modern_Web_Apps.png)](/learn/assets/Modern_Web_Apps.png) + +A typical application has 3 parts: + +1. Client-side app component that works on the device you use, **User Interface** +2. Central/remote Server component that provides **backend services** +3. Both these components separated by well-defined **REST API** contract + +## What is a WaveMaker App + +WaveMaker App can either be a web responsive application or a hybrid mobile application built using the low-code or rapid app development approach. WaveMaker App is built as a single HTML Web App, with clear separation of User Interface (UI) layer and the backend services layer using REST APIs. The UI layer is built using the visual RAD approach, with drag-n-drop of widgets onto the Canvas. Later, these widgets are integrated with the backend services, to fetch and update data. + +WaveMaker App is composed of 3 layers: + +1. **UI Layer** is built with Pages, which are composed with widgets using visual drag-n-drop approach. +2. **Binding Layer** integrates backend services with the front-end UI layer through REST APIs. +3. **Services Layer** represents backend services auto-generated from databases, external web services or custom Java services etc. + +[![WM App](/learn/assets/3layered_arch.png)](/learn/assets/3layered_arch.png) + +## App Architecture + +#### Single Page Application (SPA) + +Single-Page Applications (SPAs) are Web apps that load a single HTML page and dynamically update that page as the user interacts with the app. WaveMaker embraces the Single Page app model as against the traditional model, where the markup and other UI artifacts are generated on the server-side for each request and sent to client. + +Benefits of Single Page Applications: + +1. No page re-loads and dynamically generated HTML +2. Structure of the page i.e. header, footer, left nav is retained across pages (a.k.a Views), causing no jitter +3. Clear separation of front end and backend contract through REST APIs/JSON +4. Support rich interactions and mobile responsive design +5. Allow data to be passed across pages, defined by the Scope +6. Scalable to support large data sets and growing user-base + +[![SPA vs traditional](/learn/assets/spa_arch.png)](/learn/assets/spa_arch.png) + +## App Building Process + +WaveMaker enables rapid application development with clear separation of front-end and back-end development, and enables easy integration with well-defined REST APIs. This model brings separation of concerns for various layers, which form part of the app architecture. + +App building process combines the ability to develop front-end by auto-generating widget code and binding to the data services. From the data model obtained from the database, back-end services with their REST API contracts are auto-generated for integration. Both the front-end and back-end layers can be integrated with the help of binding and variables, which enable data integration with various services such as DB, Web Services or any custom Java Service. + +[![wmapp_process](/learn/assets/WMApp_process.png)](/learn/assets/WMApp_process.png) + +## Technology Stack + +WaveMaker Apps are built using open-standards based technology stack, without any lock-in to vendor specific frameworks. Apps built can be freely distributed without any licensing concerns and deployed on any platform of your choice. + +[![tech stack](/learn/assets/OS_Technology_Stack.png)](/learn/assets/OS_Technology_Stack.png) + +1. _Front-end_: Angular 7.x version for user interface, data binding and events. Bootstrap provides responsive layouts for various form factors +2. _Object Relational Mapping (ORM)_: Hibernate and JPA provide standards based ORM layer and Entity model for database interaction +3. _Back-end Services_: Spring framework provides the back-end service layer in Java with support for dependency injection, REST controllers, security etc. +4. _Hybrid Mobile_: Cordova framework is used for enabling access to mobile device features and native installer creation using the appropriate SDKs. + +## Material Design + +WaveMaker widgets and themes embrace Android Material Design specification for visual design and building interaction across multiple devices. Android Material Design provides design guidelines for user interaction across mobile apps and modern web apps. + +[![materialdesign_principles_metaphor](/learn/assets/materialdesign_principles_metaphor.png)](/learn/assets/materialdesign_principles_metaphor.png)Material is a metaphor coined by Android/Google Developers to standardize good design principles used for modern web and mobile apps. The foundational elements such as typography, space, color, grids, use of images guide the visual aesthetics of modern apps. A lot of emphasis has been given to these elements in the Material design principles, which makes it an apt choice for WaveMaker Apps. + +In WaveMaker widget library, widgets such as Grids, Cards, Lists, Forms etc. make use of the visual design principles from Material. These design guidelines are optimized for use in enterprise applications and also validated from a performance standpoint, to make sure the best experience has been delivered for app users. + +## Hybrid Mobile Apps + +In the age of digitization with smartphones and tablets, mobile apps are the need of the day for enterprises. Mobile apps have a farther reach and these apps would get a wider exposure. There are [three different ways of building mobile apps](http://www.wavemaker.com/item/native-responsive-or-hybrid/): + +- **Native Apps** which can be developed in a specific programming language depending upon the targeted mobile operating systems. Native mobile apps provide fast performance and a high degree of reliability. They also have access to various device features, such as its camera and address book. However, this type of app is expensive to develop because it is tied to one type of operating system, forcing the app creator to make multiple versions that work on other platforms. +- **Responsive Web Apps** which can be built just like any other web app, with the capability to adapt their UI to the size of current browser window. **Web apps built using WaveMaker Studio are responsive by default**. See here for how to build Web Responsive Apps [link](/learn/documentation-reference/). Responsive web apps, however, do not have the ability to leverage device capabilities such as the use of a camera, accessing contacts, storing a file on the device etc. and accessing the app when offline or not connected. +- **Hybrid Mobile Apps** attempt to strike a compromise between native and mobile web. They use HTML5 + CSS3 + JavaScript along with a wrapper/development framework like Sencha, PhoneGap or Titanium to give the app access to native device capabilities. **WaveMaker Studio offers this feature, hybrid mobile apps, via the [Apache Cordova Platform](https://cordova.apache.org/)**. + +[![app type](/learn/assets/project-type.png)](/learn/assets/project-type.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/pre-requisites.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/pre-requisites.md new file mode 100644 index 000000000..5a0b7dd56 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/pre-requisites.md @@ -0,0 +1,22 @@ +--- +title: "Pre-requisites for App Development" +id: "pre-requisites" +sidebar_label: "Pre-requisites" +--- +What skills you need to develop web and hybrid mobile apps using WaveMaker. + +--- +WaveMaker makes building web and mobile apps much easier. It can be used by a RAD Developer with a basic skill-set, or by a pro UI developer. + +## Skills Required +Brief outline of the skills you need to build apps using WaveMaker. + +| **Skill** | **Basic RAD Developer** | **Advanced App Developer** | +| --- | --- | --- | +| **UI Fundamentals** | Web Semantics, UI Widgets, Forms | HTML, Single Page Apps, AJAX, Form Post, etc. | +| **JavaScript** | Syntax & Scripting | Angular 7x, DOM & Event handling, scope, etc. | +| **CSS** | Basic understanding of DOM element attributes (class or id) | Bootstrap, CSS3, CSS overrides, etc. | +| **Database** | Understanding Schema & SQL syntax | Complex SQL queries, joins, relationships, ORM, procedures, etc. | +| **Java** | Java syntax, class, methods and Annotations | Object-oriented concepts, Class loading, Maven, Spring & Hibernate | +| **API** | REST API basics | REST, SOAP, OAuth, & API Security etc. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/product-walkthrough.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/product-walkthrough.md new file mode 100644 index 000000000..1cbee7615 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/product-walkthrough.md @@ -0,0 +1,110 @@ +--- +title: "Product Walkthrough" +id: "product-walkthrough" +sidebar_label: "Walkthrough" +--- +--- +WaveMaker is a RAD solution for developing web and mobile applications. In this document, learn WaveMaker terminologies and get familiar with the product dashboard. + +## Product Terminology + +Following are some of the terms commonly used in Studio parlance. + +| **Terms** |**Description** | **See this document** | +| --- | --- | --- | +| **Pages** | Pages contain app components. You can organize data by using widgets and define a workflow by interlinking them. | [Creating a Page](/learn/app-development/ui-design/page-creation/)| +| **Layouts** | Demarcating the page into sections. | [Page Layouts](/learn/app-development/ui-design/page-concepts/page-layouts) | +| **Templates** | Re-usable arrangement of one or more widgets in the page content put together. | [Templates](/learn/app-development/ui-design/page-concepts/page-templates/) | +| **Template Bundle** | Custom templates built into a bundle. |[Template Bundle](/learn/app-development/ui-design/page-concepts/#creating-template-bundles) | +| **Widgets** | UI components for user interaction and responsive design. |[Widgets Overview](/learn/app-development/widgets/ui-elements/) | +||List of Widgets.|[Widget Library](/learn/app-development/widgets/widget-library/) | +| **Prefabs** |Collection of one or more widgets that are bound to API or services. <details>Read more Prefab is a reusable, API-integrated component that can be used across apps. It encapsulates functionality, interaction & data and as such can be used to build custom widgets. For example, GoogleMap Prefab, QRCode reader or Youtube Prefab. |[Prefab Basics](/learn/app-development/custom-widgets/prefabs-overview)| +||List of prefabs that are already created.|[Predefined Prefabs](/learn/app-development/widgets/widget-library/#prefabs)| +||Build your own Prefab. |[Creating Prefabs](/learn/app-development/custom-widgets/creating-prefabs/) | +| **Project Shell** | Foundation for multiple apps in an enterprise. |[Project Shells](/learn/app-development/ui-design/project-shells/) | +| **Theme** | Colors, fonts, and branding elements (CSS & images) that is applied to all pages within an app. |[Themes Overview](/learn/app-development/ui-design/themes/)| +||Create your own custom theme.|[Creating Themes](/learn/app-development/ui-design/themes/#create-theme) | +| **Variable** | Provides data integration for the widgets. <details>Read more Variable holds the actual data to be rendered by the widgets. It is based on a data model obtained from the API source (from services like database and web-based) and renders the same in the form of a data structure used for binding, with attributes and related objects. |[Variables Overview](/learn/app-development/variables/) | +| |**Variable Types**|| +|**Database CRUD** | For the basic insert, read and update operation on the Database tables. |[Database CRUD](/learn/app-development/variables/database-crud/) | +| **Database API** | For accessing the queries and procedures and additional Database functionality. | [Database API](/learn/app-development/variables/database-apis/) | +|  |**Service API** || +|**Web Services**|From Web for the service APIs exposed by the Web services. |[Web Service](/learn/app-development/variables/web-service/)| +|**Java Services**|Service API from Java for the service APIs exposed by the Java services.|[Java Service](/learn/app-development/variables/java-services/)| +|**Security Services**|Service API from Security for the service APIs exposed by the Security services.|[Security Service](/learn/app-development/variables/security-service/) | +|**Model Variable**| It can be used as storage model to store data in the client-side. |[Model Variable](/learn/app-development/variables/model-variable/) | +|**Device Variable**| To access device features in case of mobile applications. |[Device Variable](/learn/hybrid-mobile/device-variables/) | +| **Actions** | Implement the business logic, rules and data flow. <details>Read more Actions assist in invoking a backend API, Database operation or navigation to another page when a UI event occurs. Events can be either user-initiated, notification response or as a result of another task being performed. |[Actions](/learn/app-development/variables/variables-actions) | +| **Binding** | Connecting variables and widgets. <details>Read more Binding of the Variables to Widgets helps in capturing the data from the user or fetching data from the backend services. |[Variable Binding](/learn/app-development/variables/variable-binding/) | + +## Dashboard Walkthrough + + + +## Project Workspace +--- +When a project from the Project Dashboard is opened, it opens in the Project Workspace. This space is the designer pallet for your app. The various sections of the Project Workspace assist you in building the app. + +[![](/learn/assets/project_workspace.png)](/learn/assets/project_workspace.png) + +- **Resources** are building blocks of an App like Page, Database, APIs etc. +- **Resources Panel** gives access to various resources categories - a group or category of resources of the same type such as Pages, Databases, Web Services, Java Services, and APIs. + +- **Resource Explorer** lists all the resources of the selected resource category +- **Resource Elements** constituting a selected a resource can be viewed within the **Canvas** along with the appropriate **Resource Toolbar**. + +- **Project Actions** give a quick access to recently used resources, preview and deploy the app +- **Project Configurations** helps secure, export, internationalize and version control the app. Also, the Configuration Profiles, Project Settings, and Studio Settings can be accessed from here. + + +- For the **Pages Category** + - the Resource Explorer includes **Widgets**, **Prefabs, Page Structure** and **Variables** which aid in designing and building the Page + - **Workspace Toolbar** helps in defining runtime functionality of the Page in terms of Variables, Themes, Layout etc.. + - **Widget Breadcrumb** giving the relative path to the selected element on the Page +- **Properties Panel** gives the settings for the selected Resource Element +- **Developer Utilities** gives access to the + - Files generated for the app through **File Explorer**, + - **Logs** - server and client with download option and + - miscellaneous functions like: + - manage various project artefacts like Templates, Themes, Prefabs etc., + - save project shell, + - update project source, + - edit access to frequently used files like app.css and app.js. + +## Project Canvas +--- +Once you create a project, the Main Page is created by default. You can add pages to the app, by using the **+** button next to the Page on Resource Explorer. On selection of a page, Canvas is provided: + +1. you can select the page to design/edit from the Pages resource category +2. the selected page UI is displayed in the Canvas +3. the Properties Panel displays the properties of the Page [![](/learn/assets/Canvas1.png)](/learn/assets/Canvas1.png) +4. from the Page Structure section, you can see the various elements placed on the Page and their hierarchy +5. you can select the widget from the Page structure +6. selected widget is highlighted on the Canvas +7. selected widget properties like data source, styles, events, device, and security can be set from the Properties Panel +8. Widget hierarchy shows the widget construct and allows you to traverse to the parent container. [![](/learn/assets/Canvas2.png)](/learn/assets/Canvas2.png) + +## Project Settings + +You can view and change project details and settings from the **Project Settings** dialog. + +Project Settings can be accessed from the **Settings**option of the**Secondary Actions**. + +[![](/learn/assets/Project_Settings.png)](/learn/assets/Project_Settings.png) + +- **Type** indicates whether it is an application - web or mobile; or a prefab. For Prefabs, an additional [Prefab Settings](/learn/app-development/custom-widgets/creating-prefabs/ "Projects and Templates") tab is displayed. +- **Project Name** non-editable field giving the name of the project. +- **Description** giving a brief description of the project as entered at the time of project creation which can be modified. +- **Package prefix** defines the default package for the generated code across all services. The package prefix is generated by concatenating the _com_ and _project name_. This can be modified as per your requirements. +- The **copyright** information is generated by default, which can be modified. +- **Provatar** or project avatar is an icon depicting the nature of the project, editable set from the selection from the drop-down menu. +- **Version** number can take any format as per your company standards. +- **Default Language** can be set for the project. This works in conjunction with the [Localization](/learn/app-development/widgets/datalive/form/select-locale/ "Localization"). The developer has to provide the Language Bundle via the App Messages, translation facility is not provided by this feature. In case the Language Bundle is not provided the application will run in English, which is the default language. The browser language preference of the user can be captured. If the user running the WaveMaker app has language preference set in their browser and that language is supported by the app (i.e. available in the language bundle) then the app will be rendered in that language instead of the default language of the app. +- **Home Page** defines the initial or the first page for the app at run-time. It is set to the Main page by default. **NOTE**: Few things that you need to be aware of regarding the Home Page + - In case the app is not secure, the user is redirected to the Home page configured in the project settings + - In case the [app is secure](/learn/app-development/app-security/app-security) but the Home Page is not ([permission set to everyone](/learn/app-development/app-security/access-levels-permissions/#setting-permissions)), the user is redirected to the Home page configured in the project settings + - In case the app and Home Page are secure([permission set to specific user role](/learn/app-development/app-security/access-levels-permissions/#setting-permissions)), the user is redirected to the [configured login page](/learn/app-development/app-security/login-configuration/#login-page#login) as per the user role +- **Display Format** can be used to set the display format for all the date/time fields in the app. The Configure Formats link directs you to the localization dialog where the date and time formats can be set. ([click here to know more](/learn/app-development/widgets/form-widgets/select-locale-usage/)) +- **Project Shell** used in building the app, non-editable +- **Created date** is the project creation timestamp, non-editable. +- **Last Accessed** date is the timestamp of last project modification, non-editable. diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/project-user-management.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/project-user-management.md new file mode 100644 index 000000000..9f0b2ae80 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/project-user-management.md @@ -0,0 +1,96 @@ +--- +title: "Project User Management" +id: "project-user-management" +--- +--- + +Collaboration is allowed for WaveMaker project development. The owner of a project can add new members  (already registered with WaveMaker) to the project and assign roles to them. This document walks through the various roles and permissions allowed for the members of a project. + +:::note +Enterprise version handles RBAC support differently. For more information, see [Rapid RBAC Support for Enterprise Version](/learn/app-development/wavemaker-overview/rapid-rbac-support/). +::: + +## Member Roles + +The following roles are provided by default and cannot be customized: + +- **Project Admin**: Project Admin is the actual owner of a specific Project and takes responsibility for the entire app development. +- **Default**: This is the default role when a user is assigned to a Project. This includes only view privileges. +- **Contributor:** Contributor is the co-developer of the specified Project. They have full access to app development functionality, with the following exceptions: + - cannot deploy the project, + - cannot delete the project, + - cannot add members to the project, + - cannot remove existing users, and + - cannot push the project to an external Repo. + +## Add Members + +- As the creator of a project, you are assigned the role of a Project Admin. You can assign users to the project using the **Add Member Details** option from the Project Listing. + +[![](/learn/assets/Project-Details.png)](/learn/assets/Project-Details.png) + +[![](/learn/assets/user_management_add.png)](/learn/assets/user_management_add.png) + +- Project Roles can also be assigned or updated from the Project Workspace using the User Management dialog under Settings option. + +[![](/learn/assets/user_management.png)](/learn/assets/user_management.png) + +[![](/learn/assets/user_management_assign.png)](/learn/assets/user_management_assign.png) + +## Permissions + +The list of roles and permissions are provided for project admin, default and contributors. + +### Project Admin + +|Type | Permissions | +| --- | --- | +|Pages |Create, Edit, Delete, and View | +|REST Services | Import, Edit, Delete, and View | +|SOAP Services | Import, Edit, Delete, and View | +|Websocket Services | Import, Edit, Delete, and View| +| Java Services | Import, Edit, Delete, and View | +| Database Services | Create or Import, Edit, Delete, and View; Queries - Create, Edit, Delete, and View; Procedures - Create, Edit, Delete, and View. | +| Themes | View, Import, and Change | +| Prefabs | Import, and Delete | +| Artifacts | View, and Import | +| Security | View, and Configure | +| API Designer | View, and Edit API's | +| VCS | Pull & View Log, Push to VCS, Push to External Repository, and Sync Workspace | +| Profiles | Configure Profiles | +| i18n | Configure Languages and Edit messages | +| Tools | DB Console, and File Explorer | +| Project Management | Release Management | +| Project Actions | Export Project as Zip, Export Project as Shell, Export Project as Prefab, Export Project as Template Bundle, Update Sources, Enable Workspace Sync, Export Project as WAR, Deploy Project, Publish Prefab To EDN, Publish Prefab to Workspace, Publish Project Shell To EDN, Publish Project shell to Workspace, Publish Template Bundle To EDN, Publish Template Bundle To Workspace, View Settings, Configure Settings, View User Management, Configures User Permissions, Delete Project, and Publish Theme To EDN| + + +### Default + +|Type | Permissions | +| --- | --- | +| Pages | View | +| Services | View Databases, View Java Services, View REST Services, View SOAP Services, View Websocket Sevices, View API's | +| Project Actions | View Settings, View User Management| +| VCS | Pull & View Logs| + +### Contributor + +|Type | Permissions | +| --- | --- | +| Pages | Create, Edit, Delete, and View | +| REST Services | Import, Edit, Delete, and View | +| SOAP Services | Import, Edit, Delete, and View | +| Websocket Services | Import, Edit, Delete, and View | +| Java Services | Import, Edit, Delete, and View | +| Database Services | Create or Import, Edit, Delete, and View; Queries - Create, Edit, Delete, and View; Procedures - Create, Edit, Delete, and View.| +| Themes | View, Import, and Change | +| Prefabs | Import, and Delete | +| Artifacts | View | +| Security | View, and Configure | +| API Designer | View, and Edit API's | +| VCS | Pull & View Log, Push to VCS, and Sync Workspace | +| Profiles | Configure Profiles | +| i18n | Configure Languages and Edit messages | +| Tools | DB Console, and File Explorer | +| Project Actions | View Settings, View User Management, Export Project as Zip, Export Project as Shell, Export Project as Prefab, Export Project as Template Bundle, Update Sources, Enable Workspace Sync, Export Project as WAR, Publish Prefab to Workspace, Publish Project shell to Workspace, Publish Template Bundle To Workspace | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/rapid-rbac-support.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/rapid-rbac-support.md new file mode 100644 index 000000000..1c79dfebc --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/rapid-rbac-support.md @@ -0,0 +1,123 @@ +--- +title: "Rapid RBAC Support (Enterprise Version)" +id: "rapid-rbac-support" +--- + +##### Enterprise Version post 10.0 release + +When multiple developers across the team are collaborating on large development projects, establishing a clear set of access control policies helps in effectively managing the deliverables. RBAC policies safeguard a specific set of project resources from being modified and from any unwanted/unapproved set of changes creeping into the development project. + +**Role-based access control (RBAC)** for Rapid, enables certain roles to access specific features of the product. WaveMaker Platform when setup within an enterprise is managed by 2 different types of roles: + +1. **Product Roles**: IT-centric roles managing the setup, infrastructure & integrated services required by the platform; +2. **Project Roles**: Developers & project leaders who are involved in the application development using the platform. + +## Product Roles + +**Product Roles** are defined by the Product for administration and managing the platform functions within an organization. The following are the specific roles that are provided by default under the “Product Roles” category (these roles cannot be modified): + +- _Super Admin_: : This role is the higher-order role in the organization that assumes all the functions that can be performed in the platform after setting up. Has total control over the administration, infrastructure, projects, user and role management. +- _Enterprise Admin_: This role presides over all the administrative functions related to projects, project membership, artefact approval, etc. +- _Studio User_: User is the developer or the project administrator who works on the development projects and has access to Studio for app building. Product User when given access to a created project, or when added to an existing project can play one of the project roles assigned to. Project roles are specific to the app development life-cycle and are managed by the Project Admin. + +## Product Role Policies + +- Product Roles are pre-defined by the product and cannot be customized. +- Super Admin can create or assign another user to become a Super Admin. +- Super Admin creates or assigns a user to be the Enterprise Admin and IT Admin. +- There can be multiple Enterprise Admins for a given enterprise within the product setup. However, an Enterprise Admin cannot create another Enterprise Admin. +- Enterprise Admin can do the following role assignments: + - Assign Project Admin to a project, + - Revoke Admin access to a project for a specific user, + - Remove membership for a user from a project. +- Only an Enterprise Admin can create a project and assign a Project Admin. +- Studio Users cannot create projects +- Studio Users can become part of the project with the associated Project Roles assigned by the Project Admin. + +## Project Roles + +There are several roles involved in the app development process, each of these roles are categorized based on the functions they perform in the app development lifecycle. The following roles are provided by default and cannot be customized: + +- **Project Admin**: Project Admin is the actual owner of a specific Project and takes responsibility for the entire app development. +- **Default**: This is the default role when a user is assigned to a Project. This includes only view privileges. + +Apart from these, roles can be created and defined as per the enterprise needs. These Roles are customizable and custom role definitions can be created with specific permissions by the product roles. + +**Permission Types**: There are 3-levels of Permission sets that are provided to manage access control for various roles involved in the development process: + +- **Studio permissions**: Studio Permissions are top-level permissions that are not specific to any app or project being developed. These permissions are applicable to the Studio-level actions across all Project types. +- **Project permissions**: Project Permissions are project-level permissions that are not specific to any resource or resource type. These permissions are applicable to actions that are performed in the workspace of an active project. Project Permissions specific to a Project are configured by the Project Owner. +- **Project resource permissions**: Project Resource Permissions are resource-level permissions, that are assigned specifically to a resource such as a Page, Database, Web Service etc. These permissions are applicable to all actions performed on the specific resource. Project Resource Permissions are configured within the project workspace by Project Owner. + +[![](/learn/assets/RBAC.png)](/learn/assets/RBAC.png) + +## Implementation + +As mentioned earlier, default roles are set by the Platform. Of these roles, some can be customized. Here is the list of roles and permissions that are provided: The following roles CANNOT be customized: + +| Role | Permissions | +| --- | --- | +| Project Admin | - All Studio Permissions | +| Default | - Pages - Create, Edit, Delete, and View
- Services - View Databases, View Java Services, View REST Services, View SOAP Services, View Websocket Sevices, View API's,
- View Settings,
- View User Management | + +## Role Creation and Assignment + +Studio Permissions and Project Permissions across all apps in Studio, are configured in the Launchpad, by the product Admin. Since these are not resource-dependent, they are independently configured for roles available. + +Project Resource Permissions are project specific and are configured by the Project Admin for the specific project from the User Management Settings menu. + +In the following sections, we will discuss both in detail. + +### Studio and Project Permissions + +**Launchpad** **Role Definitions**: Roles can be created from the Role Definition tab of the User On-boarding section of Launchpad. As mentioned earlier the Product Roles are pre-defined with permissions set and they cannot be modified. [![](/learn/assets/product_roles.png)](/learn/assets/product_roles.png) Project Roles come with a pre-defined roles of Project Admin, Project Developer and Default. [![](/learn/assets/project_roles.png)](/learn/assets/project_roles.png) Custom Project Roles can be created and Permissions allocated to them as per the requirements. [![](/learn/assets/project_roles_custom.png)](/learn/assets/project_roles_custom.png) From the Role Mapping tab users can be assigned to Super Admin, Enterprise Admin and Studio User. [![](/learn/assets/role_mapping.png)](/learn/assets/role_mapping.png) [![](/learn/assets/role_mapping2.png)](/learn/assets/role_mapping2.png) + +### Project Resource Permissions + +**Project Role Assignment**: Once the Project Roles are defined, they need to be assigned to Studio Users for specific projects. Project Admin will log to Rapid and assign users usin the **Add Member Details** option. [![](/learn/assets/Project-Details.png)](/learn/assets/Project-Details.png) [![](/learn/assets/project_roles_assign.png)](/learn/assets/project_roles_assign.png) Project Roles can be updated from the Project Workspace using the User Management dialog under Settings option. [![](/learn/assets/user_management.png)](/learn/assets/user_management.png) [![](/learn/assets/project_roles_update.png)](/learn/assets/project_roles_update.png) + +### Project Admin + +By default, only Project Admin can create projects and members added will be assigned the Default role and any other role assigned to them. Project Admin can be changed by EDN Admin from the EDN page. + +1. Login to EDN. +2. Select the Project tab. +3. Search and open the Project for which the admin role has to be changed. +4. EDN Admin can - Revoke Admin, Make Admin or delete the user. + +--- + +## Permissions + +As mentioned earlier, two default roles are set by the Platform. You can add roles and assign permissions based upon app requirements. The following is a list of permissions that can be set: + +| Category | Permissions | +| --- | --- | +| Pages |Create, Edit, Delete and View | +| Database Services | Create/Import , Edit , Delete and View | +| Database - Queries | Create Queries , Edit Queries , Delete Queries adn View Queries | +| Database - Procedures |
- Create Procedures
- Edit Procedures
- Delete Procedures
- View Procedures| +| Java Service | - Create Java Service
- Edit Java Service
- Delete Java Service
- View Java Service | +| REST Service | - Import REST Service
- Edit REST Service
- Delete REST Service
- View REST Service| +| SOAP Service | - Import SOAP Service
- Edit SOAP Service
- Delete SOAP Service
- View SOAP Service | +| Web Socket Service | - Import Web Socket Service
- Edit Web Socket Service
- Delete Web Socket Service
- View Web Socket Service | +| API Designer | - Edit API Designer
- View API Designer | +| Security Service | - Configure Security Service | + +| Category | Permissions | +| --- | --- | +| i18n | - Configure Languages
- Delete Language
- View i18n
- Edit Messages | +| VCS | - Push, Pull, and View Log
- Pull & View Log - Push
- Push to External Repo | +| Prefabs | - Import Prefab
- Delete Prefab | +| Tools | - DB Console
- File Explorer | +| Profiles | - Configure Profiles | +| Artifacts | - Import Artifacts
- View Artifacts | +| Themes | - Import Themes
- Change Themes
- View Themes | +| Mobile | - Export as Cordova zip
- Send to PhoneGap
- Build for Android | + +| Category | Permissions | +| --- | --- | +| Project Actions | - Export Project as Zip
- Export Project as Shell
- Export Project as Prefab
- Export Project as Template Bundle
- Update Sources
- Enable Workspace Sync | +| | - Export Project as WAR
- Deploy Project
- Publish Prefab To EDN
- Publish Prefab to Workspace
- Publish Project Shell To EDN
- Publish Project shell to Workspace | +| | - View Settings
- Configure Settings | +| | - View User Management
- Configures User Permissions | diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/react-native-and-cordova.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/react-native-and-cordova.md new file mode 100644 index 000000000..1cab3a03a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/react-native-and-cordova.md @@ -0,0 +1,40 @@ +--- +title: "React Native or Cordova to Develop a Mobile app in WaveMaker" +id: "react-native-and-cordova" +sidebar_label: "React Native or Cordova" +--- +--- + +WaveMaker supports [React Native](/learn/react-native/react-native-overview) from [WaveMaker 11 Beta](/learn/wavemaker-release-notes/v11-0-1) onwards and [Cordova](/learn/hybrid-mobile/building-hybrid-mobile-apps) framework from quite some time. But the decision of which framework to use has several considerations, which are discussed in this document. The following details can help you choose whether to use Cordova or React Native to develop a new mobile application in WaveMaker Studio. + +## Performance + +React Native apps perform better compared to Cordova apps. We tested a few typical scenarios where the same app was developed in WaveMaker Studio using Cordova and React Native. We observed that the React Native app performed 40% better than the Cordova app in terms of app loading time. + + +## Feature Parity + +Check the [available features](/learn/react-native/feature-support) and [supported widgets](/learn/react-native/supported-widgets) of React Native apps. + +## Technology + +In WaveMaker, the only difference between Cordova and React Native Apps development is the styling framework. + +### Supported Technologies + +|Cordova|React Native| +|----|----| +|UI runs on a WebView. | UI runs in a Javascript engine, such as JSC or Hermes.| +|HTML, JavaScript, and CSS to develop app UI. | You will use JavaScript to define and style the React Native UI. | + +## CSS Support + +:::note +React Native does not support CSS. +::: + +CSS is very powerful and flexible. So, WaveMaker allows developers to define React Native styles like CSS, but with limitations. WaveMaker converts these CSS styles into JS styles. Therefore, a WaveMaker developer must learn this new way of styling the React Native app. Learn [how to style and theme](/learn/react-native/styles) React Native apps. It should not take more than an hour. + +## Final thoughts + +WaveMaker React Native studio should be a preferred choice for any new mobile application development. diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/supported-technologies.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/supported-technologies.md new file mode 100644 index 000000000..a5567fcc9 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/supported-technologies.md @@ -0,0 +1,34 @@ +--- +title: "Supported Technologies" +id: "supported-technologies" +--- +Find the list of technologies supported by WaveMaker. + +--- + +In this document, you will find a list of various technologies supported by WaveMaker. + +| Description | Vendor/Version | +| --- | --- | +| Supported Browsers | Chrome (latest version) | +| | Apple Safari (ver 11.1.2) | +| | Internet Explorer (ver 11) | +| | Mozilla Firefox (latest version) | +| | Edge (latest version) | +| Supported Databases | MySQL, PostgreSQL, Oracle, SQL Server, IBM DB2, HSQL | +| | See here for [supported versions](/learn/app-development/services/database-services/database-services#supported-databases-and-versions). | +| Supported Security Providers | Database (Studio supported) based | +| | Lightweight Directory Access Protocol (LDAP) | +| | Active Directory (AD) | +| | Single sign-on via Central Authentication System (CAS) | +| | SAML | +| | OpenID | +| | Custom Java Service | +| Supported IDEs | All Maven supporting IDEs like Eclipse, IntelliJ IDEA etc. | + +### WaveMaker Technology Stack + +Find the list of various technologies supported by WaveMaker. See the latest version of [release notes](/learn/wavemaker-release-notes) for more information. +- [UI Frameworks](/learn/wavemaker-release-notes/#ui-frameworks) +- [Back-end Frameworks](/learn/wavemaker-release-notes/#back-end-frameworks) +- [Run-time Environment](/learn/wavemaker-release-notes/#run-time-environment) diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/wavemaker-11-beta.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/wavemaker-11-beta.md new file mode 100644 index 000000000..f7d6586cc --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/wavemaker-11-beta.md @@ -0,0 +1,77 @@ +--- +title: "WaveMaker 11 Beta" +id: "wavemaker-11-beta" +sidebar_label: "11 beta" +--- +--- + +:::note +This document contains information about WaveMaker 11 Beta. We provided fixes and improvements to the features since we released 11 Beta—now outdated. Follow our [release notes page](/learn/wavemaker-release-notes) for up-to-date information. Learn more about [WaveMaker 11.1](/learn/wavemaker-release-notes/v11-1-0) (latest). +::: + +We are back with a new release, and we can't wait to share all the great features and updates waiting for you in WaveMaker 11 beta. + +With every new release, our goal is consistent. It is to simplify the low-code platform to bring app ideas to life faster. While we are at it, we continue to provide a broad canvas to customize app components and services that are completely reusable at their core—and take advantage of several open-source integrations on our way. Let's see what we got this year. + +WaveMaker 11 beta release features significant advancements shaping the practicality of the low-code development for mobile consumers in a big way. And we covered you with extensive tooling capabilities, keeping the low code roots in mind. + +![React Native Studio](/learn/assets/react-native-studio.png) + +## Introducing React Native in WaveMaker + +We introduce React Native, a new platform for developing native apps, including iOS and Android app development, all within WaveMaker Studio. The best part is that it requires almost no learning curve if you are already a WaveMaker developer. It offers platform-specific versions of components so that a single codebase can share code across Android and iOS stores. [Read more](/learn/react-native/react-native-overview). + +![react native project creation](/learn/assets/react-native-project-creation.png) + +### Cordova Support Continues + +Although our emphasis at this point is to prioritize React Native, even so, we do not plan to deprecate Cordova anytime sooner. We will continue to support Cordova app development and provide an up-to-date tech stack whenever a new update is available. + +## New Flex Layout Widget + +We are persistent in producing rich studio tools that enable you to design great-looking apps using our new Linearlayout Flex widget. This widget allows you to display data in list format, giving developers complete control of vertical and horizontal layout adjustments. This feature is exclusive to React Native users for now. + +![flex widget](/learn/assets/flex-layout-widget.gif) + +## Java 11 Update + +The Java 11 version updates the tech stack but brings a few break changes and version bumps. If you build and deploy apps outside WaveMaker, you must upgrade your build infrastructure and verify the deployment setup to support Java 11. For this reason, we introduced parallel versioning of Studio so you can test your application before you upgrade to WaveMaker 11 beta. Learn more about [upgrading deployment infrastructure](/learn/how-tos/upgrade-guide-wavemaker-10-to-11#upgrade-deployment-infrastructure) before you upgrade to WaveMaker 11. + +## Upgrading SAML to new Library + +All WaveMaker projects using SAML (saml2-core) as a security provider have reached their end of life and, therefore, will be migrated to a new version of SAML (saml2-service-provider). The new library saml2-service-provider is a part of spring security which was not the case for saml2-core. + +:::note +**To do**: +After upgrading to WaveMaker 11 using saml2-service-provider, the users will have to update the new URLs in their respective security providers. For example, Okta, One login, and more. For more information, see [Configure IdP](/learn/app-development/app-security/saml-integration/#configure-idp-with-wavemaker-application) and [Deployment of Application Configured with SAML](/learn/app-development/app-security/saml-integration/#deployment-of-application-that-is-configured-with-saml) +::: + +## API Composer Toolkit + +API composer toolkit can be your playground to compose an object using multiple API endpoints. This means you can combine many REST APIs in Java Service and write custom business logic that you can use as a variable and bind to any UI widget. + +![](/learn/assets/api-composer.png) + +## API Mock Server + +API Mock Server is our own WaveMaker Studio extension. It simulates a backend API with responses that are close to accurate, which are useful for developing the UI design even if you do not have a backend service ready to consume. This is great for the app designing phase, while the backend team can develop the APIs simultaneously. For more information, see [API Mock Server](/learn/app-development/services/api-mock-server). + +## Pagination for Imported APIs + +WaveMaker now supports server-side pagination out of the box when importing API with pagination. It works seamlessly with all widgets, including tables, lists, searches, etc. You can configure these pagination parameters while importing the API. + +## Multi-version Studio + +We bring in parallel versioning of Studio to help perform project migration smoothly at your convenience. With Multi-version Studio, the project card converts into a folder that contains two versions of the same project, including versions 10 and 11. You can work on both versions of the projects, meaning you can push your critical planned fixes on WaveMaker 10 while planning your upgrade to WaveMaker 11 in its project cards, respectively. + +![multi-version studio](/learn/assets/multi-version-studio.png) + +For more information, see [Updating an App from WaveMaker 10 WaveMaker 11](/learn/how-tos/upgrade-guide-wavemaker-10-to-11). + +## POM Hierarchy Remodeled to Inheritance Model + +A generated WaveMaker application encloses a pom.xml containing build resources, such as filters, profiles, repositories, plugin management, dependencies, and user customizations. The pom structure has been remodeled to inherit from the parent pom, making it easy to read the code. + +## Teams for Enterprise + +Teams is a collaborative development environment, which comes as a standard for WaveMaker Enterprise users. Manage projects, roles, code repositories, add or remove team members, grant permissions, and more using [Teams Portal](/learn/teams/overview). \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/wavemaker-11.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/wavemaker-11.md new file mode 100644 index 000000000..b7b56ecec --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/wavemaker-11.md @@ -0,0 +1,65 @@ +--- +title: "WaveMaker 11" +id: "wavemaker-11" +sidebar_label: "WaveMaker 11" +--- +--- + +You asked we delivered—a host of new features and enhancements in WaveMaker 11 - Beta to 11.4 General Availability (GA), released on 4th September 2023. Following 11 Beta, we closely engaged with our customers and developers in thoroughly collecting and meeting their feedback and ready with the update, 11.4. We believe the platform is rather stable to move to WaveMaker 11.x. The release includes improvements to the 11 Beta features and a few more upgrades overall. + +:::important + +In WaveMaker 11, many newer updates were released with more features and bug fixes. Read this document and follow the links to release information. + +- [WaveMaker 11.3.3 - features added](/learn/wavemaker-release-notes/v11-3-6) +- [WaveMaker 11.3.3 - features added(beta)](/learn/wavemaker-release-notes/v11-3-3) +- [WaveMaker 11.3 - features added](/learn/wavemaker-release-notes/v11-3-0) +- [WaveMaker 11.2 - features added](/learn/wavemaker-release-notes/v11-2-0) +- [WaveMaker 11.1 - features added](/learn/wavemaker-release-notes/v11-1-0) +- [WaveMaker 11.1.2 - features added](/learn/wavemaker-release-notes/v11-1-2) +- [Overview WaveMaker Enterprise (WME) 11 releases, including featues and bug fixes](/learn/enterprise-release-notes#wavemaker-enterprise-v11x) +- [Overview WaveMaker Online (WMO) 11 releases, including bug fixes](/learn/wavemaker-release-notes#wavemaker-online-v11x) +- [WaveMaker 11 beta](/learn/app-development/wavemaker-overview/wavemaker-11-beta) +::: + +## Migration to 11: what to expect + +The upgrade is not flagged as a risky migration. The upgrade process is designed to transit as smoothly as possible, so you can instantly benefit from all the new features we deliver in the [newer versions](/learn/wavemaker-release-notes#wavemaker-online-v11x) of the WaveMaker 11 Studio. It includes new and advanced React Native features, Prefab Marketplace, Mockingbird support, inter and intra-team collaboration tools library updates, including a Java update, needing an action to do. + +### Java Update + +The Java 11 version is one update among the WaveMaker Studio's [latest tech stack](/learn/wavemaker-release-notes#technology-stack). A small action is required from your end to complete the update, specifically, if you build and deploy your apps outside WaveMaker. For example, Tomcat. + +You must upgrade your build infrastructure and verify the deployment setup to support Java 11. For this reason, we introduced [parallel versioning of Studio](/learn/app-development/wavemaker-overview/wavemaker-11-beta#multi-version-studio) so you can test your application thoroughly. Learn more about upgrading deployment infrastructure before initiating the project migration to WaveMaker 11 or later. See the [migration guide](/learn/how-tos/upgrade-guide-wavemaker-10-to-11) for more information. + +## Angular 12 + +Angular 12 includes JQuery library upgrades as a standard. In addition, it offers performance improvements, language services, and more. + +:::note +Note that the Angular 12 update addresses vulnerabilities. Updating to the latest version of WaveMaker Studio helps keep your application secure against critical security threats. +::: + +## Expo + +Expo version upgrade from version 45 to 48 is a major upgrade in WaveMaker Studio. To know more, see + +- [WaveMaker 11.2.2](https://docs.wavemaker.com/learn/wavemaker-release-notes/v11-2-2) +- [WaveMaker 11.3.6](https://docs.wavemaker.com/learn/wavemaker-release-notes/v11-3-6) + +## Features of WaveMaker 11.1: GA + +### React Native Studio + +In WaveMaker 11, we have introduced all new and advanced React Native features in WaveMaker Studio. These features include app-loading animations, Third-party Plugin Integration, SSL Pinning, improved inline styles, Audio support, and many more enhancements. Know more about our React Native Studio and get started with developing native applications by referring to our [React Native documentation](/learn/react-native/react-native). + +### Other New Features of 11: GAs + +Several other new features were added to WaveMaker Studio in 11 and later, including: + +- [MLTS Support](/learn/how-tos/configure-mtls-in-wmapp) +- [Azure Repos VCS Support](/learn/how-tos/azure-repos-vcs) +- [Added MongoDB Support in Session Persistence](/learn/app-development/app-security/session-persistence#mongo-db) for scaling your application horizontally. +- Sync Prefab, allowing you to keep the Prefab up to date even when re-importing a project from Zip. +- Introducing four types of [Wizard Template to Support Icons as Steps](learn/how-tos/wizard-layout). +- [Prefab Marketplace](/learn/app-development/custom-widgets/enterprise-marketplace/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/wavemaker-best-practices.md b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/wavemaker-best-practices.md new file mode 100644 index 000000000..a1d6293aa --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/wavemaker-overview/wavemaker-best-practices.md @@ -0,0 +1,74 @@ +--- +title: "WaveMaker Best Practices" +id: "wavemaker-best-practices" +--- + +Best Practices to follow while building apps using WaveMaker.   Responsive Web Apps + +WaveMaker apps can run on the mobile browsers. The browsers on these devices have limited resources to render and run JavaScript logic. Below are some hand rules for achieving design and performance. The same can be applied for any web application. + +- Ideally for good user experience you should have **one task per screen/page**. The application functionality should be broken into smaller tasks and design one page for each of these tasks. Page load will help: + - managing service call + - less code for compilation + - back button on device for navigation +- Page size can be optimized using the records per request property for variables rendering data on those pages. +- Avoid complex user interface for repeatable items like list +- Load small sized images +- Avoid using dialog or popups. Ideally dialogs in mobile application are to be used only for notification purposes. +- Avoid inline styles and delegating the style functionality to CSS classes + +#### Doc Reference + +[App Building Essentials](/learn/jump-start/jump-start-app-essentials/)   Page Layouts Page Layouts help you design app pages. By default there are six layouts provided, choose one as per your app needs: + +- Use **Blank layout** for full screen UI eg. Login screen +- Use **Layout with header & footer** for pages without any links for navigation e.g. landing page of application +- Use **Layout with header, topnav & footer** for pages with primary navigation links on top +- Use **Layout with header, left-panel & footer** for pages with primary navigation links on left +- Use **Layout with header, topnav, left-panel & footer** for pages with primary navigation links on top and contextual content /navigation on left +- Use **Layout with header, topnav, left-panel, right-panel & footer** for pages with primary navigation links on top, contextual content /navigation on left and a site map or reference links on the right. + +**Additional Tips**: + +- It is recommended to keep only one navigation panel either top or left +- Do not include two headers or two left panels for the same page +- Use square logo in the header for better resizing in mobile and web browsers +- Avoid more than 7 links/actions in navigation bar + +#### Doc Reference + +- [Page Layouts](/learn/app-development/ui-design/page-concepts/page-layouts/) + +  Page Structure + +Page is designed using various widgets. Proper placement of these widgets along with proper responsive behavior is of essence when building web responsive apps. For this purpose, WaveMaker offres a wide range of Container Widgets. Use them judiciously for maximum responsive benefits. Following are guidelines in using these container widgets. + +- Use **Grid Layout** for responsive UI. WaveMaker uses 12-column grid layout defined by bootstrap for responsive design, you can customize this layout using the Grid Layout container. +- Use **Accordion** for: + - progressive disclosure of long wizards thus reducing the number of pages, + - when the content must fit on one screen height, + - questionnaires where you want to be able to show answers or exit quickly.For example, checkout-type transactions. +- Use **Tabs** to: + - alternate between views within the same context + - when users do not need to see the entire content simultaneously,Tabs have unlimited height and they can span a number of screens +- Use **Panel** for an auxiliary window that contains controls and options that affect the active screen content or selection +- Use **Tiles** for showing less but important information like aggregated information or call to action. Tiles are mostly used in groups and Layout Grid can be used in arranging Tiles +- Use **Container** for multi-purpose, lightweight elements which can load the content from partial pages. They can be positioned absolute in the parent container and need not have any structured information. + +#### Doc Reference + +- [Container Widgets](/learn/app-development/widgets/widget-library/#container) + +  Version Control + +Version control is the process of tracking and controlling changes to a project’s files, which includes source code, documentation, and web pages. Subversion and Git are examples of such version control systems. WaveMaker includes an integrated version control system hosted on GitLab. In this document we look into the best practices to avoid conflicts. **Conflict Prevention** When multiple users are working on the same project following practices can help reduce conflict situations: + +- **Pull before push**: Before starting always Pull from the Stash, resolve conflicts if any and then start working. +- **Frequent pushes**: Keep pushing changes frequently, with proper versioning and comments for easy tracking and reverts, if needed. +- **Divide and conquer**: Ideally, each developer should be working on separate pages within the app. In case of overlap, ensure that they are not working on the same widget in the shared page. +- **Database tips**: When working with an external database, it is advisable to make any database design related changes at the external database and have the developers re-import the database. Though it is possible to make changes from the database designer within WaveMaker, it might lead to merge conflicts when not done properly. +- **Separation of intent**: For other services, like Java, security etc., having one developer responsible for each of these services helps in avoiding conflict situations. + +#### Doc Reference + +- [VCS](/learn/app-development/dev-integration/developer-collaboration/#vcs) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/advanced/carousel.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/advanced/carousel.md new file mode 100644 index 000000000..2820dcf86 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/advanced/carousel.md @@ -0,0 +1,66 @@ +--- +title: "Carousel" +id: "carousel" +--- + +**Carousel** widget is a flexible, responsive way to add a slider to your site. In addition to being responsive, the content is flexible enough to allow images, iframes, videos, or just about any type of content that you might want. + +WaveMaker provides you with two types of Carousel: + +1. **Dynamic** where the Carousel content will take the form of an array or any repeated list like a dataset. The number of items displayed within the carousel will depend upon the number of rows in the bound variable. **Carousel Template** a subWidget of Carousel holds the slide content. +2. **Static** where the Carousel content can be bound to individual image resources. **Carousel Content** a subWidget of Carousel holds the slide content. By default, Carousel comes with three carousel contents each with a picture widget. You can add more using the **Add Carousel** action property. + +[![](/learn/assets/carousel_types.png)](/learn/assets/carousel_types.png) + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for Carousel. | +| Add Carousel (available only for Static Carousel) | Allows you to add carousel content to the carousel widget. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Dataset** (available only for Dynamic Carousel) | +| Value | Set this bindable property to a variable to populate the list of images to display. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Enable Controls | This property allows you to enable the controls in the form of: - navs - arrows on either side of the images, - indicators - dots at the bottom of the images, - both - default or - none | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. Can be set to: - auto - default or - none. | +| Animation Interval | This property defines the animation interval in seconds. | + +**Carousel Content** (only for Static Carousel) SubWidget of Carousel to hold a slide content. By default, Carousel comes with three carousel contents each with a picture widget. You can add more using the Add Carousel action button. + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for your widget. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| **Format** | +| Horizontal Align | Set text alignment horizontally, can be left, center or right. | + +**Carousel Template** (only for Dynamic Carousel) SubWidget of Carousel to hold a slide content. The number of images displayed will be determined by the values of the variable bound to the Dataset Value property of Carousel. + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for your widget. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| **Format** | +| Horizontal Align | Set text alignment horizontally, can be left, center or right. | + +## Event + +| **Event** | **Description** | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/advanced/login.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/advanced/login.md new file mode 100644 index 000000000..24c998a51 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/advanced/login.md @@ -0,0 +1,32 @@ +--- +title: "Login" +id: "login" +--- + +**Login** can be used to display a pre-built Login section with a sign in button, username, and password fields. It also provides the option to remember the password. + +# Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier Login Form. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| **Message** | +| Message on error | This message will be displayed, if there is an error during the login operation. | + +# Events + +| Event | Description | +| --- | --- | +| **Callback Events** | +| On submit | This event handler is called whenever a submit event is triggered. | +| On before render | This event handler is called before rendering the form fields. | +| On success | This event handler is called whenever a success event is triggered. | +| On error | This event handler is called whenever an error event is triggered. | + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/advanced/marquee.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/advanced/marquee.md new file mode 100644 index 000000000..a8e55e09b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/advanced/marquee.md @@ -0,0 +1,23 @@ +--- +title: "Marquee" +id: "marquee" +--- + +**Marquee** widget is used to display the content in marquee styles, any widget can be dropped into it. + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for Marquee. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Behavior** | +| Scroll Delay | Sets the delay in the scroll of the Marquee. | +| Scroll Amount | Increasing scroll amount increases the speed of the scroll. | +| Direction | Changes the direction of the scroll, choose from _up, down, left or right_. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/alert-dialog.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/alert-dialog.md new file mode 100644 index 000000000..0727f3ef7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/alert-dialog.md @@ -0,0 +1,78 @@ +--- +title: "Alert Dialog" +id: "alert-dialog" +--- +--- + +[![alert_struct](/learn/assets/alert_struct.jpg)](/learn/assets/alert_struct.jpg) + +## Overview +Dragging and dropping a dialog creates a **view** containing the dialog. The view can be selected from the **Page Structure** or from the **tabs** given at the bottom. The display of the dialog box at runtime is usually associated with the _onClick_ event of a **Button** widget. You can also trigger the dialog by calling methods from _JavaScript_. + +## Alert Dialog + +For **Alert Dialog**, you can set: + +- the name, the title of the alert pop-up, message to be displayed in the pop-up, text on the OK button and the type of alert - error, information, success or warning. +- the icon for display next to the title of the alert box, you can pick the icon from the [icon dialog](/learn/app-development/widgets/basic/icon/). + +[![](/learn/assets/dialog_alert.png)](/learn/assets/dialog_alert.png) + + +## Script Access + +**Dialog** widget in your project can be accessed by associating the open and _close_ properties of the dialog with an event of any other widget. The dialog can be accessed through scripting by adding _DialogService_ to the _page controller_ and adding the code for _open_ and _close_ as shown below, here we are displaying an alert dialog on click of a button: Click event of the button should trigger the following JavaScript code: + +```js +Page.button3Click = function($event, widget) { + Page.Widgets.alertdialog1.open(); + } +``` + +For hiding dialog: +```js +/** function called on button1 click **/ + Page.button1Click = function($event, widget) { + Page.Widgets.alertdialog1.close(); + }; +``` + +## Properties & Events +--- +### Alert Dialog Properties + +| **Property** | **Description** | +| --- | --- | +| Title | Set the title of an alert dialog. | +| Name | The name is a unique identifier for alert dialog. | +| Message | Set the message of the widget. | +| Ok Text | This widget gives a pop-up window. It can be used to give a warning message to the user. For example, you are about to leave this page. | +| Alert Type | This property will help in identifying the type of alert in the alert box. Can be set to error (default), information, success, and warning. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Modal | This property, if set true, adds a backdrop for the dialog restricting the closure of the dialog when the user clicks outside of the dialog. The default value is false, which allows close of dialog on click outside. | +| **Behavior** | +| Enable Default Close Action | This property allows the user to access close action from header through an "x" icon; and also enables close through ESC key. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| Keyboard | This property if set true allows closing of dialog on ESC keypress. The default is true. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. | +| Icon Width | Optional property; but you will need this if you are using the button's iconUrl. Please enter the width of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Height | Optional property; but you will need this if you are using the button's iconUrl. Please enter the height of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | + +### Alert Dialog Events + +| Event | Description | +| --- | --- | +|**Callback Events**|| +| On ok | This event handler is called whenever an ok event is triggered. | +| On close | This event handler is called whenever a close event is triggered. | +| On open | This widget gives a pop-up window. It can be used to give a warning message to the user. For example, you are about to leave this page. | + + + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/anchor.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/anchor.md new file mode 100644 index 000000000..c1ff52690 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/anchor.md @@ -0,0 +1,92 @@ +--- +title: "Anchor" +id: "anchor" +--- +--- + +**Anchor** widget refers to the visible, clickable words used to link one web page to another. + +When inside another widget like nav, the anchor widget will come with some defaults like file icon and with default styling to have a border and background color. + +## Features + +The following features are available for anchor widget: + +- **Caption** - Sets the Name for the anchor widget. +- **Badge** Value - Indicates the small meaning information. +- **Hint** - It contains a text representing advisory information related to the element it belongs to. +- **Shortcut Key**: The shortcut key property specifies a shortcut key to click the link. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcut Key Trigger | +| --- | --- | +| Internet Explorer | [Alt] +shortcut key | +| Chrome | [Alt] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | +| Firefox | [Alt] [Shift] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | + +**Hyperlink** - Indicates the destination link. + +**Target** - The target property specifies where to open the linked document. + +- **_blank** : Opens the linked document in a new window or tab. +- **_self** : Opens the linked document in the same frame as it was clicked (this is default). +- **_parent** : Opens the linked document in the parent frame. +- **_top** : Opens the linked document in the full body of the window. + +**Icon** - Aligns the anchor widget with an icon properties + +### Anchor Class + +From the Style tab of Properties panel,  you can set the Anchor style. You can also use the Conditional Class property to set the class based upon a condition. See here for [How to](/learn/how-tos/use-conditional-class-property/). + + + +## Properties + +| Property | Description | +| --- | --- | +| Caption | The caption is the text that the end user sees on your anchor. It can be bound to a variable or another widget. | +| Name | The name is a unique identifier for Anchor widget. Special characters and spaces are not allowed in widget name. | +| Badge Value | Value to be displayed in the badge span for the anchor. | +| **Accessibility** | +| Hint | Any text or HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See here for details](#shortcut)) | +| **Layout** | +| Width | The width of your widget can be specified in _em, pt, px or %_ (i.e 50px, 75%). | +| Height | The height of your widget can be specified in _em, pt, px or %_ (i.e 50px, 75%). | +| **Dataset** | +| Hyperlink | The web URL you want to redirect to on clicking the anchor. | +| **Behavior** | +| Target | Defines behavior on click of the link: _blank: Opens the linked document in a new window or tab _self: Opens the linked document in the same frame as it was clicked (this is default) _parent: Opens the linked document in the parent frame _top: Opens the linked document in the full body of the window. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| Encode URL | Check this if you want the provided URL to be encoded at the run time. Enabling this property will encode the special characters in the URL and enable rendering of the page which otherwise might fail. By default, it is set to false. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the anchor. | +| Icon Url | This optional property allows you to add an icon to the anchor, it can be an URL of the image | +| Icon Width | Optional property; but you will need this if you are using the anchor's iconUrl. Please enter the width of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Height | Optional property; but you will need this if you are using the anchor's iconUrl. Please enter the height of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | +| Icon Position | Optional property; Property to set the position of icon in the widget - can be left, top or right | +| **Format** | +| Horizontal Align | This property specifies how the elements should be aligned horizontally - left, center or right. | + +## Events + +| Event | Description | +| --- | --- | +| On Focus | This event handler is called each time your element is focused. | +| On Blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On Click | This event handler is called whenever the click event is triggered on a widget. | +| On Double Click | This event handler is called whenever the double click event is triggered on a widget. | +| On Mouse Enter | This event handler is called whenever the mouse enters the widget. | +| On Mouse Leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On Tap | This event handler is called whenever the widget is tapped. | +| On Double Tap | This event handler is called whenever the widget is double tapped. | +| On Long tap | This event handler is called whenever the long tap event is triggered on a widget.
Note: Long Tap event is only supported in React Native applications.| + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/audio.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/audio.md new file mode 100644 index 000000000..cd8853b08 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/audio.md @@ -0,0 +1,65 @@ +--- +title: "Audio Widget" +id: "audio" +sidebar_label: "Audio" +--- +--- + +WaveMaker supports audio media. To use an audio in your project, simply drag and drop the **Audio** widget and bind it to the resource using the Property Panel. + +:::note +The following table gives the browser support for **audio** and **video** resources. To learn more about video file support, see [Video Widget](/learn/app-development/widgets/basic/video). +::: + +|Browser|MP4|WebM|Ogg| +|---|---|---|---| +|Internet Explorer|YES|NO|NO| +|Chrome|YES|YES|YES| +|Firefox|YES|YES|YES| +|Safari|YES|NO|NO| +|Opera|YES (from Opera 25)|YES|YES| + +## Using Audio Widget + +The following features are available for all the **Audio** widget. + +1. From the **Property** panel of the media widget, find the **Audio** section. Locate the **MP3 Source Path** option and click the **Bind** icon represented by a chain-link as shown in the picture below; a Bind modal dialog pops-up. + + [![Media audio](/learn/assets/media_audio.png)](/learn/assets/media_audio.png) + +2. In the modal dialog, click the **Resource** tab. + +3. Select the **Audio** type from the dropdown and click the **Upload New** button, the **Import Audio** modal dialog pops-up. + + [![media resource](/learn/assets/media_resources.png)](/learn/assets/media_resources.png) + +## Audio Customizations + +You can add customizations from the **Properties** panel. + +1. **Autoplay** — a boolean specifying whether the file should play as soon as it can +2. **Loop** — a boolean specifying whether the file should be repeatedly played. +3. **Controls** — a boolean specifying whether the browser should display its default media controls +4. **Preload** — none/metadata/auto — where 'metadata' means preload just the metadata and 'auto' leaves the browser to decide whether to preload the whole file. + +## Audio Widget Properties + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for the audio widget. | +| **Accessibility** | +| Hint | Any text or HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE:** In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Audio** | +| MP3 Source Path | This property allows you to set the file path of a mp3 file. | +| Audio Preload | This property allows if and how the author thinks the audio should be loaded when the page loads. Can be set to: - none - default - metadata, or - auto | +| Support Message | This property allows you to set the message when the audio file is not supported by the HTML5 media player. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. | +| Enable Controls | This property allows you to enable that audio/video controls should be displayed such as a play/pause button, and more. | +| Enable Autoplay | This property allows you to enable if and how the author thinks the video should be loaded when the page loads. | +| Loop | This property allows you to enable that the video will start over again, every time it is finished. | +| Mute | This property allows you to enable that the audio output of the audio/video should be muted.| diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/fileupload-use-cases.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/fileupload-use-cases.md new file mode 100644 index 000000000..1a3676650 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/fileupload-use-cases.md @@ -0,0 +1,17 @@ +--- +title: "FileUpload - Use Cases" +id: "fileupload-use-cases" +--- + +FileUpload widget can be used to let users upload files to your apps. WaveMaker **FileUpload** widget generates a **Java Service** to enable additional file processing functionality. It exposes few methods like _uploadFile_, _listFiles_, and _deleteFile_. + +- [FileUpload Basic Usage](/learn/app-development/widgets/form-widgets/file-upload-basic-usage/) +- [How to use various file service operations](/learn/how-tos/file-upload-widget-operations/) +- [How to save uploaded file to a DB](/learn/how-tos/upload-file-save-database/) +- [How to upload BLOB file to a DB](/learn/how-tos/file-upload-blob-data/) +- [How to upload file to custom directory](/learn/how-tos/file-upload-custom-directory/) +- [How to uploaded files from Java code](/learn/how-tos/accessing-file-upload-java-code/) +- [How to use FileUpload in Form and Live Form](/learn/how-tos/upload-files-from-live-form-form/) + +[![](/learn/assets/fu_service.png)](/learn/assets/fu_service.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/html.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/html.md new file mode 100644 index 000000000..b5223d213 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/html.md @@ -0,0 +1,38 @@ +--- +title: "HTML" +id: "html" +--- + +**HTML** widget can be used to display HTML content. + +## Properties + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for the widget. | +| **Accessibility** | +| Hint | Any text or HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Content** | +| Content | Html content will be included in the widget. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| **Format** | +| Horizontal Align | This property specifies how the elements should be aligned horizontally. | + +## Events + +| Event | Description | +| --- | --- | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On double click | This event handler is called whenever the double click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | +| On double tap | This event handler is called whenever the double tap event is triggered on a widget. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/icon.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/icon.md new file mode 100644 index 000000000..7c3b4dc2f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/icon.md @@ -0,0 +1,45 @@ +--- +title: "Icon" +id: "icon" +--- + +Many widgets like Panel, Button etc. have a way to display an icon. You can choose the icons from the list of **wavicon** (thin fonts that abide the iOS and Android mobile style guidelines) or **font-awesome** icons. + +[![](/learn/assets/icon_dialog.png)](/learn/assets/icon_dialog.png) + +# Features + +[![](/learn/assets/icon_props.png)](/learn/assets/icon_props.png) [![](/learn/assets/icon_sel.png)](/learn/assets/icon_sel.png) + +There are two ways of setting the icon class for a given icon: + +1. Use the bind icon next to the Icon class property and bind it to any resource, +2. From the **icon selector** on the left of the **Icon Class** property, you can: + 1. Choose a **font-awesome** or **wavicon** icon. **NOTE**: Wavicon icons are thin fonts that abide the iOS and Android mobile style guidelines. [![](/learn/assets/icon_dialog.png)](/learn/assets/icon_dialog.png) + 2. You can see the icon preview. You can: [![](/learn/assets/icon_preview.png)](/learn/assets/icon_preview.png) + +- set the _size_ of the icon as the regular _1g_, _2x_, _3x_, _4x_, or _5x_ +- choose to _rotate_ of the icon by 90, 180 or 270 degrees, +- choose to _flip_ of the icon horizontally or vertically, +- set the _animation_ of the icon to spin or pulse, +- choose to _pull_ the icon to left or right for the placement of the icon, +- set the _Fixed width_ of the icon for a uniform look while using multiple icons, and +- set the _border_ for the icon + +# Properties + +| Property | Description | +| --- | --- | +| Caption | This bindable property is the text that the end user sees on icon. | +| Name | The name is a unique identifier for icon widget. | +| **Accessibility** | +| Hint | Any text or html you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Animation | This property controls the animation of an element. The animation is based on the css classes and works only in the run mode. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. | +| Icon Size | This property defines the size of the icon. Value has to be specified along with the units (em or px). | +| Icon Position | Property to set the position of icon - can be left (default) or right. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/iframe.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/iframe.md new file mode 100644 index 000000000..eef4ebb77 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/iframe.md @@ -0,0 +1,23 @@ +--- +title: "Iframe" +id: "iframe" +--- + +![](/learn/assets/laptop.png)  **NOTE**: Iframe is available only for web responsive apps. + +An inline frame (**Iframe**) is used to embed another document within the current HTML document. Frames allow a visual HTML Browser window to be split into segments, each of which can show a different document. The iframe element represents a nested browsing context. + +# Properties + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for iFrame widget. | +| Source | This property can be used to define the source attribute of the iframe. Example Source: '//bing.com' **Note**: The implementation of iFrame requires the source to be of _http://_ type and also the _run Url_ of your app should be _http://_ and NOT _https://_ | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Encode URL | Check this if you want the provided URL to be encoded at the run time. Enabling this property will encode the special characters in the URL and enable rendering of the page which otherwise might fail. By default, it is set to false. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/label.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/label.md new file mode 100644 index 000000000..b413f9f26 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/label.md @@ -0,0 +1,60 @@ +--- +title: "Label" +id: "label" +--- + +The **label** represents a caption in a user interface. The label displays text on the page. Common use cases include + +- a page header +- a form field label +- a paragraph of text +- a link + +[![](/learn/assets/label_struct.jpg)](/learn/assets/label_struct.jpg) + +# Features + +The following features for Label can be set in the **Class** property from the **Style** tab of the **Properties** Panel. + +### Label Types + + + +### Label Styles + + + +# Properties + +| Property | Description | +| --- | --- | +| Caption | The caption is the text that the end user sees on your label. It can be bound to a variable or another widget. | +| Name | The name is a unique identifier for label widget. | +| **Accessibility** | +| Hint | You can enter any text for this property and it will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. It can be bound to a variable or another widget. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| **Format** | +| Horizontal align | This property specifies how the elements should be aligned horizontally. | + +# Events + +| Event | Description | +| --- | --- | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On double click | This event handler is called whenever the double click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On Tap | This event handler is called whenever the tap event is triggered on a widget. | +| On Double Tap | This event handler is called whenever the double tap event is triggered on a widget. | +| On Long Tap | This event handler is called whenever the long tap event is triggered on a widget.
Note: Long Tap event is only supported in React Native applications.| + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/lottie.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/lottie.md new file mode 100644 index 000000000..e7789f22b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/lottie.md @@ -0,0 +1,66 @@ +--- +title: "Lottie Widget (Beta)" +id: "lottie" +sidebar_label: "Lottie (Beta)" +--- +--- + +[Lottie Animations](https://lottiefiles.com/) are very popular and are very easy to control through JavaScript code. Lottie Widget helps to show the Lottie animations in WaveMaker. + +:::note +Lottie Widget is supported only in React Native applications in WaveMaker. +::: + +## Lottie Widget Properties + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for the video widget. | +| **Animation** | +| Source | Location of the Lottie animation JSON file. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. | +| Enable Autoplay | This property allows you to enable if and how the author thinks the animation should be loaded when the page loads. | +| Loop | This property allows you to enable that the animation will start over again, every time it is finished. | +| Speed | Set the control of speed. By default, speed is 1. Negative values of speed will make animation to run in reverse direction. + +## Methods + +### Lottie Widget Methods for Animation Control + +The following methods are available to interact with the Lottie widget using JavaScript. + + +1. Start/Resume Animation: + +```javascript +Page.Widgets.lottie1.play(); +``` + +2. Stop/Pause Animation: + +```javascript +Page.Widgets.lottie1.pause(); +``` + +3. Restart Animation: + +```javascript +Page.Widgets.lottie1.reset(); +``` + +These methods provide control over the playback of the animation using the Lottie widget. + +## Events + +The following events are available on the Lottie widget. + +| **Event** | **Description** | +| --- | --- | +| On Ready | This property defines the event handler to be called when the animation is loaded and is ready to play. | +| On Pause | This property defines the event handler to be called when the animation is paused.| +| On Play | This property defines the event handler to be called when the animation is played or resumed. | +| On Complete | This property defines the event handler to be called when the animation is completed.| diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/message.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/message.md new file mode 100644 index 000000000..1d22b78c4 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/message.md @@ -0,0 +1,47 @@ +--- +title: "Message" +id: "message" +--- + +**Message** widget helps to display a custom message on the page. Based on the message type - _error_, _warning_, _success_, _info_, _loading_- the message look and feel changes. For instance, setting the message type to _error_ shows an error icon alongside the message text, which is displayed in red. + +## Features + + + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Caption | The caption is the text that the end user sees on your label. | +| Name | The name is a unique identifier for Message widget.Special characters and spaces are not allowed in widget name. | +| Type | This property specifies the type of the variable: - error, - info, - loading, - success or - warning | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Hide Close | Hides the close option. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | + +## Methods + +Message widget has few methods exposed on widget scope which can be accessed via JavaScript. See below for usage example + +- to display message: + + Page.Widgets.message1.showMessage(); //Displays message + +- to hide message: + + Page.Widgets.message1.hideMessage(); //to hide message + + +## Events + +| **Event** | Description | +| --- | --- | +| **Callback Events** | +| On close | This event handler is called **whenever** a close event is triggered. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/picture.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/picture.md new file mode 100644 index 000000000..f86caca94 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/picture.md @@ -0,0 +1,66 @@ +--- +title: "Picture Widget" +id: "picture" +sidebar_label: "Picture" +--- +--- + +Display an image with a picture widget. Just drag and drop the **Picture** widget and bind it to the resource using the Property Panel. + +:::note +**Picture widget** can be used by itself or within any widget like Live List, Data Grid, or Carousel and more. It can be bound to a database column containing the URL for the picture resource location. Example, the `picurl` field of Employee database from Sample DB. +::: + +## Using Picture Widget + +The following features are available for all the **Picture** widget. + +1. From the **Property** panel of the media widget, find the **Source** property. Click the **Bind** icon represented by a chain-link as shown in the picture below; a Bind modal dialog pops up. + + [![Media](/learn/assets/media_pic.png)](/learn/assets/media_pic.png) + +2. In the modal dialog, click the **Resource** tab. + +3. Select the **Image** type from the dropdown and click the **Upload New** button, the **Import Image** modal dialog pops-up. + + [![media resource](/learn/assets/media_resources.png)](/learn/assets/media_resources.png) + +## Picture Customizations + +You can add customizations from the **Properties** panel such as **Width** and **Height** with valid values. For example, 50px for Width, 75px for Height. + +## Picture Widget Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the picture widget. | +| **Accessibility** | +| Hint | Any text or HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE:** In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Picture** | +| Source | This property specifies the source for the picture. The source can be either a file or a URL - **File**: enter the directory and filename for the image to display (supported file types include .jpg, .gif and .png). By default, WaveMaker looks for images in the src/main/webapp directory of the project. Every WaveMaker project has a data directory under src/main/webapp, so this is a good place to put pictures. - **URL**: enter a URL to any internet-accessible image. To display the file, foo.jpg, in the project directory src/main/webapp/resources/images/imagelists/, enter the following into the source property:resources/images/imagelists/foo.jpg or simply foo.jpg | +| Placeholder | This property will act as placeholder image for the picture. When the picture from the Source value is not provided or not available then placeholder picture will be shown. | +| Aspect | This property can automatically size an image to the height or width of the picture widget. The options are: - _none_: the image is displayed at its default size - _h_: the image is resized so that the width of the image is the same as the width of the picture widget - _v_: the image is resized so that the height of the image is the same as the height of the picture widget - the image is resized so that the height and width of the image is the same as the height of the picture widget | +| Shape | This property controls the shape of the data point. Can be: - rounded, - circle, or - thumbnail | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| Encode URL | Check this if you want the provided URL to be encoded at the run time. Enabling this property will encode the special characters in the URL and enable rendering of the image which otherwise might fail. By default, it is set to false. | + +## Picture Widget Events + +| Event | Description | +| --- | --- | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On double click | This event handler is called whenever the double click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On Tap | This event handler is called whenever the tap event is triggered on a widget. | +| On Double Tap | This event handler is called whenever the double tap event is triggered on a widget. | +| On Long Tap | This event handler is called whenever the long tap event is triggered on a widget.
Note: Long Tap event is only supported in React Native applications.| diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/progress-bar.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/progress-bar.md new file mode 100644 index 000000000..39b354e52 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/progress-bar.md @@ -0,0 +1,54 @@ +--- +title: "Progress Bar" +id: "progress-bar" +--- + +**Progress Bar** widget can be used to show the status of any given event. It can be used to represent the completion progress of a task. Progress may be either indeterminate — meaning it is unclear how much work remains before the task is complete (e.g., the task is waiting for a response from a remote host) — or a numeric value between 0 and a given maximum, explicitly specifying the fraction of work that has so far been completed + +## Features + + + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for progress bar widget. | +| Type | Indicates the format you want to use to display the progress bar. Choose from - _default_, - _default-striped_, - _success_, - _success-striped_, - _info_, - _info-striped_, - _warning_, - _warning-striped_, - _danger_, - _danger-striped_. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| Minimum Value | Enter minimum number for the Progress bar. | +| Maximum Value | Enter a maximum number for the Progress bar. | +| **Behavior** | +| Poll Interval | Time interval in milliseconds to poll the service. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Display Format | Format in which the progress needs to be displayed. You can choose from a list of decimal options like 9, 9.9, 9.99 etc. If the progress bar's data value is 30.7056 and the selected display format is: -  9.9 then label will be rounded as 30.7 -  9.999% then label will be rounded to 30.706% | +| Caption placement | Placement of progress bar value can be - inside or - hidden | + +## Events + +| **Event** | **Description** | +| --- | --- | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On double click | This event handler is called whenever the double click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On Tap | This event handler is called whenever the tab event is triggered on a widget. | +| On Double Tap | This event handler is called whenever the double tap event is triggered on a widget. | +| On Long Tap | This event handler is called whenever the long tap event is triggered on a widget.
Note: Long Tap event is only supported in React Native applications.| +| **Callback Events** | +| On start | This event handler is called on start of the progress. | +| On complete | This event handler is called on complete of the progress. | +| On before update | This event handler is called on before update of the progress. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/progress-circle.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/progress-circle.md new file mode 100644 index 000000000..a96f1045f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/progress-circle.md @@ -0,0 +1,47 @@ +--- +title: "Progress Circle" +id: "progress-circle" +--- + +**Progress Circle** widget can be used to show the status of any given event. It can be used to represent the completion progress of a task. Progress may be either indeterminate — meaning it is unclear how much work remains before the task is complete (e.g., the task is waiting for a response from a remote host) — or a numeric value between 0 and a given maximum, explicitly specifying the fraction of work that has completed. [![](/learn/assets/ProgressCircle.jpg)](/learn/assets/ProgressCircle.jpg) + +# Properties + +| **Property** | **Description** | +| --- | --- | +| Title | Title of the progress cirle. | +| Subtitle | Subtitle of the progress circle. | +| Name | The name is a unique identifier for the progress circle widget. | +| Type | Indicates the format you want to use to display the progress circle. Choose from - _default_, - _success_, - _info_, - _warning_, - _danger_, | +| **Accessibility** | ***Hint*** Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Value | Set this property to a variable to populate the list of values to display. | +| **Default Value** | +| Value | Value is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| Minimum Value | Enter minimum number for the Progress bar. | +| Maximum Value | Enter a maximum number for the Progress bar. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Display Format | The format in which the progress needs to be displayed. You can choose from a list of decimal options like 9, 9.9, 9.99, etc. If the progress bar's data value is 30.7056 and the selected display format is: -  9.9 then label will be rounded as 30.7 -  9.999% then label will be rounded to 30.706% | +| Caption placement | Placement of progress bar value can be - inside or - hidden | + +# Events + +| **Event** | **Description** | +| --- | --- | +| **Mouse Events** | +| On-click | This event handler is called whenever the click event is triggered on a widget. | +| On-double click | This event handler is called whenever the double click event is triggered on a widget. | +| On-mouse enter | This event handler is called whenever the mouse enters the widget. | +| On-mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On-tap | This event handler is called whenever the tab event is triggered on a widget. | +| On-double tap | This event handler is called whenever the double tap event is triggered on a widget. | +| On-long tap | This event handler is called whenever the long tap event is triggered on a widget.
Note: Long Tap event is only supported in React Native applications.| +| **Callback Events** | +| On-start | This event handler is called on the start of the progress. | +| On-complete | This event handler is called on complete of the progress. | +| On-before update | This event handler is called on before update of the progress. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/richtext-editor.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/richtext-editor.md new file mode 100644 index 000000000..cf78d0b07 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/richtext-editor.md @@ -0,0 +1,34 @@ +--- +title: "Richtext Editor" +id: "richtext-editor" +--- + +A **richtext editor** widget allows users to create formatted/styled text similar to entering text into a word processor. The richtext editor is used to generate HTML text codes for your website or blog. The toolbar includes text-specific buttons. This makes it easy to create headers, bold text, italic, lists, set text alignment, embed images, audio, video, and more. Users can also add tables, change fonts, apply changes to font size and color. + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for Richtext Editor. | +| Placeholder | A placeholder is text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the user starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple of the user. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Behavior** | +| Read Only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Show Preview | Checking this box turns to show the preview section of the editor. | + +## Events + +| **Event** | **Description** | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/search-basic-usage.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/search-basic-usage.md new file mode 100644 index 000000000..c888a96ed --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/search-basic-usage.md @@ -0,0 +1,30 @@ +--- +title: "Search - Basic Usage" +id: "search-basic-usage" +--- + +WaveMaker allows you to add search capability via the **search widget**. Following are the steps in using the same. We will use the search widget to search the [**Department database from the sample HRDB imported earlier**](/learn/app-development/services/database-services/working-with-databases/#integrating-database) and display the department id and name. + +[![](/learn/assets/search_run1.png)](/learn/assets/search_run1.png) + +[![](/learn/assets/search_run2.png)](/learn/assets/search_run2.png) + +[![](/learn/assets/search_run3.png)](/learn/assets/search_run3.png) + +1. Drag and drop a **search**, and four **label** widgets on a page. We have used the grid layout here. [![](/learn/assets/search_design.png)](/learn/assets/search_design.png) +2. [Import the sample database](/learn/app-development/services/database-services/working-with-databases/). [Create a Variable](/learn/assets/var_sel.png) based on the database CRUD APIs auto-generated when the database is imported. [![](/learn/assets/search_lv.png)](/learn/assets/search_lv.png) +3. Bind the **Value** dataset property of the search widget to the department variable created in the previuos step. [![](/learn/assets/search_bind.png)](/learn/assets/search_bind.png) +4. Set the **Search key** and **Label Value** properties to the column name you want to search by, in this case, _name_. **Note**: The Search Key, Label Value, and Image Source are bindable. For example, the Label Value can be bound in this case to 'deptcode+name', using the expression option from the binding dialog. [![](/learn/assets/search_props.png)](/learn/assets/search_props.png) + +You can capture the result of the Search widget in two ways: + +1. Using the **outbound properties** of **data value** - which contains the dataset returned by the search to be bound to the list or Data Table, **query** - search text entered by the user and **show**. [![](/learn/assets/search_outbound.png)](/learn/assets/search_outbound.png) +2. Using **JavaScript** - From the event tab, set the **onSubmit** event to JavaScript. [![](/learn/assets/search_event.png)](/learn/assets/search_event.png) In the Script the following function will be created The selected item can be accessed by '$event.data.item' property as follows: Here we have set the labels to the department name and id returned by the search widget. NOTE: The label names might vary in your project. + + Page.search1Submit = function($event, widget) { + Page.Widgets.label3.caption = $event.data.item.deptid; + Page.Widgets.label4.caption = $event.data.item.name; + }; + +3. Save and run the application. +4. The page will display the search widget along with the labels. diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/search.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/search.md new file mode 100644 index 000000000..2519278db --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/search.md @@ -0,0 +1,82 @@ +--- +title: "Search" +id: "search" +--- +--- + +WaveMaker allows you to add search capability via the **search widget**. Data Table widget has the **Enable Search** property which lets you add the search facility to your table. + +In addition, you can use the **Search** widget for flexibility and control. + +For the Search widget you can set the following properties: + +- Bind the **Value** dataset property of the search widget to the variable created from a Database or Web Service. +- Set the **Search key** and **Label Value** properties to the column name you want to search by. + +:::note +The Label Value, and Image Source are bindable. For example, the Label Value can be bound to a field 'deptcode' or to a combination such as 'deptcode+name', using the expression option from the binding dialog. +::: + +- Set the **Type** as: + - _autocomplete_ which would present a dropdown list of values for the user to select from; or + - _search_ (the default setting) where the filtered list of values is presented based on the user entry +- Bind the **outbound properties:** + - **datavalue** - which contains the dataset returned by the search to be bound to Live list or Data Table, + - **query** - search text entered by the user + - **result** - which contain the list of matches i.e. matches that are displayed in the dropdown while typing (note: the type of result is based on selected datafield, if set to "All Fields" the complete object is returned) and + - **show**. +- Use **JavaScript** - From the event tab, set the **onSubmit** event to JavaScript. The selected item can be accessed by '$event.data.item' property + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for your widget. | +| Type | Type of the widget can be set to

- _autocomplete_ which would present a dropdown list of values for the user to select from; or
- _search_ (the default setting) where the filtered list of values is presented based on the user entry

**Note**: All the properties are the same for both types. | +| Placeholder | A placeholder is a text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the user starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple of the user. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable.

**Note**: In Safari browsers, by default, Tab highlights only text fields.

To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut Key | The shortcut key property specifies a shortcut key to activate/focus an element. The way of accessing the shortcut key is varying in different browsers Internet Explorer - [Alt] + shortcutkey, Chrome - [Alt] + shortcutkey (Windows/Linux) [Control] [Alt] + shortcutkey (MAC), Firefox - [Alt] [Shift] + shortcutkey (Windows/Linux) [Control] [Alt] + shortcutkey (MAC), Safari - [Alt] + shortcutkey (Windows) [Control] [Alt] + shortcutkey (MAC) | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. | +| Search Key | Property to be searched upon, in the list object. | +| Label Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| Picture Source | An image which displays along with the Label Value | +| Data field | This property sets the dataValue to be returned by a select editor when the list is populated using the dataSet property. | +| Order by | Field order | +| Match Mode | Specifies how to apply the filter on fields. For examples, match the query anywhere (or start or end) in the string.

Options: startignorecase, start, endignorecase, end, anywhereignorecase, anywhere, exactignorecase and exact.

Default matchmode: startignorecase

Examples:
1. start: "Wa" would match "WaveMaker"
2. end: "Maker" would match "WaveMaker"
3. anywhere: "ve" would match "WaveMaker"
| +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the data value returned by the widget. | +| **Display Format** | +| Limit | Limits the search results to be displayed in the auto-complete. | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Read Only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Show clear | On setting `show clear` to true, the user is provided with an option to clear the input value in the search field. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred until the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | +| Min Chars | The minimum number of characters to be entered by the user before the search query is triggered. The value should be greater than 0. The default value is 1. | +| Delay Time | Delay (in ms) after which the query gets triggered when the last character is typed by the user. Default delay is 250 ms. This delay is for performance optimization to reduce multiple network calls. | +| **Graphics** | +| Picture Width | Using this property configure the width of the picture that is shown in typeahead results' dropdown. Default value is set to '16px'. | +| **Message** | +| Data loading message | This message will be displayed when waiting for data to load. | +| Data complete message | This message will be displayed when there is no more data to load. | + +## Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| On Focus | This event handler is called each time your element is focused. | +| On Blur | This event handler is called each time your focus leaves your element. | +| **Callback Events** | +| On Submit | This event handler is called whenever a submit event is triggered. | +| On Select | This event handler is called when the tab is selected | +| On Before Service Call | This event is triggered before sending the service call for fetching the search results. _inputData_ can be modified in the event. | diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/spinner.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/spinner.md new file mode 100644 index 000000000..b7fed0ed0 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/spinner.md @@ -0,0 +1,25 @@ +--- +title: "Spinner" +id: "spinner" +--- + +**Spinner** widget controls the user interaction while the browser is performing some work in the background. It gives a feedback if the page is processing or, frozen, or just not working. This widget displays a loading icon with text. + +You can drop a spinner widget on the required page and set the spinner to false at _onPageReady_ which is part of the Script of the current page by using the following code snippet: Page.Widgets.spinner1.show = false;. If you would like to set the spinner till the variable loads, you can set the "_Track Variable_" property of the spinner to that particular variable. Then, the spinner would be shown until the variable gets loaded. You can track multiple variables by selecting the same. + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Caption | The caption is the text that the end user sees on your label. | +| Name | The name is a unique identifier for spinner widget. | +| Type | This property helps in specifying which type of icon is to be displayed for the spinner. The "Type" property has two options "icon" and "image". Based on the "Type" selected, the properties in the graphics section are changed. The animation property can be applied to both icons and images. | +| Track Variable | This property allows you to bind to the service or live variable for which you want to show the loading dialog. You can select multiple variables to track.  If more than two variables are selected, then spinner would be shown till both variable call requests have been completed/resolved. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the spinner. | +| Icon Size | This property defines the size of the icon. Value has to be specified along with the units (em or px). | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/tree.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/tree.md new file mode 100644 index 000000000..eecc07b4e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/tree.md @@ -0,0 +1,66 @@ +--- +title: "Tree" +id: "tree" +--- +--- + +**Tree** is a widget that helps display data in a structured format. It can be used to show a hierarchical structure in data. + +## Features + +You can set various properties + +- **Tree Icons** sets the expand-collapse icons on the tree, +- **Levels** sets levels of the tree to be expanded by default, +- **Default Value** can be none, FirstNode or LastNode defines the node to be selected by default on the first run of the app. This field can be bound to a condition. For example, `datavalue="role === 'admin'"`. In such cases, the condition is evaluated for each node in the tree until the condition is satisfied and that node will be selected. +- Tree Widget input needs three fields for **each node** - **label** for each node, **icon** to be displayed at each node, and in the case of sub-trees a **children** node with the repeat of the tree structure. + +## Properties + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for your widget. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Tree Icons | This property sets expand-collapse icons on the tree. One can choose from: - _folder_, - _plus-minus_, - _circle-plus-minus_, - _chevron_, - _menu_, - _triangle_ (default selection) or - _expand-collapse_. | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. | +| Order by | Set the order of the content. (available only when the above Dataset Value is bound to a variable) | +| Node Label | Property of the object (bound to the value property above) for node label binding, default value is label. (available only when the above Dataset Value is bound to a variable)| +| Node Icon | Property of the object (bound to the value property above) for node icon binding, default value is icon. (available only when the above Dataset Value is bound to a variable) | +| Node Children | Property of the object (bound to the value property above) for node children binding, the default value is children. The property where the nested object is present. (available only when the above Dataset Value is bound to a variable) | +| Node Id | Property of the object (bound to the value property above) used to identify a node. The default value property can be set to a value of the node id for initial selection. (available only when the above Dataset Value is bound to a variable) | +| Node Action | This property sets the actions for the widget. (available only when the above Dataset Value is bound to a variable) | +| Node Id | Set this property to expand the node when it is clicked options being Do Nothing or Expand Node. (available only when the above Dataset Value is bound to a variable) | +| **Default Value** | +| Value | The default value to be set at runtime. Can be: - none, - FirstNode or SecondNode, - value for the Node Id property. When `datavalue` is `FirstNode`, the First Node of the tree will be selected. When `datavalue` is `LastNode`, the Last Node of the tree will be selected. When `datavalue` is bound to a condition (eg, datavalue="role === 'admin'"), The condition is evaluated for each node of the tree until the condition is satisfied. The first node which satisfies the given condition will be selected. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| **Format** | +| Horizontal Align | This property specifies how the elements should be aligned horizontally. | + +## Events + +| Event | Description | +| --- | --- | +| **Callback Events** | +| On Select | This event handler is called when the tab is selected. | + +## Methods + +The tree widget has a few methods exposed on widget scope which can be accessed via JavaScript. + +| Purpose | Usage | +| --- | --- | +| Select a node | ```Page.Widgets.[treeName].selectById(dataValue);``` ```//This method selects the node in the tree rendered.``` ```//This method accepts datavalue of the node to be selected.``` ```//Datavalue of the node is the `Node Id` field value``` ```//mapped in the property panel for the tree widget. ``` | +| Deselect a node | ```Page.Widgets.[treeName].deselectById();``` ```//This method clears the selectedNode.``` ```//Doesn’t require any parameters``` | + +## Use Cases + +- [How to build a tree from static variable](/learn/how-tos/tree-use-case-static-variable/) +- [How to build tree from java service](/learn/how-tos/tree-use-case-java-service/) +- [How to build a dynamic tree](/learn/how-tos/tree-use-case-dynamic-tree/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/video.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/video.md new file mode 100644 index 000000000..b61e585c8 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/basic/video.md @@ -0,0 +1,79 @@ +--- +title: "Video Widget" +id: "video" +sidebar_label: "Video" +--- +--- + +WaveMaker supports video media. To use a video in your project, simply drag and drop the **Video** widget and bind it to the resource using the Property Panel. + +:::note +The following table gives the browser support for **audio** and **video** resources. To learn more about audio file support, see [Audio Widget](/learn/app-development/widgets/basic/audio). +::: + +|Browser|MP4|WebM|Ogg| +|---|---|---|---| +|Internet Explorer|YES|NO|NO| +|Chrome|YES|YES|YES| +|Firefox|YES|YES|YES| +|Safari|YES|NO|NO| +|Opera|YES (from Opera 25)|YES|YES| + +## Using Video Widget + +The following features are available for all the **Video** widget. + +1. From the **Property** panel of the media widget, find the **Video** section. Locate the **MP4 Source Path** option and click the **Bind** icon represented by a chain-link as shown in the picture below; a Bind modal dialog pops-up. + + [![media video](/learn/assets/media_video.png)](/learn/assets/media_video.png) + +2. In the modal dialog, click the **Resource** tab. + +3. Select the **Video** type from the dropdown and click the **Upload New** button, the **Import Video** modal dialog pops-up. + + [![media resource](/learn/assets/media_resources.png)](/learn/assets/media_resources.png) + +## Video Customizations + +You can add customizations from the **Properties** panel. + +1. **Height and Width** — these attributes sets the dimensions of the video +2. **Poster** — poster frame to show prior to video playback +3. **MP4 source path** — sets the media resources for MP4 media elements +4. **Ogg source path** — sets the media resources for Ogg media elements +5. **WebM source path** — sets the media resources for WebM media elements +6. **Video preload** — hints how much buffering the media resource will likely need +7. **Support message** — allows the user agent to display video content within the element's playback area +8. **Subtitle source** — this property is used to specify subtitles, caption files or other files containing text, that should be visible when the media is playing. +9. **Subtitle language** — specifies the language of the track text data (required if kind="subtitles") +10. **Enable controls** — check/Uncheck for enabling controls `play, pause, stop or volume` for the media player +11. **Enable autoplay** — check/Uncheck for enabling control +12. **Loop** — whether to loop the media resource +13. **Mute** — whether to mute the media resource by default. + +## Video Widget Properties + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for the video widget. | +| **Accessibility** | +| Hint | Any text or HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE:** In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Video** | +| Poster | This property allows you to set an image to be shown while the video is downloading, or until the user hits the play button. | +| MP4 Source Path | This property allows you to set an video/mp4 format of the video. | +| OGG Source Path | This property allows you to set an video/Ogg source of the video. | +| WEBM Source Path | This property allows you to set an video/WebM source of the video. | +| Video Preload | This property allows if and how the author thinks the video should be loaded when the page loads. Can be set to: - none - default - metadata, or - auto | +| Support Message | This property allows setting the message when Html 5 video is not supported. | +| Subtitle Source | This property allows setting the source URL for the subtitle in the .vtt format. | +| Subtitle Language | This property allows setting the language for the subtitle. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. | +| Enable Controls | This property allows you to enable that audio/video controls should be displayed (such as a play/pause button etc). | +| Enable Autoplay | This property allows you to enable if and how the author thinks the video should be loaded when the page loads. | +| Loop | This property allows you to enable that the video will start over again, every time it is finished. | +| Mute | This property allows you to enable that the audio output of the audio/video should be muted. | \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/chart/chart-widget.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/chart/chart-widget.md new file mode 100644 index 000000000..26b8951d9 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/chart/chart-widget.md @@ -0,0 +1,256 @@ +--- +title: "Chart Widgets" +id: "chart-widget" +--- +--- + +Use chart widgets to represent data in a pictorial format. Using chart widgets, you can transform data into various chart types. + +## Chart Types + +In WaveMaker Studio, you can use the following chart types as specified below. + +:::note +This documentation page and charts may take a few seconds longer to load. Wait for the charts to load fully. +::: + +### 1. Line Chart + + + +### 2. Area Chart + + + +### 3. Column Chart + + + +### 4. Bar Chart + + + +### 5. Pie Chart + + + +### 6. Donut Chart + + + +### 7. Bubble Chart + + + + +## Chart Comparison + +The chart type property can be used to portray the data in various forms. Each type has its own advantages and disadvantages. Select the appropriate type depending upon the data and what you want to represent. + +- **Comparison of data** is the most common usage of charts. It can be: + - Comparing quarterly sales figure over a period of 3 years in which case a **column** chart would be best + - Comparing the sales figures of say 10 different brands of any given product, wherein a **bar** chart would be most ideal + - Trying to follow a trend like population over a period of time would be best depicted by a **line** chart +- **A composition of data** like types of users for a product can be depicted accurately through a **pie** chart. +- **Bubble** chart can be used to show **three dimensions** in a chart. Apart from the x-axis and y-axis, the size of the bubble can represent the third dimension. + +Choose the type according to your need, you might want to try different types before settling for the best. + +## Features + +Charts are used for graphical display of data  and WaveMaker charts come  with the following features: + +- The _Title_, _Sub Heading_, and _Icon_ can be set. +- [Data](#data) can come from various sources like database, web service or another widget and can be accessed through binding to Live or Service Variables +- [The layout](#layout) can be set in terms of themes, positioning, formats for labels, captions, axis etc.. +- [Types](#comp) of charts for various purposes. +- [Data aggregation](#data-aggregation) and grouping for displaying summary graphs. +- Run-time [user-interaction](#user-interaction) +- Capturing [user selection](#user-selection) + +## Data Sources + +Data can come from various sources as listed below: + +- From Database, +- From Live Filter, +- From Web Services. + +The X-Axis and Y-Axis values can be set to the fields from the data source, the chart is bound to. + +[![](/learn/assets/charts_feat1.png)](/learn/assets/charts_feat1.png) + +Depending upon the data type of the underlying fields, you can choose the Data Display Format. + +[![](/learn/assets/chart_as_yaxis_format.png)](/learn/assets/chart_as_yaxis_format.png) + +In the case, when the data source is from Web Services or Web Socket, you can choose the Format Type to be toDate or toNumber. + +[![](/learn/assets/chart_as_yaxis_formattype.png)](/learn/assets/chart_as_yaxis_formattype.png) For **Pie** and **Donut charts**, the options include Label and Value fields. You can specify + +- the position of the Values - hidden, outside (default) or inside +- the Value to be displayed - as key, value, percent (default) or key-value pair + +[![](/learn/assets/chart_as_pievalues-6.png)](/learn/assets/chart_as_pievalues-6.png) + +## Layout + +- The **theme** for charts can be chosen from a list of options. +- **Custom Colors **can be used to change the set of colors that comes predefined with the selected theme. The values for this property can be + - comma separated values, eg. red, green, blue + - bound to a static variable containing the color names or the color hash codes +- The **position** of the chart can be defined in terms of the offset values. +- **Legend** position can be set to be top or bottom. +- Layout of the **values** can be defined in terms of location, value format, caption for line charts  and more + +[![](/learn/assets/charts_feat2.png)](/learn/assets/charts_feat2.png) + +These options are available from the Advanced Settings of the chart. Apart from these properties, a **Title**, **Sub Heading**, and **Icon** can be assigned for the chart as a whole to be displayed on the top left corner of the Chart. + + + +## Data Representation + +This property defines how the data is represented in the chart. + +### Datapoint Interpolation + +Property determines how data points are joined and represented in the chart. This property is applicable to Line, Area and Cumulative Line Charts. Value can be set to: + +- Linear, +- Cardinal for smooth curves, or +- Step + +[![](/learn/assets/chart_interpolation.png)](/learn/assets/chart_interpolation.png) + +### Data Arrangement +Data Arrangement Property (available only for Column, Area and Bar Charts) controls whether to show the areas in: + +- stack, +- stream, or +- expand + +[![](/learn/assets/chart_arrangement.png)](/learn/assets/chart_arrangement.png) + +## Data Aggregation and Grouping + +When dealing with charts bound to live variables, you can add additional functionality to these charts. You can order the data, group the data and show the aggregate functions in your chart. The aggregation functions available are _average, count, minimum, maximum and sum_. + +- In the _Aggregation_ property and _Group by_ property can be used to set the aggregation functions. +- _Order By_ property can be used to set the column by which the data needs to be sorted. By default, it will be set to the Group by column selected. +- The values to be depicted on x and y-axis are set to the _group by_ and _aggregation columns_ respectively. + +[![](/learn/assets/charts_feat3.png)](/learn/assets/charts_feat3.png) + +## Interaction + +- You can interact with the charts by selecting/unselecting the column names from the legend. +- Hovering mouse over any column displays the values of X and Y-Axis for that data point. +- These data points can be captured and used to bind to a widget for further display or computational purposes from the selected item of the chart widget + +## Capturing User Selection + +You can capture user selection in two ways: + +1. The various outbound properties of a chart are available for binding to other widgets or variables. The fields under _selecteditem_ will be from the underlying dataset used for binding. + +[![](/learn/assets/chart_output.png)](/learn/assets/chart_output.png) + +2. These selected values can be accessed via JavaScript + +```js +Page.chart3Select = function($event, widgets, selectedItem, selectedChartItem) +{ + Page.Widgets.key.datavalue = selectedChartItem.key; // key value of selected item + Page.Widgets.xv.datavalue = selectedChartItem.x; // x value of selected item + Page.Widgets.yv.datavalue = selectedChartItem.y; // y value of selected item + Page.Widgets.selectname.datavalue = selectedItem.name; // name field of selected object + Page.Widgets.selectdept.datavalue = selectedItem.deptcode; // deptcode of selected object +}; +``` + +Here we have used the _On select_ event of the chart: + +[![](/learn/assets/chart_events.png)](/learn/assets/chart_events.png) + +## Chart Legend Captions + +Chart legend caption is the label or description that gets displayed when you hover over the chart legend item in the chart. These labels help you in interpreting the chart by associating each data series or category with a descriptive label. + +:::note + +WaveMaker internally uses the nvd3 library to load the charts. But with the nvd3 1.0.3 version, the captions are not populating as expected in the chart. You can upgrade to the nvd3 1.8.1 version to fix the caption issues. + +::: + +To upgrade the nvd3 library version to 1.8.1 you need to provide the below in the **index.html** file. + +```js + +``` + +### Populating Chart Legend Captions + +In WaveMaker studio, to populate the chart legend captions, you need to add the below specified JavaScript snippet on the chart **On Before Render** event. + +1. Create a [Pie Chart](#5-pie-chart). +2. Set the Pie Chart's "On Before Render" property to JavaScript. + +[![](/learn/assets/set-javascript.png)](/learn/assets/set-javascript.png) + +3. Go to the Script and add the below code snippet in it. + +```js +Page.chart4_1Beforerender = function(widget, chartInstance) { + var tooltip = nv.models.tooltip(); + tooltip.duration(0); + chartInstance.legend.dispatch.legendMouseover = function(o) { + console.log(o); + if (tooltip.hidden()) { + var data = { + series: { + key: o.x, + value: o.y, + color: o.color + } + }; + tooltip.data(data) + .hidden(false); + } + tooltip.position({ + top: d3.event.pageY, + left: d3.event.pageX + })(); + }; + chartInstance.legend.dispatch.legendMouseout = function(o) { + tooltip.hidden(true); + } +}; +``` + +[![](/learn/assets/onbeforerender-code.png)](/learn/assets/onbeforerender-code.png) + +### Customizing charts with rounded corners +Inorder to achieve rounded corners for column and bar charts add class **'rounded-cornered-chart'** and for area chart add class **'rounded-area-chart'** to the chart widget. + +#### Column Chart +[![](/learn/assets/rounded-column-chart.png)](/learn/assets/rounded-column-chart.png) + +#### Bar Chart +[![](/learn/assets/rounded-bar-chart.png)](/learn/assets/rounded-bar-chart.png) + +### Customizing grid line on the charts +Solid stroked line on x-axis and y-axis zero line can be achieved by adding **'stroked-zero-axis-line'** class +and dotted grid lines on y-axis can be achieved by adding **'dotted-yaxis-grid-line'** class. + +#### Stroked Zero line and Dotted Y-axis grid lines + +[![](/learn/assets/rounded-column-chart.png)](/learn/assets/rounded-column-chart.png)](/learn/assets/rounded-column-chart.png)](/learn/assets/rounded-column-chart.png) + + +## Use Cases + +- [Basic Usage](/learn/app-development/widgets/chart/charts-basic-usage/) +- [How to capture user selection](/learn/how-tos/charts-displaying-user-selection-another-widget/) +- [How to handling dynamic data](/learn/how-tos/charts-handling-dynamic-data/) +- [How to displaying custom data](/learn/how-tos/charts-custom-data/) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/chart/charts-basic-usage.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/chart/charts-basic-usage.md new file mode 100644 index 000000000..a30055598 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/chart/charts-basic-usage.md @@ -0,0 +1,36 @@ +--- +title: "Charts - Basic Usage" +id: "charts-basic-usage" +--- + +**Step 1: Datasource & Type** + +Once the data is imported and is ready to use follow these steps for chart creation. + +1. Go to the page layout of your application and drag-and-drop the required chart widget. Here, we are creating a column chart. ![](/learn/assets/chart_usage1.png) +2. Bind the chart to the appropriate data source. +3. Click on the _link _icon next to the _Value_ Property and choose the appropriate variable for data binding. In this example, we are using the transformed data from a web service, Quandl imported earlier. + +**Step 2: Properties** + +1. Select the values to be depicted on the x-axis and the y-axis. You can select multiple columns for the y-axis. You can add a caption for the axis, else by default the column names from the database table is taken as the caption. + +:::note +You can not use string data for plotting on the y-axis. +::: + +:::note +For **Donut and Pie Charts**, you can specify the Label and Value Data fields for representation instead of x- and y-axis. +::: + +![](/learn/assets/chart_properties.png) +2. Run your application to see the data represented in the chart format. + +**Step 3: Aggregation & Group by** + +We will see how to use this functionality using the in-built **HSQL Database** which ships with WaveMaker Studio. Let us plot the number employees working in each city from the database. + +1. In the _Aggregation_ property select _count_ and select _eid_ as the _Aggregation_ column and _state_ for _Group by_. You can also use the _Order By_ property to set the column by which the data needs to be sorted. By default, it will be set to the Group by column selected. +2. The values to be depicted on x- and y-axis are set to _state_ and _eid_ columns respectively. These are the _group by_ and _aggregation columns_ respectively. +3. Run the application to see the chart. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/chart/onbeforerender.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/chart/onbeforerender.md new file mode 100644 index 000000000..de7961c4f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/chart/onbeforerender.md @@ -0,0 +1,53 @@ +--- +title: "Callback Event for Charts Widget" +id: "onbeforerender" +sidebar_label: "Callback Event" +--- +--- + +The onBeforeRender method contains 2 parameters. + +That includes, + +1. Widget +2. chartInstance + +## Widget + +Widget is the WaveMaker instance of the Chart widget. + +## chartInstance + +This is the nvd3 chart object which can be used to manipulate the chart by setting properties supported by the nvd3 library. + +This method can optionally return an nvd3 chart object to change the complete chart which is being rendered. So in case a chart is not supported by default in WaveMaker and is supported in nvd3 the user can create that charts nvd3 object and return the newly created nvd3 object, this will render the new nvd3 object i.e. the new chart will be rendered. + +:::note +To set chart data, use the `widget.setChartData` method. +::: + +``` +Syntax: +Page.chart1Beforerender = function(widget, chartInstance) { + +} +``` + +## Example + +``` +Page.chart1Beforerender = function(widget, chartInstance) { + chartInstance = nv.models.discreteBarChart() + .x(function(d) { + return d.x + }) + .y(function(d) { + return d.y + }) + .showValues(true); + chartInstance + .xAxis.staggerLabels(true); + chartInstance.tooltip(true); + widget.chart = chartInstance; +} +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/confirm-dialog.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/confirm-dialog.md new file mode 100644 index 000000000..ff55da582 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/confirm-dialog.md @@ -0,0 +1,71 @@ +--- +title: "Confirm Dialog" +id: "confirm-dialog" +--- +--- + +[![confirm_struct](/learn/assets/confirm_struct.jpg)](/learn/assets/confirm_struct.jpg) + +## Overview +Dragging and dropping a dialog creates a **view** containing the dialog. The view can be selected from the **Page Structure** or from the **tabs** given at the bottom. The display of the dialog box at runtime is usually associated with the _onClick_ event of a **Button** widget. You can also trigger the dialog by calling methods from _JavaScript_. + +## Confirm Dialog +Confirm Dialog is used to get confirmation from the user. In addition to the properties mentioned for Alert Dialog, it has an additional **Cancel **button. The most common usage is to confirm a delete action. + +[![](/learn/assets/dialog_confirm.png)](/learn/assets/dialog_confirm.png) + + +## Script Access + +**Dialog** widget in your project can be accessed by associating the open and _close_ properties of the dialog with an event of any other widget. The dialog can be accessed through scripting by adding _DialogService_ to the _page controller_ and adding the code for _open_ and _close_ as shown below, here we are displaying an alert dialog on click of a button: Click event of the button should trigger the following JavaScript code: + +``` +Page.button3Click = function($event, widget) { + Page.Widgets.confirmdialog1.open(); + } +``` + +For hiding dialog: +``` +/* function called on button1 click */ + Page.button1Click = function($event, widget) { + Page.Widgets.confirmdialog1.close(); + }; +``` +## Properties & Events +--- +### Confirm Dialog Properties + +| Property | Description | +| --- | --- | +| Title | Set the title of the widget. | +| Name | The name is a unique identifier for the confirm dialog. | +| Message | Set the display message for the widget. | +| Ok Text | This Confirm Dialog prompts to get confirmation from the user. | +| Cancel Text | This widget gives a pop-up window. It can be used to get confirmation of an action from the user. For example, do you want to delete this item? | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** || +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Modal | This property, if set true, adds a backdrop for the dialog restricting the closure of the dialog when the user clicks outside of the dialog. The default value is false, which allows close of dialog on click outside. | +| **Behavior** | +| Enable Default Close Action | This property allows the user to access close action from header through an "x" icon; and also enables close through ESC key. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| Keyboard | This property if set true allows closing of dialog on ESC keypress. The default is true. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. | +| Icon Width | Optional property; but you will need this if you are using the button's iconUrl. Please enter the width of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Height | Optional property; but you will need this if you are using the button's iconUrl. Please enter the height of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | + +### Confirm Dialog Events + +| Event | Description | +| --- | --- | +|**Callback Events**|| +| On ok | This event handler is called whenever an ok event is triggered. | +| On cancel | This event handler is called whenever a cancel event is triggered. | +| On close | This event handler is called whenever a close event is triggered. | +| On open | This widget gives a pop-up window. It can be used to give a warning message to the user. For example, you are about to leave this page. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/container/accordion.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/accordion.md new file mode 100644 index 000000000..8c19f620b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/accordion.md @@ -0,0 +1,138 @@ +--- +title: "Accordion" +id: "accordion" +--- + +An **accordion** is a stacked list of UI components, with only one focused component expanded at any point of time and the rest collapsed. + +WaveMaker **Accordion Widget** is a collection of accordion panes where users can either place the content or include the partial pages. [![](/learn/assets/accordion_run.png)](/learn/assets/accordion_run.png) + +## Features + +When you drag and drop an Accordion, by default three accordion panes are provided. More accordion panes can be added by using _Add Accordion Pane_ action. Within each accordion pane, widgets like Data Table, List etc can be dragged and dropped and you can hide/show accordion panes according to the app requirement. In addition, you can provide the content as Partial Pages – for example – create a partial page and use that content within an accordion pane. + +### Basic Features - Accordion + +1. _Panes_ - Collection of AccordionPane controls +2. _Height_ - Set height to the Accordion. This will restrict the height of the accordion and scrollbar will appear in case the content is more. +3. _Close others_ - Check/Uncheck to allow multiple accordion panes to be visible parallelly. + +### Basic Features - Accordion pane + +1. _Header_ - The Header of accordion pane contains a title and icon +2. _Sub Header_ - Sets subheading for the accordion pane +3. _Content_ - The content in the accordion pane. This can be either + - _inline_ - HTML content, widgets etc., + - _partial _- any partial you have created within the app can be used as pane content +4. _Badge_ - Indicated the small meaning information. The badge type can be set different styles - primary, success, info, warning, or danger on the accordion pane components to customize the look and feel. It can be bound to a variable, for example, to indicate the number of employees in a department +5. _Is pane default_ - Sets a default pane to be opened when the accordion is rendered + +[![](/learn/assets/accordion_prop.png)](/learn/assets/accordion_prop.png) [![](/learn/assets/accordion_pane_prop-1.png)](/learn/assets/accordion_pane_prop-1.png) + +### Accordion Types + + + +## Usage + +- [Setting partial page content for Accordion within a List](/learn/how-tos/setting-partial-page-content-accordion-within-list/) + +## Methods + +The accordion has few methods exposed on widget scope which can be accessed via JavaScript. See below for usage example. + +- to Collapse a pane: + ``` + Page.Widgets.accordionpane1.collapse(); //collapse the specific pane. + ``` +- to Expand a pane: + ``` + Page.Widgets.accordionpane1.expand(); //Expands sales accordion pane. + ``` +- to toggles a pane i.e. opens if closed, closes if opened: + ``` + Page.Widgets.accordionpane1.toggle(); //toggles sales accordion pane. + ``` + +## Script Access + +**Step 1:- (Prepare data and widgets)** + +1. Create three variables of type ‘Employee’ entity and for 1st variable from variables tab select the variable and go to data tab and for deptid keep value as 1, do the same for others also as deptid 4, 2 for respective variables, name these variables as ‘EngineeringEmployeesData’, ‘SalesEmployeesData’, ‘MarketingEmployeesData’. [Learn how to create variables from here.](/learn/app-development/variables/database-crud/#menu) +2. Drag n Drop Accordion widget. By default, you will see accordion with 3 accordion panes. +3. Name ‘Accordion’ widget as ‘EmployeesAccordion’ and name accordion panes as ‘engineeringEmpPane’, ‘salesEmpPane’, ‘marketingEmpPane’. +4. Change accordion panes titles to ‘Engineering’, ‘Sales’, ‘Marketing’. +5. Drop ‘List’ widget in each of these tabs and bind to respective variables and map template widgets to respective fields. +6. Drop two buttons and name the first button as ‘collapseSalesBtnPane’, the second one as ‘expandSalesBtnPane’ and also change the titles to ‘Collapse Sales Employees Pane’, ‘Expand Sales Employees List’. + +**Step 2:- (Scripting with accordion)** + +1. Select JavaScript for the on click event of ‘collapseSalesPaneBtn’ and use the following as JavaScript function with the following script: +``` +Page.collapseSalesPaneBtnClick= function($event, widget) { + Page.Widgets.salesPane.collapse(); //Expands sales accordion pane. +}; +``` +2. Select JavaScript for the on click event for ‘expandSalesPaneBtn’ and use the following script: +``` +Page.expandSalesPaneBtnClick = function($event, widget) { + Page.Widgets.salesPane.expand(); //Collapses sales accordion pane. + }; +``` + +**Step 3:- (Run)** + +1. Run the application and by default first accordion will be expanded by default or if any pane is set as isDefaultPane that particular pane will be expanded on a load of the page. +2. Now click on ‘expandSalesPaneBtn’ and see sales accordion pane will be expanded. +3. Now click on ‘collapseSalesPaneBtn’ and see sales accordion pane will be collapsed. + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the Accordion. Special characters and spaces are not allowed in widget name. | +| Add Accordion Pane | This action allows one to add multiple panes to the Accordion. | +| **Accessibility** | +| Tab Index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately, irrespective of this property setting. | +| Close Others | This property specifies whether, on clicking of an accordion panel, other panels should close or not. | + +**Accordion Pane** SubWidget of Accordion, to hold the accordion header and content. + +| **Property** | **Description** | +| --- | --- | +| Title | This bindable property defines the heading or title for the accordion pane. | +| Sub Heading | This bindable property defines the subheading for the accordion pane. It is displayed right below the Title of the Pane. | +| Name | The name is a unique identifier for the accordion pane. Special characters and spaces are not allowed in widget name. | +| Badge Value | Value to be displayed in the badge area on the right edge of title next to the expand/collapse button. It is a bindable property. | +| Badge Type | This bindable property controls the color of the badge. The values are: - _default_, - _primary_, - _success_, - _info_, - _warning_, - _danger_. | +| **Accessibility** | +| Tab Index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. + +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Height | The height of the widget can be specified in px or % (i.e 50px, 75%). | +| **Content** | +| Content | Bindable property, specifies the content to be displayed within the Accordion Pane: - Inline Content - HTML content or any widget. - Page Content - in the form of Partial pages created within the app, choose from the available list. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is bindable. | +| Is Default Pane | This bindable property determines if this pane is the default pane. | +| **Graphics** | +| Icon Class | This bindable property defines the class of the icon that is applied to the button. | + +## Events + +The following events are available on the Accordion Panes + +| **Event** | **Description** | +| --- | --- | +| On load | This property defines the event handler for the load event of the accordion panes. | +| **Callback Events** | +| On expand | This property defines the event handler for the expand event of the accordion panes. | +| On collapse | This property defines the event handler for the collapse event of the accordion panes. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/container/container.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/container.md new file mode 100644 index 000000000..609e1ccd7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/container.md @@ -0,0 +1,53 @@ +--- +title: "Container" +id: "container" +--- +--- + +**Container widget** is an empty box for flow content, a collection of more semantically marked-up content that may need to be grouped together with the class, lang and title attributes. It represents its children. The users can either place the content or include the partial pages. + +Containers are semantically correct for laying out content. Its most common use will likely be for stylistic purposes — i.e., wrapping some semantically marked-up content in a CSS-styled container. + +## Properties + +You can also use the Conditional Class property from the Style tab to set the class based upon a condition. For more information, see the [How-to](/learn/how-tos/use-conditional-class-property/) doc. + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the container widget. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| **Content** | +| Content | This bindable property, defines the content to be displayed within the container: - Inline Content - HTML content, - Page Content - in the form of Partial Pages, choose from the list provided | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| **Format** | +| Horizontal Align | Set text alignment horizontally. | + +## Events + +| **Event** | **Description** | +| --- | --- | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On double click | This event handler is called whenever the double click event is triggered on a widget. | +| On mouse over | This event fires when the mouse hovers over this widget. | +| On mouse out | This event fires when the mouse moves away from this widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On Tap | This event handler is called whenever the tap event is triggered on a widget. | +| On Double Tap | This event handler is called whenever the double tap event is triggered on a widget. | +| On Long Tap | This event handler is called whenever the long tap event is triggered on a widget.
Note: Long Tap event is only supported in React Native applications.| +| On swipe up | This event handler is called whenever the swipeup event is triggered. | +| On swipe down | This event handler is called whenever swipe down event is triggered. | +| On swipe left | This event handler is called whenever a swipeleft event is triggered. | +| On swipe right | This event handler is called whenever a swiperight event is triggered. | +| On pinch in | This event handler is called whenever pinch event is triggered. | +| On pinch out | This event handler is called whenever pinch out event is triggered. | +| **Keyboard Events** | +| On enter key press | When the user hits ENTER/Return while the focus is in this editor, execute the specified event handler. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/container/flex-layout.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/flex-layout.md new file mode 100644 index 000000000..470716c7f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/flex-layout.md @@ -0,0 +1,14 @@ +--- +title: "Flex Layout" +id: "flex-layout" +--- + +Flex Layout is just a [Layout](./layout) only with 3 children. Middle child has **flex grow** is set to 1. Other children have **flex grow** set to 0. + +![](/learn/assets/widgets/container/layout/flex-layout.png) + +It is observed that this type of layout is predominantly used in mobile apps. Instead of developer creating it everytime from the generic Layout widget, a simple drag and drop option will be helpful to developer. + +:::warning +Layout and Flex Layout are available only for React Native apps. Cordova and Web apps will be supported in future. +::: diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/container/grid-layout.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/grid-layout.md new file mode 100644 index 000000000..fd2a22850 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/grid-layout.md @@ -0,0 +1,97 @@ +--- +title: "Grid Layout" +id: "grid-layout" +--- + +**Grid Layout** is the basic content layout, that caters to multiple layout needs. Using the grid layout, you can divide your page content into cells or grids and place your widgets accordingly. It gives you a flexibility of widget placement without having to get into the intricate design details. The major advantage of using grid layout is its rendering capability. WaveMaker renders the screen depending upon the device being used for viewing the app like mobile, tablet, etc.. + +WaveMaker implements the [Bootstrap Grid](http://www.w3schools.com/bootstrap/bootstrap_grid_system.asp) system which is the 12-column system: + +[![](/learn/assets/gridlayout_bootstrap.png)](/learn/assets/gridlayout_bootstrap.png) + +## Features + +### Grid Layout - Basic Features + +Grid Layout when dropped on the canvas, gives you a two-row, two-column grid to which you can: + +- **Grid-level features** + + - set the number of columns needed for your grid, this will be propagated to all the rows of the grid; + - change the height and width of the grid; + - move the columns and rows anywhere in the grid; + - _insert_ rows to the existing grid. When inserting a new row, the last row pattern is replicated, i.e. if you have the last row with two columns then the new row added will also be a two-column row. + + [![](/learn/assets/gridlayout_props.png)](/learn/assets/gridlayout_props.png) +- **Row-level features** + + - change the height of the row, + - add columns to the row from the properties panel of the selected row. When adding columns, WaveMaker ensures that the sum of all the column widths does not exceed 12. + - insert a row either before or after the selected row + - delete a selected row, by clicking delete key after selecting the row + + [![](/learn/assets/gridlayout_rowprops.png)](/learn/assets/gridlayout_rowprops.png) +- **Column-level Features** + + - change the height and width of the column from the properties panel of the selected cell. + - insert a cell before or after the selected cell. + - delete a selected column, by clicking delete key after selection. + + [![](/learn/assets/gridlayout_colprops.png)](/learn/assets/gridlayout_colprops.png) + +### Grid Layout Column Width Settings + +WaveMaker ensures that the sum of all columns in a given row does not exceed 12. For this, following scenarios are handled: + +- **While adding columns:** Columns can be added either by selecting a row or from selecting a column: + - Row or column is selected: If previous columns are of the same width, the new column width and other columns width is set as 12 / (number of columns) ie.. if previous both columns are 6 and insert column is triggered the column width of all columns will be 12 / 3 = 4. + - The row is selected and all columns are of different width: In this case, the column width will be set to last column width / 2 if it is > 1; if it is < = 1 new column will not be allowed to insert. + - Column is selected and all columns are of different width: In this case, the new column width will be width / 2 of selected column if its > 1 else new column will not be allowed to insert +- **While adding columns:** + - If total column width is 12 along with the changed width: In this case, it won't adjust the width, it will change the current column width. + - If total column width is greater than 12 along with changed width:  If it can borrow the same from sibling element it will adjust the width else it won't allow the change of width. + - If total column width is less than 12 along with the changed width:  It will add the width to sibling element that is reduced from current column. + +The following image gives you an idea of the flexible design that grid layout offers. The first row has three columns with the width being 4+4+4; second row three columns - 1+10+1; the third row with two columns - 6+6 and the last row same as the first row. + +[![](/learn/assets/gridlayout_final.png)](/learn/assets/gridlayout_final.png) + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the grid layout widget. | +| Insert | Add a row to the grid layout, at the bottom. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Columns | Number of columns in each row of the layout grid widget. Columns are droppable. The number of columns restricted to a range, to suit bootstrap fluid grid system. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | + +### Row Properties + +A sub widget of the grid layout is the direct child of the grid. + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the grid row. | +| Insert | Add a row either above or below the current row or add a column to the current row. | +| **Layout** | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | + +### Column Properties + +A sub widget of the grid layout is the direct child of the grid row. + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the grid column | +| Insert | Add a column either before or after the current column. | +| **Layout** | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Format** | +| Horizontal Align | Set text alignment horizontally. | +| Column Width | Accepts integer(x) between 1-12 and adds class col-md-(x), to suit bootstrap fluid grid system. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/container/layout.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/layout.md new file mode 100644 index 000000000..e0094807d --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/layout.md @@ -0,0 +1,110 @@ +--- +title: "Layout" +id: "layout" +--- + +As the name suggests, **Layout** widget is used to build scaffold to hold widgets. Underlyingly, this widget uses wm-linearlayout and wm-linearlayoutitem components. Let us understand these components first. + +:::warning +Layout and Flex Layout are available only for React Native apps. Cordova and Web apps will be supported in future. +::: + +## Components + +**wm-linearlayout** is a container that can only hold **wm-linearlayoutitem** as children. Following [flex-box](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox) model, wm-linearlayout arranges its children based on direction property. + +Using horizontal and vertical alignment properties, children can be aligned w.r.t wm-linearlayout. + +Space between two subsequent children can be configured using Spacing property on wm-linearlayout. If a wm-linearlayout does not have spacing property and is inside another wm-linearlayout, then spacing property is inherited from parent. + +Linear Layout allocates space to its children in the following way. + +1. Space sufficient for each indivicual child is allocated. +2. If there is any remaining space available, remaining space is allocated based upon flex grow property value on each wm-linearlayoutitem. + +For example, let's say that there is horizontal linearlayout with three children and width as 600. + +- First item requires a width of 50 and has flex property set as 0. +- Second item requires a width of 150 and has flex property set as 2. +- Third item requires a width of 100 and has flex property set as 1. + +Total space remaining is 300 (600 - 50 - 150 - 100). + +Total flex value is 3 (0 + 2 + 1). + +Space is allocated as follows: + +| | Item 1 | Item 2 | Item3 | +|--|-------|--------|-------| +| factor =
(individual flex / total flex)| 0 / 3 | 2 / 3 | 1 / 3| +| Allocated Space =
(Total Remaining Space * factor) | 300 * (0/3) = 0 | 300 * (2/3) = 200 | 300 * (1/3) = 100| + +:::note +If there is no sufficient space for all children, then shrinkage happens. But, flex shrink is not supported now. +::: + +## Layout Construction +When a Layout widget is dragged and dropped into studio canvas, a wm-linearlayout with a single wm-linearlayoutitem child are added to the markup. Further Layout construction can be done in two ways. In the first way, layout is going to be explicity built and widgets have to be dropped inside. In the second way, layout gets auto generated based on the drop position of a widget. + +### Explicit + +When a wm-linearlayout is selected, plus and minus buttons are shown. Using these buttons, wm-linearlayoutitem can be added or removed. By clicking on plus button, a child can be added at the end. By clicking on the minus button, the last child can be removed. + +If direction is horizontal, buttons are shown at right. + +![](/learn/assets/widgets/container/layout/buttons-1.png) + +If direction is vertical, buttons are shown at bottom. + +![](/learn/assets/widgets/container/layout/buttons-2.png) + +If wm-linearlayout has a single child, then add button is show at both bottom and right side. When a child is added, then the direction is automatically set based on the button clicked. + +![](/learn/assets/widgets/container/layout/buttons-3.png) + +Similarly, when a wm-linearlayoutitem is selected, plus buttons are shown at both right and bottom. + +1. Let us take child item of a horizontal layout. + +![](/learn/assets/widgets/container/layout/buttons-4.png) + +If a right plus button is clicked, a wm-linearlayoutitem is added to the same parent. + +If bottom plus button is clicked on a wm-linearlayoutitem (say item1), then a new wm-linearlayout (say layout2) with 2 items and direction as vertical, is added. All the content of item1 is moved to the first child of layout2. Then, layout2 is added into item1. + +2. Let us take child item of a vertical layout. + +![](/learn/assets/widgets/container/layout/buttons-5.png) + +If a bottom plus button is clicked, a wm-linearlayoutitem is added to the same parent. + +If right plus button is clicked on a wm-linearlayoutitem (say item1), then a new wm-linearlayout (say layout2) with 2 items and direction as horizontal, is added. All the content of item1 is moved to the first child of layout2. Then, layout2 is added into item1. + +:::note +![](/learn/assets/widgets/container/layout/insert-button.png) +Using the insert button in properties panel, wm-linearlayoutitem can also be added. +::: + +### Auto + +Layout is generated automatically whenever a widget is dropped into a wm-linearlayoutitem. It works based on the point of drop. + +1. If widget is dropped anywhere in an empty wm-linearlayoutitem (item), then widget is added in the item only. + +![](/learn/assets/widgets/container/layout/auto-linearlayout-step1.gif) + +2. If widget is dropped in the **left** half of wm-linearlayoutitem (item), then a wm-linearlayoutitem is added to the **bottom** of the item and widget is added in the newly created item. + +![](/learn/assets/widgets/container/layout/auto-linearlayout-step2.gif) +3. If widget is dropped in the **right** half of wm-linearlayoutitem (item), then a wm-linearlayoutitem is added to the **right** of the item and widget is added in the newly created item. + +![](/learn/assets/widgets/container/layout/auto-linearlayout-step3.gif) + +## Example +Below is an example to show how easy it is to construct layout automatically. Try this example (both explicit and auto) in WaveMaker Studio to get better understanding. + +![](/learn/assets/widgets/container/layout/auto-linearlayout-example.gif) + +:::note +In the last before step, flex grow property is set to zero on the wm-linearlayoutitem that has the picture. +::: \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/container/panel.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/panel.md new file mode 100644 index 000000000..ea919b4a1 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/panel.md @@ -0,0 +1,179 @@ +--- +title: "Panel" +id: "panel" +--- + +**A panel** can be used to group a set of widgets together. It has a collapsible title bar and you can add multiple panels and any number of multiple panes can be open at any given point of time. + +A panel has designated sections such as header, body, and footer. [![](/learn/assets/panel_run1.png)](/learn/assets/panel_run1.png) + +[![](/learn/assets/panel_run2.png)](/learn/assets/panel_run2.png) + +## Features + +- You can define the **content** of the panel to be another page, partial page or place widgets in the panel. +- The various **properties** can be set for the panel as per your needs: + + - **Actions** - entering a comma separated items or binding to a variable, would give a drop-down menu widget which can be handled. + - **Help Text** - entering text either in plain format or an HTML format will enable _help icon_ on the title bar of the panel which on click would display the help content. + - **Collapsible** - lets the user collapse or expand a given panel at runtime.  Note:  When the content of Panel widget is set to a partial and the initial state is collapsed, the loading of the partial is deferred/delayed until the widget is expanded for the first time. + - **Enable Full Screen** - lets the user make panel full screen + - **Expanded** - defines the default behavior of the panel + - **Enable Default Close Action** - lets user close the panel. This triggers an _onClose_ event, which the developer can choose to handle through JavaScript code. + - **Animation** - controls the animation behavior of the panel + - **Icon Class** - defines the icon to be displayed on the header + + [![](/learn/assets/panel_prop1.png)](/learn/assets/panel_prop1.png) [![](/learn/assets/panel_prop2.png)](/learn/assets/panel_prop2.png) + +### Usage + + + +### Panel Styles + +Panel style can be set by using the **Class Name** option from the **Styles** tab of the **Properties** panel. You can also use the Conditional Class property to set the class based upon a condition. See here for [How to](/learn/how-tos/use-conditional-class-property/). + + + +# Methods + +The panel has few methods exposed on widget scope which can be accessed via JavaScript. [See below for usage example](#script-access) + +- to close a panel: + ``` + Page.Widgets.panel1.close(); //Closes panel1 + ``` +- to expand a panel: + ``` + Page.Widgets.panel1.expand(); //Expand panel1 + ``` +- to collapse a panel: + ``` + Page.Widgets.panel1.collapse(); //collapses panel1 + ``` +- to toggle panel status: + ``` + Page.Widgets.panel1.toggle(); //Toggles the panel + // i.e expands if closed, closes if expanded + ``` +   +- to displays panel in full screen: + ``` + Page.Widgets.panel1.toggleFullScreen(); //displayes in full screen panel1 + ``` +- to show the help text as set from the properties panel: + ``` + Page.Widgets.panel1.toggleHelp(); //displays help text + ``` + +## Script Access + +**Step 1:- (Prepare data and widgets)** + +1. Create three variables of type ‘Employee’ entity and for 1st variable from variables tab select the variable and go to data tab and for deptid keep value as 1, do the same for others also as deptid 4, 2 for respective variables, name these variables as ‘EngineeringEmployeesData’, ‘SalesEmployeesData’, ‘MarketingEmployeesData’. [Learn how to create variables from here.](/learn/app-development/variables/database-crud/#menu) +2. Drag and Drop two Panel widget. +3. Name first ‘Panel’ widget as ‘engineeringPanel’ and second ‘Panel’ widget as ‘salesPanel’. +4. Check ‘collapsible’ and ‘closable’ on both the panel widgets from properties panel options. +5. For ‘engineeringPanel’ uncheck the ‘expanded’ property from properties panel as shown above and for ‘salesPanel’ check the ‘Enable full screen’ option from properties panel. +6. Change title of ‘engineeringPanel’ to ‘Engineering’ and subheading to ‘Dept’ and change title of ‘salesPanel’ to ‘Sales’ and subheading to ‘Dept’. +7. Drop ‘List’ widget in each of these panels and bind to respective variables and map template widgets to respective fields. +8. Drop three buttons and name the first button as ‘collapseSalesBtn’, the second one as ‘expandEngBtn’ and last one as ‘closeSalesBtn’ and also change the captions to ‘Collapse Sales Panel’, ‘Expand Engineering Panel’, ‘Close Sales Panel’. + +**Step 2:- (Scripting with accordion)** + +1. Select JavaScript for on click event of ‘collapseSalesBtn’ and use the following as javascript function with the following script: + ``` + Page.collapseSalesBtnClick = function($event, widget) { + Page.Widgets.salesPanel.toggle(); //Toggles the panel + // i.e expands if closed, closes if expanded + }; + ``` +2. Select JavaScript for the on click event for ‘expandEngBtn’ and use the following script: + ``` + Page.expandEngBtnClick = function($event, widget) { + Page.Widgets.engineeringPanel.toggle();//Toggles the panel + // i.e expands if closed, closes if expanded + }; + ``` +3. Select JavaScript for the on click event for ‘goToSalesBtn’ and use the following script: + ``` + Page.expandSalesPaneBtnClick = function($event, widget) { + Page.Widgets.salesPane.expand(); //Expands sales accordion pane. + }; + ``` +4. Select JavaScript for the on click event for ‘closeSalesBtn’ and use the following script: + ``` + Page.closeSalesBtnClick = function($event, widget) { + Page.Widgets.salesPanel.close(); //Closes sales panel + }; + ``` + +**Step 3:- (Run)** + +1. Click on ‘Collapse Sales Panel’ and see it toggles the sales employees panel i.e if expanded closes it and if closed expands it. +2. Click on ‘Expand Engineering Panel’ and see it toggles the sales employees panel i.e if expanded closes it and if closed expands it. +3. Click on ‘Close Sales Panel’ and see it closes the Sales panel. + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Title | Set the title of the panel. It is bindable. | +| Sub Heading | Set the subheading of the panel. It is bindable. | +| Name | The name is a unique identifier for the panel. | +| Badge Value | Value to be displayed in the badge span. It is bindable | +| Badge Type | This bindable property controls the color of the badge. These values are default, primary, success, info, warning, danger. | +| **Accessibility** | +| Help Text | If this property has a value, a "?" icon is added next to your editor. If the user points the mouse at this icon, the text you put into this helpText property will popup for the user. | +| **Layout** | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Content** | +| Content | Html content(in the case of an HTML widget) or Page's content(in the case of page container widgets) will be included in the widget. | +| **Actions** | +| Menu Actions | This bindable property sets the actions for the widget. To set the data and events see [dropdown menu widget](/learn/app-development/widgets/navigation/dropdown-menu-use-cases/). | +| Action Label +(available only when the above Menu Actions is bound to a variable) | Label for anchor or menu tags generated dynamically. | +| Action Icon (available only when the above Menu Actions is bound to a variable) | Class for the action. Example- 'fa fa-ban' or 'glyphicon glyphicon-cloud'. | +| Action Link (available only when the above Menu Actions is bound to a variable) | Link for the action item. | +| Action Task (available only when the above Menu Actions is bound to a variable) | Task for menu items generated dynamically. This is the action that will be triggered when the user clicks on the Menu Item. It can be a script like: Widgets.label1.show or Variables.v1.invoke() Execution order on click of Node: 1. If provided _onSelect_ will be executed first. 2. If provided _Action_ will be executed next. 3. If provided _Action link_ will be executed last. | +| User Role (available only when the above Menu Actions is bound to a variable) | Role for menu items generated dynamically. You can assign the property to 'userrole' which contains comma separated user roles. Each item will be evaluated with given 'userrole' for that item to that of the logged in user roles, from security. If any of the user roles bound to 'userrole' property matches then that menu item will be shown else will be hidden. | +| Sub Actions (available only when the above Menu Actions is bound to a variable) | When an action is required the sub-items can be mentioned in the children. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Collapsible | Enable control for collapsing and expanding the panel. | +| Enable full screen | Enable control for making the panel full screen. | +| Closable | This property defines if the panel should be allowed to be closed. | +| Expanded | Set the default state of the panel whether it is expanded or collapsed. | +| Auto Close | This property defines the behavior of menu closing, it can be: - outsideClick - close the menu when clicked outside of the menu, - always - when a menu item is selected or on click outside menu, or - disabled - do not close once opened. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. | + +## Events + +| **Event** | **Description** | +| --- | --- | +| On load | This event handler is called when the panel is loaded. | +| **Mouse Events** | +| On mouse over | This event fires when the mouse hovers over this widget. | +| On mouse out | This event fires when the mouse moves away from this widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On swipe up | This event handler is called whenever a swipeup event is triggered. | +| On swipe down | This event handler is called whenever swipe down event is triggered. | +| On swipe left | This event handler is called whenever swipe left event is triggered. | +| On swipe right | This event handler is called whenever a swiperight event is triggered. | +| On pinch in | This event handler is called whenever pinch event is triggered. | +| In pinch out | This event handler is called whenever a pinchout event is triggered. | +| **Keyboard Events** | +| On enter key press | When the user hits ENTER/Return while the focus is in this editor, execute the specified event handler. | +| **Callback Events** | +| On close | This event handler is called whenever a close event is triggered. | +| On expand | This property defines the event handler for the expand event of the accordion panels. | +| On collapse | This property defines the event handler for the collapse event of the accordion panels. | +| On actions click | This event handler is called when the actions icon is clicked. | +| On full screen | This event is called on the full-screen state of the widget. | +| On exit full screen | This event is called on the full-screen state is exited. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/container/tabs.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/tabs.md new file mode 100644 index 000000000..ccf202fc3 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/tabs.md @@ -0,0 +1,192 @@ +--- +title: "Tabs" +id: "tabs" +--- +--- + +**Tabs** can be used when you need multiple containers within a single window. Tab-based navigation provides an easy and powerful mechanism to handle a large amount of content within a limited area by separating content into different panes where one pane is viewable at a time. The user can quickly access the content by switching between the panes without leaving the page. + +In interface design, a Tabbed Document Interface (TDI) or Tab is a graphical control element that allows multiple documents or panels to contain within a single window. You can use these Tabs as a navigational widget for switching between sets of documents. It is an interface style most commonly associated with a web browser, web application and text-editor, and preference panes. + +[![tab run](/learn/assets/tab_run.png)](/learn/assets/tab_run.png) + +## Types of Tabs + +### Static Tabs + +Static Tabs do not need a dataset to add Tab Panes to the Tab bar. You add them using the **Add Tab Pane** button from the properties panel. The Static type is the default behavior of Tabs. + +### Dynamic Tabs + +You can create a fully dynamic tab component using a data source by binding a dataset to the Tabs widget. Based on the dataset, a number of Tab panes will generate. For more information, see [Using Dynamic Tabs and Accordions](/learn/how-tos/dynamic-tabs-accordions). + +## Features + +When you drag and drop a Tab widget, it comes with three default three panes. Each pane can have a separate header and content. + +### Tabs + +- Add Tab Pane. +- Tabs Position to change where the Tab header will be displayed, with respect to the content. +- Default Pane Index - to set a specific Tab to be open by default. +- Set Tab order for the display order. + +### Tab Pane + +- Title - Provide a title to the Tab pan. +- Disabled - Not allowing users to view or perform any operation on the Tab. + +### When to use Tabs + +- To organize content at a high level. +- To alternate between views within the same context. +- To logically chunk the content behind the Tabs. +- When users don't need to see content from multiple Tabs simultaneously. + +[![tab prop1](/learn/assets/tab_prop1.png)](/learn/assets/tab_prop1.png) + +[![tab prop2](/learn/assets/tab_prop2.png)](/learn/assets/tab_prop2.png) + +## Methods + +Tab has few methods exposed on widget scope that can be accessed via JavaScript. See below for usage example + +- To navigate to the previous Tab pane: + +```js +Page.Widgets.tabs1.prev(); //Navigates to previous tab +``` + +- To navigate to the next Tab Pane: + +```js +Page.Widgets.tabs1.next(); //Navigates to next tab +``` + +- To navigate to a specific Tab Pane: + +```js +Page.Widgets.tabs1.goToTab(2); //Navigates to second tab +``` + +- To select a specific Tab Pane: + +```js +Page.Widgets.tabpane1.select(); //selects tabpane1 +``` + +## Script Access + +Learn how you can access Tab events using the JavaScript option. Also, you will learn to navigate to the previous, next, and goToTab functions to switch between the tabbed content. In this case, we are using the sample HRDB with the Employee table as an example to load the data. + +### Prepare data and widgets + +1. Create three variables of type `Employee` entity. For the first variable: + - From the variables tab, select the variable and go to the Data tab. + - For `deptid`, keep the value as 1, and follow the same for others, including `deptid` 4. + - Name the respective variables as `EngineeringEmployeesData`, `SalesEmployeesData`, `MarketingEmployeesData`. + - For more information, see [Learn how to create variables](/learn/app-development/variables/database-crud/#menu). +2. Drag and Drop **Tab** widget. By default, you will see a tab with three Tab Panes. +3. Name the Tab widget as `EmployeesTab` and name the Tab Panes as `engineeringEmpPane`, `salesEmpPane`, `marketingEmpPane`. +4. Change Tab panes titles to `Engineering`, `Sales`, `Marketing`. +5. Drop the **List** widget in each of these Tabs and bind it to the respective variables. Map template widgets to the respective fields. +6. Drop three buttons. Name the first button as `previousBtn`, the second one as `nextBtn`, and the last one as `goToSalesBtn`. Also, change the titles to `Previous`, `Next`, and `Go To Sales`. + +### Scripting with Tabs + +- Select JavaScript for the on click event of `previousBtn` and use the following as javascript function with the following script: + +```js +Page.previousbtnClick = function($event, widget) { +Page.Widgets.EmployeesTab.prev(); //Navigates to previous tab +}; +``` + +- Select JavaScript for the on click event for `nextBtn` and use the following script: + +```js +Page.nextbtnClick = function($event, widget) { +Page.Widgets.EmployeesTab.next(); //Navigates to next tab +}; +``` + +- Select JavaScript for the on click event for `goToSalesBtn` and use the following script: + +```js +Page.gototabbtnClick = function($event, widget) { +Page.Widgets.EmployeesTab.goToTab(2); //Navigates to sales tab +}; +``` + +### Run + +1. Run the application. The first tab pane will open by default. +2. When you click `nextBtn`, the `salesPane` will open. +3. When you click `previousBtn`, the `engineeringPane` will open. +4. When you click `goToSalesBtn`, the `salesPane` will open. + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier of the Tab. | +| Type | This property specifies the type of Tabs widget. - ***Static***: The Tab Panes will be static, which is the default behavior of Tabs. - ***Dynamic***: The Tab Panes will be generated based on the Dataset bound to the widget. | +| Add Tab Pane | This action allows one to add multiple panes to the Tab. **NOTE**: This property applies when you set the **Type** propety to `Static`.| +| **Layout** | +| Height | The height of the Tab can be specified in px or % (i.e 50px, 75%). | +| Tab Position | This property determines if the Tabs should be displayed on the - _left_, - _top (default)_, - _right_ or - _bottom_ of the Tab content. | +| **Behavior** | +| Default Pane Index | This property sets the default active pane on a load of the widget based on the provided index. The Tab Index is an integer starting from 0, 1, 2, and so on. That is, setting this property to 0 will display the first Tab pane; setting to 1 will display the second Tab pane. | +| Retain State | This property will allow users to maintain widget states using state handling on the URL, Local Storage or Session Storage. This property, that is enabled by default enables applications that are using Tabs to deep link specific tabs using URL rewriting approach. If state information being visible in URL is not desired, other approaches to linking to specific tab includes localStorage & sessionStorage. - _URL_ : The state information will be stored in the app URL(This is the default option selected by the platform). - _Local Storage_ : The widget state information will be stored in the browser local storage. - _Session Storage_ : The state information will be stored in the browser session storage. - _None_ : No state information will be applied to the widget.| +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When the show property is not bound, the widget will be initialized immediately. | +| Transition | This property defines the transition effect to be applied when switching Tabs. You can choose from _none_ or _slide_. When the transition property is `slide`, the selected Tab will be animated into the viewport. `Swipe events` will work only when the transition value is `slide`. | +| **Format** | +| Horizontal Align | Set text alignment horizontally, can be left, center or right. | +| Tab Order | The order of the Tabs can be changed using the arrow icons next to the Tab names. | + +### Tab Pane + +SubWidget of Tabs, to hold the Tab content. + +| **Property** | **Description** | +| --- | --- | +| Title | This property defines the heading or title for the Tab panes. | +| Name | The name is a unique identifier of the Tab pane. | +| Badge Value | Value to be displayed in the badge span for the Tab pane | +| Badge Type | The property controls the color of the badge. These values are: - default, - primary, - success, - info, - warning, or - danger | +| **Accessibility** | +| Tab Index | The Tab Index attribute specifies the Tab order of an element. You can use this property to change the default tabbing order for widget access using the Tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Content** | +| Content | Inline content or Partial page's content to be included in the widget. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is bindable. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. It is bindable. | +| **Graphics** | +| Title Icon Class | This property can assign an icon for the pane. | + +## Events + +| **Event** | **Description** | +| --- | --- | +| On load | This event handler is called when the widget is loaded. | +| **Callback Events** | +| On select | This event handler is called when the Tab is selected. | +| On deselect | This event handler is called when the Tab is deselected. | + +## Apply Retain State + +When application uses Tabs, it is possible to deep link to specific tab in the tab list as user selects them. Deep linking is a way to retain the state such that even when the user refreshes the page or shares the URL with someone else, they land on the page at a particular tab. + +**Retain State** will store the state information either in the browser URL or in local or session storages of the browser. Query param called **wm_state** is appended to the URL which contains the state information. + +**Example:** + +```code +https://www.wavemakeronline.com/run-x2zq8pwbhy/ent1d52def3436/ExcelDemo_master/#/Main?wm_state=('ws'~('tabs1'~'tabpane2')) +``` + +## See Also + +[How to Use Dynamic Tabs and Accordions](/learn/how-tos/dynamic-tabs-accordions) +[How to Build Tabbed Live Form](/learn/how-tos/live-form-tabbed-form/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/container/tile.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/tile.md new file mode 100644 index 000000000..a16dd507a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/tile.md @@ -0,0 +1,56 @@ +--- +title: "Tile" +id: "tile" +--- + +**Tile** is a container for other widgets used to present a set of objects. Tile widget lets you to directly add an image, text box, video, or web code to user dashboard. Functions _similar to the container_ but it comes with some default styling which makes it different from a container. Users cannot create partials using tile. + +Tiles can be used while creating Dashboard like UI where you need to show analytics data. + +When to use Tile: + +- Unlike other containers, its size is limited, and it is not recommended to place too many widgets and/or complex widgets. + +![](/learn/assets/tile_design-1.png) + +## Properties + +You can also use the Conditional Class property from the Style tab to set the class based upon a condition. See here for [How to](/learn/how-tos/use-conditional-class-property/). + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for tile. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| **Format** | +| Horizontal Align | Set text alignment horizontally. | + +## Events + +| **Event** | **Description** | +| --- | --- | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On double click | This event handler is called whenever the double click event is triggered on a widget. | +| On mouse over | This event fires when the mouse hovers over this widget. | +| On mouse out | This event fires when the mouse moves away from this widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On Tap | This event handler is called whenever the tap event is triggered on a widget. | +| On Double Tap | This event handler is called whenever the double tap event is triggered on a widget. | +| On Long Tap | This event handler is called whenever the long tap event is triggered on a widget.
Note: Long Tap event is only supported in React Native applications.| +| On swipe up | This event handler is called whenever a swipeup event is triggered. | +| On swipe down | This event handler is called whenever a swipe down event is triggered. | +| On swipe left | This event handler is called whenever a swipeleft event is triggered. | +| On swipe right | This event handler is called whenever a swiperight event is triggered. | +| On pinch in | This event handler is called whenever pinch event is triggered. | +| On pinch out | This event handler is called whenever pinch out event is triggered. | +| **Keyboard Events** | +| On enter key press | When the user hits ENTER/Return while the focus is in this editor, execute the specified event handler. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/container/wizard.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/wizard.md new file mode 100644 index 000000000..5f825b680 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/container/wizard.md @@ -0,0 +1,177 @@ +--- +title: "Wizard" +id: "wizard" +--- + +**Wizards UI** are suitable for tasks that have **multiple independent steps,** wherein the user is taken through each step to comprehend the task in a structured manner. Wizards have steps with a specific UI style that facilitates easy navigation. Wizards provide **previous and next step buttons** for the user to confirm their selections/actions in each of these steps. Users can also **cancel** the task at any step. Wizards also provide Done or Finish button at the end of the final step, to indicate that all the steps are finished. + +There can be many **use case scenarios** where a wizard can be used. Examples of some common use cases are as follows: + +1. On-line Payments +2. Product Orders +3. Review of Documents +4. Software Installations +5. Register Accounts in Websites +6. Project/App Configurations + +[![](/learn/assets/WZ_concept.png)](/learn/assets/WZ_concept.png) + +## Features + +**Wizard widget** facilitates the user through the procedural interface to perform tasks in a specific pre-defined order. + +1. WaveMaker Wizard widget has **one step by default** and user can add multiple steps using the Wizard **Add Step** property. +2. **Next Step button** is added to all steps except the last step where a **Done button** is used to complete the wizard process. +3. **Previous Step button** is added to all steps except the first step. +4. Custom Caption for Action Buttons: + +[![](/learn/assets/WZ_props.png)](/learn/assets/WZ_props.png) + +- **Next and Previous**: To navigate through the steps of the wizard we have Next and Previous buttons in the wizard widget. The caption for these buttons can be changed using the Next caption and Previous caption properties available in the Wizard basic properties. The captions are also bindable. +- **Done and Cancel Buttons**: The Wizard also has a Done and Cancel Button which perform actions for Completion of the task or for Canceling of the task respectively. These button captions can be changed using the Cancel action caption and Done action caption properties respectively. Each of the above captions is also bindable. +- **Previous and Done Buttons**: These buttons can be disabled from the Script using the _disabledone_ and _disableprevious_ properties. For example, using productStep.disabledone = !paymentOption.datavalue;, will enable the Done button only when a payment option is checked. +- **Layout** + - **Step Style:** can be set as auto or justified + - **Default Step**: bindable property acting as the starting point for the wizard. For instance, if default step is set to step 3, then at runtime the third step is the active step on a load of the wizard with the previous two steps marked as complete. + + [![](/learn/assets/WZ_defaultstep.png)](/learn/assets/WZ_defaultstep.png) + +- **Behavior**: **Show** property of the wizard can be used to show/hide the wizard based on a variable’s value. Show feature is bindable and can be bound to a boolean field in a dataset. +- **headernavigation**: `headernavigation` property can be added in the Markup script and set as **False** to disable the navigation through Wizard stepper header numbers. +- **Events** in Wizards: + +[![](/learn/assets/WZ_events.png)](/learn/assets/WZ_events.png) + +The callback events for Wizard will fire on the trigger of the specific event: +- **OnDone:** This is a callback which fires when the Done button is pressed at the end. For Example, when Done button is clicked by the user, the order status can be set to Order Shipped and Tracking Details page can show up. +- **OnCancel:** This is a callback which fires when the Cancel button is pressed at the end of the steps. + +### Wizard Step Features + +The **Step UI** is designed with a unique style to differentiate from a tab and to start with the first step will be enabled and the remaining steps are disabled. Each of these steps has the following features that can be manipulated. + +1. **Title**: This is the title that appears on the step, which is changed by the user in the wizard step properties. + +[![](/learn/assets/WZ_steptitle.png)](/learn/assets/WZ_steptitle.png) + +2. **Content**: The content can only be an inline content which means that you have to design each step of the wizard like you design every page in WaveMaker. You cannot use partial content in any step of the wizard. +3. **Behavior**: consists of the following properties that can be configured: + +- **Show:** The Wizard step can be shown or hidden by checking it on/off. The step can also be shown or hidden by binding the show property to a boolean field. +- **Enable Skip**: This feature will allow you to skip a step and jump to next step. This can be turned on or off in the wizard step properties. It appears only as a link when turned on and at run-time when clicked it moves to the next step without doing anything in the current step.  The user can plugin JavaScript handlers to apply some logic when the skip link is clicked. +- Other Step Features include: + - **Disable Next**: This feature is not exposed as a property in the wizard and it is only available through scripting. The user can avail this feature by writing a JavaScript to disable the next step that can get invoked on Load event of the step to be disabled. Disable Next will be useful if the user has provided some information in the current step wherein next step information may become irrelevant to the user. For example: In an Employee Application form Wizard, there may be some step which would expect the user to provide information regarding previous employment. If the user has entered No for a question on Previous Employment in the current step and if the next step is for giving details on Previous Employment, Disable Next is a viable option. + - **Enable Done button**: This feature is also not exposed as a property in the wizard widget and it is only available through scripting. This can be done by on Load event of that step. The user can write a javascript function to enable Done button in a step if responses and actions for the step by the user are good enough to complete the task at that step itself. In the case of Configuration Management, a Config Wizard can take you through many steps wherein some initial steps will be mandatory and later steps may be for an advanced user. In that case, the Done button can be enabled in the step where all basic information has been provided by the user so that user can complete the task. +- **Wizard Step Events**: There are callback events for every wizard step that will fire on the happening of such events. Based on user entries and confirmations in the current step, the next step contents can be populated. Wizard scope and step scope will be passed as an argument to the respective callback event. Hence, your javascript function will have access to the Wizard scope and step scope. + - **On Load**: This is a callback which fires when onLoad of the particular step happens and only the wizard scope will be passed on to the callback event. If a user is writing a JavaScript function to handle this event, the user will be able to access the wizard scope and using that can access any widgets in that scope. OnLoad on a step can be used to populate some values in a widget based on other widgets. For example, one can populate the orders pending for a department based on the Dept id or Name. + - **On Next**: This is a callback which fires when the next step button is clicked by the user in a step. When the event fires the wizard scope and step scope will be passed as arguments to On Next callback. If you plan to invoke a JavaScript function when the event occurs, you will be able to have access to these scopes and access the widgets with respect to wizard scope and access the properties with respect to the steps. This can be used to do some updates to a field based on the user’s response in the step and the next step can show the result of the updates made. For example, once the user confirms the order, the order status field in the orders table can be set to Confirmed and it can take the user to payment step. + - **On Prev**: This is a callback which fires when the Previous button is clicked by the user in a step. When the event fires the wizard scope and step scope will be passed as arguments to On Prev callback. If you are implementing a JavaScript function to invoke when the event occurs, you will be able to have access to these scopes within your function. The user can make some edits or deletes to some content in the previous steps. For example, once the user has added items to the cart in one step and has moved to next step and later decides to remove that from the cart, the user can use the previous step to make such edits. + - **On Skip**: You will be able to skip steps by enabling skip on these steps by setting the Enable Skip property on the step to on. Once Enable Skip is on, the user will be able to see a Skip link at the left bottom of the wizard in the step for which Enable Skip is on. This callback fires when the skip link is clicked by the user in that step. If the user wants to set some defaults for the required fields in the step before he jumps to the next step, he can handle this callback. On Skip event will not take the scopes as arguments. The user can use this in case you want to assign some flags or some required values to some of the fields in the respective step UI. The user can also skip in case he does not have the necessary details to complete that step. While Registering an Account in any e-commerce site, after giving the profile information, the wizard may have one of the steps which asks for payment related details like credit card number etc. We normally skip that step as it is not necessary to provide that information while registering. + +### Widgets in Wizard + +- Each step in the wizard can have any kind of widgets depending on the usage scenario – for example -Live form widget, Data Table Widget, a list widget, Grid Layout with Label and Text Widgets. +- The Widgets are to be dragged and dropped into Wizard Step Area. Once a step is selected, the wizard step is highlighted and the appropriate widget can be dropped on that area. +- For user entries in a step, the recommended widget is a Live Form where the wizard’s next button of that step will be disabled until all required fields in a form are entered by the user. The validations which are by default available in a form will be available within the wizard step also. +- You can also have a Dialog and drag and drop a wizard into the Dialog which will give a Dialog with steps which can be hidden once the steps are completed by clicking the Done button on the wizard. +- You can drag and drop any Live and Data widgets as well as basic widgets onto a wizard step. + +## Usage Scenarios + +A basic usage scenario is used to go through the wizard interface step by step trying to build a Registration Form. A **Generic Registration Form** that can be used by any websites to get their users registered to their sites, for example, accessing trial versions of products, or for buying goods online etc. In this scenario, the user is asked to register when they need to access some resources that need registration. To register, the user is provided a Registration form for creating username and password for that user. Once the user has given the inputs, the user navigates to a page where the user has to **add personal information** and if the user is employed the **professional data** also has to be supplied by the user. Once the required data is provided by the user the user is registered and is informed of the success of registration. The scenario assumes that you will be creating the required data model for taking the login data (Person Entity), profile (Profile Entity) and professional (Profession Entity) data inputs from the user. + +[![WZ_usage_dm](/learn/assets/WZ_usage_dm.png)](/learn/assets/WZ_usage_dm.png) + +## Step 1: Setup + +This is the set-up of an existing page - Getting Basic Details from the User for Registration with a button to invoke the Wizard to add Profile and Professional data. + +- **Create a page** named _UserRegistration_ to take the basic user data for Person entity. +- **UI Design** for the Page: use _Data Table_ to display/add/edit person details +- Add **button** to invoke wizard to add profile and profession data - **Click event** should navigate to the wizard page (WizardBasic) which will be designed in the next step +- Run the App and give the inputs as needed. + +[![wz_userregistrationpage](/learn/assets/WZ_UserRegistrationPage.png)](/learn/assets/WZ_UserRegistrationPage.png) + +## Step 2: Basic Properties + +1. **Create a Page** named **WizardBasic** in WaveMaker App +2. Drag and Drop a wizard on the canvas. Once the Wizard is dropped onto the canvas, you will see the UI as shown below. By default only one step with the Title as Step Title is created. Note there are two action buttons – Cancel and Done respectively + +[![](/learn/assets/WZ_usage_design.png)](/learn/assets/WZ_usage_design.png) + +3. Edit the **Title** of the Step: Click on the step and in the properties panel change the Title to _Personal Data_. + +[![](/learn/assets/wz_usage_titleprops.png)](/learn/assets/wz_usage_titleprops.png) + +4. **Adding More Steps to the Wizard**: Add one more step – click on the wizard canvas and click on **Add Step**. Change Step **Title** to _Professional Data_ by using the Title property of the step. + +[![](/learn/assets/wz_usage_addsteps.png)](/learn/assets/wz_usage_addsteps.png) + +## Step3: Design UI + +**Design the UI for Personal Data Step:** Live Form bound to the Personal entity, using 3-column layout. + +[![WZ_usage_step1design](/learn/assets/WZ_usage_step1design.png)](/learn/assets/WZ_usage_step1design.png) + +**Design UI for Professional Data Step**: Live Form bound to the Professional entity, using 1-column layout. + +[![WZ_usage_step2design](/learn/assets/WZ_usage_step2design.png)](/learn/assets/WZ_usage_step2design.png) + +## Step 4: Event Configuration + +- Writing **Event** on the Wizard Step1 (Personal Data) + - **On Next**: Use Case – When the User is not Employed – On Blur Event of employed field In Personal Data Step when the user tabs out after entering a value in employed form field of Live Form On Blur event is fired. In the above use case, if the user does not wish to proceed to input Professional data as the user is not employed; then the appropriate handler has to be plugged into the On Blur of the employed field. This example has an On Blur JavaScript handler that does the following: + ``` + Page.employedBlur = function($event, widget) { + + var employed = Page.Widgets.employed.datavalue; + if (employed == "No") + Page.Widgets.wizardstep2.enabledone = true; + else + Page.Widgets.wizardstep2.enabledone = false; + }; + } + ]); + ``` + - Gets the data value of the employed widget and assigns it to the employed variable. + - If the employed data value is “No” it enables the Done button in this step itself as the user can complete the registration in step 1 itself without going to step 2. +- Writing Event on the Wizard Step 2 (Professional Data) – On Done: + - On Done: Use Case –When the User is Employed. In this case, the user is allowed to move to the next step to enter professional data. Once entered and Done button is clicked, On Done event fires. A JavaScript handler is added to On Done Event which does the following: + ``` + Page.wizard1Done = function(widget, steps) { + var liveData = Page.Widgets.liveform2.dataset.data; + var ctrOfData = liveData.length; + var profileData = Page.Widgets.liveform2.dataset.data[ctrOfData - + 1]; + var userName = profileData.personByPerson.userName; + Page.Variables.UpdateRegistered.setInput('uid', userName); + Page.Variables.UpdateRegistered.update(); + DialogService.open('alertdialog1', Page, { + 'mode': 'edit', + 'showInUserMode': true + }); + }; + ``` + - Gets the UserName from the Live Form Dataset + - Sets the UserName Input for the Update Query on the Person Service Variable to set the Registered field to true. + - Updates the service variable. + - Shows the Alert Dialog with Successful Message – Registration Successful – To create Alert Dialog and show up in a page – Refer Dialog Documentation + - Navigates to Registration Details Page + +## Test Run + +- Run the app and click on Update Personal Data on User Registration page + +[![WZ_usage2_run1](/learn/assets/WZ_usage2_run1.png)](/learn/assets/WZ_usage2_run1.png) + +- Enter the Personal Details and click on NEXT to enter Professional Data + +[![wz_usage2_run2](/learn/assets/WZ_usage2_run2.png)](/learn/assets/WZ_usage2_run2.png) + +- Run the app again and Enter the Personal Details with Employed set to NO, observe the DONE button with no navigation to Professional Data step + +[![WZ_usage_run1](/learn/assets/WZ_usage_run1.png)](/learn/assets/WZ_usage_run1.png) + + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards.md new file mode 100644 index 000000000..ca4cf01d1 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards.md @@ -0,0 +1,31 @@ +--- +title: "Cards Widget" +id: "cards" +sidebar_label: "Overview" +--- +--- +**Cards** represents view of items that are rendered responsively across a wide range of mobile devices and screen sizes. Cards are the popular UI elements used in the implementation of Google Now; item details on online shopping websites and many more modern mobile and web apps. + +Cards data can be obtained from various data sources like database, queries or web services through variables. Cards templates have a picture and content widgets which can be bound to the fields from the data source. Few of these templates have provision to trigger events via default action buttons. + + +## Card Features +While designing the Cards following features can be set: + +- group data by the field of the underlying data source, +- order the data by the fields of the underlying data source, +- enable multiple selections of items and +- set the pagination style for multi-page data. + +[![](/learn/assets/cards_overview.png)](/learn/assets/cards_overview.png) + +## See More + +[Card Data Source](/learn/app-development/widgets/datalive/cards/cards-data-source/) +[Card Templates](/learn/app-development/widgets/datalive/cards/cards-templates/) +[Card Configuration](/learn/app-development/widgets/datalive/cards/card-configuration/) +[Card Behavior Settings](/learn/app-development/widgets/datalive/cards/card-behavior-settings/) +[Card Properties](/learn/app-development/widgets/datalive/cards/cards-properties-events-methods/#properties) +[Card Events](/learn/app-development/widgets/datalive/cards/cards-properties-events-methods/#events) +[Card Methods](/learn/app-development/widgets/datalive/cards/cards-properties-events-methods/#methods) +[Use Cases](/learn/app-development/widgets/datalive/cards/card-use-cases/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/card-basic-usage.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/card-basic-usage.md new file mode 100644 index 000000000..5b3891199 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/card-basic-usage.md @@ -0,0 +1,150 @@ +--- +title: "Creating Cards" +id: "card-basic-usage" +sidebar_label: "Creating a Card" +--- +--- +### Creating Employee Cards + +**Cards** represents view of items that are rendered responsively across a wide range of mobile devices and screen sizes. + +[![](/learn/assets/cards_basic_run.png)](/learn/assets/cards_basic_run.png) + +To bind the Cards to your back-end services data, drag and drop the Cards Widget onto the canvas. [![](/learn/assets/cards_sel.png)](/learn/assets/cards_sel.png) + +## STEP-1: Select Data + +There can be different scenarios to deal with when configuring your Cards Widget with a data source. The data source can be in the form of a service - database, web or Java; or from an another widget on the page. + +## Example 1: When No Service or a Variable is Created +You do not have any service available in your project. In this scenario, you cannot create variable because there are no services available in your project yet. + +### `Retrieve Data From` +1. Select the **Services** option. +2. You will be prompted to **[Import Database](/learn/app-development/services/database-services/working-with-databases)** or **[Import Web Services](/learn/app-development/services/web-services/web-services)** or **[Create Java Service](/learn/app-development/services/java-services/java-service/)**. Click the appropriate option to proceed. +2. When the service is available in your application, proceed by selecting the service and follow the same steps as mentioned in [example-2](#example-2-with-an-existing-service). + +[![](/learn/assets/cards_basic_data1.png)](/learn/assets/cards_basic_data1.png) + +## Example 2: With an Existing Service +When you have a service integrated in your app, for example, [Database](/learn/app-development/services/database-services/working-with-databases/), [Web Service](/learn/app-development/services/web-services/web-services), or [Java Service](/learn/app-development/services/java-services/java-service/). + +### `Retrieve Data From` +The Services option is selected by default. + +### `Select Service Type` +Select **Database CRUD** from the dropdown. Retrieving the data From Database CRUD service. +### `Select a Service` +Select a service from the drop-down which lists the services available in your application. + +[![](/learn/assets/cards_basic_data2_1.png)](/learn/assets/cards_basic_data2_1.png) + +### `Variable Name` + +Once you select the service and Table/Entity for the service, a default variable will be created for you – see the Variable Name field populated by default which will be holding the dataset of the service. You can change the Variable name. +### `Select data node` + +You are given the option of choosing either the entire dataset – when you are binding the widget to a data source or any of the fields in the dataset. Select data node tree when binding a single widget or a List item to a field in the dataset. + +### Data Configuration Options +You also have the option of setting the following **Data Configuration** options. + +[![](/learn/assets/cards_basic_data2_2.png)](/learn/assets/cards_basic_data2_2.png) + +### `Records per request` +Records per request gives an option to enter the number of records that you can fetch on each request. This will define the pagination behavior of the List. The default is 20, for this example, we set it to 3. +### `Update data on input change` +Update Data on input change is checked by default. This means that whenever there is a change in the input parameter or filter field of the variable the data will be fetched from the service. This option will have an impact on the app performance. +### `Request data on page load` +Request data on Page Load is checked by default. This allows for data to be shown when the page is loaded. If this is not checked, you will not be able to view the data when the page gets loaded. Instead, No Data Found message appears on the widget at runtime. + +## Example 3: With an Existing Variable + +If the variables are already created in the project, [Variable Access](/learn/assets/var_sel.png). + +### `Retrieve Data From` +Select **Existing Variable** +### `Select a Variable` +From the drop-down list of the variables available in the application. You can select the one needed to bind the List Widget to. You can also search for a specific variable by typing in select variable option. If you are able to find your variable in the drop-down select the same. + +[![](/learn/assets/cards_basic_data3_1.png)](/learn/assets/cards_basic_data3_1.png) + +:::important +- When you select the variables, it shows the dataset that it is bound to. +- Data Configuration options are already set for this variable, so you do not see those options in this scenario. +::: + +[![](/learn/assets/cards_basic_data3_2.png)](/learn/assets/cards_basic_data3_2.png) + +#### Modify data request configuration + +Configure `Records per request`, `Update data on input change`, `Request data on page load` from the variable dialog. + +- Select the **Card** item from the page. +- Navigate to **Card Properties** and go to `Dataset: Value`. +- Click the `Value:link` to open the Variable dialog. +- Update the **Properties** tab and save & close. + +:::tip +For modifying widget data settings, you must modify the data-variable and not the actual widget settings. +::: + +## Example 4: Binding to Widget + +### `Retrieve Data From` +Select the Retrieve Data From option as Widgets. +`Select a widget` +Select a widget from the drop-down list. This will list the widgets present on this page, you cannot access the widgets from other pages. + +[![](/learn/assets/cards_basic_data4_1.png)](/learn/assets/cards_basic_data4_1.png) + +### `select data node` +You can select data node to be the entire widget or the selected item node in case of another Data Table or List or Cards or result from a Live Filter. + +:::important +Since you are not using a Variable the Data Configuration options will not be available. +::: + +[![](/learn/assets/cards_basic_data4_2.png)](/learn/assets/cards_basic_data4_2.png) + +## STEP-2: Select Template + +### `Select A: template` +In this step, you are expected to select a template suitable for the current use case. + +[![](/learn/assets/Card_template.png)](/learn/assets/Card_template.png) + +### `Select B: pagination` +Choose one of the pagination options provided. + +[![](/learn/assets/Card_pag.png)](/learn/assets/Card_pag.png) + +## STEP-3: Binding Data Fields + +The template selected in the [step-2](#select-a-template) provides a set of widgets that should be bound to the corresponding field from the data source configured in the [step-1](#step-1-select-data). Select the widget and bind to the corresponding properties by selecting the field from the drop-down list. + +|Widget Fields| Caption| +|--|--| +| `Field` -> `department` | `Caption` -> `department` | + + +[![](/learn/assets/cards_basic_fields.png)](/learn/assets/cards_basic_fields.png) + +## Design + +You can add widgets from the canvas, change the properties at the card and at widget level. + +[![](/learn/assets/cards_basic_design.png)](/learn/assets/cards_basic_design.png) + +## Run + +Click on Preview button to test run the app. + +[![](/learn/assets/cards_basic_run.png)](/learn/assets/cards_basic_run.png) + + +## See Also + +[Cards Use Cases](/learn/app-development/widgets/datalive/cards/card-use-cases/) +[Cards Basic Usage](/learn/app-development/widgets/datalive/cards/card-basic-usage/) +[How to access cards items](/learn/how-tos/capturing-card-items/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/card-behavior-settings.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/card-behavior-settings.md new file mode 100644 index 000000000..dd5bf8a10 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/card-behavior-settings.md @@ -0,0 +1,13 @@ +--- +title: "Cards - Behavior Settings" +id: "card-behavior-settings" +sidebar_label: "Behavior Settings" +--- +--- + +1. **Selection Limit**: This property sets the maximum items that can be chosen at run-time. It also determines whether the list can have single or multiple items selected. This property can be bound to a variable to determine the selection limit at run-time. +2. **Multiselect:** Multiselect will enable users to select multiple list items at runtime. These items can be captured via the _selecteditem_ which will be an array of objects. See Usage Scenarios for more details. +3. Item Reordering: **Enable reorder **will allow users to reorder the list items at run-time. + +[![](/learn/assets/cards_behav1.png)](/learn/assets/cards_behav1.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/card-configuration.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/card-configuration.md new file mode 100644 index 000000000..253208b57 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/card-configuration.md @@ -0,0 +1,38 @@ +--- +title: "Cards - Configuration" +id: "card-configuration" +sidebar_label: "Configuration" +--- +--- +#### Items per Row + +**Items per row** determine the number to items that can be shown in each row. This can be specified independently for different target devices, from the _device_ tab of the _Properties panel_. + +#### Grouping & Ordering + +Data displayed using Cards can be grouped and ordered. + +1. **Group by**: Choosing a field from the data source as Group By field, will display together with the card items which have the same value for that field. +2. **Group as**: This property defines the group-by behavior. The following options are available: + - _alphabet_ – grouped based on the first alphabet of the field + - _word_ – grouped based on the first word of the field + - _TIME_ – grouped based on TIME: hour, day, week, month, year +3. **Order by**: This property will help to order the card items based upon a field from the data source. You can also set the order as ascending or descending – by clicking on the arrows provided on the side of the field name. + +#### Pagination + +Pagination is dividing the set of data rows into discrete pages that will allow users to view data in the form of rows across pages. This should allow for easy navigation across pages for viewing and editing of data. + +1. **Pagination Type**: To make complete use of pagination, the Cards provides five unique types of pagination. + - _Basic_ – This option gives a next and previous arrow along with the page numbers at the right bottom of the page. + - _Classic_ - A bar with the total number of pages and number of items in the current page will be displayed along with arrows for pagination. + - _Horizontal Slider_ – This option gives next and previous arrows on both the sides of the page for pagination, carousel style. + - _Pager_ – This option gives the next and previous buttons at the bottom of the page which when clicked goes forward or backward one row. + - _Infinite Scroll_ – In this option on the scroll over the cards will cause the next page to load and display. + - _None_ - No pagination option will be given, use this when you want to display single-page records. + - _On Demand_ - allows users to load list items when needed. A '_Load More_' button is displayed at run-time, which on click will load next page records. The label 'Load More' can be configured using 'On Demand Message' property. + +#### Message + +**Messages** to be displayed at the time of data loading and in case no data is found can be configured. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/card-use-cases.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/card-use-cases.md new file mode 100644 index 000000000..42363ceff --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/card-use-cases.md @@ -0,0 +1,12 @@ +--- +title: "Cards - Use Cases" +id: "card-use-cases" +sidebar_label: "Use Cases" +--- +--- + +You can use Card Widget in many different ways.  The following links talk about the different use cases: + +- [Creating Employee Cards](/learn/app-development/widgets/datalive/cards/card-basic-usage/) +- [How to capture card items](/learn/how-tos/capturing-card-items/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/cards-data-source.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/cards-data-source.md new file mode 100644 index 000000000..c0eb7cb11 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/cards-data-source.md @@ -0,0 +1,30 @@ +--- +title: "Cards Data Source" +id: "cards-data-source" +sidebar_label: "Data Source" +--- +--- +The first step in configuring a card is to define the data that needs to be displayed. This data can be in the form of a Variable or another Widget. + +## Variable Source + +Setting the data source to a variable will facilitate following scenarios: + +- List data from Services like a Database, Web Service, Java Service; +- List values stored in a Custom (Model) Variable. + +When you select a service, a variable will be created automatically by the platform. You can use existing or predefined variables, too. The behavior of data displayed will be defined by the Variable/Data Configuration properties. These properties are at the Variable level and can be configured them only when creating a new variable. You can modify the properties from the [variable dialog](/learn/assets/var_sel.png). + +Of particular interest are: + +- **Records per request** - this is the number of records that will be displayed on a page. Configure the Pagination property to enable user navigation to various pages of data; +- **Update data on input change** - this property defines when the data displayed will be refreshed. When enabled the data is reloaded whenever the input to the Variable (in the form of filter fields for Live and parameter values for Service Variable) changes; +- **Request data on page load** - enabling this property will ensure that the data within the data table is loaded at the time of page load. + +## Widget Source + +Widgets can be a source of data in some cases. For example, you might want to display the results from a Live Filter or more details of a selected row/item from a Data Table or another List. Widget option will allow you to achieve this. Selecting Widget as the data source will display the various options available. + +[![](/learn/assets/cards-data.png)](/learn/assets/cards-data.png) + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/cards-properties-events-methods.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/cards-properties-events-methods.md new file mode 100644 index 000000000..e4013976a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/cards-properties-events-methods.md @@ -0,0 +1,134 @@ +--- +title: "Cards - Properties, Events & Methods" +id: "cards-properties-events-methods" +sidebar_label: "Properties, Events & Methods" +--- +--- +## Properties + +:::important +Card Widget is contained within a List and as such, you can set the [List Properties](/learn/app-development/widgets/datalive/list/list-properties-events-methods/#properties) too. +::: + +| **Event** | **Description** | +| --- | --- | +| Title | Set the title for the List. It is bindable. | +| Sub Heading | This bindable property defines the subheading or title for the list. | +| Name | The name is a unique identifier for the list. | +| **Picture** | +| Height | This property allows you to set the height of the picture, by default set to 200px | +| Source | This property specifies the source for the picture, it is bindable. | +| Title | This bindable property specifies the title on the picture | +| **Layout** | +| Width | The width of list can be specified in em, pt, px or % (i.e 50px, 75%). | +| Height | The height of list can be specified in em, pt, px or % (i.e 50px, 75%). | +| **Actions** | +| Menu Actions | This property sets the actions for the widget. To set the data and events see [menu widget](/learn/app-development/widgets/navigation/dropdown-menu/) | +| Action Label | Label for menu items. It can be bound to a variable or set to a field from the Dataset Value variable. | +| Action Icon | Label for menu items. It can be bound to a variable or set to a field from the Dataset Value variable. | +| Action Link | Link for the items. It can be bound to a variable or set to a field from the Dataset Value variable. **Note:** item link has priority over _onSelect_ actions i.e. when the link is selected the onSelect actions won't get executed. | +| Action Task | Task for menu items generated dynamically. This is the action that will be triggered when the user clicks on the Menu Item. | +| User Role | Role for menu items generated dynamically. You can assign a property to 'userrole' which contains comma separated user roles. Each item will be evaluated with given 'userrole' for that item to that of the logged in user roles, from security. If any of the user roles bound to 'userrole' property matches then that menu item will be shown else will be hidden. | +| Sub Actions | When a menu widget is required the sub-items can be mentioned in the children. It can be bound to a variable or set to a field from the Dataset Value variable. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| **Graphics** | +| Title Icon class | This bindable property defines the class of the icon that is applied to the button. | +| Icon Url | You can give Url of the image. | + +## Events + +| **Event** | **Description** | +| --- | --- | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on the list. | +| On double click | This event handler is called whenever the double click event is triggered on the list. | +| On mouse enter | This event handler is called whenever the mouse enters the list. | +| On mouse leave | This event handler is called whenever the mouse leaves the list. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on the list. | +| On double tap | This event handler is called whenever the double tap event is triggered on the list. | +| **Keyboard Events** | +| Enter Key Press | When the user hits ENTER/Return while the focus is on the list, execute the specified event handler. | +| **Callback Events** | +| On before data render | This event handler is called when the data is set using the pagination. | +| On pagination change | This event handler is called when the page is changed through navigation controls. | +| On reorder | This event is triggered when the item in a list is reordered. For this, the Enable Reorder property has to be set. | +| On selection limit exceed | This event is triggered when selected items cross the value set for the Selection Limit property. | + +## Methods + +The card has few methods exposed on widget scope which can be accessed via JavaScript. For the following script samples, we are considering the hrdb Employee table. EmployeeList is bound to the Live Variable corresponding to the Employee table. + +### `Clear list data` + +``` +Page.Widgets.EmployeeList.clear(); +//Clear the list items. +``` + +### `Select a list item` + +``` +Page.Widgets.EmployeeList.selectItem(0); +//Selects first item , the parameter can be index or object. +``` + +### `Deselect item` + +``` +Page.Widgets.EmployeeList.deselectItem(0); +//Deselects first item, the parameter can be index or object. +``` + +### `Change navigation` + +``` +Page.Widgets.EmployeeList.navigation = ‘Basic’; +//Changes navigation type to Basic. +``` + +### `Interact with widgets of selected item` + +``` +Page.Widgets.EmployeeList.selectedItemWidgets[0].Name.caption = ‘Eric’; +//Changes caption for Name widget of selected item to ‘Eric’. +``` + +### `Modify selected item` + +``` +Page.Widgets.EmployeeList.selecteditem = 0; +//selects first item in the list. +``` +### `Change the value of currentItem` + +:::note +`currentItem` and `currentItemWidgets` can’t be accessed through the script. But those were given as parameters for events of widgets inside list widget template. `currentItem` is given as item in the arguments. +::: + +``` +item.username = ‘Eric’; //Sets username field value to ‘Eric’; +``` + +### `Change the caption of username widget for currentItem` + +:::note +`currentItem` and `currentItemWidgets` can’t be accessed through the script. But those were given as parameters for events of widgets inside list widget template. `currentItem` is given as item in the arguments. +::: + +``` +currentItemWidgets.Name.caption = ‘Eric’; +//Sets caption of Name widget to Eric. +``` + +### `Preserve the reordered list` +Enable reorder allows the user to change the order of the items in the List in runtime, but the order after reordering do not persist after refresh. `onReorder` callback event is triggered when the order of the items in the List is changed. In the script, `$data` parameter has the complete order after each reorder. This data can be used to make the reorder permanent. + +``` +Page.livelist1Reorder = function ($event, $data, $changedItem) { + //$data is the newly reordered array of items. +}; +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/cards-templates.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/cards-templates.md new file mode 100644 index 000000000..511f45cee --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/cards/cards-templates.md @@ -0,0 +1,68 @@ +--- +title: "Cards - Templates" +id: "cards-templates" +sidebar_label: "Templates" +--- +--- +Cards elements can be displayed using various templates: + +## Profile Cards + +### Business Card + +Business Card can be used to give the employee profile with name, designation and organization details. + + + +### Contact Card + +Contact Card can be used to give the personal profile with name, address, phone number and email details. + + + +### Designation Card + +Designation Card can be used to give the employee profile with name and designation details. + + + +### I Card + +I Card can be used to give the personal profile with name, address, phone number and email details. + + + +## Feed Cards + +### Media Post + +This template can be used for posting infographic. Shows Summary information with an option to Read More. For example, Technology Infographic – Infographic on Mobile Networks; Product Development Landscape; Time Line Charts; Site Maps, etc. + + + +### News Post + +This template can be used for news feeds where you can post summary information and give a Link for Read More. You can have actions like share, like or call etc. Examples include Used in Social Media Apps like Twitter, Facebook; Corporate Social Networks like Yammer; Corporate News Letters + + + +### Personal Spotlight + +This template can be used to highlight information about a single personality and can be used to highlight their contributions etc. For example, Sports Personalities; Politicians; Top 10 CEOs; Top Women Professionals; Top 10 Employees; University Exam Toppers, etc. + + + +## Product Cards + +### Product Inventory + +This Card template can be used for showing product catalog in any e-commerce websites. For example, Product Catalogs, Library Catalogs, etc.. + +### Product Overview + +This card template can be used to show basic information on the card and have a link to show more information. For example, Product Overview with View Specifications by clicking on a Link; or Article Overview with View Original Article by clicking on a Link; or Feature Overview with View Feature Specifications by clicking on a link, etc. + +### Product Thumbnail + +This Template can be used in e-commerce websites for adding to the shopping cart online; or for listing youTube Videos with Play Video Link; or for listing Albums with an option to Add to Favorites shopping list. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/data-table.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/data-table.md new file mode 100644 index 000000000..aac3c8016 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/data-table.md @@ -0,0 +1,28 @@ +--- +title: "Data Table Widget" +id: "data-table" +sidebar_label: "Overview" +--- +--- +:::note +Data Table is available only for web responsive apps. +::: + +**Data Table** provides a tabular view for database Entities or API response data. Data Table can be bound to data sources like database tables, queries, procedures, web services or JSON objects through Variables. + +Data Table provides a user interface to perform CRUD operations for data from a database, by integrating the editable actions with their corresponding CRUD APIs that are generated automatically during [Database Integration](/learn/app-development/services/database-services/working-with-databases/) process through Database CRUD variables. + +Data Tables can also be bound with Web or Java or Query and Procedure Services, to display the response data in a tabular form. Note for such cases you will have the option of using a **Read-Only** table since the underlying CRUD functionality does not exist. + +While designing Data Table in WaveMaker, the following features are provided to configure and customize the Data Table: + +- select the type of form to be displayed for editing purposes in case of editable Data Table, +- search, filter and sort facility for the columns, +- the configuration of columns in terms of layout, format, style and role-based security, +- pagination styles for traversing through multi-page data, +- table and row level actions for adding, editing or deleting rows +- add any other custom action, +- export to CSV or Excel files, and much more. + +[![](/learn/assets/GraphicsData-Table-Widgeta.jpg)](/learn/assets/GraphicsData-Table-Widgeta.jpg) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/actions.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/actions.md new file mode 100644 index 000000000..b4f88beb8 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/actions.md @@ -0,0 +1,34 @@ +--- +title: "Data Table - Actions" +id: "actions" +sidebar_label: "Actions" +--- +--- +Data Table is capable of performing CRUD operations on the underlying Database Source. This functionality can be achieved through the table and record level actions like adding, editing and deleting records. In addition, custom actions can also be defined as per the requirements. + +Data Table actions include actions at the table-level and the row-level. These options are available from the **Actions** tab of the **Advanced Settings** property of the Data Table. + +### Table-Specific Actions + +- _New_ action which creates a new row when executed. This is provided with the Data Table by default and is programmed to insert the record into the underlying database table. +- You can add a new custom action for the Table to add a custom action method that has been created by you. The Action will be a JS function. +- These actions can be displayed either as a _Button_ or an _Anchor_. +- Actions can be made accessible using _Shortcut Keys._ Each of these Table Actions can be assigned a key from the Shortcut Key property. These keys, when used in conjunction with the key code (Alt in Windows & Linux; Alt+Shift in Firefox; Control+Alt in Mac; etc.), will activate or focus the Action. + +### Row Specific Actions + +- By default two actions are available on Table Rows each programmed to perform the respective action on the underlying database entity: + - updateRow() - to save changes made to the row fields + - deleteRow() - to delete the selected row +- You can add a custom row action to add a custom method that has been created by you. + +### Actions Visibility + +Visibility can be set based upon a column value within the row, for example, to show the  New button only if the Id value is 1, then bind the show property from Use Expression to _row.id === 1_ + +### Actions Layout + +You can configure the layout of the action column in terms of title for the column - set by default to Actions; the position of the column in the table - set to last by default; width of the column; width Unit for the above-mentioned width; class for custom column styles. + +[![](/learn/assets/AS_actions.png?ver=20)](/learn/assets/AS_actions.png?ver=20) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/data-source.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/data-source.md new file mode 100644 index 000000000..6435d439f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/data-source.md @@ -0,0 +1,28 @@ +--- +title: "Data Table - Data Source" +id: "data-source" +sidebar_label: "Data Source" +--- + +The first step in configuring a data table is to define the data that needs to be displayed. This data can be in the form of Services, Exiting Variable or another Widget. + +### Variable Source + +Variable binding will allow you to + +- Perform CRUD operations on a database through database CRUD Variables. +- List the results from a Web Service, Java Service or a Query through Variables based on the APIs exposed by the services (edit options are not available for Data Table bound to such service), +- List values stored in a Custom or Model Variables (edit options are not available in this case, too). + +You can either create a new variable or use existing variables. The behavior of data displayed will be defined by the Variable/Data Configuration properties. These properties are at the Variable level, you can configure them only when creating a new variable; for existing variables, the properties set at the time of variable creation will be used. To modify these, you will have to go to [variable dialog](/learn/assets/var_sel.png) and make changes. Of particular interest are: + +- _Records per request_ - this is the number of records that will be displayed on a page. Configure the Pagination property to enable user navigation to various pages of data; +- _Update data on input change_ - this property defines when the data displayed will be refreshed. When enabled the data is reloaded whenever the input to the Variable (in the form of filter fields for Live and parameter values for Service Variable) changes; +- _Request data on page load_ - enabling this property will ensure that the data within the data table is loaded at the time of page load. + +### Widget Source + +Widgets can be a source of data in some cases. For example, you might want to display the results from a Live Filter or more details of a selected row/item from a List or another Data Table. Widget option will allow you to achieve this. Selecting Widget as the data source will display the various options available. Widget binding will allow you to show 1-many relationships eg Employees of a selected Department list item. + +[![](/learn/assets/dt_data.png)](/learn/assets/dt_data.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/data-table-basic-usage.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/data-table-basic-usage.md new file mode 100644 index 000000000..6849b06e4 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/data-table-basic-usage.md @@ -0,0 +1,110 @@ +--- +title: "Creating Data Table" +id: "data-table-basic-usage" +sidebar_label: "Creating a Data Table" +--- +--- +### Overview + +Data Table provides a tabular view for database entities through a database service and allows to Create, Update and Delete (CRUD) operations on the entities. It can also be used to display the response data from a web or java service in a tabular form. + +## Configure Data Table + +To bind the Data Table Widget to your back-end services data, drag and drop the Data Table Widget onto the canvas. [![](/learn/assets/dt_sel.png)](/learn/assets/dt_sel.png) + +## STEP 1 – Select Data + +There can be different scenarios to deal with when configuring your Data Table Widget with a data source. The data source can be in the form of a service like Database or web or Jave service or from an another widget on the page. + +### Scenario 1 + +You do not have any databases or web services available in your project. +1. You will be prompted to import either a database or a web service. Click the appropriate button to proceed. +2. Once a service is available in your application, you can proceed to bind the widget to data source and follow the same steps as mentioned in scenario 2. +### Scenario 2 +1. **Retrieve Data From**: Services is selected by default. +2. **Select a Service**: Select a service from the drop-down which lists the services available in your application. Select Database CRUD option for this example. +3. Select Table of the database or entity in case of web service +4. **Variable Creation**: Once you select the service and table/Entity for the service, a default variable will be created for you – see the Variable Name field populated by default which will be holding the dataset of the service. You can change the Variable name. +5. **Select the Data Node**: You are given the option of choosing either the entire dataset – when you are binding the widget to a data source or any of the fields in the dataset. Select the data node tree when binding a single widget or a List item to a field in the dataset. +6. **Data Configuration Options**: You also have the option of setting the following Data Configuration options: + + - **Records per request**: with an option to enter the number of records to be fetched on each request. The default is 20. + - **Update Data on input change**: which is checked on by default. This means that whenever there is a change in the input parameter or filter field of the variable the data will be fetched from the service. This option will have an impact on the app performance. + - **Request data on Page Load**: which is checked on by default. This allows for data to be shown when the page is loaded. If this is not checked, you will not be able to view the data when the page gets loaded. Instead, No Data Found message appears on the widget at runtime. + +### Scenario 3 +If the variables based on database CRUD or web services are already created in the project/ + +1. **Retrieve Data From**: Select the retrieve data from option as Existing Variable. +2. **Select a Variable** from the drop-down list of the variables available in the application. You can select the one needed to bind the List Widget to. You can also search for a specific variable by typing in select variable option. If you are able to find your variable in the drop-down select the same. +3. Once you select the variables, it shows the dataset that it is bound to. +4. As Data Configuration options are already set for this variable, you do not see those options in this scenario. + +### Scenario 4: Binding to widget + +1. **Retrieve Data From**: Select the retrieve from data option as widget that was dragged and dropped onto the canvas. +2. **Select a widget** from the drop-down list. This will list the widgets present on this page, you cannot access the widgets from other pages. +3. You can **select data node** to be the entire widget or the selecteditem node in case of another Data Table or List or Cards or result from a Live Filter +4. As you are not using a Variable the Data Configuration options will not be available. + +[![](/learn/assets/dt_data.png)](/learn/assets/dt_data.png) + +## Step 2 – Select Layout + +Selecting the Layout includes two sub-steps: + +### i. Editable Table with + +- Form as Dialog: This can be used when you would like to have a data entry form shown as a dialog which will save space as the dialog form will be shown in the Table Layout. For Example: Adding Students to a Course with information such as Skill Level, Expertise to be entered on the dialog form. +- Form Below: This can be used when you want to view data in a Table and edit the selected row from the table using a form. For example, this can be used in use case where editable items are less, for instance, Qty in a shopping cart +- Inline Editable Table: This can be used when you want to add/edit data in a Table like a table rather than in a form. For example, this can be used in use case to create line items of an order detail table. + +[![](/learn/assets/dt_layout1.png)](/learn/assets/dt_layout1.png) + +### ii. Read-Only Table with + +- Details of the selected row displayed below the table: This can be used if you wish to select some specific fields in Data Table and would like to view some special fields in the form below. For Example: Viewing catalog items showing the Basic Tech Specs of each Device in the Data Table and on selecting each row in the grid view the Network and Connectivity related Specs in the Form below. +- Simple Table view: This Data Table provides for Read Only View of the existing Data when you want to show live data constantly refreshed. For example, Stock Trading Views, Election Results, etc. + +[![](/learn/assets/dt_layout2.png)](/learn/assets/dt_layout2.png) + +### Selecting Pagination Style + +[![](/learn/assets/dt_pagin.png)](/learn/assets/dt_pagin.png) + +## STEP 3 – Select Data Table Columns + +This step will allow us to select the fields to be shown in Data Table and once done + +1. Select your choice of fields to be displayed in Table +2. Reorder the fields for display in Table +3. Change the Title for the field +4. Change the Widget type for the field + +:::note +If you select the Data Table layout without Form in step 2, the **Done** button appears after this step. Click the **Done** button to add the Data Table to the current page. If you select other layouts, then additional two steps to do include **select the Form layout** and **select the Form fields**. +::: + +[![](/learn/assets/dt_fields.png)](/learn/assets/dt_fields.png) + +## STEP 4 – Select Form Layout + +If you have selected any of the Data Table layouts that include an inline or a dialog Form this step will allow you to select a Form layout for your inline Form or dialog Form. + +- You have the option of choosing **1-column, 2-column or 3-column layout**. 3-column layout is selected by default +- You can also set the alignment, position, and size of the **caption** of the Form fields. + +[See here for more details](/learn/app-development/widgets/datalive/live-form/liveform-layouts/) + +## STEP 5 – Select Form Fields + +Select the fields and set the title and widget property for each field + +1. Select the fields to be displayed in the Form +2. Change the title for each field +3. Change the widget type for display of each field value +4. Reorder the fields for display. In case you have selected 2- or 3-column layout, then you can specify the fields to be displayed in each column. + +[See here for more details](/learn/app-development/widgets/datalive/live-form/fields-configuration/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/data-table-use-cases.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/data-table-use-cases.md new file mode 100644 index 000000000..6782ff3a7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/data-table-use-cases.md @@ -0,0 +1,16 @@ +--- +title: "Data Table - Use Cases" +id: "data-table-use-cases" +sidebar_label: "Use Cases" +--- +--- + +- [Basic Table Usage](/learn/app-development/widgets/datalive/datatable/data-table-basic-usage/) +- [How to customize table actions](/learn/how-tos/data-table-actions/) +- [How to represent data table columns through widgets](/learn/how-tos/data-table-widget-representations/) +- [How to format data table column](/learn/how-tos/data-table-format-options/) +- [How to apply styles (generic and conditional) to data table](/learn/how-tos/data-table-styling/) +- [How to view master-detail record using a data table](/learn/how-tos/view-master-detail-data-records-using-data-table/) +- [How to add master-detail record using a data table](/learn/how-tos/add-master-detail-records-using-data-table/) +- [How to export data using a data table](/learn/how-tos/export-data-data-table/) +- [How to create a dynamic data table](/learn/how-tos/dynamic-data-tables/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/datatable-events-methods.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/datatable-events-methods.md new file mode 100644 index 000000000..be08bcdcf --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/datatable-events-methods.md @@ -0,0 +1,577 @@ +--- +title: "Data Table - Events & Methods" +id: "datatable-events-methods" +sidebar_label: "Events & Methods" +--- +--- +## Events + +Data Table behavior can be customized with the help of the call-back events. These events can be accessed from the events tab on the Properties panel. The trigger for the event can be JavaScript, another Variable call, and more. + +| Event | Trigger and JavaScript Usage | +| --- | --- | +|**On Row Click** | This event will be called when a row in Data Table is clicked. **Note**: This event can happen when selecting or deselecting a row. | + +```js +Page.[DataTableName]Rowclick = function($event, widget, row) { + //row has the data of the row which is clicked and the index of the row + // Note: Row selection will happen on click of a cell. So, cell element is present in $event. + + //Printing the clicked row data and its index + console.log(“The clicked row data with index:”, row.index , row); + }; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +|**On Row Select**| This event will be called when a row from Data Table is selected | + +```js +Page.[dataTableName]Select = function($event, widget, row) { + //row: row has the selected row data. row has also the index of the row + // Note: Row selection will happen on click of a cell. So, cell element is present in $event. + //Printing the selected row data and its index + + console.log(“The row data with index:”, row.index , row); + }; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +|**On Row Deselect**| This event will be called when a row from Data Table is deselected. | + +```js +Page.[dataTableName]Deselect = function($event, widget, row) { + //row has the deselected row data. Row has also the index of the row. + // Note: Row deselection will happen on click of a cell. So, cell element is present in $event. + //Printing the deselected row data and its index + console.log(“The row data with index:”, row.index , row); + }; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +|**On Data Sort**| This event will be called when the Data Table header is clicked to sort by a particular column. | + +```js +Page.[dataTableName]Sort = function($event, widget, $data) { + //$data: $data contains the newly sorted data, colDef, and sortDirection + + // Note: Column selection will happen on click of the header. So, column element is present in $event. + //Printing the sorted data + console.log(“The sort column data:”, $data); + }; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| **On Header Click** | This event will be called when the Data Table header is clicked. | + +```js +Page.[dataTableName]Headerclick = function($event, widget, column) { + + //column has the column definition data of the corresponding clicked header. + // Note: Column selection will happen on click of the header. So, column element is present in $event. + + //Printing the selected column field and the column definition + console.log(“The column data with column field:”, column.field , column); + }; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +|**On Before Row Delete** | This event is called before a record is deleted in a table.| + +```js +Page.[dataTableName]Beforerowdelete = function ($event, widget, row, options) { + +}; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| **On Column Select** | This event will be called when a column in Data Table is selected. **Note**: This event is accessible if you enable `Column Section` property from **Advanced Settings**. | + +```js +Page.[dataTableName]Columnselect = function($event, widget, $data) { + //$data has the object containing colDef, data and sortDirection. + //data has the selected column data. colDef has the selected column definition + + //Printing the selected column data and field name + + console.log(“The column data with column field:”, $data.colDef.field , $data.data); + }; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| **On Column Deselect** | This event will be called when a column in Data Table is deselected. **Note**: This event is accessible if you enable `Column Section` property from **Advanced Settings**. | + +```js +Page.[dataTableName]Columndeselect = function($event, widget, $data) { + //$data: $data contains colDef, data and sortDirection + + //Printing the selected column data and field name + console.log(“The column data with column field:”, $data.colDef.field , $data.data); + }; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| **On Record Delete** | This event will be called when a record is deleted from the underlying data entity. + +:::note +- This event will be triggered for _Editable Data Table with delete action defined_. +- For Data Table with Form option, this event will be available in the corresponding Form widget and not with Data Table. +::: + +```js +Page.[dataTableName]Rowdelete = function($event, widget, row ) { + //row: row has the data of the row deleted + //Printing the deleted row data + console.log(“The deleted row data:”, row); + }; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| **On Before Record Insert** | This event will be called before a new record is inserted in the underlying data entity. + +:::note +- This event is triggered for _Editable Data Table with insert action defined_. Use Case: Populate the date modified or modified user to the current date or logged in user +- For Data Table with Form option, this event will be available in the corresponding Form widget and not with Data Table. +::: + +```js +Page.[dataTableName]Beforerowinsert = function($event, widget, row, options) { + //row has the data of the new record to be inserted. This data can be modified and validated before sending the request + + //Validation can be performed here. + //If validation fails, return false will stop the operation and service call will not be made. + if (row.password.length < 6) { + wmToaster.show('error', 'ERROR', 'Password too small'); + return false; + } + //On before insert row, modify the data + row.dateModified = Date.now(); //Set today's date as modified date field + }; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| **On Record Insert** | This event will be called after a new record is inserted in the underlying data entity. + +:::note +- This event is triggered only for _Editable Data Table with insert action defined_. +- For Data Table with Form option, this event will be available in the corresponding Form widget and not with Data Table. +::: + +```js +Page.[dataTableName]Rowinsert = function($event, widget, row) { + //row: row has the data of the the new record inserted. + + //Printing the inserted row data + console.log(“The inserted row data:”, row); + }; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| **On Before Record Update** | This event will be called before a record is updated to the underlying data entity. | + +:::note +- This event is triggered only for _Editable Data Tables with update action defined_. +- For Data Table with Form option, this event will be available in the corresponding Form widget and not with Data Table. +::: + +```js +Page.[dataTableName]Beforerowupdate = function($event, widget, row, options) { + //row has the data of the the record to be updated. This data can be modified and validated before sending the request + + //Validation can be performed here. + //If validation fails, return false will stop the operation and service call will not be made. + if (row.password.length < 6) { + wmToaster.show('error', 'ERROR', 'Password too small'); + return false; + } + + //On before update row, modify the data + row.dateModified = Date.now(); //Set today's date as modified date + }; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| **On Record Update** | This event will be called after a record is updated to the underlying data entity.| + +:::note +- This event is triggered only for _Editable Data Tables with update action defined_. +- For Data Table with Form option, this event will be available in the corresponding Form widget and not with Data Table. +::: + + +```js +Page.[dataTableName]Rowupdate = function($event, widget, row) { + //row has the data of the the record updated. + + //Printing the deleted row data + console.log(“The deleted row data:”, row); + }; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| **On Before Data Render** | This event will be called the before the data is rendered in the Data Table. **Note**: The data accessible is restricted to the current page of the Data Table. Use Case: If you want to change the display value based on the values of a column | + +```js +Page.[dataTableName]Setrecord = function($event, data, columns) { + //data has data to be rendered in table + // An object of column names with each column name pointing to column definition. + + //Modify the data in required format. This modified data will be rendered in data table + $data.forEach(function(obj) { + if (obj.age <= 5) { obj.age = 'younger'; } else if (obj.age > 5 && obj.age <= 10) { + obj.age = 'young'; + } else { + obj.age = 'older'; + } + }); + }; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| **On Before Form Render** | (Only for Data Table with Quick-Edit and Inline-Edit) This event is fired on the edit of a row and before the inline form is rendered. | + +:::note +This gives access to data to be displayed in the form Use Case: You can use this event to edit values to be displayed in the form. Edit also can be prevented in form based on some condition. +::: + +```js +Page.[dataTableName]Beforeformrender = function($event, +widget, row, $operation) { + //row: row has the data of the row being edited/ inserted + //$operation: $operation value is 'new' for new row and 'edit' when row being edited + //If row has role admin, show error and stop edit + if (row.role === 'admin') { + wmToaster.show('error', 'error', 'Admin row can not be edited'); + return false; //Returning false will stop the editing and form is not rendered + } + //If city is not present in the row being edited, set default city + if (!row.city) { + row.city = 'New York'; + } + //For insert, set default role as 'user' + if ($operation === 'new') { + row.role = 'user'; + } +}; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| **On Form Render** | This event is accessible for Data Table with `Quick-Edit` and `Inline-Edit` templates. This event is called after the inline form is rendered. | + +:::note +This gives access to the widgets in the form. Use Case: Individual widget can be disabled based on a condition. +::: + +```js +Page.[gridName]Formrender = function($event, widget, +formWidgets, $operation) { + //formWidgets: formWidgets has the scopes of all the widgets in the form. Individual widget can be accessed as formWidgets.[fieldName] + //$operation: $operation value is 'new' for new row and 'edit' when row being edited + //Disabled the editing of role field + formWidgets.role.disabled = true; +}; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| **On Error** | (ONLY for Data Table with Quick-Edit and Inline-Edit) This event will be called after the edit/insert/delete operation returns a failure response | + +```js +Page.[gridName]Error = function($event, widget, +$data, $operation) { + //$data has the error message returned from the API. + //$operation: operation performed - edit or new or delete + console.log("Error returned from server:", $data);}; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| **On Before Export** | (ONLY for Data Table with Export Format selected) This event will be called before downloading the file. Any data changes like file format changes, field expression, size changes etc can be performed here. Returning false from the script will stop the file download. | + +```js +Page.hrdbDeptTable1Beforeexport = function (widget, $data) { + $data.exportType = 'CSV'; + + //updating the header + $data.columns.firstname.header = ‘Fullname’; + //updating first name expression + $data.columns.firstname.expression = firstname + ' ' +lastname; + + //adding new column + $data.columns.username = { + header: ‘Username’, + expression: firstname + '.' + lastname + } +}; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| **On Before Filter** | This event will be called when filter is applied on Data Table and before the search is triggered by the Data Table. Search values can be modified in this method. If false is returned from the method, Data Table filter will be stopped. | + +```js +Page.[dataTableName]Beforefilter = function($event, widget, columns) { + // Add tenantId filter always + columns.tenantId = { + value: 1 + } +}; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +|**On Data Render** | This event will be called when the data is rendered in the Data Table. **Note**: This gives access to data displayed on the current page of the Data Table Use Case: You can use this event to add a class to a particular row. | + +```js +Page.[dataTableName]Datarender = function(widget, data) { + //data: data has the data to be rendered in the current page of data table + + //widget.datagridElement has the data table jquery element + widget.datagridElement.find('tr.app-datagrid-row').each(function(index) { + //Loop through the rows. Add class admin for users having role as adminrole + if (data[index].role === 'adminrole') { + $(this).addClass('admin'); + } + }); + }; +``` + +| Event | Trigger and JavaScript Usage | +|---|---| +|**On Pagination Change**| This event is called on change of pagination. | + +```js +Page.[gridName]Setrecord = function ($event, widget, data, pageInfo) { + +}; +``` + +## Event Flow + +Following is the flow of events for each action triggered on the Data Table. + +| Action | Flow | +| --- | --- | +| On Row Select | Single select [![](/learn/assets/rowclick_event1.png)](/learn/assets/rowclick_event1.png) Row deselect will be called only if previously a row was selected | +|| Multi-Select If a selected row is clicked: [![](/learn/assets/rowclick_event2a.png)](/learn/assets/rowclick_event2a.png) If an unselected row is clicked: [![](/learn/assets/rowclick_event2b.png)](/learn/assets/rowclick_event2b.png) | +| On Header click | Column selection is enabled If a selected column is clicked: [![](/learn/assets/headerclick_event1a.png)](/learn/assets/headerclick_event1a.png) If an unselected column is clicked: [![](/learn/assets/headerclick_event1b.png)](/learn/assets/headerclick_event1b.png) | +|| Column selection is disabled & sort is enabled [![](/learn/assets/headerclick_event2.png)](/learn/assets/headerclick_event2.png) On Row Select row is triggered if select first record is enabled | +| On Page Load | [![](/learn/assets/pageload_event1.png)](/learn/assets/pageload_event1.png) If ‘Select first record’ is enabled: [![](/learn/assets/pageload_event2.png)](/learn/assets/pageload_event2.png) | +| On Filter | [![](/learn/assets/filter_event1.png)](/learn/assets/filter_event1.png) On Row Select row is triggered if select first record is enabled. | +| On Export | [![](/learn/assets/export_event1.png)](/learn/assets/export_event1.png) | +| On Pagination | [![](/learn/assets/pagination_event1.png)](/learn/assets/pagination_event1.png) | +| On Click of edit or new buttons | [![](/learn/assets/editnew_event1.png)](/learn/assets/editnew_event1.png) | +| On Click of save in edit mode | [![](/learn/assets/saveedit_event1.png)](/learn/assets/saveedit_event1.png) If before row update returns false, operation is stopped and next events are not fired | +| On Click of save in insert mode | [![](/learn/assets/saveinsert_event1.png)](/learn/assets/saveinsert_event1.png) If before row insert returns false, operation is stopped and next events are not fired | +| On Click of delete button | [![](/learn/assets/delete_event1.png)](/learn/assets/delete_event1.png) If before row delete returns false, operation is stopped and next events are not fired | + +## Methods +--- +Data Table has few methods exposed on widget scope which can be accessed via JavaScript. For the following script samples, we are considering the hrdb Department table. DepartmentGrid is bound to the Database CRUD Variable corresponding to the Department table. + +- To refresh the data in data table with the currently applied filters and sort: + +```js +Page.Widgets.[gridName].refreshData(); +``` + +- To clear the filters applied on data table: + +```js +Page.Widgets.[gridName].clearFilter(); +``` + +- To focus on a field in edit mode(applicable to inline and quick edit data tables alone): + +```js +Page.Widgets.[dataTableName].formfields.[columnname].focus(); +//This will focus the input on [columnname] field +``` + +- To change a property of a column: + +```js +Page.Widgets.[dataTableName].columns.[columnname].displayName = ‘Deptarment Id’; +//Will change the display name of specified column to ‘Department Id’. +``` + +- To force re-render Data Table: + +```js +Page.Widgets.[dataTableName].redraw(true); +//Will force re-render data table. +``` + +- To change a property of a column: + +```js + Page.Widgets.[dataTableName].column.[columnname].sortable = false; + // disables the sort property on the data table + //Note: you can replace 'sortable' with any column property listed in the advanced settings. +``` + +- To change value of a field which is in edit mode (applicable to inline and quick edit data tables alone): + +```js + Page.Widgets.[dataTableName].formfields.[columnname].widget.datavalue = 'Engineering 1'; + // Sets ‘Engineering 1’ to the specified column edit field + //Note: This will work only on click of edit on a row. +``` + +- To retrieve value of a field which is in edit mode (applicable to inline and quick edit data tables alone): + +```js + console.log(Page.Widgets.[dataTableName].formfields.[columnname].getProperty('value')); + // This will display the specified column field value in the console. + //Note: This will work only on click of edit on a row. +``` + +- To select a row: + +```js + Page.Widgets.[dataTableName].selectItem(1); + // The parameter can be index or object of row +``` + +- To deselect a row: + +:::note +Deselect will work only for data table with multiselect enabled on it. +::: + +```js + Page.Widgets.[dataTableName].deselectItem(1); + //the parameter can be index or object of row (data bound to row), + //For grid actions user can send $row (which is row data) , + //that can be sent as an argument to this method. +``` + +- Working with selected item: + +```js + Page.Widgets.[dataTableName].selecteditem = 2; + //Selects the third row or item + Page.Widgets.[dataTableName].selecteditem = [2, 3]; + //Selects the third and fourth row/item + Page.Widgets.[dataTableName].selecteditem = []; + //Deselects the existing rows or items +``` + +- Set filter mode: + +```js + Page.Widgets.[dataTableName].filtermode = ‘search’; + // To set filter mode as search + Page.Widgets.[dataTableName].filtermode = ‘multicolumn’; + //To set filter mode as multi column +``` +   +## Inline edit for service variable + +Inline editing can be enabled for a Data Table when bound to a Web Service/Java Service Variable + +- Go to Advanced Settings for the Data Table. +- Go to the Actions tab. +- Select the New, Edit and Delete actions. +- As the Data Table is bound to Variable based on APIs exposed by the web service/ java service which returns list of records, for edit, update or delete user should map it to respective variables. This can be achieved through events on data table. +- To _On Record Insert_: + +```js +Page.[gridName]Rowinsert = function($event, widget, row) { + //row: row has the data of the row being inserted + //row can be modified here + row.dateInserted = Date.now(); + //Set the input as row for variable + Page.Variables.[insertVariable].setInput(row); + //Insert the data by invoking the variable + Page.Variables.[insertVariable].invoke({}, function() { + //On success, call the refreshData on method to get the refreshed data + widget.refreshData(); + }); + }; +``` + +- To On Record Update: + +```js +Page.[gridName]Rowupdate = function($event, widget, row) { + //row: row has the data of the row being updated + //row can be modified here + row.dateModified = Date.now(); + //Set the input as row for variable + Page.Variables.[updateVariable].setInput(row); + //Update the data by invoking the variable + Page.Variables.[updateVariable].invoke({}, function() { + //On success, call the refreshData on method to get the refreshed data + widget.refreshData(); + }); + }; +``` + +- On Record Delete: + +```js +Page.[gridName]Rowdelete = function($event, widget, row) { + //row: row has the data of the row being deleted + //Set the input as row for variable + Page.Variables.[deleteVariable].setInput(row); + //Delete the data by invoking the variable + Page.Variables.[deleteVariable].invoke({}, function() { + //On success, call the refreshData on method to get the refreshed data + widget.refreshData(); + }); + }; +``` + +Methods: Below methods can be used for inline editing (applicable to inline and quick edit data tables alone) + +- To edit a row + +```js + Page.Widgets.[dataTableName].editRow(); + // Selected row will be edited +``` + +- To add a new row + +```js + Page.Widgets.[dataTableName].addRow(); +``` + +- To save a row + +```js + Page.Widgets.[dataTableName].saveRow(); +``` + +- To cancel a row edit + +```js + Page.Widgets.[dataTableName].cancelRow(); +``` + +- To delete a row + +```js + Page.Widgets.[dataTableName].deleteRow(); +``` + +- To hide the edit row and go back to view mode + +```js + Page.Widgets.[dataTableName].hideEditRow(); +``` \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/events-methods.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/events-methods.md new file mode 100644 index 000000000..e89151033 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/events-methods.md @@ -0,0 +1,90 @@ +--- +title: "Live Form - Events & Methods" +id: "events-methods" +sidebar_label: "Events & Methods" +--- + +# Events + +Live Form behavior can be customized with the help of the call-back events. These events can be accessed from the events tab on the Properties panel. The trigger for the event can be JavaScript, another Variable call etc.. + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| On before service call | This event will be called on saving the live form. Any validation checks can be performed here. Returning false from the script will stop the live form save. | +| | +Page.liveform1Beforeservicecall = function($event, $operation, $data) { +//$operation: Current operation being performed - INSERT or UPDATE or DELETE +//$data has the data of the all widgets inside the live form. This data can be modified and validated before sending the request. + function isValidData(data) { + /*restrict password to be minimum of 6 characters*/ + if ($data.password) { + if ($data.password.length < 6) { + return false; + } + } else { + return false; + } + } + return isValidData($data) +}; + + | +| On result | This event will be called after the live form is saved and API returns a response. The event is triggered in both success and failure cases. | +| | + +Page.liveform1Result = function($event, $operation, $data) { +//$operation: operation performed - INSERT or UPDATE or DELETE +//$data has the response returned from the API. +console.log("server response:", $data); +}; + + | +| On success | This event will be called after the live form is saved and API returns a success response. | +| | + +Page.liveform1Success = function($event, $operation, $data) { +//$operation: operation performed - INSERT or UPDATE or DELETE +//$data has the response returned from the API. +console.log("The inserted/updated/deleted data:", $data); +}; + + | +| On error | This event will be called after the live form is saved and API returns a failure response. | +| | + +Page.liveform1Error = function($event, $operation, $data) { +//$operation: operation performed - INSERT or UPDATE or DELETE +//$data has the error message returned from the API. +console.log("Error returned from server:", $data); +}; + + | + +# Methods + +Live Form has few methods exposed on widget scope to Edit, Delete, Add record and trigger actions like reset and cancel. + +For the following script samples, we are considering the _hrdb_ _Employee_ table. **EmployeeForm** is bound to the SelectedItem of a Data Grid corresponding to Employee Live Variable. + +- To delete a record: + + Page.Widgets.EmployeeForm.delete(); //Deletes the current record that is bound to EmployeeForm. + +- To update a record: + + Page.Widgets.EmployeeForm.save(); //Updates the current record bound + +- To add a new record: + + Page.Widgets.EmployeeForm.new(); //Adds a new record to dataset that is bound to EmployeeForm. + +- To reset a form: + + Page.Widgets.EmployeeForm.reset(); //Resets the form to initial state. + +- To cancel an edit operation: + + Page.Widgets.EmployeeForm.cancel(); //Cancels the form edit. + +   + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/field-configuration.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/field-configuration.md new file mode 100644 index 000000000..e6947eaf8 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/field-configuration.md @@ -0,0 +1,168 @@ +--- +title: "Data Table - Field Configuration" +id: "field-configuration" +sidebar_label: "Field Configuration" +--- +--- +:::note +The following features are available from the **Advanced Settings** property of the Data Table. +::: + +## Configure column display options + +The columns or fields to be displayed in a Data Table can be further configured: + +1. to be displayed based upon the platform i.e. for desktop and mobile. This enables you to keep your mobile display clutter free, you can choose to display only limited columns or fields for mobile platform; +2. the order can also be specified as different from the underlying data source ordering by using the arrow keys given below the column listing; +3. group columns under a common heading; +4. add a custom column; +5. to choose a representational view based upon the field content, like picture field can be depicted as an _image_ for the picurl field, boolean fields as a _checkbox_ etc.; +6. to define the display format of the column or field, based upon the content including date, currency, decimal and many more formats; +7. to style the fields for a better readability and for highlighting a particular value; +8. to restrict the display based upon the security roles; +9. filter criteria can be applied to referenced entities for Inline Editable and Quick Edit Data Tables ([see here for usage](/learn/how-tos/using-filter-criteria-data-live-widgets)). + +All the above-mentioned options are available from the **Columns tab** of the **Advanced Settings** property. + +[![](/learn/assets/AS_fields.png)](/learn/assets/AS_fields.png) + +### Column Grouping + +This feature helps you group columns under a heading for better readability and convenience. [![](/learn/assets/group_run.png)](/learn/assets/group_run.png) + +1. Use the **Add Group** button under _Columns_ tab of _Advanced Settings_. This will allow you to give a title to the group. [![](/learn/assets/group_new.png)](/learn/assets/group_new.png) +2. **Add columns**  to the group by either + - using the _drag_ or  _reorder_ option from the column tree on the left panel within the  Advanced Settings dialog, or + - by selecting the _Group_ from the Basic properties tab [![](/learn/assets/group_add.png)](/learn/assets/group_add.png) +3. You can also have nested groups by selecting the parent group while adding the group or use the drag feature. [![](/learn/assets/group_nested.png)](/learn/assets/group_nested.png) [![](/learn/assets/group_nested_final.png)](/learn/assets/group_nested_final.png) + +### View Mode Options + +[![](/learn/assets/dt_cols_view.png)](/learn/assets/dt_cols_view.png) + +#### Widget Representation + +##### Anchor Mode Options + +- _Widget Class_ - style class for the entire column +- _Conditional Widget Class_ - specify the style class name to be applied to select rows satisfying the given condition. +- _Widget Title_ - title to be displayed on the button at run-time, set by default to the column name, can be edited as per the needs +- _Widget Hyperlink_ - link to the page to be opened on click. +- _Value Expression_ - You can write a custom expression to change the display setting for a table column. The expression needs to follow AngularJS conventions for binding. A sample expression is given which can be enhanced as per the needs of the application. + +##### Button Mode Options + +- _Widget Class_ - style class for the entire column +- _Conditional Widget Class_ - specify the style class name to be applied to select rows satisfying the given condition. +- _Widget Title_ - title to be displayed on the button at run-time, set by default to the column name, can be edited as per the needs +- _Widget Icon_ - icon name, including the class name, for example, glyphicon glyphicon-home +- _Widget Action_ - method, as defined in Script, to be invoked on the click event of the button. The method will be auto-generated upon the selection of JavaScript option with a parameter set to _selectedItem_. +- _Value Expression_ - You can write a custom expression to change the display setting for a table column. The expression needs to follow AngularJS conventions for binding. A sample expression is given which can be enhanced as per the needs of the application. + +##### Checkbox Mode Options + +- _Widget Class_ - style class for the entire column +- _Conditional Widget Class_ - specify the style class name to be applied to select rows satisfying the given condition. +- _Disable_ - code example given to disable the checkbox in the table +- _Value Expression_ - You can write a custom expression to change the display setting for a table column. The expression needs to follow AngularJS conventions for binding. A sample expression is given which can be enhanced as per the needs of the application. + +##### Icon Mode Options + +- _Widget Class_ - style class for the entire column +- _Conditional Widget Class_ - specify the style class name to be applied to select rows satisfying the given condition. +- _Widget Title_ - title to be displayed on the button at run-time, set by default to the column name, can be edited as per the needs +- _Widget Icon_ - icon name, including the class name, for example, glyphicon glyphicon-home +- _Icon Position_ - to set the position of the Icon; choose Left (default) or Right +- _Value Expression_ - You can write a custom expression to change the display setting for a table column. The expression needs to follow AngularJS conventions for binding. A sample expression is given which can be enhanced as per the needs of the application. + +##### Image Mode Options + +- _Widget Class_ - style class for the entire column +- _Conditional Widget Class_ - specify the style class name to be applied to select rows satisfying the given condition. +- _Image Source_ - by default it is populated with the column name, it can be replaced with any external source path. +- _Value Expression_ - You can write a custom expression to change the display setting for a table column. The expression needs to follow AngularJS conventions for binding. A sample expression is given which can be enhanced as per the needs of the application. + +##### Label Mode Options + +- _Widget Class_ - style class for the entire column +- _Conditional Widget Class_ - specify the style class name to be applied to select rows satisfying the given condition. +- _Widget Title_ - title to be displayed on the button at run-time, set by default to the column name, can be edited as per the needs +- _Value Expression_ - You can write a custom expression to change the display setting for a table column. The expression needs to follow AngularJS conventions for binding. A sample expression is given which can be enhanced as per the needs of the application. + +[See here for usage example](/learn/how-tos/data-table-widget-representations/) + +#### Format Options + +[![](/learn/assets/dt_cols_format.png)](/learn/assets/dt_cols_format.png) + +**Format** Options enables you to define the display format of the column at runtime. The options include _toDate, toCurrency, prefix, suffix, and srtingtoNumber_. Be aware that these format types selected are only for display purpose. During runtime, edit row will display the values as defined in the data source. + +##### Prefix/Suffix Options: + +- Prefix/Suffix value can be specified + +##### Currency Options: + +- Symbol by name can be selected from the drop-down list and the currency symbol will be inserted in the column +- Fraction Size can be set + +##### Date Options: + +- Date Pattern can be selected from the drop-down list + +##### Number Options: + +- Fraction Size can be set + +[See here for usage example](/learn/how-tos/data-table-format-options/) + +### Edit Mode Options + +For _Quick Edit_ and _Inline Editable_ Table, you can specify the Display Format and Validation criteria for the columns (non-primary key) when the row is in **Edit Mode**. + +1. **Display options** include: + + - - _Widget_ - text, select, datetime etc., + - _Placeholder_ + - _Default Value_ + - _Filter on Field_ to set cascading data, i.e., restrict the display values for the current field based on the value of the field set for this property. For example, the values displayed in the city field should depend upon the value selected for state field; then correspondingly for city field, filter on field property should be set to state. + + [![](/learn/assets/dt_cols_edit.png)](/learn/assets/dt_cols_edit.png) +2. **Validation options**: + + - - **Required**: whether the column entry is mandatory or not; + - **Validations**: depending upon the data type of the column you have the option to set + - _maximum character_ for text type, + - _minimum length_ and _maximum length_ for number fields and + - _regular expression for validations_ for text and numeric fields. + - **Validation Message** to be displayed if the field fails the validation specified. in case of validation failure, an error icon is displayed, hovering over which will display the validation message. + + [![](/learn/assets/dt_cols_validations.png)](/learn/assets/dt_cols_validations.png) + +### Export Options + +In the case where the export option is set by selecting the Export Format as EXCEL or CSV, the **Export Options** can be used to customize the export values by setting the Value Expressions. This is particularly useful to display name column as a combined value like 'firstname+lastname' while export. + +NOTE: Value Expression **has** to be set for custom fields. + +[![](/learn/assets/dt_cols_export.png)](/learn/assets/dt_cols_export.png) + +### Filter Mode Options + +In the case, Filter Option is set to Row while designing the Data Table, then the **Filter Options** can be enabled or disabled for the specific column. + +[![](/learn/assets/dt_cols_filter.png)](/learn/assets/dt_cols_filter.png) + +### Styling Options + +**Styles** can be used to change the styles for the selected field. + +For more information about styles and properties, see [Data Table Styles](/learn/app-development/widgets/datalive/datatable/styles). + +For examples, see [Custom Styling Data Table Columns & Rows](/learn/how-tos/data-table-styling/) + +### Security Options + +**Role-based access** can be set to enforce security at column-level: If the [security has been enabled](/learn/app-development/app-security/app-security) in your app, then you can define the app role which has access to a specific column. + +[![](/learn/assets/dt_security.png)](/learn/assets/dt_security.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/layouts.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/layouts.md new file mode 100644 index 000000000..2712de2fe --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/layouts.md @@ -0,0 +1,67 @@ +--- +title: "Data Table - Layouts" +id: "layouts" +sidebar_label: "Layouts" +--- +--- +Data Table can be editable or read-only with editable options being inline or dialog-based. These options are available as **Layout options**. + +:::note +Editable options are available only for Database CRUD Variables; as other variables do not support CRUD operations. +::: + +## Editable Data Table with Forms +--- +### Editable with Form as Dialog + +A Data Table Layout for data viewing and a Dialog Form for User Data Entry + +- The Table Layout will have Edit/Delete option for each row and will have a NEW button at the bottom to add data using the Dialog Form +- A blank Dialog Form will show up on click of NEW button to add new record and will have a Save button to save +- When edit button is clicked in a row, the selected row values will be shown in the Dialog Form where you can make the changes and save the data. + + + +### Editable with Form given below the Table + +- This is very similar to the first template except that the Form for editing is given below the Table. +- Select any row for editing +- The Data Table here again provides Edit/Delete and New options + + + +## Editable Data Table +--- + +### Inline Editable + +- A Table Layout with Edit/Delete/New option +- By default when NEW is clicked to add a new row, the new row will be appended to the bottom of the table. You can change this setting from ADVANCED SETTINGS and set the Form Position property to Top. + + + +### Quick Edit + +- A Table Layout to enable quick editing of rows in a Data Table using keyboard events. +- The following keys can be used: + - Click on any row to make it editable + - Use tab key to go to the next field or column + - Tabbing out of the row will save the changes, automatically + - Tabbing out of the last row will add a new row to the table + - Use ESC key to cancel the changes + - Use Delete key to delete the row currently in edit mode +- In the Quick mode, always a new row will be shown in the data table. However, the position will depend upon the form position property.**Note:** _Quick edit template will not have new button action._ + +## Read-Only Data Tables +--- + +### Read-Only with Details Below + +- This Data Table provides for Read Only View of the existing Data + +### Read-Only Simple View + +- This Data Table provides for Read Only View of the existing Data + + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/row-expansion-data-table.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/row-expansion-data-table.md new file mode 100644 index 000000000..c0e92b7e6 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/row-expansion-data-table.md @@ -0,0 +1,30 @@ +--- +title: "Row Expansion in Data Table" +id: "row-expansion-data-table" +sidebar_label: "Row Expansion" +--- +--- +:::note +The row expansion feature is available since WaveMaker 10.0. GA release.  +::: + +Row expansion is a property in the data table widget. By enabling the row expansion, you expand a row horizontally to view additional information of the expanded item. This feature appears as a small arrow placed on the left column of the table field. When you click the small arrow, the row expands as illustrated below. Using the row expansion, you can connect to different data sources and call information from multiple tables, web and REST APIs. For example, you can use Salesforce API to view “quick information” on the same page without needing to open a new tab or a new page.  + +![](/learn/assets/RowExpansionWM10.gif)Row expansion enables you to expand and collapse the row for the optimum use of the display, which means you can instantly expand to view more details and collapse when not necessary. This way, you offer your app an engaging user experience. + +## How row expansion works + +Typically, you create a data table and a [partial](/learn/app-development/ui-design/page-concepts/partial-pages/). A partial is a semi-page, and it is a reusable object, whereas a data table is a data widget which displays data in a tabular format. You design the partial to contain information related to the table item which you intend to expand. For example, a table field and its expansion. Once the partial has been created, you add page params in the partial page settings. And lastly, you bind the partial and page params through the data table settings for the row expansion enablement. + +## Example +In the following table, the **Table** is a Data Table; **Additional information** is a Partial. The **Table** connects to the **Additional information** through the specified Page Param called **Table field**.  + +| Table | Table field | Additional information | +| --- | --- | --- | +| (Data Table) → | (Page Param) → | (Partial) | +| Customers → | Customer ID → | Recent orders | +| Orders → | Order Number → | Items from the order | +| Department → | Department ID → | Displaying charts for budget-related info | +| Employee name → | Employee ID → | Employee's profile information | + +For more information, see [How to Configure Row Expansion in a Data Table](/learn/how-tos/how-to-configure-row-expansion-in-a-data-table/). diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/show-header-data-table.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/show-header-data-table.md new file mode 100644 index 000000000..aa191a1ad --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/show-header-data-table.md @@ -0,0 +1,35 @@ +--- +title: "Show Header Property in Data Table" +id: "show-header-data-table" +--- + +Show Header is a Data Table property. It determines the visibility of the column header captions. + +## Enable Show Header Property + +You can choose to show or hide the header of the Data Table. The Data Table header displays when you enable the Show Header property from the advanced settings. The property value is enabled to Show Header by default. The following example shows the table view when the Show Header property is enabled. + + + +## Disable Show Header Property + +To hide the Data Table header, disable the **Show Header** property for the selected table. The following example shows the table view when you disable the Show Header property. + + + +## How to do + +The following steps show how to enable or disable a Show Header property. + +![](/learn/assets/ShowHideHeader.gif) + +1. Select the Data Table. +2. Go to **Advanced Settings.** +3. Go to the **Layout** section in the **Data Table** tab. +4. Enable or disable the **Show Header** property to the show or hide the header of the table. + +In this Page + +- [Show Header](#show-header) +- [Hide Header](#hide-header) +- [How to do](#how-to) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/styles.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/styles.md new file mode 100644 index 000000000..f511d38a6 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/styles.md @@ -0,0 +1,38 @@ +--- +title: "Data Table Styles" +id: "styles" +sidebar_label: "Styles" +--- +--- + +## Data Table Classes + +From [release 10.4](/learn/wavemaker-release-notes/v10-4-0), the default pattern of the data tables change from boxy borders to list view. + +The class names for bordered table and striped table are optional. You can add these from the right style property panel. + +- table-bordered +- table-hover +- table-striped + +![datatable styles](/learn/assets/datatable-styles.png) + +## Column Styles + +From Advanced Settings, to go **Columns**, and then click the **Styles** tab. + +The styles can be used to change the styles for the selected field. + +- **Width** for the column which can be specified in terms of the **Width Unit** - _px_ or _%_ +- **Text Alignment** of the column content +- **Background** color for the column can be set +- CSS **Class** for styling the field, this needs to be under the Style tab of the Page +- **Conditional Class** for custom styling the column based on a condition + +## Row Styles + +Similar to columns styling, styles can be applied to rows in the Data Table. Conditional classes can also be applied based upon the data value within the rows. + +[![](/learn/assets/table-config3.png)](/learn/assets/table-config3.png) + +For examples, see [Custom Styling Data Table Columns & Rows](/learn/how-tos/data-table-styling/) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/summary-row.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/summary-row.md new file mode 100644 index 000000000..ed974eace --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/summary-row.md @@ -0,0 +1,254 @@ +--- +title: "Data Table - Summary Row Function" +id: "summary-row" +sidebar_label: "Summary Row" +--- +--- + +When creating a data table, you can use Summary Row Function to add a summary at the bottom of the table. This summary computes on the client-side or the server-side. + +Using Summary Row Function, you can summarize any number of columns. A table can also include more than one summary row. To calculate the summary, you can simply use in-built javascript functions like ```sum, minimum, maximum, percent```. Application developers may also write their own javascript function that calculates the summary. + +You can set summary row using the below-exposed function on a column in the **Beforedatarender** event callback: + +- `setSummaryRowData` + +## setSummaryRowData + +WaveMaker provides aggregate functions that can be referenced and used in the `setSummaryRowData` method for using inbuilt aggregate functions for DataTable columns. This method accepts a single or an array of: + +- Plain values and Built-in aggregation functions +- Custom Functions with aggregation logic +- Objects for custom styling + +## Plain Values and Built-in aggregation functions + +### Single Summary Row + +Call **setSummaryRowData** on the column where you want to set the summary row data + +```js +Page.GroceriesTable1Beforedatarender = function(widget, data, columns) { + columns.item.setSummaryRowData('Net Total'); + columns.netAmount.setSummaryRowData('670'); +}; +``` + +[![summaryrow1](/learn/assets/datatable_summaryrow1.png)](/learn/assets/datatable_summaryrow1.png) + +### Multiple Summary Rows + +Call **setSummaryRowData** on the column where you want to set the summary rows data and pass an array of values. + +```js +Page.GroceriesTable1Beforedatarender = function(widget, data, columns) { + columns.item.setSummaryRowData([ + 'Net Total', + 'Discount' + ]); + columns.netAmount.setSummaryRowData([ + '670', + '2%' + ]); +}; +``` + +[![summaryrow2](/learn/assets/datatable_summaryrow2.png)](/learn/assets/datatable_summaryrow2.png) + +### Summary Row with Aggregate Function and Variables + +Create an aggregate function instance and call the inbuilt aggregate functions on the column **setSummaryRowData**. + +```js +Page.GroceriesTable1Beforedatarender = function(widget, data, columns) { + const DISCOUNT = Page.Variables.Discount.dataSet.dataValue; + const netAmountAggregate = columns.netAmount.aggregate; + + columns.item.setSummaryRowData([ + 'Net Total', + 'Discount' + ]); + columns.netAmount.setSummaryRowData([ + netAmountAggregate.sum(), + DISCOUNT + '%' + ]); +}; +``` + +[![summaryrow3](/learn/assets/datatable_summaryrow2.png)](/learn/assets/datatable_summaryrow2.png) + +### Built In Aggregate functions + +A Column contains the below built-in aggregate functions that you can use in summary rows. + +| Function | Parameters | +|----|----| +| sum | NA | +| average | NA | +| count | NA | +| minimum | NA | +| maximum | NA | +| percent | Total value to calculate percentage | + +The above aggregate functions can be accessed using the `aggregate` object on the columns as shown below. + +```js +Page.Beforedatarender = function(widget, data, columns) { + const columnAggregate = columns..aggregate; + columns..setSummaryRowData(columnAggregate.sum()); +}; +``` + +## Custom Functions with aggregation logic + +### Summary Row Custom Function + +Call custom function and return data in **setSummaryRowData** on the column where you want to set the summary row data. + +```js +Page.GroceriesTable1Beforedatarender = function(widget, data, columns) { + const DISCOUNT = Page.Variables.Discount.dataSet.dataValue; + const netAmountAggregate = columns.netAmount.aggregate; + + columns.item.setSummaryRowData([ + 'Net Total', + 'Discount', + 'Total' + ]); + columns.netAmount.setSummaryRowData([ + netAmountAggregate.sum(), + DISCOUNT + '%', + calculateTotal() + ]); + + function calculateTotal() { + let total = netAmountAggregate.sum(); + return total - ((total / 100) * DISCOUNT); + } +}; +``` + +[![](/learn/assets/datatable_summaryrow3.png)](/learn/assets/datatable_summaryrow3.png) + +## Styling the Summary row + +Return an object with keys value and class to display data and add styles associated to that class in **setSummaryRowData** on the column you want to set the summary row data. + +```js +Page.GroceriesTable1Beforedatarender = function(widget, data, columns) { + const DISCOUNT = Page.Variables.Discount.dataSet.dataValue; + const netAmountAggregate = columns.netAmount.aggregate; + + columns.item.setSummaryRowData([ + 'Net Total', + 'Discount', + { + value: 'Total Budget', + class: 'bold-class' + } + ]); + columns.netAmount.setSummaryRowData([ + netAmountAggregate.sum(), + DISCOUNT + '%', + { + value: calculateTotal(), + class: 'bold-class' + } + ]); + + function calculateTotal() { + let total = netAmountAggregate.sum(); + return total - ((total / 100) * DISCOUNT); + } +}; +``` + +[![](/learn/assets/datatable_summaryrow4.png)](/learn/assets/datatable_summaryrow4.png) + +You can also create a CSS class with all the required CSS properties inside the styles tab and use that class inside the `setSummaryRowData` function in the script page. + +Refer below example: + +```js +.styleSummaryRow{ +color: red; +font-weight: bold; +} +``` + +```js +columns.age.setSummaryRowData({ + value: 'Total Salary', + class: 'styleSummaryRow' + }) +}; +``` + +### Summary Row Custom Asynchronous Function + +The javascript function that calculates the summary can invoke an API to return the result of the calculation executed on the server-side. This API could be the application's business logic. For example, when calculating the applied discount, business logic may assign the discount value based on the logged-in user or amount, money spent, etc. In such a case, the javascript function will return a `Promise` after calling the API. + +Here is an example of a custom javascript function that invokes an API and returns a promise to the ```setSummaryRowData```. + +```js +Page.GroceriesTable1Beforedatarender = function(widget, data, columns) { + const DISCOUNT = Page.Variables.Discount.dataSet.dataValue; + const netAmountAggregate = columns.netAmount.aggregate; + + columns.item.setSummaryRowData([ + 'Net Total', + 'Discount', + 'Total' + ]); + columns.netAmount.setSummaryRowData([ + netAmountAggregate.sum(), + DISCOUNT + '%', + calculateTotal() + ]); + + function calculateTotal() { + return new Promise(function(resolve, reject) { + Page.Variables.Total.invoke().then((data) => { + resolve(JSON.parse(data.body).budget); + }); + }); + } +}; +``` + +[![](/learn/assets/datatable_summaryrow5.gif)](/learn/assets/datatable_summaryrow5.gif) + +## Handling Column Visibility + +:::note +The Summary row-column visibility may depend on the actual column's visibility. If a column is set to not show in mobile/desktop devices, the respective summary row columns may also need to be hidden. Using the authorization setting in WaveMaker, a column could be hidden for specific roles of users. +::: + +To Handle column visibility, check the column's occurrence in runtime to handle such scenarios. If a column is hidden, it will not be available under the **columns** interface in runtime. In such cases, consider the below code: + +```js +Page.DepartmentTable1Beforedatarender = function(widget, data, columns) { + const budgetAggregate = columns.budget.aggregate; + columns.budget.setSummaryRowData(budgetAggregate.sum()); + + if (columns.deptId) { + columns.deptId.setSummaryRowData("Total Budget"); + } else { + columns.name.setSummaryRowData("Total Budget"); + } +}; +``` + +Here, if the column ```deptId``` is present in the table, the label "Total Budget" is rendered under the respective column. Otherwise, it renders under the ```name``` column. + +The scenario could suit a requirement where the column ```deptId``` is present in the larger screens but not in mobile screens, while column ```name``` is present in all the screens. + +Here is how the summary row will appear in respective screens: + +### Large Screen + +[![](/learn/assets/datatable_summaryrow7.png)](/learn/assets/datatable_summaryrow7.png) + +### Mobile Screen + +[![](/learn/assets/datatable_summaryrow8.png)](/learn/assets/datatable_summaryrow8.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/table-configuration.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/table-configuration.md new file mode 100644 index 000000000..c496c9dd1 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/datatable/table-configuration.md @@ -0,0 +1,94 @@ +--- +title: "Data Table Configuration" +id: "table-configuration" +sidebar_label: "Configuration" +--- +--- + +:::tip +Access to the following features from the **Advanced Settings** property of a Data Table. +::: + +## Search and Filter Configuration + +Search and Filter facility is particularly helpful when dealing with huge tables. Instead of restricting the data being displayed, the option can be left to the user to decide which data to be displayed. + +In WaveMaker this can be achieved via the **filter mode** property. The various options available are: + +- **no filter** - would give a plain table, +- **search**  - to include a search by field widget at the top of the data table, wherein the user can select the field on which the search can be performed, +- **multi-column** - to include filter conditions for each column based on the column data type. The condition could start with, ends with, is null etc. etc.. This feature can be disabled for a specific column from the column settings. + +## Sorting + +You can add Sorting capability to a Data Table, thus allowing the end-user to sort the rows, based upon the column/fields of their choice. By enabling this property, every column header becomes clickable which toggles the display order. This can be overridden at the column level. + +In case the underlying Variable has the order by field set, that will be honored with priority given to Data Table sort in case of conflict. + +## Selection + +End-user can also be provided with a way to select rows and columns of a table. + +- Select the first row by default +- Row selection can be either + - single with the display of a radio button or + - multiple with the display of a checkbox. This option is not available for Data Grid with Form layout +- Column selection needs to be further configured using the On Column Select and On Column Deselect events. +- For Quick Edit and Inline Edit, New row position can be specified to be at the bottom or at the top of the Data Table. + +![table-config1](/learn/assets/table-config1.png) + +## Pagination + +Pagination is dividing the set of data rows into discrete pages that will allow users to view data in the form of rows across pages. This should allow for easy navigation across pages for viewing and editing of data. This property depends on the underlying variable configuration. The records to be fetched per request decides the page size of the data table. If the records exceed that limit, then they will be displayed on the next page. + +**Pagination Type**: To make complete use of pagination, the Data Table provides three unique types of pagination. + +### Basic + +This option gives a next and previous arrow along with the page numbers at the right bottom of the page. + +### Classic + +A bar with the total number of pages and number of items on the current page will be displayed along with arrows for pagination. + +### Pager + +This option gives the next and previous buttons at the bottom of the page which when clicked goes forward or backward one row. + +### On Demand + +This option gives flexibility to visualize a large dataset in smaller manageable pages with size configured are displayed at a time and the next page is shown on click of the **View More** button at the end of the table. On the last page, **View Less** button can also be configured to return to the first page. + +- This approach is particularly useful when dealing with datasets that are too large to be displayed all at once, as it helps improve performance, user experience, and readability. + +![table-config2](/learn/assets/table-config1-2.png) + +### Infinite Scroll + +This option is similar to on demand type in all terms except that next page is shown on scroll event not on a button click. + +### None + +No pagination is applied, whole dataset is shown in table at once. + +## Export Data + +The user can Export the Data Table to an Excel or CSV format. This option is available only when the Data Source is a Variable based on database CRUD APIs or a Variable based upon a java service or depending on a query. + +'**Export Data Size**' property on data table specifies the number of records to be exported. Based on the profile settings limit, records are fetched. If you specify an export data size value, records are fetched based on this value. By default, the value is set to 100, the maximum export size. + +To export more than 100 records, the max size in the [profile](/learn/app-development/deployment/configuration-profiles/) needs to be changed from the Project Configurations menu of [Project Workspace](/learn/app-development/wavemaker-overview/product-walkthrough/#project-workspace). + +Only the contents displayed in the Data Table will be exported, as opposed to the contents of the entire underlying database table. For each column selected for display, you can customize the export value using Value Expressions. Value Expression **has** to be set for custom fields. + +![table-config2](/learn/assets/table-config2.png) + +## Message + +Configure various messages to display at different stages of Data Table rendering. For example, configure a message to display when No Data is found or when data is loading. Depending on the selected layout type, the message list will vary. + +You can configure *Messages* for **View More** and **View Less** buttons in Data Table with [On-Demand](#on-demand) and [Infinite Scroll](#infinite-scroll) paginations. + +Message On Error, Message On Add and Message On Update can be configured for CRUD operations in editable grids. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/field-validator.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/field-validator.md new file mode 100644 index 000000000..9b07915f7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/field-validator.md @@ -0,0 +1,319 @@ +--- +title: "Form & DataTable Field Validator Function" +id: "field-validator" +sidebar_label: "Field Validations" +--- +--- + +When creating a form/datatable, you can use Validator Functions to set rules to the form/table. Validation of form/table data is based on the validator type you specify for each field. For each validator type, only a specific set of rules apply. During record submission, the user can modify any input fields that contain invalid data. + +Using Validator Functions, you can apply validations to a single field or multiple fields using methods described in this document. These methods can be used to set sync validations on a field and can include default validators like required, min value, max value, or add more customizations to just basic validations. + +There are three ways to apply Validations on a field; they are: + +- `setValidators` +- `observeOn` +- `setAsyncValidators` + +## setValidators + +WaveMaker provides validators which can be referenced and used in the setValidator method for setting default validations for Form/DataTable fields. This method accepts an array of: + +- Objects for default validators +- Functions for custom validation + +### Object Validators + +These validations also include default validators like required, min value, max value, and more. To apply **required** validation, follow the steps below: + +#### Form +```js +Page.Widgets.formName.formfields.fieldName.setValidators([{ + type: VALIDATOR.REQUIRED, + validator: true, + // Display error message for the form field + errorMessage: "This field cannot be empty." + }]); +``` + +#### Data Table +```js +Page.Widgets.tableName.columns.columnName.setValidators([{ + type: VALIDATOR.REQUIRED, + validator: true, + // Display error message for the table column field + errorMessage: "This field cannot be empty." + }]); +``` + +In the above example, `VALIDATOR` can be accessed from constants service as shown below. + +```js +var VALIDATOR = App.getDependency('CONSTANTS').VALIDATOR; +``` + +### Validator Types + +`VALIDATOR` contains the default validators which can be accessed using the following validator types. + +|Validator | Validator type | +|----|----| +|required | `VALIDATOR.REQUIRED` | +|maxchars | `VALIDATOR.MAXCHARS` | +|minvalue | `VALIDATOR.MINVALUE` | +|maxvalue | `VALIDATOR.MAXVALUE` | +|regexp | `VALIDATOR.REGEXP` | +|mindate | `VALIDATOR.MINDATE` | +|maxdate | `VALIDATOR.MAXDATE` | +|excludedates | `VALIDATOR.EXCLUDEDATES` | +|excludedays | `VALIDATOR.EXCLUDEDAYS` | +|mintime | `VALIDATOR.MINTIME` | +|maxtime | `VALIDATOR.MAXTIME` | + +### Custom Validators using Functions + +These validations can contain custom validations. Follow the steps below to add customizations to the form/table field. + +#### Form + +```js +Page.Widgets.formName.formfields.fieldName.setValidators([lastNameVal]); +``` + +```js +function lastNameVal(field, form) { + if (field.value && field.value.length < 2) { + return { + errorMessage: "Enter your full name." + }; + } +} +``` + +In the above example, `firstNameVal` function accepts field and table as arguments. This function returns an error message if the condition fails. + +#### Data Table + +```js +Page.Widgets.tableName.columns.columnName.setValidators([lastNameVal]); +``` + +```js +function lastNameVal(field, table) { + if (field.value && field.value.length < 2) { + return { + errorMessage: "Enter your full name." + }; + } +} +``` + +In the above example, `firstNameVal` function accepts field and form as arguments. This function returns an error message if the condition fails. + +### Example using Objects and Custom Validator Functions + +#### Form + +In the following example, form `EmployeeForm1` has multiple validations, including email, it should validate regular expression `REGEXP` and should not be empty. + +```js +Page.Widgets.EmployeeForm1.formfields.email.setValidators([emailRequired, { + type: VALIDATOR.REGEXP, + validator: /\w+@\w+\.\w{2,3}/, + errorMessage: "Not a Valid Email" +}]); +``` + +```js +function emailRequired(field, form) { + if (field.value && field.value.length < 1) { + return { + errorMessage: "Email cannot be empty." + }; + } +} +``` + +#### Data Table + +In the following example, data table `EmployeeTable1` has multiple validations, including email, it should validate regular expression `REGEXP` and should not be empty. + +```js +Page.Widgets.EmployeeTable1.columns.email.setValidators([emailRequired, { + type: VALIDATOR.REGEXP, + validator: /\w+@\w+\.\w{2,3}/, + errorMessage: "Not a Valid Email" +}]); +``` + +```js +function emailRequired(field, table) { + if (field.value && field.value.length < 1) { + return { + errorMessage: "Email cannot be empty." + }; + } +} +``` + +:::tip +To watch for validator values, use functions, instead of widget data values. + +In the following example, if validator depends on some other widget value, then return the datavalue using the function and not use widget datavalue directly. + +#### Recommended + +```js +validator:function(){ + return Page.Widgets.date1.datavalue; + } +``` + +#### Not Recommended + +```js +validator:Page.Widgets.date1.datavalue; +``` +::: + +## observeOn + +This validation type observes changes in two or more fields. This method accepts an array of field names. Registering observeOn on a field triggers the field validations whenever there are changes in the observing field values. For example, it notifies whenever there are changes in any of the fields specified in the array. + +### Example for ObserveOn + +In the following example, we are matching password and confirm password. Confirm password field depends on password field value. + +In the following lines of code, we are defining validator for `confirmpassword` field with `confirmPasswordEval` function which observes `password` form field. + +#### Form + +```js +Page.Widgets.EmployeeForm1.formfields.confirmpassword.setValidators([confirmPasswordEval]); +Page.Widgets.EmployeeForm1.formfields.confirmpassword.observeOn(['password']); +``` + +In the following lines of code, it displays an error message if the password and confirm password does not match the values. + +```js +function confirmPasswordEval(field, form) { + if (field.value && form.formfields.password.value != field.value) { + return { + errorMessage: "Password & ConfirmPassword are not the same value" + }; + } +} +``` + +#### Data Table + +```js +Page.Widgets.staticVariable2Table1.columns.confirmpassword.setValidators([confirmPasswordEval]); +Page.Widgets.staticVariable2Table1.columns.confirmpassword.observeOn(['password']); +``` + +In the following lines of code, it displays an error message if the password and confirm password does not match the values. + +```js +function confirmPasswordEval(field, table) { + if (field.value && table.columns.password.value != field.value) { + return { + errorMessage: "Password & ConfirmPassword are not the same value" + }; + } +} +``` + +## setAsyncValidators + +This method on the form field/table can be used to set async validations on the field. This method accepts an array of promises or function returning a promise. + +### Example for setAsyncValidators + +In the following lines of code, we are setting async validation for email field by defining a function called `emailAsync`. + +#### Form + +```js +Page.Widgets.employeeInfoForm3.formfields.email.setAsyncValidators([emailAsync]); +``` + +In the following lines of code, the entered email should not be present in the list of emails that are stored in the database already. + +```js +function emailAsync(field, form) { + if (field.value) { + return new Promise(function(resolve, reject) { + var emailExists = Page.Variables.EmailData.dataSet.filter(function(data) { + if (data.dataValue === field.value) { + return true; + } + }); + if (emailExists.length != 0) { + reject({ + errorMessage: "The email address is already registered." + }); + } + resolve(); + }); + } +} +``` + +#### Table + +```js +Page.Widgets.employeeInfoTable3.columns.email.setAsyncValidators([emailAsync]); +``` + +In the following lines of code, the entered email should not be present in the list of emails that are stored in the database already. + +```js +function emailAsync(field, table) { + if (field.value) { + return new Promise(function(resolve, reject) { + var emailExists = Page.Variables.EmailData.dataSet.filter(function(data) { + if (data.dataValue === field.value) { + return true; + } + }); + if (emailExists.length != 0) { + reject({ + errorMessage: "The email address is already registered." + }); + } + resolve(); + }); + } +} +``` + +## Customizing Error Messages + +Customize form/table field validation error messages using functions, or simply use a string value to display error messages for form/table field validation. + +### Example for Customizing Error Messages + +You can customize error messages to make it more specific to what the user enters. In the following example, the `field.value` is the user-entered value which displays in the error message along with the extended text as shown below. + +#### Form + +```js +errorMessage: function(field, form) { + return field.value + " is not a valid Email."; + } +``` + +#### Data Table + +```js +errorMessage: function(field, table) { + return field.value + " is not a valid Email."; + } +``` + +To use a static message, simply use a string value with your own error message. + +```js +errorMessage: "The entered value is not a valid email address." +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form.md new file mode 100644 index 000000000..341fecbd0 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form.md @@ -0,0 +1,79 @@ +--- +title: "Forms Overview" +id: "form" +sidebar_label: "Forms Overview" +--- +--- + +A form consists of a group of input fields that connects to a datasource such as a table or a query. Using the Form widget, you can enter, edit, or display data from the data source. For example, a simple contact form, registration form, login form, and more. + +Based on your datasource, you can create forms to contain text fields, email, date, dropdown, checkboxes, and more. Plus, you can add validations to the form fields to capture quality and accurate information from the users. + +Additionally, build complex forms that contain multiple data widgets inside a single form, and form inside another form called repeated sections. + +[![form](/learn/assets/Form_run.png)](/learn/assets/Form_run.png) + +## Forms Types + +Use an appropriate type of form to work with different types of datasets. There are two types of forms in WaveMaker; they are **Form** and **Live Form**. + +### Form + +Use **Form** widget to work with a service or procedure based flow. For this, you can use a service variable or CRUD variable through API calls like, REST API, SOAP, and more. You can configure fields to use an appropriate **[Form Widget](/learn/app-development/widgets/widget-library#form-widgets)**. For example, text, number, dropdown, and more. + +### Live Form + +**Live Form** works similar to a **Form**. However, Live Form is specific to database CRUD operations when you import a database from an external resource. + +:::note +Form and Live Form are two different widgets that work similarly. Live Form is used for DB Services with CRUD operations only. For more information, see [Live Forms](/learn/app-development/widgets/datalive/live-form). +::: + +## How do Forms work + + A form contains a group of input fields. Each field binds to the variable metadata that you can configure to the form-field settings. You can design the form to perform business operations and save it to the server. + +### Handling Form Submission Data + +Firstly, to build a form, you should have a dataset. You can use APIs for REST services, java service, and database service. There are multiple ways to build and manage a datasource in WaveMaker. + +You can instantly create a form without even having a dataset ready using a model variable. This helps you to plan and design your form structure. For more information, see [Build a Form](/learn/app-development/widgets/datalive/form/form-usage-scenarios). + +### Layout and styling options + +![form layout selection](/learn/assets/form-layout-selection.png) + +#### Dialog + +You can display form as a dialog. This means the form displays a pop-up when an action occurs. + +#### Inline + +To display form inline with a page. This is the default option. + +#### Align + +Set the alignment of the form. You can choose from the left, center, right, and floating alignments. + +#### Position + +Set the position of the input field and label placement as shown in the image above: {label: field}, {field: label}, {label: field below}. + +#### Layout Style + +Select form layout styles. For example, display form fields in a single column, two columns, or three columns. + +### Configure Form Fields + +![Form field](/learn/assets/selectfield.gif) + +- By default, an appropriate **Form Widget** is assigned to each field. However, you can select a suitable **Form Widget** for a field. +- Field input validation. For example, should the field be a required field, or should it contain a regex expression, or more custom [field validations](/learn/app-development/widgets/datalive/field-validator). + +### Form Actions + +A typical form contains the following Form actions. + +- Reset form field data. For example, to clear entered data, or to start over. +- Allow performing actions. For example, edit, save or submit data, and add a new record. +- Cancel action for Live Form to clear entered-data. \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/calendar.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/calendar.md new file mode 100644 index 000000000..08f9aba74 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/calendar.md @@ -0,0 +1,182 @@ +--- +title: "Calendar" +id: "calendar" +--- + +The **Calendar** widget is the most popular solution for scheduling events on a full-sized calendar in a web application. This widget can be used to show agenda. The calendar will be automatically switched to the Web or Mobile version, based on the device it is being viewed on. + +[![](/learn/assets/calendar_feats.png)](/learn/assets/calendar_feats.png) + +# Features + +## Display Events in the Calendar + +For displaying events in the Calendar widget you need a variable of type _Array_ or an object with single event data. The data **must** contain a field corresponding to Start property, other properties are optional. The expected date format for the value of Start property is a Date Object - ‘YYYY/MM/DD’ or ‘MM/DD/YYYY’ or ‘DD MMMM YYYY’. + +1. Drag and drop a Calendar widget onto the canvas +2. Bind the variable consisting the data to the **Dataset Value** property of the widget. +3. Set the properties _Title_, _Start_, _End_, _All day_, _Class name_ to the keys of the variable bound. :::note +Start property is a must, other properties are optional. +::: +4. **Enable controls** There are five different types of controls on the calendar that can be enabled to: + - navigate between the months, weeks and days, depending on the calendar view + - select current day + - switch the view to Month + - switch the view to Week + - switch the view to Day. +5. **Type** Type can be: + - set as _basic_ - will show the events in a single row, or + - set as Agenda - will show the complete day agenda with hours included. + +## Capturing Events in the Calendar + +The following are the outbound properties of a Calendar widget that can be captured. These values can be captured from JavaScript to be triggered by any Calendar event like _on Select_: + +- _currentview_: gives the start and end values of the current calendar view +- _selecteddata_: gives the entire dataset corresponding to the selected item within the calendar +- _selecteddates_: gives the user selection on the calendar. + +## Configurations for Calendar + +**Views** Calendar comes in three views - Month, Week and Day. + +- The _Month_ view of the Calendar displays all the days in the month. + + + +- The _Week_ view of the Calendar displays all the days in the week. + + + +- The _Day_ view of the Calendar displays all the events on the day. + + + + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the Calendar. Special characters and spaces are not allowed in widget name. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| Height | The height of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. | +| **Events Data** | +| Title | Title for the Event, set from the Dataset fields. | +| Start | Start date or date time for the event, set from the Dataset fields. | +| End | End date or date time for the event, set from the Dataset fields. | +| All day | Whether it is an All day event or not | +| Class name | Display Class to be applied to that event. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Type | This property allows you to set the type of the calendar widget: - agenda, or - basic (default). | +| Enable Controls | This property allows you to enable the header controls for calendar widget. These include - navigation - to navigate previous/next month/week/day(depending upon the display) on the calendar, - today - go to today's location on the calendar, - month - to display entire month, - week - to display entire week, - day - to display entire day. All these controls on the calendar are used to navigate between the months and switch the view to _Month_(or) _Week_ (or) _Day._ **Note:** _This property is shown only for the Web version of the Calendar._ | +| View | This property allows you to set the default view of the calendar widget: - month (default), +- week or - day. | +| Selection Mode | This property can be used to control the user selection of the dates using a simple mouse drag operation. The values can be: - _None_: no selection, the calendar is just there to present data, not to be selected - _Single_: only one row can be selected at a time - _Multiple_: many rows can be selected at a time. | + +## Events + +| Event | Description | +| --- | --- | +| **Callback Events** | +| On Select | This event is triggered when a user selects one or more dates. | +| On View Render | This event handler is triggered when the calendar view is changed. | +| On Event Drop | This event handler is triggered when dragging of an event in calendar stops and the event has moved to a different day/time. | +| On Event Resize | This event handler is triggered when resizing of the event in calendar stops and the event has changed in duration. | +| On Event Click | This event handler is triggered when an event is clicked in the calendar. | +| On Event Render | This event handler is triggered when an event is rendered. | + +## Methods + +To set the properties of the calendar widget through the script, access the properties on the calendar as (consider the calendar with name ‘wmcalendar’) Page.Widgets.wmcalendar.propertyname and change or assign the values accordingly. For example: + +- To set the first day of the month view [Default: 0 (Sunday)]: Page.Widgets.wmcalendar.calendarOptions.calendar.firstDay = 0; +- To hide the all day slot of the agenda view [Default: true]: Page.Widgets.wmcalendar.calendarOptions.calendar.allDaySlot= false; +- To set the text of the all-day slot in the agenda view [Default: ‘all-day’]: Page.Widgets.wmcalendar.calendarOptions.calendar.allDayText= ‘all-day’; + +Other properties which can be set using the similar methods: For more information on Calendar, properties [see here.](https://fullcalendar.io/docs/) + +| Method | Description | +| --- | --- | +| allDaySlot | Determines if the title ("all-day") slot is displayed at the top of the calendar. When false, all-day events will not be displayed in agenda views. | +| allDayText | The text for title ("all-day") slot at the top of the calendar. | +| slotDuration | The frequency for displaying time slots. Default: '00:30:00' (30 minutes) | +| slotLabelFormat | Determines the time-text that will be displayed on the vertical axis of the agenda views. default: 'h(:mm)a' The default English value will produce times that look like "5pm" and "5:30pm". | +| slotLabelInterval | Determines how often the time-axis is labeled with text displaying the date/time of slots. | +| snapDuration | If not specified, this value is automatically computed from slotDuration. With slotDuration's default value of 30 minutes, this value will be 1 hour. | +| scrollTime | Determines how far down the scroll pane is initially scrolled down. default: '06:00:00' (6am). The user will be able to scroll upwards to see events before this time. If you want to prevent users from doing this, use the minTime option instead. | +| minTime | Determines the starting time that will be displayed, even when the scrollbars have been scrolled all the way up. default: "00:00:00" The default "00:00:00" means the start time will be at the very beginning of the day (midnight). | +| maxTime | Determines the end time (exclusively) that will be displayed, even when the scrollbars have been scrolled all the way down. default: "24:00:00" The default "24:00:00" means the end time will be at the very end of the day (midnight). | +| slotEventOverlap | Determines if timed events in agenda view should visually overlap. default: true. When set to true (the default), events will overlap each other. At the most half of each event will be obscured. When set to false, there will be absolutely no overlapping. | +| selectDate() | It highlights the default date given for the calendar. +``` +

Case 1 - datavalue (data/string): If the default value is date object, then that particular date will be highlighted. For example: To select 1st June 2017

Page.Widgets.calendar.datavalue = '01/0/2017';
+Page.Widgets.calendar.selectDate();
+ +

Case 2 - datavalue (Object): If the default value is Object, then the particular dates from start to end date will be highlighted. For example: To select dates from 1st Jan to 10th Jan 2017

Page.Widgets.calendar.datavalue = {start:'01/01/2017', end:'10/01/2017'};
+Page.Widgets.calendar.selectDate();
+``` + | +| gotoDate() | + +It shows the calendar view to default date given for the calendar. For example, to go to a specific date - 1st Jan 2107 + +Page.Widgets.calendar.datavalue='01/01/2017'; +Page.Widgets.calendar.gotoDate(); + + | +| gotoMonth(int) | + +This method renders the present view (i.e. year view will be the same) for the specified month. For example: To view the February month. + +Page.Widgets.calendar.gotoMonth(2); + + | +| gotoNextMonth() | + +This method renders the present view (i.e. year view will be the same) for the next month. For example: To view the next month + +Page.Widgets.calendar.gotoNextMonth(); + + | +| gotoPrevMonth() | + +This method renders the present view (i.e. year view will be the same) for the prev month. For example: To view the prev month + +Page.Widgets.calendar.gotoPrevMonth(); + + | +| gotoNextYear() | + +This method renders the present view (i.e. month/week view will be the same) for the next year. For example: To view the next year + +Page.Widgets.calendar.gotoNextYear(); + + | +| gotoPrevYear() | + + It renders the present view (i.e. month/week view will be the same ) for the previous year. For example: To view the previous year + +Page.Widgets.calendar.gotoPrevYear(); + + | +| rerenderEvents() |  It rerenders the events from the dataset. For example, to get events on the calendar, we use: + +Page.Widgets.calendar.rerenderEvents(); + + | + +## Use Cases + +- [How to create an event and save it in a Database](/learn/how-tos/calendar-usage-create-event/) +- [How to integrate with Google Calendar](/learn/how-tos/calender-usage-google-calendar-integration/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/currency.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/currency.md new file mode 100644 index 000000000..de1c725a3 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/currency.md @@ -0,0 +1,61 @@ +--- +title: "Currency" +id: "currency" +--- + +**Currency **widget is a special text widget to input the currency type data. This widget will change the display format based on the currency type. + + + +# Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for Currency widget. | +| Placeholder | A placeholder is text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the user starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple of the user. | +| Currency | Currency determines which currency symbol should be shown for the currency widget. Choose from the available list. | +| **Accessibility** | +| Hint | Any text you enter for this property will be shown as a tooltip when the mouse hovers over this widget for _1.5 seconds. _It can be bound to a variable or another widget. | +| Tab Index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut Key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)) | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| Minimum Value | Enter minimum number. This property applies when the type is a number. | +| Maximum Value | Enter maximum number. This property applies when the type is a number. | +| Step | Use the stepper to increment/decrement the input value by the specified step interval. Example: if step='3', legal numbers could be -3, 0, 3, 6, etc. | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Read Only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | + +**Shortcut key**: The shortcut key property specifies a shortcut key to click the button. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcutkey Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcut key | +| Chrome | [Alt] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | +| Firefox | [Alt] [Shift] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | + +## Events + +| **Event** | **Description** | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-configurations.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-configurations.md new file mode 100644 index 000000000..f798549bd --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-configurations.md @@ -0,0 +1,35 @@ +--- +title: "Form Configurations" +id: "form-configurations" +sidebar_label: "Configuration" +--- +--- + +The main features of a Form are as follows: + +- **Title** and **Sub Heading** can be set for the Form +- **Default Form Data** can be set to value or bound to another widget like Data Table, List or Live Filter. These define the values to be displayed when the Form is first loaded +- **Dataset Value** defines the Web service API or database API on which the insert or update operations will be performed. This is set to the Variable selected in the data selection step while configuring the Form + +[![](/learn/assets/Form_props1.png)](/learn/assets/Form_props1.png)  [![](/learn/assets/Form_props2.png)](/learn/assets/Form_props2.png)Other **Form Configurations** include: + +- Set** Validation Type **at form level. It can be + - _Default_: here the all failed validation messages will be shown under the corresponding field; + - _HTML_: the HTML validations will be applied and displayed for the first failed field, the validation messages set at the field level will be displayed once the field loses focus; + - _No Validations_: validations will not be performed in this case. +- Define the **Behavior** in terms of + - **Method** to be invoked - _post_, _put_ or _delete_ + - **Action** to be performed in terms of Http request action path + - **Encoding Type** + - **Target** + - Enable **Auto Complete** for the form fields +- **Caption** properties in terms of Alignment, Position, and Size +- Return **Message** configuration - whether inline or toaster, and content for call success and failure cases + +[![](/learn/assets/form_config.png)](/learn/assets/form_config.png)**Form Field Configurations** include Display Properties: + +- Widget Representation, +- Conditional Class Specifications + +[![](/learn/assets/form_field_config.png)](/learn/assets/form_field_config.png)**Form Actions** include default actions of Save and Reset. You can add your own custom actions, if needed.[![](/learn/assets/form_action_config.png)](/learn/assets/form_action_config.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-data-source.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-data-source.md new file mode 100644 index 000000000..f90ed0f2f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-data-source.md @@ -0,0 +1,12 @@ +--- +title: "Form - Data Source" +id: "form-data-source" +sidebar_label: "Data Source" +--- +--- +The first step in configuring a Form is to define the data that needs to be displayed. This data can be in the form of a Variable. + +### Variable Source + +Binding the data will allow you to gather input parameters and invoke a Web Service, Java Service or a Query. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-events-methods.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-events-methods.md new file mode 100644 index 000000000..b701d1045 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-events-methods.md @@ -0,0 +1,89 @@ +--- +title: "Form - Events & Methods" +id: "form-events-methods" +sidebar_label: "Events & Methods" +--- +--- +## Events + +Form behavior can be customized with the help of the call-back events. These events can be accessed from the events tab on the Properties panel. The trigger for the event can be JavaScript, another Variable call etc.. + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| On before submit | This event will be called before submitting the form. Any validation checks can be performed here. Returning false from the script will stop the form submit. | + +We are assuming that Notification Action notificationAction1 is already created. +``` +Page.form1Beforesubmit = function ($event, widget, $data) { + //$data has the data of the all widgets inside the form. This data can be modified and validated before sending the request + + //Validation can be performed here. If validation fails, return false will stop the operation and service call will not be made + if (data.password.length < 6) { + Page.Actions.notificationAction1.invoke({ + "class": "error", + "message": "Password too small", + "position": "center center" + });; + return false; + //Data can be modified before making a service call + $data.dateModified = Date.now(); //Set today's date as modified date field +}; +``` +| Event | Trigger and JavaScript Usage | +| --- | --- | +| On submit | This event will be called on submitting the form. (This is called after ‘on before submit’. If on before submit returns false, this function will not be called). | + +``` +Page.form1Submit = function ($event, widget, $formdata) { +//$formData has the data of the all widgets inside the form. +console.log(“Form data:”, $formdata); +}; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| On result | This event will be called after the form is submitted and API returns a response. This event is triggered in both success and failure cases. | + +``` +Page.form1Result = function ($event, widget, $data) { +//$data has the response returned from the API. +console.log(“server response:”, $data); +}; +``` +| Event | Trigger and JavaScript Usage | +| --- | --- | +| On success | This event will be called after the form is submitted and API returns a success response. | + +``` +Page.form1Success = function ($event, widget, $data) { +//$data has the response returned from the API. +console.log(“The inserted data:”, $data); +}; +``` + +| Event | Trigger and JavaScript Usage | +| --- | --- | +| On error | This event will be called after the form is submitted and API returns a failure response. | + +``` +Page.form1Error = function ($event, widget, $data) { +//$data has the error message returned from the API. +console.log(“Error returned from server:”, $data); +}; +``` + +## Methods + +Form has few methods exposed on widget scope. + +- To submit form: +``` +Page.Widgets.[formName].submit(); +//This method submits the form. +//This method can be used if form is to be submitted from outside of the form. +``` +- To clear messages from the form: +``` +Page.Widgets.[formName].clearMessage(); +//This method removes the success/error message on the form. +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-fields-configuration.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-fields-configuration.md new file mode 100644 index 000000000..a3993c61e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-fields-configuration.md @@ -0,0 +1,63 @@ +--- +title: "Form Fields Configuration" +id: "form-fields-configuration" +sidebar_label: "Fields Configuration" +--- +--- + +## Configure form fields display options + +You can set the display properties of the elements of the Form. + +1. specify the **widget** to be used to represent each data field. Based on the data type of the field, the available widget options would vary. +2. create **custom columns** by clicking on the **'+'** icon. + +:::note +If a custom column is not selected on the left panel, it will be deleted when the Form Designer is saved. +::: + +3. modify the behavior of **individual fields**, from the canvas, by selecting any field on the form and setting the properties: + - The display **Title** for the field - can be bound to another variable, + - **Input Type** to perform on screen validation of the user input, for example, setting the Input Text to email will ensure that the user enters the text in an email id format, + - set the **Default Value** or bind it to a variable + - choose when to **Update the data value** - on _blur_ or on _keypress_ + - set the **Update data value delay** in milliseconds + - additional Validations like **Required**, pattern matching in the form of **Regular Expression** and **Maximum Characters** allowed + - behavior like **Auto Focus**, **Read Only**, **Show** etc can be set. + +[![](/learn/assets/Form_Fields.png)](/learn/assets/Form_Fields.png) + +![image](/learn/assets/form_field_properties.png) +## Form Validations + +There are various ways in which Form fields can be validated depending upon the underlying data type. You can see these options in the properties panel for the selected field on the canvas. + +1. For each field, check **Required** check box to make it as mandatory field while submitting the form, this will issue an error in case the user hits save without making an entry +2. For **Text Type fields**, **Regular expression** field can be used to provide valid and desired formats. +3. For **Text Type fields**, you can restrict the **Maximum characters** to be entered +4. For **Number Type fields**, **Minimum and Maximum Values** permissible can be set +5. For **Date Type fields**, **Min Date, Max Date, Exclude Days and Dates** can be set. In this case, the date picker will not have the invalid dates available for selection. +6. For additional checks, you can use the **On Before Submit** event to perform any validation checks. For example, we want to make sure that the password entry is at least six characters in length. Select the **Events** panel and select Javascript for **On Before Submit** and enter the following code. This will ensure that before updating the data source, the JavaScript is executed. + +```js +Page.form1Beforesubmit = function($data, $event) { + function isValidData($data) { + /*restrict password to be minimum of 6 characters*/ + if ($data.password) { + if ($data.password.length < 6) { + return { + 'error': "Password too small" + }; + } + } else { + return { + 'error': "Password field required" + }; + } + } + return isValidData($data) + }; +``` + +[![](/learn/assets/LF_valid.png)](/learn/assets/LF_valid.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-layouts.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-layouts.md new file mode 100644 index 000000000..77a1d0199 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-layouts.md @@ -0,0 +1,13 @@ +--- +title: "Form - Layouts" +id: "form-layouts" +sidebar_label: "Layouts" +--- +--- + +Form **layout** can be _1-column_, _2-column_ or _3-column_. Apart from this, the **alignment of the caption** for the form fields can be configured to be placed at the _top_, _left_, _right_ or _floating_ of the form fields. + +1. 1-Column Form with left-aligned Captions +2. 2-Column Form with right-aligned Captions +3. 3-Column Form with top-aligned Captions +4. 3-Column Form with floating Captions ([Angular material style](https://material.angular.io/components/form-field/examples)) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-usage-scenarios.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-usage-scenarios.md new file mode 100644 index 000000000..448f4504a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/form-usage-scenarios.md @@ -0,0 +1,112 @@ +--- +title: "Creating Form" +id: "form-usage-scenarios" +sidebar_label: "Creating a Form" +--- +--- + +The **Form** widget has inbuilt functionality to perform **POST & GET operations** on the data source it is bound to. A typical Form set up in WaveMaker has the following steps: + +1. Set the **data source** that the Form will be working on. This takes the form of a variable based on the APIs exposed by [Java Service Integration](/learn/app-development/services/java-services/java-service/) or [Web Service Integration](/learn/app-development/services/web-services/web-services/). +2. Select the display **layout** of the Form. You can choose from one-column, two-column or a three-column layout. +3. Select the **fields** to be available for the user to interact with. All the fields from the selected data source will be presented for selection and assign the display widget for each. + +Drag and drop the **Form** widget onto the page. + +[![](/learn/assets/form_usage_dnd.png)](/learn/assets/form_usage_dnd.png) + +## STEP 1 – Select Data + +There can be different scenarios to deal with when configuring your Form Widget with a data source. The data source can be in the form of a variable based on the APIs exposed by the imported web, java or query service. + +### Scenario 1 + +You do not have any services available in your project. In this scenario, no variables can be created as there are no services available in your project. +1. You will be prompted to import either a database or web service or create a java service. Click the appropriate button to proceed. +2. Once a service is available in your application, you can proceed to bind the widget to data source and follow the same steps as mentioned in scenario 2. + +### Scenario 2 + +There are no variables created for any of the services in your application +1. **Retrieve Data From**: Services is selected by default. If no widgets are placed in the current page, the widgets option will be disabled. +2. Select the **Services** option. +3. **Select a Service**: Select a service from the drop-down which lists the services available in your application. +4. Select the **Table/Entity** of the service which would correspond to the functions, methods or queries for DB services respectively. +5. **Variable Creation**: Once you select the service and Table/Entity for the service, a default variable will be created for you – see the Variable Name field populated by default which will be holding the dataset of the service. You can also change the Variable name. +6. **Data Configuration Options**: You can also set the following Data Configuration options: + - **Update Data on input change**: which is checked on by default. This means that whenever there is a change in the input parameter or filter field of the variable the data will be fetched from the service. This option will have an impact on the app performance. + - **Request data on Page Load**: which is checked on by default. This allows for data to be shown when the page is loaded. If this is not checked, you will not be able to view the data when the page gets loaded. Instead, No Data Found message appears on the widget at runtime. + +### Scenario 3 + +If the database API variables are already created in the project +1. **Retrieve Data From**: Services, Existing Variables or Widgets are the options provided to you for choosing the source of data. +2. Select **Existing Variable.** Note that you can create a new variable if required. +3. **Select a Variable** from the drop-down list of the variables available in the application. You can select the one needed to bind the List Widget to. You can also search for a specific variable by typing in select variable option. If you are able to find your variable in the drop-down select the same. +4. Once you select the variables, it shows the dataset that it is bound to. +5. As Data Configuration options are already set for this variable, you do not see those options in this scenario. + +[![](/learn/assets/form_usage_var.png)](/learn/assets/form_usage_var.png) + +## STEP 2: Layout and Alignment Configuration + +- You can choose to have a _1, 2 or 3-column layout_. +- You can set the _Alignment, Position, and Size_ of the **Caption** for the Form. + +[![](/learn/assets/form_usage_layout.png)](/learn/assets/form_usage_layout.png) + +## STEP 3: Field Configuration + +- The **View As** widget to represent the selected field. The widgets applicable to the field based on the field data type, are available for selection from the drop-down box. +- In the case of a multi-column layout, you can choose the fields to be displayed in the respective columns. You can use the up and down arrows to arrange the fields. + +[![](/learn/assets/form_usage_data.png)](/learn/assets/form_usage_data.png) + +## Using Form to trigger an Insert Query + +We will be seeing how to use a Form to insert values into an Employee table of the hrdb database using Insert Query: + +1. Create a query in database designer with input params + +``` +INSERT INTO EMPLOYEE +(FIRSTNAME, LASTNAME, STREET, CITY, STATE, ZIP, BIRTHDATE, PICURL, JOBTITLE, TENANTID) +VALUES (:firstname, :lastname, :street, :city, :state, :zip, :birthdate, :picurl, :jobtitle, :tenantid) +``` + +2. Provide test values and run and save the query (as InsertEmp). +3. Create a variable by dragging and dropping Form widget and using Create new functionality or by using this query operation from the variable dialog. +4. Select Layout and Configure Fields changing the display name and widget type if needed. Note that if the database API Variable underlying the Form, has to have some input fields the same should be done using the Data tab of the Variable. +5. Your page will look like this in design mode. + +[![](/learn/assets/form_query_design.png)](/learn/assets/form_query_design.png) + +6. Run the app, enter the values and SAVE. + +[![](/learn/assets/form_query_run.png)](/learn/assets/form_query_run.png) + +## Using Form as Filter + +A form can be used as a filter for GET type of API’s. + +Below example is for filtering the data using a query. We will be using the Employee table of the hrdb database to filter on city field. + +1. Create a query in database designer with input params. +``` +SELECT * FROM EMPLOYEE WHERE CITY = :city +``` +2. Provide test values and run and save the query (as EmpByCity). +3. Create a variable using this query operation from the variable dialog or dragging and dropping Form widget and using Create new functionality. +4. Select Layout and Configure Fields changing the display name and widget type if needed. +5. Drag and drop a Data Table onto the canvas and bind it to the Database API Variable created when configuring Form. Your page will look like this in design mode. + +:::note +We have changed the name of the SAVE button to FILTER +::: + +[![](/learn/assets/form_filter_design.png)](/learn/assets/form_filter_design.png) + +6. Run the app, enter the values and FILTER, see the content of the Data Table change. + +[![](/learn/assets/form_filter_run.png)](/learn/assets/form_filter_run.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/select-locale.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/select-locale.md new file mode 100644 index 000000000..1d308f36f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/form/select-locale.md @@ -0,0 +1,85 @@ +--- +title: "Select Locale" +id: "select-locale" +--- + +Localization refers to the tools, techniques, and steps taken to enable your application to run in other languages. WaveMaker allows you to create a  dictionary of localized messages so that users can change the language of the application to experience the application in their language. + +There are three ways that Localization comes into effect: + +1. WaveMaker automatically detects the user's preferred locales (from the browser) and renders the application with the locale of the user's preference if the application supports. If not, displays the application in the default language configured in application settings. +2. The user can be given a choice to select the language using the Select Locale widget. +3. You can also choose to trigger the language switch through user events like button click from JavaScript, the following snippet changes language to English: + + App.changeLocale({'datavalue': 'en'}) + + +## Properties + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for Select Locale widget. | +| Placeholder | A placeholder is text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the user starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple of the user. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)) | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. By default, it is bound to the supportedLocale variable which gets created when [Localization](/learn/how-tos/localization-wavemaker-apps/ "Localization") is enabled. | +| Data field | This property sets the dataValue to be returned by a select editor when the list is populated using the dataSet property. | +| Display field | This property sets the displayValue to show in the select editor when the list is populated using the dataSet property. | +| Display Expression | This is an advanced property that gives more control over what is displayed in the drop-down select list. A Display Expression uses a Javascript expression to format exactly what is shown. | +| Order by | This allows for multiple selections for ordering the display of rows based on fields in asc or desc order - up arrow for asc and down arrow for desc | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Auto Focus | This property makes the element get focused automatically when the page loads. | +| Read Only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Multiple | Enable/Disable to switch between Multiple/Single File Upload Widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | + +## Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. By default, it is set to invoke +1. _changeAppLocale_ which would change the language rendered in the application; and +2. _reloadApp_ event which will reload the app to enable rendering. _If you do not want the app to reload whenever the locale changes remove the reloadApp event._ + + | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | +| **Keyboard Events** | +| On key down | This event handler is called whenever a key is pressed down. | +| On key press | This event handler is called whenever a key is pressed. | +| On key up | This event handler is called whenever a key is released. | + +**Shortcut key**: The shortcut key property specifies a shortcut key to click the button. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcut key Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcut key | +| Chrome | [Alt] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | +| Firefox | [Alt] [Shift] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | + +## Use Cases + +- [Simple Usage Scenario](/learn/app-development/widgets/form-widgets/select-locale-usage/) +- [Localization of Error Messages](/learn/how-tos/localization-error-messages/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list.md new file mode 100644 index 000000000..d806005fc --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list.md @@ -0,0 +1,31 @@ +--- +title: "List Widget" +id: "list" +sidebar_label: "Overview" +--- +--- + +**List widget** provides a list view of items from a data source. List data can be obtained from various Services like database, queries or web services through Variables. The list provides a variety of flexible templates for defining the display format of each item. + +## Features of List Widget + +While designing the List following features can be set: + +- define the number of items to be displayed per row, +- group data by the field of the underlying data source, +- order the data by the fields of the underlying data source, +- set the pagination style for multi-page data, +- enable reorder property can be used to allow the user to reorder the list items at runtime +- enable multiple selections of items in the list, +### For multi-selection +- To select consecutive items, click the first item, press and hold down SHIFT, and then click the last item. Or press and hold down SHIFT, and use arrow keys to select next item. +- To select nonconsecutive items, press and hold down CTRL, and then click each item. +- For mobile: Press and hold the item for a second which enables multi-select then tap on other items to select more items in a List. (default behavior nonconsecutive selection) + +## Select List Items at run-time +list items can be selected by the user at run-time either +- by a simple click of the mouse on the item or +- _Up_ and _Down arrows_ can be used to traverse the list items. Pressing enter key on any focused item will select the item. + +[![](/learn/assets/LL_Features.png)](/learn/assets/LL_Features.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/behavior-settings.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/behavior-settings.md new file mode 100644 index 000000000..1b65fa7be --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/behavior-settings.md @@ -0,0 +1,28 @@ +--- +title: "List - Behavior Settings" +id: "behavior-settings" +sidebar_label: "Behavior Settings" +--- +--- + +## Selection Limit +This property sets the maximum items that can be chosen at run-time. It also determines whether the list can have single or multiple items selected. This property can be bound to a variable to determine the selection limit at run-time. + +## Multiselect +Multiselect will enable users to select multiple list items at runtime. These items can be captured via the _selecteditem_ which will be an array of objects. See Usage Scenarios for more details. + +## Item Reordering +**Enabling reorder** will enable users to reorder the list items at run-time. + +## Disable Item +This property will disable all the events on the item and other widgets present it. + +[![](/learn/assets/cards_behav1.png)](/learn/assets/cards_behav1.png) + +## Touch Events + +Tap, Double Tap, and Long Tap events allow you to set actions associated with the touch events. + +## Selection Limit Exceed + +This event is bound with the **Selection Limit** property that gets invoked when you exceed the count of the maximum items that can be selected in the list. diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/configuration.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/configuration.md new file mode 100644 index 000000000..dec35262d --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/configuration.md @@ -0,0 +1,48 @@ +--- +title: "List - Configuration" +id: "configuration" +sidebar_label: "Configuration" +--- +--- + +## Items per Row + +**Items per row** determine the number to items that can be shown in each row. This can be specified independently for different target devices, from the _device_ tab of the _Properties panel_. + +## Grouping & Ordering + +These include: + +### Group by +Choosing a field from the data source as Group By field, will display collectively the list items which have the same value for that field. +- Each List Group can be collapsed by setting the **Collapsible** property. Thus if you are displaying a list of employees grouped by Department, then a group header will be displayed for each Department. This header when clicked will display the employee list for that Department. By default, each group is expanded. +- Count of list items within the group can be displayed on the group header by setting the **Show count** property. This displays the item count for each group in the header, without the need for writing additional code or query. + +### Group as +This property defines the group-by behavior. The following options are available: +- _alphabet_ – grouped based on the first alphabet of the field +- _word_ – grouped based on the first word of the field +- _TIME_ – grouped based on TIME: hour, day, week, month, year + +### Order by +This property will help to order the list items based upon a field from the data source. You can also set the order as ascending or descending – by clicking on the arrows provided on the side of the field name. + +## Pagination + +Pagination is dividing the set of data rows into discrete pages that will allow users to view data in the form of rows across pages. This should allow for easy navigation across pages for viewing and editing of data. + +**Pagination Type**: To make complete use of pagination, the List provides five unique types of pagination. +- _Basic_ – This option gives a next and previous arrow along with the page numbers at the right bottom of the page. +- _Classic_ - A bar with the total number of pages and number of items in the current page will be displayed along with arrows for pagination. +- _Horizontal Slider_ – This option gives next and previous arrows on both the sides of the page for pagination, carousel style. +- _Pager_ – This option gives the next and previous buttons at the bottom of the page which when clicked goes forward or backward one row. +- _Infinite Scroll_ – In this option on the scroll over the list will cause the next page to load and display. +- _None_ - No pagination option will be given, use this when you want to display single-page records. +- _On Demand_ - allows users to load list items when needed. A '_Load More_' button is displayed at run-time, which on click will load next page records. The label 'Load More' can be configured using 'On Demand Message' property. + +## Message + +**Messages** to be displayed at the time of data loading and in case no data is found can be configured. + +[![](/learn/assets/cards_config-1.png)](/learn/assets/cards_config-1.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-basic-usage.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-basic-usage.md new file mode 100644 index 000000000..355baa782 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-basic-usage.md @@ -0,0 +1,90 @@ +--- +title: "List - Basic Usage" +id: "list-basic-usage" +sidebar_label: "Create a List" +--- +--- + +## Creating Employee List + +You can use the List widget to list data from a database. This post gives you a basic List usage by building an Employee List. + +**Pre-requisites:** + +1. Create a web responsive app +2. Create a page to hold the list + +**Outcome:** + +We will be building the following list: + +[![](/learn/assets/list_basic_run.png)](/learn/assets/list_basic_run.png) + +## Select Data + +There can be different scenarios to deal with when configuring your List Widget with a data source. The data source can be from a service like a Database, web or Java Service or from an another widget on the page. + +- **Scenario 1**: You do not have any services available in your project. + + - You will be prompted to import a service by either [Database Integration](/learn/app-development/services/database-services/working-with-databases/), or [Web Service Integration](/learn/app-development/services/web-services/web-services/), or [Java Service Integration](/learn/app-development/services/java-services/java-service/). Click the appropriate button to proceed. + - Once a service is available in your application, you can proceed to bind the widget to data source and follow the same steps as mentioned in scenario 2 + + [![Screenshot](/learn/assets/list_basic_data1.png)](/learn/assets/list_basic_data1.png) +- **Scenario 2**– There are no variables created for any of the services in your application + + - **Retrieve Data From**: Services is selected by default. + - Select Services option and select the Service Type and Service - here we are using Database CRUD API from hrdb database service. + - Select the **Table/Entity** of the service which would correspond to the entity in case of database service or a method in case of web/java services [![](/learn/assets/list_basic_data2_1.png)](/learn/assets/list_basic_data2_1.png) + - **Variable Creation**: Once you select the service and Table/Entity for the service, a default variable will be created for you – see the Variable Name field populated by default which will be holding the dataset of the service. You can also change the Variable name, if required. + - **Select the Data Node**: You are given the option of choosing either the entire dataset – when you are binding the widget to a data source or any of the fields in the dataset. Select data node tree when binding a single widget or a List item to a field in the dataset. + - **Data Configuration Options**: You also have the option of setting the following Data Configuration options: + - **Records per request**: with an option to enter the number of records to be fetched on each request. The default is 20. For this example, we have set it to 5. + - **Update Data on input change**: which is checked on by default. This means that whenever there is a change in the input parameter or filter field of the variable the data will be fetched from the service. This option will have an impact on the app performance. + - **Request data on Page Load**: which is checked on by default. This allows for data to be shown when the page is loaded. If this is not checked, you will not be able to view the data when the page gets loaded. Instead, No Data Found message appears on the widget at runtime. + + [![](/learn/assets/list_basic_data2_2.png)](/learn/assets/list_basic_data2_2.png) +- **Scenario 3**– If the variables are already created in the project + + - **Retrieve Data From**: Select **Existing Variable.** + - **Select a Variable** from the drop-down list of the variables available in the application. You can select the one needed to bind the List Widget to. You can also search for a specific variable by typing in select variable option. If you are able to find your variable in the drop-down select the same. + - Once you select the variables, it shows the dataset that it is bound to. + - As Data Configuration options are already set for this variable, you do not see those options in this scenario. + + [![](/learn/assets/list_basic_data3_2.png)](/learn/assets/list_basic_data3_2.png) +- **Scenario 4**: Binding to widget + + - **Retrieve Data From**: Select the Retrieve Data From option as Widget that was dragged and dropped onto the canvas of the project. + - **Select a widget** from the drop-down list. This will list the widgets present on this page, you cannot access the widgets from other pages. + - You can **select data node** to be the entire widget or the selecteditem node in case of another Data Table or List or Cards or result from a Live Filter + - As you are not using a Variable the Data Configuration options will not be available. + + [![](/learn/assets/list_basic_data4_1.png)](/learn/assets/list_basic_data4_1.png) + +## Select Template + +In this step, you are expected to select a **template** and **pagination** style suitable for the current use case. For this example, we are choosing _Contact List_ as the template and _Basic_ as pagination style. + +[![](/learn/assets/ll_template.png)](/learn/assets/ll_template.png) + +[![](/learn/assets/ll_pagin.png)](/learn/assets/ll_pagin.png) + +## Binding Data Fields + +- The template selected in the previous step provides a set of widgets that need to be bound to the corresponding field from the data source selected in the first step. +- Select the widget and bind to the corresponding properties like Caption etc. to the fields by selecting the field from the drop-down list. + +[![](/learn/assets/ll_fields.png)](/learn/assets/ll_fields.png) + +## Design View + +From the Canvas, you can further enhance the list design by adding/removing widgets, setting properties etc. + +[![](/learn/assets/list_basic_design.png)](/learn/assets/list_basic_design.png) + +## Run View + +Test Run or Preview the App + +[![](/learn/assets/list_basic_run.png)](/learn/assets/list_basic_run.png) + +[List Use Cases](/learn/app-development/widgets/datalive/list/list-use-cases/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-data-source.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-data-source.md new file mode 100644 index 000000000..7540158ce --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-data-source.md @@ -0,0 +1,28 @@ +--- +title: "List - Data Source" +id: "list-data-source" +sidebar_label: "Data Source" +--- +--- +The first step in configuring a list is to define the data that needs to be displayed. This data can be in the form of Services or Widget or Existing Variable. + +## Variable Source + +Variable binding will allow you to + +- - List data from a database table through Database CRUD Variables; + - List the results from a Web Service, Java Service or a Query; + - List values stored in a Model. + +You can either create a new variable or use existing variables. The behavior of data displayed will be defined by the Variable/Data Configuration properties. These properties are at the Variable level, you can configure them only when creating a new variable; for existing variables the properties set at the time of variable creation will be used. To modify these, you will have to go to variable dialog and make changes. Of particular interest are: + +- _Records per request_ - this is the number of records that will be displayed on a page. Configure the Pagination property to enable user navigation to various pages of data; +- _Update data on input change_ - this property defines when the data displayed will be refreshed. When enabled the data is reloaded whenever the input to the Variable (in the form of filter fields for Live and parameter values for Database APIs Variable) changes; +- _Request data on page load_ - enabling this property will ensure that the data within the data table is loaded at the time of page load. + +## Widget Source + +Widgets can be a source of data in some cases. For example, you might want to display the results from a Live Filter or more details of a selected row/item from a Data Table or another List. Widget option will allow you to achieve this. Selecting Widget as the data source will display the various options available. + +[![](/learn/assets/list_data.png)](/learn/assets/list_data.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-properties-events-methods.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-properties-events-methods.md new file mode 100644 index 000000000..d077ed8df --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-properties-events-methods.md @@ -0,0 +1,222 @@ +--- +title: "List - Properties, Events & Methods" +id: "list-properties-events-methods" +sidebar_label: "Properties, Events & Methods" +--- +--- +## Properties + +| **Event** | **Description** | +| --- | --- | +| Title | Set the title for the List. It is bindable. | +| Sub Heading | This bindable property defines the subheading or title for the list. | +| Name | The name is a unique identifier for the list. | +| **Accessibility** | +| Tab Index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of list can be specified in em, pt, px or % (i.e 50px, 75%). | +| Height | The height of list can be specified in em, pt, px or % (i.e 50px, 75%). | +| **Dataset** | +| Value | Set this bindable property to a variable to populate the list of values to display. | +| Group by | This property allows for grouping the list of rows in the variable bound to a dataset by selecting one of the field names from the drop-down list. | +| Order by | This allows for multiple selection for ordering the display of rows based on fields in asc or desc order - up arrow for asc and down arrow for desc. | +| **Behavior** | +| Enable Reorder | This property will allow users to reorder the list items at runtime. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disable Selection | If this property is set to true (checked), selection of List item won't be allowed at run-time. | +| Selection Limit | This bindable property will allow users to select only a limited number of items. | +| Multiselect | On checking this property users can select multiple items. | +| Select first item | If this bindable property is checked, the first item of the livelist will be selected automatically when the livelist is displayed. | +| **Pagination** | +| Type | Select the pagination type for the list. This property determines how records are fetched. It can be: Basic, Pager, Classic, Infinite Scroll, Horizontal Slider or None | +| Show Total Records | This property controls whether the total record count is displayed in the pagination or not. | +| Align | This property specifies how the paginator should be aligned horizontally: Left, center or right. | +| **Graphics** | +| Loading Icon | This property can assign an icon that is shown while loading list items. | +| Title Icon Class | This property defines the class of the icon that is applied to the list. | +| **Format** | +| Horizontal align | This property specifies how the list should be aligned horizontally: left, center or right. | +| **Message** | +| No data message | This message will be displayed when there is no data to display. It is bindable. | +| Data loading message | This message will be displayed when waiting for data to load. It is bindable. | + +## Events + +| **Event** | **Description** | +| --- | --- | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on the list. | +| On double click | This event handler is called whenever the double click event is triggered on the list. | +| On mouse enter | This event handler is called whenever the mouse enters the list. | +| On mouse leave | This event handler is called whenever the mouse leaves the list. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on the list. | +| On double tap | This event handler is called whenever the double tap event is triggered on the list. | +| **Keyboard Events** | +| Enter Key Press | When the user hits ENTER/Return while the focus is on the list, execute the specified event handler. | +| **Callback Events** | +| On before data render | This event handler is called when the data is set using the pagination. | +| On pagination change | This event handler is called when the page is changed through navigation controls. | +| On reorder | This event is triggered when the item in a list is reordered. For this, the Enable Reorder property has to be set. | +| On selection limit exceed | This event is triggered when selected items cross the value set for the Selection Limit property. | + +## Methods + +The list has few methods exposed on widget scope which can be accessed via JavaScript. For the following script samples, we are considering the hrdb Employee table. EmployeeList is bound to the Live Variable corresponding to the Employee table. + +| **Purpose** | **Usage** | +| --- | --- | +| Clear list data | Clear the list items | + +``` +Page.Widgets.EmployeeList.clear(); +``` +| **Purpose** | **Usage** | +| --- | --- | +| To select a list item | Selects first item, the parameter can be index or object.| + +``` +Page.Widgets.EmployeeList.selectItem(0); +``` + +| **Purpose** | **Usage** | +| --- | --- | +| To deselect item | Deselects first item, the parameter can be index or object. | + +``` +Page.Widgets.EmployeeList.deselectItem(0); +``` + +| **Purpose** | **Usage** | +| --- | --- | +| To change navigation | Changes navigation type to Basic. | + +``` +Page.Widgets.EmployeeList.navigation = ‘Basic’; +``` + +| **Purpose** | **Usage** | +| --- | --- | +| To access widgets within the List | | + +``` +Page.Widgets.EmployeeList.getWidgets(widgetName, index); +//returns the widget you are trying to access +//widgetName: name of the widget which we are trying to access [Required] +//index: zero based index of the list item. [Optional] +``` +The widget returned can be manipulated as any other widget using `$element` property. +``` + Page.Widgets.button1.$element.removeClass('btn-primary'); +//to remove the button primary class +``` +:::note +Returns an array of widgets with the given name inside the list. When the index is provided, only the widget with the given name at the given index will be returned. When the index is not provided, all the widgets with the given name inside the livelist will be returned. +::: + +| **Purpose** | **Usage** | +| --- | --- | +| Modify selected item | selects first item in the list | +``` +Page.Widgets.EmployeeList.selecteditem = 0; +``` + +| **Purpose** | **Usage** | +| --- | --- | +| To change value of currentItem | Sets username field value to ‘Eric’; | + +``` +item.username = ‘Eric’; +//Sets username field value to ‘Eric’; +``` + +:::note +currentItem and currentItemWidgets can’t be accessed through script. But those were given as parameters for events of widgets inside list widget template. currentItem is given as item in the arguments. +::: + +| **Purpose** | **Usage** | +| --- | --- | +| To change caption of username widget for currentItem | Sets caption of Name widget to Eric | + +``` +currentItemWidgets.Name.caption = ‘Eric’; +``` +:::note +currentItem and currentItemWidgets can’t be accessed through the script. But those were given as parameters for events of widgets inside list widget template. currentItem is given as item in the arguments. +::: + +| **Purpose** | **Usage** | +| --- | --- | +| To preserve the reordered list | | + +``` +Page.livelist1Reorder = function ($event, $data) { + //$data is the newly reordered array of items. +}; +``` +:::note +Enable reorder allows the user to change the order of the items in the List in runtime, but the order after reordering do not persist after refresh. _onReorder_ callback event is triggered when the order of the items in the List is changed. In the script, $data parameter has the complete order after each reorder. This data can be used to make the reorder permanent. +::: + +| **Purpose** | **Usage** | +| --- | --- | +| To interact with widgets of selected item | | +``` +Page.Widgets.EmployeeList.selectedItemWidgets[0].Name.caption = ‘Eric’; +//Changes caption for Name widget of selected item to ‘Eric’. +``` +| **Purpose** | **Usage** | +| --- | --- | +| **getIndex**: To find the index of a list item | | + +**Syntax** +``` +Page.Widgets.MyList.getIndex(listItemObject: ListItem); +``` + +**Parameter:** listItemObject: list item object against which the index is required. +**Return:** Index of the passed list item object. + +**Example:** +``` +let i = Page.Widgets.list1.getIndex(Page.Widgets.list1.selecteditem); +``` + +| **Purpose** | **Usage** | +| --- | --- | +| **getItem**: To find the list item object for an index || +**Syntax** +``` +Page.Widgets.MyList.getItem(index: number); +``` +**Parameter:** index: index (zero based) of the list item against which the corresponding list item object is required. +**Return:** list item object. +**Example:** +``` +let item = Page.Widgets.list1.getItem(1); +//returns list item against 2nd index (0 based) +``` + +| **Purpose** | **Usage** | +| --- | --- | +| **getWidget:** | Returns a list of all widgets against a passed widget name. | While designing a list in a WM app, when a widget (with name my_widget) is dropped in the list template, multiple instances of the same widget are created for each list item. In order to access all the instances of a widget, the getWidgets method can be used. | + +**Syntax** +``` +Page.Widgets.Mylist.getWidgets(name: string, [index: number]) +``` +**Parameter** +Name (string): name of the widget in the list template. +Index (number)  [optional]: Index of the list item for which the widget instance is required. +**Return:** Returns a list of all widget instances with the passed name. If index is passed, the list contains only one widget instance against the passed index. + +### Example +``` +let widgetsList = Page.Widgets.MyList.getWidgets(“my_text_widget”); +// If there are 10 list items, the method call will return an array of 10 +instances of widget “my_text_widget” for each list item. +let widget = Page.Widgets.MyList.getWidgets(“my_text_widget”, 4); +// returns an array with one widget instance for 5th list item (zero based index) +``` + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-templates.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-templates.md new file mode 100644 index 000000000..7b1a4699e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-templates.md @@ -0,0 +1,32 @@ +--- +title: "List - Templates" +id: "list-templates" +sidebar_label: "Templates" +--- +--- +List _items _can be displayed using various templates: + +## Action List + +Action List can be used when you need to comment or share or like an item. For example, setting favorites on a List of Albums, to view the details - you can use this as Master List of items and on click of the icon on the left, it can take to a Detail Page. + + + +## Contact List + +Contact List template can be used when you need to list some basic information like List Of Contacts, To-Do List, Tasks List, Products List, List of Employees, etc. + + + +## Email List + +As the name of the template suggests that you can use it to show a list of Emails with some basic details and body of the email. This can be even shown as notifications where only the first few lines of the email body will be shown. This template can also be used for RSS Feeds and Article Feeds + + + +## Media List + +This template can be used to populate basic information about Students, Products, Players, Results, Tutorial Videos etc. This template has a menu option where you can add some menu options to do some actions like add an item, edit or delete. + + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-use-cases.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-use-cases.md new file mode 100644 index 000000000..45b05b802 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/list/list-use-cases.md @@ -0,0 +1,17 @@ +--- +title: "List - Use Cases" +id: "list-use-cases" +sidebar_label: "Use Cases" +--- +--- + +- [Basic Usage - Creating an Employee List](/learn/how-tos/list-basic-usage/) +- [How to group list items](/learn/how-tos/list-grouped/) +- [How to group list items based upon multiple fields](/learn/how-tos/list-multi-grouped/) +- [How to include data table within a list](/learn/how-tos/list-data-table/) +- [How to set partial page content for Accordion within a List](/learn/how-tos/setting-partial-page-content-accordion-within-list/) +- [How to set partial page content for Panel within a List using JavaScript](/learn/how-tos/setting-partial-page-content-panel-within-list-using-javascript/) +- [How to build editable list using live form](/learn/how-tos/building-editable-list/) +- [How to build list from the selected item of another list](/learn/how-tos/building-cascading-lists/) +- [How to access list items](/learn/how-tos/list-item-access/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-filter.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-filter.md new file mode 100644 index 000000000..8f82644d3 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-filter.md @@ -0,0 +1,19 @@ +--- +title: "Live Filter Widget" +id: "live-filter" +sidebar_label: "Overview" +--- +--- + +**Live Filter** provides data filtering UI and functionality. Live Filter can be bound to a data source from the database through the Database CRUD Variable. It returns filtered results which in turn can be bound to any widget. When designing in WaveMaker, Live Filter offers the following features to be configured: + +- filter fields style and display formats, +- specify the range filtering for numeric fields, +- specify the number of records to be filtered, +- filter behavior in case of empty or null results, +- specify the match mode, +- specify a cascading filter, +- different layout styles like 1-column, 2-column or 3-column + +[![](/learn/assets/livefilter_concept.png)](/learn/assets/livefilter_concept.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form.md new file mode 100644 index 000000000..9611ad5ad --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form.md @@ -0,0 +1,22 @@ +--- +title: "Live Form Widget" +id: "live-form" +sidebar_label: "Overview" +--- +--- + +**Live Form** widget provides a columnar group of input elements for user entry. Live Form can be bound to a database through Database CRUD variables and can be used to perform CRUD operations on the underlying database via REST API call. These CRUD APIs are auto-generated at the time of Database Integration. + +Live Form in WaveMaker, when associated with the current `item/selected item/row` of a List or Data Table, provides values for update operations. + +The Live Form fields are auto-generated from the Database CRUD Variable to which it is bound and can be configured to: + +- be represented by appropriate widgets, +- enable field input validation, +- reset form field data; +- perform actions like editing and saving the form fields, adding a new record, and deleting existing record; +- be set as a read-only form and +- different layout styles like 1-column, 2-columns or 3-columns. + +[![](/learn/assets/LiveForm_concept.png)](/learn/assets/LiveForm_concept.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/events-methods.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/events-methods.md new file mode 100644 index 000000000..ec6404fb6 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/events-methods.md @@ -0,0 +1,103 @@ +--- +title: "Live Form - Events & Methods" +id: "events-methods" +sidebar_label: "Events & Methods" +--- +--- + +## Events + +Live Form behavior can be customized with the help of the call-back events. These events can be accessed from the events tab on the Properties panel. The trigger for the event can be JavaScript, another Variable call, and more. + +### `On before service call` + +This event will be called on saving the live form. Any validation checks can be performed here. Returning false from the script will stop the live form save. + +**Example** + +``` +Page.liveform1Beforeservicecall = function($event, $operation, $data) { +//$operation: Current operation being performed - INSERT or UPDATE or DELETE +//$data has the data of the all widgets inside the live form. This data can be modified and validated before sending the request. + function isValidData(data) { + /*restrict password to be minimum of 6 characters*/ + if ($data.password) { + if ($data.password.length < 6) { + return false; + } + } else { + return false; + } + } + return isValidData($data) +}; +``` + +### `On result` +This event will be called after the live form is saved and API returns a response. The event is triggered in both success and failure cases. + +**Example** + +``` +Page.liveform1Result = function($event, $operation, $data) { +//$operation: operation performed - INSERT or UPDATE or DELETE +//$data has the response returned from the API. +console.log("server response:", $data); +}; +``` + +### `On success` +This event will be called after the live form is saved and API returns a success response. + +**Example** + +``` +Page.liveform1Success = function($event, $operation, $data) { +//$operation: operation performed - INSERT or UPDATE or DELETE +//$data has the response returned from the API. +console.log("The inserted/updated/deleted data:", $data); +}; +``` + +### `On error` +This event will be called after the live form is saved and API returns a failure response. + +**Example** +``` +Page.liveform1Error = function($event, $operation, $data) { +//$operation: operation performed - INSERT or UPDATE or DELETE +//$data has the error message returned from the API. +console.log("Error returned from server:", $data); +}; +``` + +## Methods + +Live Form has few methods exposed on widget scope to Edit, Delete, Add record and trigger actions like reset and cancel. + +For the following script samples, we are considering the `hrdb` `Employee` table. **`EmployeeForm** is bound to the `SelectedItem` of a Data Grid corresponding to `Employee` Live Variable. + +### Delete a record +``` +Page.Widgets.EmployeeForm.delete(); //Deletes the current record that is bound to EmployeeForm. +``` + +### Update a record +``` +Page.Widgets.EmployeeForm.save(); //Updates the current record bound +``` + +### Add a new record +``` +Page.Widgets.EmployeeForm.new(); //Adds a new record to dataset that is bound to EmployeeForm. +``` + +### Reset a form +``` +Page.Widgets.EmployeeForm.reset(); //Resets the form to initial state. +``` + +### Cancel an Edit operation +``` +Page.Widgets.EmployeeForm.cancel(); //Cancels the form edit. +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/fields-configuration.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/fields-configuration.md new file mode 100644 index 000000000..847bbcba7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/fields-configuration.md @@ -0,0 +1,73 @@ +--- +title: "Live Form - Fields Configuration" +id: "fields-configuration" +sidebar_label: "Fields Configuration" +--- +--- +## Configure form fields display options + +You can set the following properties of the elements of the Live Form from the **Advanced Settings** properties: + +1. set cascading data, i.e., restrict the display values for the current field based on the value of the field set against** Filter on Field** property. For example, the values displayed in the city field should depend upon the value selected for state field; then correspondingly for city field, filter on field property should be set to state. +2. specify the **widget** to be used to represent each data field. Based on the data type of the field, the available widget options would vary. +3. create **custom columns** by clicking on the **'+'** icon. **Note:** If a custom column is not selected for display, it will be deleted when the Form Designer is saved. +4. modify the behavior of **individual fields**, from the canvas, by selecting any field on the form and setting the properties: + - The display **Title** for the field - can be bound to another variable, + - **Input Type** to perform on screen validation of the user input, for example, setting the Input Text to email will ensure that the user enters the text in an email id format, + - set the **Default Value** or bind it to a variable + - choose when to **Update the data value** - on _blur_ or on _keypress_ + - set the **Update data value delay** in milliseconds + - additional Validations like **Required**, pattern matching in the form of **Regular Expression** and **Maximum Characters** allowed + - behavior like **Auto Focus**, **Read Only**, **Show** etc can be set; + - **filter criteria** can be applied to referenced entities ([see here for usage](/learn/how-tos/using-filter-criteria-data-live-widgets/)). + +[![](/learn/assets/LF_Fields.png)](/learn/assets/LF_Fields.png) + +## Live Form Validations + +There are various ways in which Form fields can be validated depending upon the underlying data type. You can see these options in the properties panel for the selected field on the canvas. + +1. For each field, check **Required** check box to make it as mandatory field while submitting the form, this will issue an error in case the user hits save without making an entry +2. For **Text Type fields**, **Regular expression** field can be used to provide valid and desired formats. +3. For **Text Type fields**, you can restrict the **Maximum characters** to be entered +4. For **Number Type fields**, **Minimum and Maximum Values** permissible can be set +5. For **Date Type fields**, **Min Date, Max Date, Exclude Days and Dates** can be set. In this case, the date picker will not have the invalid dates available for selection. [![](/learn/assets/LF_valid.png)](/learn/assets/LF_valid.png) +6. You can invoke the **hightlightInvalidFields** method on _Save_ action from the Advanced Settings, to highlight all invalid fields in red and display appropriate error messages. [![](/learn/assets/AS_actions_valid.png)](/learn/assets/AS_actions_valid.png) +7. For additional checks, you can use the **Before Service Call** event to perform any validation checks. For example, we want to make sure that the password entry is at least six characters in length. Select the **Events** panel and select Javascript for **Before Service Call** and enter the following code. This will ensure that before updating the data source, the JavaScript is executed. + +``` +Page.liveform1Beforeservicecall = function($data, $event) { + function isValidData($data) { + /*restrict password to be minimum of 6 characters*/ + if ($data.password) { + if ($data.password.length < 6) { + return { + 'error': "Password too small" + }; + } + } else { + return { + 'error': "Password field required" + }; + } + } + return isValidData($data) + }; +``` + + +## Using Widgets for Live Form Fields + +Widgets like select, autocomplete, radioset, checkboxset and switch can be used for various fields within Live Form. These widgets can be used to show the predefined options to the user. + +- When they are limited number of options: **Select**, **Radioset** and **Switch** widgets can be used, +- When number of options are more -  **autocomplete** widget can be used, as user can search from list of available options, +- When multiple options are to be selected - **Checkboxset** and **Select** (with multiple options) widgets are recommended. + +1. Drag and drop a Live Form and bind it to a Database CRUD Variable. +2. Configure layout options, as per your needs. +3. In fields configuration step, change the required field widget type to Select. [![](/learn/assets/lf_widget_fields.png)](/learn/assets/lf_widget_fields.png) +4. Select the field from the canvas. +5. The dataset for the form field widget is auto populated with the Variable Dataset field. Data field and display field is set to field’s key. Here, the dataset value can be bound to any other variable or widget. [![](/learn/assets/lf_widget_propss.png)](/learn/assets/lf_widget_propss.png) +6. The widget can be changed from Live Form Advanced Settings also. [![](/learn/assets/lf_widget_AS.png)](/learn/assets/lf_widget_AS.png) +7. Now, at runtime, the user can use this widget to select a value from predefined options. [![](/learn/assets/lf_widget_run.png)](/learn/assets/lf_widget_run.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/live-form-basic-usage.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/live-form-basic-usage.md new file mode 100644 index 000000000..7a132316b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/live-form-basic-usage.md @@ -0,0 +1,91 @@ +--- +title: "Creating Live Form" +id: "live-form-basic-usage" +sidebar_label: "Creating a Live Form" +--- +--- + +The **Live Form** widget has inbuilt functionality for performing **CRUD operations** on the data source it is bound to. A typical Live Form set up in WaveMaker has the following steps: + +1. Set the **data source** that the Live Form will be working on. This takes the form of a Variable or a selected item from a Widget like a List or a Data Table. +2. Select the display **layout** of the Live Form. You can choose from one-column, two-column or a three-column layout. +3. Select the **fields** to be available for the user to interact with. All the fields from the selected data source will be presented for selection. +4. Form **actions** - Cancel and Save are provided by default with every Live Form. No need to code these functionalities. + +To use a form in your app, drag and drop the **Live Form** widget onto a page. [![](/learn/assets/lf_sel.png)](/learn/assets/lf_sel.png) + +## STEP 1 – SELECT DATA + +There can be different scenarios to deal with when configuring your Live Form Widget with a data source. The data source can be in the form of database CRUD variables or from an another widget, usually Data Table, on the page. + +### Scenario 1 +You do not have any databases available in your project. In this scenario, no variables can be created as there are no services available in your project. + +1. You will be prompted to import either a database or design data model. Click the appropriate button to proceed. +2. Once a service is available in your application, you can proceed to bind the widget to the data source and follow the same steps as mentioned in scenario 2. + + [![](/learn/assets/lf_scenario1.png)](/learn/assets/lf_scenario1.png) + +### Scenario 2 + +There are no variables created on database CRUD in your application. + +1. **Retrieve Data From** Services is selected by default. +2. Select **Services Type** to Database CRUD, this is the only option available. +3. **Select a Service**: Select a service from the drop-down which lists the services available in your application. +4. **Table/entity:** Select the desired Table/entity from the drop down list +5. **Variable Creation**: Once you select the service and Table/entity for the service, a default variable will be created for you – see the Variable Name field populated by default which will be holding the dataset of the service. You can change the Variable name if required. +6. **Select the Data Node**: You are given the option of choosing either the entire dataset – when you are binding the widget to a data source or any of the fields in the dataset. Select data node tree when binding a single widget or a List item to a field in the dataset. +7. **Data Configuration Options**: You also have the option of setting the following Data Configuration options: + - **Records per request**: with an option to enter the number of records to be fetched on each request. The default is 20. + - **Update Data on input change**: which is checked on by default. This means that whenever there is a change in the input parameter or filter field of the variable the data will be fetched from the service. This option will have an impact on the app performance. + - **Request data on Page Load**: which is checked on by default. This allows for data to be shown when the page is loaded. If this is not checked, you will not be able to view the data when the page gets loaded. Instead, No Data Found message appears on the widget at runtime. + + [![](/learn/assets/lf_scenario2.png)](/learn/assets/lf_scenario2.png) + +### Scenario 3 +If the variables are already created in the project. + +1. **Retrieve Data From** to **Existing Variable.** +2. **Select a Variable** from the drop-down list of the variables available in the application. You can select the one needed to bind the List Widget to. You can also search for a specific variable by typing in select variable option. If you are able to find your variable in the drop-down select the same. +3. Once you select the variables, it shows the dataset that it is bound to. +4. As Data Configuration options are already set for this variable, you do not see those options in this scenario. +[![](/learn/assets/lf_scenario3.png)](/learn/assets/lf_scenario3.png) + +### Scenario 4: Binding to widget +1. **Retrieve Data From** Select the source of data as Widget that was dragged and dropped onto the canvas. +2. **Select a widget** from the drop-down list. This will list the widgets present on this page, you cannot access the widgets from other pages. +3. You can **select data node** to be the entire widget or the selecteditem node in case of another Data Table or List or Cards or result from a Live Filter +4. As you are not using a Variable the Data Configuration options will not be available. + +[![](/learn/assets/lf_data.png)](/learn/assets/lf_data.png) + +## Step 2: Layout and Alignment Configuration + +- You can choose to have a _1, 2 or 3-column layout_. +- You can also set the **Mode** as _READ ONLY_ or _EDITABLE_. Read only will be used for display purposes alone, while with an Editable form, the user will be allowed to enter or modify values. +- You can set the _Alignment, Position, and Size_ of the **Caption** for the Form. + +[![](/learn/assets/lf_layout.png)](/learn/assets/lf_layout.png) + +## Step 3: Field Configuration + +- Select the **fields** that have to be displayed in the form +- The **display widget** to represent the selected field. The widgets applicable to the field based on the field data type, are available for selection from the drop-down box. +- In case of a multi-column layout, you can choose the fields to be displayed in the respective columns. You can use the up and down arrows to arrange the fields. + +[![](/learn/assets/lf_field.png)](/learn/assets/lf_field.png) + + +## See Also + +- [How to split live form](/learn/how-tos/live-form-tabbed-form/) +- [How to link live form to another widget](/learn/how-tos/live-form-linking-another-widget/) +- [How to configure related fields in a Live Form](/learn/how-tos/live-form-related-fields/) +- [How to use cascading select and automplete widgets for fields in a Live Form](/learn/how-tos/using-cascading-select-autocomplete-live-form-fields/) +- [How to configure cascading select for fields in a Live Form](/learn/how-tos/using-cascading-select-within-live-form/) +- [How to add master-detail records from the same Live Form](/learn/how-tos/adding-master-detail-records-transaction/) +- [How to use cascaded Live Filter to populate Live Form](/learn/how-tos/using-cascading-filter-populate-live-form/) +- [How to add master-detail records from Live Form using Wizard](/learn/how-tos/using-wizard-master-detail-live-form/) +- [How to progressively add fields to a record using Wizard](/learn/how-tos/using-wizard-progressive-data-entry-live-form/) +- [How to accumulate data over multiple steps in a Wizard and save at the last step](/learn/how-tos/using-wizard-cumulative-data-entry-live-form/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/live-form-data-source.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/live-form-data-source.md new file mode 100644 index 000000000..ea2b04a7c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/live-form-data-source.md @@ -0,0 +1,42 @@ +--- +title: "Live Form - Data Source" +id: "live-form-data-source" +sidebar_label: "Data Source" +--- +--- + +The first step in configuring a Live Form is to define the data that needs to be displayed. This data can be in the form of a Variable or another Widget. + +## Variable Source + +Variable binding will allow you to + +### `Database CRUD` + +Perform CRUD operations on a database through `Database CRUD` variables. + +You can either create a new variable or use existing variables. The behavior of data displayed will be defined by the Variable/Data Configuration properties. These properties are at the Variable level, you can configure them only when creating a new variable. For existing variables, the properties set at the time of variable creation will be used. To modify these, go to the variable dialog and make changes. + +## Modifying the Variable + +### `Records per request` +This is the number of records that will be displayed on a page. Configure the Pagination property to enable user navigation to various pages of data. +### `Update data on input change` +This property defines when the data displayed will be refreshed. When enabled the data is reloaded whenever the input to the Variable (in the form of filter fields for Live and parameter values for Database API Variable) changes; +### `Request data on page load` +Enabling this property will ensure that the data within the data table is loaded at the time of page load. + +### Binding +Under the Data tab of a Variable, you can: + +- Bind input fields with values for `insert`, `delete` and `update`. +- Bind Filter fields with values for `read`. + +[![](/learn/assets/lf_scenario2.png)](/learn/assets/lf_scenario2.png) + +## Widget Source + +Widgets can be a source of data in some cases. For example, you might want to display the results from a Live Filter or more details of a current item/selected row/item from a Data Table or List. Widget option will allow you to achieve this. Selecting Widget as the data source will display the various options available. Widget binding will allow you to show 1-many relationships, for example- Employees of a selected Department list item. + +[![](/learn/assets/lf_data.png)](/learn/assets/lf_data.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/liveform-actions.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/liveform-actions.md new file mode 100644 index 000000000..47d99d568 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/liveform-actions.md @@ -0,0 +1,59 @@ +--- +title: "Live Form - Actions" +id: "liveform-actions" +sidebar_label: "Actions" +--- +--- + +You can define **action buttons** using the **Actions** tab. By default, six actions are provided categorized based upon the behavior of the Form. They are: + +### Edit mode +1. **Cancel** +2. **Save** +3. **Reset** + +:::note +Out of all the actions, the cancel and save actions are pre-selected. +::: + +### View mode +1. **Delete** +2. **Update** +3. **New** + +## Configuring Live Form Actions +For each action button, you can specify the following: + +- **Title** +- **Class** +- Display **icon** +- On-click **Action** + - These can be set for form actions, such as cancel, save and view. + - For navigation events + - API invocation. + +:::note +**Multiple events** can be handled for a single Action. +::: +- **Type** of button + - _submit_ + - _reset_; +- **hidden** to hide the button from the form +- choose an icon to be displayed on the button. + +### How to Trigger Form Actions +The Form Events can be triggered from actions outside the Live Form. For examples, a button placed outside the Live Form template can trigger a form save the event. + +[![](/learn/assets/lf_events.png)](/learn/assets/lf_events.png) + +### Adding a New Action + +New action functionality can be added by clicking on the **ADD** button, against the respective category. Once the action is specified a code snippet will be created in the JavaScript which can be used to code the desired action. The Action will be a JS function as shown below. Here we have written a function to display an alert dialog. The name of the function is the action field entry in the custom button created earlier. + +``` +Page.test = function(){ + alert("hello"); + }; +``` + +[![](/learn/assets/LF_actions.png)](/learn/assets/LF_actions.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/liveform-configurations.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/liveform-configurations.md new file mode 100644 index 000000000..23bdfeb17 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/liveform-configurations.md @@ -0,0 +1,69 @@ +--- +title: "Live Form - Configurations" +id: "liveform-configurations" +sidebar_label: "Configuration" +--- +--- +## Live Form Properties + +You can set the following properties of the Live Form. + +### `Title` +Set the title of the Live Form. + +### `Sub Heading` +Set the sub heading of the Live Form. + +[![](/learn/assets/liveform_props1.png)](/learn/assets/liveform_props1.png)   + +### `Default Value: Form data` +Set the value or bind to another widget like Data Table, List or Live Filter. These define the values that display when the Live Form loads. + +### `Dataset: Value` +Defines the database entity on which the insert or update operations will be performed. This is set to the Variable selected in the data selection step while configuring the Live Form. + +[![](/learn/assets/liveform_props2.png)](/learn/assets/liveform_props2.png) + +### `On Success` +For a Live Form in Dialog mode, the `On Success` event is set to trigger `dialog.close` event. This means, by default, after saving the Form data, the Form dialog will close automatically. You can choose to disable this behavior by removing the `On Success` event. + +[![](/learn/assets/lf_dialog_successevent.png)](/learn/assets/lf_dialog_successevent.png) + + +The other features of a Live Form include: + +### `Validation Type` + +|Validation Type | Description | +|---|---| +|**`Default`** |Here all the failed validation messages will be shown under the corresponding field. | +|**`HTML`** | The HTML validations will be applied and displayed for the first failed field, the validation messages set at the field level will be displayed once the field loses focus.| +|**`No Validations`** | Validations will not be performed in this case.| + +### `Behavior` +Set the **Behavior** to: +- `Editable` or `Read-Only` +- Enable or disable `Auto Complete`. Enabling `Auto Complete` will give suggestions in the form of a drop-down selection box to the user while entering the data at run time. + +[![](/learn/assets/liveform_settings.png)](/learn/assets/liveform_settings.png) + +### `Caption` +Apply caption customizations, including: +- `alignment` +- `position` +- `size` + +### `Message Properties` +For **Layout**, properties include: +- `inline` +- `toaster` + +**Message text** for display, include: +- `error` +- `success` +- `add` +- `update` +- `deletion` + + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/liveform-layouts.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/liveform-layouts.md new file mode 100644 index 000000000..259d43914 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/liveform-layouts.md @@ -0,0 +1,53 @@ +--- +title: "Live Form - Layouts" +id: "liveform-layouts" +sidebar_label: "Layouts" +--- +--- +## Layout Configuration + +### Layouts +Live Form **layouts** include: +1. Column Form with left-aligned Captions +2. Column Form with right-aligned Captions +3. Column Form with top-aligned Captions +4. Column Form with floating Captions ([Angular material style](https://material.angular.io/components/form-field/examples)) + +### Types +The **Types** of live form can be set to the following: +1. `inline`: It can be displayed on the page. +2. `dialog`: It can be displayed as a pop-up dialog. + +### Modes +**Mode** of the Live Form can be set to the following: +1. `editable` +2. `read-only` + +### Alignment of the caption +For form fields, the **alignment of the caption** can be configured to place as following: +1. `top` +2. `left` +3. `right` +4. `floating` + +[![](/learn/assets/lf_layout.png)](/learn/assets/lf_layout.png) + +## Layouts + +### 1. Column Form with left-aligned Captions + + + +### 2. Column Form with right-aligned Captions + + + +### 3. Column Form with top-aligned Captions + + + +### 4. Column Form with floating Captions (Angular material style) + +[![](/learn/assets/liveFormWithThreeCol.png)](/learn/assets/liveFormWithThreeCol.png) + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/liveform-use-cases.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/liveform-use-cases.md new file mode 100644 index 000000000..d12346c2c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/live-form/liveform-use-cases.md @@ -0,0 +1,18 @@ +--- +title: "Live Form - Use Cases" +id: "liveform-use-cases" +sidebar_label: "Use Cases" +--- +--- + +- [Live Form Basic Usage](/learn/app-development/widgets/datalive/live-form/live-form-basic-usage/) +- [How to split live form](/learn/how-tos/live-form-tabbed-form/) +- [How to link live form to another widget](/learn/how-tos/live-form-linking-another-widget/) +- [How to configure related fields in a Live Form](/learn/how-tos/live-form-related-fields/) +- [How to use cascading select and autocomplete widgets for fields in a Live Form](/learn/how-tos/using-cascading-select-autocomplete-live-form-fields/) +- [How to configure cascading select for fields in a Live Form](/learn/how-tos/using-cascading-select-within-live-form/) +- [How to add master-detail records from the same Live Form](/learn/how-tos/adding-master-detail-records-transaction/) +- [How to add master-detail records from Live Form using Wizard](/learn/how-tos/using-wizard-master-detail-live-form/) +- [How to progressively add fields to a record using Wizard](/learn/how-tos/using-wizard-progressive-data-entry-live-form/) +- [How to accumulate data over multiple steps in a Wizard and save at the last step](/learn/how-tos/using-wizard-cumulative-data-entry-live-form/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/filter-configurations.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/filter-configurations.md new file mode 100644 index 000000000..c0389d7f6 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/filter-configurations.md @@ -0,0 +1,25 @@ +--- +title: "Live Filter - Configurations" +id: "filter-configurations" +sidebar_label: "Configuration" +--- +--- + +## Filter Properties + +- You can specify the number of records to be fetched via the **Page Size** property of the Live Filter. By default, this value is set to 20. +- Each of the field in the Live Filter can be selected and properties set. The **Input Type** property can be used to set the type of data user is required to enter. This will enforce basic validations to be performed on the values entered by the user. + +## Filter Advanced Settings + +**Live Filter Settings** can be changed from here. These include: + +- **Auto Complete** and the **Caption** properties of _Align, Position, and Size_. +- _Collapsible_ and _Expanded_ options will allow you to expand and collapse the Live Filter like a panel widget. +- **Empty Filter Options** property can be used to enable '_No Value_' option for select and radioset widgets in **Live Filter**. The various sub-options define the behavior in case No Value is selected by the user. The options are: + - NULL: Filtering on 'No Value' returns null records. + - EMPTY: Filtering on 'No Value' returns empty records. +- **Filter on input change** will trigger the filter automatically when any of the filter field values change. + +[![](/learn/assets/filter_basics.png)](/learn/assets/filter_basics.png) [![](/learn/assets/filter_props-1.png)](/learn/assets/filter_props-1.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/live-filter-basic-usage.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/live-filter-basic-usage.md new file mode 100644 index 000000000..4f2a8ed15 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/live-filter-basic-usage.md @@ -0,0 +1,71 @@ +--- +title: "Live Filter - Basic Usage" +id: "live-filter-basic-usage" +sidebar_label: "Creating a Live Filter" +--- +--- +To add filter capabilities to your app, drag-and-drop the **Live Filter** widget and bind the result from the Live Filter to the desired widget like Data Table or List. + +[![](/learn/assets/lftr_sel.png)](/learn/assets/lftr_sel.png) + +## STEP-1: Select Data + +There can be different scenarios to deal with when configuring your Live Filter Widget with a data source. The data source can be in the form of a variable created from a database CRUD API autogenerated at the time of [Database Integration](/learn/app-development/services/database-services/working-with-databases/) or from an another widget on the page. + +### Scenario 1 +You do not have any database or web services available in your project. In this scenario, no variables can be created as there are no services available in your project. +1. You will be prompted to import a database. Click the appropriate button to proceed. +2. Once a service is available in your application, you can proceed to bind the widget to data source and follow the same steps as mentioned in scenario 2. +### Scenario 2 +There are no variables created for any of the services in your application +1. **Retrieve Data From**: Services is selected by default. If no widgets are placed in the current page, the widgets option will be disabled. +2. Select **Services** option. +3. **Select a Service**: Select a service from the drop-down which lists the services available in your application. +4. Select the **Table/Entity** of the service which would correspond to the entity in case of database service or a method in case of web/java services +5. **Variable Creation**: Once you select the service and table/entity for the service, a default variable will be created for you – see the Variable Name field populated by default which will be holding the dataset of the service. You can change the Variable name. +6. **Select the Data Node**: You are given the option of choosing either the entire dataset – when you are binding the widget to a data source or any of the fields in the dataset. Select data node tree when binding a single widget or a List item to a field in the dataset. +7. **Data Configuration Options**: You also have the option of setting the following Data Configuration options: + +- **Records per request**: There is an option to enter the number of records to be fetched on each request. The default is 20. +- **Update Data on input change**: This option is checked on by default. This means that whenever there is a change in the input parameter or filter field of the variable the data will be fetched from the service. This option will have an impact on the app performance. +- **Request data on Page Load:** It is checked on by default. This allows for data to be shown when the page is loaded. If this is not checked, you will not be able to view the data when the page gets loaded. Instead, No Data Found message appears on the widget at runtime. + +[![](/learn/assets/livefilter_data_new.png)](/learn/assets/livefilter_data_new.png) + +### Scenario 3 +If the variables are already created in the project. + +1. **Retrieve Data From**: Services, Variables or Widgets are the options provided to you for choosing the source of data. +2. Select **Existing Variable.** Note that you can create a new variable if you so desire. +3. **Select a Variable** from the drop-down list of the variables available in the application. You can select the one needed to bind the List Widget to. You can also search for a specific variable by typing in select variable option. If you are able to find your variable in the drop-down select the same. +4. Once you select the variables, it shows the dataset that it is bound to. +5. As Data Configuration options are already set for this variable, you do not see those options in this scenario. + +[![](/learn/assets/lftr_data.png)](/learn/assets/lftr_data.png) + +### Scenario 4: Binding to widget + +1. **Retrieve Data From**: Select the source of data for the widget that was dragged and dropped onto the canvas. Variables or Widgets are the options provided to you for choosing the source of data. +2. **Select a widget** from the drop-down list. This will list the widgets present on this page, you cannot access the widgets from other pages. +3. You can **select data node** to be the entire widget or the selecteditem node in case of another Data Table or List or Cards or result from a Live Filter +4. As you are not using a Variable the Data Configuration options will not be available. + +[![](/learn/assets/livefilter_data_widget.png)](/learn/assets/livefilter_data_widget.png) + +## STEP-2: Layout and Alignment Configuration + +Select the Live Filter **Layout** from _one-column, two-column or three-column_. You can also specify the **Caption** _Alignment, Position, and Size_. + +[![](/learn/assets/lftr_layout.png)](/learn/assets/lftr_layout.png) + +## Field Selection + +Once the data source and layout are selected, you can set the filter **fields**. You can choose the fields to be displayed on the filter by selecting from the list and set the appropriate widget for the fields. Click on the **Done** button. Now your filter is ready. + +[![](/learn/assets/lftr_fields.png)](/learn/assets/lftr_fields.png) + +## See Also + +- [How to Apply Live Filter to a Data Table/Chart](/learn/how-tos/live-filter-applying/) +- [How to build a filtering based upon multiple values](/learn/how-tos/live-filter-multiple-values/) +- [How to build a filtering based upon a range of values](/learn/how-tos/live-filter-range-filter/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/live-filter-data-source.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/live-filter-data-source.md new file mode 100644 index 000000000..9a6334aad --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/live-filter-data-source.md @@ -0,0 +1,26 @@ +--- +title: "Live Filter - Data Source" +id: "live-filter-data-source" +sidebar_label: "Data Source" +--- +--- + +The first step in configuring a Live Filter is to define the data that needs to be filtered upon. This data can be in the form of a Variable or another Widget. + +## Variable Source + +Variable binding will allow you to obtain filter fields from a database through Database CRUD Variables. + +You can either create a variable or use existing variables. The behavior of data displayed will be defined by the Variable/Data Configuration properties. These properties are at the Variable level, you can configure them only when creating a service; for existing variables, the properties set at the time of variable creation will be used. To modify these, you will have to go to [variable dialog](/learn/assets/var_sel.png) and make changes. Of particular interest are: + +### `Records per request` +This is the number of records that will be displayed on a page. Configure the Pagination property to enable user navigation to various pages of data; +### `Update data on input change` +This property defines when the data displayed will be refreshed. When enabled the data is reloaded whenever the input to the Variable in the form of filter fields changes; +### `Request data on page load` +Enabling this property will ensure that the data within the data table is loaded at the time of page load. + +## Widget Source + +Widgets can be a source of data in some cases. For example, to display the results from a Live Filter or more details of a selected row/item from a Data Table or List. Widget option will allow you to achieve this. Selecting Widget as the data source will display the various options available. Widget binding will allow you to show `1-many relationships`. For example, `Employees` of a selected Department list item. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-actions.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-actions.md new file mode 100644 index 000000000..8796fe0d7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-actions.md @@ -0,0 +1,13 @@ +--- +title: "Live Filter - Actions" +id: "livefilter-actions" +sidebar_label: "Actions" +--- +--- + +## Configuring filter actions + +**Actions** to be performed can be mentioned from the **Actions** tab, by default filter and clear buttons are provided. You can add custom actions to your filter. Multiple events can be triggered by a given action. Note: If a custom column/action is not selected, it will be deleted when the Filter Designer is saved. + +[![](/learn/assets/filter_actions.png)](/learn/assets/filter_actions.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-events-methods.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-events-methods.md new file mode 100644 index 000000000..29c9a567a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-events-methods.md @@ -0,0 +1,59 @@ +--- +title: "Live Filter - Events & Methods" +id: "livefilter-events-methods" +sidebar_label: "Events & Methods" +--- +--- + +## Events + +Live Filter behavior can be customized with the help of the call-back events. These events can be accessed from the events tab on the Properties panel. The trigger for the event can be JavaScript, another Variable call etc.. + +### `On before service call` + +This event will be called on Live Filter. Any validation checks can be performed here. Returning false from the script will stop the filtering. + +``` +Page.livefilter1Beforeservicecall = function($data) { + //$data has the data of the all widgets inside the live filter. This data can be modified and validated before sending the request. + $data.tenantid.value = 1; //Values can be set for some specific fields. + }; +``` + + +### `On success` + +This event will be called after API returns a success response. + +``` +Page.livefilter1Success = function($data) { + //$data has the fitlered response returned from the API. + console.log("The filtered data:", $data); + }; +``` + +### `On error` +This event will be called after API returns a failure response. +``` +Page.livefilter1Error = function($data) { + //$data has the error message returned from the API. + console.log("Error returned from server:", $data); +}; +``` + + +## Methods + +Following methods can be used from within the JavaScript to manipulate a Live Filter properties: + +### To filter data +``` +Page.Widgets.DepartmentFilter.formfields.deptId.value = 1; +//Sets the value to filter field deptId to 1 and filters the data. +``` + +### To clear the filter +``` +Page.Widgets.DepartmentFilter.clearFilter();; +//Clears the filter. +``` diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-field-configuration.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-field-configuration.md new file mode 100644 index 000000000..43c034bac --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-field-configuration.md @@ -0,0 +1,27 @@ +--- +title: "Live Filter - Field Configuration" +id: "livefilter-field-configuration" +sidebar_label: "Field Configuration" +--- +--- + +## Configure filter fields display options + +**Filter Fields** can be set from the _Fields_ tab of **Advanced Settings** property. Using this option you can select the columns for display on the Live Filter. Ordering can also be changed by using the buttons at the bottom of the designer window. Further, you can set: + +- **Filter on Field** property can be used to set a cascading filter. For example for the values displayed in the city field should depend upon the state value selected, then for city field, filter on field property should be set to state. +- set the **widget** type to be _text, select, checkboxset or radioset_ and much more. For date-type field, the _date widget_ can be set and the _date pattern_ can be selected +- for numeric fields, it can be a **range filter**, in which case the user has to enter the range of values to set the filter on, +- **Conditional Class** can be specified for each field, similar to the way it is done for columns in a data table. +- You create **custom columns** by clicking on the ‘+’ icon. All the above-mentioned properties are available for custom columns. +- For a field of string type, an additional property called **Match Mode** will define how the filter should be applied. The values can be: + -  _start_ for matching the beginning of the string, + - _end_ for matching the ending of the string, + - _anywhere_ for matching any part of the string, or + - _exact_ for matching the entire string; +- **filter criteria** can be applied to referenced entities for Inline Editable and Quick Edit Data Tables + +([see here for usage](/learn/how-tos/using-filter-criteria-data-live-widgets/)). + +[![](/learn/assets/filter_fields.png)](/learn/assets/filter_fields.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-layouts.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-layouts.md new file mode 100644 index 000000000..675314119 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-layouts.md @@ -0,0 +1,26 @@ +--- +title: "Live Filter - Layouts" +id: "livefilter-layouts" +sidebar_label: "Layouts" +--- +--- + +Live Filter **layout** can be _1-column_, _2-column_ or _3-column_. Apart from this, the **alignment of a caption** for the fields can be configured to be placed on _top_, _left_, _right_ or _floating_ of the filter fields. + +[![](/learn/assets/lftr_layout.png)](/learn/assets/lftr_layout.png) + +### 1-Column Filter with left-aligned Captions: + + + +### 2-Column Filter with right-aligned Captions: + + + +### 3-Column Filter with top-aligned Captions + + + +### 3-Column Filter with floating Captions (Angular material style) + +[![](/learn/assets/liveFilterWithThreeCol.png)](/learn/assets/liveFilterWithThreeCol.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-use-cases.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-use-cases.md new file mode 100644 index 000000000..396b137c6 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/datalive/livefilter/livefilter-use-cases.md @@ -0,0 +1,11 @@ +--- +title: "Live Filter - Use Cases" +id: "livefilter-use-cases" +sidebar_label: "Use Cases" +--- +--- + +- [Basic Usage Scenario](/learn/app-development/widgets/datalive/livefilter/live-filter-basic-usage/) +- [How to Apply Live Filter to a Data Table/Chart](/learn/how-tos/live-filter-applying/) +- [How to build a filtering based on multiple values](/learn/how-tos/live-filter-multiple-values/) +- [How to build a filtering based upon a range of values](/learn/how-tos/live-filter-range-filter/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/design-dialog.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/design-dialog.md new file mode 100644 index 000000000..c180f7225 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/design-dialog.md @@ -0,0 +1,68 @@ +--- +title: "Design Dialog" +id: "design-dialog" +--- + +--- + +[![design_struct](/learn/assets/design_struct.jpg)](/learn/assets/design_struct.jpg) + +## Overview +Dragging and dropping a dialog creates a **view** containing the dialog. The view can be selected from the **Page Structure** or from the **tabs** given at the bottom. The display of the dialog box at runtime is usually associated with the _onClick_ event of a **Button** widget. You can also trigger the dialog by calling methods from _JavaScript_. + +## Design Dialog +Design Dialog gives a **Form** for obtaining additional information from the user, like the name. It is a composite widget with Labels and Text widgets. It comes with two buttons **Cancel **and **Save**. + +[![dialog_form](/learn/assets/dialog_form.png)](/learn/assets/dialog_form.png) + + +## Script Access + +**Dialog** widget in your project can be accessed by associating the open and _close_ properties of the dialog with an event of any other widget. The dialog can be accessed through scripting by adding _DialogService_ to the _page controller_ and adding the code for _open_ and _close_ as shown below, here we are displaying an alert dialog on click of a button: Click event of the button should trigger the following JavaScript code: + +```js +Page.button3Click = function($event, widget) { + Page.Widgets.designdialog1.open(); + } +``` + +For hiding dialog: +```js +/* function called on button1 click */ + Page.button1Click = function($event, widget) { + Page.Widgets.designdialog1.close(); + }; +``` + +## Properties & Events +--- +### Design Dialog Properties + +| Property | Description | +| --- | --- | +| Title | Set the title of the design dialog. | +| Name | The name is a unique identifier for design dialog. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** || +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Show Header | Show/hide header of the design dialog. | +| Modal | This property, if set true, adds a backdrop for the dialog restricting the closure of the dialog when the user clicks outside of the dialog. The default value is false, which allows close of dialog on click outside. | +| **Behavior** | +| Enable Default Close Action | This property allows the user to access close action from header through an "x" icon; and also enables close through ESC key. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. | +| Icon Width | Optional property; but you will need this if you are using the button's iconUrl. Please enter the width of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Height | Optional property; but you will need this if you are using the button's iconUrl. Please enter the height of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | + +### Design Dialog Events + +| Event | Description | +| --- | --- | +| **Callback Events** || +| On close | This event handler is called whenever a close event is triggered. | +| On open | This widget gives a pop-up window. It can be used to give a warning message to the user. For example, you are about to leave this page. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/button-group.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/button-group.md new file mode 100644 index 000000000..6e9c824cd --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/button-group.md @@ -0,0 +1,40 @@ +--- +title: "Button Group" +id: "button-group" +--- +--- + +**Button Group** widget is a container that shows a set of buttons that can be managed and styled as a group. + +The buttons inside the group can be: + +- aligned horizontally or +- vertically. + +## Using Button Group + +Using Button Group, Buttons can exist together as a group. They are great when you need to display a group of actions in a bar. These build off the button styles and work perfectly with the grid. Button group can be used in cases where you have three different behavior upon a single entity. Example for video/audio we have a play, pause, stop operations. In such cases, the button group provides visual groupings of buttons. + +[![](/learn/assets/buttongroup_graphic.jpg)](/learn/assets/buttongroup_graphic.jpg) + +## Properties + +Refer to  [Button widget document](/learn/app-development/widgets/form-widgets/button/) for individual Button features and properties. + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for the Button Group. Special characters and spaces are not allowed in widget name. | +| Add Button | You can choose to add more buttons to the given default three buttons using this control. | +| **Layout** | +| Width | The width of your widget can be specified in _em, pt, px or %_ (i.e 50px, 75%). | +| Vertical | This property determines if the tabs should be vertical. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| **Format** | +| Horizontal Align | This property specifies how the elements should be aligned horizontally. | + +## See More + +[Form Widgets](/learn/app-development/widgets/widget-library/#form) +[Button](/learn/app-development/widgets/form-widgets/button/) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/button.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/button.md new file mode 100644 index 000000000..14b965df2 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/button.md @@ -0,0 +1,128 @@ +--- +title: "Button" +id: "button" +--- +--- +A **button** indicates a possible user action. The button provides a styled clickable UI functionality with arbitrary content to indicate the different states. + +The button widget can trigger any of the following actions when it is clicked. + +- Navigate to another page +- Query a database +- Show or hide a dialog window +- Call a JavaScript function +- Call a web service or Java method + +[![](/learn/assets/button_graphic.jpg)](/learn/assets/button_graphic.jpg) + +## Features + +**Shortcut key**: The shortcut key property specifies a shortcut key to click the button. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcut key Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcut key | +| Chrome | [Alt] + shortcut key (Windows/Linux) | +| | [Control] [Alt] + shortcut key (MAC) | +| Firefox | [Alt] [Shift] + shortcut key (Windows/Linux) | +| | [Control] [Alt] + shortcut key (MAC) | + +### Hide/Show Properties +The business logic of an application often requires a certain button to be temporarily enabled/ disabled. WaveMaker button can be configured to the initially disabled or enabled by checking the show or disabled properties from behavior section. +### Icon image +The button can accommodate an icon, which enhances the meaning of the text content. The widget provides two ways to add an icon with the class name or with a background image i.e image URL (usually a sprite). +### Icon class +In some cases, you may want to use a Button with no text and only an icon inside. You will be provided with two types of icon one is the wavicon and the other is the font awesome icon. +### Icon Url +Image icons are applied via the imageUrl property and are displayed as an img element. + +## Button Class + +From the Style tab of Properties panel,  you can set the button style. You can also use the Conditional Class property to set the class based upon a condition. See here for [How to](/learn/how-tos/use-conditional-class-property/). + + + +## Button Size + +From the Style tab of Properties panel, you can also set the button size along with the style as btn-primary btn-xs + + + + +## Button Properties +--- + +| **Property** | **Description** | +| --- | --- | +| Caption | The caption is the text that the end user sees on the button. This property can be bound to any variable or another widget. | +| Name | The name is a unique identifier for the button. Special characters and spaces are not allowed in widget name. | +| Type | Specify the type of button: - Button: for most click events, - Reset or Submit: for customizing the Form reset and submit functionality | +| Badge Value | Value to be displayed in the badge span for anchor and button. | +| **Accessibility** | +| Hint | Any text you enter for this property will be shown as a tooltip when the mouse hovers over this widget for _1.5 seconds. _It can be bound to a variable or another widget. | +| Tab Index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE:** In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from ```Preferences -> Advanced -> Accessibility``` set the option "Press Tab to highlight each item on a webpage". | +| Shortcut Key | Alphabet to act as the Shortcut key. The shortcut key property specifies a key to click the button. The way to activate the shortcut key varies from browser to browser. | +| **Layout** | +| Width | The width of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| Height | The height of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the widget becomes display-only and user input will not be accepted. It can also set programmatically by binding it to a boolean type variable. | +| Animation | This property controls the animation of an element. The animation is based on the [CSS classes](https://daneden.github.io/animate.css/) and works only in the run mode. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. You can use either Icon class or Icon URL. | +| Icon Url | This optional property allows you to add an icon to the left side of your button. You can give URL of the image. You can use either Icon class or Icon URL. | +| Icon Width | Optional property; but you will need this if you are using the button's iconUrl. Please enter the width of your icon. NOTE: It's best to specify size in pt(points), not percent. | +| Icon Height | Optional property; but you will need this if you are using the button's iconUrl. Please enter the height of your icon. NOTE: It's best to specify size in pt(points), not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | +| Icon Position | Optional property; Property to set the position of icon in the widget - can be left, top or right | +| **Format** | +| Horizontal Align | This property specifies how the elements should be aligned horizontally - left, center or right. | + +## Events +--- +| Event | Description | +| --- | --- | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | It is an HTML button. It is used to generate a click event. For example, save button. | +| On double click | This event handler is called whenever the double click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On Tap | This event handler is called whenever the widget is tapped. | +| On Double Tap | This event handler is called whenever the widget is double tapped. | +| On Long Tap | This event handler is called whenever the long tap event is triggered on a widget.
Note: Long Tap event is only supported in React Native applications.| +| **Keyboard Events** | +| On key down | This event handler is called when the widget is in focus and a key is pressed. | +| On key press | This event handler is called when the widget is in focus and a key is pressed. This event will relay the character pressed | +| On key up | This event handler is called when the widget is in focus and a key is pressed and released. | + +## Use Cases + +- Change button properties from **Markup** +``` + +``` +- To add hint to the given button from the markup +``` + +``` +- Change button properties from **Script**. To Hide button1 use the following code snippet: + +``` +Page.Widgets.button1.setWidgetProperty('show', false); +``` + +- To Capture the show value: + +``` +alert(Page.Widgets.button1.show); +``` + +## See More + +[Form Widgets](/learn/app-development/widgets/widget-library/#form) +[Button Group](/learn/app-development/widgets/form-widgets/button-group) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/calendar.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/calendar.md new file mode 100644 index 000000000..90b92b775 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/calendar.md @@ -0,0 +1,165 @@ +--- +title: "Calendar" +id: "calendar" +--- +--- +The **Calendar** widget is the most popular solution for scheduling events on a full-sized calendar in a web application. This widget can be used to show agenda. The calendar will be automatically switched to the Web or Mobile version, based on the device it is being viewed on. + +[![](/learn/assets/calendar_feats.png)](/learn/assets/calendar_feats.png) + +# Features + +## Display Events in the Calendar + +For displaying events in the Calendar widget you need a variable of type _Array_ or an object with single event data. The data **must** contain a field corresponding to Start property, other properties are optional. The expected date format for the value of Start property is a Date Object - ‘YYYY/MM/DD’ or ‘MM/DD/YYYY’ or ‘DD MMMM YYYY’. + +1. Drag and drop a Calendar widget onto the canvas +2. Bind the variable consisting the data to the **Dataset Value** property of the widget. +3. Set the properties _Title_, _Start_, _End_, _All day_, _Class name_ to the keys of the variable bound. + +:::note +Start property is a must, other properties are optional. +::: +4. **Enable controls** There are five different types of controls on the calendar that can be enabled to: + - navigate between the months, weeks and days, depending on the calendar view + - select current day + - switch the view to Month + - switch the view to Week + - switch the view to Day. +5. **Type** Type can be: + - set as _basic_ - will show the events in a single row, or + - set as Agenda - will show the complete day agenda with hours included. + +## Capturing Events in the Calendar + +The following are the outbound properties of a Calendar widget that can be captured. These values can be captured from JavaScript to be triggered by any Calendar event like _on Select_: + +- _currentview_: gives the start and end values of the current calendar view +- _selecteddata_: gives the entire dataset corresponding to the selected item within the calendar +- _selecteddates_: gives the user selection on the calendar. + +## Configurations for Calendar + +**Views** Calendar comes in three views - Month, Week and Day. + +- The _Month_ view of the Calendar displays all the days in the month. + + + +- The _Week_ view of the Calendar displays all the days in the week. + + + +- The _Day_ view of the Calendar displays all the events on the day. + + + + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the Calendar. Special characters and spaces are not allowed in widget name. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| Height | The height of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. | +| **Events Data** | +| Title | Title for the Event, set from the Dataset fields. | +| Start | Start date or date time for the event, set from the Dataset fields. | +| End | End date or date time for the event, set from the Dataset fields. | +| All day | Whether it is an All day event or not | +| Class name | Display Class to be applied to that event. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Type | This property allows you to set the type of the calendar widget: - agenda, or - basic (default). | +| Enable Controls | This property allows you to enable the header controls for calendar widget. These include - navigation - to navigate previous/next month/week/day(depending upon the display) on the calendar, - today - go to today's location on the calendar, - month - to display entire month, - week - to display entire week, - day - to display entire day. All these controls on the calendar are used to navigate between the months and switch the view to _Month_(or) _Week_ (or) _Day._ **Note:-** _This property is shown only for the Web version of the Calendar._ | +| View | This property allows you to set the default view of the calendar widget: - month (default), - week or - day. | +| Selection Mode | This property can be used to control the user selection of the dates using a simple mouse drag operation. The values can be: - _None_: no selection, the calendar is just there to present data, not to be selected - _Single_: only one row can be selected at a time - _Multiple_: many rows can be selected at a time. | + +## Events + +| Event | Description | +| --- | --- | +| **Callback Events** | +| On Select | This event is triggered when a user selects one or more dates. | +| On View Render | This event handler is triggered when the calendar view is changed. | +| On Event Drop | This event handler is triggered when dragging of an event in calendar stops and the event has moved to a different day/time. | +| On Event Resize | This event handler is triggered when resizing of the event in calendar stops and the event has changed in duration. | +| On Event Click | This event handler is triggered when an event is clicked in the calendar. | +| On Event Render | This event handler is triggered when an event is rendered. | + +## Methods + +To set the properties of the calendar widget through the script, access the properties on the calendar as (consider the calendar with name ‘wmcalendar’) Page.Widgets.wmcalendar.propertyname and change or assign the values accordingly. For example: + +- To set the first day of the month view `[Default: 0 (Sunday)]`: +``` +Page.Widgets.wmcalendar.calendarOptions.calendar.firstDay = 0; +``` +- To hide the all day slot of the agenda view `[Default: true]`: +``` +Page.Widgets.wmcalendar.calendarOptions.calendar.allDaySlot= false; +``` +- To set the text of the all-day slot in the agenda view `[Default: ‘all-day’]`: +``` +Page.Widgets.wmcalendar.calendarOptions.calendar.allDayText= ‘all-day’; +``` + +- To set the Calendar language to English (en) and rerender the Calendar widget. Similarly, you can apply the same code snippet to Internationalize (i18n) by replacing `en` with other i18n codes, such as `es` for the Spanish language. + +```js +Page.Widgets.calendar2.applyCalendarOptions('option', 'locale','en'); +Page.Widgets.calendar2.applyCalendarOptions('render'); +``` + +Other properties which can be set using the similar methods: For more information on Calendar, properties [see here.](https://fullcalendar.io/docs/) + +| Method | Description | +| --- | --- | +| allDaySlot | Determines if the title ("all-day") slot is displayed at the top of the calendar. When false, all-day events will not be displayed in agenda views. | +| allDayText | The text for title ("all-day") slot at the top of the calendar. | +| slotDuration | The frequency for displaying time slots. Default: '00:30:00' (30 minutes) | +| slotLabelFormat | Determines the time-text that will be displayed on the vertical axis of the agenda views. default: 'h(:mm)a' The default English value will produce times that look like "5pm" and "5:30pm". | +| slotLabelInterval | Determines how often the time-axis is labeled with text displaying the date/time of slots. | +| snapDuration | If not specified, this value is automatically computed from slotDuration. With slotDuration's default value of 30 minutes, this value will be 1 hour. | +| scrollTime | Determines how far down the scroll pane is initially scrolled down. default: '06:00:00' (6am). The user will be able to scroll upwards to see events before this time. If you want to prevent users from doing this, use the minTime option instead. | +| minTime | Determines the starting time that will be displayed, even when the scrollbars have been scrolled all the way up. default: "00:00:00" The default "00:00:00" means the start time will be at the very beginning of the day (midnight). | +| maxTime | Determines the end time (exclusively) that will be displayed, even when the scrollbars have been scrolled all the way down. default: "24:00:00" The default "24:00:00" means the end time will be at the very end of the day (midnight). | +| slotEventOverlap | Determines if timed events in agenda view should visually overlap. default: true. When set to true (the default), events will overlap each other. At the most half of each event will be obscured. When set to false, there will be absolutely no overlapping. | +| selectDate() | It highlights the default date given for the calendar. +``` +

Case 1 - datavalue (data/string): If the default value is date object, then that particular date will be highlighted. For example: To select 1st June 2017

Page.Widgets.calendar.datavalue = '01/0/2017';
+Page.Widgets.calendar.selectDate();
+ +

Case 2 - datavalue (Object): If the default value is Object, then the particular dates from start to end date will be highlighted. For example: To select dates from 1st Jan to 10th Jan 2017

Page.Widgets.calendar.datavalue = {start:'01/01/2017', end:'10/01/2017'};
+Page.Widgets.calendar.selectDate();
+``` +||| +|--|--| +| gotoDate() | It shows the calendar view to default date given for the calendar. For example, to go to a specific date - 1st Jan 2107. | + +``` +Page.Widgets.calendar.datavalue='01/01/2017'; +Page.Widgets.calendar.gotoDate(); +``` +||| +|--|--| +| gotoMonth(int) | This method renders the present view (i.e. year view will be the same) for the specified month. For example: To view the February month. ```Page.Widgets.calendar.gotoMonth(2);``` | +| gotoNextMonth() | This method renders the present view (i.e. year view will be the same) for the next month. For example: To view the next month. ```Page.Widgets.calendar.gotoNextMonth();``` | +| gotoPrevMonth() | This method renders the present view (i.e. year view will be the same) for the prev month. For example: To view the prev month. ```Page.Widgets.calendar.gotoPrevMonth();``` | +| gotoNextYear() | This method renders the present view (i.e. month/week view will be the same) for the next year. For example: To view the next year. ```Page.Widgets.calendar.gotoNextYear();``` | +| gotoPrevYear() |  It renders the present view (i.e. month/week view will be the same ) for the previous year. For example: To view the previous year ```Page.Widgets.calendar.gotoPrevYear();``` | +| rerenderEvents() |  It rerenders the events from the dataset. For example, to get events on the calendar, we use: ```Page.Widgets.calendar.rerenderEvents();``` | + +## See Also + +[How to create an event and save it in a Database](/learn/how-tos/calendar-usage-create-event/) +[How to integrate with Google Calendar](/learn/how-tos/calender-usage-google-calendar-integration/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/checkbox.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/checkbox.md new file mode 100644 index 000000000..bd76b2fff --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/checkbox.md @@ -0,0 +1,55 @@ +--- +title: "Checkbox" +id: "checkbox" +--- +--- +A checkbox is a specific type of two-states button that can be either checked or unchecked. Checkboxes let a user select an option. Examples: "_I agree to terms and conditions"_ etc. checked and unchecked options. + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Caption | The caption is the text that the end user sees on the button. This property can be bound to any variable or another widget. | +| Name | The name is a unique identifier for the button. Special characters and spaces are not allowed in widget name. | +| **Accessibility** | +| Hint | Any text you enter for this property will be shown as a tooltip when the mouse hovers over this widget for _1.5 seconds. _It can be bound to a variable or another widget. | +| Tab Index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut Key | Alphabet to act as a Shortcut key. The shortcut key property specifies a key to click the button. The way to activate the shortcut key varies from browser to browser ([see below for details](#shortcut)). | +| **Layout** | +| Width | The width of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| Height | The height of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| Checked Value | This property defines the value of the widget when the element is in the checked state. The default value is boolean value true. If specified, the value will be of string type. | +| Unchecked Value | This property defines the value of the widget when the element is in the unchecked state. | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the widget becomes display-only and user input will not be accepted. It can also set programmatically by binding it to a boolean type variable. | + +**Shortcut key**: The shortcut key property specifies a shortcut key to check the checkbox. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcut key Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcut key | +| Chrome | [Alt] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | +| Firefox | [Alt] [Shift] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | + +## Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | It is an HTML button. It is used to generate a click event. For example, save button. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the widget is tapped. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/checkboxset.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/checkboxset.md new file mode 100644 index 000000000..a05a101e7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/checkboxset.md @@ -0,0 +1,70 @@ +--- +title: "CheckboxSet" +id: "checkboxset" +--- +--- +CheckboxSet allows you to group a set of checkboxes under a common heading. You need to bind to a dataset to display a checkbox for each value. + +[![](/learn/assets/checkboxset_struct.jpg)](/learn/assets/checkboxset_struct.jpg) + +Using the Group By property you can group the items together under a heading. The Show Count property will show the number of items within a group. + +[![](/learn/assets/checkboxset_group.png)](/learn/assets/checkboxset_group.png) + +## Change the layout of CheckboxSet - Vertical or Horizontal + +You can easily change the layout of the options inside the CheckboxSet, so that they are aligned vertifically, horizontally or grouped by a specific number. +**Items per row** determine the number of items that can be shown in each row. This can be specified independently for different target devices, from the _device_ tab of the _Properties panel_. + +[![checkboxset layout](/learn/assets/checkboxset_horizontal.png)](/learn/assets/checkboxset_horizontal.png) + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the button. Special characters and spaces are not allowed in widget name. | +| **Accessibility** | +| Tab Index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in _`em, pt, px`_ or _`% (_i.e _50px, 75%)`._ | +| Height | The height of your widget can be specified in _`em, pt, px`_ or _`% (_i.e _50px, 75%)`._ | +| Layout | This property controls how contained widgets are displayed within this widget container. | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. | +| Use Keys | Use the keys of the live variable object as checkbox set options. | +| Data field | This property sets the dataValue to be returned by a select editor when the list is populated using the dataSet property. | +| Display Field | This property sets the displayValue to show in the select editor when the list is populated using the dataSet property. | +| Display Expression | This is an advanced property that gives more control over what is displayed in the drop-down select list. A Display Expression uses a Javascript expression to format exactly what is shown. | +| Group by | This property allows for grouping the items in the variable bound to the checkboxset dataset by selecting one of the field names from the drop-down list. | +| Group as | This property allows for groups to be displayed under categories. | +| Order by | This allows for multiple selections for ordering the display of rows based on fields in asc or desc order - up arrow for asc and down arrow for desc. | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Behavior** | +| Read only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the widget becomes display-only and user input will not be accepted. It can also set programmatically by binding it to a boolean type variable. | +| Collapsible | Enable control for collapsing and expanding the group. | +| Show Count | To display the number of items within the group. | + +## Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| **Mouse Events** | +| On click | It is an HTML button. It is used to generate a click event. For example, save button. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the widget is tapped. | +| **Callback Events** | +| On ready | This event handler is called when the container is loaded. | + +## See Also + +[Working with Selection Widgets](/learn/how-tos/selection-widgets-use-case/) +[How to use CheckboxSet widget to filter a List](/learn/how-tos/checkboxset-filter-list-data/) + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/chips.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/chips.md new file mode 100644 index 000000000..b6f053c1d --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/chips.md @@ -0,0 +1,196 @@ +--- +title: "Chips" +id: "chips" +--- +--- + +**Chips** represent complex entities in small blocks, such as a contact. Contact chips may represent contact information in a compact way. Chips can be used for various types of entities, including free-form text, predefined text, rules, or contacts. Chips may also contain icons. + +[![chip design](/learn/assets/chips_design.png)](/learn/assets/chips_design.png) + +## Using Chips Widget + +Using Chips widget is a growing trend across social and communication-related apps. This can afford recipient selection using tokenized auto-completing text fields. This kind of UI is more concise than list-based interfaces and more visually rich, intuitive and directly manipulable (manage recipients by touching their token). + +### Where can Chips Widget be used in WaveMaker + +Chips Widget is one of the Form Widgets. It is available to be used as a standalone widget or as a part of Live Forms, Data Entry Dialogs etc. + +## Features + +1. The Chips widget **Value** property can be bound to a dataset of valid values for example, Email Addresses, Hobbies, Skillset, Categories, and more. You can add new values but these new values will not be added to the dataset. +2. It acts as **search/autocomplete** widget. When you starts typing in the Chips widget, it triggers the selection of values from the dataset and shows the corresponding values for the character pressed. +3. **Allow Only Select** (Default: false) - If Allow Only Select is set to true, Chips will restrict adding values other than in the selection. By default, there is no restriction. But note that these new values will not be added to the dataset. +4. **Max Size** (Default: 0) - By default, there is no limit on the number of chips to add. If it set to true, after Max Size is reached the input box to add more will be hidden and will be shown again after some of the elements are deleted. +5. **Enable reorder** property can be used to allow you to reorder the Chip Elements at runtime, using a simple drag and drop operation. +6. Runtime Functionality: You can **navigate** between the chip items using the keyboard right and left keys. Also using the delete/backspace keys the Chip item can be **Deleted**. +7. **Chip item class name** property from the styles tab can be used to apply styles for individual items of the Chip: + 1. a class can be added conditionally when bound to an expression ([see below for use case example](#ex3)), or + 2. class names can be entered (without any condition), these classes will be applied to all the chips. + +### Difference between Search and Chips widget + +1. In Search, you can select only one element, whereas in Chips multiple elements can be selected. +2. In Search, you cannot edit or remove selected items, whereas Chips support these features. + +## Adding a Chip + +1. Search for a field by typing it in the input box. Select the required chip and by clicking on to it or enter key press +2. Enter add chip other than listed items and hit enter that will add to the existing list. +3. If you want to add an item which is not there in the populated list, type the item and press enter. It will be added to the chips list but it will not be added to the dataset. + +## Deleting a Chip + +1. Click on to the cross button of each Chip element. +2. You can also select a Chip element and press the DELETE button. +3. Hitting backspace in the input will select the last Chips element and later deletes it. + +## Reorder Chip Elements + +1. You can drag and drop the element in the required place. + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the chips. Special characters and spaces are not allowed in widget name. | +| Placeholder | A placeholder is a text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the you starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple to enter. | +| **Accessibility** || +| Tab Index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** || +| Width | The width of Chip widget can be specified in em, pt, px or % (i.e 50px, 75%). | +| Height | The height of Chip widget can be specified in em, pt, px or % (i.e 50px, 75%). | +| Input Width | Use this property to set the width of the chip item input box. You can select from: - Default – which is the normal Chip widget size, 170px, or - Full – 100% width of the container | +| **Dataset** || +| Value | Set this property to a variable to populate the list of values to display. Can be bound to a Variable. | +| Search Key | The field from the above Value dataset is based on which the search needs to be performed for fetching Chip Elements for the selection. | +| Picture Source | This property sets the image to be displayed in the search results. Pick from the fields from the above Dataset Value. | +| Data field | This property is useful when the dataSet is an array of objects. It decides the dataValue to be returned by the widget. If set to **All Fields**, the whole object is returned against the selection. If set to a particular field, the returned value will be the value of that field in the selected object. In the case of multi-selection, the returned dataValue will also be an array. | +| Display Field | This property sets the displayValue to show in the select editor when the list is populated using the dataSet property. | +| Display Expression | This is an advanced property that gives more control over what is displayed in the drop-down select list. A Display Expression uses a Javascript expression to format exactly what is shown. | +| Order by | This allows for multiple selections for ordering the display of rows based on fields in asc or desc order - up arrow for asc and down arrow for desc. | +| **Default Value** || +| Value | This is the default value to display value for an editor widget. **NOTE**: the display value is just what the you see initially, and is not the dataValue returned by the widget. | +| **Behavior** || +| Auto Focus | This property makes the Chip to get focus automatically when the page loads. | +| Read only | Selecting this property prevents you from changing the data value of a widget. This property can be bound to a boolean value. | +| Max Size | If the max size is set, chips will restrict adding more than the max size. | +| Input Position | Use this property to change the position of the newly added chip item as - _First_ - The input box appears in the beginning followed by the selected chips - _Last_ – The input box appears at the end of the chip item list, this is the default setting | +| Allow Only Select | If Allow Only Select is set to true, chips will restrict adding values other than in the selection. By default, there is no restriction. | +| Enable Reorder | This property will allow you to reorder the Chip Elements at runtime. This is a bindable property. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and the Show property is bound, the initialization of the widget will be deferred until the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When the Show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the widget becomes display-only and your input will not be accepted. It can also be set programmatically by binding it to a boolean type variable. | +| Min Chars | The minimum number of characters you can enter before the search query is triggered. The value should be greater than 0. The default value is 1. | + +## Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time the chip item value changes. | +| **Mouse Events** | +| On Chip Click | This event handler is called each time the chip item is clicked. | +| **Callback Events** | +| On Before Add | This event gives handle to user whether to continue or abort to add current chip item 1. If the function does not return anything the chip item will be added 2. If the function returns false, then chip item will not be added 3. If the function returns anything other than false, chip item will be added | +| On Add | This event gives a handle on the successful addition of the Chip item. | +| On Before Remove | This event gives handle to user whether to continue or abort removing current chip item 1. If the function does not return anything the chip item will be removed 2. If the function returns false, then chip item will not be removed 3. If the function returns anything other than false, chip item will be removed | +| On Remove | This event gives handle to user on successful removal | +| On Chip Select | This event handler is called each time the chip item is selected. | +| On Before Service Call | This event is triggered before sending the service call for fetching the search results. | +| On Before Reorder | This event gives handle to user whether to continue or abort reordering current chip item 1. If the function does not return anything the chip item will be reordered 2. If the function returns false, then chip item will not be reordered 3. If the function returns anything other than false, chip item will be reordered | +| On Reorder | This event gives a handle on successful reordered in the following form:| + +```js +Page.chips1Reorder = function($event, widget, $data, $changedItem) + +where + +- _$data_ - is the object containing the current chip item data, +- _$changedItem - _gives _newIndex_ and _oldIndex_ specifying the position of the chip item + +``` + +## Use Cases + +### Example 1: Adding contacts and sending Emails + +In this use case, you will be using the chips widget as email recipients and create a UI of Composing an Email. + +[![chips ext](/learn/assets/chips_ex1.png)](/learn/assets/chips_ex1.png) + +Have a database called ProfileDB and a table named Profile with basic fields like first name, last name, job title, email. + +1. Drag and drop the chips widget onto the canvas. +2. Create a variable based on the database CRUD APIs that is bound to Profile Table. [Know more from here](/learn/app-development/variables/database-crud/#). +3. Bind this variable to the dataset value property. +4. Choose Data Field as email +5. Choose Display Field as FirstName +6. Drag and Drop a TextArea Field for composing messages +7. Create a [Java Service for Sending Email](/learn/app-development/services/3rd-party-libraries/using-3rd-party-jar-files/). +8. Create a variable based on the APIs auto-generated for the methods from the Java service. [Know more from here](/learn/app-development/variables/java-services/). +9. From the Data tab, bind the values to those returned by the Chips widget. +10. Drag and Drop a button – Give the caption as Send. On Click of that button trigger the service variable for Java service. + +### Example 2: Use in Live Form + +1. Create two more tables in Profile DB namely Hobbies and Skillsets. Have ID and Name as fields in both. +2. Create a one-to-many relationship between id -  HobbyID +3. Create a Live Form based on a data source – ProfileDB. +4. From Advanced Settings and set the widget property for the fields Hobbies and Skillset to chips and also display expression as Hobbies and Skillset respectively. +5. Now Save and Run the App. You will observe for the Hobbies and Skillsets you are able to enter multiple values. +6. The multiple values will have to be delimited before you save the date in live form. This can be done through scripting.  + 1. Go to the Live Form events tab and for the "On before service call" event + 2. Select JavaScript from the drop-down, and in the script tab, add the code as below. + +```js +Page.liveform1Beforeservicecall = function($event, $operation, $data) { + $data. = $data..join(','); + }; +``` + +### Example 3: Use a conditional class + +1. Import the sample hrdb and create a CRUD Variable for the Employee table. +2. Drag and drop **Chips** widget and bind the Dataset Value property to the HRDB employee variable +3. Set Data field property to **All Fields**, +4. From the **Styles** tab bind the Chip item class name to the following expression: + +```js +bind: item.value.department.name === 'Engineering'? 'skyblue' : 'mustard' +``` + +This will check if the employee's department name is an `Engineering` and applies `skyblue` class, else applies `mustard` class. + +:::note +Here "item" denotes the chip object. +::: + +[![chips example](/learn/assets/chips_ex3_1.png)](/learn/assets/chips_ex3_1.png) + +[![chips example](/learn/assets/chips_ex3_2.png)](/learn/assets/chips_ex3_2.png) + +5. Add the following class to the app using the Style tab – for skyblue and mustard + +```js +.nav.app-chips > li.skyblue .app-chip { + background-color: #50b4dd; + color: white; + font-weight: normal; +} +.nav.app-chips > li.mustard .app-chip { + background-color: #dda950; + color: white; + font-weight: normal; +} +``` + +[![chips example](/learn/assets/chips_ex3_3.png)](/learn/assets/chips_ex3_3.png) + +6. Preview the page + +[![chips example](/learn/assets/chips_ex3_4.png)](/learn/assets/chips_ex3_4.png) + +7. Setting the chip item class name (or Class Name property) as skyblue, will apply skyblue class to all the chips at runtime. + +[![chips example](/learn/assets/chips_ex3_5.png)](/learn/assets/chips_ex3_5.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/color-picker.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/color-picker.md new file mode 100644 index 000000000..9a49e034e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/color-picker.md @@ -0,0 +1,56 @@ +--- +title: "Color Picker" +id: "color-picker" +--- +--- +   +:::note +Color Picker is available only for web responsive apps. +::: + +**Color Picker** widget helps in selecting a color and translate to the hex value. The Color Picker Tool can be used to select a color on any image opened on your screen. By clicking a point on an image, you can change the active color to that which is located under the pointer. + + + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for Color Picker widget. | +| Placeholder | A placeholder is text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the user starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple of the user. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)) | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Behavior** | +| Read Only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | +| Auto Close | This property defines when to close the colorpicker popover. **Outside Click**: picker popover will close when user clicks anywhere outside the picker area. **Always**: picker popover will close when user clicks anywhere on the page. **Disabled**: picker popover will close only when user press enter key on the picker input field.| + +***Shortcut key**: The shortcut key property specifies a shortcut key to click the button. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcut key Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcut key | +| Chrome | [Alt] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | +| Firefox | [Alt] [Shift] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | + +## Events + +| **Event** | **Description** | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On double click | This event handler is called whenever the double click event is triggered on a widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/currency.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/currency.md new file mode 100644 index 000000000..4dc34eb73 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/currency.md @@ -0,0 +1,61 @@ +--- +title: "Currency" +id: "currency" +--- +--- +**Currency** widget is a special text widget to input the currency type data. This widget will change the display format based on the currency type. + + + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for Currency widget. | +| Placeholder | A placeholder is text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the user starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple of the user. | +| Currency | Currency determines which currency symbol should be shown for the currency widget. Choose from the available list. | +| **Accessibility** | +| Hint | Any text you enter for this property will be shown as a tooltip when the mouse hovers over this widget for _1.5 seconds. _It can be bound to a variable or another widget. | +| Tab Index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut Key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)) | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| Minimum Value | Enter minimum number. This property applies when the type is a number. | +| Maximum Value | Enter maximum number. This property applies when the type is a number. | +| Step | Use the stepper to increment/decrement the input value by the specified step interval. Example: if step='3', legal numbers could be -3, 0, 3, 6, etc. | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Read Only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | +| Allow Trailing Zeros | This property specifies whether to keep trailing zeros after decimal point or not.| + +**Shortcut key**: The shortcut key property specifies a shortcut key to click the button. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcutkey Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcut key | +| Chrome | [Alt] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | +| Firefox | [Alt] [Shift] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | + +## Events + +| **Event** | **Description** | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/date-time-datetime.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/date-time-datetime.md new file mode 100644 index 000000000..c1ec76fd7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/date-time-datetime.md @@ -0,0 +1,177 @@ +--- +title: "Date,  Time and  Datetime" +id: "date-time-datetime" +--- +--- + +**Date, Time and Datetime** widgets can be used to capture the date and time-related data from the user. Drag and drop of these widgets result in a composite widget along with a label. + +## Features + +The main **properties** include + +- **Date Pattern** which defines how the date/time/date time is rendered in the UI, and +- **Output Pattern** defines the format of output data value returned by these widgets. +- **Hour Step and Minute Step** defines the time picker UI for the time and datetime widgets. +- For date and datetime widgets, **Min Date, Max Date, Exclude Days and Dates** can be set. In this case, the date picker will not have the invalid dates available for selection. + +The following tables show the behavior in various scenarios: _Date Patterns_: [![](/learn/assets/date_patterns.png)](/learn/assets/date_patterns.png) + +_Time Patterns_: [![](/learn/assets/time_patterns.png)](/learn/assets/time_patterns.png) + +_Datetime Patterns_: [![](/learn/assets/datetime_patterns.png)](/learn/assets/datetime_patterns.png) + +**Note**: For Time and Datetime widgets the time picker UI based on the time pattern given. For example, if the pattern is ‘hh:mm:ss a’, seconds and AM/PM pattern is displayed in time picker. If the pattern is ‘HH:mm’, 24Hr format is shown. Seconds and AM/PM are not displayed in time picker. + +## Properties + +### Date Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for Date widget. | +| Placeholder | A placeholder is text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the user starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple of the user. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)) | +| **Layout** | +| Width | The width of your widget can be specified in _px_ or _% (_i.e _50px, 75%)._ | +| **Default Value** | +| Value | This is the default value to display value for an editor widget, it can be set to current date. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Display Format** | +| Date Pattern | Date pattern lets you override how dates are displayed. Common options are 'dd-MMMM-yyyy', 'yyyy/MM/dd'. | +| **Output** | +| Output Format | Defines the format of output datavalue returned by the date widget. Default output format is 'yyyy-MM-dd', which returns the equivalent data value. E.g data value for '19/06/2015' is '2015-06-19'. If the output format is given as 'MMM dd, yyyy', widget returns datavalue as 'Jun 19, 2015'. | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| Min Date | Enter a minimum date. The dates before this will not be shown in the date picker. The field is bindable. | +| Max Date | Enter a maximum date. The dates after this will not be shown in the date picker. The field is bindable. | +| Exclude Days | Select days which are to be excluded from the selection from the date picker. | +| Exclude Dates | Accepts string and a variable containing dates which will be excluded from the selection from the date picker. | +| **Behavior** | +| Show DatePicker on | Using this property you can control the visibility of the Date Picker. You can choose to open it on: - input click and button click (default setting), or - only on button click. | +| Show Week Number | When set, week number will be displayed in the date picker UI. | +| Auto Focus | This property makes the element get focused automatically when the page loads. | +| Read Only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | + +### Datetime Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for Date widget. | +| Placeholder | A placeholder is text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the user starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple of the user. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)) | +| **Layout** | +| Width | The width of your widget can be specified in _px_ or _% (_i.e _50px, 75%)._ | +| **Default Value** | +| Value | This is the default value to display value for an editor widget, it can be set to current date. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Display Format** | +| Date Pattern | Date pattern lets you override how dates are displayed. Common options are 'dd-MMMM-yyyy', 'yyyy/MM/dd'. | +| Hour Step | Number of hours to increase or decrease. | +| Minute Step | Number of minutes to increase or decrease. | +| **Output** | +| Output Format | Defines the format of output datavalue returned by the date time widget. Default output format is 'timestamp', which returns the equivalent timestamp integer. E.g timestamp value for '2012-12-12 12:12 PM' is '1355294520000'. If the output format is given as 'yyyy-MM-dd hh:mm a', widget returns datavalue as '2012-12-12 12:12 PM'. | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| Min Date | Enter a minimum date. The dates before this will not be shown in the date picker. The field is bindable. | +| Max Date | Enter a maximum date. The dates after this will not be shown in the date picker. The field is bindable. | +| Exclude Days | Select days which are to be excluded from the selection from the date picker. | +| Exclude Dates | Accepts string and a variable containing dates which will be excluded from the selection from the date picker. | +| **Behavior** | +| Show DateTimePicker on | Using this property you can control the visibility of the DateTime picker. You can choose to open it on: - input click and button click (default setting), or - only on button click. | +| Show Week Number | When set, week number will be displayed in the date picker UI. | +| Auto Focus | This property makes the element get focused automatically when the page loads. | +| Read Only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | + +### Time Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for Date widget. | +| Placeholder | A placeholder is text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the user starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple of the user. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)) | +| **Default Value** | +| Value | This is the default value to display value for an editor widget, it can be set to current date. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Display Format** | +| Time Pattern | Time pattern lets you override how time is displayed. Common options are 'hh-mm-ss'. | +| Hour Step | Number of hours to increase or decrease. | +| Minute Step | Number of minutes to increase or decrease. | +| **Output** | +| Output Format | Defines the format of output data value returned by the time widget. Default output format is 'timestamp', which returns the equivalent timestamp integer. E.g timestamp value for '10:10:00 AM' is '16800000'. If the output format is given as 'hh:mm a', widget returns data value as '10:10 AM'. | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Show TimePicker on | Using this property you can control the visibility of the Time picker. You can choose to open it on: - input click and button click (default setting), or - only on button click. | +| Auto Focus | This property makes the element get focused automatically when the page loads. | +| Read Only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | + +**Shortcut key**: The shortcut key property specifies a shortcut key to click the button. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcut key Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcut key | +| Chrome | [Alt] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | +| Firefox | [Alt] [Shift] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | + +## Events + +### Date Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | + +### Datetime Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | + +### Time Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/file-upload-basic-usage.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/file-upload-basic-usage.md new file mode 100644 index 000000000..6028f88d5 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/file-upload-basic-usage.md @@ -0,0 +1,19 @@ +--- +title: "FileUpload - Basic Usage" +id: "file-upload-basic-usage" +--- + +1. Drag and drop a **FileUpload** widget onto the canvas. +2. You will be prompted to create a _FileServiceUploadFile_ Variable. For this demo purpose, retain the default selections of _Update data on input change_. **NOTE**: You can create and use any service, but keep in mind that the operation selected should be able to accept file data. The default file service _uploadFile_ operation fulfills this requirement. [![](/learn/assets/fu_servicevar.png)](/learn/assets/fu_servicevar.png) +3. From the Properties panel, set the **Multiple** property to true, this will enable us to upload multiple files, else you can upload a single file at a time. [![fu_props](/learn/assets/fu_props.png)](/learn/assets/fu_props.png) +4. Run the app, select files to upload [![fu_run](/learn/assets/fu_run.png)](/learn/assets/fu_run.png) + +[FileUpload Use Cases](/learn/app-development/widgets/basic/fileupload-use-cases/) + +- [1. FileUpload Basic Usage](/learn/app-development/widgets/form-widgets/file-upload-basic-usage/) +- [2. How to use various file service operations](/learn/how-tos/file-upload-widget-operations/) +- [3. How to save uploaded file to a DB](/learn/how-tos/upload-file-save-database/) +- [4. How to upload BLOB file to a DB](/learn/how-tos/file-upload-blob-data/) +- [5. How to upload file to custom directory](/learn/how-tos/file-upload-custom-directory/) +- [6. How to uploaded files from Java code](/learn/how-tos/accessing-file-upload-java-code/) +- [7. How to use FileUpload in Form and Live Form](/learn/how-tos/upload-files-from-live-form-form/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/file-upload.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/file-upload.md new file mode 100644 index 000000000..d8ab647e3 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/file-upload.md @@ -0,0 +1,82 @@ +--- +title: "FileUpload" +id: "file-upload" +--- +--- +The FileUpload widget can be used to let users upload files to your apps. WaveMaker **FileUpload** widget generates a **Java Service** to enable additional file processing functionality. + +## Features + +Following properties can be set for a **FileUpload** widget: + +- **Multiple** to allow multiple selections for FileUpload, Message to be displayed in case of Multiple FileUpload, +- **Allowed File Extensions** can be selected from the _list_ (multiple selections are allowed), or _bound to space separated file extensions list_ prefixed with dots Ex: '.html .css .tiff' +- **Max File Size** of files allowed for upload can be specified in MB, default being 1MB. The max allowed limit is 50MB. +- A **Java Service** will be created with default methods and service variables. These methods contain the basic functionality related to upload, list, delete and download. You can customize the code as per your requirements. You need to create service variables to invoke these methods. +- **Mode** to _Upload_ which will upload the file or _Select_ which will select the file but not upload; Upload is the mode set by default. + - Drag and drop of a FileUpload widget creates a service variable, **FileServiceUploadFile** by default. The service for this variable is set to the Java FileService and the operation as uploadFile. This variable will have a file field in data tab which would be bound to the file select widget by default. Additionally, the relativePath can be set, if the value is set as ‘files’ then the file will be uploaded to ‘/resources/uploads/files’. + - By default, the On Select event of the FileUpload widget will be bound to the above mentioned Service Variable. In run mode, as the user selects the file, the Service Variable kicks in and the upload action is triggered. + - By deleting the Variable from the widget (from the On Select Event), the Widget can be set to Select mode. In this mode, the widget will act as a file selector with no additional modes. There will be no service or operation selection on the widget and hence it will not trigger the upload action internally. + +[![](/learn/assets/fu_feats.png)](/learn/assets/fu_feats.png) + +### Clear Uploaded Files from UI + +Clear the list of uploaded files from the UI (user interface). For this, you can add the following properties: +1. Choose an icon or use a default one. +2. Write a hint description on mouse-over. + +**cleariconclass**: Set the class name for the Clear icon, choosing from the [icons](/learn/app-development/widgets/basic/icon). The default value of the property is `wi wi-clear`. To change the default icon, configure the property from the **Markup** tab or by using the exposed method `setClearIconClass`. + +**cleariconhint**: You can set the hint property to show a text message when you mouse-over the icon. The default value is set to the text *`Clear`*. To change the default hint text, configure the property from the **Markup** tab or by using the exposed method `setClearIconHint(hint)`. + +**clear()**: Call the `clear()` method to remove the uploaded files from the UI - all at once. + +![file upload clear](/learn/assets/file-upload-clear.png) + +## Properties + +| Property | Description | +| --- | --- | +| Caption | The caption is the text that the end user sees on your label. | +| Name | The name is a unique identifier for FileUpload widget. | +| **Accessibility** || +| Hint | Any text or html you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** || +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| **Behavior** || +| Multiple | Enable/Disable to switch between Multiple/Single FileUpload Widget. | +| Message | Message text for file upload while in multi-select mode | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | +| Allowed File Extensions | Select the default filter file type in file choose option. It can be bindable to a string having comma separated extensions. Example: '.pdf, .doc, .gif'. | +| Max File Size | If the max file size is set, file upload will restrict the files more than max file size. Default Max file size is 1MB, it can be set up to 50MB. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. By default, it is set to _wi wi-file-upload_ | +| **Format** | +| Horizontal Align | This property specifies how the elements should be aligned horizontally. | + +## Events + +| Event | Description | +| --- | --- | +| **Callback Events** || +| On Before Select | This event handler is called before the upload of the file. It can be used to perform any validations before the file is further processed. | +| On Select | This event handler is called when the files are selected. By default, it invokes the Service Variable to upload the selected files. Deleting this variable will set the FileUpload to act as a file selector. | + +Apart from the above events attached to the FileUpload widget, the following Service Variable events are invoked after the upload of the files. + +| Event | Description | +| --- | --- | +| **Callback Events** || +| On Abort | These events will appear only for the Service Variables targeting an upload service. | +| On Before Update | These events are called just before the variable is triggered to hit the target service. “inputData” contains an object having key-value pairs of input fields (that appear under the “Data” tab of Variable definition dialog). The call to the target service from the variable can be prevented by assigning a JavaScript function to this event and returning false from this function. If input data needs modification or validation, it should be done at this place. | +| On Result | This event is triggered as soon as the variable receives a response from the target service. onResult is called whether or not there was an error generated. An additional last argument as the “operation-name” that holds the invoked operation is present for Database CRUD Variables. | +| On Progress These events will appear only for the Service Variables targeting an upload service. | A progress bar is displayed below the file selector, this is handled by file widget. User can perform actions on the onProgress event. However, the default progress bar shown is not hidden on providing a handler to this event. | +| On Error | This event is called if there is an error generated during the Service call. An additional last argument as the “operation-name” that holds the invoked operation is present for Database CRUD Variables. | +| On Before Dataset Ready | This event is triggered just before the variable’s dataSet property is updated with the data received from the target service (after onResult). This event handler gives you the opportunity to manipulate the data before your variable’s dataSet property is assigned this value. If you want to add rows to a Grid or List or Select, this is a good way to add in extra items into your results before your variable is set and your widget is updated. The new data can be returned from here in order to update the Variable’s dataSet. | +| On Can Update | This event is triggered just before the variable’s dataSet property is updated with the data received from the target service (after onResult). This event handler gives you the opportunity to manipulate the data before your variable’s dataSet property is assigned this value. If you want to add rows to a Grid or List or Select, this is a good way to add in extra items into your results before your variable is set and your widget is updated. The new data can be returned from here in order to update the Variable’s dataSet. | +| On Success | Allows you to trigger an action when the Variable has completed its life cycle. Any component bound to the resultant dataSet of this Variable will be updated just before this event is triggered. So, If you want to trigger another Variable which is dependent on the dataSet of this Variable, the Variable should be triggered by this event. An additional last argument as the “operation-name” that holds the invoked operation is present for Database CRUD Variables. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/fileupload-use-cases.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/fileupload-use-cases.md new file mode 100644 index 000000000..1a3676650 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/fileupload-use-cases.md @@ -0,0 +1,17 @@ +--- +title: "FileUpload - Use Cases" +id: "fileupload-use-cases" +--- + +FileUpload widget can be used to let users upload files to your apps. WaveMaker **FileUpload** widget generates a **Java Service** to enable additional file processing functionality. It exposes few methods like _uploadFile_, _listFiles_, and _deleteFile_. + +- [FileUpload Basic Usage](/learn/app-development/widgets/form-widgets/file-upload-basic-usage/) +- [How to use various file service operations](/learn/how-tos/file-upload-widget-operations/) +- [How to save uploaded file to a DB](/learn/how-tos/upload-file-save-database/) +- [How to upload BLOB file to a DB](/learn/how-tos/file-upload-blob-data/) +- [How to upload file to custom directory](/learn/how-tos/file-upload-custom-directory/) +- [How to uploaded files from Java code](/learn/how-tos/accessing-file-upload-java-code/) +- [How to use FileUpload in Form and Live Form](/learn/how-tos/upload-files-from-live-form-form/) + +[![](/learn/assets/fu_service.png)](/learn/assets/fu_service.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/number.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/number.md new file mode 100644 index 000000000..5538ca5f4 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/number.md @@ -0,0 +1,84 @@ +--- +title: "Number" +id: "number" +--- +--- + +**Number widget** is an editor widget that accepts numeric input. + +You can: + +1. Can be used in conjunction with the selected app Locale to display the number in the appropriate format. +2. Limit the input by applying maximum character length. +3. Apply regular expressions to validate client side number. + +:::note +Number widget applies the number formatting as per the Locale automatically. In case you do not wish to change the app behavior as per the Locale, use the Text widget with Number Type. For more information, see [Text Widget with Number Type](/learn/app-development/widgets/form-widgets/text). +::: + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for Number widget. | +| Placeholder | A placeholder is a text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the user starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple of the user. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)) | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Validation** | +| Required | A required editor in ```wm.LiveForm``` may refuse to save without a required field. | +| Regular Expression | Enter any regular expression to be used to validate user input for client-side input validation. | +| Minimum value | Enter minimum value user is allowed to enter. | +| Maximum value | Enter maximum value user is allowed to enter. | +| Step | Use the stepper to increment/decrement the input value by the specified step interval. Example: if step='3', legal numbers could be -3, 0, 3, 6, etc. | +| **Behavior** | +| Auto Focus | This property makes the element get focused automatically when the page loads. | +| Read Only | Selecting this checkbox property prevents the user from changing the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | +| Allow Trailing Zeros | This property specifies whether to keep trailing zeros after decimal point or not.| +| Update value on | If the selected value is `blur`: data value will be updated on blur event, `default`: data value will be updated on key up. | + +## Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | +| **Keyboard Events** | +| On key down | This event handler is called whenever a key is pressed down. | +| On key press | This event handler is called whenever a key is pressed. | +| On key up | This event handler is called whenever a key is released. | + +**Shortcutkey**: The shortcut key property specifies a shortcut key to click the button. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcutkey Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcutkey | +| Chrome | [Alt] + shortcutkey (Windows/Linux) | +| | [Control] [Alt] + shortcutkey (MAC) | +| Firefox | [Alt] [Shift] + shortcutkey (Windows/Linux) | +| | [Control] [Alt] + shortcutkey (MAC) | + +## See More + +[Form Widgets](/learn/app-development/widgets/widget-library/#form) +[Currency](/learn/app-development/widgets/form-widgets/currency/) +[Date](/learn/app-development/widgets/form-widgets/date-time-datetime/) +[Datetime](/learn/app-development/widgets/form-widgets/date-time-datetime/) +[Text](/learn/app-development/widgets/form-widgets/text/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/radioset.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/radioset.md new file mode 100644 index 000000000..844e5ce77 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/radioset.md @@ -0,0 +1,61 @@ +--- +title: "Radioset" +id: "radioset" +--- +--- +Radioset allows you to group a set of radio buttons under a common heading. You need to bind to a dataset to display a radio button for each value. + + +## Change the layout of RadioSet - Vertical or Horizontal + +You can easily change the layout of the options inside the RadioSet, so that they are aligned vertifically, horizontally or grouped by a specific number. +**Items per row** determine the number of items that can be shown in each row. This can be specified independently for different target devices, from the _device_ tab of the _Properties panel_. + +[![radioset layout](/learn/assets/radioset_horizontal.png)](/learn/assets/radioset_horizontal.png) + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the button. Special characters and spaces are not allowed in widget name. | +| **Accessibility** | +| Tab Index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| Height | The height of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| Layout | This property controls how contained widgets are displayed within this widget container - inline or stacked. | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| Dataset | +| Value | Set this property to a variable to populate the list of values to display. | +| Use Keys | Use the keys of the live variable object as checkboxset options. | +| Data field | This property sets the dataValue to be returned by a select editor when the list is populated using the dataSet property. | +| Display Field | This property sets the displayValue to show in the select editor when the list is populated using the dataSet property. | +| Display Expression | This is an advanced property that gives more control over what is displayed in the drop-down select list. A Display Expression uses a Javascript expression to format exactly what is shown. | +| Order by | This allows for multiple selections for ordering the display of rows based on fields in asc or desc order - up arrow for asc and down arrow for desc. | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Read only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the widget becomes display-only and user input will not be accepted. It can also set programmatically by binding it to a boolean type variable. | + +## Events + +| **Event** | **Description** | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| **Mouse Events** | +| On click | It is an HTML button. It is used to generate a click event. For example, save button. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the widget is tapped. | + +## Use Cases + +- [Working with Selection Widgets](/learn/how-tos/selection-widgets-use-case/) +- [How to use Radioset widget to filter a List](/learn/how-tos/radioset-filter-list/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/rating-widget.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/rating-widget.md new file mode 100644 index 000000000..d6bd26cb0 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/rating-widget.md @@ -0,0 +1,60 @@ +--- +title: "Rating Widget" +id: "rating-widget" +--- +--- + +**Rating** widget can be used to display or elicit information about a quantitative or a qualitative attribute in the form of a set of categories. + +## Features + +- **Icon color** property can be set from the _Styles_ tab of Property Panel +- **Show captions** property can be used to hide or show the captions. +- Default Value can be set for: + - **Value** to be shown as the initial setting or rating selection + - **Maximum value** for the highest rating user can select +- **Dataset** property will allow mapping of caption value against the value selected by the user. It can accept: + - _Comma separated_ string containing the caption values which mapped to rating value in ascending order). + - An _array of objects_ in the form of a Variable. The structure of the Variable should have an integer field for DataField to be mapped to rating value and a field for DisplayField to be mapped to caption against the rating value + - This binding will also set the title for rating widget and the caption will change on hover of each element in rating widget. +- In **Read only** mode, if the dataset is null then the caption can be bound through displayexpression. +- **Tab index** selects the widget (focus the widget) and the UP-ARROW and DOWN-ARROW keypress would increase and decrease the rating value. + +## Properties + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for Rating widget. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Default Value** | +| Value | Default value (number of active stars) of Rating.It should always be less than or equal to the maximum value of Rating. | +| Maximum Value | Maximum value (number of stars) of Rating.It should be less than or equal to 10. | +| **Dataset** | +| Value | This property is used to map a caption value against the value of the widget. It can accept: 1. Comma separated string containing the caption values (mappped to rating value in ascending order). 2. Array of strings (mapped as above). 3. Array of objects, needs selection of DataField(to map to rating value) and DisplayField(to map to caption against the rating value). | +| Data Field | This property indicates the field (in DataSet) to represent selected value for the rating widget. It should be mapped to an integer field in DataSet. | +| Display Field | This property indicates the field (in DataSet) that represents caption against the selected value(mapped as DataField) of the rating widget. | +| Display Expression | This is an advanced property that gives more control over what values are to be displayed for rating widget. A Display Expression uses a JavaScript expression to format exactly what is shown. For readonly mode, If dataset is null then the caption can be bound directly to display expression. | +| **Behavior** | +| Read Only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Show Captions | Captions for Rating widget are shown only when this property is set. | +| **Graphics** | +| Icon Size | This property defines the size of the icon. Value has to be specified along with the units (em or px). | + +## Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | + +## Use Cases + +You can use the Rating widget to capture the input from the user as Widgets.rating1.datavalue or from the direct bind dialog. You can also change the caption according to the user selection. + +- [How to build Rating widget from static data](/learn/how-tos/rating-widget-using-static-data/) +- [How to build Rating widget from static variable data](/learn/how-tos/rating-widget-using-static-variable/) +- [how-tos/building-rating-widget-using-variable](/learn/how-tos/building-rating-widget-using-variable) +- [How to build an interactive rating widget](/learn/how-tos/rating-widget-interactive/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/select-locale-usage.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/select-locale-usage.md new file mode 100644 index 000000000..c668d1f92 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/select-locale-usage.md @@ -0,0 +1,71 @@ +--- +title: "Localization Using Select Locale" +id: "select-locale-usage" +--- +--- + +## Step 1: App Messages + +1. From the **Secondary Actions Menu**, click the `I18N` option. + +[![](/learn/assets/loc_create.png)](/learn/assets/loc_create.png) + +2. **Localized Messages** dialog shows a list of localized text in the current application. The localized text appears as a dictionary of keys and values in different languages. + +[![](/learn/assets/loc_default_msgs.png)](/learn/assets/loc_default_msgs.png) + +3. To Add new language, go to `Manage Languages`. It opens the **Languages** window. Select the desired language and click the **Plus** icon. Similarly, add any number of languages, and click `Save`. + +[![](/learn/assets/loc_new_locale.png)](/learn/assets/loc_new_locale.png) + +4. To add localized messages, select the language and place the curser on the *message* to edit. + +[![](/learn/assets/loc_edit_msg.png)](/learn/assets/loc_edit_msg.png) + +5. To create a new localized text, click the **Plus** icon placed next to `Message Key`. + +[![](/learn/assets/loc_new_msg.png)](/learn/assets/loc_new_msg.png) + +6. Enter a `Message Key` and enter messages for all the Languages added and click **Done** to save. + +[![](/learn/assets/loc_new_msg_entry.png)](/learn/assets/loc_new_msg_entry.png) + +7. You can also set the date and time formats specific to a required locale. This will ensure that the date and time pickers are properly aligned and set to the preferred format. + +:::note +With release 11.8.0, you can now update the date format for Internationalization (i18n) service through JavaScript as well. Use the below code to update, `App.getDependency(“i18nService”).dateFormat = “dd-MM-yyyy”;`. + +[![](/learn/assets/date-format-i18n.png)](/learn/assets/date-format-i18n.png) + +::: + +:::tip +You can also select the currency symbol from anywhere in the app. This symbol applies to all the currency widgets across the app. +::: + +[![](/learn/assets/loc_edit_formats.png)](/learn/assets/loc_edit_formats.png) + +8. Number format changes can also be implemented by using the Number widget. This will change the format based upon the selected or browser locale. For more information, see [Numbers in Form Widget](/learn/app-development/widgets/form-widgets/number/). + +## Step 2: Binding + +1. WaveMaker creates a `.json` file for each of the locales. You can find the list of files when you select `Locale` in the **File Explorer** section from the **Developer Utilities** menu. You can edit, save and delete files in the Code Editor. + +[![](/learn/assets/loc_json.png)](/learn/assets/loc_json.png) + +2. To display messages, select the **Label**. Using the **Properties Panel**, you can bind the `Caption` or any other relevant property to any of the application messages of the project. Once you have bound all the relevant widgets to the messages, you should enable the application to show the message based on the user's locale. + +[![](/learn/assets/loc_binding.png)](/learn/assets/loc_binding.png) + +## Step 3: Application + +Let us see how we can add localization to our applications. + +1. Drag and drop a **Select Locale** widget on the project. This widget is bound by default to the `supportLocale` variable created when the locales were added in the previous step. Use a label bound to the Localized Message created in the previous step. + +[![](/learn/assets/loc_design.png)](/learn/assets/loc_design.png) + +2. Save and run the application. From the Select widget, choose a language and see the text change in the Label widget. + +3. When the user selects a _Language_ on your application or when you set the _default language_ of the app from the [Project Settings](/learn/app-development/wavemaker-overview/product-walkthrough#project-settings) dialog, WaveMaker applies the relevant locale settings to show the messages as per its value for that locale. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/select-locale.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/select-locale.md new file mode 100644 index 000000000..5fd9f4b7a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/select-locale.md @@ -0,0 +1,81 @@ +--- +title: "Select Locale" +id: "select-locale" +--- +--- + +Localization refers to the tools, techniques, and steps taken to enable your application to run in other languages. WaveMaker allows you to create a  dictionary of localized messages so that users can change the language of the application to experience the application in their language. + +There are three ways that Localization comes into effect: + +1. WaveMaker automatically detects the user's preferred locales (from the browser) and renders the application with the locale of the user's preference if the application supports. If not, displays the application in the default language configured in application settings. +2. The user can be given a choice to select the language using the Select Locale widget. +3. You can also choose to trigger the language switch through user events like button click from JavaScript, the following snippet changes language to English: + +``` +App.changeLocale({'datavalue': 'en'}) +``` + +## Properties + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for Select Locale widget. | +| Placeholder | A placeholder is text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the user starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple of the user. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)) | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. By default, it is bound to the supportedLocale variable which gets created when [Localization](/learn/how-tos/localization-wavemaker-apps/ "Localization") is enabled. | +| Data field | This property sets the dataValue to be returned by a select editor when the list is populated using the dataSet property. | +| Display field | This property sets the displayValue to show in the select editor when the list is populated using the dataSet property. | +| Display Expression | This is an advanced property that gives more control over what is displayed in the drop-down select list. A Display Expression uses a Javascript expression to format exactly what is shown. | +| Order by | This allows for multiple selections for ordering the display of rows based on fields in asc or desc order - up arrow for asc and down arrow for desc | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Auto Focus | This property makes the element get focused automatically when the page loads. | +| Read Only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Multiple | Enable/Disable to switch between Multiple/Single File Upload Widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | + +## Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. By default, it is set to invoke 1. _changeAppLocale_ which would change the language rendered in the application; and 2. _reloadApp_ event which will reload the app to enable rendering. _If you do not want the app to reload whenever the locale changes remove the reloadApp event._ | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | +| **Keyboard Events** | +| On key down | This event handler is called whenever a key is pressed down. | +| On key press | This event handler is called whenever a key is pressed. | +| On key up | This event handler is called whenever a key is released. | + +**Shortcut key**: The shortcut key property specifies a shortcut key to click the button. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcut key Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcut key | +| Chrome | [Alt] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | +| Firefox | [Alt] [Shift] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | + +## See Also + +[Simple Usage Scenario](/learn/app-development/widgets/form-widgets/select-locale-usage/) +[Localization of Error Messages](/learn/how-tos/localization-error-messages/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/select-use-cases.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/select-use-cases.md new file mode 100644 index 000000000..f8818849a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/select-use-cases.md @@ -0,0 +1,14 @@ +--- +title: "Select - Use Cases" +id: "select-use-cases" +--- + +WaveMaker offers various ways to use the Select widget. This section elaborates on all the options available. These various options pertain to how the data displayed in the drop down list is set. Running the app will display the select widgets with the label showing the selection. + +- [How to use list of values for select widget configuration](/learn/how-tos/configuring-select-widget-static-list-values/) +- [How to use variable for select widget configuration](/learn/how-tos/configuring-select-widget-variable/) +- [How to use display and data value fields for select widget configuration](/learn/how-tos/configuring-select-widget-display-data-fields/) +- [How to use database fields for select widget configuration](/learn/how-tos/configuring-select-widget-database-fields/) +- [How to configure cascading select](/learn/how-tos/configuring-cascading-select/) + +[![](/learn/assets/sel_dnd.png)](/learn/assets/sel_dnd.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/select.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/select.md new file mode 100644 index 000000000..e9cc91cde --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/select.md @@ -0,0 +1,69 @@ +--- +title: "Select" +id: "select" +--- +--- + +The Select widget provides a way for users to select an item from a drop-down list of choices. The selection can be captured through the _displayValue_ property. + +The number of records fetched will be limited by the "Records per Request" property of the underlying Variable to which the Select widget is bound to. Refer to the corresponding Variable to change this value. + +## Properties + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for Select widget. | +| Placeholder | A placeholder is text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the user starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple of the user. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)) | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. | +| Data field | This property sets the dataValue to be returned by a select editor when the list is populated using the dataSet property. | +| Display field | This property sets the displayValue to show in the select editor when the list is populated using the dataSet property. | +| Display Expression | This is an advanced property that gives more control over what is displayed in the drop-down select list. A Display Expression uses a Javascript expression to format exactly what is shown. | +| Order by | This allows for multiple selections for ordering the display of rows based on fields in asc or desc order - up arrow for asc and down arrow for desc | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Auto Focus | This property makes the element get focused automatically when the page loads. | +| Read Only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Multiple | Enable/Disable to switch between Multiple/Single File Upload Widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | + +## Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. By default, it is set to invoke $root.changeLocale which would change the language rendered in the application. | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | +| **Keyboard Events** | +| On key down | This event handler is called whenever a key is pressed down. | +| On key press | This event handler is called whenever a key is pressed. | +| On key up | This event handler is called whenever a key is released. | + +**Shortcut key**: The shortcut key property specifies a shortcut key to click the button. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcut key Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcut key | +| Chrome | [Alt] + shortcut key (Windows/Linux) | +| | [Control] [Alt] + shortcut key (MAC) | +| Firefox | [Alt] [Shift] + shortcut key (Windows/Linux) | +| | [Control] [Alt] + shortcut key (MAC) | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/slider.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/slider.md new file mode 100644 index 000000000..652e77f42 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/slider.md @@ -0,0 +1,71 @@ +--- +title: "Slider" +id: "slider" +--- +--- + +**Sliders** are often the UI control of choice for letting users select a value or range from a fixed set of options. Sliders are good to use while: + +- setting mobile volumes such as media, alarm clock, and ringtones etc. +- setting screen brightness +- setting price range while purchasing things online + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for slider widget. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for _1.5 seconds._ | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)) | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| Minimum Value | Enter minimum number. This property applies when the type is a number. | +| Maximum Value | Enter maximum number. This property applies when the type is a number. | +| Step | It is a composite widget with a label and a selector. The user can select from the range specified with the increment as defined by the step value. | +| **Behavior** | +| Read Only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | +| **Range** | +| Range | This property can be used to add a range within the Slider Widget. | +| Datatype | Select the input datatype. This property is to provide the datatype that can be number or dataset | +| Dataset | This is to provide the input data array | +| Datafield | This property indicates the field (in DataSet) to represent selected value for the range in Slider widget. It should be mapped to an integer field in DataSet. | +| Displayexpression | This is an advanced property that gives more control over what values are to be displayed for the range in the Slider widget. A Display Expression uses a JavaScript expression to format exactly what is shown. For readonly mode, If dataset is null then the caption can be bound directly to display expression. | +| Tooltip expression | This property is used to get and customize the text displayed in the tooltip associated with the range value. | +| Showmarkers | This property can be used to control whether a marker or indicator is displayed on the Slider widget. | +| Showtooltip | Enable this property to show the tooltip for the applied range. | + +- Range +- Datatype - number or dataset +- Dataset - to provide a dataset +- Datafield - about the data given in the dataset +- Displayfield - +- Displayexpression - to add +- Tooltip expression - value on top of the thumb +- Showmarkers - display the scale +- Showtooltip - whether to display tooltip or not + + +**Shortcut key**: The shortcut key property specifies a shortcut key to click the button. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcut key Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcut key | +| Chrome | [Alt] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | +| Firefox | [Alt] [Shift] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | + +## Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/switch.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/switch.md new file mode 100644 index 000000000..8b5e61b75 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/switch.md @@ -0,0 +1,45 @@ +--- +title: "Switch" +id: "switch" +--- +--- + +**Switch widget** can help switching between 3 or more different options by pressing a single key. + +## Properties + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for Switch widget. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. By default, it is set to _yes_. | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. By default, it is set to _yes, no, maybe_. | +| Data field | This property sets the dataValue to be returned by a select editor when the list is populated using the dataSet property. | +| Display field | This property sets the displayValue to show in the select editor when the list is populated using the dataSet property. | +| Order by | This allows for multiple selections for ordering the display of rows based on fields in asc or desc order - up arrow for asc and down arrow for desc | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | + +## Events + +| **Event** | **Description** | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On mouse enter | This event occurs when the pointer is moved onto a widget. | +| On mouse leave | The mouse leave event occurs when the mouse pointer leaves a widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/text.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/text.md new file mode 100644 index 000000000..968fe4c77 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/text.md @@ -0,0 +1,81 @@ +--- +title: "Text" +id: "text" +--- +--- + +**Text widget** is an editor widget that accepts single-line text input. + +## Using Text Widget +Using Text widget, you can do the following: + +1. Limit the input text by applying maximum character length +2. Apply regular expressions to validate client side text + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for Text widget. | +| Type | This property specifies the type of the variable. It can be of type: - color - date, datetime-local, time - email - number, month, week - password - search, text, tel, url | +| Placeholder (only for alphanumeric type) | A placeholder is a text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the user starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple of the user. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **Note**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from ```Preferences -> Advanced -> Accessibility``` set the option "Press Tab to highlight each item on a webpage". | +| Shortcut key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)). | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. **Note** that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Validation** | +| Required | A required editor in _wm.LiveForm_ may refuse to save without a required field. | +| Regular Expression | Enter any regular expression to be used to validate user input for client-side input validation. | +| Maximum Characters | Defines the maximum number of characters that can be entered in the editor. **Note**: Not available for color, date, time, month, week types.| +| Minimum value | Enter minimum number. This property applies when the type is a number. **Note**: Only for numeric, date, time, week, month types. | +| Maximum value | Enter maximum number. This property applies when the type is a number. **Note**: Only for numeric, date, time, week, month types. | +| Step | Use the stepper to increment/decrement the input value by the specified step interval. Example: if step='3', legal numbers could be -3, 0, 3, 6, etc. **Note**: Only for numeric, date, time, week, month types. | +| **Behavior** | +| Auto Focus | This property makes the element get focused automatically when the page loads. | +| Read Only | Selecting this checkbox property prevents the user from changing the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. **Note**: Visible only when show property is bound to a variable. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | +| Auto Complete | Checking this box turns on auto-completion in the editor. As the user types into the pull-down select editor, the choices change dynamically. | +| Display Format | The keys in display format represent the special tokens/characters used to delimit acceptable ranges of inputs. For example, we use '9' here to accept any numeric values for a phone number: displayformat='(999) 999-9999'. The values associated with each token are regexen. Each regex defines the ranges of values that will be acceptable as inputs in the position of that token. When placeholder and default value are both provided for a widget, the default value takes precedence. Upon focusing on the widget, the display format will be shown to make the user input easy. Tokens: - A Any letter. - 9 Any number. - * Any letter or number. - ? Make any part of the mask optional. | +| Show Display Format On | This property decides when to show the display format on the widget. **Always**: the provided display format will always be shown. **On keypress**: the provided display format will be shown when user starts typing in the widget. | +| Update value on | If the selected value is `blur`: data value will be updated on blur event, `default`: data value will be updated on key up. | +| Update delay | The amount of delay in milliseconds to update the data value. | + +## Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | +| **Keyboard Events** | +| On key down | This event handler is called whenever a key is pressed down. | +| On key press | This event handler is called whenever a key is pressed. | +| On key up | This event handler is called whenever a key is released. | + +**Shortcutkey**: The shortcut key property specifies a shortcut key to click the button. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcutkey Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcutkey | +| Chrome | [Alt] + shortcutkey (Windows/Linux) | +| | [Control] [Alt] + shortcutkey (MAC) | +| Firefox | [Alt] [Shift] + shortcutkey (Windows/Linux) | +| | [Control] [Alt] + shortcutkey (MAC) | + +## See More +[Form Widgets](/learn/app-development/widgets/widget-library/#form) +[Number](/learn/app-development/widgets/form-widgets/number/) +[Textarea](/learn/app-development/widgets/form-widgets/textarea/) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/textarea.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/textarea.md new file mode 100644 index 000000000..cfa61062f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/textarea.md @@ -0,0 +1,64 @@ +--- +title: "Textarea" +id: "textarea" +--- +--- + +**Textarea widget** represents a multi-line plain-text editing control. It can be used in a web application for adding comments and feedback forms as a plain text editor. + +## Properties + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for textarea widget. | +| Placeholder | A placeholder is text to show in the editor when there is no value. A common use of this is a search box that says in faint gray italicized text "Search..." which disappears as soon as the user starts to edit the text box. This is a useful alternative to a caption if you are constrained in space and asking for something simple of the user. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)) | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| Maximum characters | Defines the maximum number of characters that can be entered in the editor. | +| Help text (character count) | Display the number of characters entered or left to enter by comparing it with the value you have set in the **Maximum characters** in the text area. There are three default ways to display the help text property in runtime, including: 1. 0 characters filled out of 100 2. 100 characters left out of 100 3. 0/100 If you want to show this property other than the default values, you can use the bind expression button and change the value of this help text property. You can also provide the `charlength` and `maxchars` properties for binding in the **Use Expression** dialog. **NOTE:** This property will only show when you set the Maximum characters property. | +| **Behavior** | +| Auto Focus | This property makes the element get focused automatically when the page loads. | +| Read Only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | +| Update value on | If the selected value is `blur`: data value will be updated on blur event, `default`: data value will be updated on key up. | +| Update delay | The amount of delay in milliseconds to update the data value. | + +## Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | +| **Keyboard Events** | +| Key Down | This event handler is called whenever a key is pressed down. | +| Key Press | This event handler is called whenever a key is pressed. | +| Key Up | This event handler is called whenever a key is released. | + +**Shortcut key**: The shortcut key property specifies a shortcut key to click the button. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcut key Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcut key | +| Chrome | [Alt] + shortcut key (Windows/Linux) | +| | [Control] [Alt] + shortcut key (MAC) | +| Firefox | [Alt] [Shift] + shortcut key (Windows/Linux) | +| | [Control] [Alt] + shortcut key (MAC) | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/toggle.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/toggle.md new file mode 100644 index 000000000..ebc7ea1f7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form-widgets/toggle.md @@ -0,0 +1,55 @@ +--- +title: "Toggle" +id: "toggle" +--- +--- +**Toggle widget** represents a physical switch that allows users to turn things on or off. Use Toggle controls to present users with exactly two mutually exclusive options (like on/off), where choosing option results in an immediate action. + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Caption | The caption is the text that the end user sees on your label. | +| Name | The name is a unique identifier for Toggle widget. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)) | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. It is set to _false_ by default. | +| Checked Value | This property defines the value of the widget when the element is in the checked state. The default value is boolean value true. If specified, the value will be of string type. | +| Unchecked Value | This property defines the value of the widget when the element is in the unchecked state. | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | + +**Shortcut key**: The shortcut key property specifies a shortcut key to click the button. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcut key Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcut key | +| Chrome | [Alt] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | +| Firefox | [Alt] [Shift] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | + +## Events + +| **Event** | **Description** | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| On focus | This event handler is called each time your editor gets focus allowing the user to start typing. | +| On blur | This event handler is called each time user focus leaves the editor. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On mouse enter | This event occurs when the pointer is moved onto a widget. | +| On mouse leave | The mouse leave event occurs when the mouse pointer leaves a widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form/calendar.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form/calendar.md new file mode 100644 index 000000000..078d9e9ea --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form/calendar.md @@ -0,0 +1,239 @@ +--- +title: "Calendar" +id: "calendar" +--- + +The **Calendar** widget is the most popular solution for scheduling events on a full-sized calendar in a web application. This widget can be used to show agenda. The calendar will be automatically switched to the Web or Mobile version, based on the device it is being viewed on. + +[![](/learn/assets/calendar_feats.png)](/learn/assets/calendar_feats.png) + +# Features + +## Display Events in the Calendar + +For displaying events in the Calendar widget you need a variable of type _Array_ or an object with single event data. The data **must** contain a field corresponding to Start property, other properties are optional. The expected date format for the value of Start property is a Date Object - ‘YYYY/MM/DD’ or ‘MM/DD/YYYY’ or ‘DD MMMM YYYY’. + +1. Drag and drop a Calendar widget onto the canvas +2. Bind the variable consisting the data to the **Dataset Value** property of the widget. +3. Set the properties _Title_, _Start_, _End_, _All day_, _Class name_ to the keys of the variable bound. **Note**: Start property is a must, other properties are optional. +4. **Enable controls** There are five different types of controls on the calendar that can be enabled to: + - navigate between the months, weeks and days, depending on the calendar view + - select current day + - switch the view to Month + - switch the view to Week + - switch the view to Day. +5. **Type** Type can be: + - set as _basic_ - will show the events in a single row, or + - set as Agenda - will show the complete day agenda with hours included. + +## Capturing Events in the Calendar + +The following are the outbound properties of a Calendar widget that can be captured. These values can be captured from JavaScript to be triggered by any Calendar event like _on Select_: + +- _currentview_: gives the start and end values of the current calendar view +- _selecteddata_: gives the entire dataset corresponding to the selected item within the calendar +- _selecteddates_: gives the user selection on the calendar. + +## Configurations for Calendar + +**Views** Calendar comes in three views - Month, Week and Day. + +- The _Month_ view of the Calendar displays all the days in the month. + + + +- The _Week_ view of the Calendar displays all the days in the week. + + + +- The _Day_ view of the Calendar displays all the events on the day. + + + + +# Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the Calendar. Special characters and spaces are not allowed in widget name. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| Height | The height of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. | +| **Events Data** | +| Title | Title for the Event, set from the Dataset fields. | +| Start | Start date or date time for the event, set from the Dataset fields. | +| End | End date or date time for the event, set from the Dataset fields. | +| All day | Whether it is an All day event or not | +| Class name | Display Class to be applied to that event. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| iswheelpicker | This property can be added in Markup script and set as **True** to set the date, month, and year using a scrollable wheel. This can be set as **False** to use the traditional Modal calendar.| +| Type | This property allows you to set the type of the calendar widget: + +- agenda, or +- basic (default). + + | +| Enable Controls | This property allows you to enable the header controls for calendar widget. These include + +- navigation - to navigate previous/next month/week/day(depending upon the display) on the calendar, +- today - go to today's location on the calendar, +- month - to display entire month, +- week - to display entire week, +- day - to display entire day. + +All these controls on the calendar are used to navigate between the months and switch the view to _Month_(or) _Week_ (or) _Day._ + +**Note:-** _This property is shown only for the Web version of the Calendar._ | +| View | This property allows you to set the default view of the calendar widget: + +- month (default), +- week or +- day. + + | +| Selection Mode | This property can be used to control the user selection of the dates using a simple mouse drag operation. The values can be: + +- _None_: no selection, the calendar is just there to present data, not to be selected +- _Single_: only one row can be selected at a time +- _Multiple_: many rows can be selected at a time. + + | + +# Events + +| Event | Description | +| --- | --- | +| **Callback Events** | +| On Select | This event is triggered when a user selects one or more dates. | +| On View Render | This event handler is triggered when the calendar view is changed. | +| On Event Drop | This event handler is triggered when dragging of an event in calendar stops and the event has moved to a different day/time. | +| On Event Resize | This event handler is triggered when resizing of the event in calendar stops and the event has changed in duration. | +| On Event Click | This event handler is triggered when an event is clicked in the calendar. | +| On Event Render | This event handler is triggered when an event is rendered. | + +# Methods + +To set the properties of the calendar widget through the script, access the properties on the calendar as (consider the calendar with name ‘wmcalendar’) Page.Widgets.wmcalendar.propertyname and change or assign the values accordingly. For example: + +- To set the first day of the month view [Default: 0 (Sunday)]: Page.Widgets.wmcalendar.calendarOptions.calendar.firstDay = 0; +- To hide the all day slot of the agenda view [Default: true]: Page.Widgets.wmcalendar.calendarOptions.calendar.allDaySlot= false; +- To set the text of the all-day slot in the agenda view [Default: ‘all-day’]: Page.Widgets.wmcalendar.calendarOptions.calendar.allDayText= ‘all-day’; + +Other properties which can be set using the similar methods: For more information on Calendar, properties [see here.](https://fullcalendar.io/docs/) + +| Method | Description | +| --- | --- | +| allDaySlot | Determines if the title ("all-day") slot is displayed at the top of the calendar. When false, all-day events will not be displayed in agenda views. | +| allDayText | The text for title ("all-day") slot at the top of the calendar. | +| slotDuration | The frequency for displaying time slots. Default: '00:30:00' (30 minutes) | +| slotLabelFormat | Determines the time-text that will be displayed on the vertical axis of the agenda views. default: 'h(:mm)a' The default English value will produce times that look like "5pm" and "5:30pm". | +| slotLabelInterval | Determines how often the time-axis is labeled with text displaying the date/time of slots. | +| snapDuration | If not specified, this value is automatically computed from slotDuration. With slotDuration's default value of 30 minutes, this value will be 1 hour. | +| scrollTime | Determines how far down the scroll pane is initially scrolled down. default: '06:00:00' (6am). The user will be able to scroll upwards to see events before this time. If you want to prevent users from doing this, use the minTime option instead. | +| minTime | Determines the starting time that will be displayed, even when the scrollbars have been scrolled all the way up. default: "00:00:00" The default "00:00:00" means the start time will be at the very beginning of the day (midnight). | +| maxTime | Determines the end time (exclusively) that will be displayed, even when the scrollbars have been scrolled all the way down. default: "24:00:00" The default "24:00:00" means the end time will be at the very end of the day (midnight). | +| slotEventOverlap | Determines if timed events in agenda view should visually overlap. default: true. When set to true (the default), events will overlap each other. At the most half of each event will be obscured. When set to false, there will be absolutely no overlapping. | +| selectDate() | It highlights the default date given for the calendar. +``` +

Case 1 - datavalue (data/string): If the default value is date object, then that particular date will be highlighted. For example: To select 1st June 2017

Page.Widgets.calendar.datavalue = '01/0/2017';
+Page.Widgets.calendar.selectDate();
+ +

Case 2 - datavalue (Object): If the default value is Object, then the particular dates from start to end date will be highlighted. For example: To select dates from 1st Jan to 10th Jan 2017

Page.Widgets.calendar.datavalue = {start:'01/01/2017', end:'10/01/2017'};
+Page.Widgets.calendar.selectDate();
+``` + | +| gotoDate() | + +It shows the calendar view to default date given for the calendar. For example, to go to a specific date - 1st Jan 2107 + +Page.Widgets.calendar.datavalue='01/01/2017'; +Page.Widgets.calendar.gotoDate(); + + | +| gotoMonth(int) | + +This method renders the present view (i.e. year view will be the same) for the specified month. For example: To view the February month. + +Page.Widgets.calendar.gotoMonth(2); + + | +| gotoNextMonth() | + +This method renders the present view (i.e. year view will be the same) for the next month. For example: To view the next month + +Page.Widgets.calendar.gotoNextMonth(); + + | +| gotoPrevMonth() | + +This method renders the present view (i.e. year view will be the same) for the prev month. For example: To view the prev month + +Page.Widgets.calendar.gotoPrevMonth(); + + | +| gotoNextYear() | + +This method renders the present view (i.e. month/week view will be the same) for the next year. For example: To view the next year + +Page.Widgets.calendar.gotoNextYear(); + + | +| gotoPrevYear() | + + It renders the present view (i.e. month/week view will be the same ) for the previous year. For example: To view the previous year + +Page.Widgets.calendar.gotoPrevYear(); + + | +| rerenderEvents() |  It rerenders the events from the dataset. For example, to get events on the calendar, we use: + +Page.Widgets.calendar.rerenderEvents(); + + | + +# Use Cases + +- [How to create an event and save it in a Database](/learn/how-tos/calendar-usage-create-event/) +- [How to integrate with Google Calendar](/learn/how-tos/calender-usage-google-calendar-integration/) + +[3. Form Widgets](/learn/app-development/widgets/widget-library/#form) + +- [3.1 Button](/learn/app-development/widgets/form-widgets/button/) +- [3.2 Button Group](/learn/app-development/widgets/form-widgets/button-group/) +- [3.3 Calendar](#) + - [i. Features](#features) + - [○ Display Events](#display-events) + - [○ Capturing Events](#capture-events) + - [○ Calendar Configuration](#configuration) + - [ii. Properties](#properties) + - [iii. Events](#events) + - [iv. Methods](#methods) + - [v. Use Cases](#use-cases) +- [3.4 Checkbox](/learn/app-development/widgets/form-widgets/checkbox/) +- [3.5 CheckboxSet](/learn/app-development/widgets/form-widgets/checkboxset/) +- [3.6 Chips](/learn/app-development/widgets/form-widgets/chips/) +- [3.7 Color Picker](/learn/app-development/widgets/form-widgets/color-picker/) +- [3.8 Currency](/learn/app-development/widgets/form-widgets/currency/) +- [3.9 Date](/learn/app-development/widgets/form-widgets/date-time-datetime/) +- [3.10 Datetime](/learn/app-development/widgets/form-widgets/date-time-datetime/) +- [3.11 FileUpload](/learn/app-development/widgets/form-widgets/file-upload/) +- [3.12 Number](/learn/app-development/widgets/form-widgets/number/) +- [3.13 Radioset](/learn/app-development/widgets/form-widgets/radioset/) +- [3.14 Rating](/learn/app-development/widgets/form-widgets/rating-widget/) +- [3.15 Select](/learn/app-development/widgets/form-widgets/select/) +- [3.16 Select Locale](/learn/app-development/widgets/form-widgets/select-locale/) +- [3.17 Slider](/learn/app-development/widgets/form-widgets/slider/) +- [3.18 Switch](/learn/app-development/widgets/form-widgets/switch/) +- [3.19 Text](/learn/app-development/widgets/form-widgets/text/) +- [3.20 Textarea](/learn/app-development/widgets/form-widgets/textarea/) +- [3.21 Time](/learn/app-development/widgets/form-widgets/date-time-datetime/) +- [3.22 Toggle](/learn/app-development/widgets/form-widgets/toggle/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form/checkbox.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form/checkbox.md new file mode 100644 index 000000000..5258f0349 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form/checkbox.md @@ -0,0 +1,55 @@ +--- +title: "Checkbox" +id: "checkbox" +--- + +A checkbox is a specific type of two-states button that can be either checked or unchecked. Checkboxes let a user select an option. Examples: "_I agree to terms and conditions"_ etc. checked and unchecked options. + +# Properties + +| **Property** | **Description** | +| --- | --- | +| Caption | The caption is the text that the end user sees on the button. This property can be bound to any variable or another widget. | +| Name | The name is a unique identifier for the button. Special characters and spaces are not allowed in widget name. | +| **Accessibility** | +| Hint | Any text you enter for this property will be shown as a tooltip when the mouse hovers over this widget for _1.5 seconds. _It can be bound to a variable or another widget. | +| Tab Index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut Key | Alphabet to act as a Shortcut key. The shortcut key property specifies a key to click the button. The way to activate the shortcut key varies from browser to browser ([see below for details](#shortcut)). | +| **Layout** | +| Width | The width of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| Height | The height of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| Checked Value | This property defines the value of the widget when the element is in the checked state. The default value is boolean value true. If specified, the value will be of string type. | +| Unchecked Value | This property defines the value of the widget when the element is in the unchecked state. | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the widget becomes display-only and user input will not be accepted. It can also set programmatically by binding it to a boolean type variable. | + +**Shortcut key**: The shortcut key property specifies a shortcut key to check the checkbox. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcut key Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcut key | +| Chrome | [Alt] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | +| Firefox | [Alt] [Shift] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcut key (_MAC_) | + +## Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| On focus | This event handler is called each time your element is focused. | +| On blur | This event handler is called each time your focus leaves your element. | +| **Mouse Events** | +| On click | It is an HTML button. It is used to generate a click event. For example, save button. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the widget is tapped. | diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form/checkboxset.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form/checkboxset.md new file mode 100644 index 000000000..1ed7be261 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form/checkboxset.md @@ -0,0 +1,63 @@ +--- +title: "CheckboxSet" +id: "checkboxset" +--- + +CheckboxSet allows you to group a set of checkboxes under a common heading. You need to bind to a dataset to display a checkbox for each value. + +[![](/learn/assets/checkboxset_struct.jpg)](/learn/assets/checkboxset_struct.jpg) + +Using the Group By property you can group the items together under a heading. The Show Count property will show the number of items within a group. + +[![](/learn/assets/checkboxset_group.png)](/learn/assets/checkboxset_group.png) + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the button. Special characters and spaces are not allowed in widget name. | +| **Accessibility** | +| Tab Index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| Height | The height of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| Layout | This property controls how contained widgets are displayed within this widget container. | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. | +| Use Keys | Use the keys of the live variable object as checkbox set options. | +| Data field | This property sets the dataValue to be returned by a select editor when the list is populated using the dataSet property. | +| Display Field | This property sets the displayValue to show in the select editor when the list is populated using the dataSet property. | +| Display Expression | This is an advanced property that gives more control over what is displayed in the drop-down select list. A Display Expression uses a Javascript expression to format exactly what is shown. | +| Group by | This property allows for grouping the items in the variable bound to the checkboxset dataset by selecting one of the field names from the drop-down list. | +| Group as | This property allows for groups to be displayed under categories. | +| Order by | This allows for multiple selections for ordering the display of rows based on fields in asc or desc order - up arrow for asc and down arrow for desc. | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Behavior** | +| Read only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the widget becomes display-only and user input will not be accepted. It can also set programmatically by binding it to a boolean type variable. | +| Collapsible | Enable control for collapsing and expanding the group. | +| Show Count | To display the number of items within the group. | + +## Events + +| Event | Description | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| **Mouse Events** | +| On click | It is an HTML button. It is used to generate a click event. For example, save button. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the widget is tapped. | +| **Callback Events** | +| On ready | This event handler is called when the container is loaded. | + +## Use Cases + +- [Working with Selection Widgets](/learn/how-tos/selection-widgets-use-case/) +- [How to use CheckboxSet widget to filter a List](/learn/how-tos/checkboxset-filter-list-data/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form/file-upload.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form/file-upload.md new file mode 100644 index 000000000..c76ee32b2 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form/file-upload.md @@ -0,0 +1,68 @@ +--- +title: "FileUpload" +id: "file-upload" +--- + +The FileUpload widget can be used to let users upload files to your apps. WaveMaker **FileUpload** widget generates a **Java Service** to enable additional file processing functionality. + +## Features + +Following properties can be set for a **FileUpload** widget: + +- **Multiple** to allow multiple selections for FileUpload, Message to be displayed in case of Multiple FileUpload, +- **Allowed File Extensions** can be selected from the _list_ (multiple selections are allowed), or _bound to space separated file extensions list_ prefixed with dots Ex: '.html .css .tiff' +- **Max File Size** of files allowed for upload can be specified in MB, default being 1MB. The max allowed limit is 50MB. +- A **Java Service** will be created with default methods and service variables. These methods contain the basic functionality related to upload, list, delete and download. You can customize the code as per your requirements. You need to create service variables to invoke these methods. +- **Mode** to _Upload_ which will upload the file or _Select_ which will select the file but not upload; Upload is the mode set by default. + - Drag and drop of a FileUpload widget creates a service variable, **FileServiceUploadFile** by default. The service for this variable is set to the Java FileService and the operation as uploadFile. This variable will have a file field in data tab which would be bound to the file select widget by default. Additionally, the relativePath can be set, if the value is set as ‘files’ then the file will be uploaded to ‘/resources/uploads/files’. + - By default, the On Select event of the FileUpload widget will be bound to the above mentioned Service Variable. In run mode, as the user selects the file, the Service Variable kicks in and the upload action is triggered. + - By deleting the Variable from the widget (from the On Select Event), the Widget can be set to Select mode. In this mode, the widget will act as a file selector with no additional modes. There will be no service or operation selection on the widget and hence it will not trigger the upload action internally. + +[![](/learn/assets/fu_feats.png)](/learn/assets/fu_feats.png) + +## Properties + +| Property | Description | +| --- | --- | +| Caption | The caption is the text that the end user sees on your label. | +| Name | The name is a unique identifier for FileUpload widget. | +| **Accessibility** | +| Hint | Any text or html you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| **Behavior** | +| Multiple | Enable/Disable to switch between Multiple/Single FileUpload Widget. | +| Message | Message text for file upload while in multi-select mode | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | +| Allowed File Extensions | Select the default filter file type in file choose option. It can be bindable to a string having comma separated extensions. Example: '.pdf, .doc, .gif'. | +| Max File Size | If the max file size is set, file upload will restrict the files more than max file size. Default Max file size is 1MB, it can be set up to 50MB. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. By default, it is set to _wi wi-file-upload_ | +| **Format** | +| Horizontal Align | This property specifies how the elements should be aligned horizontally. | + +## Events + +| Event | Description | +| --- | --- | +| **Callback Events** | +| On Before Select | This event handler is called before the upload of the file. It can be used to perform any validations before the file is further processed. | +| On Select | This event handler is called when the files are selected. By default, it invokes the Service Variable to upload the selected files. Deleting this variable will set the FileUpload to act as a file selector. | + +Apart from the above events attached to the FileUpload widget, the following Service Variable events are invoked after the upload of the files. + +| Event | Description | +| --- | --- | +| **Callback Events** | +| On Abort These events will appear only for the Service Variables targeting an upload service. | | +| On Before Update | These events are called just before the variable is triggered to hit the target service. “inputData” contains an object having key-value pairs of input fields (that appear under the “Data” tab of Variable definition dialog). The call to the target service from the variable can be prevented by assigning a JavaScript function to this event and returning false from this function. If input data needs modification or validation, it should be done at this place. | +| On Result | This event is triggered as soon as the variable receives a response from the target service. onResult is called whether or not there was an error generated. An additional last argument as the “operation-name” that holds the invoked operation is present for Database CRUD Variables. | +| On Progress These events will appear only for the Service Variables targeting an upload service. | A progress bar is displayed below the file selector, this is handled by file widget. User can perform actions on the onProgress event. However, the default progress bar shown is not hidden on providing a handler to this event. | +| On Error | This event is called if there is an error generated during the Service call. An additional last argument as the “operation-name” that holds the invoked operation is present for Database CRUD Variables. | +| On Before Dataset Ready | This event is triggered just before the variable’s dataSet property is updated with the data received from the target service (after onResult). This event handler gives you the opportunity to manipulate the data before your variable’s dataSet property is assigned this value. If you want to add rows to a Grid or List or Select, this is a good way to add in extra items into your results before your variable is set and your widget is updated. The new data can be returned from here in order to update the Variable’s dataSet. | +| On Can Update | This event is triggered just before the variable’s dataSet property is updated with the data received from the target service (after onResult). This event handler gives you the opportunity to manipulate the data before your variable’s dataSet property is assigned this value. If you want to add rows to a Grid or List or Select, this is a good way to add in extra items into your results before your variable is set and your widget is updated. The new data can be returned from here in order to update the Variable’s dataSet. | +| On Success | Allows you to trigger an action when the Variable has completed its life cycle. Any component bound to the resultant dataSet of this Variable will be updated just before this event is triggered. So, If you want to trigger another Variable which is dependent on the dataSet of this Variable, the Variable should be triggered by this event. An additional last argument as the “operation-name” that holds the invoked operation is present for Database CRUD Variables. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form/radioset.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form/radioset.md new file mode 100644 index 000000000..d11bbd6e5 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form/radioset.md @@ -0,0 +1,53 @@ +--- +title: "Radioset" +id: "radioset" +--- + +Radioset allows you to group a set of radio buttons under a common heading. You need to bind to a dataset to display a radio button for each value. + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the button. Special characters and spaces are not allowed in widget name. | +| **Accessibility** | +| Tab Index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| Height | The height of your widget can be specified in _em, pt, px_ or _% (_i.e _50px, 75%)._ | +| Layout | This property controls how contained widgets are displayed within this widget container - inline or stacked. | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| Dataset | +| Value | Set this property to a variable to populate the list of values to display. | +| Use Keys | Use the keys of the live variable object as checkboxset options. | +| Data field | This property sets the dataValue to be returned by a select editor when the list is populated using the dataSet property. | +| Display Field | This property sets the displayValue to show in the select editor when the list is populated using the dataSet property. | +| Display Expression | This is an advanced property that gives more control over what is displayed in the drop-down select list. A Display Expression uses a Javascript expression to format exactly what is shown. | +| Order by | This allows for multiple selections for ordering the display of rows based on fields in asc or desc order - up arrow for asc and down arrow for desc. | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Read only | Selecting this checkbox property prevents the user from being able to change the data value of a widget. | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the widget becomes display-only and user input will not be accepted. It can also set programmatically by binding it to a boolean type variable. | + +## Events + +| **Event** | **Description** | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| **Mouse Events** | +| On click | It is an HTML button. It is used to generate a click event. For example, save button. | +| On mouse enter | This event handler is called whenever the mouse enters the widget. | +| On mouse leave | This event handler is called whenever the mouse leaves the widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the widget is tapped. | + +## Use Cases + +- [Working with Selection Widgets](/learn/how-tos/selection-widgets-use-case/) +- [How to use Radioset widget to filter a List](/learn/how-tos/radioset-filter-list/) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/form/switch.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/form/switch.md new file mode 100644 index 000000000..b4af00312 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/form/switch.md @@ -0,0 +1,45 @@ +--- +title: "Switch" +id: "switch" +--- + +**Switch widget** can help switching between 3 or more different options by pressing a single key. + +## Properties + +| Property | Description | +| --- | --- | +| Name | The name is a unique identifier for Switch widget. | +| **Accessibility** | +| Hint | Any text or an HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. By default, it is set to _yes_. | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. By default, it is set to _yes, no, maybe_. | +| Data field | This property sets the dataValue to be returned by a select editor when the list is populated using the dataSet property. | +| Display field | This property sets the displayValue to show in the select editor when the list is populated using the dataSet property. | +| Order by | This allows for multiple selections for ordering the display of rows based on fields in asc or desc order - up arrow for asc and down arrow for desc | +| **Validation** | +| Required | A required editor in wm.LiveForm may refuse to save without a required field. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Disabled | If the disabled property is true (checked) the value of the editor cannot change. The widget becomes display-only. | + +## Events + +| **Event** | **Description** | +| --- | --- | +| Change | This event handler is called each time your element's value changes. | +| **Mouse Events** | +| On click | This event handler is called whenever the click event is triggered on a widget. | +| On mouse enter | This event occurs when the pointer is moved onto a widget. | +| On mouse leave | The mouse leave event occurs when the mouse pointer leaves a widget. | +| **Touch Events** | +| On tap | This event handler is called whenever the tap event is triggered on a widget. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/iframe-dialog.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/iframe-dialog.md new file mode 100644 index 000000000..9f328abd4 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/iframe-dialog.md @@ -0,0 +1,79 @@ +--- +title: "IFrame Dialog" +id: "iframe-dialog" +--- +--- + +[![iframe_struct](/learn/assets/iframe_struct.jpg)](/learn/assets/iframe_struct.jpg) + +## Overview +Dragging and dropping a dialog creates a **view** containing the dialog. The view can be selected from the **Page Structure** or from the **tabs** given at the bottom. The display of the dialog box at runtime is usually associated with the _onClick_ event of a **Button** widget. You can also trigger the dialog by calling methods from _JavaScript_. + +## Iframe Dialog + +An Iframe Dialog is a popup window that displays content from an external source (URL) in a dialog. It has an **URL** property, where you mention the external source for the content. + +**Note:** Since WaveMaker is secured, only secure URLs can be displayed in the Iframe. + +[![](/learn/assets/dialog_iframe.png)](/learn/assets/dialog_iframe.png) + +## Script Access + +**Dialog** widget in your project can be accessed by associating the open and _close_ properties of the dialog with an event of any other widget. The dialog can be accessed through scripting by adding _DialogService_ to the _page controller_ and adding the code for _open_ and _close_ as shown below, here we are displaying an alert dialog on click of a button: Click event of the button should trigger the following JavaScript code: + +``` +Page.button3Click = function($event, widget) { + Page.Widgets.iframedialog1.open(); + } +``` + +For hiding dialog: + +```js +/* function called on button1 click */ + Page.button1Click = function($event, widget) { + Page.Widgets.iframedialog1.close(); + }; +``` + +## Properties & Events +--- +### Iframe Dialog Properties + +Check this if you want the provided URL to be encoded at the run time. + +| Property | Description | +| --- | --- | +| Title | Set the title of iframe dialog. | +| Name | The name is a unique identifier for iframe dialog. | +| Ok Text | This widget gives a pop-up window. It can be used to provide contextual information from an HTML source to the user. For example, here is a sample from the source. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** || +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Show Header | Show/hide header of the iframe dialog. | +| Modal | This property, if set true, adds a backdrop for the dialog restricting the closure of the dialog when the user clicks outside of the dialog. The default value is false, which allows close of dialog on click outside. | +| **Content** | +| Url | Any URL entered for this property will be shown in the dialog content. | +| **Behavior** | +| Enable Default Close Action | This property allows the user to access close action from header through an "x" icon; and also enables close through ESC key. | +| Show actions | This property shows/hides actions section of the iframe dialog. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| Encode URL | Check this if you want the provided URL to be encoded at the run time. Enabling this property will encode the special characters in the URL and enable rendering of the page which otherwise might fail. By default, it is set to false. | +| Keyboard | This property if set true allows closing of dialog on ESC keypress. The default is true. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. | +| Icon Width | Optional property; but you will need this if you are using the button's iconUrl. Please enter the width of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Height | Optional property; but you will need this if you are using the button's iconUrl. Please enter the height of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | + +### Iframe Dialog + +| Event | Description | +| --- | --- | +| **Callback Events** || +| On ok | This event handler is called whenever an ok event is triggered. | +| On close | This event handler is called whenever a close event is triggered. | +| On open | This widget gives a pop-up window. It can be used to give a warning message to the user. For example, you are about to leave this page. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/login-dialog.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/login-dialog.md new file mode 100644 index 000000000..19dbc2c9f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/login-dialog.md @@ -0,0 +1,70 @@ +--- +title: "Login Dialog" +id: "login-dialog" +--- +--- + +[![login_struct](/learn/assets/login_struct.jpg)](/learn/assets/login_struct.jpg) + +## Overview + +Dragging and dropping a dialog creates a **view** containing the dialog. The view can be selected from the **Page Structure** or from the **tabs** given at the bottom. The display of the dialog box at runtime is usually associated with the _onClick_ event of a **Button** widget. You can also trigger the dialog by calling methods from _JavaScript_. + +## Login Dialog + +Login Dialog is a popup window that displays Login page content and can be dismissed by the user. Especially used to refresh the membership or for additional confirmation. The events that can be set include _onSuccess_, _onError_ and _onClose_. + +[![dialog_login](/learn/assets/dialog_login.png)](/learn/assets/dialog_login.png) + +## Script Access + +**Dialog** widget in your project can be accessed by associating the open and _close_ properties of the dialog with an event of any other widget. The dialog can be accessed through scripting by adding _DialogService_ to the _page controller_ and adding the code for _open_ and _close_ as shown below, here we are displaying an alert dialog on click of a button: Click event of the button should trigger the following JavaScript code: + +```js +Page.button3Click = function($event, widget) { + Page.Widgets.logindialog1.open(); + } +``` + +For hiding dialog: + +```js +/* function called on button1 click */ + Page.button1Click = function($event, widget) { + Page.Widgets.logindialog1.close(); + }; +``` + +## Properties & Events +--- + +### Login Dialog Properties + +| Property | Description | +| --- | --- | +| Title | Set the title of the widget. | +| Name | The name is a unique identifier for the widget. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Modal | This property, if set true, adds a backdrop for the dialog restricting the closure of the dialog when the user clicks outside of the dialog. The default value is false, which allows close of dialog on click outside. | +| **Behavior** | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| Keyboard | This property if set true allows closing of dialog on ESC keypress. The default is true. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. | +| Icon Width | Optional property; but you will need this if you are using the button's iconUrl. Please enter the width of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Height | Optional property; but you will need this if you are using the button's iconUrl. Please enter the height of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | + +### Login Dialog Events + +| Event | Description | +| --- | --- | +| **Callback Events** | +| On submit | This event handler is called whenever a submit event is triggered. | +| On close | This event handler is called whenever a close event is triggered. | +| On open | This widget gives a pop-up window. It can be used to give a warning message to the user. For example, you are about to leave this page. | +| On success | This event handler is called whenever a success event is triggered. | +| On error | This event handler is called whenever an error event is triggered. | + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/barcode-scanner.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/barcode-scanner.md new file mode 100644 index 000000000..0fa8c3c5b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/barcode-scanner.md @@ -0,0 +1,114 @@ +--- +title: "Barcode Scanner" +id: "barcode-scanner" +--- +--- + +**Barcode** is a number encoded in a sequence of bars (vertical line). It is used for machine reading the number.  A common example where barcode scanning is used is billing in supermarkets. Bill desk employees add a product to the bill by just scanning the product’s barcode. Barcode scanner widget brings this scanning functionality to mobile devices. + +**Barcode Scanner widget** is a button which, when clicked, opens the device camera for scanning. The scanned information will be available as ‘datavalue’ outbound property. + +## Features + +Barcode scanner has two main properties. + +1. **Caption** to be displayed +2. **Icon class** for the icon to use. + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Caption | The caption is the text that the end user sees. | +| Name | The name is a unique identifier for the Barcode Scanner. Special characters and spaces are not allowed in widget name. | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Bar Code Format | You can restrict the format of the barcode to scan based on your app requirement. The format can be: - CODABAR (not supported in iOS), - CODE_39, - CODE_93 (not supported in iOS), - CODE_128, - DATA_MATRIX, - EAN_8, - EAN_13, - ITF - PDF_417 (not supported in iOS), - QR_CODE, - RSS14 (not supported in iOS), - RSS_EXPANDED (not supported in iOS), - UPC_E, - UPC_A, - ALL is the default setting. This option can be used to scan any barcode format listed above except PDF_417 and RSS_EXPANDED. | +| **Graphics** | +| Icon Class | This bindable property defines the class of the icon that is applied to the button. | +| Icon Size | This property defines the size of the icon. Value has to be specified along with the units (em or px). | +| **Format** | +| Horizontal Align | This property specifies how the elements should be aligned horizontally - left, center or right. | + +## Events + +- **On Success** - The event listener to call when the barcode is successfully scanned. +Two parameters are passed -  event object and isolate scope of the widget. + +## Use Cases +--- + +## Overview + +Barcode Scanner can be used to scan and encode a barcode sequence. **Example: Barcode Scanner Usage with Web Service for book details from scanned book barcode** In this post, we will be creating a page that has a button to scan a book’s barcode. When a book’s barcode is scanned, information about the book has to fetched using google books API and barcode. [![](/learn/assets/book_barcode_run3.png)](/learn/assets/book_barcode_run3.png) + +## Step 1: Data + +1. Open or Create a Hybrid Mobile App. +2. From the **Resources** section, click on **Web Services** option >> Plus Icon>> Rest services to import the Google books API rest web service. +3. Use the following **Url**: https://www.googleapis.com/books/v1/volumes?q={q} +4. Enable **Advanced Settings** and specify following parameters: + - Headers Name: q + - Test Value: 0141912499 +5. Click **TEST** at the bottom of the dialog. +6. Once the response appears, click **NEXT** +7. Click **IMPORT** + +[![](/learn/assets/book_barcode_service.png)](/learn/assets/book_barcode_service.png) + +## Step 2: Layout + +1. Create a page with _basic profile template_. + +[![](/learn/assets/book_barcode_template.png)](/learn/assets/book_barcode_template.png) + +2. Drag and drop _barcode scanner_ widget on the page. + +[![](/learn/assets/book_barcode_design.png)](/learn/assets/book_barcode_design.png) + +## Step 3: Variable & Binding + +1. Create a page level **API variable** to use the imported google books API. + +[![](/learn/assets/book_barcode_sv.png)](/learn/assets/book_barcode_sv.png) + +2. Bind the value of q with barcode scanner ‘dataValue’ property and save the variable. + +[![](/learn/assets/book_barcode_svdata.png)](/learn/assets/book_barcode_svdata.png) + +[![](/learn/assets/book_barcode_svdatabind.png)](/learn/assets/book_barcode_svdatabind.png) + +### Steps on the binding page + +- Bind Card Image to book thumbnail of the Variable. +- Bind Caption of Main Label to the book title. +- Bind Caption of the Last Label to the book description. +- Bind Show property of Tile such that tile will be shown only if there is book information. + +[![](/learn/assets/book_barcode_showbind.png)](/learn/assets/book_barcode_showbind.png) + +3. Drag and Drop a Label to the page, set Caption property to ‘Book Not found’. Bind the Show property this label such that this label is shown when the Variable does not return any books. + +[![book_barcode_showbind2](/learn/assets/book_barcode_showbind2.png)](/learn/assets/book_barcode_showbind2.png) + +4. On the success of barcode scanner, invoke the created variable. + +[![](/learn/assets/book_barcode_event.png)](/learn/assets/book_barcode_event.png) + +## Step 4: Build & Run + +1. Build the apk, install it on an android phone and open the app. + +[![](/learn/assets/book_barcode_run1.png)](/learn/assets/book_barcode_run1.png) + +2. Click on ‘scan a book’ button. The camera will open for barcode scanning. Point the camera at any book barcode. + +[![](/learn/assets/book_barcode_run2.png)](/learn/assets/book_barcode_run2.png) + +3. Book data will come up on the app, provided google has the book information. + +[![](/learn/assets/book_barcode_run3.png)](/learn/assets/book_barcode_run3.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/camera.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/camera.md new file mode 100644 index 000000000..ba08dee7d --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/camera.md @@ -0,0 +1,82 @@ +--- +title: "Camera" +id: "camera" +--- + +**The camera** is a**button based widget that opens device camera for taking photos or videos. The path of the photo or video captured is exposed as outbound property ‘localFilePath’.** + +## Features + +The camera can be used for taking a picture or video. To specify the mode of the camera, set the **Capture Type** property to Image or Video. + +Following **Image Properties** can be further configured: + +- _Target Width_ _-_ A picture is scaled to this property’s value while maintaining the image’s aspect ratio. +- _Target Height_ _-_A picture is scaled to this property’s value while maintaining the image’s aspect ratio. If both target width and target height are specified, then the image will be scaled to the minimum of them. +- _Encoding Type_ _-_ the format in which the image has to be saved. Supported formats are JPEG and PNG. +- _Image Quality_ _-_ This is JPEG compression level in percentage. So, this value is used only when JPEG is selected as encoding type. If the value is 100, then no compression is applied to the image. +- _Save To Gallery_ _-_ If turned on, then photos taken using this widget will be saved to the device gallery. +- _Edit_ _-_ If this property is checked, then the user can edit or crop the picture taken. + +You can use the _localFilePath_ and _localFile_ to further enhance the app functionality. These properties are passed as parameters for Camera Success Event. See  [Use Case](#store-image) for more details. + +[![](/learn/assets/camera_bind.png)](/learn/assets/camera_bind.png) + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the Camera. Special characters and spaces are not allowed in widget name. | +| **Accessibility** | +| Hint | Any text or HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Capture Type | This specifies whether the image or video that is to be captured. | +| **Graphics** | +| Icon Class | This bindable property defines the class of the icon that is applied to the button. | +| Icon Size | This property defines the size of the icon. Value has to be specified along with the units (em or px). | +| **Format** | +| Horizontal Align | This property specifies how the elements should be aligned horizontally - left, center or right. | +| **Image Properties** | +| Target Width | This property specifies the width in px to resize the image. | +| Target Height | This property specifies the height in px to resize the image. | +| Image Quality | Quality of the saved image expressed as a range of 0-100, where 100 is typically full resolution with no loss of file compression | +| Encoding Type | Choose the returned image file's encoding. The default is JPEG. | +| Save to Gallery | Save the image to the photo album on the device after capture | +| Edit | Allow simple editing of the image before selection. | + +## Events + +- **On Success** - The event listener to call when a photo or video is successfully captured. This can be bound to a Database CRUD Variable of Insert operation, to save the picture into a database + +### Usage + +Capture an image using camera and store in the database using CRUD variable (we are using a Customer Database with pic as the blob type field): + +1. Bind the Input Fields from the Data tab for the CRUD Variable to the Camera -> localFile field [![](/learn/assets/camera_db_storefields.png)](/learn/assets/camera_db_storefields.png)[![](/learn/assets/camera_db_storebind.png)](/learn/assets/camera_db_storebind.png) +2. On Sucess event of Camera widget needs to invoke the above Insert Variable [![](/learn/assets/camera_db_storeevent.png)](/learn/assets/camera_db_storeevent.png) + +## Use Cases + +### Overview + +Camera Widget can be used to capture images and videos from a Mobile App In this post, we will create a mobile app to capture and display a photo. [![](/learn/assets/camera_run3.png)](/learn/assets/camera_run3.png) + +### Step 1: Building Page + +1. Create or Open a Hybrid Mobile App. +2. Create a page using _blank template_ and layout as ‘_One column layout with top navbar_’ [![](/learn/assets/camera_template.png)](/learn/assets/camera_template.png) [![](/learn/assets/camera_layout.png)](/learn/assets/camera_layout.png) +3. Drag and drop a _container widget_ and set horizontal align property as the center. +4. Drag and drop a camera widget. +5. Drag and drop a picture widget and set its width to 100%. [![](/learn/assets/camera_design.png)](/learn/assets/camera_design.png) +6. Bind the source of the picture to the ‘localFilePath’ of camera widget. [![](/learn/assets/camera_binding.png)](/learn/assets/camera_binding.png) + +### Step 4: Build & Run + +1. Build the apk, install it on an android phone and open the app. [![](/learn/assets/camera_run1.png)](/learn/assets/camera_run1.png) +2. Open the app and click camera button and take a photo. [![](/learn/assets/camera_run2.png)](/learn/assets/camera_run2.png) +3. The captured image will get displayed in the app. [![camera_run3](/learn/assets/camera_run3.png)](/learn/assets/camera_run3.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/camera/learn/app-development/widgets/mobile-widgets/camera.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/camera/learn/app-development/widgets/mobile-widgets/camera.md new file mode 100644 index 000000000..0a66a6451 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/camera/learn/app-development/widgets/mobile-widgets/camera.md @@ -0,0 +1,87 @@ +--- +title: "Camera" +id: "camera" +--- + +**The camera** is a**button based widget that opens device camera for taking photos or videos. The path of the photo or video captured is exposed as outbound property ‘localFilePath’.** + +## Features + +The camera can be used for taking a picture or video. To specify the mode of the camera, set the **Capture Type** property to Image or Video. + +Following **Image Properties** can be further configured: + +- _Target Width_ _-_ A picture is scaled to this property’s value while maintaining the image’s aspect ratio. +- _Target Height_ _-_A picture is scaled to this property’s value while maintaining the image’s aspect ratio. If both target width and target height are specified, then the image will be scaled to the minimum of them. +- _Encoding Type_ _-_ the format in which the image has to be saved. Supported formats are JPEG and PNG. +- _Image Quality_ _-_ This is JPEG compression level in percentage. So, this value is used only when JPEG is selected as encoding type. If the value is 100, then no compression is applied to the image. +- _Save To Gallery_ _-_ If turned on, then photos taken using this widget will be saved to the device gallery. +- _Edit_ _-_ If this property is checked, then the user can edit or crop the picture taken. + +You can use the _localFilePath_ and _localFile_ to further enhance the app functionality. These properties are passed as parameters for Camera Success Event. See  [Use Case](#store-image) for more details. [![](/learn/assets/camera_bind.png)](/learn/assets/camera_bind.png) + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the Camera. Special characters and spaces are not allowed in widget name. | +| **Accessibility** | +| Hint | Any text or HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| **Default Value** | +| Value | This is the default value to display value for an editor widget. Note that the display value is just what the user sees initially, and is not always the dataValue returned by the widget. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Capture Type | This specifies whether the image or video that is to be captured. | +| **Graphics** | +| Icon Class | This bindable property defines the class of the icon that is applied to the button. | +| Icon Size | This property defines the size of the icon. Value has to be specified along with the units (em or px). | +| **Format** | +| Horizontal Align | This property specifies how the elements should be aligned horizontally - left, center or right. | +| **Image Properties** | +| Target Width | This property specifies the width in px to resize the image. | +| Target Height | This property specifies the height in px to resize the image. | +| Image Quality | Quality of the saved image expressed as a range of 0-100, where 100 is typically full resolution with no loss of file compression | +| Encoding Type | Choose the returned image file's encoding. The default is JPEG. | +| Save to Gallery | Save the image to the photo album on the device after capture | +| Edit | Allow simple editing of the image before selection. | + +## Events + +- **On Success** - The event listener to call when a photo or video is successfully captured. This can be bound to a Database CRUD Variable of Insert operation, to save the picture into a database + +### Usage + +Capture an image using camera and store in the database using CRUD variable (we are using a Customer Database with pic as the blob type field): + +1. Bind the Input Fields from the Data tab for the CRUD Variable to the Camera -> localFile field [![](/learn/assets/camera_db_storefields.png)](/learn/assets/camera_db_storefields.png)[![](/learn/assets/camera_db_storebind.png)](/learn/assets/camera_db_storebind.png) +2. On Sucess event of Camera widget needs to invoke the above Insert Variable [![](/learn/assets/camera_db_storeevent.png)](/learn/assets/camera_db_storeevent.png) + +## Use Cases + +### Overview + +Camera Widget can be used to capture images and videos from a Mobile App In this post, we will create a mobile app to capture and display a photo. [![](/learn/assets/camera_run3.png)](/learn/assets/camera_run3.png) + +### Step 1: Building Page + +1. Create or Open a Hybrid Mobile App. +2. Create a page using _blank template_ and layout as ‘_One column layout with top navbar_’ [![](/learn/assets/camera_template.png)](/learn/assets/camera_template.png) [![](/learn/assets/camera_layout.png)](/learn/assets/camera_layout.png) +3. Drag and drop a _container widget_ and set horizontal align property as the center. +4. Drag and drop a camera widget. +5. Drag and drop a picture widget and set its width to 100%. [![](/learn/assets/camera_design.png)](/learn/assets/camera_design.png) +6. Bind the source of the picture to the ‘localFilePath’ of camera widget. [![](/learn/assets/camera_binding.png)](/learn/assets/camera_binding.png) + +### Step 4: Build & Run + +1. Build the apk, install it on an android phone and open the app. + +[![](/learn/assets/camera_run1.png)](/learn/assets/camera_run1.png) + +2. Open the app and click camera button and take a photo. + +[![](/learn/assets/camera_run2.png)](/learn/assets/camera_run2.png) + +3. The captured image will get displayed in the app. + +[![camera_run3](/learn/assets/camera_run3.png)](/learn/assets/camera_run3.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/media-list.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/media-list.md new file mode 100644 index 000000000..3f3279b91 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/media-list.md @@ -0,0 +1,81 @@ +--- +title: "Media List" +id: "media-list" +--- + +![](/learn/assets/phone.png)  **NOTE**: Media List is available only for mobile apps. + +**Media List Widget** can be used for displaying a list of pictures. Initially, a list with thumbnails of the pictures is displayed. When the user clicks on a thumbnail, then the original picture will be displayed. + +# Layouts + +Media List has two **layout options**: + +1. _Single-row_  where all the thumbnail images are displayed in a single row with horizontal scroll, and +2. _Multi-row_ where the thumbnail images are displayed in multiple rows. + +# Features + +**Dataset** of a Media List has the following properties: + +- _Value_ **- An array of objects that has the data for media list.** +- _Thumbnail URL_ - The data property which contains the URL for the picture’s thumbnail URL. +- _Media URL_ - The data property which contains the URL for the picture. + +**Media template** is a child container in Media List for which the width and height can be set. By default, the thumbnail will be shown in media template. Additional widgets can be added by drag and drop. + +# Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the Media List. Special characters and spaces are not allowed in widget name. | +| **Accessibility** | +| Hint | Any text or HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Layout | This property controls how contained widgets are displayed within this widget container - single-row or multi-row. | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. | +| Thumbnailurl | Field from the above Dataset value that holds the Thumbnail URL. | +| Mediaurl | Field from the above Dataset value that holds the Media URL. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | + +# Use Cases + +### Overview + +Media List can be used to display images in a Hybrid Mobile App. + +In this post, we will be creating a page with Media List to display employee’s pictures. We will be using the Sample HRDB for this example. [![](/learn/assets/medialist_run.png)](/learn/assets/medialist_run.png) + +### Step 1: Data + +1. Open or Create a Hybrid Mobile App. +2. From the **Resources section,** select Database and click on Add icon. Select Connect to a DB option >> Sample HRDB. +3. To create an appropriate variable, select the Variables >>New Variable>> Database CRUD option. In the New Variables window,  select the source as ‘hrdb’, type as ‘employee’ and operation as read. [![](/learn/assets/medialist_lv.png)](/learn/assets/medialist_lv.png) + +### Step 2: Design + +1. Drag and drop _Media List_ widget on the page. +2. Bind the _dataset value_ property of Medial List to ‘employees’ live variable dataset created in the previous step. [![](/learn/assets/medialist_bind.png)](/learn/assets/medialist_bind.png) +3. From the Properties panel set _Thumbnailurl_ and _Mediaurl_ to the _picurl_ property of the CRUD Variable. **NOTE**: In this example, we are using the original picture for both Thumbnail and Media. [![](/learn/assets/medialist_props.png)](/learn/assets/medialist_props.png) + +### Step 3: Preview App + +1. Click **Run** to preview the Media List. [![](/learn/assets/medialist_run.png)](/learn/assets/medialist_run.png) + +[10. Mobile & Device Widgets](/learn/app-development/widgets/widget-library/#mobile) + +- [10.1 Media List](/learn/app-development/widgets/mobile-widgets/media-list/) + - [i. Layouts](#layouts) + - [ii. Features](#features) + - [iii. Properties](#properties) + - [iv. Use Cases](#use-cases) +- [10.2 Segmented Control](/learn/app-development/widgets/mobile-widgets/segmented-control/) +- [10.3 Barcode Scanner](/learn/app-development/widgets/mobile-widgets/barcode-scanner/) +- [10.4 Camera](/learn/app-development/widgets/mobile-widgets/camera/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/segmented-control.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/segmented-control.md new file mode 100644 index 000000000..75e394bf2 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/mobile-widgets/segmented-control.md @@ -0,0 +1,79 @@ +--- +title: "Segmented Control" +id: "segmented-control" +--- + +![](/learn/assets/phone.png)  **NOTE**: Segmented Control is available only for mobile apps. + +**Segmented Control** is a group of buttons that toggle _Segmented Content_. + +**Segmented Content** is a sub-widget of segment control that holds the content of each segment.  On left swipe of a segmented content, the segment content next to it will be shown. On right swipe of a segmented content, the segment content previous to it will be shown. + +## Features + +A Segmented Control has three segments by default. Additional segments can be added by clicking on ‘_Add Segmented Content_’ button in widgets property panel. + +**NOTE:** To select a particular Segmented Control in design mode, click on any segment and press ‘ESC’ to select the segmented control. + +Each segment content has the following configurable properties. + +- ****Caption** - This property is for setting title for the segment,** +- **Load -** This property is to delay the content loading of invisible segments and thus reduce page load time. You can choose from three options: + - the default or blank denotes ‘Load immediately’,   + - after-select - segment content will be loaded on visible of the segment.  + - after-delay - segment content will be loaded after a time delay. +- **Load Delay** - In the case when the ‘load’ is after-delay, then content will be loaded after the number of milliseconds as specified on this property. +- **Icon Class -** Icon to use for the segment. + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for the Segmented Control. Special characters and spaces are not allowed in widget name. | +| Add Segmented Content | This action allows one to add multiple contents to the Segment Control. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | + +**Segment Content** SubWidget of Segmented Control, to hold content. + +| **Property** | **Description** | +| --- | --- | +| Caption | This bindable property defines the text that the end user sees. | +| Name | The name is a unique identifier for the segment content. Special characters and spaces are not allowed in widget name. | +| **Layout** | +| With | The width of the widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of the widget can be specified in px or % (i.e 50px, 75%). | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Load | This property defines the load behavior of the container can be: - after-select - load the content after selection of the content or - after-delay - load content after a time delay. | +| Load Delay | Time in milliseconds, after which the container has to be loaded. This property is used only when the load mode is set to 'after-delay'. | +| **Graphics** | +| Icon Class | This bindable property defines the class of the icon that is applied to the button. | +| **Format** | +| Horizontal Align | This property specifies how the elements should be aligned horizontally - left, center or right. | + +## Events + +### On segmented control + +- **On before segment change** -  The event Listener to call before changing to an another segment. Three parameters are passed: + 1. the scope of the widget, + 2. old selected segment index and + 3. newly selected index +- **On segment change** - The event Listener to call after changing to a segment. Three parameters are passed: + 1. the scope of the widget, + 2. old selected segment index and + 3. newly selected index + +### On each segment + +- **On ready** -  The event Listener to call when the content is loaded for the segment. Two parameters are passed: + 1. event object and + 2. the scope of the widget. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/modal-dialogs/modal-windows-dialogs.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/modal-dialogs/modal-windows-dialogs.md new file mode 100644 index 000000000..6041cc756 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/modal-dialogs/modal-windows-dialogs.md @@ -0,0 +1,283 @@ +--- +title: "Modal Windows/ Dialogs" +id: "modal-windows-dialogs" +--- + +WaveMaker provides the facility to add pop-up windows to your project through the **Dialog widgets**. Pop-up windows are a way to give additional information to users without cluttering your project space. This can be for alerts, getting additional information like user name, or for login purposes. There are six types of Dialog widgets provided by WaveMaker. + +[![alert_struct](/learn/assets/alert_struct.jpg)](/learn/assets/alert_struct.jpg) + +[![confirm_struct](/learn/assets/confirm_struct.jpg)](/learn/assets/confirm_struct.jpg) + +[![design_struct](/learn/assets/design_struct.jpg)](/learn/assets/design_struct.jpg) + +[![iframe_struct](/learn/assets/iframe_struct.jpg)](/learn/assets/iframe_struct.jpg) + +[![page_struct](/learn/assets/page_struct.jpg)](/learn/assets/page_struct.jpg) + +[![login_struct](/learn/assets/login_struct.jpg)](/learn/assets/login_struct.jpg) + +## Overview + +Dragging and dropping a dialog creates a **view** containing the dialog. The view can be selected from the **Page Structure** or from the **tabs** given at the bottom. The display of the dialog box at runtime is usually associated with the _onClick_ event of a **Button** widget. You can also trigger the dialog by calling methods from _JavaScript_. + +**Note:** Even though the dialog widget is placed in a view, that view is not available for navigation. + +[![](/learn/assets/dialog.png)](/learn/assets/dialog.png) + +# Features + +## Alert Dialog + +For **Alert Dialog**, you can set: + +- the name, the title of the alert pop-up, message to be displayed in the pop-up, text on the OK button and the type of alert - error, information, success or warning. +- the icon for display next to the title of the alert box, you can pick the icon from the [icon dialog](/learn/app-development/widgets/basic/icon/). + +[![](/learn/assets/dialog_alert.png)](/learn/assets/dialog_alert.png) + +## Confirm Dialog + +Confirm Dialog is used to get confirmation from the user. In addition to the properties mentioned for Alert Dialog, it has an additional **Cancel **button. The most common usage is to confirm a delete action. + +[![](/learn/assets/dialog_confirm.png)](/learn/assets/dialog_confirm.png) + +## Design Dialog + +Design Dialog gives a **Form** for obtaining additional information from the user, like the name. It is a composite widget with Labels and Text widgets. It comes with two buttons **Cancel **and **Save**. + +[![dialog_form](/learn/assets/dialog_form.png)](/learn/assets/dialog_form.png) + +## IFrame Dialog + +An Iframe Dialog is a popup window that displays content from an external source (URL) in a dialog. It has an **URL** property, where you mention the external source for the content. + +**Note:** Since WaveMaker is secured, only secure URLs can be displayed in the Iframe. + +[![](/learn/assets/dialog_iframe.png)](/learn/assets/dialog_iframe.png) + +## Login Dialog + +Login Dialog is a popup window that displays Login page content and can be dismissed by the user. Especially used to refresh the membership or for additional confirmation. The events that can be set include _onSuccess_, _onError_ and _onClose_. + +[![dialog_login](/learn/assets/dialog_login.png)](/learn/assets/dialog_login.png) + +## Page Dialog + +Page Dialog is a popup window that displays page content and can be dismissed by the user. The **content** property of this widget can be set to the desired [partial page](/learn/app-development/ui-design/page-concepts/partial-pages/) content. + +[![](/learn/assets/dialog_page.png)](/learn/assets/dialog_page.png) + +# Script Access + +**Dialog** widget in your project can be accessed by associating the open and _close_ properties of the dialog with an event of any other widget. The dialog can be accessed through scripting by adding _DialogService_ to the _page controller_ and adding the code for _open_ and _close_ as shown below, here we are displaying an alert dialog on click of a button: Click event of the button should trigger the following JavaScript code: + + +Page.button3Click = function($event, widget) { + Page.Widgets.alertdialog1.open(); + } + +For hiding dialog: + +/** function called on button1 click **/ + Page.button1Click = function($event, widget) { + Page.Widgets.alertdialog1.close(); + }; + +## Properties & Events + +### **Alert Dialog Properties** + +| **Property** | **Description** | +| --- | --- | +| Title | Set the title of an alert dialog. | +| Name | The name is a unique identifier for alert dialog. | +| Message | Set the message of the widget. | +| Ok Text | This widget gives a pop-up window. It can be used to give a warning message to the user. For example, you are about to leave this page. | +| Alert Type | This property will help in identifying the type of alert in the alert box. Can be set to error (default), information, success, and warning. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Modal | This property, if set true, adds a backdrop for the dialog restricting the closure of the dialog when the user clicks outside of the dialog. The default value is false, which allows close of dialog on click outside. | +| **Behavior** | +| Enable Default Close Action | This property allows the user to access close action from header through an "x" icon; and also enables close through ESC key. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| Keyboard | This property if set true allows closing of dialog on ESC keypress. The default is true. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. | +| Icon Width | Optional property; but you will need this if you are using the button's iconUrl. Please enter the width of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Height | Optional property; but you will need this if you are using the button's iconUrl. Please enter the height of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | + +| Event | Description | +| --- | --- | +| **Callback Events** | +| On ok | This event handler is called whenever an ok event is triggered. | +| On close | This event handler is called whenever a close event is triggered. | +| On open | This widget gives a pop-up window. It can be used to give a warning message to the user. For example, you are about to leave this page. | + +### **Confirm Dialog Properties** + +| Property | Description | +| --- | --- | +| Title | Set the title of the widget. | +| Name | The name is a unique identifier for the confirm dialog. | +| Message | Set the display message for the widget. | +| Ok Text | This Confirm Dialog prompts to get confirmation from the user. | +| Cancel Text | This widget gives a pop-up window. It can be used to get confirmation of an action from the user. For example, do you want to delete this item? | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Modal | This property, if set true, adds a backdrop for the dialog restricting the closure of the dialog when the user clicks outside of the dialog. The default value is false, which allows close of dialog on click outside. | +| **Behavior** | +| Enable Default Close Action | This property allows the user to access close action from header through an "x" icon; and also enables close through ESC key. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| Keyboard | This property if set true allows closing of dialog on ESC keypress. The default is true. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. | +| Icon Width | Optional property; but you will need this if you are using the button's iconUrl. Please enter the width of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Height | Optional property; but you will need this if you are using the button's iconUrl. Please enter the height of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | + +| Event | Description | +| --- | --- | +| **Callback Events** | +| On ok | This event handler is called whenever an ok event is triggered. | +| On cancel | This event handler is called whenever a cancel event is triggered. | +| On close | This event handler is called whenever a close event is triggered. | +| On open | This widget gives a pop-up window. It can be used to give a warning message to the user. For example, you are about to leave this page. | + +### **Design Dialog Properties** + +| Property | Description | +| --- | --- | +| Title | Set the title of the design dialog. | +| Name | The name is a unique identifier for design dialog. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Show Header | Show/hide header of the design dialog. | +| Modal | This property, if set true, adds a backdrop for the dialog restricting the closure of the dialog when the user clicks outside of the dialog. The default value is false, which allows close of dialog on click outside. | +| **Behavior** | +| Enable Default Close Action | This property allows the user to access close action from header through an "x" icon; and also enables close through ESC key. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. | +| Icon Width | Optional property; but you will need this if you are using the button's iconUrl. Please enter the width of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Height | Optional property; but you will need this if you are using the button's iconUrl. Please enter the height of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | + +| Event | Description | +| --- | --- | +| **Callback Events** | +| On close | This event handler is called whenever a close event is triggered. | +| On open | This widget gives a pop-up window. It can be used to give a warning message to the user. For example, you are about to leave this page. | + +### **Iframe Dialog Properties** + +Check this if you want the provided URL to be encoded at the run time. + +| Property | Description | +| --- | --- | +| Title | Set the title of iframe dialog. | +| Name | The name is a unique identifier for iframe dialog. | +| Ok Text | This widget gives a pop-up window. It can be used to provide contextual information from an HTML source to the user. For example, here is a sample from the source. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Show Header | Show/hide header of the iframe dialog. | +| Modal | This property, if set true, adds a backdrop for the dialog restricting the closure of the dialog when the user clicks outside of the dialog. The default value is false, which allows close of dialog on click outside. | +| **Content** | +| Url | Any URL entered for this property will be shown in the dialog content. | +| **Behavior** | +| Enable Default Close Action | This property allows the user to access close action from header through an "x" icon; and also enables close through ESC key. | +| Show actions | This property shows/hides actions section of the iframe dialog. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| Encode URL | Check this if you want the provided URL to be encoded at the run time. Enabling this property will encode the special characters in the URL and enable rendering of the page which otherwise might fail. By default, it is set to false. | +| Keyboard | This property if set true allows closing of dialog on ESC keypress. The default is true. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. | +| Icon Width | Optional property; but you will need this if you are using the button's iconUrl. Please enter the width of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Height | Optional property; but you will need this if you are using the button's iconUrl. Please enter the height of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | + +| Event | Description | +| --- | --- | +| **Callback Events** | +| On ok | This event handler is called whenever an ok event is triggered. | +| On close | This event handler is called whenever a close event is triggered. | +| On open | This widget gives a pop-up window. It can be used to give a warning message to the user. For example, you are about to leave this page. | + +### **Page Dialog Properties** + +| Property | Description | +| --- | --- | +| Title | Set the title of the widget. | +| Name | The name is a unique identifier for the widget. | +| Ok Text | This widget gives a pop-up window. It can be used to provide contextual information to the user. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. +NOTE: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Modal | This property, if set true, adds a backdrop for the dialog restricting the closure of the dialog when the user clicks outside of the dialog. The default value is false, which allows close of dialog on click outside. | +| **Content** | +| Content | Page's content to be included in the widget. | +| **Behavior** | +| Enable Default Close Action | This property allows the user to access close action from header through an "x" icon; and also enables close through ESC key. | +| Show actions | This property shows/hides actions section of the widget. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| Keyboard | This property if set true allows closing of dialog on ESC keypress. The default is true. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. | +| Icon Width | Optional property; but you will need this if you are using the button's iconUrl. Please enter the width of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Height | Optional property; but you will need this if you are using the button's iconUrl. Please enter the height of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | + +| Event | Description | +| --- | --- | +| On load | This event handler is called when the widget is loaded. | +| **Callback Events** | +| On ok | This event handler is called whenever an ok event is triggered. | +| On close | This event handler is called whenever a close event is triggered. | +| On open | This widget gives a pop-up window. It can be used to give a warning message to the user. For example, you are about to leave this page. | + +### **Login Dialog Properties** + +| Property | Description | +| --- | --- | +| Title | Set the title of the widget. | +| Name | The name is a unique identifier for the widget. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Modal | This property, if set true, adds a backdrop for the dialog restricting the closure of the dialog when the user clicks outside of the dialog. The default value is false, which allows close of dialog on click outside. | +| **Behavior** | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| Keyboard | This property if set true allows closing of dialog on ESC keypress. The default is true. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. | +| Icon Width | Optional property; but you will need this if you are using the button's iconUrl. Please enter the width of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Height | Optional property; but you will need this if you are using the button's iconUrl. Please enter the height of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | + +| Event | Description | +| --- | --- | +| **Callback Events** | +| On submit | This event handler is called whenever a submit event is triggered. | +| On close | This event handler is called whenever a close event is triggered. | +| On open | This widget gives a pop-up window. It can be used to give a warning message to the user. For example, you are about to leave this page. | +| On success | This event handler is called whenever a success event is triggered. | +| On error | This event handler is called whenever an error event is triggered. | + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/modal-windows-dialogs.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/modal-windows-dialogs.md new file mode 100644 index 000000000..059c7d13c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/modal-windows-dialogs.md @@ -0,0 +1,16 @@ +--- +title: "Modal Windows/ Dialogs" +id: "modal-windows-dialogs" +--- +--- + +WaveMaker provides the facility to add pop-up windows to your project through the **Dialog widgets**. Pop-up windows are a way to give additional information to users without cluttering your project space. This can be for alerts, getting additional information like user name, or for login purposes. There are six types of Dialog widgets provided by WaveMaker. + +## Dialog Widgets + +- [Alert Dialog](alert-dialog.md) +- [Confirm Dialog](confirm-dialog.md) +- [Design Dialog](design-dialog.md) +- [Iframe Dialog](iframe-dialog.md) +- [Login Dialog](login-dialog.md) +- [Page Dialog](page-dialog.md) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/breadcrumb-use-cases.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/breadcrumb-use-cases.md new file mode 100644 index 000000000..71bda2b24 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/breadcrumb-use-cases.md @@ -0,0 +1,98 @@ +--- +title: "Creating Breadcrumb" +id: "breadcrumb-use-cases" +sidebar_label: "Creating a Breadcrumb" +--- +--- + +Learn how to use a **Breadcrumb** widget. + +Breadcrumbs are a type of secondary navigation and they help users to recognize the hierarchy, and they are typically placed in a horizontal form under the header or navigation of the website. The starting point for the breadcrumb begins from the home page and it is considered as the first level. + +## Creating Breadcrumb with three pages + +**Scenario**: Consider an app with three pages - Main, First and Second Pages. Breadcrumb in the First Page will enable one to navigate to Main Page, while the one in Second Page will provide navigation to First and Main Page. + +[![breadcrumb](/learn/assets/bc_run1.png)](/learn/assets/bc_run1.png) + +[![breadcrumb](/learn/assets/bc_run2.png)](/learn/assets/bc_run2.png) + +### Create App + +Create an app with three pages - Main, Page1, and Page2. We have used Employee Profile and Admin Dashboard templates for Page1 and Page2 respectively. + +### Create Variable + +- Click the Variable option under Variables in Workspace Toolbar. Click **New Variable** and then click **Model**.  Choose the Application as Owner i.e. Application scoped. + +[![create varriable](/learn/assets/Var_create.png)](/learn/assets/Var_create.png) + +- In the text editor of the Model Variable, enter the following code: This code sets values for the properties of _label, id, icon, and link_ to be displayed on the breadcrumb. + - _label_ and _icon_ are the name and icon displayed on the Breadcrumb, + - _a link_ is an action to be performed when the Breadcrumb item is clicked, + - _id_ is the identifier for the current page i.e the page name. The Breadcrumb will search for the page name in this dataset and gets the first possible path for the page. + - _children_ will be a repeat of the entire structure in case you want a sub-menu like structure + +```json +[{ +"label": "Main Page", +"icon": "glyphicon glyphicon-home", +"link": "#/Main", +"id": "Main", +"children": [ + { + "label": "First Page", + "icon": "wi wi-ellipsis-v", + "link": "#/Page1", + "id": "Page1", + "children": [ + { + "label": "Sub Page1", + "id": "subPage11", + "icon": "wi wi-euro-symbol" + }, + { + "label": "Sub Page2", + "id": "subPage12", + "icon": "wi wi-euro-symbol", + "link": "#/subPage12" + } + ] + } + ]}, + { + "label": "Page2", + "id": "Page2", + "icon": "wi wi-euro-symbol", + "link": "#/Page2" + } +] +``` + +[![breadcrumb variable](/learn/assets/bc_var.png)](/learn/assets/bc_var.png) + +### Binding Variable with Breadcrumb Widget + +- Drag and drop **Breadcrumb widget** onto the canvas of FirstPage +- Bind the **value (under dataset) property** to the Model **dataset** which we have created above and set the **Action** properties to the corresponding fields from the Model. + +[![breadcrumb properties](/learn/assets/bc_props.png)](/learn/assets/bc_props.png) + +### Steps for another Page + +- Open the **Page2** and repeat the above steps. + +## Run the app + +- Run the app, see the breadcrumb displayed in the First and Second pages. Clicking on the links will navigate to the previous pages +- In the above Model, structure the provision to have Breadcrumb for sub-levels is also given, for example, Page1 has two sub-pages subPage11 and subPage12. This will help in setting the path for the sub-pages. + +:::note +If the ID's are repeating then the first possible path will be shown in the breadcrumb. +::: + +## See Also + +[Creating a Dropdown Menu](/learn/app-development/widgets/navigation/dropdown-menu-use-cases) +[Creating Navigation](/learn/app-development/widgets/navigation/nav-basic-usage) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/breadcrumb.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/breadcrumb.md new file mode 100644 index 000000000..cf0b3d82c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/breadcrumb.md @@ -0,0 +1,45 @@ +--- +title: "Breadcrumb Overview" +id: "breadcrumb" +--- +--- + +:::note +Breadcrumb is available only for web responsive apps. +::: + +**Breadcrumb** is a _Navigation widget_ which will specify the path taken to reach the current page. Breadcrumb widget is to _show the site hierarchy_. Breadcrumb navigation can greatly enhance the accessibility of the websites by indicating the user where they are in relation to the rest of the site when they navigate. + +Most websites organize their content by a hierarchy. Some are shallow and some are deep depending on the amount of content. It is advisable to use breadcrumb navigation if the user’s hierarchy contains 3 levels or more. + +[![](/learn/assets/bc_run2.png)](/learn/assets/bc_run2.png) + +:::note +You can apply Smart Template and Layout for Breadcrumb widget. For more information, see [How to apply Smart Template and Layout for Widgets](/learn/how-tos/widget-template-layout). +::: + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for your widget. Each page element and component must be uniquely identified. WaveMaker automatically renames any non-unique element. Special characters and spaces are not allowed in widget name. | +| **Layout** | +| Height | The height of breadcrumb can be specified in px or % (i.e 50px, 75%). | +| Width | The width of breadcrumb can be specified in px or % (i.e 50px, 75%). | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. | +| **Actions** | +| Action Label | Label for the breadcrumb item. Bindable or pick from the list generated from the Dataset Value variable specified. | +| Action Icon | Class for the icon in the breadcrumb. Example- 'fa fa-ban' or 'glyphicon glyphicon-cloud'. Bindable or pick from the list generated from the Dataset Value variable specified. | +| Anchor Link | Link for the breadcrumb. Bindable or pick from the list generated from the Dataset Value variable specified. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| **Format** | +| Horizontal Align | Set text alignment horizontally. | + +## See Also + +[Creating a Breadcrumb](/learn/app-development/widgets/navigation/breadcrumb-use-cases/) +[Dropdown Menu](/learn/app-development/widgets/navigation/dropdown-menu/) +[Creating Navigation](/learn/app-development/widgets/navigation/nav-basic-usage) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/dropdown-menu-use-cases.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/dropdown-menu-use-cases.md new file mode 100644 index 000000000..ecd8cdc22 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/dropdown-menu-use-cases.md @@ -0,0 +1,86 @@ +--- +title: "Creating a Dropdown Menu" +id: "dropdown-menu-use-cases" +sidebar_label: "Creating a Dropdown Menu" +--- +--- + +This document talks of a simple Dropdown Menu usage. For usage example involving role-based menu access [see here](/learn/how-tos/restricting-menu-item-display-based-user-role/). + +In this section, we will walk through the steps to create a multi-level menu, with icons and links to pages at various levels. + +[![](/learn/assets/menu_run1.png)](/learn/assets/menu_run1.png) + +[![](/learn/assets/menu_run2.png)](/learn/assets/menu_run2.png) + +## Using a Model Variable + +We will be using a Model Variable for this example. + +1. Create or Open the app where you want to use the Dropdown Menu +2. Open the Variables dialog from the Variables menu and using New Variable create a Model variable ([Know more about variables)](/learn/app-development/variables/model-variable/). +3. Name the variable as _menudata_ and _s_elect _isList_ option_._ + +[![](/learn/assets/Dropdown_Var_create.png)](/learn/assets/Dropdown_Var_create.png) + +4. Add the following in the _Text Editor._ It defines the structure for Menu identifying _Label_, _Icon_, _Link_, and _Children_. Icons can be [halflings from glyphicons](http://glyphicons.com/) or [font awesome](https://fortawesome.github.io/Font-Awesome/cheatsheet/) icons. + +```json + [ + { + "label": "Main Page", + "icon": "glyphicon glyphicon-home", + "link": "#Main" + }, + { + "label": "Facebook", + "icon": "glyphicon glyphicon-user", + "link": "http://www.facebook.com" + }, + { + "label": "Search Engines", + "icon": "glyphicon glyphicon-search", + "children": [ + { + "label": "Google", + "icon": "glyphicon glyphicon-arrow-right", + "link": "http://www.google.com" + }, + { + "label": "Yahoo", + "icon": "glyphicon glyphicon-arrow-right", + "link": "http://www.yahoo.com" + } + ] + } + ] +``` + +:::note +If you follow this structure, WaveMaker picks the label, icon, link and children tags automatically. If you are using different tag names, then you need to specify them in the Menu property as shown in step: 4 +::: + +[![](/learn/assets/fieldeditor.png)![](/learn/assets/fieldeditor.png)](/learn/assets/fieldeditor.png) + +5. Bind the _Value_ property of the Menu widget to the model variable created in the previous step. + +[![](/learn/assets/menu_props.png)](/learn/assets/menu_props.png) + +6. Set the _Action label_, _Action icon_, _Action link_, _Sub actions_ to the appropriate item names from the model variable. + +:::note +If you have used the same names then you may skip this step. +::: + +7. Use the _Action link_ specified above to navigate to a page within the project, or an external URL. You can use the **On Select event** to invoke a dialog or call a variable. From the Events tab of Properties panel, set On Select event to JavaScript and use the following code. This code will check if the selected value of the Menu is My Account and open either a dialog or invoke a variable. + +```js +if($item.label=="My Account"){ + DialogService.open("DialogName"); + } +else{ + Page.Variables.logoutAction.invoke(); + } +``` + +8. Run the application and see the menu in action. diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/dropdown-menu.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/dropdown-menu.md new file mode 100644 index 000000000..31563a1b4 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/dropdown-menu.md @@ -0,0 +1,98 @@ +--- +title: "Dropdown Menu" +id: "dropdown-menu" +--- +--- + +A **menu** displays grouped navigation actions. The drop-down menu is typically used inside the navigation header to display a list of related links on a mouse hover or click on the trigger element. + +Dropdown Menu can be used as: + +1. **Command menus**, which initiate an action based on the option user selects. Each menu item consists of a discrete option or action that can affect the app, the view, or selected elements within a view. +2. **Navigation menus**, which take users to a new location. Note that menus should not be used as a primary method for navigation within an app. + +**WaveMaker Dropdown Menu** widget allows one to display a label, an icon and a link to be opened on click event. The data source for the Menu can be a Model variable or from a database. The structure of the data source should contain fields which can be set: + +- **Action label** - usually caption; +- **Action icon** - some graphic image; +- **Action link** - specifying the action to be performed and +- **sub action** for a nested menu structure. + +The **Menu Layout** - _horizontal_ or _vertical_ and **Menu Position** can be set as per the app requirements + +[![](/learn/assets/menu_run2.png)](/learn/assets/menu_run2.png) + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Caption | The caption is the text that the end user sees on the Menu label. | +| Name | The name is a unique identifier for Menu. | +| **Accessibility** | +| Hint | Any text or HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. It can be bound to a variable. | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. | +| Shortcut Key | The shortcut key property specifies a shortcut key to activate/focus an element. (*[See below for details](#shortcut)) | + +:::note +In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". +::: + +| | | +| --- | --- | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Menu Layout | _Vertical_ layout arranges the menu items vertically. _Horizontal_ layout arranges the menu items horizontally. | +| Menu Position | Position of the menu list items - inline, down-right, down-left, up-left, up-right. | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. | +| Order by | Set this property to order the Menu items. | +| **Actions** | +| Action Label | Label for menu items. It can be bound to a variable or set to a field from the Dataset Value variable. | +| Action Icon | Label for menu items. It can be bound to a variable or set to a field from the Dataset Value variable. | +| Action Link | Link for the items. It can be bound to a variable or set to a field from the Dataset Value variable. | + +:::note +Item link has priority over _onSelect_ actions i.e. when the link is selected the onSelect actions won't get executed. +::: + +| | | +| --- | --- | +| Action Task | Task for menu items generated dynamically. This is the action that will be triggered when the user clicks on the Menu Item. It can be a script like: `Widgets.label1.show` or `Variables.v1.invoke()` Execution order on click of Node: 1. If provided _onSelect_ will be executed first. 2. If provided _Action_ will be executed next. 3. If provided _Action link_ will be executed last. | +| User Role | Role for menu items generated dynamically. You can assign the property to 'userrole' which contains comma separated user roles. Each item will be evaluated with given 'userrole' for that item to that of the logged in user roles, from security. If any of the user roles bound to 'userrole' property matches then that menu item will be shown else will be hidden. | +| Sub Actions | When a menu widget is required the sub-items can be mentioned in the children. It can be bound to a variable or set to a field from the Dataset Value variable. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Link Target | This defines the app behavior on click of the Item Link. - `_blank` Opens the linked document in a new window or tab; - `_self` Opens the linked document in the same frame as it was clicked (this is the default value); - `_parent` Opens the linked document in the parent frame; - `_top` Opens the linked document in the full body of the window. | +| Auto Close | This property defines the behavior of menu closing, it can be: - outsideClick - close the menu when clicked outside of the menu, - always - when a menu item is selected or on click outside menu, or - disabled - do not close once opened. | +| Animation on to content | This property controls the animation of the menu items. It can be set to _slide, fade, or scale_. Note: This feature works only in the run mode. | +| **Graphics** | +| Icon Class | This bindable property defines the class of the icon that is applied to the button. | +| **Format** | +| Horizontal Align | This property specifies how the elements should be aligned horizontally. It can be Left, Centered or Right | + +**Shortcut key**: The shortcut key property specifies a shortcut key to click the button. The way of accessing the shortcut key is varying in different browsers: + +| Browser | Shortcutkey Trigger | +| --- | --- | +| Internet Explorer | [Alt] + shortcut key | +| Chrome | [Alt] + shortcut key (_Windows/Linux_) | +| | [Control] [Alt] + shortcutkey (_MAC_) | +| Firefox | [Alt] [Shift] + shortcutkey (_Windows/Linux_) | +| | [Control] [Alt] + shortcutkey (_MAC_) | + +## Events + +| **Event** | **Description** | +| --- | --- | +| **Callback Events** | +| On Select | This event handler is called when the tab is selected. | + +## See Also + +[Creating a Dropdown Menu](/learn/app-development/widgets/navigation/dropdown-menu-use-cases) +[Creating Navigation](/learn/app-development/widgets/navigation/nav-basic-usage) +[Restricting Menu Items based on the User Role](/learn/how-tos/restricting-menu-item-display-based-user-role) +[Dynamic Menu based on the User Role](/learn/how-tos/dynamic-menu-based-user-role) +[Implementing Localization for Dropdown Menu](/learn/how-tos/implementing-localization-dropdown-menu) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/nav-bar.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/nav-bar.md new file mode 100644 index 000000000..941ca62c7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/nav-bar.md @@ -0,0 +1,42 @@ +--- +title: "Nav Bar Overview" +id: "nav-bar" +--- +--- + +:::note +Nav Bar is available only for web responsive apps. +::: + +**Nav Bar Widget** can be used to create responsive navigation header for your website or application. These responsive navbars are initially collapsed on devices having small viewports like cell-phones but expand when user click the toggle button. However, it will be horizontal as normal on the medium and large devices like laptop or desktop. + +You can also create different variations of the navbar such as navbars with drop-down menus and search boxes as well as fixed positioned navbar with much less effort. + + + +**WaveMaker Nav Bar** widget is used in the implementation of the default _topnav_ when the [page layout](/learn/app-development/ui-design/page-concepts/page-layouts/) is chosen to include the same. Following features are available: + +1. _Title_ and _image _for the navbar can be specified +2. Two _nav widgets_ are provided and each can be customized to include Anchor, Menu, Popover, Button. Each of these nav widgets is aligned to the left and right of the Nav Bar. [Click here for nav widget usage](/learn/app-development/widgets/navigation/nav/). + +## Properties + +| Property | Description | +| --- | --- | +| Title | Set the title of the Navbar. This name is used for the first (home) link of the navbar. | +| Name | The name is a unique identifier for Navbar. | +| Home Link | This property can be used to specify the URL for the home link. By default, this is set to the Home page set in the Project Configuration dialog. | +| **Layout** | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Image Source | This bindable property specifies the source for the brand image. The source can be either a file or a URL: - File: enter the directory and filename for the image to display (supported file types include .jpg, .gif and .png). By default, WaveMaker looks for images in the src/main/webapp directory of the project. - URL: enter a URL to any internet-accessible image. To display the file, foo.jpg, in the project directory `src/main/webapp/resources/images/imagelists/`, enter the following into the source property: `resources/images/imagelists/foo.jpg` or simply `foo.jpg` | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Menu icon | This property sets the icon for the menu button that will appear in the mobile layout ONLY. | + +## See Also + +[Navigation Properties and Events](/learn/app-development/widgets/navigation/nav) +[Basic Usage](/learn/app-development/widgets/navigation/nav-basic-usage/) +[Creating a Dropdown Menu](/learn/app-development/widgets/navigation/dropdown-menu-use-cases) +[Dynamic Menu based on the User Role](/learn/how-tos/dynamic-menu-based-user-role) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/nav-basic-usage.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/nav-basic-usage.md new file mode 100644 index 000000000..9c9a7ae7a --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/nav-basic-usage.md @@ -0,0 +1,128 @@ +--- +title: "Navigation - Basic Usage" +id: "nav-basic-usage" +sidebar_label: "Creating navigation" +--- +--- + +## Steps to Create Navigation + +In this post, we will walk through the steps to create a simple navigation, with icons and links to pages. + +[![](/learn/assets/nav_run.png)](/learn/assets/nav_run.png) + +We will be using a Model Variable for the purpose of this example: + +1. Create or Open page where you want to use the Nav Widget. +2. Open the Variables dialog from the Variables menu and using New Variable create a Model variable ([Know more about variables)](/learn/app-development/variables/model-variable/). + +[![](/learn/assets/Nav_Var_create.png)](/learn/assets/Nav_Var_create.png) + +3. Create a new Model Variable called as _navvar_ and select _isList_. + +[![](/learn/assets/nav_var.png)](/learn/assets/nav_var.png) + +4. Add the following in the _Text Editor_, this defines the structure for Menu identifying _Label_, _Icon_, _Link_, _Badge Value_ and _sub-action_. Icons can be [halflings from glyphicons](http://glyphicons.com/) or [font awesome](https://fortawesome.github.io/Font-Awesome/cheatsheet/) icons. + +``` +[ + { + "label": "Home", + "Icon": "glyphicon glyphicon-home", + "Link": "#Main", + "badge-value": "2", + "sub-action": { + "label": "Sub-action" + } + }, + { + "label": "Projects", + "Icon": "wi wi-folder-open", + "Link": "#projects", + "badge-value": "3" + }, + { + "label": "Services", + "Icon": "wi wi-settings-applications", + "Link": "#services", + "badge-value": "1" + } +] +``` + +5. Bind the _Value_ property of the Menu widget to the variable created in the previous step. +6. Set the + + - _Action Label_ to label, + - _Action Icon_ to Icon, + - _Action Link_ to Link, + - _Item Badge_ to badge-value, + - _Sub Actions_ to sub-action. + + If you need you can modify the JSON structure given for the Model Variable and do the appropriate settings. + + [![](/learn/assets/nav_props.png)](/learn/assets/nav_props.png) + +7. Run the application and see the menu in action. + +## Multilevel Nav + +You can have multiple levels of nav-items. Follow the steps from the above example, replace the Variable JSON with the below code: + +``` +[ + { + "label": "item1", + "icon": "wi wi-euro-symbol", + "children": [ + { + "label": "sub-menu-item1", + "icon": "wi wi-euro-symbol" + }, + { + "label": "sub-menu-item2", + "icon": "wi wi-euro-symbol", + "children": [ + { + "label": "sub-menu-child-item1", + "icon": "wi wi-euro-symbol", + "children": [ + { + "label": "sub-menu-child-item1-item1", + "icon": "wi wi-euro-symbol", + "path": "/item1/item2/item1/item1" + }, + { + "label": "sub-menu-child-item1-item2", + "icon": "wi wi-euro-symbol", + "path": "/item1/item2/item1/item2" + } + ] + }, + { + "label": "sub-menu-child-item2", + "icon": "wi wi-euro-symbol" + } + ] + } + ] + }, + { + "label": "item2", + "icon": "wi wi-euro-symbol" + }, + { + "label": "item3", + "icon": "wi wi-euro-symbol" + }, + { + "label": "item4", + "icon": "wi wi-euro-symbol" + } +] +``` + +You will get the following nav. + +[![](/learn/assets/nested_nav_items.png)](/learn/assets/nested_nav_items.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/nav.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/nav.md new file mode 100644 index 000000000..f51ac6580 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/nav.md @@ -0,0 +1,69 @@ +--- +title: "Nav Overview" +id: "nav" +--- +--- + +The **Nav** element represents a section of a page that links to other pages or to parts within the page: a section with navigation links. + +**WaveMaker Nav** widget is used in the implementation of the default _leftnav_ and _rightnav_ when the [page layout](/learn/app-development/ui-design/page-concepts/page-layouts/) is chosen to include the same. Within an app, it can be used in two ways. + +## Binding Dataset + +Bind dataset for the nav elements using the _Value_ property and setting the _Action Items_ by mapping the properties from the value dataset to the action properties such as label, icon, link, badge value, sub actions. + +## Add Widgets +Provides widget to be added to the nav panels such as Anchor, Menu, Popover, Button. Depending upon the widgets added to the nav various properties can be set: + +1. _Anchor_: can have _hyperlink_ to specify the destination link, _target_ where the linked document should be opened +2. _Menu_: can specify the _layout_, _position_ and _value_-_action_ combination. [Click here for more on menu usage](/learn/app-development/widgets/navigation/dropdown-menu/) +3. _Popover_: can set the _content source_ and _content_ for further action. [Click here for Popover usage](/learn/app-development/widgets/navigation/popover/). +4. _Button_: _on click event_ can be set for page navigation + +## Nav Types & Layouts + +From the Properties panel,  you can set the Nav Types and Layout + + + +## Properties + +Action IconClass for the icon. Choose from the options available based upon the structure of the Dataset Value. + +| **Property** | **Description** | +| --- | --- | +| Name | The name is a unique identifier for Nav widget. | +| Type | Defines the display style, choose between _navbar_, _pills (default)_ or _tabs_. | +| Add Widget | This action button allows you to add widgets within the Nav. The available options are Anchor, Menu, Popover, or Button. | +| **Layout** | +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Layout | This property controls how contained widgets are displayed within this widget container. It can be stacked or justified | +| **Dataset** | +| Value | Set this property to a variable to populate the list of values to display. It can be bound to any Variable | +| Order by | This allows for multiple selections for ordering the display of rows based on fields in asc or desc order - up arrow for asc and down arrow for desc. The fields are auto-populated based upon the structure of Dataset Value | +| **Actions** | +| Action Label | Label for menu items. Choose from the options available based upon the structure of the Dataset Value. | +| Action Icon | Class for the icon for menu items. Example- 'fa fa-ban' or 'glyphicon glyphicon-cloud' | +| Action Link | Link for the anchor widget. Choose from the options available based upon the structure of the Dataset Value. | +| Action Task | Task for nav items. This is the action that will be triggered when the user clicks on the Nav Item. It can be a script like: Variables.v1.invoke() Execution order on click of Node: 1. If provided _onSelect_ will be executed first. 2. If provided _Action_ will be executed next. 3. If provided _Action link_ will be executed last. | +| User Role | Role for menu items generated dynamically. You can assign a property to 'userrole' which contains comma separated user roles. Each item will be evaluated with given 'userrole' for that item to that of the logged in user roles, from security. If any of the user roles bound to 'userrole' property matches then that menu item will be shown else will be hidden. | +| Item Badge | Badge value to be displayed. Choose from the options available based upon the structure of the Dataset Value. | +| Sub Actions | When a menu widget is required the sub items can be mentioned in the children. Choose from the options available based upon the structure of the Dataset Value. | +| **Behavior** | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Auto Close | This property defines the behavior of menu closing, it can be: - outsideClick - close the menu when clicked outside of the menu, - always - when a menu item is selected or on click outside menu, or - disabled - do not close once opened. | +| **Format** | +| Horizontal Align | Set text alignment horizontally. | + +## Event + +Each _anchor_ widget events are available for adding functionality to this layout. For more on Anchor widget see [here](/learn/app-development/widgets/basic/anchor/ "Basic Widgets"). + +## Use Cases + +[Using Navigation](/learn/app-development/widgets/navigation/nav-basic-usage/) +[Working with Nav Bar](/learn/app-development/widgets/navigation/nav-bar) +[Creating a Dropdown Menu](/learn/app-development/widgets/navigation/dropdown-menu-use-cases) +[Dynamic Menu based on the User Role](/learn/how-tos/dynamic-menu-based-user-role) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/popover-basic-usage.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/popover-basic-usage.md new file mode 100644 index 000000000..8bb3a8403 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/popover-basic-usage.md @@ -0,0 +1,64 @@ +--- +title: "Using Popover Widget" +id: "popover-basic-usage" +sidebar_label: "Creating a Popover" +--- +--- + +We will use the popover to display the list of employees of a particular department using the Sample HRDB Database. + +## 1. Import Database + +[Import Sample HRDB](/learn/app-development/services/database-services/working-with-databases/) and in the [Query Editor](/learn/app-development/services/database-services/working-with-queries) write two queries - one to obtain **Employee count** for a given department and one for **Employee Picurl**. + +`Select count(*) from EMPLOYEE where EMPLOYEE.DEPTID = :deptid` `Select EMPLOYEE.PICURL from EMPLOYEE where EMPLOYEE.DEPTID = :deptid` + +## 2. Create a **popover page** + +Create a popover page and select a blank template. +- Drag and drop a **List** onto the canvas space, select the _data source_ to the _dataset_ of the _Emp_Picurl_ query variable created in the first step and set the _layout_ to _Media List_. + +[![](/learn/assets/popover_configurelist.png)](/learn/assets/popover_configurelist.png) + +- Bind the _picture_ widget to the picurl field of the query variable, delete the label from the list on canvas. + +## 3. Drag and drop Popover Widget + +1. Open the page where you want to have the popover, drag and drop the popover widget. + +[![](/learn/assets/popover_drag.png)](/learn/assets/popover_drag.png) + +2. Set the **content source** property to the _partial_ and the **content** as _popover page_ created in the previous step and bind the **badge** value to the _Emp_Count value_. Content defines the page to be displayed when the popover link is clicked and badge indicates the number of items that will be displayed in the content. + +[![](/learn/assets/popover_badgevalue.png)](/learn/assets/popover_badgevalue.png) + +3. We have added a select widget for the user to select the department for which they want to see the employee list. Drag and drop a **select widget** and bind it to _Department Dataset_. Set the **display field** to _name_, and **data field** to _deptid_. + +4. Be sure you bind the **data field of both the query variables** to the _select widget datavalue_, and set the **Auto Update** to true. + +## 4. Run the application + +Run the application and see the menu in action. + +## 5. Configurations and Settings + +Repeat the steps 2 till 3 for the following: + +- Set the **content source** property to be _inline_ +- Set the _content_ as follows, we have used the list HTML from the partial page created in steps 2,3,4 + +```html + + + + + + + +``` + +:::note +Content can be any HTML code or URL to another page. +::: + +[![](/learn/assets/popover_link2.png)](/learn/assets/popover_link2.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/popover.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/popover.md new file mode 100644 index 000000000..08a37cf15 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/navigation/popover.md @@ -0,0 +1,87 @@ +--- +title: "Popover Overview and Properties" +id: "popover" +sidebar_label: "Popover Overview" +--- +--- + +**Popover Widget** can be used to display a list of items on click event. An example of this would be the Notifications displayed on the Facebook page. + +Popovers are an interactive way to provide a secondary form of navigation in many different locations outside the dedicated areas. This UI pattern has the advantage of providing a lightweight and straightforward way of viewing additional information or taking a particular action, but they do so without pulling the user out of their current activity. + +Popovers “pop-up” when the user performs a certain action or gets to a specific place in the app, showing the relevant information/controls associated with that particular action/place in the UI. The original content or place in the app is still visible in the background, but the popover gives you the option of tweaking certain things or learning about what comes next. The popover gets the user’s attention and provides important notifications where needed. At the same time, however, users can easily dismiss the popover and return back to whatever they were originally doing by simply tapping or swiping the screen. + +## Properties + +| **Property** | **Description** | +| --- | --- | +| Caption | The caption is the text that the end user sees on Popover. | +| Title | The Title is the text that the end user sees on Popover. | +| Name | The name is a unique identifier for Popover. | +| Badge Value | Value to be displayed in the badge span for Popover | + + +### Accessibility + +| **Property** | **Description** | +| --- | --- | +| Hint | Any text or HTML you enter for this property will be shown as a tooltip if the mouse hovers over this widget for 1.5 seconds. | +| Tab Index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| Shortcut Key | The shortcut key property specifies a shortcut key to activate/focus an element. The way of accessing the shortcut key is varying in different browsers - Internet Explorer - [Alt] + shortcutkey, - Chrome - [Alt] + shortcutkey (Windows/Linux) [Control] [Alt] + shortcutkey (MAC), - Firefox - [Alt] [Shift] + shortcutkey (Windows/Linux) [Control] [Alt] + shortcutkey (MAC), - Safari - [Alt] + shortcutkey (Windows) [Control] [Alt] + shortcutkey (MAC) | + +### Layout + +| **Property** | **Description** | +| --- | --- | +| Width | The width of your widget can be specified in `px` or `%` i.e `50px, 75%`. | +| Height | The height of your widget can be specified in `px` or `%` i.e `50px, 75%`. | +| Popover Width | This property defines the width of the popover. | +| Popover Height | This property defines the height of the popover. | + +### Content + +| **Property** | **Description** | +| --- | --- | +| Content Source | Can be inline or partial. | +| Content | In case the source is selected as - inline enter the HTML code for the same. - Partial source, choose from the available list of partial pages. | +| Partial Param | In case the above set Partial page requires parameters. | + +### Behavior + +| **Property** | **Description** | +| --- | --- | +| Show | Showing determines whether or not a component is visible. It is a bindable property. | +| Load on Demand (visible only when show property is bound to a variable) | When this property is set and show property is bound, the initialization of the widget will be deferred till the widget becomes visible. This behavior improves the load time. Use this feature with caution, as it has a downside (as we will not be able to interact with the widget through script until the widget is initialized). When show property is not bound the widget will be initialized immediately. | +| Interaction | This property defines which action should trigger the Popover to open or close. You can choose from the following options: - **Click**: Popover opens on click and closes on click anywhere on the document. - **Hover**: Popover opens on hover and closes on hover out. - **Click and Hover** (Default): Popover opens and closes on both click or hover. | +| Auto Close | This property defines when to close the popover. **Outside Click**: popover will close when user clicks anywhere outside the popover content. **Always**: the popover will close when user clicks anywhere on the page. **Disabled**: popover will close only when user clicks on the popover link.| +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | + + +### Popover Behavior + +| **Property** | **Description** | +| --- | --- | +| Popover Placement | This property defines the placement of the popover. Choose from - bottom, - left, - right or - top. | +| Popover Arrow | This property defines the arrow for the popover. | + +### Graphics + +| **Property** | **Description** | +| --- | --- | +| Icon Class | This property defines the class of the icon that is applied to the button. | +| Icon Url | This optional property allows you to add an icon to the left side of your button. You can give URL of the image. | +| Icon Width | Optional property; but you will need this if you are using the button's iconUrl. Please enter the width of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Height | Optional property; but you will need this if you are using the button's iconUrl. Please enter the height of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | +| Icon position | Optional property; Property to set the position of the icon in the widget. Can be set to left, top or right. | + + +### Format + +| **Property** | **Description** | +| --- | --- | +| Horizontal Align | This property specifies how the elements should be aligned horizontally. | + +## See Also + +[Using Popover Widget](/learn/app-development/widgets/navigation/popover-basic-usage) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/page-dialog.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/page-dialog.md new file mode 100644 index 000000000..63e5ea201 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/page-dialog.md @@ -0,0 +1,75 @@ +--- +title: "Page Dialog" +id: "page-dialog" +--- +--- + +[![page_struct](/learn/assets/page_struct.jpg)](/learn/assets/page_struct.jpg) + +## Overview + +Dragging and dropping a dialog creates a **view** containing the dialog. The view can be selected from the **Page Structure** or from the **tabs** given at the bottom. The display of the dialog box at runtime is usually associated with the _onClick_ event of a **Button** widget. You can also trigger the dialog by calling methods from _JavaScript_. + +## Page Dialog + +Page Dialog is a popup window that displays page content and can be dismissed by the user. The **content** property of this widget can be set to the desired [partial page](/learn/app-development/ui-design/page-concepts/partial-pages/) content. + +[![](/learn/assets/dialog_page.png)](/learn/assets/dialog_page.png) + +## Script Access + +**Dialog** widget in your project can be accessed by associating the open and _close_ properties of the dialog with an event of any other widget. The dialog can be accessed through scripting by adding _DialogService_ to the _page controller_ and adding the code for _open_ and _close_ as shown below, here we are displaying an alert dialog on click of a button: Click event of the button should trigger the following JavaScript code: + +```js +Page.button3Click = function($event, widget) { + Page.Widgets.pagedialog1.open(); + } +``` + +For hiding dialog: + +```js +/* function called on button1 click */ + Page.button1Click = function($event, widget) { + Page.Widgets.pagedialog1.close(); + }; +``` + +## Properties & Events +--- + +### Page Dialog Properties + +| Property | Description | +| --- | --- | +| Title | Set the title of the widget. | +| Name | The name is a unique identifier for the widget. | +| Ok Text | This widget gives a pop-up window. It can be used to provide contextual information to the user. | +| **Accessibility** | +| Tab index | The tab index attribute specifies the tab order of an element. You can use this property to change the default tabbing order for widget access using the tab key. The value can range from 0 to 32767. The default is 0 and -1 makes the element non-focusable. **NOTE**: In Safari browsers, by default, Tab highlights only text fields. To enable Tab functionality, in Safari Browser from Preferences -> Advanced -> Accessibility set the option "Press Tab to highlight each item on a webpage". | +| **Layout** || +| Width | The width of your widget can be specified in px or % (i.e 50px, 75%). | +| Height | The height of your widget can be specified in px or % (i.e 50px, 75%). | +| Modal | This property, if set true, adds a backdrop for the dialog restricting the closure of the dialog when the user clicks outside of the dialog. The default value is false, which allows close of dialog on click outside. | +| **Content** | +| Content | Page's content to be included in the widget. | +| **Behavior** | +| Enable Default Close Action | This property allows the user to access close action from header through an "x" icon; and also enables close through ESC key. | +| Show actions | This property shows/hides actions section of the widget. | +| Animation | This property controls the animation of an element. The animation is based on the CSS classes and works only in the run mode. | +| Keyboard | This property if set true allows closing of dialog on ESC keypress. The default is true. | +| **Graphics** | +| Icon Class | This property defines the class of the icon that is applied to the button. | +| Icon Width | Optional property; but you will need this if you are using the button's iconUrl. Please enter the width of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Height | Optional property; but you will need this if you are using the button's iconUrl. Please enter the height of your icon. WARNING: It's best to specify size in pixels, not percent. | +| Icon Margin | Optional property; only has meaning if you specify the button's iconUrl. Values should all have "px" next to them. Use this to adjust the space between the icon and the button text. | + +### Page Dialog Events + +| Event | Description | +| --- | --- | +| On load | This event handler is called when the widget is loaded. | +| **Callback Events** | +| On ok | This event handler is called whenever an ok event is triggered. | +| On close | This event handler is called whenever a close event is triggered. | +| On open | This widget gives a pop-up window. It can be used to give a warning message to the user. For example, you are about to leave this page. | diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/barcode-scanner-prefab.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/barcode-scanner-prefab.md new file mode 100644 index 000000000..af497c19d --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/barcode-scanner-prefab.md @@ -0,0 +1,21 @@ +--- +title: "Barcode Scanner Prefab" +id: "barcode-scanner-prefab" +--- +--- + +The Barcode Scanner prefab can be used to scan different type of barcodes from the WM App. It uses the [zxing-js](https://github.com/zxing-js/library) library internally for the purpose. + +## How to use the prefab + +1. Download the prefab zip from the [github](https://github.com/wavemaker/prefab-barcode/releases) repo and [import](/learn/app-development/custom-widgets/prefabs-overview#importing-prefabs) it in your WaveMaker project. +2. Drag and Drop the prefab on to the canvas on the desired page +3. The prefab has scan and cancel buttons that opens and closes the camer (for scanning). The caption & icon for these buttons can be configured from the properties pane +![/learn/assets/entity-extraction-from-document-picture1.png](/learn/assets/barcode-scanner-properties.png) +4. The prefab also has onBeforeScan() and onSuccess() call backs. The scanned code can be fetched by either using the onSuccess() callback (as shown below) or by using the prefab property 'datavalue' as `Page.Widgets..datavalue`. +![/learn/assets/entity-extraction-from-document-picture1.png](/learn/assets/barcode-scanner-events.png) +![/learn/assets/entity-extraction-from-document-picture1.png](/learn/assets/barcode-scanner-on-success.png) + + + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/box-viewer-prefab.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/box-viewer-prefab.md new file mode 100644 index 000000000..8e0a10374 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/box-viewer-prefab.md @@ -0,0 +1,42 @@ +--- +title: "Box Viewer Prefab" +id: "box-viewer-prefab" +--- +--- + +The Box preview prefab enables preview of hundreds of different file formats including all Microsoft Office Documents images, videos, 3D models etc. It uses the [Box preview API](https://developer.box.com/docs/box-view) provided by a developer account of Box Platform. + +[![](https://www.wavemaker.com./assets/Screenshot-2018-12-06-at-10.49.12-AM.png)](https://www.wavemaker.com./assets/Screenshot-2018-12-06-at-10.49.12-AM.png)Prerequisites of using the prefab are: + +1. A Developer account in [box.com](https://developer.box.com/). +2. Create an app ([https://app.box.com/developers/console](https://app.box.com/developers/console)). + +![](/learn/assets/Screenshot-2018-12-06-at-2.13.18-PM.png) + +3. Generate a Public/Private key pair for the app. + +![](/learn/assets/Screenshot-2018-12-06-at-2.15.18-PM.png) + +4. Download the App Settings as json. + + + +![](/learn/assets/skitch.png) + +5. Drag and drop the prefab into the page of your project. And set the App Environment. + +In your app’s `Settings > Config profile > Box prefab > App Environment`, add key-value pairs for the respective field from the downloaded App Settings json. + +![](/learn/assets/Screenshot-2018-12-06-at-3.27.56-PM.png) + +![](/learn/assets/Screenshot_2018-12-06_at_3_31_45_PM.png) + +6. Bind the URL property of the prefab in your page with the path to the file (uploaded to the project) to be viewed. + +![](/learn/assets/Screenshot-2018-12-06-at-3.26.34-PM.png) + +That’s it, clicking on the prefab link at app runtime will launch the viewer. + +![](/learn/assets/Screenshot-2018-12-06-at-3.41.38-PM.png) + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/docusign.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/docusign.md new file mode 100644 index 000000000..7e60dae69 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/docusign.md @@ -0,0 +1,51 @@ +--- +title: "Docusign Prefab" +id: "docusign" +--- +--- +Docusign prefab allows user to enable electronic signature technology services using the Docusign API. Application using this prefab can allow it's users to electronically sign their documents for various purposes. + +  + +![](/learn/assets/Screenshot-2018-12-15-at-1.43.11-PM.png) + +## Prerequisites for using the Docusign prefab: + +### 1. Create a developer account in Docusign. +![](/learn/assets/Screenshot-2018-12-15-at-11.47.48-AM.png) +### 2. Go to Admin page and add an App! +[](/learn/assets/Screenshot-2018-12-15-at-11.55.26-AM.png) +![](/learn/assets/Screenshot-2018-12-15-at-11.44.52-AM.png) +### 3. Now go to your Apps listing and click on Actions drop down of your created app and click Edit. +![](/learn/assets/Screenshot-2018-12-15-at-11.46.14-AM.png) +### 4. From the pop up copy the Integrator key and keep it ready. +![](/learn/assets/Screenshot-2018-12-15-at-11.46.49-AM.png) + +## Project Integration +Drag and drop the prefab into your project page. It'll appear as a link labeled "E-sign". Then go to settings and select Config Profiles + +![](/learn/assets/Screenshot-2018-12-06-at-3.27.56-PM.png) + +In the dialogue that appears enter the required fields after selecting Docusign namely: + +1. Base URL: It'll be prefilled +2. Docusign password: provide your password for Docusign(you can also provide the encrypted password) +3. Docusign Username: Provide your username +4. Integrator Key: Provide the Integrator Key derived for your Docusign App from the Docusign Admin console. +5. Return URL: Provide the URL to the page of your WaveMaker app that uses the prefab. + +![](/learn/assets/Screenshot-2018-12-15-at-11.41.48-AM.png) + +Now bind the Source of the prefab to the URL of the file to be e-signed and the email to the email of the user who will perform the e-signing. + +![](/learn/assets/Screenshot-2018-12-15-at-2.46.45-PM.png) + +With the above steps done your Docusign prefab integration is complete. Now clicking on the E-sign link will invoke a Docusign dialogue and the your document will appear in the dialogue. Click continue to start the e-signing process. Click on the e-signing options from the left menu and e-sign the document. Then click finish button in the popup to complete the process. + +![](/learn/assets/Screenshot-2018-12-15-at-1.22.23-PM.png) + +![](/learn/assets/Screenshot-2018-12-15-at-1.23.47-PM.png) + +![](/learn/assets/Screenshot-2018-12-15-at-1.23.11-PM.png) + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/entity-extraction-from-documents.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/entity-extraction-from-documents.md new file mode 100644 index 000000000..0e949c36c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/entity-extraction-from-documents.md @@ -0,0 +1,43 @@ +--- +title: "Entity Extraction Prefab" +id: "entity-extraction-from-documents" +--- +--- + +Automatically extract data from structured documents such as Invoices, Receipts. + +There are many situations where specific data needs to be extracted from a scanned receipt or say, a screenshot taken from a mobile phone. To be able to automatically extract chosen information from such documents can help build delightful user experiences. This prefab helps implement this extraction of data from any structured document. With the document as the input, the prefab uploads it to [AWS Textract](https://docs.aws.amazon.com/textract/latest/dg/what-is.html) to extract data from it. This extracted data is available as key-value pair and developers can pick the data they are interested in. + +## How to use this prefab + +1. Download the [prefab](https://github.com/wavemaker/prefab-entity-extractor/releases/latest) and [import](/learn/app-development/custom-widgets/prefabs-overview#importing-prefabs) into your WaveMaker project. + + 1. [Click to download the Prefab ZIP](https://github.com/wavemaker/prefab-entity-extractor/raw/1.3/prefab.zip). + +2. Create AWS account and IAM user with policy `AmazonTextractFullAccess`. + + 1. [Document: Getting started with AWS Textract.](https://docs.aws.amazon.com/textract/latest/dg/getting-started.html) + +3. Generate and set `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and the `AWS_REGION` at prefab’s App Environment. (In your app’s `Settings > Config profile > EntityEXtraction (prefab) > App Environment`) +![/learn/assets/entity-extraction-from-document-picture1.png](/learn/assets/entity-extraction-from-document-picture1.png) + +4. Bind the “URL” and “Entities” (properties of prefab) on your page. + + 1. URL is the path of the document(Prefab v1.2 supports `.png` and `.jpg` formats) to download and process. You can bind URL property with [FileUpload](/learn/app-development/widgets/form-widgets/file-upload) widget's java service variable as shown in the below screen. + + 2. Entities are labels from the document whose values have to be extracted. For example, in a [W2 form](https://i0.wp.com/www.rgbrenner.com/wp-content/uploads/2015/02/W2.png) `Employee’s social security number` could be an entity. +![/learn/assets/entity-extraction-from-document-picture2.png](/learn/assets/entity-extraction-from-document-picture2.png) + +5. That’s it. Now you can bind prefab’s output(JSON object - key-value pair) back to different widgets (text, list, table, or form). The below example shows how to bind each individual entity-value to a `Text` widget. +![/learn/assets/entity-extraction-from-document-picture3.png](/learn/assets/entity-extraction-from-document-picture3.png) + +6. Finally, you can upload the document and then click on the prefab `extract_info`, It can fill values automatically in `Text` widgets as below. +![/learn/assets/entity-extraction-from-document-picture4.png](/learn/assets/entity-extraction-from-document-picture4.png) + +## Known Issue + +1. Prefab `v1.2` won't support PDF document. + +## Other Prefabs + +1. [Use Box Viewer to view Office documents in browser](/learn/app-development/widgets/prefab/box-viewer-prefab) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/googlemaps.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/googlemaps.md new file mode 100644 index 000000000..8b7d0fbba --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/googlemaps.md @@ -0,0 +1,193 @@ +--- +title: "Googlemaps" +id: "googlemaps" +--- +--- + +The **Googlemaps** prefab connects with Google Maps and displays the map on your page. It can be used either for **location** map or as **route** map or as a **heat** map. + +[![](/learn/assets/prefab.png)](/learn/assets/prefab.png)In order to use GoogleMaps, you need to register your app with Google Maps and add the API key here: + +[![](/learn/assets/googlemaps_apikey.png)](/learn/assets/googlemaps_apikey.png) + +## Layouts + +Three types of maps can be plotted using Googlemaps Prefab: + +Heat map + + + +Location map + + + +Route map + + + +## Features + +Using Googlemaps Prefab, you can: + +- display various types of maps, +- [use events](#events) to customize the map behavior, and +- [use scripts](#script-access) to enhance the functionality. + +There are three **Map Types** supported by Googlemaps Prefab: + +1. **Markers** help to mark a given _location_ with an _icon_, _information_, highlight using a circle of given _radius_ and _shade_(color). The input can be any variable which has the above-mentioned fields delimited. The variable can be bound to the Locations property and each of the above properties can be set to the elements of the variable. + - **Locations**: Variable containing the location details. Can be static variable in JSON format, or a Live Variable with the following fields + - **Location type**: tells the format of the location being plotted. It can be + - **LatLng** in which case Marker Latitude and Marker Longitude of the location is given as the input + - **Address** wherein the Address fields in the form of a city, state, zip etc can be picked from the multi-list dropdown. These are the fields from the variable bound to the Locations property above. + - **Marker Icon**: Used to mark the location + - **Marker Info**: Any information that needs to be displayed when the location is clicked + - **Perimeter Color**: Used to set a circle shaped boundary around the marker. + - **Perimeter Radius**: Used to set the radius of the boundary around the marker. _This change is reflected in prefab only when Perimeter property is enabled_. +2. As a **route map** you can mark: + - the **origin** and **destination** by passing the String or GeoLocations(Latitude and longitude) to get the route rendered on the map, + - the **Waypoints** a location which needs to be included in the route from the origin to destination, + - using the **Stopover** property you can choose to mark the waypoint in the route, + - the **Travel Mode** can be Driving, Walking or Transit. The Route information like Origin, Destination, Duration, Distance is displayed below the map. +3. As a **Heatmap,** the traffic congestion points can be marked. You can set: + - **Marker Latitude** and **Longitude**can be selected from the fields from the Locations variable + - **Gradient** + - **Pixel Density** to mark the size of the marker + - **Opacity** to set the appearance of the marker + +[![](/learn/assets/gm_features.png)](/learn/assets/gm_features.png) + +## Events + +The following events are exposed for Googlemaps Prefab: + +1. On Load: this can be used to trigger any action when the Prefab is loaded on the page containing it +2. On Destroy: this can be used to trigger any action when the Prefab is deleted/closed +3. onMarkerclick: this can be used to trigger any action when a marker on the map is clicked +4. onMarkerhover: this can be used to trigger any action when a marker on the map is hovered on + +## Script Access + +- You can get the marker information from **$data** in the On Marker Click event of the google map. +- You can open the info window of the marker by invoking the _showInfoWindow_ method on the widget scope. Params required for the method : ‘_mapMarkerData_’. For example Page.Widgets.googlemaps1.showInfoWindow(mapMarkerData). This will open the info window for the selected marker. **Example:** To open the info window of the marker in the Marker on Click event is shown below: + +```javascript + Page.googlemaps1Markerclick = function($event, $data) { +    Page.Widgets.googlemaps1.showInfoWindow($data); + }; +``` + +- You can plot a custom Marker on the map either by sending the Address to the _markAddress_ function (or) by sending the _lat, lng_ values to the _markLatLng_ function. For example: Page.Widgets.googlemaps1.markAddress('Chicago') will plot the marker in Chicago, USA. Page.Widgets.googlemaps1.markLatLng(31.619770, 74.876713) will plot the marker according to the provided latitude, longitude values. +- You can remove all the custom Markers by invoking the function _clearAllMarkers_ on widget scope + +[![](/learn/assets/gm_features_events.png)](/learn/assets/gm_features_events.png) + +## Usage Scenario + +We will see three use cases for various features of the Googlemaps prefab: + +1. Location from Database +1. [Location from Static Variable](#location-from-static-variable) +1. [Route Map](#route-map) + +### Location from Database + +1. Drag and drop the **Googlemaps** prefab onto the canvas on any of the pages in your application. +2. Bind the **Locations** property to a database which contains the address fields. Here we are using _HrdbEmployeeData_ table from the [imported Sample DB](/learn/app-development/services/database-services/#integrating-database). [![screenshot](/learn/assets/googlemaps_loc_db.png)](/learn/assets/googlemaps_loc_db.png) +3. Set the **Markertype** to **Address** and choose a **city, state, and zip** for the **Address** property. [![screenshot](/learn/assets/googlemaps_props_address.png)](/learn/assets/googlemaps_props_address.png) +4. You can set the other properties to any fields in your DB. Here we are not setting them since we do not have corresponding fields in the sample DB. +5. Run and see the map. [![screenshot](/learn/assets/googlemaps_run_db.png)](/learn/assets/googlemaps_run_db.png) + +### Location from Static Variable + +1. Drag and drop the **Googlemaps** prefab onto the canvas on any of the pages in your application. +2. Create a custom variable as per your requirements. [Know more from here](/learn/app-development/variables/model-variable/). Then enable the **isList property**, and enter the appropriate JSON in the **Text Editor**. [![screenshot](/learn/assets/googlemaps_loc_statvar.png)](/learn/assets/googlemaps_loc_statvar.png) As an example you can use the following: + +```json + [ + { + "coords": { + "lat": 41.428146, + "lng": -73.918993 + }, + "icon": "http://maps.google.com/mapfiles/ms/micons/water.png", + "info": "Hudson River", + "radius": 12345, + "color": "#5133AB" + }, + { + "coords": { + "lat": 40.712397, + "lng": -74.005469 + }, + "icon": "http://maps.google.com/mapfiles/ms/micons/arts.png", + "info": "New York", + "radius": 12345, + "color": "#0BC86E" + }, + { + "coords": { + "lat": 39.366105, + "lng": -74.436832 + }, + "icon": "http://maps.google.com/mapfiles/ms/micons/dollar.png", + "info": "Atlantic City", + "radius": 12345, + "color": "#264B7F" + } +] +``` + +- Bind the location's property of the prefab to the model variable created. +- Select _coords.lat_ for **Lat** property, _coords.lng_ for **Lng** property, _icon_ for **Icon** property and _info_ for **info** property. You can set the height and width of the prefab. The **zoom** property can be set for the default level of display, set the **width** and **height** of the display window. [![screenshot](/learn/assets/googlemaps_props_sample.png)](/learn/assets/googlemaps_props_sample.png) +- Save and run the application. +- You will see the google map displayed with the cities mentioned in the static variable highlighted with the appropriate icon and information tags. You can zoom in, zoom out, pan left, right, top and bottom as you would with google maps. [![screenshot](/learn/assets/prefab_google_run.png)](/learn/assets/prefab_google_run.png) +- To get the marker details in the on click event of the marker: + - Go to the google map prefab and navigate to the Events tab in the properties panel. Here, in the On Marker Click event, select javascript from the dropdown. [![screenshot](/learn/assets/googlemapsonclickeventscript.png)](/learn/assets/googlemapsonclickeventscript.png) + - In the Script tab from the Markerclick event, you can access the marker data as below: Example: + +```javascript + Page.googlemaps1Markerclick = function($event, $data) { + var lat = $data.latLng.lat(); + var lng = $data.latLng.lng(); + var color = $data.color; + var info = $data.info; + var icon = $data.icon; + var radius = $data.radius; + }; +``` + +### Route Map + +Using the Origin and Destination properties, you can plot a route. + +1. Drag and drop the **Googlemaps** prefab onto the canvas on any of the pages in your application. +1. Enter the values for **Origin** and **Destination**. These can be static string values or bound to variables. For example, we have used **Toronto** and **Ottawa** values: [![Screenshot](/learn/assets/googlemaps_route_run1.png)](/learn/assets/googlemaps_route_run1.png) +1. Using **Waypoint** property, you can set the intermediary points from origin to destination. + +:::note +Due to restriction from Google Maps API, the input to waypoint has to be in a JSON format. Create a model **variable** with this content and bind it to the waypoint property. +::: + +[![Screenshot](/learn/assets/googlemaps_route_statvar.png)](/learn/assets/googlemaps_route_statvar.png) Here is a sample code we have used for this example. + +```json +[ + { + "location": { + "lat": 44.32384807250689, + "lng": -78.079833984375 + } + }, + { + "location": { + "lat": 44.55916341529184, + "lng": -76.17919921875 + } + } +] +``` + +- Set the **Origin** and **Destination** to **Toronto** and **Ottawa**, and bind the **Waypoint** to the model variable created in the previous step. Selecting the **Stopover** property will mark the waypoint. [![Screenshot](/learn/assets/googlemaps_route_waypt.png)](/learn/assets/googlemaps_route_waypt.png) +- Run the app. [![Screenshot](/learn/assets/googlemaps_route_run2.png)](/learn/assets/googlemaps_route_run2.png) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs.md new file mode 100644 index 000000000..6061346a4 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs.md @@ -0,0 +1,35 @@ +--- +title: "OAuth Prefabs" +id: "oauth-prefabs" +--- + +## Introduction + +OAuth 2.0 is an authorization framework, which is updated after the original OAuth protocol created in 2006. OAuth 2.0 focuses on client developer simplicity by providing secured delegated access for web and desktop applications. + +[![](/learn/assets/instagram-design-flow.png)](/learn/assets/instagram-design-flow.png) + +The device flow is illustrated in the above image. The steps include: + +1. The client requests the authorization server to give the access. The request includes the client identifier in it. +2. The authorization server provides a verification code, an end- user code, and the end-user verification URI. +3. The client instructs the end-user to use its user-agent (elsewhere) and visit the provided end-user verification URI. The client provides the end-user with the end-user code that is necessary to enter, in order to gain access. +4. The authorization server authenticates the end-user (via the user-agent) and prompts the end-user to grant the client's access request. If the end-user accepts the client's request, then the end-user enters the end-user code provided by the client. The authorization server validates this end-user code. +5. While the end-user authorizes (or denies) the client's request (D), the client continuously polls the authorization server to verify if the end-user authorization step is successfully accomplished. The client's request includes the verification code and its client identifier. +6. Assuming that the end-user has granted access, the authorization server validates the verification code provided by the client and eventually responds with the access token. + +Most Web Services use OAuth for access, and configuring your app to use these Web Services can be an uphill task. WaveMaker Prefabs abstracts OAuth and offers API integration without the need for writing code. This section deals with such OAuth Prefabs. + +WaveMaker provides few OAuth Prefabs for developer convenience. [![](/learn/assets/OAuth.png)](/learn/assets/OAuth.png) + +Steps in using OAuth Prefabs: + +1. Register your application at the third party website. You will need to create an account and access to the same needs to be granted while running the app using the OAuth Prefab. **Note**: The run and deploy URLs for Studio applications are different. One needs to register both at the third party website. +2. Drag and drop the OAuth Prefab on to the application canvas +3. You can set the Login Mode to be: + - _auto_ will in the run mode after initialization of the Prefab the app would automatically be navigated to the OAuth Authorization page + - _manual_ (default mode) will invoke the OAuth Authorization page on click of the login button +4. Bind Server Properties AppId and Secret of the Prefab to the AppId and Secret Key generated in step 1 above. The RedirectPage should reflect the landing page of your application. +5. Import the required API as a REST service to Studio and set the parameters as required. +6. The API data will be exposed in the form of Service Variables. Use these for binding to any widgets in your application. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/box.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/box.md new file mode 100644 index 000000000..05cf99682 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/box.md @@ -0,0 +1,27 @@ +--- +title: "Box" +id: "box" +--- + +## Introduction + +OAuth 2.0 is an authorization framework, which is updated after the original OAuth protocol created in 2006. OAuth 2.0 is a standard protocol, which provides delegated secured access for web, mobile, and desktop applications. To know more about the working of WaveMaker OAuth Prefabs [click here](/learn/app-development/widgets/prefab/oauth-prefabs/). + +## Box OAuth in WaveMaker + +Box uses OAuth 2.0 to authenticate connections that use the Box APIs. Box has secured authentication for Box APIs, to allow only the registered users to interact with Box content. For more information on Box OAuth, [click here.](https://docs.box.com) + +**Disclaimer**: The screenshots from the Box website were current at the time of writing this document, the actual screens might differ. To use the **Box**OAuth prefab, please follow the below steps: + +1. Drag and drop the Box OAuth Prefab on the canvas of the desired page of the application. [![](/learn/assets/box_prefab.png)](/learn/assets/box_prefab.png) +2. Drag and drop a Label in the canvas. Click on Bind property to bind label with the `callbackurl` property of the Box OAuth prefab. [![](/learn/assets/box_bind.png)](/learn/assets/box_bind.png) +3. Save and Run the project. Select the Callback URL from the label. [![](/learn/assets/Box_callback_URL.png)](/learn/assets/Box_callback_URL.png) +4. To create a Box account, [click here](https://app.box.com/signup). Login to the Box account with the credentials. +5. To open the Box API platform, [click here.](https://app.box.com/developers/console) The Box API gives access to secured content management system within your own app. +6. Click on Create New App button to build an Application, as shown in the below figure. [![](/learn/assets/box_new_app.jpg)](/learn/assets/box_new_app.jpg) +7. Select Authentication Method as Standard OAuth 2.0(User Authentication) to authenticate the Box APIs. [![](/learn/assets/box_auth.png)](/learn/assets/box_auth.png) +8. Click on Configuration Tab to acquire the Client ID and Client Secret from the created App. +9. Paste the selected callback URL in the redirect URI section of the App in Box, as highlighted in the below figure. [![](/learn/assets/box_uri.png)](/learn/assets/box_uri.png) +10. In the WaveMaker studio, click on Properties. Enter the necessary server properties such as Appid, Secret, and Page for the BOX prefab widget. [![](/learn/assets/box_prop.png)](/learn/assets/box_prop.png) +11. Run the project and log in using Box. +12. For more information on Authentication with OAuth, [click here](https://docs.box.com/docs/oauth-20). diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/facebook.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/facebook.md new file mode 100644 index 000000000..a08119127 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/facebook.md @@ -0,0 +1,54 @@ +--- +title: "Facebook" +id: "facebook" +--- + +## Introduction + +OAuth 2.0 is an authorization framework, which is updated after the original OAuth protocol created in 2006. OAuth 2.0 is a standard protocol, which provides delegated secured access for web, mobile, and desktop applications. To know more about the working of WaveMaker OAuth Prefabs [click here](/learn/app-development/widgets/prefab/oauth-prefabs/). + +## Facebook OAuth in WaveMaker + +In order to use the **Facebook** OAuth prefab, please follow the below steps: Disclaimer: The screenshots from the FaceBook website were current at the time of writing this document, the actual screens might differ. + +1. Log on to [https://developers.facebook.com/apps/](https://developers.facebook.com/apps/) and enter your credentials. Facebook Developers page is displayed. +2. Click **Register Now.** Register as a Facebook Developer window is displayed. +3. Accept the **Facebook Platform Policy** and **Facebook Privacy Policy** click Next. +4. Select the **Country** from the dropdown list and enter your **Phone Number** to get the confirmation code. You may choose to get your confirmation code as a text or via phone call. +5. Enter the **Confirmation Code** and click **Register**. Successfully Registered as a Facebook developer window is displayed. +6. Click **Done**. On registering, Add a New App page is displayed. +7. Select **Website** as a platform to get started. +8. Enter a **Name** to your app and click **Create New Facebook App ID**. Create a New App ID window is displayed. +9. Select a category from **Choose a Category** drop-down list and click **Create App ID**. Tell us about your website window is displayed. +10. Enter a sample valid URL in the **Site URL** field and click **Next**. Your App Dashboard page is displayed. **Note:** Make a note of the **App ID** and **App Secret**. [![](/learn/assets/Facebook_reg9.png)](/learn/assets/Facebook_reg9.png) + +# Usage Example + +1. Open WaveMaker application where you want to use the Facebook OAuth Prefab. +2. Drag and Drop the Facebook Prefab from the Prefabs Tab under OAuth. You can use the default login page created by WaveMaker. +3. You can set the **Login Mode** to be: + + - _auto_ will in the run mode after initialization of the Prefab the app would automatically be navigated to the OAuth Authorization page + - _manual_ (default mode) will invoke the OAuth Authorization page on click of the login button + + [![](/learn/assets/Facebook_app1.png)](/learn/assets/Facebook_app1.png) +4. In the Properties Panel, under **SERVER PROPERTIES**, enter the **Appid, Page, Scope** and **Secret** in their respective fields. [![](/learn/assets/Facebook_app2.png)](/learn/assets/Facebook_app2.png) +5. Save the application and Run the application. Note the generated redirect URL. You might have to click REMOVE TOOLBAR to get the URL. Copy the redirect uri till the _callback_ part only. [![](/learn/assets/Facebook_app_run1.png)](/learn/assets/Facebook_app_run1.png) +6. Go to Facebook Developers – your project page and click on Settings on the left side of the Dashboard page. +7. Enter this redirect URl in the Site URL field and click Save Changes. [![](/learn/assets/Facebook_reg10.png)](/learn/assets/Facebook_reg10.png) +8. Go back to WaveMaker application and again Run the app. You can now see the WaveMaker login page. [![](/learn/assets/Facebook_app_run2.png)](/learn/assets/Facebook_app_run2.png) +9. Click on the Login with Facebook button to be redirected to Facebook Authorisation page. This will the first page, in case you have set the Login Mode to auto +10. To use the Facebook API in your application, import the corresponding [REST Web Service](/learn/services/web-services/web-services/#rest) into WaveMaker by giving a valid URL with the access token. Test and Import. +11. You can see the variables imported from the service in the Left panel and these are available for binding and usage within your app. ![Facebook_serviceVar](/learn/assets/Facebook_serviceVar.png) + +[9. Custom Widgets - Prefabs](/learn/app-development/widgets/widget-library/#prefabs) + +- [9.1 Youtube](/learn/app-development/widgets/prefab/youtube/) +- [9.2 Googlemaps](/learn/app-development/widgets/prefab/googlemaps/) +- [9.3 QRCode](/learn/app-development/widgets/prefab/qrcode/) +- [9.4 OAuth Prefabs](/learn/app-development/widgets/prefab/oauth-prefabs/) + - [9.4.1 Box](/learn/app-development/widgets/prefab/oauth-prefabs/box/) + - [9.4.2 Facebook](#) + - [9.4.3 Google](/learn/app-development/widgets/prefab/oauth-prefabs/google/) + - [9.4.4 Instagram](/learn/app-development/widgets/prefab/oauth-prefabs/instagram/) + - [9.4.5 LinkedIn](/learn/app-development/widgets/prefab/oauth-prefabs/linkedin/) diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/google.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/google.md new file mode 100644 index 000000000..b67d30e8b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/google.md @@ -0,0 +1,43 @@ +--- +title: "Google" +id: "google" +--- + +## Introduction + +OAuth 2.0 is an authorization framework, which is updated after the original OAuth protocol created in 2006. OAuth 2.0 is a standard protocol, which provides delegated secured access for web, mobile, and desktop applications. To know more about the working of WaveMaker OAuth Prefabs [click here](/learn/app-development/widgets/prefab/oauth-prefabs/). + +## Google OAuth in WaveMaker + +In order to use the **Google** OAuth prefab, please follow the below steps: + +Disclaimer: The screenshots from the Google website were current at the time of writing this document, the actual screens might differ. + +1. Log on to [https://console.developers.google.com](https://console.developers.google.com) and enter your credentials. **Google Developers Console** window is displayed. +2. On the left of the Google Developers Console screen click **Create Project**. New Project window is displayed. Enter the Project name in its respective field. **Note**: Project ID is displayed by default. Check the Terms of Service checkbox and click Create. Your project is successfully created. +3. In the left panel of the project screen select **Credentials** from **APIs & auth** section. +4. Click **Create new Client ID.** Create Client ID window is displayed. +5. Select the Application type to be a **Web application** and click **Configure consent screen.** Consent screen page is displayed. +6. Enter **Email address** and **Product name** and click **Save**. Note: The remaining options are optional. Create ID screen with Authorized JavaScripts origins window is displayed. +7. Enter a valid sample Authorized JavaScript origins and Authorized redirect URIs and click Create Client ID. Your client ID is now created. **Note**: Make a note of the Client ID and Client secret + +# Usage Example + +Here we show a simple use case for login using Google credentials. [For validation using custom security to access Gmail API see here](/learn/how-tos/custom-security-using-google-oauth-prefab/). + +- Create an application using WaveMaker. Drag and Drop the **Google OAuth PreFab** onto the canvas. You can use the default login page created by WaveMaker. +- You can set the **Login Mode** to be: + + - _auto_ will in the run mode after initialization of the Prefab the app would automatically be navigated to the OAuth Authorization page + - _manual_ (default mode) will invoke the OAuth Authorization page on click of the login button + + [![](/learn/assets/Google_design1.png)](/learn/assets/Google_design1.png) +- From the Properties Panel, enter the Client ID and Client Secret in the **Server Properties**  panel in their respective fields. [![](/learn/assets/Google_props1.png)](/learn/assets/Google_props1.png) +- Save the application and Run the application. Note the **redirect URL**. +- After you run the application, redirect URL is generated. You might have to click REMOVE TOOLBAR to get the URL. Copy the redirect uri till the _callback_ part only. [![](/learn/assets/Google_run.png)](/learn/assets/Google_run.png) +- Go to **Google Developers Console** – your project page and click on Edit Settings. Enter this redirect Url in the Authorized redirect URIs field and click Update. +- Go back to WaveMaker application and again Run the app. You can now see the application. You will see the WaveMaker login screen if you have set the Login Mode as manual: [![](/learn/assets/Google_run_manual.png)](/learn/assets/Google_run_manual.png) Click the Login with Google button and you will be directed to the Google login page. This will be the first screen in case you have set the Login Mode to auto: [![](/learn/assets/Google_run_auto.png)](/learn/assets/Google_run_auto.png) +- Entering the Google credential will allow access to the WaveMaker App +- To use Google APIs, you need to [import the appropriate web service](/learn/services/web-services/web-services/). Go to https://developers.google.com/oauthplayground/, select the required API and get the Authorization key [![](/learn/assets/Google_API.png)](/learn/assets/Google_API.png) +- From app designer, import a web service with the proper credentials as obtained from the above step. [![](/learn/assets/Google_Service.png)](/learn/assets/Google_Service.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/instagram.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/instagram.md new file mode 100644 index 000000000..8f440a3a2 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/instagram.md @@ -0,0 +1,49 @@ +--- +title: "Instagram" +id: "instagram" +--- +--- + +OAuth 2.0 is an authorization framework, which is updated after the original OAuth protocol created in 2006. OAuth 2.0 is a standard protocol, which provides delegated secured access for web, mobile, and desktop applications. To know more about the working of WaveMaker OAuth Prefabs [click here](/learn/app-development/widgets/prefab/oauth-prefabs/). + +## Instagram OAuth in WaveMaker + +In order to use the **Instagram** OAuth prefab, please follow the below steps: + +Disclaimer: The screenshots from the Instagram website were current at the time of writing this document, the actual screens might differ. + +1. Drag and drop the **Instagram OAuth Prefab** onto the canvas of the desired page in the application. + +[![](/learn/assets/Instagram_Prefab.png)](/learn/assets/Instagram_Prefab.png) + +2. Drag and drop a **Label** onto the canvas. Click on bind icon against the label caption property to the `callbackurl` property of the Instagram OAuth Prefab. + +[![](/learn/assets/instagram_bind.png)](/learn/assets/instagram_bind.png) + +3. Save and Run the project. Make a note of the Callback URL displayed on the Label. + +[![](/learn/assets/instagram_URI.png)](/learn/assets/instagram_URI.png) + +4. Login to the [Instagram](http://www.instagram.com/). +5. To open the Instagram API platform [click here](https://www.instagram.com/developer/). +6. Click Register Your Application tab to create an app. + +[![](/learn/assets/instagram_register.png)](/learn/assets/instagram_register.png) + +7. Click **Manage Clients** to acquire the _Client ID_ and _Client Secret_ for the created App Client. Paste the _callback URL_ from step 3 in the **redirect URI** section of the App in Instagram. + +[![](/learn/assets/instagram_ClientID.png)](/learn/assets/instagram_ClientID.png) + +8. From WaveMaker, select Prefab Properties. Enter the necessary server properties such as Clientid, Client secret obtained from the previous step. + +[![](/learn/assets/instagram_ClientID-1.png)](/learn/assets/instagram_ClientID-1.png) + +9. Run the project and you will be prompted to log in using Instagram. +10. Utilize the scope property of the Prefab, to achieve the advanced permissions. For more information on the scope property, [click here](https://www.instagram.com/developer/authorization/). + +:::note +When an app is created with Instagram developer suite, its status will be in **Sandbox mode**. Sandbox mode is a **fully functional environment,** that allows testing **the API** before submitting the app for **review**. Each created app will have to be reviewed by the Instagram team before making it live. For more details, [click here](https://www.instagram.com/developer/sandbox/). +::: + +After the OAuth authorization is completed, you can make API calls to the Instagram. This facilitates to fetch the information of the users and media from the Instagram. For more details on the API Endpoints, please [click here](https://www.instagram.com/developer/endpoints/). + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/linkedin.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/linkedin.md new file mode 100644 index 000000000..03762c52e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/oauth-prefabs/linkedin.md @@ -0,0 +1,40 @@ +--- +title: "LinkedIn" +id: "linkedin" +--- + +## Introduction + +OAuth 2.0 is an authorization framework, which is updated after the original OAuth protocol created in 2006. OAuth 2.0 is a standard protocol, which provides delegated secured access for web, mobile, and desktop applications. To know more about the working of WaveMaker OAuth Prefabs [click here](/learn/app-development/widgets/prefab/oauth-prefabs/). + +## LinkedIn OAuth in WaveMaker + +In order to use the **LinkedIn** OAuth prefab, please follow the below steps: **Disclaimer**: The screenshots from the LinkedIn website were current at the time of writing this document, the actual screens might differ. + +1. Log on to [https://developer.linkedin.com/](https://developer.linkedin.com/) and enter your credentials. LinkedIn Developers page is displayed. [![](/learn/assets/ld_homepage.png)](/learn/assets/ld_homepage.png) +2. Go to My Apps and click **Create Application**. Create a New Application page is displayed. [![](/learn/assets/ld_createapp1.png)](/learn/assets/ld_createapp1.png) +3. Enter **Company Name, Name, Description, Application Logo URL, Application Use, Website URL, Business Email** and **Business Phone** in their respective fields. Check the **LinkedIn API Terms of Use** checkbox and click **Submit**. Authorize Redirect URLs page is displayed. [![](/learn/assets/ld_sampleurl.png)](/learn/assets/ld_sampleurl.png) +4. Enter a valid sample **Authorized Redirect URLs** below **OAuth 2.0** and click **Add.** Click **Update.** Your application is successfully created. [![](/learn/assets/ld_success1..png)](/learn/assets/ld_success1..png) Note: Make a note of the **Client ID** and **Client Secret** + +# Usage Example + +1. Open WaveMaker and create an application. +2. Check and confirm the settings and click **Save** on the Project Settings window. +3. Select a Template for Main page and click **OK.** +4. Drag and Drop the **LinkedIn Prefab** from the Prefabs Tab under OAuth.You can use the default login page created by WaveMaker. +5. You can set the **Login Mode** to be: + + - _auto_ will in the run mode after initialization of the Prefab the app would automatically be navigated to the OAuth Authorization page + - _manual_ (default mode) will invoke the OAuth Authorization page on click of the login button + + [![](/learn/assets/linkedin_design1.png)](/learn/assets/linkedin_design1.png) +6. In the Properties Panel, below **SERVER PROPERTIES**, enter the **Appid, Page, Scope** and **Secret** in their respective fields. [![](/learn/assets/linkedin_props1.png)](/learn/assets/linkedin_props1.png) +7. Save and Run the application. +8. After you run the application, redirect URL is generated. You might have to click REMOVE TOOLBAR to get the URL. Copy the redirect uri till the _callback _part. For example, if your url looks like this: `https://www.linkedin.com/uas/oauth2/authorization?client_id=xxx&response_type=xxx&redirect_uri=https://www.wavemakeronline.com/run-xyz/projectname/prefabs/LinkedInOAuth/oAuthHandler/callback&state=xxx&scope=xxx` use only: `https://www.wavemakeronline.com/run-xyz/projectname/prefabs/LinkedInOAuth/oAuthHandler/callback` +9. Go to LinkedIn Developers – your project page and click on Settings on the left side. Add the generated redirect URL below **OAuth 2.0** and Click **Update.** [![](/learn/assets/ld_Settings.png)](/learn/assets/ld_Settings.png) +10. Go back to WaveMaker application and again Run the app. You will see the WaveMaker Login page if you have set the Login Mode to manual. Click the Login using Linkedin button. [![](/learn/assets/linkedin_run_manual.png)](/learn/assets/linkedin_run_manual.png) +11. You will be redirected to the LinkedIn Allow Access screen, this will be the screen you will first see if you have set Login Mode to auto. Enter your credentials to Login and click **Allow Access** You can now see the application with **Access Token** and **Callback URL**. [![](/learn/assets/ld_run_auto.png)](/learn/assets/ld_run_auto.png) +12. To use LinkedIn APIs, you need to [import the appropriate web service](/learn/services/web-services/web-services/). Go to [https://apigee.com/console/linkedin](https://apigee.com/console/linkedin), select the required API and get the Authorization key. +13. From WaveMaker app designer, import a web service with the proper credentials as obtained from the above step. [![ld_testurl](/learn/assets/ld_testurl.png)](/learn/assets/ld_testurl.png) + + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/qrcode.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/qrcode.md new file mode 100644 index 000000000..bda10f2d7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/qrcode.md @@ -0,0 +1,14 @@ +--- +title: "QRCode" +id: "qrcode" +--- +--- +**QRCode** prefab that ships with WaveMaker can be used to add any text or URL to your app in the QRCode format. This code, when scanned by a QR Reader, will display the stored content. For more information, see [QR Code](http://www.qrcode.com/en/). + +[![](/learn/assets/QRCode_Prefab.png)](/learn/assets/QRCode_Prefab.png) + +1. Drag and drop the **QRCode** prefab onto the canvas on any of the pages of your application. +2. The property of interest is the **text** which sets the information you want to store using this Prefab +3. You can also change the display style by setting the Darkcolor and Lightcolor property. +4. Type and Level can also be set for the QRCode. + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/youtube.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/youtube.md new file mode 100644 index 000000000..6e30d5114 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/prefab/youtube.md @@ -0,0 +1,16 @@ +--- +title: "Youtube" +id: "youtube" +--- +--- + +**Youtube** prefab ships with WaveMaker and it connects with Youtube to display a video on the web page. + +1. Drag and drop the **Youtube** prefab onto the canvas on any of the pages of your application. +2. Set the **Height**, **Width** and **Youtube URL** properties of the **Youtube** prefab using the **Properties Panel**. +3. Save and **Run** the project. You will see that the video is now embedded on the page in a container with specified height and width. + +[![](/learn/assets/prefab.png)](/learn/assets/prefab.png) + +[![](/learn/assets/youtube_props.png)](/learn/assets/youtube_props.png) + diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/ui-elements.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/ui-elements.md new file mode 100644 index 000000000..d6709d170 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/ui-elements.md @@ -0,0 +1,53 @@ +--- +title: "Composing Widgets" +id: "ui-elements" +sidebar_label: "Widgets Composition" +--- +Learn about widgets and how it works. + +--- + +Learn about Widgets in WaveMaker. These are HTML/Bootstrap based widgets with rich interaction and designed for highly-responsive design. Also, see the common Widget properties in this section. + +:::tip +To view the list of widgets in WaveMaker, see [Widgets Library](widget-library.md). +::: + +## How it works + +Pages are constructed as a composition of widgets using the visual drag-n-drop approach. Responsive Layout grid is used for the placement of widgets for automatically making them responsive to all devices. + +[![](/learn/assets/widget_concept.png)](/learn/assets/widget_concept.png) + +WaveMaker provides **HTML/Bootstrap based widgets or UI Components**, with rich interaction and for responsive design. Widgets are the building block of any application. They are the tools for exchange of information from the user to the project. Widgets eliminate repeated development and provide consistent behavior across browsers and platforms. Drag and drop action lets you add widgets to your project. + +Widgets could simply map to a standard HTML construct like a label or select or could be complex HTML structures like Lists or extended Forms built for responsive design. + +## Widget Properties + +Once you add a widget to your page, click on the widget to see the available actions in the **Properties Panel**. Below are some of the common actions of Widgets. + +[![](/learn/assets/widget_props.png)](/learn/assets/widget_props.png) + +### Basic Attributes +Define the content to be displayed in a widget by connecting it to a database query, web service, Java method, or another widget. Data binding provides integration with data sources known as ‘Variables’ or any other Widgets. Variables offer the ability to integrate with services such as a database, web service or any other backend service. [More on Variables and Binding](/learn/app-development/variables/data-integration/). + +### Styling +Use the **Styles** tab in the **Properties Panel** to define styles. Widget styles for alignment such as margin, padding, text & background, and border styles can be customized as per the required look-n-feel. Advanced users can switch to the Style **Page Mode** to edit the code. [More on Styling](/learn/app-development/ui-design/page-artefacts/#page-style "Markup, Scripting and Styles"). + +### Event Binding +Use the **Event** tab in the **Properties Panel** to choose the action for specific events. Widgets expose click, mouse enter/leave events, tap and double tap for multiple devices, which can be bound to Variables or methods of Services. [More on Events](/learn/responsive-web/web-ui-design/#events "Events and navigation"). For Mobile app, these take the form of [gestures](/learn/hybrid-mobile/mobile-page-concepts/#page-transitions-gestures). + +### Device +Use the **Device** tab in the **Properties Panel** to choose the widget visibility. Manage the widget visibility across device sizes. + +### Access Control +Define which user roles can access the widget in the **Security** tab of the **Properties Panel**. For more information, see [Role-based Access, and Widget Security](/learn/app-development/app-security/access-levels-permissions/#role-based-access-to-widgets). + +We have seen the basics of the HTML/Bootstrap based widgets or UI Components and properties. + +## See Also + +[Widgets Library](widget-library.md) +[Design Pages](/learn/app-development/ui-design/design-overview) +[Prefab - Custom Widgets](/learn/app-development/custom-widgets/prefabs-overview)    diff --git a/website/versioned_docs/version-v11.8.5/app-development/widgets/widget-library.md b/website/versioned_docs/version-v11.8.5/app-development/widgets/widget-library.md new file mode 100644 index 000000000..99c4879fc --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/app-development/widgets/widget-library.md @@ -0,0 +1,14 @@ +--- +title: "Widgets Library" +id: "widget-library" +sidebar_label: "Widgets Library" +--- +Widgets are HTML/Bootstrap based UI components with rich interaction and designed for responsiveness. View the entire list of Widgets in this page. + +:::note +Pages are designed as a composition of widgets. See [Design Pages](/app-development/ui-design/design-overview) and learn about widgets workflow. For more information, see [Widgets Overview](ui-elements.md). +::: + +import WidgetTabs from '@site/src/components/widgets.js' + + \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/connectors/connectors-architecture.md b/website/versioned_docs/version-v11.8.5/connectors/connectors-architecture.md new file mode 100644 index 000000000..e376e9d98 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/connectors/connectors-architecture.md @@ -0,0 +1,24 @@ +--- +title: "Architecture" +id: "connectors-architecture" +sidebar_label: "Architecture" +--- +--- + +## Connector Component view + +A Connector project contains three Components. + +1. **Connector API**: A Connector interface and skeleton of Connector APIs. +2. **Connector Impl**: Actual implantation of Connector interfaces including some required external Libraries. +3. **Configuration Profiles**: Externalizable properties are profiled via WaveMaker Profiles. +4. **Third-Party Systems**: External services like Kafka, MongoDB, AWS, Azure services, and more. + +[![lftr_sel](/learn/assets/connector/ConnectorArchitecture.png)](/learn/assets/connector/ConnectorArchitecture.png) + +## Connector view inside a WaveMaker App + +One or more Connectors can be used inside a WaveMaker Application. +Connectors are orchestrated through Java Services. + +[![lftr_sel](/learn/assets/connector/ConnectorInsideApp.png)](/learn/assets/connector/ConnectorInsideApp.png) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/connectors/connectors-building.md b/website/versioned_docs/version-v11.8.5/connectors/connectors-building.md new file mode 100644 index 000000000..4afc8a1c0 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/connectors/connectors-building.md @@ -0,0 +1,174 @@ +--- +title: "Build a New Connector" +id: "connectors-building" +sidebar_label: "Build a New Connector" +--- +--- + +This document explains how to build a Connector, and it explains about a Connector project and how it is structured. + +A Connector project is basically a multi-module spring-based maven project which can be developed and build outside of WaveMaker Studio. + +## Prerequisites + +1. Java 1.8 or above +2. Maven 3.1.0 or above +3. Any java editor such as Eclipse, Intelij..etc +4. Internet connection + +## Connector Archetype + +WaveMaker introduced a maven based Connector Archetype to create a new Connector. Connector project can be built as explained in the following steps. + +### Adding Profile + +Open maven setting xml file, you can find at `$M2_HOME/conf/settings.xml`. Adding the following profile in the profiles section + +```xml + + wmrepo + + + wavemaker-maven-repo + wavemaker-maven-repo + https://s3.amazonaws.com/maven.wavemaker.com/release + + + + com.wavemaker.connector + wavemaker-connector-archetype + 0.1 + + +``` + +#### Activate Profile + +Activate the above profile by adding the following lines outside of the profiles. + +```xml + + wmrepo + +``` + +### Commands used + +You can create a Connector project by using any of the following commands. Go to your terminal and execute the following command + +```shell +mvn archetype: generate –DgroupId=<> -DartifactId=<> -Dversion=<> +``` + +```shell +mvn archetype:generate +``` + +In either of the above approach, you should provide the following values. + +```shell +<> : +group id of the connector project +<> : artifact id of connector project +<> : version of connector project +``` + +For example, in the following example, we are going to create a MongoDB Connector using **wavemaker-connector-archetype**. + +``` +mvn archetype:generate –DgroupId=com.wavemaker.connector -DartifactId=mongodb -Dversion=1.0 +``` + +### Define Value Properties + +Above archetype will execute interactively. As a result it will ask the end-user to provide values for few properties and note these properties have default values if the user does not provide any value then default value will be considered. + +- Define value for property 'package' <<groupId>>: : +- Define value for property 'connector-name' <<artifactId>>: : +- Define value for property 'connector-description': A simple Connector <<connector-name>> that can be used in WaveMaker application: : +- Define value for property 'connector-java-class-name' WaveMaker<<connector-name>>Connector: : + +For the above properties will have default values such as + +**package:** default value is groupId given in mvn command +**connector-name:** default value is artifactId given in the mvn command +**connector-java-class-name:** default value is WaveMaker <<connectorName>>Connector + +#### Example-1 + +[![lftr_sel](/learn/assets/connector/connector-archetype.png)](/learn/assets/connector/connector-archetype.png) + +After providing the above values, it will ask for your confirmation to create a Connector. After confirming, the Connector project will be created. You can open the Connector project in any java editor such as Eclipse, IntelliJ, and more. + +#### Example-2 + +[![lftr_sel](/learn/assets/connector/connector-archetype-finish.png)](/learn/assets/connector/connector-archetype-finish.png) + +## About Connector Project + +A Connector project contains three modules. + +1. **API module**: this module contains a Connector interface and skeleton of Connector APIs. +2. **Implementation module**: this module contains an actual implementation of the Connector API. +3. **Packaging module**: this module will take care of packaging the Connector and the Connector developers don't need to do any changes in this module. + +[![lftr_sel](/learn/assets/connector/connector-module-base.png)](/learn/assets/connector/connector-module-base.png) + +### API Module + +In this module, users are expected to write Connector interfaces and this module contains + +1. **Connector interface**: A Connector is identified by an annotation “WMConnector”. Any interface which does have WMConnector annotation is considered a Connector interface. In a Connector project, you can have multiple interfaces with WMConnector annotations, however, the name value in the annotation should be the same. +2. **Connector metadata**: Metadata of a Connector such as version, name, description, and Connector configuration class. + +#### Version + +This is the Connector version, for every build, it increases the version. WaveMaker allows upgrade of the Connector only when the version is same, or higher than the existing version. + +#### Connector configuration class + +Connector configuration class is the spring configuration class available in the implementation module, if you have any changes either class name or package name change, then you must update in this file. + +[![lftr_sel](/learn/assets/connector/connector-api-module.png)](/learn/assets/connector/connector-api-module.png) + +### Impl Module + +In this module, users are expected to write their implementation of Connector interfaces and this module contains the following. + +1. **Implementation to connector Interface**: Actual implantation of Connector interfaces. +2. **Spring configuration class**: A Connector application is a spring-based project and there will be the spring configuration class where users can add their beans, component scans, properties loading, and more. +3. **Properties files**: There are two properties files in each Connector project. + +- **connector-externalizable.properties**: These are the properties that are externalized to the WaveMaker application when the Connector is imported. As a result, values can be managed in the WaveMaker application. +- **connector-local.properties**: These properties will not be externalized to the WaveMaker application and they are used only internally inside the Connector project. +- **Custom properties files**: Connector Developer can have any number of properties files, however, the developer should add these properties file spring configuration class. + +:::note +These custom property files are not externalized to the WaveMaker application. +::: + +4. **POM.xml**: User can add any maven dependencies based on the Connector project requirement. However, you have **wavemaker-app-runtime** as a bom dependency in Connector parent pom, most of the artifacts are available as transitive dependencies in a bom, so add a transitive dependency in your API or IMPL module without declaring the version. + +:::note +To see all the dependencies which are already available in wavemaker-app-runtime, you can either open wavemaker-app-runtime pom.xml by clicking on the dependency artifact or you can run following maven command to see all dependencies +::: + +```shell +mvn dependency:tree +``` + +5. **Test cases**: There will be a test case for each Connector interface, where users can add test cases, in addition, the test cases will have its own properties file, and spring configuration class. + +[![lftr_sel](/learn/assets/connector/connector-impl-testcases.png)](/learn/assets/connector/connector-impl-testcases.png) + +### Packaging Module + +This module is used for packaging the Connector. There will be a plugin in the packaging module of the pom xml file, which is responsible for the packaging of the Connector as a ZIP artifact. The user is not supposed to do any changes in this module. + +After Connector development is done, then it is time to build the Connector. Use the following command to build the Connector. + +```mvn clean install``` + +On successful build, under the Connector project **dist** directory, a zip artifact will be available. + +[![lftr_sel](/learn/assets/connector/connector-packaging-zip.png)](/learn/assets/connector/connector-packaging-zip.png) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/connectors/connectors-import.md b/website/versioned_docs/version-v11.8.5/connectors/connectors-import.md new file mode 100644 index 000000000..438894c35 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/connectors/connectors-import.md @@ -0,0 +1,67 @@ +--- +title: "Import Connectors" +id: "connectors-import" +sidebar_label: "Import Connectors" +--- +--- + +## Import a Connector into WaveMaker Studio + +We need a Connector zip to import it to the WaveMaker application. + +There are two ways to get the zip. + +- Go to the Releases section in the WaveMaker Connectors' Github account, and get the latest released version. +- After building the Connector, you will have a zip artifact in `/dist/Connector-name-version.zip`. + +In WaveMaker studio, import the Connector zip in the import resource dialog. Import resource allows you to import the Connector zip artifact. + +[![lftr_sel](/learn/assets/connector/connector-import.png)](/learn/assets/connector/connector-import.png) + +## Externalizing Connector Properties + +On successful import of Connector into a WaveMaker application, Connector externalizable properties are automatically profiled in the WaveMaker application profiles. The format of the Connector-profiled property is as shown below. + +```Connector.<>.<>.property=value``` + +- **`connectorId`**: name of the Connector +- **`configurationId`**: you can import the Connector once and can create multiple instances from it. While creating multiple instances, you have to provide `configurationId` for each instance. By default, `configurationId` is “default”. + +[![lftr_sel](/learn/assets/connector/connector-profiles.png)](/learn/assets/connector/connector-profiles.png) + +## Use Connector in Java Service + +Using Connector in java service is the same as using any spring bean. You can autowire the Connector in any java service, and it can be used in your APIs. + +[![lftr_sel](/learn/assets/connector/connector-in-java-service.png)](/learn/assets/connector/connector-in-java-service.png) + +## Multiple Instance of Connector + +You can import Connector into the WaveMaker project once and create as many instances you need. +Such as, you can import the MongoDB Connector once, and it can be used for various MongoDB databases by creating multiple instances of the Connector. + +The following are the steps to create multiple instances of a Connector. + +### Step-1 + +Since each instance of the Connector will have its own properties. So the end-users should add profile properties for new instances of Connectors. In the following profile property, `<>` is the name of the new instance of the Connector. + +```Connector.<>.<>.property=value``` + +Add all profile properties in the above format. Such as adding new instance “salesmongodb” properties in the following screen + +[![lftr_sel](/learn/assets/connector/connector-multi-instance-profile.png)](/learn/assets/connector/connector-multi-instance-profile.png) + +### Step-2 + +Add placeholders of the above new properties in `app.properties`. + +[![lftr_sel](/learn/assets/connector/connector-app-config.png)](/learn/assets/connector/connector-app-config.png) + +### Step-3 + +Using a new instance of the Connector in the Java Service. + +[![lftr_sel](/learn/assets/connector/connector-java-service-new-instance.png)](/learn/assets/connector/connector-java-service-new-instance.png) + +You can create variables on top of a Java Service to invoke a Java Service from the UI. \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/connectors/connectors-introduction.md b/website/versioned_docs/version-v11.8.5/connectors/connectors-introduction.md new file mode 100644 index 000000000..4fb40f0bd --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/connectors/connectors-introduction.md @@ -0,0 +1,21 @@ +--- +title: "Connectors" +id: "connectors-introduction" +sidebar_label: "Introduction" +--- +--- + +A Connector is a reusable Java-based backend extension for WaveMaker applications. Connectors are built as Java modules to connect with third-party services. Each Connector exposes a set of APIs as Java SDKs to be invoked from a WaveMaker application. + +For example, a Connector can accept an Excel file as an input, parse the data, and return the parsed response. +(Or) +A Connector could connect to an external service like Kafka, MongoDB, AWS, Azure services, etc., and provide the respective integration capabilities. + +## Highlights + +- Each Connector is built for a specific purpose and may integrate with one or more of the external services. +- Each Connector exposes a set of APIs as Java SDKs. +- Connectors are imported and used in the WaveMaker application. +- Connector is built once and reused in multiple WaveMaker applications. +- Each Connector runs in its own isolated container thereby providing the ability to have its own version of the third-party dependencies. +- Multiple connectors can be orchestrated inside a WaveMaker application to implement the business logic. diff --git a/website/versioned_docs/version-v11.8.5/connectors/connectors-list.md b/website/versioned_docs/version-v11.8.5/connectors/connectors-list.md new file mode 100644 index 000000000..c6ee8d25e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/connectors/connectors-list.md @@ -0,0 +1,108 @@ +--- +title: "Connectors List" +id: "connectors-list" +sidebar_label: "List of Connectors" +--- +--- + +Below are the Connectors developed by WaveMaker Team and are open-sourced. + +Search the full list of Connectors in WaveMaker's Github account https://github.com/wavemaker/?q=connector&type=&language=. + +## Email Connector + +Email Connector provides simplified APIs to integrate with any E-mail service provider. It provides methods for sending a plain text message, parameterized/templatized messages and also enables sending messages with attachments. + +This Email Connector is hosted at https://github.com/wavemaker/email-connector + +[Click here to see How-to use this Connector in WaveMaker App](/learn/how-tos/sending-email-using-java-service#docsNav). + +## Jasper Reports Connector + +Jasper Reports (https://community.jaspersoft.com/) is an open-source java reporting engine that enables Java developers to add reporting capabilities to their applications. Jasper Studio lets you build reports from various data sources, configure the look and feel of the report, and export the reports as xml files (called jrxmls). + +Jasper Reports Connector provides APIs to execute the jasper reports and export the report as PDF using the jasper templates (jrxmls). The WaveMaker application can invoke Connector by passing the required data source and parameter values and export it to various formats such as Html, PDF and Word doc. + +The Connector is hosted at: https://github.com/wavemaker/jasper-reports-connector + +[Click here to see How-to use this Connector in WaveMaker App](/learn/how-tos/generate-pdf-file-using-jasper-reports) + + +## Excel Connector + +Excel Connector provides APIs to parse the Excel file. Below, see How-to use this Connectors with tabular structures and return the table data as Java objects. The return response can be directly mapped to entity classes that enable it to easily persist the entities into database tables directly. + +The Connector sources are hosted at: https://github.com/wavemaker/excel-connector + +[Click here to see How-to use this Connector in WaveMaker App](/learn/how-tos/insert-data-from-excel) + +## Azure File Storage Connector + +Azure File storage (https://azure.microsoft.com/en-in/services/storage/files/) Connector provides simplified APIs to work with azure file storage to store and retrieve files from Azure Storage Service. Using this Connector, one can build the Upload, Download, List and Delete operations of files in Azure storage. + +The Connector sources are hosted at: https://github.com/wavemaker/azure-file-storage-connector + +[Click here to see How-to use this Connector in WaveMaker App](/learn/how-tos/azure-file-storage-connector) + +## Camunda Connector + +Camunda BPM is a lightweight, opensource platform for Business Process Management. Camunda is used primarily to automate Business Process WorkFlows and Decision Modeling into the applications. + +This Connector will provide an easy API to interact with the Camunda business processes to invoke and get the status of those processes. This Connector will enable WaveMaker developers to integrate workflows and decision modeling in their application. + +The Connector is hosted at: https://github.com/wavemaker/camunda-connector + +## AWS S3 Connector + +AWS S3 Connector provides simplified APIs to work with AWS S3 storage to store and retrieve files from it. Using this Connector, one can build the Upload, Download, List and Delete operations of files in S3. + +The Connector sources are hosted at: https://github.com/wavemaker/aws-s3-connector + +## MongoDB Connector + +MongoDB is an open-source document database which means it stores the data in JSON-like documents and it is the leading NoSQL database. MongoDB is a cross-platform, document-oriented database that provides, high performance, high availability, and easy scalability. MongoDB works on the concept of collection and document. + +The MongoDB Connector provides APIs to perform CRUD (Create, Read, Update, List) operations on the MongoDB documents. + +The Connector sources is hosted at: https://github.com/wavemaker/mongodb-connector + + +## Kafka Connector + +Apache Kafka (https://kafka.apache.org/) is an open-source, distributed publish-subscribe messaging system. Kafka is a fast, scalable, durable, fault-tolerant, and distributed messaging system by design. It was originally developed by LinkedIn, later, it became a part of the Apache project. + +This Connector works as both Publisher and Subscriber for the messages. Using this Connector, you can send messages to Kafka Queue and also register a callback listener to receive messages from a Kafka Queue as and when a new message is published. + +The Connector sources are found at: https://github.com/wavemaker/kafka-connector + +## AWS Lambda Connector + +With AWS Lambda, you can run code without provisioning or managing servers. You pay only for the compute time that you consume—there’s no charge when your code isn’t running. You can run code for virtually any type of application or backend service—all with zero administration. Just upload your code and Lambda takes care of everything required to run and scale your code with high availability. You can set up your code to automatically trigger from other AWS services or call it directly from any web or mobile app. + +This Connector enables you to invoke the lambda function from a WaveMaker application. + +The Connector sources are hosted at: https://github.com/wavemaker/aws-lambda-connector + + +## AWS SNS Connector + +Amazon Simple Notification Service (Amazon SNS) is a web service that coordinates and manages the delivery or sending of messages to subscribing endpoints or clients. In Amazon SNS, there are two types of clients—publishers and subscribers—also referred to as producers and consumers. Publishers communicate asynchronously with subscribers by producing and sending a message to a topic. Subscribers (that is, web servers, email addresses, Amazon SQS queues, AWS Lambda functions) consume or receive the messages. +The AWS SNS Connector enables you to add Push Notifications capability to WaveMaker web and mobile applications. It leverages SNS service and uses the FCM (Firebase Cloud Messaging) to send the notification to Web Browsers, Android and iOS Devices. + +The Connector sources are found at: https://github.com/wavemaker/aws-sns-connector + +## Twilio Connector + +Twilio is a cloud based communication platform which performs communication functions using its API's. Twilio lets you receive SMS, MMS, WhatsApp, Voice messages or even respond to the messages and many more services. + +This connector exposes API's to send messages to and receive messages from Twilio using WaveMaker application. + +The Connector sources are found at: https://github.com/wavemaker/twilio-connector + +[Click here to see How-to use this Connector in WaveMaker App](/learn/how-tos/twilio-connector) + +## Google Cloud File Storage Connector + +Cloud Storage is a flexible, scalable, and durable storage option for your virtual machine instances. Google Cloud File Storage Connector provides simplified APIs to work with google cloud file storage to store and retrieve files from Cloud Storage buckets. Using this Connector, one can Upload, Download, List and Delete operations of files in Google cloud storage. This connector exposes api to interact with Google cloud file storage from WaveMaker application. + +The Connector sources are found at: https://github.com/wavemaker/google-cloud-file-storage-connector diff --git a/website/versioned_docs/version-v11.8.5/documentation-reference.md b/website/versioned_docs/version-v11.8.5/documentation-reference.md new file mode 100644 index 000000000..1b1d06653 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/documentation-reference.md @@ -0,0 +1,88 @@ +--- +id: "documentation-reference" +title: "WaveMaker Developers Guide" +sidebar_label: "Introduction" +--- +Introduction to WaveMaker. Find a complete developer's guide to build an app with Low-code approach. + +--- + +[WaveMaker](https://www.wavemaker.com/) is a low-code platform for developing modern and secured applications, including native mobile apps and scalable web apps. The Studio offers rich design experience with over [80 out-of-the-box widgets](/learn/app-development/widgets/widget-library), ready to consume APIs. Import or design APIs for Databases, REST services, Java services, and more. + +WaveMaker lays down extensive developer tooling capabilities and integration services. You can customize complex solutions to simpler format, such as variables. Bind them to the user interface to function simply. + +In addition, create your own custom widgets called [Prefabs](/learn/app-development/custom-widgets/prefabs-overview) that are API-integrated, encapsulating functionality, interaction and data, allowing you to develop once and edit and reuse as many times. + +The platform provides you with everything you need for developing and building production-ready applications with faster and streamlined deployment process. Find complete developers' guide for building low-code apps using WaveMaker. + +## WaveMaker App Development Flow + +Develop apps with a design-first approach or API-first approach. For a general idea, see the flow chart below. + +```mermaid +graph TD; +A[Create Page]-->B(Drag and drop Widgets) +B-->C{API Existing} +C-->|Yes| D[fa:fa-link Bind Service] +C-->|No| E[Import/Create Service] +E-->|Creates Variable | F[Preview App] +D-->|Customize Variable | F[Preview App] +``` + +### Create an App + +**Step-1**: WaveMaker app is a collection of pages. Design your app by dragging-and-dropping widgets on the page. + +:::tip +Widgets are UI elements, which make your app functional without coding. Explore the [widgets library](/learn/app-development/widgets/widget-library). +::: + +**Step-2**: Create or import a backend service. It can be a data service, web service, java service, security service, or use a third-party API. + +:::tip +WaveMaker provides a few ready-to-use sample databases and services. To learn more, see [Backend Services](/learn/app-development/services/creating-backend-services). +::: + +**Step-3**: In a few simple clicks, using [variables](/learn/app-development/variables/variables), integrate the backend service with the widgets. + +**Step-4**: Deploy application with the [one-click deployment](/learn/app-development/deployment/one-click-deployment/) process. + +### See in action + +View the short video to see how WaveMaker apps work in a three-layered architecture, which includes, UI, binding, and backend services. + + + +## WaveMaker Studio Editions + +WaveMaker offers two variants of Studio. For cloud-based and on-premise development, respectively. + +### 1. WaveMaker Online (WMO) +WMO is a cloud-based product - no installation is required. For more information on the pre-requisites and setup guide, see [WaveMaker Pre-requisites](/learn/app-development/wavemaker-overview/pre-requisites) and [Online Setup Guide](/learn/wmo-setup). + +### 2. WaveMaker Enterprise (WME) +WME is an on-premise product. For WME installation, see [WaveMaker Enterprise Setup Guide](/learn/on-premise/welcome). + +:::note +Most of the WaveMaker app development capabilities are available in WMO and WME editions. Even so, Enterprise edition offers more specific business integrations like Git Enterprise, behind the firewall services, Single sign-on for platform logins, and more. +::: + +## Quick Start Guide + +| To | See | +| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| Start with beginner's guide | [Video Tutorials](/learn/tutorials) | +| For installation related information, On-premise Setup | [Pre-requisites to Develop App in WaveMaker](/learn/app-development/wavemaker-overview/pre-requisites) | +| Get the WaveMaker Studio walkthrough | [Product Terminology and Dashboard Walkthrough](/learn/app-development/wavemaker-overview/product-walkthrough) | +| Explore Widgets and play around | [Widgets Library](/learn/app-development/widgets/widget-library) | +| Build an app in 5 mins | [Build a WaveMaker App in 5 Minutes](https://www.youtube.com/watch?list=PLNlIJ337WpshRs-8eCubDm2vilhsloiqs&v=tLjGGJbrZ2Q) | +| Jumpstart to app building process and create a simple app. | [WaveMaker App Building Essentials](/learn/jump-start/jump-start-app-essentials/) | + + +## [Guided Trial](https://www.wavemaker.com/talk-to-expert/) + +We offer a guided trial. During this period you can develop, test, run and collaborate with your team members. Deploy your app to Amazon Web Service or WaveMaker Demo Cloud. At the end of the 30-day trial, you get an option to choose a suitable plan in order to continue working on the app. There are purchase plans for monthly and annual subscription. To get a customized plan for your organization, talk to our [Consultant](https://www.wavemaker.com/talk-to-expert/). + +--- +#### Notice something is incorrect or outdated? +First off, great catch! We appreciate your discovery and want to ensure it gets addressed immediately. Please let us know [here](https://github.com/wavemaker/docs/issues/new). diff --git a/website/versioned_docs/version-v11.8.5/enterprise-release-notes.md b/website/versioned_docs/version-v11.8.5/enterprise-release-notes.md new file mode 100644 index 000000000..9e62df5de --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/enterprise-release-notes.md @@ -0,0 +1,192 @@ +--- +title: Enterprise Release +id: "enterprise-release-notes" +sidebar_label: "Enterprise Release (WME)" + +--- + +:::note +This document applies to Enterprise users only. If you are a WaveMaker Online (WMO) user, see [WaveMaker Online Release](/learn/wavemaker-release-notes). +::: + +See what's new in WaveMaker—including new features, enhancements, and bug fixes. If you experience bugs or issues, please get in touch with [support](mailto:support@wavemaker.com). + +Follow our [team blog](/learn/blog) to learn product updates from the engineers who develop it. + +## Release History + +--- + +### WaveMaker Enterprise v11.x + + +|Named Version|Releases Include|What's in it| Release Date| +|---|---|---|---| +|**v11.8.5**

*latest*

| - [v11.8.5](/learn/wavemaker-release-notes/v11-8-5) | WaveMaker 11.8.5 includes enhancements and bug fixes. React Native can now be embedded into native applications. Skeleton Loader supports Lottie animations, and you can control the visibility of child components. The Dialog widget has a new look. Bug fixes include Git navigation, Datatable events, Theme Updates, and checkbox selection issues. React Native fixes address Wizard widget steps and file upload restrictions. |07 October 2024. | +|**v11.8.4** | - [v11.8.4](/learn/wavemaker-release-notes/v11-8-4) |WaveMaker 11.8.4 is here with enhancements in Dialogs User Interface(UI), and individual Form field reset properties along with some major bug fixes related to Datatable, Prefab Configuration and so on. This would also include React Native bug fixes related to Donut chart center label, hiding and showing the widgets, starting and stopping animations, File upload restrictions, and so on. |23 September 2024. | +|**v11.8.3** | - [v11.8.3](/learn/wavemaker-release-notes/v11-8-3) |WaveMaker 11.8.3 is here with enhancements to reduce application loading time and the `gotoStep` function in the Wizard widget, along with several bug fixes. This release also introduces a new CSS class in the Accordion widget, accessibility labels for widgets, and various React Native bug fixes.| 09 September 2024 | +|**v11.8.2** | - [v11.8.2](/learn/wavemaker-release-notes/v11-8-2) |WaveMaker release 11.8.2 is a bug fix release which includes the enhancements in FileUpload widget, API Orchestration, and few bug fixes. This release also includes new CSS classes for Chart widget and other React Native fixes related to the Show property, Currency widget, Ripple effect, and Wizard widget. | 26 August 2024 | +|**v11.8.1** | - [v11.8.1](/learn/wavemaker-release-notes/v11-8-1) |WaveMaker release 11.8.1 is majorly a bug fix release which includes the issues with vulnerability and other User Interface (UI) issues. This release also has a new CSS class for Lottie Player and a few React Native and Cordova bug fixes. | 12 August 2024 | +|**v11.8.0** | - [v11.8.0](/learn/wavemaker-release-notes/v11-8-0) |WaveMaker release 11.8.0, includes includes significant upgrades like Angular 17 and Expo 50 along with Artifact sharing between WaveMaker Enterprise (WME) setups and Single Page Application (SPA) behavior as new features. In React Native, new CSS style classes in Slider widget, setting range in Slider widget, Secure Sockets Layer (SSL) certificate pinning, navigation in Wizard widget, and Wheel date picker are some of the ehancements along with many bug fixes. | 30 Jul 2024 | +|**v11.7.5** | - [v11.7.5](/learn/wavemaker-release-notes/v11-7-5) |WaveMaker release 11.7.5, includes essential bug fixes. | 08 Jul 2024 | +|**v11.7.4** | - [v11.7.4](/learn/wavemaker-release-notes/v11-7-4) | In WaveMaker 11.7.4 we have extended support for application deployment with Java 17 and 21. Included improvements like the Themes section in Project Configuration, iframe widget message, and some bug fixes. | 01 Jul 2024 | +|**v11.7.3** | - [v11.7.3](/learn/wavemaker-release-notes/v11-7-3) | This release includes studio performance improvements, and some bug fixes. | 17 Jun 2024 | +|**v11.7.2** | - [v11.7.2](/learn/wavemaker-release-notes/v11-7-2) | This release includes performance improvements, artifact version management, notifications response in Project Hub to improve perforamance of Studio designer and project opening, and some bug fixes. | 03 Jun 2024 | +|**v11.7.1** | - [v11.7.1](/learn/wavemaker-release-notes/v11-7-1) | Includes a new feature, Pull Request (PR) Flow. This also includes some enhancements like Internationalization (i18n) message customization, extended Semantic Versioning, disabling Prefab editing in a project, and other bug fixes. | 28 May 2024 | +|**v11.7.0** | - [v11.7.0](/learn/wavemaker-release-notes/v11-7-0) | Includes New Studio with enhanced user experience and performance. This release has new features like API reimport and impact analysis along with many enhancements and bug fixes. In React Native, we have introduced many new features like CSS variables for styling, Dynamic forms, Accessibility, and Custom Template for widgets along with enhancements and bug fixes. This also includes an issue that was fixed where the users do not need to provide case-sensitive details in the project. | 30 April 2024 | +|**v11.6.1** | - [v11.6.1](/learn/wavemaker-release-notes/v11-6-1)
- [v11.6.0](/learn/wavemaker-release-notes/v11-6-0) | Includes multiple enhancements like dynamic passing of Content Delivery Network(CDN) URL as a system property, **Show** field for edit mode in Data Table widget, conditional classes for few input widgets, and improved security Role Mapping configurations along with many bug fixes related to new studio based on Angular which will be a phased rollout. | 26 Mar 2024 | +|**v11.5.3** | - [v11.5.3](/learn/wavemaker-release-notes/v11-5-3) | Includes enhancements like conditional classes for input widgets, setting the next button as default in the Wizard widget, and support to add links in the Label along with other bug fixes in React Native and Studio Page Workspace. | 23 Jan 2024 | +|**v11.5.2**| - [v11.5.2](/learn/wavemaker-release-notes/v11-5-2) | Includes enhancements like an image as thumb and multiple slides display in the Carousel and other bug fixes in React Native and Studio Page Workspace. | 26 Dec 2023 | +|**v11.5.1**| - [v11.5.1](/learn/wavemaker-release-notes/v11-5-1)
- [v11.5.0](/learn/wavemaker-release-notes/v11-5-0)
- [v11.4.3](/learn/wavemaker-release-notes/v11-4-3) | Includes enhancements in Widgets and multiple bug fixes related to Studio Page Workspace, React Native, Cordova, and others. Also includes new features like Appium Support, Dockerfiles in a project, importing icon font family, and enhancements like Angular framework support for Prefab workspace, NG studio upgrade to version 15, changes in project shell web template and other bug fixes. Lastly, addressed bug fixes related to the Prefab artifact and Studio Page Workspace. Introduced an option to upload platform logs to AWS S3 link in the Config portal. Entended support to list users for all the team members. | 13 Dec 2023 | +|**v11.4.2** | - [v11.4.2](/learn/wavemaker-release-notes/v11-4-2)
- [v11.4.1](/learn/wavemaker-release-notes/v11-4-1)
- [v11.4.0](/learn/wavemaker-release-notes/v11-4-0) | New features to improve developer collaboration, including the Core project, API reimport analysis report, and a few React Native features, Live Form, and Database Variables, and more. Also, included enhancements, such as support for language fonts, indication mark in the Select widget, and bug fixes. Includes Dynamic Accordion as a new feature and horizontal display of radio buttons as an enhancement in React Native. It also includes support for Bitbucket 8 VCS provider and timezone in the Date widget along with some other enhancements and bug fixes. | 03 Oct 2023 | +|**v11.3.7** | - v11.3.7 | This release includes bug fixes
Includes UI fixes
It also includes support for Bitbucket 8 VCS provider | 25 Sep 2023 | +|**v11.2.6** | - v11.2.6 | This release includes bug fixes
Includes UI fixes
It also includes support for Bitbucket 8 VCS provider | 25 Sep 2023 | +|**v11.3.6** | - [v11.3.6](/learn/wavemaker-release-notes/v11-3-6)
- [v11.3.5](/learn/wavemaker-release-notes/v11-3-5) | New features in React Native, such as Multi-theme support, Touch events, Audio widget, RTL Layout, Multiple selections in the List widget, React Native feature enhancements, and other bug fixes. And it also have Enhancements for the Googlemap Prefab, pagination, as well as bug fixes for nested menus, app crashing, and database queries and procedures. | 14 Aug 2023 | +|**v11.3.4** | - [v11.3.4](/learn/wavemaker-release-notes/v11-3-4)
- [v11.3.3](/learn/wavemaker-release-notes/v11-3-3) | WaveMaker has released a version, 11.3.4, containing bug fixes related to access denied pop-ups and slow loading of the project listing page. | 14 Jun 2023 | +|**v11.3.2** | - [v11.3.2](/learn/wavemaker-release-notes/v11-3-2) | This release includes enhancements related to mobile and bug fixes related to Summary Row, Material 2.0 theme, assigning server port, and more. | 26 May 2023 | +|**v11.3.1** | - v11.3.1
- [v11.3.0](/learn/wavemaker-release-notes/v11-3-0) | This release includes new features, including Publish to Marketplace and consume, Semantic Versioning support, React Native Lottie file support, loaders and more. | 04 May 2023 | +|**v11.2.5** | - [v11.2.5](/learn/wavemaker-release-notes/v11-2-5) | This release includes bug fixes for accessibility in widgets and In-memory sessions.
Includes UI fixes | 20 March 2023 | +|**v11.2.4** | - [v11.2.4](/learn/wavemaker-release-notes/v11-2-4)
- v11.2.3 | This release includes bug fixes for Dynamic Data Table infinite scroll pagination and keyboard date picker and along with Fixed the Connectors artifact import issue, which earlier failed and could not run existing connectors.
Includes UI fixes | 13 Febraury 2023 | +|**v11.2.2** | - [v11.2.2](/learn/wavemaker-release-notes/v11-2-2)
- [v11.2.1](/learn/wavemaker-release-notes/v11-2-1) | This release includes support to mock imported APIs using MockingBird Server Extension, formatting fixes, Calendar widget accessibility and icon rendering fixes, and user account log out related issues. | 19 January 2023 | +|**v11.2.0** | - [v11.2.0](/learn/wavemaker-release-notes/v11-2-0) | This release includes several new features, including One-click enabling of API Mocking in Studio, the easy discovery of dependencies of services and methods to compose Java API, Single Page App behavior for UI, the Ability to create new projects from VCS repo for Teams users, Update timezones at Pages and Widget level, changes in JDBC connectors, Cordova Android updates, bug fixes, and more.|28 November 2022| +|**v11.1.3**|- [v11.1.3](/learn/wavemaker-release-notes/v11-1-3)
- [v11.1.2](/learn/wavemaker-release-notes/v11-1-2)
- [v11.1.1](/learn/wavemaker-release-notes/v11-1-1)
- [v11.1.0](/learn/wavemaker-release-notes/v11-1-0)
- [v11.0.3](/learn/wavemaker-release-notes/v11-0-3)
- [v11.0.2](/learn/wavemaker-release-notes/v11-0-2)
- [v11.0.1](/learn/wavemaker-release-notes/v11-0-1)
- [v10.15.0](/learn/wavemaker-release-notes/v10-15-0)
- [v10.14.0](/learn/wavemaker-release-notes/v10-14-0) | Includes new features like React Native, Layout and Flex Widget in Cordova, Multi-version Studio, API composer toolkit, API Mock Server extension, pagination for imported APIs, Java 11, SAML library updates, Azure Repos, MTLS for REST APIs, and more. [Read more.](/learn/app-development/wavemaker-overview/wavemaker-11-beta) |03 October 2022| + + +### WaveMaker Enterprise v10.x + +|Named Version|Releases Include|What's in it| Release Date| +|---|---|---|---| +|**v10.13.2**|- [v10.13.2](/learn/wavemaker-release-notes/v10-13-2)
- [v10.13.1](/learn/wavemaker-release-notes/v10-13-1)
- [v10.13.0](/learn/wavemaker-release-notes/v10-13-0)
- [v10.12.2](/learn/wavemaker-release-notes/v10-12-2)
- [v10.12.1](/learn/wavemaker-release-notes/v10-12-1)
- [v10.12.0](/learn/wavemaker-release-notes/v10-12-0)
| New features and bug fixes|12 April 2022| +|**v10.11.2**|- [v10.11.2](/learn/wavemaker-release-notes/v10-11-2)|UI fixes and bug fixes|24 January 2022 | +| **v10.11.1** |- [v10.11.1](/learn/wavemaker-release-notes/v10-11-1)|Bug fixes|12 January 2022 | +| **v10.11.0** |- [v10.11.0](/learn/wavemaker-release-notes/v10-11-0)
- [v10.10.3](/learn/wavemaker-release-notes/v10-10-3)
- [v10.10.2](/learn/wavemaker-release-notes/v10-10-2)
- [v10.10.1](/learn/wavemaker-release-notes/v10-10-1) |New features and bug fixes|24 December 2021 | +|**v10.10.0**|- [v10.10.0](/learn/wavemaker-release-notes/v10-10-0)
- [v10.9.2](/learn/wavemaker-release-notes/v10-9-2)
- [v10.9.1](/learn/wavemaker-release-notes/v10-9-1)
- [v10.9.0](/learn/wavemaker-release-notes/v10-9-0)
- [v10.8.2](/learn/wavemaker-release-notes/v10-8-2)
- v10.8.1| New features and bug fixes

- v10.8.1: GoogleMaps Prefab update failure |22 November 2021 | +|**v10.8.0** |- [v10.8.0](/learn/wavemaker-release-notes/v10-8-0)
- [v10.7.5](/learn/wavemaker-release-notes/v10-7-5)
- [v10.7.4](/learn/wavemaker-release-notes/v10-7-4)
- [v10.7.3](/learn/wavemaker-release-notes/v10-7-3)
- [v10.7.2](/learn/wavemaker-release-notes/v10-7-2) |New features and bug fixes | 16 August 2021| +|**v10.7.1** |- [v10.7.1](/learn/wavemaker-release-notes/v10-7-1)
- [v10.7.0](/learn/wavemaker-release-notes/v10-7-0)
- [v10.6.9](/learn/wavemaker-release-notes/v10-6-9)
- [v10.6.7](/learn/wavemaker-release-notes/v10-6-7)
- [v10.6.6](/learn/wavemaker-release-notes/v10-6-6)
- [v10.6.5](/learn/wavemaker-release-notes/v10-6-5)
- [v10.6.4](/learn/wavemaker-release-notes/v10-6-4)
- [v10.6.3](/learn/wavemaker-release-notes/v10-6-3) |New features and bug fixes |04 June 2021| +|**v10.6.2**| - [v10.6.2](/learn/wavemaker-release-notes/v10-6-2)| Bug fixes |25 January 2021| +| **v10.6.1** | - [v10.6.1](/learn/wavemaker-release-notes/v10-6-1)
- [v10.6.0](/learn/wavemaker-release-notes/v10-6-0)| New features and bug fixes|24 December 2020| +|**v10.5.6**| - [v10.5.6](/learn/wavemaker-release-notes/v10-5-6)
- [v10.5.5](/learn/wavemaker-release-notes/v10-5-5)
- [v10.5.4](/learn/wavemaker-release-notes/v10-5-4)
|Bug fixes |28 October 2020| +|**v10.5.3**|- [v10.5.3](/learn/wavemaker-release-notes/v10-5-3)
- [v10.5.2](/learn/wavemaker-release-notes/v10-5-2)
- [v10.5.1](/learn/wavemaker-release-notes/v10-5-1)
- [v10.5.0](/learn/wavemaker-release-notes/v10-5-0) |New features and bug fixes|29 July 2020| +|**v10.4.2**|- [v10.4.2](/learn/wavemaker-release-notes/v10-4-2)
- [v10.4.1](/learn/wavemaker-release-notes/v10-4-1)
- [v10.4.0](/learn/wavemaker-release-notes/v10-4-0)
- [v10.3.3](/learn/wavemaker-release-notes/v10-3-3)
- [v10.3.2](/learn/wavemaker-release-notes/v10-3-2) |New features and bug fixes |10 May 2020| +|**v10.3.1**|- [v10.3.1](/learn/wavemaker-release-notes/v10-3-1)
- [v10.3.0](/learn/wavemaker-release-notes/v10-3-0)
- v10.2.8
- [v10.2.7](/learn/wavemaker-release-notes/v10-2-7)
- [v10.2.6](/learn/wavemaker-release-notes/v10-2-6)
- v10.2.5
- [v10.2.4](/learn/wavemaker-release-notes/v10-2-4)
- [v10.2.3](/learn/wavemaker-release-notes/v10-2-3)
- [v10.2.2](/learn/wavemaker-release-notes/v10-2-2)
- [v10.2.1](/learn/wavemaker-release-notes/v10-2-1) |New features and bug fixes

v10.2.5: UX changes to the subscription [account settings page](https://www.wavemakeronline.com/subscriptions/app/main.html#/account/subscriptions) |14 February 2020| +|**v10.2.0**|- [v10.2.0](/learn/wavemaker-release-notes/v10-2-0) | New features and bug fixes | 11 November 2019| +|**v10.1.2**|- v10.1.2,
- v10.1.1 |Bug fixes | 25 October 2019| +|**v10.1.0**|- [v10.1.0](/learn/wavemaker-release-notes/v10-1-0)
- [v10.0.4](/learn/wavemaker-release-notes/v10-0-4) |New features and bug fixes |19 August 2019| +|**v10.0.3**| - [v10.0.3](/learn/wavemaker-release-notes/v10-0-3)
- [v10.0.2](/learn/wavemaker-release-notes/v10-0-2)
- [v10.0.1](/learn/wavemaker-release-notes/v10-0-1)
- [v10 GA](/learn/wavemaker-release-notes/v10-0-ga)
- [Beta: v10](/learn/wavemaker-release-notes/v10-0-preview) |New features and bug fixes

v10-0-1: Migration bug fixes

v10-0-beta: Try new features and enhancements before 10.GA release |29 May, 2019| + + +## Technology Stack + +Last updated: [v11.8.5](/learn/wavemaker-release-notes/v11-8-5) + +--- + +### UI Frameworks + +| Description | JS Library | Version | +| --- | --- | --- | +| JS Binding | jquery | 3.7.1 | +| | jquery-ui* | 1.13.3 | +| MVC Framework | Angular | 17.3.11 | +| | ngx-bootstrap | 9.0.0 | +| Styles | bootstrap | 3.3.7 | +| Charting | d3 | 7.8.5 | +| | nvd3 | 1.8.11 | +| Built-in functions | lodash-es | 4.17.21| +| Device support, gestures | hammerjs | 2.0.8 | + +Optimized jQuery-UI library excluding unwanted components like accordion, datepicker, dialog, progressbar, spinner, tabs, and all jQuery-UI Effects. + +### Backend Frameworks + +| Description | Java Library | Version | +| --- | --- | --- | +| | Spring Framework | 5.3.39 | +| Security framework | Spring Security | 5.8.14 | +| Java JSON utilities | Gson | 2.11.0 | +| DB Persistence library | Hibernate | 5.6.15.Final | +| Sample database | HSQL | 2.7.3 | +| JSON library | Jackson | 2.17.2 | +| Logging framework | SLF4j | 1.7.36 | +| Logging Implementation | Log4j2 | 2.18.0| +| Http client library | HttpComponents - httpclient | 4.5.14 | +| Servlet Framework | | 4.0.4 | +| Database Connection Pooling | HikariCP | 5.1.0 | +| | Commons Lang3 | 3.17.0 | +| | Guava | 33.3.0-jre | +| | Postgresql Driver | 42.7.4 | + + +### Runtime Environment + +| Description | Version | +| --- | --- | +| JDK | 11 | +| WebSphere Liberty | 19.0.0.1+ | +| JBoss Wildfly | 15+ | +| Tomcat | 9.0.87 | +| Cordova (mobile apps)
Android
iOS |12.0.0
13.0.0
17.5 | + +:::note +- Cordova-iOS supports from iOS 16. +- Cordova-Android supports from iOS Android 24 (Nougat). +::: + +This is the default Tomcat runtime support. Apps can be deployed to any standard Java Web Server running on JDK 11. For more information, see [here](/learn/app-development/deployment/deployment-web-server). + + +# Build Environment for Studio +--- + +:::important + +With the release of 11.4, we have ended our support for WaveMaker 10 projects. To know more, see [Ending Support to WaveMaker 10 Projects](/learn/blog/2023/08/11/wavemaker10x-end-of-support). +::: + +## Build Environment 11 + +### React Native 11 + +#### Environment Setup + +|Description| Version| +|---|---| +|Java | 11 | +|Node|18.16.1| +|Maven| 3.9.8 | +|npm | 9.5.1| +|Ant| 1.10.11| +| Android Studio | Ladybug 2024.2.1 | +| SDK Build Tools | 34.0.0 | +| [wm-reactnative-cli](https://www.npmjs.com/package/@wavemaker/wm-reactnative-cli) | 1.8.5 | +| Android Gradle Plugin (AGP) | 8.3 - 8.7 | + +:::note +It is required to use Android Studio version be **Iguana | 2023.2.1** or above and Android Gradle Plugin(AGP) version be **8.3** and above. The recommended versions for Android Studio is **Ladybug | 2024.2.1** and AGP is **8.3**. + +Please ensure that your [Android Studio](https://developer.android.com/studio/releases#android_gradle_plugin_and_android_studio_compatibility) has a compatible version of the [AGP](https://developer.android.com/build/releases/past-releases/agp-8-3-0-release-notes#compatibility). Additionally, verify the compatibility of the AGP with the SDK build tools version, JDK, and Gradle version. +::: + +#### SDK Update + +|Description| Version| +|---|---| +| Expo | 50.0.17 | +| React Native | 0.73.6 | + +### Angular Web and Mobile 11 + +|Description| Version| +|---|---| +|Java | 11 | +|Node| 18.16.1| +|Maven| 3.9.8 | +|npm | 9.5.1| +|Ant| 1.10.11| + +For more information about building projects with Maven, see [here](/learn/app-development/deployment/building-with-maven). + +## Older Releases + +- **[WaveMaker 9.x Documentation](https://www.wavemaker.com/9/learn/index.html)** +- **[WaveMaker 8.x Documentation](https://www.wavemaker.com/8/learn/index.html)** diff --git a/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/getting-started.md b/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/getting-started.md new file mode 100644 index 000000000..fa25723ab --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/getting-started.md @@ -0,0 +1,37 @@ +--- +title: "WaveMaker MockingBird Setup Process" +id: "getting-started" +sidebar_label: "Overview" +--- +--- + +[MockingBird](/learn/app-development/services/mock-services/mock-imported-apis) is an extension that creates mocks for backend APIs in WaveMaker Studio. This documentation describes the process for setting up MockingBird and integrate it with WaveMaker Enterprise (WME). + +:::note +MockingBird for WaveMaker Enterprise works on Kubernetes environment. Thus, related terminolgies are used in this series of documentation. +::: + +- MockingBird Extension should be installed on K8s Cluster. It can be hosted and managed by an organization on their own K8s Cluster. + +- You can setup MockingBird on any K8s Cluster. + +## MockingBird Platform Setup Process + +MockingBird setup requires you to follow the steps below. + + +### 1. Understanding and Setting up Prerequisites + +Understand and procure the [Prerequisites](/learn/extensions/mockingbird/enterprise/prerequisites), including [Persisted Volume Creation](/learn/extensions/mockingbird/enterprise/persistent-volumes). + +### 2. Install MockingBird Platform + +Start installing [Helm Charts](/learn/extensions/mockingbird/enterprise/install). + +### 3. Integrating with WME platform + +Once MockingBird setup is successfully installed, follow these steps to integrate it with the WME Platform. + +Integrate the above installed MockingBird extension with WME [Integrate](/learn/extensions/mockingbird/enterprise/integrate). + + diff --git a/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/install.md b/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/install.md new file mode 100644 index 000000000..6d1a3a0a4 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/install.md @@ -0,0 +1,126 @@ +--- +title: "Install MockingBird Platform" +id: "install" +sidebar_label: "Install" +--- +--- + +## Setting up cluster access at JumpBox + +- Once K8s Cluster is ready, verify K8s access using the following command + +```bash +kubectl config view +``` +- Cross-verify both K8s server and Kubctl versions using the following command + +```bash +kubectl version +``` + +### Namespace Creation + +- Create a new namespace + +```bash +kubectl create ns mockingbird +``` + +## Download deliverables + +- Download the helm package from the link shared by WaveMaker support team. + +```bash +cat | helm registry login -u _json_key_base64 --password-stdin https://us-east4-docker.pkg.dev +``` + +```bash +helm pull oci://us-east4-docker.pkg.dev/api-mock-server-332212/mockingbird/helm-charts/api-mock-server --version [MOCKINGBIRD-VERSION] +``` + + +### Check sha1sum + +- Verify SHA1SUM of downloaded file with the SHA1SUM given by WaveMaker support + +```bash +sha1sum api-mock-server-[MOCKINGBIRD-VERSION].tgz +``` + +### Login to Docker/Podman + +- Login to docker with JSON Key provided by WaveMaker support + +```bash +cat | docker login -u _json_key_base64 --password-stdin https://us-east4-docker.pkg.dev +``` +- Login to podman with JSON Key provided by WaveMaker support + +```bash +cat | podman login -u _json_key_base64 --password-stdin us-east4-docker.pkg.dev +``` + +### Create K8s Secrets + +- Using kubectl with docker login create image pull secrets after replacing DIR-PATH-TO-CONFIG-JSON path. By default, the path is $HOME/.docker/config.json + +```bash Command +kubectl create secret generic mb-image-pull-secret --from-file=.dockerconfigjson=[DIR-PATH-TO-CONFIG-JSON]/config.json --type=kubernetes.io/dockerconfigjson -n mockingbird +``` +- Using oc with podman login create image pull secrets after replacing DIR-PATH-TO-AUTH-JSON path. By default, the path is /run/user/$UID/containers/auth.json + +```bash Command +oc create secret generic mb-image-pull-secret --from-file=.dockerconfigjson=[DIR-PATH-TO-AUTH-JSON]/auth.json --type=kubernetes.io/dockerconfigjson -n mockingbird +``` + +- Using kubectl create SSL cert secret with CERT_PRIVATE_KEY_FILE and CERT_FILE replaced with path values. + +```bash +kubectl create secret tls mb-ssl-secret --key ${CERT_PRIVATE_KEY_FILE} --cert ${CERT_FILE} -n mockingbird +``` +- Using oc create SSL cert secret with CERT_PRIVATE_KEY_FILE and CERT_FILE replaced with path values. + +```bash +oc create secret tls mb-ssl-secret --key ${CERT_PRIVATE_KEY_FILE} --cert ${CERT_FILE} -n mockingbird +``` + +### Create One time Setup Values YAML + +- Create values yaml file with this code snippet by replacing these placeholders with proper values [MOCKINGBIRD-DOMAIN] and [MOCKINGBIRD-STATIC-IP] + +one-time-setup-values.yaml + +```yaml +global: + domainName: [MOCKINGBIRD-DOMAIN] +apimock-ingress-nginx: + controller: + service: + loadBalancerIP: [MOCKINGBIRD-STATIC-IP] +``` +- If deploying to openshift cluster then a property 'openshift: "true"' in one-time-setup-values.yaml + +one-time-setup-values.yaml + +```yaml +global: + domainName: [MOCKINGBIRD-DOMAIN] + openshift: "true" +apimock-ingress-nginx: + controller: + service: + loadBalancerIP: [MOCKINGBIRD-STATIC-IP] +``` + +### Install Helm Chart + +- Run helm command to install chart for MockingBird Platform by replacing HELM-PACKAGE and MOCKINGBIRD-DOMAIN + +```bash +helm install mockingbird [HELM-PACKAGE] -n mockingbird -f one-time-setup-values.yaml +``` + +### Map Domain to Static IP Reserved for MockingBird + +- Map Static IP to MockingBird Domain + diff --git a/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/integrate.md b/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/integrate.md new file mode 100644 index 000000000..10d513ae9 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/integrate.md @@ -0,0 +1,57 @@ +--- +title: "Integrate MockingBird with WME" +id: "integrate" +sidebar_label: "Integrate" +--- +--- + +## Integration requirements + +### Integrate Mockingbird with WME Platform + +- Make sure MockingBird domain is accessible to WaveMaker Enterprise (WME) setup. +- Add the **loadBalancerSourceRanges** key in the **one-time-setup-values.yaml** file and replace [WHITELIST-IP-RANGE] property with concern network CIDR ranges + - Example ["1.2.3.4/32", "1.2.3.5/24"] +- Make sure that [MOCKINGBIRD-DOMAIN], [MOCKINGBIRD-STATIC-IP] as replaced with proper values. + +```yaml +global: + domainName: [MOCKINGBIRD-DOMAIN] +apimock-ingress-nginx: + controller: + service: + loadBalancerIP: [MOCKINGBIRD-STATIC-IP] + loadBalancerSourceRanges: [WHITELIST-IP-RANGE] +``` + +```bash +helm upgrade mockingbird [HELM-PATCH-PACKAGE] -n mockingbird -f one-time-setup-values.yaml +``` + +### Pairing up WME Platform and MockingBird Platform + +- Here is the command to run from WME Pltform instance to integrate both the platforms + +```bash +bash /usr/local/content/wme/wme-installer//wme-installer.sh --register_mocking_bird +``` + +![mb](/learn/assets/consul_mb_props.png)](/learn/assets/consul_mb_props.png) + +### Enable Mocking feature from WME Platform Launchpad team portal + +Open WME Launchpad page + +1) Select the "Teams" tab on the right nav and click on the permissions icon for the team that you want to enable APIMock server access as shown in the below screen. + +![[mb](/learn/assets/launchpad_mb_permission.png)](/learn/assets/launchpad_mb_permission.png) + +2) Select the project role for which the API Mock Server feature need to be enabled. + +![[mb](/learn/assets/launchpad_mb_enable.png)](/learn/assets/launchpad_mb_enable.png) + +3) Save the above changes as shown below. + +![[mb](/learn/assets/launchpad_mb_save.png)](/learn/assets/launchpad_mb_save.png) + + diff --git a/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/persistent-volumes.md b/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/persistent-volumes.md new file mode 100644 index 000000000..68a3b6671 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/persistent-volumes.md @@ -0,0 +1,154 @@ +--- +title: "Creating Persisted Volumes" +id: "persistent-volumes" +sidebar_label: "Volume Creation" +--- +--- + +## Storage Disks Creation + +- Create Storage Disks with following names from respective cloud computing with 50GB storage each and type as HDD + + + + + +
+ Storage Disks +
    +
  • k8s-mbe-redis-data
  • +
  • k8s-mbe-swagger-json-data
  • +
  • k8s-mbe-tomcat-logs-data
  • +
+
+ +:::note +Make sure these storage disks are at same region as K8s cluster. +::: + +## StorageClass and PV creation for GKE + +### StorageClass Creation +- Create StorageClass yaml file with this code snippet + +storageclass.yaml + +```yaml +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: mockingbird-sc +parameters: + type: pd-standard +provisioner: kubernetes.io/gce-pd +allowVolumeExpansion: true +reclaimPolicy: Retain +``` + +- Create StorageClass with this command + +```bash +kubectl apply -f storageclass.yaml -n mockingbird +``` + +### PV's and PVC's creation + +- Create servicestorage yaml file + +servicestorage.yaml + +```yaml +apiVersion: v1 +kind: PersistentVolume +metadata: + name: pv-k8s-mbe-redis-data +spec: + storageClassName: "mockingbird-sc" + capacity: + storage: 50Gi + accessModes: + - ReadWriteOnce + claimRef: + namespace: mockingbird + name: pv-claim-k8s-mbe-redis-data + gcePersistentDisk: + pdName: k8s-mbe-redis-data +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: pv-claim-k8s-mbe-redis-data + namespace: mockingbird +spec: + storageClassName: "mockingbird-sc" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 50Gi +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: pv-k8s-mbe-swagger-json-data +spec: + storageClassName: "mockingbird-sc" + capacity: + storage: 50Gi + accessModes: + - ReadWriteOnce + claimRef: + namespace: mockingbird + name: pv-claim-k8s-mbe-swagger-json-data + gcePersistentDisk: + pdName: k8s-mbe-swagger-json-data +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: pv-claim-k8s-mbe-swagger-json-data + namespace: mockingbird +spec: + storageClassName: "mockingbird-sc" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 50Gi +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: pv-k8s-mbe-tomcat-logs-data +spec: + storageClassName: "mockingbird-sc" + capacity: + storage: 50Gi + accessModes: + - ReadWriteOnce + claimRef: + namespace: mockingbird + name: pv-claim-k8s-mbe-tomcat-logs-data + gcePersistentDisk: + pdName: k8s-mbe-tomcat-logs-data +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: pv-claim-k8s-mbe-tomcat-logs-data + namespace: mockingbird +spec: + storageClassName: "mockingbird-sc" + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 50Gi +``` + +- Create PV's and PVC's with this command + +```bash +kubectl apply -f servicestorage.yaml -n mockingbird +``` + diff --git a/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/prerequisites.md b/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/prerequisites.md new file mode 100644 index 000000000..862a1e31d --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/prerequisites.md @@ -0,0 +1,102 @@ +--- +title: "MockingBird Prerequisites" +id: "prerequisites" +sidebar_label: "What you'll need" +--- +--- + +:::note +This document uses words like **VM**, **Nodes**, **Instance** to refer a machine, Cluster to refer a Kubernete Cluster and K8s to Kubernetes. +::: + +You can setup MockingBird on any K8s Cluster, but we verified on Google Kubernetes Engine (GKE). + +## MockingBird Setup Requirements + +### Kubernetes Cluster + +1. K8s Cluster - v1.26 and above + +2. MockingBird platform can be setup at any of the following Kubernetes Clusters, including: + 1. [Google Kubernetes Engine (GKE)](https://cloud.google.com/learn/what-is-kubernetes) + 2. [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/) + 3. [Azure Kubernetes Service (AKS)](https://learn.microsoft.com/en-us/azure/aks/) + +### MockingBird Platform Setup Instance (JumpBox) + +- JumpBox should be configured with Kubernetes Cluster access. +- Secure JumpBox to access your network infra, especially access to only K8s cluster. +- Here is the list of software packages to be installed at the JumpBox where K8s Cluster is accessible + + + + + +
+ Software +
    +
  • Kubectl v1.24.0 or higher
  • +
  • Helm v3.8.0 or higher
  • +
  • Docker 20.x or higher
  • +
  • sha1sum
  • +
  • Basic linux commands like cat
  • +
+
+ +### Persistent Volume creation + +- Make sure the following PVC's are ready before you start the setup + + + + + +
+ Persistent Volume Claims +
    +
  • pv-claim-k8s-mbe-redis-data
  • +
  • pv-claim-k8s-mbe-swagger-json-data
  • +
  • pv-claim-k8s-mbe-tomcat-logs-data
  • +
+
+ +- If you are new to Kubernetes and not ready with above PVC's, refer to this document [Volume Creation](/learn/extensions/mockingbird/enterprise/persistent-volumes). + +### Capacity Planning + +Adding an instance to the K8s workspace aids in the scalability of the mocking services. + +### Deliverables + +WaveMaker team will share the following Google Cloud Platform (GCP) Service-Account file and SHA1SUM file of the MockingBird Helm Package. + +- GCP service account file +- SHA1SUM file of MockingBird Helm Package +- MockingBird Version + +## IP Address and DNS Mapping + +You will be needing IP Address for the following. + +### IP Address + +- One static IP for accessing the MockingBird platform machine from the WaveMaker Platform network. + +### DNS Mapping + +Map a domain to the above IP for easy access. + +| **Domain** | **Domain URL** | **Description** | +| --- | --- | --- | +| MockingBird Platform | `mockingbird.[mycompany].com` | This domain will be used to access MockingBird Platform APIs by WaveMaker Enterprise (WME) after integration | + +:::note +In the preceding table, `[mycompany]` is used as an example. You may have to replace `[mycompany]` with your appropriate domain name. +::: + +### Network Communication + +- Before you start installing MockingBird, make sure WME setup is ready. +- Below diagram explain's the network Integration between the WaveMaker Platform Instance and MockingBird K8s Platform. Make sure MockingBird Platform domain is only accessible to the WME Platform domain. + +[![network-communication-between-instances](/learn/assets/wme-setup/network-communication-between-mbe-wme.jpg)](/learn/assets/wme-setup/network-communication-between-mbe-wme.jpg) diff --git a/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/upgrade.md b/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/upgrade.md new file mode 100644 index 000000000..3eb396ee3 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/extensions/mockingbird/enterprise/upgrade.md @@ -0,0 +1,24 @@ +--- +title: "Upgrade and Rollback" +id: "upgrade" +--- +--- + +## Upgrade and Rollback MockingBird setup + +### Upgrade MockingBird Platform + +- Here is the command to upgrade the Mockingbird extension with a patch release or with a new release. +- Replace [HELM-PATCH-PACKAGE] with the helm package name of a new release or patch release after download. + +```bash +helm upgrade mockingbird [HELM-PATCH-PACKAGE] -n mockingbird -f one-time-setup-values.yaml +``` + +### RoleBack MockingBird setup + +- Here is the command to rollback previously installed patch/upgrade + +```bash +helm rollback mockingbird -n mockingbird +``` diff --git a/website/versioned_docs/version-v11.8.5/how-tos/accessing-file-upload-java-code.md b/website/versioned_docs/version-v11.8.5/how-tos/accessing-file-upload-java-code.md new file mode 100644 index 000000000..78ba6e241 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/accessing-file-upload-java-code.md @@ -0,0 +1,37 @@ +--- +title: "Accessing File Upload from Java Code" +id: "accessing-file-upload-java-code" +--- +--- +File upload service can be accessed via Java code. For example, if you have a fileupload widget in your app, the file can be accessed using the following code: + +``` +public String sampleJavaOperation(MultipartFile singleFile){ + +//for single file upload +singleFile.getInputStream() +} +} + +In case you are using FileUpload to handle multiple files, then the code would be: + +public String sampleJavaOperation(MultipartFile[] multipleFiles){ + +//for multiple files upload +for (MultipartFile file : multipleFiles) { + fileuploaded = multipleFiles.getInputStream(); +} +} +``` + +:::note +You need to import a few class files, as given below. +::: + +``` +import org.springframework.web.multipart.MultipartFile; +import com.wavemaker.runtime.file.model.DownloadResponse; +import javax.servlet.http.HttpServletRequest; +import java.io.File; +``` + diff --git a/website/versioned_docs/version-v11.8.5/how-tos/accessing-loggedin-user-information-using-a-java-service.md b/website/versioned_docs/version-v11.8.5/how-tos/accessing-loggedin-user-information-using-a-java-service.md new file mode 100644 index 000000000..855926152 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/accessing-loggedin-user-information-using-a-java-service.md @@ -0,0 +1,190 @@ +--- +title: "Accessing Logged-in User Details using Java Service" +id: "accessing-loggedin-user-information-using-a-java-service" +--- +--- + +In this document, learn how to get the logged-in user information using a Java Service. You write a handler to get user information. For example, get the username, userID, IP address, and browser details. To do this, follow the steps described below. + +## Step 1: Create a Java Handler in Source + +Write a java handler class by using an existing handler. + +Create a service in the `src/main/java` inside the handlers folder. For example, `UserManagementApp/src/main/java/com/wavemaker/appscore/custom/handlers/CustomAuthenticationSuccessHandler.java` + +[![](/learn/assets/Doc1.png)](/learn/assets/Doc1.png) + +For more information to add files in a project, see [including resource files](/learn/app-development/services/3rd-party-libraries/#including-resource-files). + +## Step 2: Implementing Success Handler + +:::note +Create these classes in an IDE and copy it in the path specified in the above screenshot in the `CustomAuthenticationSuccessHandler.java` file. For more information, see [working with IDE](/learn/app-development/dev-integration/extending-application-using-ides/). +::: + +- Implement `WMAuthenticationSuccessHandler` interface and override the method `onAuthenticationSuccess`. This method invokes on successful login. + +```java +public class CustomAuthenticationSuccessHandler implements WMAuthenticationSuccessHandler { + +@Override + public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, + WMAuthentication wmAuthentication) throws IOException, ServletException + { + } +} +``` + +- Use the following method parameters, including `HttpServletRequest`, `HttpServletResponse`, `WMAuthentication`. It allows accessing the logged-in user information. +- Create a `userMap` to capture user information as shown in the example below. + +:::tip +Follow the commented-sections in the `CustomAuthenticationSuccessHandler.java` file in the following example. +::: + +### Example + +**`CustomAuthenticationSuccessHandler.java`** + +```java +package com.wavemaker.appscore.custom.handlers; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.core.Authentication; +import com.wavemaker.runtime.security.WMAuthentication; +import com.wavemaker.runtime.security.handler.WMAuthenticationSuccessHandler; +import java.util.*; + + +public class CustomAuthenticationSuccessHandler implements WMAuthenticationSuccessHandler { + + private static final Logger logger = LoggerFactory.getLogger(CustomAuthenticationSuccessHandler.class); + + //Created the useMap to capture the userinfo. + public static final Map userMap=new HashMap(); + +@Override + public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, + WMAuthentication wmAuthentication) throws IOException, ServletException { + + //Accessing the ip address and userid and username + + final String userId=wmAuthentication.getUserId(); + final String username=wmAuthentication.getPrincipal(); + final String ip=httpServletRequest.getRemoteAddr(); + + //Process the browser info from the header using 'User-Agent' + final String browserDetails = httpServletRequest.getHeader("User-Agent"); + final String user = browserDetails.toLowerCase(); + + String browser = ""; + + //===============Browser Name Processing=========================== + if (user.contains("msie")) { + String substring = browserDetails.substring(browserDetails.indexOf("MSIE")).split(";")[0]; + browser = substring.split(" ")[0].replace("MSIE", "IE") + "-" + substring.split(" ")[1]; + } else if (user.contains("safari") && user.contains("version")) { + browser = (browserDetails.substring(browserDetails.indexOf("Safari")).split(" ")[0]).split( + "/")[0] + "-" + (browserDetails.substring( + browserDetails.indexOf("Version")).split(" ")[0]).split("/")[1]; + } else if (user.contains("opr") || user.contains("opera")) { + if (user.contains("opera")) + browser = (browserDetails.substring(browserDetails.indexOf("Opera")).split(" ")[0]).split( + "/")[0] + "-" + (browserDetails.substring( + browserDetails.indexOf("Version")).split(" ")[0]).split("/")[1]; + else if (user.contains("opr")) + browser = ((browserDetails.substring(browserDetails.indexOf("OPR")).split(" ")[0]).replace("/", + "-")).replace( + "OPR", "Opera"); + } else if (user.contains("chrome")) { + browser = (browserDetails.substring(browserDetails.indexOf("Chrome")).split(" ")[0]).replace("/", "-"); + } else if ((user.indexOf("mozilla/7.0") > -1) || (user.indexOf("netscape6") != -1) || (user.indexOf( + "mozilla/4.7") != -1) || (user.indexOf("mozilla/4.78") != -1) || (user.indexOf( + "mozilla/4.08") != -1) || (user.indexOf("mozilla/3") != -1)) { + browser = "Netscape-?"; + + } else if (user.contains("firefox")) { + browser = (browserDetails.substring(browserDetails.indexOf("Firefox")).split(" ")[0]).replace("/", "-"); + } else if (user.contains("rv")) { + browser = "IE"; + } else { + browser = "UnKnown, More-Info: " + browserDetails; + } + //Preparing the userMap + userMap.put("IP",ip); + userMap.put("UserId",userId); + userMap.put("Username",username); + userMap.put("Browser",browser); +} +} +``` + +[![](/learn/assets/Doc3.png)](/learn/assets/Doc3.png) + +## Step 3: Declaring Handler as Bean + +In **`project-user-spring.xml`**, add the bean to declare the user-defined handler. + +```xml + restService(String origin, String destination) { + ArrayList directionList = new ArrayList(); + try { + URL url = new URL("http://maps.googleapis.com/maps/api/directions/xml?origin="+origin+"&destination="+destination+"&sensor=false"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + if (conn.getResponseCode() != 200) { + throw new RuntimeException("Failed : HTTP error code : "+ conn.getResponseCode()); + } + BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream()))); + String output; + while ((output = br.readLine()) != null) {while ((output = br.readLine()) != null) { + if(output.contains("")) + { + output = output.substring(output.indexOf(">")+1, output.indexOf("")); + directionList.add(output); + } + }} conn.disconnect();} + catch (MalformedURLException e) { + e.printStackTrace();} + catch (IOException e) { + e.printStackTrace();} + return directionList; + } +``` + + + +## See Also + +[How to send emails using Java Service](/learn/how-tos/sending-email-using-java-service/) +[How to implement forgot password feature using Java Service](/learn/how-tos/implementing-forgot-password-feature-using-java-service/) +[How to schedule a Java Service](/learn/how-tos/scheduling-java-service/) +[How to accomplish Pre-Post Processing for a DB Service APIs](/learn/how-tos/pre-post-processing-db-service-apis/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/active-directory-use-cases.md b/website/versioned_docs/version-v11.8.5/how-tos/active-directory-use-cases.md new file mode 100644 index 000000000..5a03c40f9 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/active-directory-use-cases.md @@ -0,0 +1,41 @@ +--- +title: "Active Directory - Use Cases" +id: "active-directory-use-cases" +--- + +**Active Directory** Domain Services is Microsoft’s Directory Server. It provides authentication and authorization mechanisms as well as a framework within which other related services can be deployed (AD Certificate Services, AD Federated Services, etc). It is an LDAP compliant database that contains objects. + +In WaveMaker, you can set [AD as security service provider](/learn/app-development/app-security/authentication/#ad) and configure the details. There are few scenarios which need special configurations: + +1. [using alternate UPN suffix](#multipleUPN), +2. [using sAMAccountName](#sAMAccountName), +3. [allowing certain domain name suffix](#domainname). + +**Scenario 1**: Support for **alternate UPN suffix** in an AD domain. + +In the Windows operating system's Active Directory, a [User Principal Name](https://msdn.microsoft.com/en-us/library/ms677605(v=vs.85).aspx) (UPN) is the name of a system user in an e-mail address format. The user name (or "username") is followed by the "at sign (@)" and the name of the Internet domain with which the user is associated. In cases where there are multiple child domains within a parent domain, the parent domain name gets suffixed to the child domain, thus making the UPN suffix too lengthy and difficult to handle. To get over this situation, alternate UPN suffix is created and the user uses this to login. + +When configuring for these situations, you need to: + +1. leave **Domain** entry _blank,_ +2. enter the **Root DN** following the placeholder convention "_dc=example,dc=com_", +3. enter **Test Username** in the suffix email style i.e. _along with the @domain.com_ + +[![](/learn/assets/AD_case1-1.png)](/learn/assets/AD_case1-1.png)**Scenario 2**: Support for user search using sAMAccountName. + +The [sAMAccountName](https://msdn.microsoft.com/en-us/library/ms677605(v=vs.85).aspx#sAMAccountName) attribute is the User Logon Name used to support clients and servers from the previous version of Windows, such as Windows NT 4.0, Windows 95, Windows 98, and LAN Manager. Both userPrincipalName and sAMAccountName can be used to login to AD. + +By default, WaveMaker sets the Active Directory user search to be based upon the userPrincipalName. In order to set the search based upon the sAMAccountName you need to: + +1. leave **Domain** entry _blank,_ +2. enter the **User Search Pattern** as: `(&(objectClass=user)(sAMAccountName={0}))` + +[![](/learn/assets/AD_case2-1.png)](/learn/assets/AD_case2-1.png)**Scenario 3**: Support for users with certain domain name suffix + +In order to allow access to users of a particular domain you need to: + +- enter the **User Search Pattern** as `(&(objectClass=user)(userPrincipalName={0}@yourdomain.com))` ([more about search filter](https://msdn.microsoft.com/en-us/library/aa746475(v=vs.85).aspx)) + +You can allow multiple domains by appending to the User Search Pattern: `(&(objectClass=user)(|(userPrincipalName={0}@yourdomain.com)(userPrincipalName={0}@anotherdomain.com)))` + +[![](/learn/assets/AD_case3-1.png)](/learn/assets/AD_case3-1.png) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/add-custom-filters.md b/website/versioned_docs/version-v11.8.5/how-tos/add-custom-filters.md new file mode 100644 index 000000000..670f4b418 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/add-custom-filters.md @@ -0,0 +1,150 @@ +--- +title : "Adding Custom Filters in WaveMaker app" +id : "add-custom-filters" +--- + + +In Spring Security, a filter is a fundamental component that plays a crucial role in controlling and securing access to resources within a Spring-based web application. Filters in Spring Security are responsible for performing various security-related tasks, such as authentication, authorization, and request processing, before or after a request reaches the application's endpoints. + + +### Need of Custom Filters +In every security enabled application, you can find **FilterChain**.By default FilterChain consists of spring's pre-defined filters which performs authentication and authorization. But if you want to add custom pre or post processing tasks on request or response you need to add custom filters in FilterChain. + +:::note +**FilterChain**: It refers to a series or sequence of filters that are applied to incoming requests before they reach the intended servlet or resource. Each filter in the filter chain performs specific pre-processing or post-processing tasks on the request or response, such as authentication, authorization, logging, data transformation, or error handling. +::: + +### Create Custom Filter + +1. Create a custom java class that extends Filter. After creating save the file. + +```java +package com.filters; + +import javax.servlet.*; +import java.io.IOException; + +public class CustomFilter implements Filter { + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + //Write custom filter logic according to your requirements + chain.doFilter(request, response); + } + + @Override + public void destroy() { + + } +} +``` + +2. Navigate to the File Explorer and upload the class into src/main/java into the required package. After uploading the class click cancel to apply the changes. + +[![CustomFilter_class_upload](/learn/assets/CustomFilterclass_upload.jpg)](/learn/assets/CustomFilterclass_upload.jpg) + +3. Define the above created CustomFilter class bean in **project-user-spring.xml** file. + +```java + +``` + +[![CustomFilter_bean_defination](/learn/assets/CustomFilter_bean_defination.jpg)](/learn/assets/CustomFilter_bean_defination.jpg) + +By following above steps you can create a bean of custom filter, but to add custom filter in FilterChain follow the below steps. + +### Add Custom Filter to the application Security Filters +In **general-options.json** file, `customFilterList` attribute is used to add custom filters.This attribute accepts list of objects. + + +In the `customFilterList` attribute, you can use any name for a custom filter in the `name` field. The `ref` field accepts the bean id of the CustomFilter bean defined in **project-user-spring.xml** file. Third field in `customFilterList` attribute defines where to add custom filter in FilterChain and the field can be any one of these `position`, `after`, and `before`. This third field takes the filter enum value which represents the pre-defined spring filter. + +#### Using position field in customFilterList + +1. When a `position` attribute is used, custom filter will be added at the position of pre-defined spring filter which is mentioned in value of `position` field. + +```java +"customFilterList" : [ + { + "name" : "customFilter", + "ref" : "customFilter", + "position" : "" + } + ], +``` + +[![CustomFilter_adding_using_position](/learn/assets/Custom_filter_adding_using_position.jpg)](/learn/assets/Custom_filter_adding_using_position.jpg) + +#### Using before field in customFilterList + +1. When a `before` attribute is used, custom filter will be added before the position of pre-defined spring filter which is mentioned in value of `before` field. +```java +"customFilterList" : [ + { + "name" : "customFilter", + "ref" : "customFilter", + "before" : "" + } + ], +``` + +[![CustomFilter_adding_using_position](/learn/assets/Custom_filter_adding_using_before.jpg)](/learn/assets/Custom_filter_adding_using_before.jpg) + +#### Using after field in customFilterList + +1. When a `after` attribute is used, custom filter will be added after the position of pre-defined spring filter which is mentioned in value of `after` field. +```java +"customFilterList" : [ + { + "name" : "customFilter", + "ref" : "customFilter", + "after" : "" + } + ], +``` + +[![CustomFilter_adding_using_position](/learn/assets/Custom_filter_adding_using_after.jpg)](/learn/assets/Custom_filter_adding_using_after.jpg) + +
+ +:::note +The below enum values can be given as input for `position`, `after`, and `before` fields in the `customFilterList` attribute: + + +| Filter enum value |Filter CLass | +| ----- | ------ | +|FIRST|SessionRepositoryFilter| +|CHANNEL_FILTER|ChannelProcessingFilter| +|SECURITY_CONTEXT_FILTER|SecurityContextPersistenceFilter| +|CONCURRENT_SESSION_FILTER|ConcurrentSessionFilter| +|WEB_ASYNC_MANAGER_FILTER|WebAsyncManagerIntegrationFilter| +|HEADERS_FILTER|HeaderWriterFilter| +|CORS_FILTER|CorsFilter| +|CSRF_FILTER|CsrfFilter| +|LOGOUT_FILTER|LogoutFilter| +|X509_FILTER|X509AuthenticationFilter| +|PRE_AUTH_FILTER|AbstractPreAuthenticatedProcessingFilter| +|CAS_FILTER|CasAuthenticationFilter| +|FORM_LOGIN_FILTER|UsernamePasswordAuthenticationFilter| +|OPENID_FILTER|OAuth2LoginAuthenticationFilter| +|LOGIN_PAGE_FILTER|DefaultLoginPageGeneratingFilter| +|DIGEST_AUTH_FILTER|DigestAuthenticationFilter| +|BASIC_AUTH_FILTER|BasicAuthenticationFilter| +|REQUEST_CACHE_FILTER|RequestCacheAwareFilter| +|SERVLET_API_SUPPORT_FILTER|SecurityContextHolderAwareRequestFilter| +|JAAS_API_SUPPORT_FILTER|JaasApiIntegrationFilter| +|REMEMBER_ME_FILTER|RememberMeAuthenticationFilter| +|ANONYMOUS_FILTER|AnonymousAuthenticationFilter| +|SESSION_MANAGEMENT_FILTER|SessionManagementFilter| +|EXCEPTION_TRANSLATION_FILTER|ExceptionTranslationFilter| +|FILTER_SECURITY_INTERCEPTOR|FilterSecurityInterceptor| +|SWITCH_USER_FILTER|SwitchUserFilter| +|LAST|SwitchUserFilter| + +::: + +On adding your custom filter in the `customFilterList` attribute in **general-options.json**, WaveMaker internally adds this filter in your application FilterChain. \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/how-tos/add-master-detail-records-using-data-table.md b/website/versioned_docs/version-v11.8.5/how-tos/add-master-detail-records-using-data-table.md new file mode 100644 index 000000000..4ec0f0491 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/add-master-detail-records-using-data-table.md @@ -0,0 +1,25 @@ +--- +title: "Add Master-Detail records using Data Table" +id: "add-master-detail-records-using-data-table" +--- + +**Scenario**: To implement CRUD operations on an Master-Detail database schema. We will be adding records in a  Master-Detail scenario using Data Table bound to Live Variable. + +1. For a Customer you will be able create Order rows. +2. For an Order you will be able to create Order Detail rows. +3. You will also be able to edit and delete operations too. + + + +[Data Table Use Cases](/learn/app-development/widgets/datalive/datatable/data-table-use-cases/) + +- [1. Basic Table Usage](/learn/app-development/widgets/datalive/datatable/data-table-basic-usage/) +- [2. How to customise table actions](/learn/how-tos/data-table-actions/) +- [3. How to represent data table columns using widgets](/learn/how-tos/data-table-widget-representations/) +- [4. How to format data table column](/learn/how-tos/data-table-format-options/) +- [5. How to apply styles (generic and conditional) to data table](/learn/how-tos/data-table-styling/) +- [6. How to view master-detail record using a data table](/learn/how-tos/view-master-detail-data-records-using-data-table/) +- [7. How to add master-detail record using a data table](/learn/how-tos/add-master-detail-records-using-data-table/) +- [8. How to export data using a data table](/learn/how-tos/export-data-data-table/) +- [9. How to create a dynamic data table](/learn/how-tos/dynamic-data-tables/) +- [10. How to bind column of a data table to query variable](/learn/how-tos/data-table-column-bound-query/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/adding-custom-fonts-richtext-editor.md b/website/versioned_docs/version-v11.8.5/how-tos/adding-custom-fonts-richtext-editor.md new file mode 100644 index 000000000..474227943 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/adding-custom-fonts-richtext-editor.md @@ -0,0 +1,39 @@ +--- +title: "Adding Custom Fonts to Richtext Editor" +id: "adding-custom-fonts-richtext-editor" +--- +--- + +In this document, learn how to add custom fonts to the Richtext Editor. + +## Adding Custom Fonts + +To add custom fonts to the Richtext Editor, modify the **defaultOptions** property of the widget and add desired font names to the list. For that, you must add the function inside the **onBeforeRender()** event before the widgets are loaded. + +### Steps + +Follow the steps below to achieve this. + +1. Add the below snippet inside the **onBeforeRender()** event of the Richtext Editor widget. + + - The snippet adds `Inter` font to the `fontNames` array. + +```javascript +Page.Beforerender = function($event, widget) { + var defaultOptions = widget.getDefaultOptions(); + defaultOptions.fontNames.push("Inter"); + defaultOptions.fontNamesIgnoreCheck = ["Inter"]; // ignore checks for the font +}; +``` + +:::note +We have included the `fontNamesIgnoreCheck` array to ignore checks for the font, as it may take longer to load. +::: + +2. Import the font CSS in the project. Here, we are importing the stylesheet in `index.html`. + +```html + +``` + +![/learn/assets/RichtextEditor/RTE-custom-font.png](/learn/assets/RichtextEditor/RTE-custom-font.png) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/how-tos/adding-master-detail-records-transaction.md b/website/versioned_docs/version-v11.8.5/how-tos/adding-master-detail-records-transaction.md new file mode 100644 index 000000000..0543cc569 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/adding-master-detail-records-transaction.md @@ -0,0 +1,13 @@ +--- +title: "Adding Master-Detail records in the same transaction" +id: "adding-master-detail-records-transaction" +--- + +In this use case, you will be: + +1. adding parent/child or master/detail records in the same transaction +2. using Database CRUD and a Model Variable +3. using a Data Table within a Live Form. + + + diff --git a/website/versioned_docs/version-v11.8.5/how-tos/adding-parent-child-records-single-transaction.md b/website/versioned_docs/version-v11.8.5/how-tos/adding-parent-child-records-single-transaction.md new file mode 100644 index 000000000..0d199d864 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/adding-parent-child-records-single-transaction.md @@ -0,0 +1,87 @@ +--- +title: "Submit Parent and Child Records in a Single Transaction" +id: "adding-parent-child-records-single-transaction" +--- +--- + +This topic describes how to add Parent and Child records in a single transaction, where a Parent is the master record, and the Child is the extension or the details of the master record using repeatable Forms. + +**Example:** +Assume that a Pizza is a Parent entity, the Types of Pizzas are the Child entity type.  When you enter the Parent record, you want to add the Child records at the same time, too. To do this, follow the step-by-step instructions as below. Also, achieve this topic's agenda of: + +- Adding Parent/Child or master-detail's records in a single action. +- Using database CURD and a Model variable. +- Using a List inside a Form. + +## Database Configuration + +Navigate to the Databases section and create your own database. For more information, see [Working with Databases](/learn/app-development/services/database-services/working-with-databases/). + +- Step-1: In the database designer, add a one-to-many relation for the Parent and Child tables. +- Step-2: Enable the **Cascade Option** for the one-to-many relation as shown in the image below. For more information, see [Working with Database Schema](/learn/app-development/services/database-services/working-database-schema/). + +[![](/learn/assets/form/db-cascade.png)](/learn/assets/form/db-cascade.png) + +## Page Design + +### Configure Parent LiveForm + +- Step-3: On a page, drag and drop a **Live Form** and bind it to the Parent entity (Employee Entity in the database). The Employee Live Form is the Parent Form. + +### Model Variable Settings + +- Step-4: Create a model variable with **Entry** type and set the flag to the **isList** option and also the metadata same as the Child entity(Address Entity present in the database) as shown in the image below. + +[![](/learn/assets/form/model-variable.png)](/learn/assets/form/model-variable.png) + +### Configure List inside Parent LiveForm + +- Step-5: Drag and drop a **List Widget** inside the Parent Form (Employee LiveForm) and bind it to the model variable created in Step4. + +### Configure Form inside List Widget + +- Step-6: Drag and drop a **Form** widget inside the List template and bind it to the same model variable created in Step4 and configure the Form. + +- Step-7: Now click the **Advanced Settings** option present under the Properties panel for the inner Form (Child Form/Address Form) from the dialog uncheck the actions(as we wanted to submit the Child objects during Parent record submission). + +### Add Child Objects on Button Click + +- Step-8: Drag and drop a **Button** widget on the Parent form (created in step-3) and change the button caption as "Add Child Items". + +- Step-9: Go to the **Events** tab of the **Add Child Items** button, and set the **On Click** event as javascript, and write as script to add one more Child Form or AddressDetails Form as shown below. + +```js +Page.button1Click = function($event, widget) { + Page.Variables.StVarAddressDetail.dataSet.push({}); +}; +``` + +The above code adds one more Child object(address object) into the model variable (created in Step4). + +### Rename List Widget + +- Step-10: Now search for the `${ParentEntityName}.java` file under **FileExplorer** and check the Child entity reference name (variable name) and update the List widget name which dropped inside the Parent LiveForm with the Child reference variableName. + +[![](/learn/assets/form/Employeepojo.png)](/learn/assets/form/Employeepojo.png) + +:::note +Ensure that the List widget naming convention is same as the related Child entity mentioned in its Parent entity. To verify the name, see .java file of the Parent entity from the File Explorer. +::: + +The page tree structure should be as below. + - Parent LiveForm (bound to Employee Entity) + - List Widget (bound to model variable) + - Form Widget(bound to model Variable) + - Button (to add Child objects) + +### App in Preview + +Preview the App. You will see Employee LiveForm fields along with the button as shown below. + +[![preview](/learn/assets/form/Preview1.png)](/learn/assets/form/Preview1.png) + +Click the Add Address Details button; the List items and the Form will be added here. If you want to add another address details, click the button to add the same List using Form. Likewise, you can add any number of address details (List with Forms). + +The final object structure will be as shown in the image below along with the employee details, i.e., two address object details, including, one residential and permanent addresses. + +[![object structure](/learn/assets/form/objectstructure.png)](/learn/assets/form/objectstructure.png) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/how-tos/adding-parent-child-using-form-datatable.md b/website/versioned_docs/version-v11.8.5/how-tos/adding-parent-child-using-form-datatable.md new file mode 100644 index 000000000..30ce63c52 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/adding-parent-child-using-form-datatable.md @@ -0,0 +1,65 @@ +--- +title: "Submit Parent and Child Records in a Single Transaction using Form and Data Table" +id: "adding-parent-child-using-form-datatable" +--- +--- + +This topic describes how to add Parent and Child records in a single transaction, where a Parent is the master record, and the Child is the extension or the details of the master record using form and Data Table. + +**Example:** +Assume that a Pizza is a Parent entity, the Types of Pizzas are the Child entity type.  When you enter the Parent record, you want to add the child records at the same time, too. To do this, follow the step-by-step instructions as below. Also, achieve this topic's agenda of: + +- Adding parent/child or master-detail's records in a single action. +- Using database CURD and a Model variable. +- Using a Data Table inside a Form. + +## Database Configuration + +Navigate to the Databases section and create your own database. For more information, see [Working with Databases](/learn/app-development/services/database-services/working-with-databases/). + +- Step-1: In the database designer, add a one-to-many relation for the parent and child tables. +- Step-2: Enable the **Cascade Option** for the one-to-many relation as shown in the image below. For more information, see [Working with Database Schema](/learn/app-development/services/database-services/working-database-schema/). + +[![DB cascade](/learn/assets/form/db-cascade.png)](/learn/assets/form/db-cascade.png) + +## Page Design + +### Configure Parent LiveForm + +- Step-3: On a page, drag and drop a **Live Form** and bind it to the Parent entity(Employee Entity in the database). The Employee Live Form is the Parent form. + +### Model Variable Settings + +- Step-4: Create a model variable with **Entry** type and set the flag to the **isList** option and also the metadata same as the child entity(Address Entity present in the database) as shown in the image below. + +[![model variable](/learn/assets/form/model-variable.png)](/learn/assets/form/model-variable.png) + +### Configure Datatable inside Parent LiveForm + +- Step-5: Drag and drop a **Data Table** widget inside the Parent LiveForm(Employee LiveForm) and bind it to the model variable created in Step4. + +- Step-6: Now click the **Advanced Settings** option present under the Properties panel of the Data Table and from the dialog enable all the actions to insert address details for parent record submission. + +### Rename Datatable Widget + +- Step-7: Now search for the `${ParentEntityName}.java` file under **FileExplorer** and check the child entity reference name(variable name) and update the datatable widget name which dropped inside the parent LiveForm with the child reference variableName. + +[![](/learn/assets/form/Employeepojo.png)](/learn/assets/form/Employeepojo.png) + +:::note +Ensure that the Data Table widget naming convention is same as the related Child entity mentioned in its Parent entity. To verify the name, see .java file of the parent entity from the File Explorer. +::: + +### App in Preview + +Preview the App. You will see the Employee LiveForm fields along with Data Table as shown below. + +[![Form Data Table](/learn/assets/form/form-datatable.png)](/learn/assets/form/form-datatable.png) + +Click the New button and add the Address Details. Likewise, you can add any number of address details using Data Table. + +[![Form table data](/learn/assets/form/form-table-data.png)](/learn/assets/form/form-table-data.png) + +The final object structure will be as shown in the image below along with the employee details, i.e., two address object details, including, one residential and permanent addresses. + +[![Form table object](/learn/assets/form/form-table-object.png)](/learn/assets/form/form-table-object.png) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/how-tos/adding-ui-for-api-server-side-pagination.md b/website/versioned_docs/version-v11.8.5/how-tos/adding-ui-for-api-server-side-pagination.md new file mode 100644 index 000000000..d59e822a3 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/adding-ui-for-api-server-side-pagination.md @@ -0,0 +1,190 @@ +--- +title: "Adding UI Pagination for API Server-side Pagination" +id: "adding-ui-for-api-server-side-pagination" +sidebar_label: "UI for API Server-side Pagination" +--- +--- + +Pagination is a way to represent data in sets of pages. Server-side pagination controls how these sets are retrieved from the API. It is useful when your application wants to display records with a specific order or filter criteria the API sets out. For example, an Instagram feed with a Cursor pagination; it retrieves a set of five latest posts based on a timestamp as you scroll. + +In WaveMaker, add UI pagination for representing APIs supporting Server-side pagination using a bit of JavaScript API exposed on the widgets such as List, Table, and more. + +## Types of Pagination + +Types of Server-side pagination WaveMaker supports: + +- Offset +- Page +- Cursor + +### Widgets and Services Support + +- **Supported Widgets**: Data widgets, including Data Table, List, Cards +- **Supported Services**: Web Services and Imported APIs + +## Configuring Pagination Parameters + +Configure pagination parameters for imported API using the setPagination method. It renders Widget's data, ensuring the UI is paging through data and making the API calls with appropriate input parameters. + +### Set Pagination + +The **setPagination** method is exposed on all service variables to support Server-side pagination. + +You can set the pagination on a variable: + +1. **Page.onReady** at the Page level +2. **App.onAppVariablesReady** at app.js functions + + +## Offset + +This method uses **offset** and **limit** query parameters, most suitable for using explicit or fixed data that you toggle through. + +### Configuring Offset + +The following code snippet describes how to configure Offset pagination. + +- Create a [Service Variable](/learn/app-development/variables/web-service#how-to-create-a-service-variable). +- Drag-n-drop a data widget, for example, Data table. +- Bind the Data Table to Service Variable. +- Go to the Script tab, and configure Offset pagination as described below. + +```js +Page.onReady = function() { +Page.Variables.serviceVariable2.setPagination({ + type: ‘offset’, + input: { + offset: '$offset', + size: '$limit' + }, + output: { + size: '$body."_meta"."$limit"', + totalElements: '$body."_meta".itemCount', + hasMoreItems: '$body."_meta".hasMoreItems' + } +} +) +} +``` + +### Example + +```html +API: https://sampleapi.com?$offset=0&$limit=5 +``` + +``` +Sample Response: +{ + data: [...{}], +_meta: { + $limit: 5, + $offset: 5, + itemCount: 30, +hasMoreItems: true +} +} +``` + +## Page + +Page divides set into pages. The API accepts a page parameter of an integer type, indicating specific data the page needs to return. In this pagination, you can jump to any page, retrieve data on that particular page, and make parallel requests. + +### Configuring Page + +The following code snippet describes how to configure Cursor pagination. + +- Create a [Service Variable](/learn/app-development/variables/web-service#how-to-create-a-service-variable). +- Drag-n-drop a data widget, for example, Data table. +- Bind the Data Table to Service Variable. +- Go to the Script tab, and configure Cursor pagination as described below. + +```js +{ + type: ‘page’, + input: { + page: 'page', + size: ‘size’ + }, + output: { + totalElements: '$body.totalPassengers' + } +} +``` + +### Example + +API: https://sampleapi.com?size=10&page=1 + +```js +Sample Response: +{ + data: [...{}], +totalPassengers: 73760, +totalPages: 7376 +} +``` + +## Cursor Pagination + +Cursor works by returning a pointer to a specific item in the set of data. On subsequent requests, the API returns results after the given pointer. + +### Configuring Cursor + +The following the code snippet describes how to configure the Cursor pagination. + +- Create a [Service Variable](/learn/app-development/variables/web-service#how-to-create-a-service-variable). +- Drag-n-drop a data widget; for example, Data table. +- Bind the Data Table to Service Variable. +- Go to Script tab, configure Cursor pagination as described below. + +```js +{ + type: ‘cursor’, + input: { + page: 'page' + }, + output: { + next: '$header.x-links-next', + prev: '$header.x-links-previous' + } +} +``` + +### Example + +API: https://sampleapi.com/v2/users?page=1 + +```js +Sample Response: [.....{}] +Sample Response Headers: + +x-links-current: https://gorest.co.in/public/v2/users?page=2 +x-links-next: https://gorest.co.in/public/v2/users?page=3 +x-links-previous: https://gorest.co.in/public/v2/users?page=1 +x-pagination-limit: 20 +x-pagination-page: 1 +x-pagination-pages: 138 +x-pagination-total: 2751 +``` + +## JMES Library + +:::note +When providing values for keys to the input and output parameters, you must follow JMES guidelines. +::: + +JMESPath allows you to specify how to extract elements from a JSON document declaratively. It is a query language for JSON. Define paths using JMES as below. Using the “jmespath” library to evaluate JMES expressions. For more information, see on [more about JMES](https://jmespath.org/) + +### Example + +Pagination controls can be sent both as the body of an HTTP Request or an HTTP Header. The following example shows how to send these in an HTTP header. + +**Response headers**: + +``` +{ "status":{"message":[{"message_TYPE":"SU","messageDesc":"SUCCESS","messageCode":"0000"}]}, +"X-WM-pagination":{"totalRecordCount":"75","nextStartIndex":"11","hasMoreRecords":"Y","numRecReturned":"2"}} +``` + +**hasMoreItems**: '$header."X-WM-pagination".hasMoreRecords == Y' diff --git a/website/versioned_docs/version-v11.8.5/how-tos/adjust-leftnav-width.md b/website/versioned_docs/version-v11.8.5/how-tos/adjust-leftnav-width.md new file mode 100644 index 000000000..5f0f24eef --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/adjust-leftnav-width.md @@ -0,0 +1,29 @@ +--- +title: "Adjust Left Navigation Width" +id: "adjust-leftnav-width" +--- +--- + +Learn how to adjust the leftnav width and main content width in WaveMaker Studio. To do this, follow the steps described below. + +## Adjusting Left Nav Width + +You can adjust the leftnav width by using the `Column Width` property. + +1. Select the left navigation bar. +2. Go to the **Properties** panel and find the `Column Width` property under the **Format** options. +3. Set a value for the `Column Width` property from the dropdown as shown in the screenshot below. + +![leftnav](/learn/assets/leftnav_width.png) + +## AdjustIng Main Content Width + +Similarly, you can adjust the main content width by using the `Column Width` property. + +1. Select the main content of the page. +2. Go to the **Properties** panel and find the `Column Width` property under the **Format** options. +3. Set a value for the `Column Width` property from the dropdown to sum-up with the width of the left navigation bar. For example, if you set the leftnav width to 1, then the main content width should be 9. + +![maincontent](/learn/assets/maincontent_width.png) + + diff --git a/website/versioned_docs/version-v11.8.5/how-tos/app-migration-wavemaker-9x-10x.md b/website/versioned_docs/version-v11.8.5/how-tos/app-migration-wavemaker-9x-10x.md new file mode 100644 index 000000000..472ddd339 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/app-migration-wavemaker-9x-10x.md @@ -0,0 +1,86 @@ +--- +title: "App Migration from WaveMaker 9x to 10x" +id: "app-migration-wavemaker-9x-10x" +--- +--- +Upgrade of the WaveMaker MVC Framework from Angular 1.6 to Angular 7 results in changes to the way the app code is generated. The platform automatically migrates your existing app (built in WaveMaker 9x version) to WaveMaker 10 to generate the Angular 7 code base. + +This document is to briefly outline the changes that will happen to your apps. You need not manually make any changes to your existing apps. + +## Execution Context + +Apps in WaveMaker 10 have two independent contexts instead of the scope inheritance model of WaveMaker 9x: + +- App +- Page/Partial/Prefab + +Earlier the execution context followed a hierarchy `$rootScope` -> `$scope` -> widgets like Dialog, Grid, Form etc. + +To refer to the parent context `$parent` and `$scope.$root` for app level was used, which is no longer needed. + +Now, these can be referred independently in the App or Page/Partial/Prefab context. + +[![](/learn/assets/migration.png)](/learn/assets/migration.png) + +## Widget Access + +Widgets can now be accessed directly using the context as mentioned above. + +For example, to refer to a Button in a Page: + +
WaveMaker 9xWaveMaker 10x
$scope.Widgets.button_namePage.Widgets.button_name
+ +## Variable Access + +Similar to Widgets, Variables too can now be accessed directly using the context. App level Variables can be accessed from within Pages using App context. + +For example, to refer to a Variable in a Page: + +
WaveMaker 9xWaveMaker 10x
$scope.Variables.variable_namePage.Variables.variable_name
+ +Similarly, to refer to an App Variable from a Page: + +
WaveMaker 9xWaveMaker 10x
$scope.$root.Variables.variable_nameApp.Variables.variable_name
+ +## Dependency Injection + +Earlier in order to use certain WaveMaker services, we needed to inject the dependencies in app controller: +``` +App.controller(‘pageController’, [“$http”,”DialogService”,...,function($http, DialogService, ...){}]) +``` +Now the dependency injection can be done as shown below: + +``` +var $http = App.getDependency(‘HttpService’); +var wmToaster = App.getDependency(‘ToasterService’); +var i18nService = App.getDependency(‘i18nService’); +var DialogService = App.getDependency(‘DialogService’); +var wmSpinner = App.getDependency(‘SpinnerService’); +``` +## File Upload Widget Changes + +When a user drags and drops the File Upload widget a Service Variable owned by page will be created with the service as File Java Service and the operation as upload file. This variable will have a file field in data tab which would be bound to the file select widget by default. Additionally, it will be containing various other input parameters based on the type of service of the variable. The upload will be triggered by the Service Variable created and by default the on-select event of the File widget will be bound to this Service Variable. + +In run mode, as the user selects the file, the Service Variable kicks in and the upload action is triggered. Delinking the Service Variable from the on select event will convert the widget to a File Select widget. In this mode, the File widget will only act as a file selector with no additional modes. There will be no service or operation selection on the widget and hence it will not trigger the upload action internally. Refer to the document for the updated functionality, [doc link](/learn/app-development/widgets/form-widgets/file-upload/). + +In earlier versions the File Upload Widget mode selection was made at the widget level, leading to confusion. The existing functionality will continue to work with migration taking care of the transition. + +## Utility Functions + +All the utility functions, like _angular.uppercase_, _angular.isDefined_, etc., will be migrated to the corresponding Lodash functions. When using in newly created projects, you need to use the Lodash utilities, [refer here to know about Lodash methods](https://lodash.com/docs/). + +## Inter-context Communication + +The following changes are made to the communication between contexts: + +|Earlier | Replaced with | +|---|---| +|`$rootScope.$emit` | `App.notify`| +| `$rootScope.$broadcast` | `App.notify`| +| `$rootScope.$on` | `App.subscribe` | + +## Deprecation + +Any Angular 1.6 specific methods, like _directive_,  _module_, _controller_ etc., in your existing projects will no longer work. These will not be migrated and you need to make the appropriate conversion to Angular 7x, manually. + +Any Prefabs using Angular modules will not be migrated. The changes need to be done manually. diff --git a/website/versioned_docs/version-v11.8.5/how-tos/audit-history-using-crud-listeners.md b/website/versioned_docs/version-v11.8.5/how-tos/audit-history-using-crud-listeners.md new file mode 100644 index 000000000..9c7d77f44 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/audit-history-using-crud-listeners.md @@ -0,0 +1,112 @@ +--- +title: "Record Transactional History of an Entity" +id: "audit-history-using-crud-listeners" +sidebar_label: "Transactional History of Entity" +--- +--- + +In this document, learn how you can use [Database CRUD Listeners](/learn/app-development/services/database-crud-event-listeners) to record the history, including the details related to data change of a specific entity/table in a logger table. + +In the following example, we use three Event Listeners, including: + +1. [EntityPostCreateEvent](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/data/event/EntityPostCreateEvent.java) +2. [EntityPostUpdateEvent](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/data/event/EntityPostUpdateEvent.java) +3. [EntityPostDeleteEvent](https://github.com/wavemaker/wavemaker-app-runtime-services/blob/master/wavemaker-app-runtime-core/src/main/java/com/wavemaker/runtime/data/event/EntityPostDeleteEvent.java) + +## Download and Import Database File + +1. Download the [EmployeeDB](/learn/assets/Audithistory-using-crudListeners/EmployeeDB_dump.sql) SQL file. +2. Import the file in [DB Tools](/learn/app-development/services/database-tools#db-scripts). +3. Connect to the Database from your application. + +## Create a Java Service to Insert Transactional Details + +In this use case, we use the `EMPLOYEE_DETAILS_LOG` table to insert transactional details of the `EMPLOYEE` table. + +1. Create a Java service in the project. +2. Add the below import statements. + +```java +import org.springframework.beans.factory.annotation.Autowired; +import com.wavemaker.runtime.security.SecurityService; +import com.wavemaker.runtime.data.event.EntityPostCreateEvent; +import com.wavemaker.runtime.data.event.EntityPostUpdateEvent; +import com.wavemaker.runtime.data.event.EntityPostDeleteEvent; +import org.springframework.context.event.EventListener; +import com..employeedb.EmployeeDetailsLog; +import com..employeedb.service.EmployeeDetailsLogService; +import java.time.*; +import com..employeedb.Employee; +import com.wavemaker.runtime.data.exception.EntityNotFoundException; +``` + +### Add Methods to the Java Service + +Add the following three methods into the Java service that perform the below operations: + +1. Get the logged-in user details from the security service, +2. Get employee details from the event, and +3. Insert employee details into the `EMPLOYEE_DETAILS_LOG` table. + +```java +@EventListener +public void PostEntityCreate(EntityPostCreateEvent entityPostCreateEvent) { + String userName = securityService.getLoggedInUser().getUserName(); + LocalDateTime localDateTime = LocalDateTime.now(); + Integer entityId = entityPostCreateEvent.getEntity().getEmpId(); + EmployeeDetailsLog employeeDetailsLog = new EmployeeDetailsLog(); + employeeDetailsLog.setUserName(userName); + employeeDetailsLog.setDatetime(localDateTime); + employeeDetailsLog.setOperationType("Create"); + employeeDetailsLog.setEmpId(entityId); + employeeDetailsLogService.create(employeeDetailsLog); +} + + +@EventListener +public void PostEntityUpdate(EntityPostUpdateEvent entityPostUpdateEvent) { + String userName = securityService.getLoggedInUser().getUserName(); + LocalDateTime localDateTime = LocalDateTime.now(); + Integer entityId = entityPostUpdateEvent.getEntity().getEmpId(); + EmployeeDetailsLog employeeDetailsLog = new EmployeeDetailsLog(); + employeeDetailsLog.setUserName(userName); + employeeDetailsLog.setDatetime(localDateTime); + employeeDetailsLog.setOperationType("Update"); + employeeDetailsLog.setEmpId(entityId); + employeeDetailsLogService.create(employeeDetailsLog); +} + +@EventListener +public void PostEntityDelete(EntityPostDeleteEvent entityPostDeleteEvent) { + String userName = securityService.getLoggedInUser().getUserName(); + LocalDateTime localDateTime = LocalDateTime.now(); + Integer entityId = entityPostDeleteEvent.getEntity().getEmpId(); + EmployeeDetailsLog employeeDetailsLog = new EmployeeDetailsLog(); + employeeDetailsLog = new EmployeeDetailsLog(); + employeeDetailsLog.setUserName(userName); + employeeDetailsLog.setDatetime(localDateTime); + employeeDetailsLog.setOperationType("Delete"); + employeeDetailsLog.setEmpId(entityId); + employeeDetailsLogService.create(employeeDetailsLog); +} +``` + +## Configure the Variable to Data Table + +1. Go to a page, and drag-and-drop a Data Table widget. +2. Create an `EMPLOYEE` CRUD variable and bind it to the Data Table at the time of configuring the widget. +3. Drag and drop another Data Table widget. +4. Create an `EMPLOYEE_DETAILS_LOG` CRUD variable and bind it to the Data Table when configuring it. +5. Invoke the `EMPLOYEE_DETAILS_LOG` CRUD variable using the `onSuccess` event of the `EMPLOYEE` CRUD variable created in step-2. + +![on success event](/learn/assets/crud-on-success-event.png) + +## Preview the Application + +In preview, perform some CRUD operations in the Employee table and notice the transactional details insert into the `EMPLOYEE_DETAILS_LOG` table. + +## See Also + +[Database CRUD Operations Event Listeners](/learn/app-development/services/database-crud-event-listeners) +[Dynamic Validations using CRUD Listeners](/learn/how-tos/validations-using-crudListeners) +[Custom Business Logic using DB CRUD Event Listeners](/learn/how-tos/custom-business-logic-using-crud-event-listeners) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/how-tos/aws-s3-connector.md b/website/versioned_docs/version-v11.8.5/how-tos/aws-s3-connector.md new file mode 100644 index 000000000..b8e9c59da --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/aws-s3-connector.md @@ -0,0 +1,119 @@ +--- +title: "Integrate Amazon S3(Simple Storage Service) into WaveMaker App" +id: "aws-s3-connector" +sidebar_label: "Integrate Amazon S3 into WaveMaker App" +--- +--- + +Learn how to implement file upload, download and delete file on S3 bucket using AWS S3 Connector. + +## AWS S3 Connector +Amazon S3 (Simple Storage Service) is a scalable, high-speed, low-cost web-based service designed for online backup and archiving of data and application programs. It allows to upload, store, and download any type of files up to 5 TB in size. This service allows the subscribers to access the same systems that Amazon uses to run its own web sites. The subscriber has control over the accessibility of data, i.e. privately/publicly accessible. + +This connector exposes api to interact with AWS S3 from WaveMaker application. + +## Step 1: Importing the aws-s3-connector to project + +1. Download the latest aws-s3-connector zip [here](https://github.com/wavemaker/aws-s3-connector/releases) +2. Import the downloaded aws-s3-connector zip into your app using the [Import Resource](/learn/app-development/services/3rd-party-libraries) option to the **Connector** folder. + +## Step 2: Configure aws-s3-connector properties in profiles +1. By default externalized connector properties are added in the project profiles [Know More](/learn/connectors/connectors-import#externalizing-connector-properties). +2. Connector externalized properties are prefixed with **connector.${connectorName}** + +```Java +connector.aws-s3-connector.default.aws.accessKey= +connector.aws-s3-connector.default.aws.accessSecret= +connector.aws-s3-connector.default.aws.clientRegion= +connector.aws-s3-connector.default.aws.bucketName= +``` + +## Step3: Perform File Operations in Storage Account. +Autowire the Connector Service into the added JavaService. + +Import Statement: +```Java +import com.wavemaker.connector.awss3connector.S3Connector; +``` +```Java +@Autowired +private S3Connector s3Connector; +``` + +### 1. Upload file to Amazon S3 bucket. +Uploads a new file object to the specified Amazon S3 bucket. + +Import statements required: +```Java +import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; +``` +Source Code: +```Java +public void uploadFile(MultipartFile file){ + try{ + s3Connector.uploadFileToS3(file.getInputStream(),file.getOriginalFilename(), null); + } catch (IOException e) { + throw new RuntimeException("Exception occurred while uploading file: "+e); + } +} +``` +:::note +The third param for upload API is the custom metadata. Add the key value pairs of the custom user-metadata for the associated file object. If the entry in the custom user-metadata map already contains the specified key, it will be replaced with these new contents. +::: +### 2. List files from Amazon S3. +Returns a list of summary information about the objects in the specified bucket. + +Import statements required: +```Java +import com.wavemaker.connector.awss3connector.AWSS3ObjectSummary; +import java.util.List; +``` +Source Code: +```Java +public List listObjects(){ + return s3Connector.listS3Objects(); +} +``` + +### 3. Download file from S3. +Gets the object from Amazon S3 under the specified bucket. + +Import statements required: +```Java +import com.wavemaker.runtime.file.model.DownloadResponse; +import java.io.OutputStream; +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +``` +Source Code: +```Java +public DownloadResponse downloadFile(String s3KeyName){ + try{ + OutputStream data= s3Connector.downloadFile(s3KeyName); + DownloadResponse downloadResponse=new DownloadResponse(); + ByteArrayOutputStream outStream = (ByteArrayOutputStream)data; + downloadResponse.setContents(new ByteArrayInputStream(outStream.toByteArray())); + downloadResponse.setInline(false); + downloadResponse.setFileName(s3KeyName); + return downloadResponse; + }catch(IOException e){ + throw new RuntimeException("Exception occurred while downloading file"+e); + } + } +``` + +### 4. Delete file in S3. +Deletes the specified object in the specified bucket. + +Source Code: +```Java +public void deleteFile(String s3KeyName){ + s3Connector.deleteFile(s3KeyName); +} +``` + +:::note +**s3KeyName** is the file key name. +Example: IMG_20200202.jpg +::: \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/how-tos/azure-file-storage-connector.md b/website/versioned_docs/version-v11.8.5/how-tos/azure-file-storage-connector.md new file mode 100644 index 000000000..27b8b733b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/azure-file-storage-connector.md @@ -0,0 +1,185 @@ +--- +title: "Integrate Azure File Storage into WaveMaker App" +id: "azure-file-storage-connector" +sidebar_label: "Integrate Azure File Storage" +--- +--- + +Learn how to implement upload, download and delete file operations using Azure file storage connector. + +## Azure File Storage Service + +Azure file storage service provides a way to store the documents/files in a centralized file storage server and also enables sharing the documents across users. Azure file storage is offered under the Azure storage account and once we have created an Azure storage account, we should have a file **share** created. + +We can create an unlimited number of file shares within a storage account. Once we create a file **share**, then we can create directories, just like folders, and then we can upload files into it. + +The process shows how to upload, download or delete file in storage account: + +1. Upload file to the storage. +2. List files in storage. +3. Download file from storage. +4. Delete file present in file storage. + +:::note + As the directories or files cannot be created under storage account directly we have to create **share** first. +::: + +## Step 1: Importing the azure-file-storage-connector to project + +1. Download the latest azurefilestorage connector zip [here](https://github.com/wavemaker/azure-file-storage-connector/releases) +2. Import the downloaded azurefilestorage connector zip into your app using the [Import Resource](/learn/app-development/services/3rd-party-libraries) option to the **Connector** folder. + +## Step 2: Configure azurefilestorage properties in profiles +1. By default externalized connector properties are added in the project profiles [Know More](/learn/connectors/connectors-import#externalizing-connector-properties). +2. Connector externalized properties are prefixed with **connector.${connectorName}** + +` +connector.azurefilestorage.default.azure.connectionString= +` + +:::important +To work with azure file storage connector provide the **connectionString** given by azure. +::: + +:::tip +You can find your storage account's connection strings in the [Azure portal](https://portal.azure.com). Navigate to SETTINGS > Access keys in your storage account's menu blade to see connection strings. +::: + +## Step3: File Operations in Storage Account. +Autowire the Connector Service into the added JavaService. + +Import Statement: +```Java +import com.wavemaker.connector.azurefilestorage.AzureFileStorageConnector; +``` +```Java +@Autowired +private AzureFileStorageConnector azureFileStorageConnector; +``` + +### 1. Create File Share in Storage Account. + +Import Statements Required. +```Java +import javax.annotation.PostConstruct; +``` + +Create Share in PostConstruct. +```Java + private static final String shareName=""; + + @PostConstruct + public void init(){ + azureFileStorageConnector.createShare(shareName); + } +``` + +### 2: Upload file to Azure File Storage. + +Upload file to the storage account. Make sure the specified share exists in the storage account. + +Import statements required. +```Java +import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; +import java.io.InputStream; +import java.io.ByteArrayInputStream; +``` + +```Java +public void uploadFile(String filePath, MultipartFile file){ + try (InputStream inputStream = new ByteArrayInputStream(file.getBytes())) { + azureFileStorageConnector.upload(shareName, filePath,inputStream); + } catch (IOException e) { + throw new RuntimeException("Exception occurred while uploading file: "+e); + } +} +``` + +### 3. List Files from Azure File Storage. +List the files and directories present in the specified directory path. + +```Java +import com.wavemaker.connector.azurefilestorage.model.AzureFile; +import java.util.List; +``` + +```Java +public List listFiles(String shareName, String directoryPath){ + return azureFileStorageConnector.listFiles(shareName,directoryPath); +} +``` + +### 4: Download File from Azure File Storage + +Download file from the storage account from the given filepath in azure share. + +Import Statements required. +```Java +import com.wavemaker.runtime.file.model.DownloadResponse; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +``` + +```Java +public DownloadResponse downloadFile(String filePath){ + String fileName=filePath.substring(filePath.lastIndexOf('/')+1,filePath.length()); + AzureFileResponse data= azureFileStorageConnector.downloadFileWithProperties(shareName,filePath); + DownloadResponse downloadResponse=new DownloadResponse(); + ByteArrayOutputStream outStream = (ByteArrayOutputStream)data.getOutputStream(); + downloadResponse.setContents(new ByteArrayInputStream(outStream.toByteArray())); + downloadResponse.setInline(false); + downloadResponse.setFileName(fileName); + downloadResponse.setContentType(data.getContentType()); + return downloadResponse; +} +``` + +### 5. Delete File from Azure File Storage +Delete the file from the given file path from the given share. + +```Java +public void deleteFile(String shareName, String filePath){ + azureFileStorageConnector.deleteFile(shareName,filePath); +} +``` + +:::note + The filepath should be specified as '/' if the file is inside the directory. If the file is present in the share then give the file name directly. +::: + +## Also see how to upload file to Azure storage using File upload widget. +The below process shows how to upload the file using file upload widget to the azure storage. +1. Drop File upload widget. +2. Create Variable for uploadFile added in the Javaservice in Step 3, point 2. +3. Invoke created Variable. + +### 1. Drop File upload Widget. +Drag 'n' drop file upload widget on to the canvas. + +:::note + Remove the **FileServiceUploadFile** from the **onSelect** event default added to the file upload widget (removing this because we just want to select the file and upload to azure storage). +::: + +### 2. Create Variable for the uploadFile method. +1. Create JavaService variable for the **uploadFile** method (added in Step3, point number2). Uncheck the properties **Update data on input change** and **Request data on page load**. + +2. Switch to **Data** tab and bind the required inputs needed for the variable. + 1. click on **file** input bind icon and select the file upload widget selectedFiles.(File upload selectedFiles gives info about the list of selected files) + + **Example:** + ```Js + Widgets.fileupload1.selectedFiles[0] + ``` + 2. click on bind icon of the **filePath** input and give the upload directory path of the azure storage along with fileName. + + **Example:** + ```JS + "qadir/"+Widgets.fileupload1.selectedFiles[0].name + ``` + where **qadir** is the directory path in the azure storage. + +### 3. Invoke Created Variable. +Drop a button on the canvas and **onClick** event of the button call the created variable. + +Now preview the app and select any file, the selected file will be uploaded in the directory of the azure storage. \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/how-tos/azure-repos-vcs.md b/website/versioned_docs/version-v11.8.5/how-tos/azure-repos-vcs.md new file mode 100644 index 000000000..d58438175 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/azure-repos-vcs.md @@ -0,0 +1,38 @@ +--- +title: "Configure Azure Repos In CodeRepository" +id: "azure-repos-vcs" +--- + +WaveMaker Team offering allows Team admins to configure Version Control System (VCS), which stores the project source code. + +From WaveMaker 11 GA, Team admins can configure **Azure Repos** under the **Add Code Repository** page. Although Azure supports Git and TFVC (Team Foundation Version Control) repositories, currently, WaveMaker supports only Git repositories. Thus, all WaveMaker projects created in Azure Repos will be Git repositories. + +Following are the instructions to configure Azure DevOps organization settings. + +## Base Url for Organization + +You must enter the base URL for **Azure Repos** in the following format. + +``` +https://dev.azure.com/{organizationName} +``` + +![azure organization settings](/learn/assets/azure-repos-organization-page.png) + +Ensure you enable **Use the new URL**. + +## User Name + +The username can be Full Name or Contact Email. + +![azure profile page](/learn/assets/azure-repos-profile-page.png) + +## Private AccessToken + +Access token for Azure Repos must contain full access to the user. See [Use Personal Access Tokens](https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops) for more information. + +## Select Project + +- Select an Azure project in the **Select Project** field. Repositories will be created in the selected project. + +- If no projects are on the list, **create them manually from the Azure Repos account**. diff --git a/website/versioned_docs/version-v11.8.5/how-tos/building-cascading-lists.md b/website/versioned_docs/version-v11.8.5/how-tos/building-cascading-lists.md new file mode 100644 index 000000000..8c667ff84 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/building-cascading-lists.md @@ -0,0 +1,20 @@ +--- +title: "Building Cascading Lists" +id: "building-cascading-lists" +--- + +**Scenario:** To show Master-Detail records using List + +We will see how a List can be populated from the selected item of another List + + + +[List Use Cases](/learn/app-development/widgets/datalive/list/list-use-cases/) + +- [1. List Basic Usage](/learn/app-development/widgets/datalive/list/list-basic-usage/) +- [2. How to group list items](/learn/how-tos/list-grouped/) +- [3. How to group list items based upon multiple fields](/learn/how-tos/list-multi-grouped/) +- [4. How to include data table within a list](/learn/how-tos/list-data-table/) +- [5. How to build editable list using live form](/learn/how-tos/building-editable-list/) +- [6. How to build list from the selected item of another list](/learn/how-tos/building-cascading-lists/) +- [7. How to access list items](/learn/how-tos/list-item-access/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/building-editable-list.md b/website/versioned_docs/version-v11.8.5/how-tos/building-editable-list.md new file mode 100644 index 000000000..a30467cb4 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/building-editable-list.md @@ -0,0 +1,23 @@ +--- +title: "Building an Editable List" +id: "building-editable-list" +--- + +**Scenario**: To make List editable. + +We will see how a Live Form can be added to a List to make it editable. + +1. Live form Form Data will be bound to selected item in a list. +2. Selected item in the List will show that record in Live Form which allows for editing the record and saving it. + + + +[List Use Cases](/learn/app-development/widgets/datalive/list/list-use-cases/) + +- [1. List Basic Usage](/learn/app-development/widgets/datalive/list/list-basic-usage/) +- [2. How to group list items](/learn/how-tos/list-grouped/) +- [3. How to group list items based upon multiple fields](/learn/how-tos/list-multi-grouped/) +- [4. How to include data table within a list](/learn/how-tos/list-data-table/) +- [5. How to build editable list using live form](/learn/how-tos/building-editable-list/) +- [6. How to build list from the selected item of another list](/learn/how-tos/building-cascading-lists/) +- [7. How to access list items](/learn/how-tos/list-item-access/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/building-pwa-app.md b/website/versioned_docs/version-v11.8.5/how-tos/building-pwa-app.md new file mode 100644 index 000000000..196c7878c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/building-pwa-app.md @@ -0,0 +1,148 @@ +--- +title: "Enabling PWA - Beta" +id: "building-pwa-app" +sidebar_label: "Enabling PWA" +--- +--- + +## What is PWA (Progressive Web Application) + +PWA (Progressive Web Application) are web applications that provide a native mobile app experience. These applications combine great functionalities and enhanced user experience based on the browser's capabilities and work on any platform, including desktop and mobile devices. You can develop PWA using web technologies such as JavaScript, HTML, and CSS. + +WaveMaker web applications are already responsive and ready to be converted to Progressive Web App. In this document, learn how to turn any WaveMaker web application into a PWA. + +## When to Use PWA vs. Mobile App + +WaveMaker Studio allows you to create two types of projects: + +1. Web Application +2. Mobile Application + +PWA applies explicitly to web applications, allowing them to behave closer to native mobile apps. However, to list a mobile app on Google Play or App Store, you should create a Mobile application project instead. + +### Advantages of Using PWA + +PWAs have many features and benefits that make them more unique compared to traditional web and native apps, including: + +- Fully responsive apps and compatible with browsers +- Connectivity independence +- App-like interface +- Push notifications +- Automatic updates +- More secure +- Discoverability and easy installation without going through app store approval cycles + +These features make PWA unique from native mobile applications and provide more robust features on any platform using any device. + +[![](/learn/assets/pwa/advantages.PNG)](/learn/assets/pwa/advantages.PNG) + +## PWA Features Supported by WaveMaker + +Currently, the following features are implemented in WaveMaker; that includes: + +- Add to the home screen +- Offline capabilities - storing of application code on mobile +- Push notifications + +### Deploying a New Version of the App + +**Understanding PWA**: When PWA is installed on a mobile device, the application's code, including JavaScript, CSS, and other artifacts, is stored and served from mobile file storage. Thus, it decreases the application startup time. + +**What happens when a new version is deployed**: WaveMaker build process configures the service worker manifest file to make this happen without having to do anything. When a new version of the web application is deployed on the cloud during the PWA startup, it performs the up-to-date check to verify if its cached contents are valid. If cached content is not valid, the new version of the deployed code is downloaded before starting the application. + + +### Prerequisites + +You must enable SSL and deploy the application using a secure connection to work with PWA features. When developing your application in WaveMaker, go to Security dialog and enable SSL. Then make sure you deploy the application on a domain with a valid SSL certificate. + +## Steps to Enable PWA Capabilities + +Create a project, add the PWA flag, and set the value as “true”. For example, `app.pwa.enabled=true` from the corresponding profile properties file. + +- The default behavior of the PWA feature is disabled. Therefore, if the PWA flag is not set or not available, it is considered disabled. + +:::note +This feature is under active development, and hence to enable it, you need to turn the feature flag on for every project. +::: + +[![](/learn/assets/pwa/flagproperty.png)](/learn/assets/pwa/flagproperty.png) + +- Deploy the app and launch the deployed app on any browser using the deployed URL. +- Once the app loads, an install icon shows up in the address bar of the browser. +- You can install the app by clicking on the icon highlighted below. + +[![](/learn/assets/pwa/install.png)](/learn/assets/pwa/install.png) + +- When you click the icon, a pop-up shows up, allowing you to install the application or cancel the installation. + +[![](/learn/assets/pwa/installDialog.png)](/learn/assets/pwa/installDialog.png) + +- After installing the application, the app opens up as a standalone application. + +[![](/learn/assets/pwa/launchedApp.png)](/learn/assets/pwa/launchedApp.png) + +### Enable PWA in Old Applications + +To enable the PWA feature in old applications, along with the above step, i.e., enabling PWA flag, do the following. + +- **Projects without Authentication enabled:** Add Manifest pattern in `project-security.xml`, i.e., add the following lines in the `project-security.xml` file. + +```java + + +``` + +- **Projects with Authentication enabled:** Re-save the security config from the Studio, which would regenerate the `project-security.xml` with the manifest pattern. + +## Steps to Set App Icon + +When PWA is installed on a mobile device, the icon you provide for the app will show on the mobile home screen. + +You can set the app icon as a user-provided icon for PWA in WaveMaker. Please find the steps below to add the app icon. + +1. Create a folder named “PWA-icons” in the root directory of a project. +2. Place the icon in the “PWA-icons” folder with either of the sizes: + - 512x512 + - 384x384 + - 192x192 + - 152x152 + - 144x144 + - 128x128 + - 96x96 + - 72x72 +3. Image file naming should be an icon-<size>.png. For example, `icon-384x384.png`. + +[![](/learn/assets/pwa/pwaIconsFolder.png)](/learn/assets/pwa/pwaIconsFolder.png) + +4. Re-deploying the app reflects the above changes. + +:::note +- In case of any missing icon(s), the nearest resolution will be used from the “pwa-icons” directory. + +**Example:** + +In the above image, we have uploaded two different image sizes. But the chrome browser uses 128x128, which is not present in the upload list; therefore, the PWA generation uses 384x384 size as the app icon. +- If no icons are present in the "pwa-icons" directory, PWA will use the WaveMaker default icons. +- As of now, only PNG format images are supported. +::: + +## Steps to Install PWA in Mobile Devices + +The above features can be applied in mobile, including Android and iPhone. To install the app on mobile, load the deployed app URL in Chrome browser and add the app to the home screen/install the app. + +[![](/learn/assets/pwa/mobileInstall.png)](/learn/assets/pwa/mobileInstall.png) + +[![](/learn/assets/pwa/installDialog_mobile.png)](/learn/assets/pwa/installDialog_mobile.png) + +You can observe the app in the app drawer. + +[![](/learn/assets/pwa/appdrawer.png)](/learn/assets/pwa/appdrawer.png) + +And once you open the app, it will be opened as a native mobile application. + +[![](/learn/assets/pwa/applaunched.png)](/learn/assets/pwa/applaunched.png) + +### Browser Support for PWA + +- All browsers do not support all the features of PWA. +- Please load this [URL](https://tomayac.github.io/pwa-feature-detector/) on any browser to know the PWA features it supports. diff --git a/website/versioned_docs/version-v11.8.5/how-tos/building-rating-widget-using-variable.md b/website/versioned_docs/version-v11.8.5/how-tos/building-rating-widget-using-variable.md new file mode 100644 index 000000000..ff7c63528 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/building-rating-widget-using-variable.md @@ -0,0 +1,46 @@ +--- +title: "Build Rating Widget using Model Variable" +id: "building-rating-widget-using-variable" +--- +--- + +Data for the Rating widget can come from a Variable - Model, Live etc.. In this example we will see how to use a Model Variable as the data source for a Rating Widget. The process is same for all types of Variables. + +1. Create a [Model Variable](/learn/assets/var_sel.png) of Entry Type, with Is List option selected and using the following JSON structure: + +``` +[ + { + "name": "Poor", + "dataValue": "1" + }, + { + "name": "Average", + "dataValue": "2" + }, + { + "name": "Good", + "dataValue": "3" + }, + { + "name": "V. Good", + "dataValue": "4" + }, + { + "name": "Excellent", + "dataValue": "5" + } +] +``` + +[![](/learn/assets/rating_usage_statvar.png)](/learn/assets/rating_usage_statvar.png) + +2. Drag and drop a Rating widget +3. Bind the Value Dataset property to the Static Variable created above and set the Data and Display Fields to the respective fields within the Variable. +4. Set the properties for Default Value, Maximum Value and Show captions according to your app requirements. + +[![](/learn/assets/rating_usage_statvar_bind.png)](/learn/assets/rating_usage_statvar_bind.png) + +5. Preview the app to see the Rating widget in action. + + diff --git a/website/versioned_docs/version-v11.8.5/how-tos/calendar-usage-create-event.md b/website/versioned_docs/version-v11.8.5/how-tos/calendar-usage-create-event.md new file mode 100644 index 000000000..50d2221c8 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/calendar-usage-create-event.md @@ -0,0 +1,25 @@ +--- +title: "Calendar Usage - Create an Event" +id: "calendar-usage-create-event" +--- +--- +The procedure to create an event, when a user clicks on a particular date is described in the presentation below. + +We will be using the following JavaScript for the on Before Dataset Ready event of the CRUD variable. + +```js +Page.event_varonBeforeDatasetReady = function(variable, data) { + data = data || []; + data.forEach(function(event) { + event.startDate = new Date(event.startDate); + event.endDate = new Date(event.endDate); + }); + }; +``` + + + +[Calendar Cases](/learn/app-development/widgets/form-widgets/calendar/#use-cases) + +- [1. Create an event](/learn/how-tos/calendar-usage-create-event/) +- [2. Integrate with Google Calendar](/learn/how-tos/calender-usage-google-calendar-integration/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/calender-usage-google-calendar-integration.md b/website/versioned_docs/version-v11.8.5/how-tos/calender-usage-google-calendar-integration.md new file mode 100644 index 000000000..9529cea49 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/calender-usage-google-calendar-integration.md @@ -0,0 +1,67 @@ +--- +title: "Calender Usage - Google Calendar Integration" +id: "calender-usage-google-calendar-integration" +--- +--- + +Google Calendar is one of the most popular ways to manage events, meetings, holidays and anything else that needs to be scheduled. In this document you'll learn how to integrate google calendar events into the WaveMaker calendar widget. + +[![](/learn/assets/google_calendar.png)](/learn/assets/google_calendar.png) + +## Prerequisites + +### Obtain Google Calendar API Key + +1. Go to the [Google Developer Console](https://console.developers.google.com) and create a new project. +2. Once you are in the project, navigate to **Library** on the sidebar. +3. Search for `Google Calendar API` and **Enable** it. +4. On the overview tab of Google calendar API, click **Create Credentials**. +5. In this step, you should add credentials to your project. Follow the steps below to add credentials. + - Step 1: For `Which API are using?` choose `Google Calendar API`. + - Step 2: For `Where will you be calling the API from?` choose `Web Browser(JavaScript)`. + - Step 3: For `What data you will be accessing?` choose an appropriate option. For example, select **User Data** and continue to "What Credentials do I need?". +6. You can skip the "Set up OAuth consent screen" prompt. +7. For "Create an OAuth 2.0 client ID" enter the domain details to host your calendar. If you do not have the details, leave them blank and go to the **Credentials** tab. + +:::tip +You can enter the domain details later if you want. +::: + +8. The new API key will appear in the credentials section. It can takes a few minutes before it starts working. + +### Make your Google Calendar public + +1. In the Google Calendar interface, locate the "My calendars" area on the left. +2. Hover over the calendar you need and click the downward arrow. +3. Click "Calendar settings" and go to Access permissions. +4. Check "Make this calendar public". +5. Make sure "Share only my free/busy information" is **unchecked**. +6. Click "Save". + +For more information, please follow this link https://support.google.com/calendar/answer/37083?hl=en. + +### Obtain your Google Calendar's ID + +1. In the Google Calendar interface, locate the "My calendars" area on the left. +2. Hover over the calendar you need and click the downward arrow. +3. A menu will appear. Click "Calendar settings". +4. In the "Calendar Address" section of the screen, you will see your Calendar ID. It will look something like "abcd1234@group.calendar.google.com". + +## WaveMaker App Integration + +1. Open a web responsive app +2. Drag and drop a Calendar widget +3. Insert the below function in the Page.onPageReady function of script part of the calendar widget page. Here our calendar name will be the same as that of name attribute of the calendar. + ```javascript + Page.Widgets.MyCalendar.addEventSource({ + source: 'google', + googleCalendarApiKey: '*********', // your google API key. + googleCalendarId: 'en.usa#holiday@group.v.calendar.google.com' // Your google calendar Id. + }) + ``` +4. Now the calendar is successfully configured with google calendar. + +## See Also + +[Calendar Cases](/learn/app-development/widgets/form-widgets/calendar/#use-cases) +[Create an event](/learn/how-tos/calendar-usage-create-event/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/camunda-wavemaker-app-integration.md b/website/versioned_docs/version-v11.8.5/how-tos/camunda-wavemaker-app-integration.md new file mode 100644 index 000000000..0e1667641 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/camunda-wavemaker-app-integration.md @@ -0,0 +1,157 @@ +--- +title: "How to Design a workflow in Camunda BPM and integrate into a WaveMaker app" +id: "camunda-wavemaker-app-integration" +sidebar_label: "Design a workflow in Camunda BPM and integrate into a WaveMaker app" +--- +--- + +## Overview + +In this article you will learn how to add workflow into a WaveMaker application by integrating with a opensource BPM product - Camunda. We will use the flexibility of the code generated by WaveMaker and call rules modelled in Camunda. + +For demonstration purpose, we will use Employee Leave Management application. Employee will apply for the leave using UI and the request will go to the backend where Camunda business rules engine is integrated. Based on leave balance, Camunda REST API will return the list of approvers to process the request. + +### STEP 1 – CAMUNDA SETUP + +1. About Camunda: + +[Camunda BPM](https://camunda.com/) is a light-weight, open-source platform for Business Process Management. Camunda is implemented in Java and supports BPMN for workflow and process automation, CMMN for Case Management and DMN for Business Decision Management. + +1. Getting Started With Camunda + https://docs.camunda.org/get-started/quick-start/ + +1. [Download and Install Camunda](https://docs.camunda.org/enterprise/download/) + Note: For Integrating WM online server, Please install Camunda services on cloud such as AWS/Azure. + +1. Create BPMN Process for Apply Leave Request + Below is the process flow create in Camunda. + [![lftr_sel](/learn/assets/leave_processflow.png)](/learn/assets/leave_processflow.png) + +1. Create DMN(Decision Management) table for setting up rules + Below is the decision table created using the Camunda DMN. + + [![lftr_sel](/learn/assets/business_rules.png)](/learn/assets/business_rules.png) + +1. Create a REST End-point for Camunda WorkFlow Engine + You can create the Camunda REST endpoint url. [Refer to this Camunda documentation](https://docs.camunda.org/manual/7.12/reference/rest/decision-definition/get/) + Example: `POST /decision-definition/key/{key}` +#### Request: +``` + POST http:///engine-rest/decision-definition/key/approve_leave/evaluate` + HTTP Headers: Content-Type="application/json" + Request Payload: + {"variables":{"applied":{"value":3,"type":"Integer"},"leftBalance":{"value":10,"type":"Integer"}} + } +``` +#### Response: + Response Payload: This will return the list of all Approvers needed for a leave request. +``` + [ + { + "secondApprover": { + "type": "String", + "value": "Director", + "valueInfo": {} + }, + "firstApprover": { + "type": "String", + "value": "Manager", + "valueInfo": {} + } + } + ] +``` + +### STEP 2 – Build Leave Management WaveMaker App + +In leave management application, employee will apply for the leaves entering start date & end date. Note: Initial leave balance for all the employees will be 10. Depending on the applied leave by employee Camunda workflow will process it and request will go to the respected person i.e. Manager, Director or HR. + +#### Create the UI in WaveMaker for Leave Management application: + +[![lftr_sel](/learn/assets/leavemgmt_app.png)](/learn/assets/leavemgmt_app.png) + +### STEP 3 – Integrate Camunda REST APIs for Business Rules Evaluation + +WaveMaker generates REST API needed to perform Create, Read, Update, Delete (CRUD) operations, when you import a database. This REST API allows customisation via addition of pre & post processing hooks. To learn in more detail about this feature, [refer to this page](/learn/how-tos/pre-post-processing-db-service-apis/). + +#### Import the REST endpoint url + +Import the Camunda REST Web Service from WaveMaker’s Web Service section. +Note: Please make sure to add Content-Type value as application/json in Header Params. + +[![lftr_sel](/learn/assets/importcamunda_api.png)](/learn/assets/importcamunda_api.png) + +#### Implement the Pre-processing service before invoking Database API + +```java + @Override + public LeaveRequest create(LeaveRequest leaveRequest) { + String camundaResponse = invokeRestService(leaveRequest); + + //Write the actual invocation method.. + private String invokeRestService(LeaveRequest leaveRequest){ + String serviceId = "restService"; //serviceId which we need to invoke + String operationId = "invoke"; //default operation provided + Date dateBefore = leaveRequest.getStartDate(); + Date dateAfter = leaveRequest.getEndDate(); + int appliedDays = daysBetween(dateBefore, dateAfter); + int leaveBalance = leaveRequest.getBalanceLeave(); + + HttpRequestData httpRequestData = new HttpRequestData(); + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add("Content-Type", "application/json"); + httpRequestData.setHttpHeaders(httpHeaders); + + try{ + + JSONObject leftBal = new JSONObject(); + leftBal.put("value", leaveBalance); + leftBal.put("type", "Integer"); + + JSONObject applied = new JSONObject(); + applied.put("value", appliedDays); + applied.put("type", "Integer"); + + JSONObject variables = new JSONObject(); + variables.put("applied", applied); + variables.put("leftBalance", leftBal); + + JSONObject main = new JSONObject(); + main.put("variables", variables); + + httpRequestData.setRequestBody(new ByteArrayInputStream(main.toString().getBytes(StandardCharsets.UTF8))); + + HttpResponseDetails httpResponseDetails = restRuntimeService.executeRestCall(serviceId,operationId, httpRequestData); + return IOUtils.toString(httpResponseDetails.getBody(), "UTF-8"); + + }catch(Exception ex){ + throw new WMRuntimeException("Some error encountered in Camunda invoke: "+ ex, ex); + } +``` + +#### STEP 4 – Database Design for the WM app + +The following is the database design in WaveMaker for Leave Management Application. +The model has employee details and his leave balance along with leave requests and history. +Model has "user" table which has different role like HR, Manager and Director who are responsbile for leave request approval. + +[![lftr_sel](/learn/assets/leavemgmnt_databasedesign.png)](/learn/assets/leavemgmnt_databasedesign.png) + +#### SUMMARY + +In this article you have learnt step by step approach on Camunda BPM workflow integration with WaveMaker generated prebuilt CRUD operations REST APIs. The following are the highlights: + +1. How to invoke external workflow engine like Camunda exposed REST APIs by importing into WaveMaker WebServices interface. + +1. Leveraging WaveMaker generated prebuilt Database APIs and intercepting in pre-processing hooks to call Camunda REST APIs + +1. Externalizing Business Rules onto Camunda decision flows so that any change in business rules WavaMaker app is not affected. + +1. Able to demonstrate a live application like Employee Leave Management, where Camunda returns list of leave approvers while the actual UI interaction is built in WavaMaker. WaveMaker can trigger automatice emails to the list of leave approvers. + +## See Also + +[How to send emails using Java Service](/learn/how-tos/sending-email-using-java-service/) +[How to access REST APIs from Java Service](/learn/how-tos/accessing-rest-apis-java-service/) +[How to schedule a Java Service](/learn/how-tos/scheduling-java-service/) +[How to accomplish Pre-Post Processing for a DB Service APIs](/learn/how-tos/pre-post-processing-db-service-apis/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/capturing-card-items.md b/website/versioned_docs/version-v11.8.5/how-tos/capturing-card-items.md new file mode 100644 index 000000000..e747faf3d --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/capturing-card-items.md @@ -0,0 +1,25 @@ +--- +title: "Capturing Card Items" +id: "capturing-card-items" +--- + +1. **currentItem & currentItemWidgets**: These bind objects can be used to bind the current item of the list to any form widget placed within the list template. The currentItemWidgets can be accessed as the fourth argument of the events for widgets within the List. For example, button click event within List will result in the following code will capture the caption property of the Name label within a List: + + Page.button1Click = function($event, widgets, item, currentItemWidgets) { + alert(currentItemWidgets.Name.caption); + }; + +2. **selecteditem & selectedItemWidgets**: These bind objects can be used to capture the selected item of the list when selection is enabled for the List. The return type would be array in case of multi-select List. Both selecteditem and selectedItemWidgets can be accessed through the script as follows, the click of a button will capture the selected item firstname and the caption of widget Name: + + Page.button1Click = function($event, widgets, item, currentItemWidgets) { + alert(Page.Widgets.livelist1.selecteditem.firstname); + alert(Page.Widgets.livelist1.selectedItemWidgets.Name.caption); + }; + + +[![list_bind](/learn/assets/list_bind.png)](/learn/assets/list_bind.png) + +[Cards Use Cases](/learn/app-development/widgets/datalive/cards/card-use-cases/) + +- [1. Cards Basic Usage](/learn/app-development/widgets/datalive/cards/card-basic-usage/) +- [2. How to access cards items](/learn/how-tos/capturing-card-items/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/change-icon-global-spinner.md b/website/versioned_docs/version-v11.8.5/how-tos/change-icon-global-spinner.md new file mode 100644 index 000000000..a5bd0cdd1 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/change-icon-global-spinner.md @@ -0,0 +1,26 @@ +--- +title: "Change Icon for the Global Spinner" +id: "change-icon-global-spinner" +--- +--- + +The icon that is displayed at the time of page load or data load are defined by a `wm-spinner` tag defined in the `index.html`. You can set it to any Font-Awesome icon using the corresponding icon class. For example, "fa fa-hourglass-o fa-spin fa-lg". + +## Changing Icon for Global Spinner + +You can change the icon using the following steps. + +1. From the left pullout menu Files tab, select Project from the drop down, and locate `index.html`. +2. Add the icon class property to the "wm-spinner" tag. +3. Save the index.html page and run the application. + +[![](/learn/assets/spin_icon.png)](/learn/assets/spin_icon.png) + +## See Also + +[How to change the default app favicon](/learn/how-tos/changing-default-favicon/) +[How to set the app logo](/learn/how-tos/changing-app-logo/) +[How to incorporate additional icons](/learn/how-tos/incorporating-additional-icons/) +[How to conditionally change the color of icons](/learn/how-tos/displaying-icon-color-based-upon-condition/) +[How to change the page title](/learn/how-tos/changing-page-title/) +[How to customise the app login page](/learn/how-tos/customise-login-page/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/changing-app-logo.md b/website/versioned_docs/version-v11.8.5/how-tos/changing-app-logo.md new file mode 100644 index 000000000..7cdeb68b5 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/changing-app-logo.md @@ -0,0 +1,59 @@ +--- +title: "Changing App Logo" +id: "changing-app-logo" +--- +--- +App Logo is used in multiple places, for example: + +- on the header of each page +- on the login page + +[![design_logo](/learn/assets/design_logo.png)](/learn/assets/design_logo.png) + +## Steps to change app logo + +By default, the WaveMaker logo is used as an app logo. You can change it by replacing the logo file. + +There are two ways to change the app logo. + +### Method-1: Change the logo from the header + +1. Go to the page header, click the logo and navigate to the picture properties, and click bind. + +[![design_logo_resource](/learn/assets/app-logo-bind.png)](/learn/assets/app-logo-bind.png) + +2. In the following screen, navigate to the **logos** directory, and click **Upload New** to add new logo file. + +[![design_logo_resource](/learn/assets/app-logo-header.png)](/learn/assets/app-logo-header.png) + +3. Select the new uploaded logo, and click **Bind**. + +4. Save and run the app. + + +### Method-2: Change logo from the File Explorer + +:::note +To use this method, you must use the same file name and the same location. +::: + +1. Go to **File Explorer** -> **Resources** -> **Import Resource**. + +[![design_logo_resource](/learn/assets/import-resources.png)](/learn/assets/import-resources.png) + +2. Navigate to **Images** -> **logos** directory -> `logo.png`. Alternatively, use the Search. + +[![design_logo_resource](/learn/assets/design_logo_resource.png)](/learn/assets/design_logo_resource.png) + +3. Delete this file and upload a new icon in the **same location with the same name**. + +4. Run the app to view changes. + +## See Also + +[Design UI Cases](/learn/app-development/ui-design/use-cases-ui-design/) +[How to change the default app favicon](/learn/how-tos/changing-default-favicon/) +[How to incorporate additional icons](/learn/how-tos/incorporating-additional-icons/) +[How to conditionally change the color of icons](/learn/how-tos/displaying-icon-color-based-upon-condition/) +[How to change load icon](/learn/how-tos/change-icon-global-spinner/) + diff --git a/website/versioned_docs/version-v11.8.5/how-tos/changing-default-favicon.md b/website/versioned_docs/version-v11.8.5/how-tos/changing-default-favicon.md new file mode 100644 index 000000000..453621051 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/changing-default-favicon.md @@ -0,0 +1,37 @@ +--- +title: "Changing Default Favicon" +id: "changing-default-favicon" +--- +--- + +By default, WaveMaker logo is displayed as the favicon when you run your app. + +[![design_favicon](/learn/assets/design_favicon.png)](/learn/assets/design_favicon.png) + +## Steps to change app favicon + +You can change the favicon of your app by replacing the default favicon file. + +:::note +Make sure to use the same file name as before in the same file location. +::: + +1. Go to **File Explorer** -> **Resources** -> **Import Resource**. + +![design_logo_resource](/learn/assets/import-resources.png) + +2. Navigate to **Images** -> **logos** directory -> `favicon.ico`. Alternatively, use the Search. + +[![design_favicon_resource](/learn/assets/design_favicon_resource.png)](/learn/assets/design_favicon_resource.png) + +3. Delete this file and upload a new icon in the **same location with the same name**. + +4. Run the app to view changes. + +## See Also + +[How to set the app logo](/learn/how-tos/changing-app-logo/) +[How to add additional icons](/learn/how-tos/incorporating-additional-icons/) +[How to conditionally change the color of icons](/learn/how-tos/displaying-icon-color-based-upon-condition/) +[How to change the page title](/learn/how-tos/changing-page-title/) +[How to change load icon](/learn/how-tos/change-icon-global-spinner/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/changing-page-title.md b/website/versioned_docs/version-v11.8.5/how-tos/changing-page-title.md new file mode 100644 index 000000000..7ac82c967 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/changing-page-title.md @@ -0,0 +1,28 @@ +--- +title: "Changing Page Title" +id: "changing-page-title" +--- +--- + +By default, the page title is set to the name given at the time of page creation. You can view it when you remove the toolbar and exit the preview mode. + +[![](/learn/assets/design_pagetitle.png)](/learn/assets/design_pagetitle.png) + +## Steps to change page title + +1. You can set the Page Title from the properties panel of the page + +[![](/learn/assets/design_pagetitle_prop-1.png)](/learn/assets/design_pagetitle_prop-1.png) + +2. You can set it from the Markup, too: + - Go to the **Markup** of the concerned page + - Locate the **pagetitle tag** and give the name of your choice. + +[![](/learn/assets/design_pagetitle_markup.png)](/learn/assets/design_pagetitle_markup.png) + +## See Also + +[How to set home page, language and date/time format](/learn/how-tos/setting-language-date-format/) +[How to set the app logo](/learn/how-tos/changing-app-logo/) +[How to change load icon](/learn/how-tos/change-icon-global-spinner/) +[How to customise the app login page](/learn/how-tos/customise-login-page/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/charts-custom-data.md b/website/versioned_docs/version-v11.8.5/how-tos/charts-custom-data.md new file mode 100644 index 000000000..2a96ef47b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/charts-custom-data.md @@ -0,0 +1,36 @@ +--- +title: "Charts - Custom Data" +id: "charts-custom-data" +sidebar_label: "Custom Data" +--- +--- + +**Custom Data Manipulation**: Instead of using the existing columns to be plotted on the x- and y-axis ([see here to know how](/learn/how-tos/charts-displaying-user-selection-another-widget/)), you can plot custom data as an aggregation or sum of the columns. For example, from the Department table of the sample hrdb, we want to plot the chart with average of all four quarters data (Q1, Q2, Q3, and Q4) + +1. Drag and drop chart widget, bind the Dataset Value property to the [Database CRUD Variable](/learn/assets/var_sel.png) (say, HrdbDepartmentData) with source as hrdb, and type as Department +2. Enter the following script in the above-mentioned variable _onSuccess_ event. This script will calculate the average of budget value and set it to the chart data set. + +```js +App.HrdbDepartmentDataonSuccess = function(variable, data) { + var aggregatedData = []; + + for (var i = 0; i < data.length; i++) { + var deptObj = data[i], + avgBudget = (deptObj.q1 + deptObj.q2 + deptObj.q3 + deptObj.q4) / 4; + + //Constructing aggregated data of all quarters + aggregatedData[i] = { + 'name': deptObj.name, + 'quaterBudget': avgBudget + }; + } + //Update the variable that is bound to chart + App.Variables.ChartData.dataSet = aggregatedData; + }; +``` + +## See Also  + +[Chart Widget Cases](/learn/app-development/widgets/chart/chart-widget/#use-cases) +[How to capture user selection](/learn/how-tos/charts-displaying-user-selection-another-widget/) +[How to handling dynamic data](/learn/how-tos/charts-handling-dynamic-data/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/charts-displaying-user-selection-another-widget.md b/website/versioned_docs/version-v11.8.5/how-tos/charts-displaying-user-selection-another-widget.md new file mode 100644 index 000000000..1f4754f37 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/charts-displaying-user-selection-another-widget.md @@ -0,0 +1,42 @@ +--- +title: "Charts - Displaying User Selection in another Widget" +id: "charts-displaying-user-selection-another-widget" +sidebar_label: "Display User Selection in another Widget" +--- +--- + +Hovering over the chart shows the values corresponding to the nearest data point. These data points can be captured and used to bind to a widget for further display or computational purposes. Here we will see how to do the same: + +1. We are using the _Department_ DB available after [importing the sample DB](/learn/app-development/services/database-services/working-with-databases/) which ships with the product. + +[![](/learn/assets/db_apis_db.png)](/learn/assets/db_apis_db.png) + +2. We have designed the canvas with a _Grid Layout_ with three rows. We will have + 1. _Chart widget_, + 2. two _Label Widgets_ - to display the total budget of the selected department from the chart and + 3. a _Data Table_ - to display the selected department details from the chart in each of the three rows. + + [![](/learn/assets/chart_sel_design.png)](/learn/assets/chart_sel_design.png) + +3. Create a [Database CRUD Variable](/learn/assets/var_sel.png) (say, _deptVar_) using the Department table +4. Drag and drop a Line chart onto the first Grid row. Bind the chart widget to the Department dataset, and set x-axis to deptCode and y-axis to Q1, Q2, Q3, and Q4 + +[![](/learn/assets/chart_sel_chart.png)](/learn/assets/chart_sel_chart.png) + +5. Drag and drop two labels onto the second row of the Grid. Set the caption of one to say "Total Budget:". Bind the caption property of the second Label widget to display the total budget as the sum of Q1, Q2, Q3 and Q4 values from the selected item under chart widget using the Use Expression option in the bind dialog. + +[![](/learn/assets/chart_sel_label.png)](/learn/assets/chart_sel_label.png) + +6. Drag and drop a Data Table onto the third row of the Grid. Set the data source of the Data Table to the selected item of the chart widget. Choose the other settings as per your requirements. We have chosen a Read-only table and selected to display department id, name, budget, code, and location. + +[![](/learn/assets/chart_sel_dt.png)](/learn/assets/chart_sel_dt.png) + +7. Run the and click on one data point and see the total displayed in the label and the details displayed in the Data Table. + +[![](/learn/assets/chart_sel_run.png)](/learn/assets/chart_sel_run.png) + +## See Also + +[Chart Widget Cases](/learn/app-development/widgets/chart/chart-widget/#use-cases) +[How to handling dynamic data](/learn/how-tos/charts-handling-dynamic-data/) +[How to displaying custom data](/learn/how-tos/charts-custom-data/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/charts-handling-dynamic-data.md b/website/versioned_docs/version-v11.8.5/how-tos/charts-handling-dynamic-data.md new file mode 100644 index 000000000..a7d4ab288 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/charts-handling-dynamic-data.md @@ -0,0 +1,19 @@ +--- +title: "Charts - Handling Dynamic Data" +id: "charts-handling-dynamic-data" +sidebar_label: "Handling Dynamic Data" +--- +--- + +**Dynamic Data**: Ensure that the chart reflects changes in data: for example, if you are using a chart to track dynamic data like stock data, you need to ensure that the changes to the data are reflected in the chart. For this, you can use a [Timer Action](/learn/app-development/variables/timer-action/). + +1. Drag and drop chart widget, bind the Dataset Value property to the [Variable](/learn/assets/var_sel.png) based on the service fetching the dynamic data +2. Create a _Timer Variable_ and set the _delay_ to the required time gap between fetching data and set _repeating_ if the process is continuous +3. Set the _on Timer Fire_ event to trigger the variable to which the chart widget is bound +4. Run the project, after the specified Timer Delay, the chart will be refreshed. If you have set the repeating option then the process will be repeated at the delay intervals. + +## See Also + +[Chart Widget Cases](/learn/app-development/widgets/chart/chart-widget/#use-cases) +[How to capture user selection](/learn/how-tos/charts-displaying-user-selection-another-widget/) +[How to displaying custom data](/learn/how-tos/charts-custom-data/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/checkboxset-filter-list-data.md b/website/versioned_docs/version-v11.8.5/how-tos/checkboxset-filter-list-data.md new file mode 100644 index 000000000..cc4572bbe --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/checkboxset-filter-list-data.md @@ -0,0 +1,13 @@ +--- +title: "CheckboxSet to Filter List data" +id: "checkboxset-filter-list-data" +--- + +WaveMaker offers three ways of allowing user to choose from given options: + +- Select: Select widget lets the user to select values from an available list of options. The options are given in the form of a drop-down list from which the user can choose one option. +- Radioset and **CheckboxSet** are used when there are multiple values belonging to a single group to choose from. In case we have a yes/no or true/false scenario, we can use the Checkbox widgets. + +Here we will see how to Filter a List using a CheckboxSet Widget + + diff --git a/website/versioned_docs/version-v11.8.5/how-tos/combining-columns-data-table.md b/website/versioned_docs/version-v11.8.5/how-tos/combining-columns-data-table.md new file mode 100644 index 000000000..3b88d2072 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/combining-columns-data-table.md @@ -0,0 +1,39 @@ +--- +title: "Combining Columns in Data Table" +id: "combining-columns-data-table" +--- +--- + +## Scenario + +You can combine two or more columns to be displayed in a single column in a Data Table. **Use Case**: From the Department table, display two half-yearly budget figures by adding the values for first two and the second two quarters. We will be using the hrdb that is shipped with WaveMaker. + +## Pre-requisites + +1. Create a Web responsive app +2. Import the sample hrdb database +3. Drag and drop a Data Table, setting the data source to the Department table from hrdb + +## Steps to combine to columns + +1. Go to Advanced Settings of the Data Table from the Properties panel +2. From the Columns tab, add two new columns - H1 and H2 +3. In the View Mode section, enter the following for Value Expression: + +{{row.getProperty('q1') + row.getProperty('q2')}} + +This will add the content from columns q1 and q2 and set it as the content for H1 column. + +[![](/learn/assets/dt_ve_1.png)](/learn/assets/dt_ve_1.png) + +:::note +q1 and q1 are the Mapped Column name for the columns Q1 and Q2. +::: + +[![](/learn/assets/dt_ve_2.png)](/learn/assets/dt_ve_2.png) + +4. Run the app and see the Data Table. + +[![](/learn/assets/dt_ve_3.png)](/learn/assets/dt_ve_3.png) + + diff --git a/website/versioned_docs/version-v11.8.5/how-tos/concurrency-record-locking-wavemaker.md b/website/versioned_docs/version-v11.8.5/how-tos/concurrency-record-locking-wavemaker.md new file mode 100644 index 000000000..dc13dbd7b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/concurrency-record-locking-wavemaker.md @@ -0,0 +1,46 @@ +--- +title: "Concurrency and Record Locking in WaveMaker" +id: "concurrency-record-locking-wavemaker" +--- +--- + +## Use Case + +How to handle the scenario wherein two users update a row in a Database Table at the same time. + +The document explains the implementation for obtaining concurrency and record locking in WaveMaker.We will be using MariaDB on MySQL Cloud setup. + +## Steps + +1. [Create a MariaDB database](/learn/app-development/services/database-services/working-with-databases/). See the following the [documentation link](/learn/app-development/services/database-services/working-with-databases/#integrating-database) for details +2. Add a table with the following columns: + - ID - type integer, + - Name - type String name, and + - Version - type long. +3. Go to the File Explorer and navigate to the following directory: + +``` +/services//src/com/// +``` + +- Add @Version annotation for the version column as shown below. + +[![](/learn/assets/concurrency_annot.png)](/learn/assets/concurrency_annot.png) + +- Add the below import statement. + +```js +import javax.persistence.Version; +``` + +:::note +Please note the @Version annotation added in the above step might get reverted each time a DB re-import operation is performed, hence replace the @Version after each DB re-import. +::: + +4. Create a Page in the app. +5. Drag and drop a Data Table widget into the page and set the data source as the table/entity designed in Step #2. +6. Open the Advanced Settings of the Data Table widget and uncheck the Show property for the version column. + +[![](/learn/assets/concurrency_DTAS.png)](/learn/assets/concurrency_DTAS.png) + +7. Run the application and insert/update values into the Data Table widget. When two users update a row in the data table at the same time, only one of the transactions will be completed whereas the other call will fail with an error message. diff --git a/website/versioned_docs/version-v11.8.5/how-tos/configure-mtls-in-wmapp.md b/website/versioned_docs/version-v11.8.5/how-tos/configure-mtls-in-wmapp.md new file mode 100644 index 000000000..ec455b833 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/configure-mtls-in-wmapp.md @@ -0,0 +1,86 @@ +--- +title: "Configure MTLS in WaveMaker Application" +id: "configure-mtls-in-wmapp" +sidebar_label: "Configuring MTLS" +--- +--- + +WaveMaker supports importing [REST API](/learn/app-development/services/web-services/rest-services) as a Service which you can bind it to a widget in the UI (User Interface). When the REST API is hit in the design time or runtime, an SSL (Secure Sockets Layer) connection is established between the client and server. When this communication takes place, the sensitive information is encrypted. + +You can also configure the SSL connection to enable server and client authentication, which is Mutual TLS. You can achieve this in WaveMaker applications now. + +MTLS (Mutual Transport Layer Security) configuration can be done at the application level. Therefore, it applies to all the Rest Services that are imported and yet to be imported. Also, it applies to the APIs that you have imported using Swagger. + +:::note +MTLS configuration applies only to the REST APIs with proxy enabled, as the backend receives the request only when the proxy is enabled. +::: + +## Server Authentication + +You can find the properties to configure server authentication as shown below in the Profile properties. + +``` +security.general.truststore.config=SYSTEM_ONLY +security.general.truststore.file= +security.general.truststore.fileType= +security.general.truststore.password= +``` +## Truststore Configuration + +### SYSTEM_ONLY + +Default java trust store is used. It does not require any additional Truststore file. + +### APPLICATION_ONLY + +The custom Truststore is used. It requires a trust store file, file type, and password of the Truststore. If the Truststore is in the classpath prefix **classpath:** or if it is in a system file directory prefix **file:** + +### APPLICATION_AND_SYSTEM + +Both custom and default Java Truststore are used here. + +### NO_CHECK + +There is no server authentication enabled here. + +If Truststore configuration is set as `NO_CHECK` or `SYSTEM_ONLY`, the truststore file is not required. If the truststore configuration is set as `APPLICATION_ONLY` or `APPLICATION_AND_SYSTEM`, then it requires the truststore file, the file type, and truststore password. + +## Client Authentication + +The properties to configure client authentication can be found in the **Profile** properties, as shown below. + +``` +security.general.mtls.enabled=false +security.general.mtls.keystore.file= +security.general.mtls.keystore.fileType= +security.general.mtls.keystore.password= +``` + +If MTLS enabled is false, the client authentication is disabled. If it is true, it requires the Keystore file, file type, and Keystore password. + +The Truststore or Keystore can be uploaded into the `src/main/resources` directory using the import resource option, as shown below. + +![Import-Resource](/learn/assets/import-resource.png) + +:::note +If the Keystore or Truststore is in the classpath prefix **classpath:** or if it is in a system file directory prefix **file:** to the file property as shown below: + +``` +security.general.truststore.file=classpath:truststore.jks +security.general.truststore.fileType=JKS +security.general.mtls.keystore.file=classpath:keystore.p12 +security.general.mtls.keystore.fileType=PKCS12 +``` +Both Keystore and Truststore file types can be JKS, PKCS12, or any other supported file types. +::: + +## Hostname Verification + +Hostname verification matches the hostname that the client is trying to connect to and the hostname that is present in the certificate provided by the server. +The SSL connection is established only if the hostname matches. By default, hostname verification is true and can be disabled in the profile properties. + +Below is the property to configure hostname verification. + +``` +security.general.client.ssl.hostNameVerification.enabled=true +``` \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/how-tos/configuring-aws-redshiftdb.md b/website/versioned_docs/version-v11.8.5/how-tos/configuring-aws-redshiftdb.md new file mode 100644 index 000000000..62625583c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/configuring-aws-redshiftdb.md @@ -0,0 +1,51 @@ +--- +title: "Connect To AWS Redshift Database" +id: "configuring-aws-redshiftdb" +--- +--- + +## Introduction + +The document provides the steps to connect to an existing Database in AWS RedshiftDB from a WaveMaker application. A Redshift Database is a cloud-based, big data warehouse solution offered by Amazon. The platform provides a storage system that allows companies to store petabytes of the data in easy-to-access “clusters” that can be queried in parallel. + +## Prerequisites + +- RedshiftDB connection details such as + - Host + - DB name + - DB Credentials +- Allow connections from WaveMakerOnline (reach out to [support](mailto:support@wavemaker.com) for the Gateway IP) + + +## Steps + +1. Navigate to the Databases section and click on the plus icon to add the Database to the project. From the popup, choose **Connect To a DB** option. + + +[![](/learn/assets/redshift-add-db.png)](/learn/assets/redshift-add-db.png) + +[![](/learn/assets/redshift-connect-db.png)](/learn/assets/redshift-connect-db.png) + +2. In the next step, choose the Database provider. Select **Amazon Redshift**. + +[![](/learn/assets/Import-DB.png)](/learn/assets/Import-DB.png) + +3. In the next step, enter the details of the RedshiftDB. + - Database Info: + - **Username and Password**: DB Credentials. + - **Database Name**: Provide the name of the Database to connect. + - **Host**: Hostname of the Database to connect. + - **Schema Filter**: List of schema names to be imported in the WaveMaker. + - Advanced Settings: + - **Port**: Port on which Redshift is configured (default is 443). + - **JDBC URL**: JDBC connection string of the DB. + +[![](/learn/assets/redshift-provide-details.png)](/learn/assets/redshift-provide-details.png) + +4. Test the connection and click on the Next button. + +5. Select the desired tables to be imported and click on the Next button. This will now automatically generate the CRUD APIs for the select entities. The imported tables can be viewed from the DB designer. + +[![](/learn/assets/redshift-select-tables.png)](/learn/assets/redshift-select-tables.png) + +[![](/learn/assets/redshift-db-designer.png)](/learn/assets/redshift-db-designer.png) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/configuring-cascading-select.md b/website/versioned_docs/version-v11.8.5/how-tos/configuring-cascading-select.md new file mode 100644 index 000000000..fc5ab52b9 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/configuring-cascading-select.md @@ -0,0 +1,21 @@ +--- +title: "Configuring Cascading Select" +id: "configuring-cascading-select" +--- + +One can drive the content of a Select widget based upon the selection of another Select widget. For example, a user is provided with a list of Countries and based upon the selection, a list of Cities is displayed for selection from a second list. Let us see how to achieve this in WaveMaker. **Note**: We are using a dataset CityListing which contains the country and city details. [![](/learn/assets/sel_cs_db.png)](/learn/assets/sel_cs_db.png) + +1. Drag and drop two Select and one Label widgets onto the canvas. +2. [Create a Database CRUD Variable](/learn/assets/var_sel.png) for the above CityListing table (say, _citylistingVar_). [![](/learn/assets/sel_cs_var1.png)](/learn/assets/sel_cs_var1.png) +3. Bind the first Select widget to the _citylistingVar _dataset. Set the Display Field and Data Field to the Country field of the dataset. [![](/learn/assets/sel_cs_prop1.png)](/learn/assets/sel_cs_prop1.png) +4. [Create another Database CRUD variable](/learn/assets/var_sel.png) (say, _cityVar_), bind it to the CityListing dataset and set filter on the Country field to the Country Select widget datavalue. [![](/learn/assets/sel_cs_var2.png)](/learn/assets/sel_cs_var2.png) +5. Bind the second Select widget to the variable (_cityVar) _created in the above step. Set the Display Field and Data Field to the City field. [![](/learn/assets/sel_cs_prop2.png)](/learn/assets/sel_cs_prop2.png) +6. Run the application, select country and see the city list change. + +[Select Use Cases](/learn/app-development/widgets/form-widgets/select-use-cases/) + +- [1. How to use list of values for select widget configuration](/learn/how-tos/configuring-select-widget-static-list-values/) +- [2. How to use variable for select widget configuration](/learn/how-tos/configuring-select-widget-variable/) +- [3. How to use display and data value fields for select widget configuration](/learn/how-tos/configuring-select-widget-display-data-fields/) +- [4. How to use database fields for select widget configuration](/learn/how-tos/configuring-select-widget-database-fields/) +- [5. How to configure cascading select](/learn/how-tos/configuring-cascading-select/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/configuring-content-security-policy.md b/website/versioned_docs/version-v11.8.5/how-tos/configuring-content-security-policy.md new file mode 100644 index 000000000..19d24ef0e --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/configuring-content-security-policy.md @@ -0,0 +1,78 @@ +--- +title: "Configuring Content-Security-Policy" +id: "configuring-content-security-policy" +--- +--- + +Content Security Policy (CSP) is a computer security standard introduced to prevent cross-site scripting (XSS), clickjacking, and other code injection attacks resulting from executing malicious content in the trusted web page context. + +## CSP Support in WaveMaker apps + +From [WaveMaker 10.15.0](/learn/wavemaker-release-notes/v10-15-0) onwards, web apps built on WaveMaker support strict content-security-policy. + +1. The platform does not evaluate JavaScript during runtime out of the box. +2. The platform does not include any inline script. + +As a result, you do not need to declare "unsafe-eval" and "unsafe-inline" keywords against the script-src directive. + +Similarly, no inline style tags are added by unknown providers. Thus, you do not need to declare the "unsafe-inline" keyword against the style-src directive. + +:::note +Please note that the generated Angular app supports strict CSP. The preview app does not support strict CSP. Keywords like "unsafe-eval" and "unsafe-inline" are still required during Preview mode. +::: + +## Enabling CSP in WaveMaker apps + +WaveMaker apps support supplying CSP via HTTP response headers while serving the index.html file. You can configure it as part of the maven profile and have different policies for different profiles. This makes whitelisting resource providers easy and configurable as per the profile. + +### Content Security Policy Properties + +From WaveMaker 10.15 onwards, two new properties are introduced in the maven config profile to configure CSP. + +- security.general.csp.enabled +- security.general.csp.policy + +## Example Policy + +To enable CSP for the deployment profile, perform the following steps: + +1. Edit the deployment.properties file in the project as follows: + +``` +security.general.csp.enabled=true +security.general.csp.policy=script-src 'self'; style-src 'self' 'nonce-${NONCE_VALUE}'; default-src 'self' +``` + +2. In the index.html file, add a meta tag inside the head tag as follows: +``` + +``` +3. Deploy and test + +:::note +The policy above is a sample one. You can provide your own policy against the property security.general.csp.policy +::: + +## ${NONCE_VALUE} + +### What is ${NONCE_VALUE} + +If you notice, an additional keyword is mentioned against the style-src directive, nonce-${NONCE_VALUE}. This is a placeholder for the WaveMaker backend to generate a random nonce value and supply the same to the browser on every page refresh. Without this, widgets based on specific 3rd party libs like nvd3, ngx-bs, etc. will not work properly. + +### How it works + +WaveMaker runtime uses certain 3rd party open source libraries like ngx-bootstrap, nvd3, etc. These libraries add inline style tags, which the browser will block unless unsafe-inline is declared against the style-src directive in the CSP. If that is done, the web app becomes vulnerable to XSS attacks from unknown sources. + +### Solution + +To solve this issue, we use the concept of a nonce, where a random keyword is generated at the backend, which will be supplied to the browser in the CSP. Now, the browser will only allow those inline style tags with this nonce as an attribute. WaveMaker runtime supplies nonce to all its available 3rd party libs, thus, safely whitelisting inline styles added by these trusted sources. The meta tag with CSP-NONCE is required to read the nonce value by JS runtime. + +## Exception Scenarios + +By default, WaveMaker apps do not require special keywords like 'unsafe-eval' and 'unsafe-inline' for the script-src directive. But there are a few scenarios where the app will not work without these keywords. + +These are: + +- When **Dynamic DataTable** is used, 'unsafe-eval' is required against the script-src directive. +- When **Dynamic form** is used, 'unsafe-eval' is required against the script-src directive. +- When the **Richtext editor** widget is used, 'unsafe-inline' is required against the style-src directive. This widget uses open source library summernote, which is heavily jQuery based and applies inline styles. \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/how-tos/configuring-jws-and-opaque-security-providers.md b/website/versioned_docs/version-v11.8.5/how-tos/configuring-jws-and-opaque-security-providers.md new file mode 100644 index 000000000..8608f8569 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/configuring-jws-and-opaque-security-providers.md @@ -0,0 +1,218 @@ +--- +title: "Configure JWS and Opaque providers" +id: "configuring-jws-and-opaque-security-providers" +--- + +WaveMaker offers many security providers to enable authentication to the WaveMaker applications from the security dialog. The security providers like DEMO, Database, LDAP, Active Directory, SAML, OpenID, and Custom Security are the primary security providers. Additionally along with the primary provider a secondary provider can also be enabled like JWS or Opaque Token provider. + +## Enabling JWS Provider + +1. Navigate to the File Explorer and search auth-info.json. + +[![](/learn/assets/file_explorer_auth_info_json.png)](/learn/assets/file_explorer_auth_info_json.png) + +2. Add the below JSON content to auth-info.json which is a sample JSON structure to enable JWS. + +[![](/learn/assets/secondary_provider_script.png)](/learn/assets/secondary_provider_script.png) + +```json + + "secondaryAuthProviders": { + "JWS": { + "enabled": true, + "jwsProviderIdVsProviderInfo": { + "okta": { + "providerId": "okta", + "enabled": true, + "issuerUrl": " ", + "principalClaimName": "email", + "roleMappingEnabled": true, + "roleMappingConfig": { + "modelName": "testdb", + "entityName": "RoleTable", + "tableName": "ROLE_TABLE", + "usernameField": "username", + "usernameColumn": "USERNAME", + "roleField": "role", + "roleColumn": "ROLE", + "roleQuery": "", + "queryType": "HQL" + } + }, + "google": { + "providerId": "google", + "enabled": true, + "issuerUrl": "https://accounts.google.com", + "principalClaimName": "email", + "roleMappingEnabled": true, + "roleMappingConfig": { + "roleAttributeName": "roleAttribute" + } + } + }, + "type": "JWS" + } + + + } + +``` + +3. Go to `${openid-server-url}/.well-known/openid-configuration API` that returns the issuer URL and other details of the server. This helps to find the issuer URL if the provider that is being configured follows OpenID spec. +4. Under the JWS section set `enabled` as true. + +:::note + +JWS provider can have multiple providers configured like Google, Okta, and each sub-provider can be enabled/disabled. + +::: + +[![](/learn/assets/enabled_jws_true.png)](/learn/assets/enabled_jws_true.png) + +|Field|Description| +|-----|------| +|providerId|A unique provider ID for each sub provider in JWS| +|issuerUrl|The issuer URL of the open ID provider.| +|principalClaimName|The claim name in the ID token which will be used as current logged in user’s userID| +|roleMappingEnabled|role mapping can be enabled/disabled for each sub provider| +|roleMappingConfig|JWS supports two types of role mappings| + +### Role Mapping in JWS + +The role attribute is configured using the JWS or database. To know more about role mapping, see [Role Mapping](/learn/app-development/app-security/central-authentication-system/#role-mapping). + +#### JWS Role Attribute Mapping + +Configure a role attribute in the issuer. The attribute should be available in the ID token claims. This attribute value is used for role mapping authorization. Add `roleAttributeName` in the JSON structure as shown below. + +#### Database Role Attribute Mapping + +Configure a role table and once the token is authenticated the current logged-in user role is retrieved from the database. Add the `modelName`, `entityName`,`tableName`, `usernameField`, `usernameColumn`, `roleField`, `roleColumn` or `roleQuery`, `queryType` in the JSON structure as shown below for the Okta provider. + +5. Save the auth-info.json file and open the security dialog. + +[![](/learn/assets/security_dialog.png)](/learn/assets/security_dialog.png) + +6. Go to the Authentication and Authorization tab to enable the primary security provider. Click Save. + +:::note + +A primary security provider should be enabled to apply a secondary provider to the application. + +::: + +[![](/learn/assets/authentication_authorization.png)](/learn/assets/authentication_authorization.png) + +7. Navigate to the File Explorer and open the required profile properties file. + +[![](/learn/assets/development_properties.png)](/learn/assets/development_properties.png) + +8. Update the property security.activeProviders by adding JWS to it. Example: DEMO, JWS. + +[![](/learn/assets/security_provider_jws_property.png)](/learn/assets/security_provider_jws_property.png) + +9. Invoke an API by passing the ID token as a bearer token. To know how to pass the ID token as a bearer token in the WaveMaker application, see [How to Pass Logged-In User ID/Access Tokens as Header](learn/how-tos/passing-id-access-tokens-as-header). + +:::note + +If the incoming token is of JWS format then enable the JWS provider. + +::: + +## Enabling Opaque Token Provider + +1. Navigate to the File Explorer and search auth-info.json. + +[![](/learn/assets/file_explorer_auth_info_json.png)](/learn/assets/file_explorer_auth_info_json.png) + +2. Add the below JSON content to auth-info.json to enable the Opaque token provider. + +[![](/learn/assets/opaque_security.png)](/learn/assets/opaque_security.png) + + +```json + "secondaryAuthProviders": { + "OPAQUE_TOKEN": { + "enabled": false, + "introspectionUrl": " ", + "clientId": " ", + "clientSecret": " ", + "principalClaimName": "sub", + "roleMappingEnabled": true, + "roleMappingConfig": { + "modelName": "testdb", + "entityName": "RoleTable", + "tableName": "ROLE_TABLE", + "usernameField": "username", + "usernameColumn": "USERNAME", + "roleField": "role", + "roleColumn": "ROLE", + "roleQuery": "", + "queryType": "HQL" + }, + "type": "OPAQUE_TOKEN" + } + } + +``` + +3. Go to `${openid-server-url}/.well-known/openid-configuration API` that returns the introspection URL and other details of the server. This helps to find the introspection URL if the provider that is being configured follows OpenID spec. +4. Under the OPAQUE_TOKEN section set `enabled` as true. + +:::note + +Opaque token provider can be enabled only if the OpenID provider that is used supports introspection. + +::: + +[![](/learn/assets/opaque_secondary_provider.png)](/learn/assets/opaque_secondary_provider.png) + +|Field|Description| +|-----|------| +|introspectionUrl|Introspection endpoint is used to validate the access token and should be supported by the provider.| +|clientId and clientSecret|Provided by the open ID provider once the app is registered.| +|principalClaimName|The claim name in the Access token which will be used as current logged-in user’s ID.| +|roleMappingEnabled|role mapping can be enabled/disabled for each sub provider.| +|roleMappingConfig|Opaque token provider supports two types of role mappings.| + +### Role Mapping in Opaque Token + +The role attribute is configured using the Opaque token or database. To know more about role mapping, see [Role Mapping](/learn/app-development/app-security/central-authentication-system/#role-mapping). + +#### Opaque Token Role Attribute Mapping + +Configure a role attribute in the issuer. The attribute should be available in the ID token claims and the attribute value will be used for authorization(role mapping). Add `roleAttributeName` in the JSON structure under the `roleMappingConfig` as shown below. + +#### Database Role Attribute Mapping + +Configure a role table and once the token is validated using the introspection endpoint the current logged-in user role is retrieved from the database. Add `modelName`, `entityName`, `tableName`, `usernameField`, `usernameColumn`, `roleField`, `roleColumn` or `roleQuery`, `queryType` in the JSON structure as shown below. + +5. Save the auth-info.json file and open the security dialog. + +[![](/learn/assets/security_dialog_opaque.png)](/learn/assets/security_dialog_opaque.png) + +6. Go to the Authentication and Authorization tab to enable the primary security provider. Click Save. + +:::note + +A primary security provider should be enabled to apply a secondary provider to the application. + +::: + +[![](/learn/assets/authentication_authorization.png)](/learn/assets/authentication_authorization.png) + +7. Navigate to the File Explorer and open the required profile properties file. + +[![](/learn/assets/developement_properties.png)](/learn/assets/developement_properties.png) + +8. Update the property security.activeProviders by adding OPAQUE_TOKEN to it. Example: DEMO, OPAQUE_TOKEN. + +[![](/learn/assets/security_active_properties_opaque.png)](/learn/assets/security_active_properties_opaque.png) + +9. Invoke an API by passing the access token as a bearer token. To know how to pass access token as bearer token in the WaveMaker application, see [How to Pass Logged-In User ID/Access Tokens as Header](learn/how-tos/passing-id-access-tokens-as-header). + +:::note + +If the incoming token is of Opaque format then enable the Opaque token provider. + +::: \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/how-tos/configuring-sap-hana-clouddb.md b/website/versioned_docs/version-v11.8.5/how-tos/configuring-sap-hana-clouddb.md new file mode 100644 index 000000000..3f0cb9e2f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/configuring-sap-hana-clouddb.md @@ -0,0 +1,51 @@ +--- +title: "Connect To SAP Hana Cloud Database" +id: "configuring-sap-hana-clouddb" +--- +--- + +## Introduction + +This document provides the steps to connect to SAP HANA Cloud Database and configure the relational Database schema in WaveMaker. SAP HANA Cloud is a fully managed in-memory cloud Database as a Service (DBaaS) offered by SAP. It helps manage your data storage and integration while running powerful applications. + +## Prerequisites + +- SAP HANA Cloud connection details such as: + - Host + - DB name + - DB Credentials +- Allow connections from WaveMakerOnline (reach out to [support](mailto:support@wavemaker.com) for the Gateway IP) + +## Steps + +1. Navigate to the Databases section and click on the plus icon to add the Database to the project. From the popup, choose **Connect To a DB** option. + + +[![](/learn/assets/saphanacloud-add-db.png)](/learn/assets/saphanacloud-add-db.png) + +[![](/learn/assets/saphanacloud-connect-db.png)](/learn/assets/saphanacloud-connect-db.png) + +2. In the next step, choose the Database provider. Select **SAP HANA**. + +[![](/learn/assets/Import-DB.png)](/learn/assets/Import-DB.png) + +3. In the next step, enter the details of the SAP HANA Cloud Database. + - Database Info: + - **Username and Password**: DB Credentials. + - **Database Name**: Provide the name of the Database to connect. + - **Host**: Hostname of the Database to connect. + - **Schema Filter**: List of schema names to be imported in the WaveMaker. + - Advanced Settings: + - **Port**: Port on which SAP HANA is configured (default is 443). + - **JDBC URL**: JDBC connection string of the DB. + (Example: `**jdbc:sap://< hostname>:< port>/?encrypt=true&validateCertificate=false&nonBlockingIO=false**`) + +[![](/learn/assets/saphanacloud-provide-details.png)](/learn/assets/saphanacloud-provide-details.png) + +4. Test the connection and click on the Next button. + +5. Select the desired tables to be imported and click on the Next button. This will now automatically generate the CRUD APIs for the select entities. The imported tables can be viewed from the DB designer. + +[![](/learn/assets/saphanacloudselect-tables.png)](/learn/assets/saphanacloudselect-tables.png) + +[![](/learn/assets/saphanacloud-db-designer.png)](/learn/assets/saphanacloud-db-designer.png) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-database-fields.md b/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-database-fields.md new file mode 100644 index 000000000..bec177c6b --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-database-fields.md @@ -0,0 +1,27 @@ +--- +title: "Configuring Select Widget from Database Fields" +id: "configuring-select-widget-database-fields" +--- + +A Select widget can be used in various ways based on the source of data. Each type of data source needs a different approach. WaveMaker Select widget works in any one of the following ways: + +- [Using static list of values](/learn/how-tos/configuring-select-widget-static-list-values/) +- [Using variable data](/learn/how-tos/configuring-select-widget-variable/) +- [Using display and data value fields from a Variable](/learn/how-tos/configuring-select-widget-display-data-fields/) +- Using database fields + +The options displayed in the Select drop-down can come from a database, too. For example, you want the user to select department id based on the department they belong to. + +1. Drag and drop a Select and Label widget onto the canvas. +2. Bind the Select widget to a database. Here we are using the Department table from the hrdb, [import the sample db](/learn/app-development/services/database-services/working-with-databases/) that comes shipped with Studio and has been imported earlier and [Create Database CRUD Variable](/learn/assets/var_sel.png) [![](/learn/assets/sel_db_var.png)](/learn/assets/sel_db_var.png) +3. Set the Datafield property to the deptid field and Display Field property to the name field of the Live Variable corresponding to Department dataset [![](/learn/assets/sel_db_props.png)](/learn/assets/sel_db_props.png) +4. The selection made by the user is displayed in a Label widget, by binding the select datavalue to it. [![](/learn/assets/sel_list_res.png)](/learn/assets/sel_list_res.png) +5. Preview the app and see the selected item from the Select widget displayed in the label. + +[Select Use Cases](/learn/app-development/widgets/form-widgets/select-use-cases/) + +- [1. How to use list of values for select widget configuration](/learn/how-tos/configuring-select-widget-static-list-values/) +- [2. How to use variable for select widget configuration](/learn/how-tos/configuring-select-widget-variable/) +- [3. How to use display and data value fields for select widget configuration](/learn/how-tos/configuring-select-widget-display-data-fields/) +- [4. How to use database fields for select widget configuration](/learn/how-tos/configuring-select-widget-database-fields/) +- [5. How to configure cascading select](/learn/how-tos/configuring-cascading-select/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-display-data-fields.md b/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-display-data-fields.md new file mode 100644 index 000000000..65df0d563 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-display-data-fields.md @@ -0,0 +1,51 @@ +--- +title: "Configuring Select Widget using Display and Data Fields" +id: "configuring-select-widget-display-data-fields" +--- + +A Select widget can be used in various ways based on the source of data. Each type of data source needs a different approach. WaveMaker Select widget works in any one of the following ways: + +- [Using static list of values](/learn/how-tos/configuring-select-widget-static-list-values/) +- [Using variable data](/learn/how-tos/configuring-select-widget-variable/) +- Using display and data value fields from a Variable +- [Using database fields](/learn/how-tos/configuring-select-widget-database-fields/) + +Usually, when giving options to the user, one would want the option to make sense to the user while using a different value internally within the application. For example, the user may select Male/Female but the value stored could be M/F or 0/1. To cater to such needs, WaveMaker Studio offers an Entry type while creating a Model Variable. Using this option, the developer can specify different fields for the variable – one called dataValue and the other called name. For example, you want the user to select gender as Male or Female but want to use M or F internally. + +1. Drag and drop a Select and Label widget onto the canvas. +2. [Create a variable](https://docs.wavemaker.com/learn/app-development/variables/), and choose the variable type as the **Model**. + +![Model Variable](/learn/assets/select-model-variable.png) + +3. Select **Entry** as Type. Check the **Is List** property to confirm that the variable is storing the list and add the list values. You can use the text editor to enter the values in JSON format. + +![select_widget_values](/learn/assets/configure-variable.png) + +## Binding Select Widget with Variable + +1. Bind the dataset of the **Model** variable to the **Select** widget. + +![select_widget_values](/learn/assets/bind-model-variable.png) + +2. Set the **Data field** property to the **dataValue** and **Display Field** to the **name** of the static variable. + +![select_widget_ValueProperties](/learn/assets/select_widget_ValueProperties.png) + +3. Drag and drop two **Label** widgets and bind them using the below **Use Expression** to show the Data value and display values. + + ![select_widget_displayvalue](/learn/assets/display-value.png) + + ![select_widget_datavalue](/learn/assets/select-widget-datavalue.png) + +4. Preview the app and see the Display Value and Data Value of the selected item from the **Select** widget displayed on the screen with the use of the **Label** widget. + + ![select_widget_ListResult](/learn/assets/select_widget_ListResult.png) + + +[Select Use Cases](/learn/app-development/widgets/form-widgets/select-use-cases/) + +- [1. How to use list of values for select widget configuration](/learn/how-tos/configuring-select-widget-static-list-values/) +- [2. How to use variable for select widget configuration](/learn/how-tos/configuring-select-widget-variable/) +- [3. How to use display and data value fields for select widget configuration](#) +- [4. How to use database fields for select widget configuration](/learn/how-tos/configuring-select-widget-database-fields/) +- [5. How to configure cascading select](/learn/how-tos/configuring-cascading-select/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-static-list-values.md b/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-static-list-values.md new file mode 100644 index 000000000..59c1df9e7 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-static-list-values.md @@ -0,0 +1,25 @@ +--- +title: "Configuring Select Widget from a Static List of Values" +id: "configuring-select-widget-static-list-values" +--- + +A Select widget can be used in various ways based on the source of data. Each type of data source needs a different approach. WaveMaker Select widget works in any one of the following ways: + +- Using static list of values +- [Using variable data](/learn/how-tos/configuring-select-widget-variable/) +- [Using display and data value fields from a Variable](/learn/how-tos/configuring-select-widget-display-data-fields/) +- [Using database fields](/learn/how-tos/configuring-select-widget-database-fields/) + +1. Drag and drop a Select and Label widget onto the canvas. +2. The simplest way to use the Select Widget is to enter the values in a comma-separated format for display in the Value property under the DATASET section. In this example, we have set the value to Travelling, Reading, Writing, Photography. +3. You can set the Default Value. This is the value that is seen by the user when the app runs, it should be one of the options set in the value field above. In the above example, we have set it to Writing. [![](/learn/assets/sel_list.png)](/learn/assets/sel_list.png) +4. The selection made by the user is displayed in a Label widget, by binding the select datavalue to it. [![](/learn/assets/sel_list_res.png)](/learn/assets/sel_list_res.png) +5. Preview the app and see the selected item from the Select widget displayed in the label. + +[Select Use Cases](/learn/app-development/widgets/form-widgets/select-use-cases/) + +- [1. How to use list of values for select widget configuration](#) +- [2. How to use variable for select widget configuration](/learn/how-tos/configuring-select-widget-variable/) +- [3. How to use display and data value fields for select widget configuration](/learn/how-tos/configuring-select-widget-display-data-fields/) +- [4. How to use database fields for select widget configuration](/learn/how-tos/configuring-select-widget-database-fields/) +- [5. How to configure cascading select](/learn/how-tos/configuring-cascading-select/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-static-variable.md b/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-static-variable.md new file mode 100644 index 000000000..4cad9a57c --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-static-variable.md @@ -0,0 +1,17 @@ +--- +title: "Configuring Select Widget from a Static Variable" +id: "configuring-select-widget-static-variable" +--- +--- + +Instead of having a [comma-separated list](/learn/how-tos/configuring-select-widget-static-list-values/), one can use a Static Variable to hold the list and then bind it to the Select widget. This will enable us to reuse the list at multiple places, if needed. + +1. [Create a Static Variable](/learn/app-development/variables/variables), choose the Is List and add the list values: [![sel_listvar](/learn/assets/sel_listvar.png)](/learn/assets/sel_listvar.png) +2. Bind the Select Widget to the Static Variable dataset: [![sel_listvar_bind](/learn/assets/sel_listvar_bind.png)](/learn/assets/sel_listvar_bind.png) +3. Set the Datafield value to the datavalue of the static variable. This is the value that is selected by the user: [![sel_listvar_props](/learn/assets/sel_listvar_props.png)](/learn/assets/sel_listvar_props.png) +4. Running the app will result in the display of the Select widget [![sel_listvar_run1](/learn/assets/sel_listvar_run1.png)](/learn/assets/sel_listvar_run1.png) [![sel_listvar_run2](/learn/assets/sel_listvar_run2.png)](/learn/assets/sel_listvar_run2.png) + + +## See Also +[Select Use Cases](/learn/app-development/widgets/form-widgets/select-use-cases/) + diff --git a/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-variable.md b/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-variable.md new file mode 100644 index 000000000..2ced14883 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/configuring-select-widget-variable.md @@ -0,0 +1,29 @@ +--- +title: "Configuring Select Widget from a Variable" +id: "configuring-select-widget-variable" +--- + +A Select widget can be used in various ways based on the source of data. Each type of data source needs a different approach. WaveMaker Select widget works in any one of the following ways: + +- [Using static list of values](/learn/how-tos/configuring-select-widget-static-list-values/) +- Using variable data +- [Using display and data value fields from a Variable](/learn/how-tos/configuring-select-widget-display-data-fields/) +- [Using database fields](/learn/how-tos/configuring-select-widget-database-fields/) + +Instead of having a [comma-separated list](/learn/how-tos/configuring-select-widget-static-list-values/), one can use a Variable to hold the list and then bind it to the Select widget. This will enable us to reuse the list at multiple places if needed. + +1. Drag and drop a Select and Label widget onto the canvas. +2. [Create a Model Variable](/learn/assets/var_sel.png), choose the Is List and add the list values: [![](/learn/assets/sel_listvar.png)](/learn/assets/sel_listvar.png) +3. Bind the Select Widget to the Model Variable dataset +4. Set the Data field value to the dataValue of the model variable. This is the value that is selected by the user. +5. The Display field is what the user sees in the list. In this case it is same as the Data field. We will see the case when both are different in the next use case. [![](/learn/assets/sel_listvar_props.png)](/learn/assets/sel_listvar_props.png) +6. The selection made by the user is displayed in a Label widget, by binding the select datavalue to it. [![](/learn/assets/sel_list_res.png)](/learn/assets/sel_list_res.png) +7. Preview the app and see the selected item from the Select widget displayed in the label. + +[Select Use Cases](/learn/app-development/widgets/form-widgets/select-use-cases/) + +- [1. How to use list of values for select widget configuration](/learn/how-tos/configuring-select-widget-static-list-values/) +- [2. How to use variable for select widget configuration](#) +- [3. How to use display and data value fields for select widget configuration](/learn/how-tos/configuring-select-widget-display-data-fields/) +- [4. How to use database fields for select widget configuration](/learn/how-tos/configuring-select-widget-database-fields/) +- [5. How to configure cascading select](/learn/how-tos/configuring-cascading-select/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/connect-azure-sql-server.md b/website/versioned_docs/version-v11.8.5/how-tos/connect-azure-sql-server.md new file mode 100644 index 000000000..a3d48ca8f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/connect-azure-sql-server.md @@ -0,0 +1,44 @@ +--- +title: "Connect To Azure SQL Server" +id: "connect-azure-sql-server" +--- + +## Prerequisites + +- To import/connect to SQL Server running in Azure Cloud, you need to have the database driver jar named sqljdbc4.jar available with you. [Steps in download](/learn/app-development/services/database-services/download-jdbc-driver-jar/) +- Access to Azure Account with permission to edit the firewall rules. +- SQL Server running in Azure with database that you want to import. + +## Steps in Azure Integration + +1. [Connect to Azure SQL Server by uploading the jar and configuring the connection settings](#instructions) +2. [Map the WaveMaker connection settings with SQL Server settings](#mapping) +3. [Enable Firewall to access SQL Server](#firewall) + +## Instructions + +1. Create/Open the project in which you want to import the SQL Server database. +2. From the [Add Database](/learn/app-development/services/database-services/working-with-databases/) dialog, select SQL Server database. +3. Select Database Versions as Azure SQL Database and provide sqljdbc4.jar file as Driver jar and click on upload button. After the JAR imported successfully, click on Next. [![](/learn/assets/azure_dbdriver.png)](/learn/assets/azure_dbdriver.png) +4. Provide Azure SQL server details such as Host, User Name, Password and Database Name, Schema Filter (comma-separated list of schema names to import) in the configure settings step and click on ADVANCED SETTINGS button to review the generated connection url. Note: The mappings between the Azure MS SQL Server and WaveMaker are given in the [next section](#mapping). [![](/learn/assets/azure_dbsettings.png)](/learn/assets/azure_dbsettings.png) +5. Once connection has been successfully established you will be provided with a connection success message and Next button will be enabled. In case you get an error message, check the Firewall settings at Azure as [explained here](#firewall). +6. Click on next button to view tables in the database +7. Select tables and click on import button. + +Your Database is imported and ready to use in the application. + +## Connection settings Mappings + +(NOTE: The screenshots from Azure were current at the time of creation of this document. The actual images might differ) + +1. Login to Azure Dashboard +2. Navigate to Microsoft Azure -> SQL databases -> [![](/learn/assets/azure_dbmap1.png)](/learn/assets/azure_dbmap1.png) +3. Click on show database connection strings [![](/learn/assets/azure_dbmap2.png)](/learn/assets/azure_dbmap2.png) +4. The Server name maps to the Host and JDBC link maps to the connection URL in the configuration settings dialog [![](/learn/assets/azure_dbmap3.png)](/learn/assets/azure_dbmap3.png) + +## Enable Firewall to access SQL Server + +1. While Testing Connection with MS SQL Server, it may fail to connect as the firewall does not allow incoming connections from WaveMaker by displaying the message as shown below. [![](/learn/assets/azure_firewall.png)](/learn/assets/azure_firewall.png) +2. From the error message, you can **extract the IP of WaveMaker** and enable firewall for that IP. **Beware**: This IP address is common to _all WaveMakeronline_ users and as such any WaveMakerOnline user will be able to access your server once you enable firewall for the IP. You are strongly advised to take appropriate measures to protect your server. +3. To set up firewall in Azure SQL navigate to _Sql Servers-> <your-database-server> -> settings -> firewall settings_ +4. Add _Rule name_, _Start IP (the IP of WaveMaker, obtained from the error message)_ and _End IP (the IP of WaveMaker, obtained from the error message)_ and save [![](/learn/assets/azure_firewall1.png)](/learn/assets/azure_firewall1.png) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/consuming-existing-wm-api-into-another-wm-project.md b/website/versioned_docs/version-v11.8.5/how-tos/consuming-existing-wm-api-into-another-wm-project.md new file mode 100644 index 000000000..3d25b7e06 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/consuming-existing-wm-api-into-another-wm-project.md @@ -0,0 +1,48 @@ +--- +title: "How to Consume a WaveMaker API into another WaveMaker App using Open API/Swagger" +id: "consuming-existing-wm-api-into-another-wm-project" +sidebar_label: "Consuming an Existing WaveMaker API" +--- +--- + +You can Import REST API endpoints via Open API/Swagger import feature. + +In this document, see how you can use an API of an existing WaveMaker app into another WaveMaker app in just a few simple steps. + +:::note +This document assumes that you have a sample HRDB imported in your project. For more information, see [Connect to a sample DB](/learn/app-development/services/database-services/working-with-databases/#connect-to-a-db). +::: + +## Download Swagger from a WaveMaker Project + +- Click **File Explorer**. +- Go to the following path `services/hrdb/designtime/hrdb_API.json` +- Download the file. + +![download swagger](/learn/assets/download-swagger.png) + +## Import Swagger into another Project + +Import the downloaded swagger into another WaveMakar project. For more information on how to import, see [Importing REST APIs via Swagger](/learn/app-development/services/api-designer/import-rest-apis-swagger). + +## Enter Host Name and Base Path + +You will need the host name and base path when you import an API via [Swagger Import](/learn/app-development/services/api-designer/import-rest-apis-swagger). + +:::note +Ensure that the application is deployed before you could use the API. For more information on how to deploy an app, see [One-Click Deployment](/learn/app-development/deployment/one-click-deployment). +::: + +![updating host and basepath](/learn/assets/update-host-basepath.png) + +- Enter the **Host Name**. The host is the URL where the app is hosted. For example, `hostid.cloud.wavemakeronline.com/yourappname`. +- Enter the **Base Path**. For example, `/services` is the basepath for HRDB. +- Click **Save**. + +The WaveMaker app's API is ready to consume in your project. + +## See Also + +[OpenAPI support in WaveMaker - Blog](/learn/blog/2020/04/21/wavemaker-openapi-import) +[Importing REST APIs via Swagger](/learn/app-development/services/api-designer/import-rest-apis-swagger) + diff --git a/website/versioned_docs/version-v11.8.5/how-tos/copy-to-clipboard.md b/website/versioned_docs/version-v11.8.5/how-tos/copy-to-clipboard.md new file mode 100644 index 000000000..4764286d3 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/copy-to-clipboard.md @@ -0,0 +1,47 @@ +--- +title: "Copy to Clipboard" +id: "copy-to-clipboard" +--- +--- +Learn how to implement the copy text to clipboard in WaveMaker by following the steps below. You can use copying text to clipboard functionality for text, number, and textarea widgets. + +:::note +Copying to clipboard applies to input widgets only. For example, text, number, textarea, and it does not apply to widgets like label. +::: + +## Copy Text to Clipboard + +The clipboard allows you to copy the text on a single button click or through an event handler. The following steps describe how to implement copy text to the clipboard feature on a button click. + +[![form_filter_design](/learn/assets/Copy_ClipBoard.png)](/learn/assets/Copy_ClipBoard.png) + +## Step-1: Drag and Drop Widget + +1. Drag-and-drop a text, number, or a textarea widget on a page. +2. Drag-and-drop a button and name it as `Copy Text`. + +## Step-2: Adding Script to the On Click Event + +Add the following Script to the button to copy text. + +- Click the `Copy Text` button, go to **Events** -> **On Click** and select `JavaScript` from the dropdown. + +### Text and Number widgets + +For text and number widgets, use the following script for button on click event. + +```js +Page.Widgets..$element.find('input').select(); +document.execCommand("copy"); +``` + +### Textarea widget + +For textarea widget, use the following script for button on click event. + +```js +Page.Widgets..$element.find('textarea').select(); +document.execCommand("copy"); +``` + + diff --git a/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-angular-module.md b/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-angular-module.md new file mode 100644 index 000000000..716262469 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-angular-module.md @@ -0,0 +1,279 @@ +--- +title: "Create Prefab using Angular Module" +id: "create-prefab-using-angular-module" +--- +--- +In this section, we will list the steps in creating a Prefab using an AngularJS module. For this we will be using the AngularJS tree module provided [here](http://jimliu.github.io/angular-ui-tree/). Below example is based on [v2.15.0](https://github.com/angular-ui-tree/angular-ui-tree/releases/tag/v2.15.0). We need to download the css and js files. + +## Creating Prefab + +1. From the Prefab tab in Project Dashboard, click on the **Create Prefab** icon. + +[![prefab_create1](/learn/assets/Prefab_Create1.png)](/learn/assets/Prefab_Create1.png) + +2. Enter Name and Description and click on **CREATE**. + +[![prefab_create2](/learn/assets/Prefab_Create2.png)](/learn/assets/Prefab_Create2.png) + +3. From the **Prefab Settings** dialog, **SAVE** without any changes. +4. **Import** the css and js files to the resources folder, using the Import option from Main Menu. + +[![import_resource1](/learn/assets/import_resource1.png)](/learn/assets/import_resource1.png) + +[![prefab_angui_resource](/learn/assets/prefab_angui_resource.png)](/learn/assets/prefab_angui_resource.png) + +:::note +Ensure that the resources folder is selected for the import. +::: + +5. From Main Menu use Create option to **Create a Static Variable**, **defaultTreeData**, to hold the default tree structure. Select the **is List** option and enter the Json structure. The structure needs to include **id, title, and nodes for subitems**. + +Here we have used the structure provided at the [website](http://jimliu.github.io/angular-ui-tree/). + +```json +[ + { + "id": 1, + "title": "1. dragon-breath", + "nodes": [] + }, + { + "id": 2, + "title": "2. moiré-vision", + "nodes": [ + { + "id": 21, + "title": "2.1. tofu-animation", + "nodes": [ + { + "id": 211, + "title": "2.1.1. spooky-giraffe", + "nodes": [] + }, + { + "id": 212, + "title": "2.1.2. bubble-burst", + "nodes": [] + } + ] + }, + { + "id": 22, + "title": "2.2. barehand-atomsplitting", + "nodes": [] + } + ] + }, + { + "id": 3, + "title": "3. unicorn-zapper", + "nodes": [] + }, + { + "id": 4, + "title": "4. romantic-transclusion", + "nodes": [] + } +] +``` + +[![prefab_angui_statvar](/learn/assets/prefab_angui_statvar.png)](/learn/assets/prefab_angui_statvar.png) + +6. Set the following Prefab properties, from the Prefab Settings: + - **Add a Style** to include the imported _css file_. + - **Add module**, give the name **ui.tree** and point it to the uploaded _js file_. **Note**: The module and its name is the requirement of the angular module being implemented. Use the same name. + + [![prefab_angui_resourcesettings](/learn/assets/prefab_angui_resourcesettings.png)](/learn/assets/prefab_angui_resourcesettings.png) + + - **Add a property** + - _Name_ & _Display Name_ as **list** + - _Data Type_ set to **list** + - the _Default Value_ bound to the static variable, **defaultTreeData** created + - the _Binding Type_ set to **in-out-bound** + - _Widget Type_ as **text** + + [![prefab_angui_props](/learn/assets/prefab_angui_props.png)](/learn/assets/prefab_angui_props.png) + + [![prefab_angui_propbind](/learn/assets/prefab_angui_propbind.png)](/learn/assets/prefab_angui_propbind.png) + + - **APPLY** changes and **CLOSE** the dialog +7. Define the template in html **markup** as: + +```html + +
+
    +
  1. +
+
+
+``` + +[![prefab_angui_html](/learn/assets/prefab_angui_html.png)](/learn/assets/prefab_angui_html.png) + +**Script** to include the following functions to be trigger whenever a property defined inside a prefab is changed. This also will generate the html file included above: + +:::note +Be sure to include **$templateCache** in the first line of the Script in **two places**. +::: + +```html +$templateCache.put('nodes_renderer.html', + '
' + + '' + + '' + + '' + + '{{node.title}}' + + '' + + '' + + '' + + '' + + '' + + '' + + '
' + + '
    ' + + '
  1. ' + + '
' + ); +``` +```js +$scope.remove = function (scope) { + scope.remove(); +}; + +$scope.toggle = function (scope) { + scope.toggle(); +}; + +$scope.newSubItem = function (scope) { + var nodeData = scope.$modelValue; + nodeData.nodes.push({ + id: nodeData.id * 10 + nodeData.nodes.length, + title: nodeData.title + '.' + (nodeData.nodes.length + 1), + nodes: [] + }); +}; +``` + +[![prefab_angui_script](/learn/assets/prefab_angui_script.png)](/learn/assets/prefab_angui_script.png) + +Add required **styles**: + +```css +.btn { + margin-right: 8px; +} +.angular-ui-tree-handle { + background: #f8faff; + border: 1px solid #dae2ea; + color: #7c9eb2; + padding: 10px 10px; +} +.angular-ui-tree-handle:hover { + color: #438eb9; + background: #f4f6f7; + border-color: #dce2e8; +} +.angular-ui-tree-placeholder { + background: #f0f9ff; + border: 2px dashed #bed2db; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.group-title { + background-color: #687074 !important; + color: #FFF !important; +} +``` + +[![prefab_angui_styles](/learn/assets/prefab_angui_styles.png)](/learn/assets/prefab_angui_styles.png) + +8. **Save** and **run** the Prefab. + +[![prefab_angui_run](/learn/assets/prefab_angui_run.png)](/learn/assets/prefab_angui_run.png) + +9. **Publish** the Prefab. + + +## Using Prefab + +To use the prefab in your application, Open the app where you want to use the Prefab + +1. Since the Prefab was published to workspace, you can see it in the Widget toolbox ready for drag and drop operation. Drag and drop the prefab onto the canvas and run the application. + +[![prefab_angui_app](/learn/assets/prefab_angui_app.png)](/learn/assets/prefab_angui_app.png) + +2. You can bind the prefab list property to any list and change the tree structure. We have created a static variable with the following structure and bound it to the list property. + +```json +[ + { + "id": 1, + "title": "node1", + "nodes": [ + { + "id": 11, + "title": "node1.1", + "nodes": [ + { + "id": 111, + "title": "node1.1.1", + "nodes": [] + } + ] + }, + { + "id": 12, + "title": "node1.2", + "nodes": [] + } + ] + }, + { + "id": 2, + "title": "node2", + "nodrop": true, + "nodes": [ + { + "id": 21, + "title": "node2.1", + "nodes": [] + }, + { + "id": 22, + "title": "node2.2", + "nodes": [] + } + ] + }, + { + "id": 3, + "title": "node3", + "nodes": [ + { + "id": 31, + "title": "node3.1", + "nodes": [] + } + ] + } +] +``` + +[![prefab_angui_appstatvar](/learn/assets/prefab_angui_appstatvar.png)](/learn/assets/prefab_angui_appstatvar.png) + +3. Bind the List property of the Prefab to the Static Variable created in the previous step. + +[![prefab_angui_appsbind](/learn/assets/prefab_angui_appsbind.png)](/learn/assets/prefab_angui_appsbind.png) + +4. **Run** the app and see the new tree structure + +[![prefab_angui_apprun](/learn/assets/prefab_angui_apprun.png)](/learn/assets/prefab_angui_apprun.png) + +## See Also + +[Prefab to compare two strings](/learn/how-tos/create-simple-prefab/) +[Prefab using 3rd Party UI Widgets](/learn/how-tos/create-prefab-using-third-party-ui-widgets/) +[Prefab Using D3 & NVD3 Charts](/learn/how-tos/create-prefab-using-d3-nvd3-charts/) +[Prefab Using D3 Library (DataMaps)](/learn/how-tos/create-prefab-using-d3-library-datamaps/) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-custom-element.md b/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-custom-element.md new file mode 100644 index 000000000..69809fde1 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-custom-element.md @@ -0,0 +1,303 @@ +--- +title: "Create Prefab using Angular, React Components" +id: "create-prefab-using-custom-element" +--- +--- + +WaveMaker framework is a pure javascript based runtime, making it compatible with most of the open web standards. The developers can include jquery based ui plugins, visualization libraries or any other javascript based code units to extend or complement the rich component library provided by the WaveMaker framework. + +The components developed in one of the js frameworks are normally not compatible with other frameworks and cannot be directly used inside standard HTML markup with framework or build bundles. Inorder to make these components work across web, it needs to be converted into a framework agnostic module. [**Web Components**](https://developer.mozilla.org/en-US/docs/Web/Web_Components) is one of such open standards. It relies on standard browser APIs such as [CustomElements](https://developer.mozilla.org/en-US/docs/Web/API/Window/customElements), [Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM) enabling its support across [browsers](https://caniuse.com/?search=web%20components) & frameworks. As mentioned earlier, WaveMaker works greatly with Open Standards thus with Web Component/Custom Elements as well. + +Most of the modern javascript frameworks have support for packaging the components as Web Components. WaveMaker supports the use of Web Components inside its projects & recommends its integration through [**Prefabs**](/learn/app-development/custom-widgets/custom-widgets). Its recommended to refer [documentation](/learn/app-development/custom-widgets/creating-prefabs/#build-your-own-prefabs) to know more about Prefabs in detail. + +The developers with **Angular** or **React** based components can leverage them in the WaveMaker project by exporting them as Web Components & importing through Prefabs.This documentation helps you understand the process with the help of Sample Component(_PosterWidget_) developed in both React & Angular. The source code is also shared for reference. + + +:::note +The shared _PosterWidget_ uses [OMDB](http://www.omdbapi.com/) API to fetch resources. If you are planning to try out the source code of component, please get the API key & replace in the source code before build. +::: + +## Convert Angular Component into Prefabs +Angular Framework recommends **Angular Elements** to export its components as Web Componenets. The documentation covers the process in detail with sample code as well. + +### Sample Angular Component +For this demonstration we will use a `PosterWidget` Component developed with Angular version 9. The code for the component can be found in the Github repository. The repo has the Angular elements configured for the project. So, on building it generates Web Component artefacts for the `PosterWidget` angular component. + +However, you can [download the artefacts](/learn/assets/webcomponents/poster-widget-angular.zip) directly from here & continue with the rest of the steps. The artefact is a zip file & on extracting it provides following files, +* polyfills-*.js +* vendor-*.js +* runtime-*.js +* styles-*.js +* main-*.js + +:::note +Before importing the Angular based Web Component into WaveMaker Prefabs/Projects, please validate that the components have no render issues or errors by including them in an plain HTML files. +::: + +### Create Prefab +Once we have the [artefacts](/learn/assets/webcomponents/poster-widget-angular.zip), we can create a Prefab for it with the help of below steps, +* Create a Prefab project using the **Prefab** tab of the Project Dashboard. + +[![](/learn/assets/howto_prefab_wc_01.png)](/learn/assets/howto_prefab_wc_01.png) + +* Enter a _Name_ and _Description_ for the Prefab + +[![](/learn/assets/howto_prefab_wc_02.png)](/learn/assets/howto_prefab_wc_02.png) + +* Upload the [artefacts](/learn/assets/webcomponents/poster-widget-angular.zip) into the `Resources` folder of project as shown below. + +[![](/learn/assets/howto_prefab_wc_03.png)](/learn/assets/howto_prefab_wc_03.png) + +[![](/learn/assets/howto_prefab_wc_04.png)](/learn/assets/howto_prefab_wc_04.png) + +* From the _Project_ Screen, choose **Config Prefab** under **Settings**. In the **Resources** tab, update **Scripts** with the JS file imported in the previous step. + +[![](/learn/assets/howto_prefab_wc_05.png)](/learn/assets/howto_prefab_wc_05.png) + +[![](/learn/assets/howto_prefab_wc_06.png)](/learn/assets/howto_prefab_wc_06.png) + +* Please ensure the Javascript sction the scripts in the below order + * `polyfills-*.js` + * `vendor-*.js` + * `runtime-*.js` + * `styles-*.js` + * `main-*.js` +* Open the `index.html` of the Prefab project and add the below Web Component polyfills to ensure support for all the browsers + +```html +... + + ... + + + + + +... +``` +* Open the markup of `Main` page of Prefab and add the below code to use `poster-widget-angular` Web Component in the page markup. + +```html + + +
+ + +
+
+``` +* Inorder to specify `poster-widget-angular` is a Web Component & not built in components, please add an additional attribute `html-custom-element="true"`. +* Click on **Preview**, to check if the Web component is rendered without any issues. + +[![](/learn/assets/howto_prefab_wc_07.png)](/learn/assets/howto_prefab_wc_07) + +* Once the component is rendered, we need to configure the input attribute `title` for the component. +* Inorder to communicate with web components, Prefab has an option called `Properties` under **Prefab Configurations** as shown below. +* Add a new property named `title` using the interface as shown below. + +[![](/learn/assets/howto_prefab_wc_05.png)](/learn/assets/howto_prefab_wc_05) + +[![](/learn/assets/howto_prefab_wc_08.png)](/learn/assets/howto_prefab_wc_08) + + +* This property can be used as a bridge between the external inputs or bindings to dynamically update the attribute of the WebComponent. +* Once the property is added, we can write the script to update the Web Component's attribute on change of the property as shown below. +```js +// PREFAB SCRIPT CODE +... + +Prefab.onPropertyChange = function(key, newVal, oldVal) { + + switch (key) { + case 'title': + /* Get the container Id */ + let widget_id = Prefab.Widgets.prefab_container1.widgetId; + /* + Get the WebComponent instance & + update the new property value to its "title" attribute + */ + document.querySelector('div[widget-id="' + widget_id + '"]') + .querySelector('poster-widget-angular') + .setAttribute('title', newVal); + + break; + } + +}; + +... + +``` +* Now test the Prefab using **Preview** option again. Try with updating the `title` value in **Inputs** section of **Properties**. The Web Component should update accordingly. + +[![](/learn/assets/howto_prefab_wc_09.png)](/learn/assets/howto_prefab_wc_09) + +### Publish Prefab +* **Save** & **Publish** the Prefab. You can set the version for the Prefab and Publish it. Know more about publishing Prefabs from [here](/learn/app-development/custom-widgets/prefabs-overview#publishing-prefabs). +* Once approved, the Prefab will be available for use across the Projects. An entry will appear in the Artefacts list from the Developer Utilities on the [Project Workspace.](/learn/app-development/wavemaker-overview/product-walkthrough/#project-workspace) The Prefab needs to be imported before it can be used from the Widget Toolbox. + + + +## Convert React Component into Prefab +Unlike Angular, currently there is no official support from React to develop Web Components. However, there are several community backed projects which can help in achieving it. Alternatively, developers can build Custom Element wrapper classes over existing react components as well. Lots of community blogs are available for both approaches which can be referred. + +### Sample React Component +For this demonstration we will use a `PosterWidget` Component developed with React Version 17. The sample React component is converted into a Web Component using Custom Element Wrapper approach in which each lifecycle event of React is mapped to corresponding event in CustomElement. The code for the component can be found in the Github repository. The repo has all the details to build & generate Web Component artefacts for the `PosterWidget` React component. + +However, you can [download the artefacts](/learn/assets/webcomponents/poster-widget-react.zip) directly from here & continue with the rest of the steps. The artefact is a zip file & on extracting it provides following files, +* `react-poster-widget.min.js` +* `react-poster-custom-element-wrapper.min.js` + +:::note +Before importing the React based Web Component into WaveMaker Prefabs/Projects, please validate that the components have no render issues or errors by including them in an plain HTML files. +::: + +### Create Prefab +Once we have the [artefacts](/learn/assets/webcomponents/poster-widget-angular.zip), we can create a Prefab for it with the help of below steps, +* Create a Prefab project using the **Prefab** tab of the Project Dashboard. + +[![](/learn/assets/howto_prefab_wc_01.png)](/learn/assets/howto_prefab_wc_01.png) + +* Enter a _Name_ and _Description_ for the Prefab + +[![](/learn/assets/howto_prefab_wc_10.png)](/learn/assets/howto_prefab_wc_10.png) + +* Upload the [artefacts](/learn/assets/webcomponents/poster-widget-angular.zip) into the `Resources` folder of project as shown below. + +[![](/learn/assets/howto_prefab_wc_03.png)](/learn/assets/howto_prefab_wc_03.png) + +[![](/learn/assets/howto_prefab_wc_11.png)](/learn/assets/howto_prefab_wc_11.png) + +* From the _Project_ Screen, choose **Config Prefab** under **Settings**. In the **Resources** tab, update **Scripts** with the JS file imported in the previous step. As we are rendering React elements inside out custom element wrapper, we should import React & React DOM libs as well. + +[![](/learn/assets/howto_prefab_wc_12.png)](/learn/assets/howto_prefab_wc_12.png) + +[![](/learn/assets/howto_prefab_wc_13.png)](/learn/assets/howto_prefab_wc_13.png) + +* Please ensure the Javascript sction the scripts in the below order + * `https://unpkg.com/react@17/umd/react.production.min.js` + * `https://unpkg.com/react-dom@17/umd/react-dom.production.min.js` + * `react-poster-widget.min.js` + * `react-poster-custom-element-wrapper.min.js` +* Open the `index.html` of the Prefab project and add the below Web Component polyfills to ensure support for all the browsers +```html +... + + ... + + + + + +... +``` + +* Open the markup of `Main` page of Prefab and add the below code to use `poster-widget-react` Web Component in the page markup. + +```html + + +
+ + +
+
+``` + +* Inorder to specify `poster-widget-react` is a Web Component & not built in components, please add an additional attribute `html-custom-element="true"`. +* Click on **Preview**, to check if the Web component is rendered without any issues. + +[![](/learn/assets/howto_prefab_wc_14.png)](/learn/assets/howto_prefab_wc_14) + +* Once the component is rendered, we need to configure the input attribute `title` for the component. +* Inorder to communicate with web components, Prefab has an option called `Properties` under **Prefab Configurations** as shown below. +* Add a new property named `title` using the interface as shown below. + +[![](/learn/assets/howto_prefab_wc_12.png)](/learn/assets/howto_prefab_wc_12) + +[![](/learn/assets/howto_prefab_wc_15.png)](/learn/assets/howto_prefab_wc_15) + + +* This property can be used as a bridge between the external inputs or bindings to dynamically update the attribute of the WebComponent. +* Once the property is added, we can write the script to update the Web Component's attribute on change of the property as shown below. +```js +// PREFAB SCRIPT CODE +... + +Prefab.onPropertyChange = function(key, newVal, oldVal) { + + switch (key) { + case 'title': + /* Get the container Id */ + let widget_id = Prefab.Widgets.prefab_container1.widgetId; + /* + Get the WebComponent instance & + update the new property value to its "title" attribute + */ + document.querySelector('div[widget-id="' + widget_id + '"]') + .querySelector('poster-widget-react') + .setAttribute('title', newVal); + + break; + } + +}; + +... + +``` +* Now test the Prefab using **Preview** option again. Try with updating the `title` value in **Inputs** section of **Properties**. The Web Component should update accordingly. + +[![](/learn/assets/howto_prefab_wc_16.png)](/learn/assets/howto_prefab_wc_16) + +### Publish Prefab +* **Save** & **Publish** the Prefab. You can set the version for the Prefab and Publish it. Know more about publishing Prefabs from [here](/learn/app-development/custom-widgets/prefabs-overview#publishing-prefabs). +* Once approved, the Prefab will be available for use across the Projects. An entry will appear in the Artefacts list from the Developer Utilities on the [Project Workspace.](/learn/app-development/wavemaker-overview/product-walkthrough/#project-workspace) The Prefab needs to be imported before it can be used from the Widget Toolbox. + + + +## Using Prefab inside the Project +* Open/Create a Project to use the Prefabs. +* Open the `index.html` of the Project and add the below Web Component polyfills to ensure support for all the browsers + +```html +... + + ... + + + + + +... +``` + +* Drag & Drop `AngularElementPrefab`, `ReactElementPrefab` (names may vary depending on what users have saved their prefabs with) Prefabs onto the page. + +[![](/learn/assets/howto_prefab_wc_17.png)](/learn/assets/howto_prefab_wc_17) + +* Drag & Drop a _Select_ widget into the page, & provide static list of movie title as its _Dataset_ value. We will be binding the selected title as the input for Prefabs. + +[![](/learn/assets/howto_prefab_wc_18.png)](/learn/assets/howto_prefab_wc_18) + +* Bind `Title` property value on the Prefab to value from _Select_ widget. + +[![](/learn/assets/howto_prefab_wc_19.png)](/learn/assets/howto_prefab_wc_19) + +* **Preview** & **Deploy** the application to validate Prefabs created from Angular & React Components. + +[![](/learn/assets/howto_prefab_wc_20.png)](/learn/assets/howto_prefab_wc_20) + + +## See Also + +[Prefab to compare two strings](/learn/how-tos/create-simple-prefab/) +[Prefab using 3rd Party UI Widgets](/learn/how-tos/create-prefab-using-third-party-ui-widgets/) +[Prefab Using D3 & NVD3 Charts](/learn/how-tos/create-prefab-using-d3-nvd3-charts/) +[Prefab Using D3 Library (DataMaps)](/learn/how-tos/create-prefab-using-d3-library-datamaps/) \ No newline at end of file diff --git a/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-d3-library-datamaps.md b/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-d3-library-datamaps.md new file mode 100644 index 000000000..bde764b47 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-d3-library-datamaps.md @@ -0,0 +1,549 @@ +--- +title: "Create Prefab Using D3 Library DataMaps" +id: "create-prefab-using-d3-library-datamaps" +--- +--- + +**D3.js** is a JavaScript library for producing dynamic, interactive data visualizations in web browsers. It uses widely implemented SVG, HTML5, and CSS standards and it is also known as D3 (Data-Driven Documents). + +**DataMaps** provides data visualizations based on geographical data, and it mainly relies on the `D3.js` library. DataMaps are designed based on the SVG type; thus, it can scale into any screen size. + +In this document, learn how to create a Prefab that displays **Datamaps** and use it in a project. + +[![datamap_runbasic](/learn/assets/datamap_runbasic.png)](/learn/assets/datamap_runbasic.png) + +Also, learn how to add some basic properties to edit the functionality. For example, add different colors, show bubbles, labels, and more. + +![bubbles](/learn/assets/bubbles-corona-tracker.png) + +## Creating DataMaps Prefab + +From the **Project Dashboard**, go to the **Prefab** tab and click **Create**. + +![create prefab](/learn/assets/prefab_create.png) + +Enter a name and description of the Prefab. + +### Download files + +1. Go to [DataMaps website](http://datamaps.github.io/) and download the required files from the **Downloads** section. + +:::important +We have used the following two files - [topojson min.js](/learn/assets/topojson.min_.zip) and [datamaps world min.js](/learn/assets/datamaps.world_.min_.zip). Extract files from the `downloaded-zip` files. +::: + +2. [Import the Resources](/learn/app-development/services/3rd-party-libraries). +3. Select the folder where you want the resource to import. For this example, select the `resources` folder and upload the `topojson.min.js` and `datamaps.world.min.js` files. + +[![](/learn/assets/datamap_resource.png)](/learn/assets/datamap_resource.png) + +### Project Configuration + +1. Click **Config Prefab** from the **Settings** dropdown. + +![prefab project config](/learn/assets/prefab-project-config.png) + +2. Reference the uploaded javascript files here. Ensure to add `topojson` first, and then the `datamaps` resource. + +[![](/learn/assets/datamap_settings.png)](/learn/assets/datamap_settings.png) + +### Adding UI Properties + +From the **Properties** tab, set the **UI Properties** for the Prefab to configure from an app. In this case, you add `scope` and `dataset`. For example, `scope` lets you choose a particular country map, or a world map. + +![prefab ui properties](/learn/assets/prefab-ui-properties.png) + +|Property Name | Display value | Data Type | Default value | Binding Type | Widget Type | Data Options | +|---|---|---|---|---|---|---| +|scope | Scope | string | World | | Select | World, India | +|dataset | Dataset| object | |in-bound|text || + +### Designing the UI + +Drag and drop a **Container Widget** onto the canvas, and provide a **Name**: `mapContainer`, and set the **Class Name**: `map-container`. + +[![](/learn/assets/prefab_container.png)](/learn/assets/prefab_container.png) + +### Add Custom Functions + +Go to the **Script** tab, and add the following code. + +[![](/learn/assets/datamap_script-1.png)](/learn/assets/datamap_script-1.png) + +In this example, we are using the world map and India map. Here, you can choose which map to use based on the scope property of the Prefab. + +:::note +After creating the Prefab, inside the script, you can find a few pre-defined functions. + +- `[Prefab.onPropertyChange = propertyChangeHandler;]` +- `Prefab.onReady` method will be triggered after the initialization of the prefab. The code should go here. +::: + +```js +Prefab.onPropertyChange = function(key, newVal, oldVal) { + switch (key) { + case 'dataset': + Prefab.datafield = 'name'; //hardcoded + Prefab.labelfield = 'customLabel'; //hardcoded + + generateDataset(newVal); + + if (Prefab.map) { //if map has been previously initialized + Prefab.map.options.customLabelText = {}; + resetLabels(); + + Prefab.map.options.fills = Prefab.colormap; + Prefab.map.updateChoropleth(Prefab.data, { + reset: true + }); + generateLabels(); + + if (Prefab.showbubbles) + generateBubbles(); + + if (Prefab.legend) { + $($('.datamaps-legend')).empty(); + Prefab.map.legend(); + } + } + break; + case 'colormap': + break; + default: + break; + } +}; + + +Prefab.onReady = function() { + initDataMap(); +}; + +function initDataMap() { + var mapCtr = Prefab.Widgets.mapContainer.$element[0]; + // this method will be triggered post initialization of the prefab. + if (Prefab.scope === 'world') { + initWorldMap(mapCtr); + } + // India map + if (Prefab.scope === 'india') { + initIndiaMap(mapCtr); + } + + //draw bubbles for bombs + if (Prefab.showbubbles) + generateBubbles(); + if (Prefab.legend) + Prefab.map.legend(); +} + +function initWorldMap(mapCtr) { + Prefab.map = new Datamap({ + element: mapCtr, + scope: Prefab.scope, + fills: Prefab.colormap, //Any fill key, HIGH, LOW, MEDIUM, MAJOR, MINOR + //height: Prefab.height, + //width: Prefab.width, + data: Prefab.data, + //customTemplate: Prefab.detailstemplate, + done: function(datamap) { + //datamap.svg.call(d3.behavior.zoom().on("zoom", redrawMap)); + Prefab.datamap = datamap; + //Prefab.zoom = d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoomed); + + // function redrawMap() { + // debugger + // console.log("inside refraw----", d3); + // datamap.svg.selectAll("g").attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); + // } + Prefab.datamap = datamap; + }, + geographyConfig: { + popupOnHover: Prefab.showdetails, + //highlightOnHover: Prefab.highlight ? true : false, + // highlightFillColor: Prefab.highlight, + highlightBorderColor: Prefab.highlight, + highlightBorderOpacity: 0.5, + popupTemplate: function(geography, data) { + return data["detailstemplate"]; + } + }, + responsive: true + }); + + generateLabels(); +} + +function initIndiaMap(mapCtr) { + Prefab.map = new Datamap({ + element: mapCtr, + scope: Prefab.scope, + //height: Prefab.height, + geographyConfig: { + popupOnHover: Prefab.showdetails, + highlightOnHover: true, + borderColor: '#444', + borderWidth: 0.5, + dataUrl: 'https://rawgit.com/Anujarya300/bubble_maps/master/data/geography-data/india.topo.json', + highlightBorderColor: Prefab.highlight, + highlightBorderOpacity: 0.5, + popupTemplate: function(geography, data) { + return data["detailstemplate"]; + } + }, + fills: Prefab.colormap, + data: Prefab.data, + done: function(datamap) { + }, + setProjection: function(element) { + var lat, lon, scaleval; + if (window.matchMedia("screen and (max-width: 480px)").matches) { + lat = 118.9629; + lon = 23.5937; + scaleval = 500; + } else if (window.matchMedia("screen and (max-width: 640px)").matches) { + lat = 96.9629; + lon = 23.5937; + scaleval = 700; + } else if (window.matchMedia("screen and (max-width: 800px)").matches) { + lat = 104.9629; + lon = 23.5937; + scaleval = 650; + } else if (window.matchMedia("screen and (max-width: 1200px)").matches) { + lat = 96.9629; + lon = 23.5937; + scaleval = 750; + } else { + lat = 84.9629; + lon = 23.5937; + scaleval = 1000; + } + var projection = d3.geo.mercator() + .center([lat, lon]) // always in [East Latitude, North Longitude] + .scale(scaleval); + var path = d3.geo.path().projection(projection); + return { + path: path, + projection: projection + }; + }, + responsive: true + }); + generateLabels(); +} + +//generate dataset for datamap, call on property init() +function generateDataset(dset) { + if (Prefab.scope === 'india') { + Prefab.data = {}; + } else { + Prefab.data = []; + } + Prefab.labeldata = {}; + if (dset && Prefab.datafield) { + var mainKey = []; + var field = Prefab.datafield.split('.'); + var lblfield = Prefab.labelfield.split('.'); + _.forEach(dset, function(value, key) { + mainKey = field.length > 1 ? value[field[0]][field[1]] : value[field[0]]; + Prefab.data[mainKey] = value; + var labelKey = lblfield.length > 1 ? value[lblfield[0]][lblfield[1]] : value[lblfield[0]]; + if (labelKey) + Prefab.labeldata[mainKey] = labelKey; + }); + } +} +``` + +- Now, the Prefab should be ready for use. + +### Publish the Prefab + +1. Save and **Publish** the Prefab. +2. You can set the version for the Prefab and Publish it. For more information about publishing Prefabs, see [Publish Prefab](/learn/app-development/custom-widgets/creating-prefabs/#publish-prefab). +3. The Prefab will be available for use across the Projects. You can see the entry in the [Artefacts](/learn/assets/artifactsAccess.png) list and in the Widget Toolbox of any Project within your workspace. + +## Using the DataMaps Prefab + +1. Open the project where you want to include the Datamaps Prefab which you created. +2. You can find the new Prefab in the **Prefabs** section. + +[![](/learn/assets/datamap_toolbar.png)](/learn/assets/datamap_toolbar.png) + +3. Drag and drop the Prefab onto the canvas and set the height to auto and width to 100%. +4. Set the scope as World or India. + +### Adding the Data + +To add the Dataset, create a variable. For example, you can create a CRUD variable, add a Web Service, or create a model variable. For this example, we are using a model variable derived from a web service variable. For more information to add variable, see [Variable](/learn/app-development/variables/variables). + +#### Example data + +**Data for World map** + +```json +[ + { + "name": "RUS", + "fillKey": "RUS", + "latitude": 61.52401, + "longitude": 105.318756, + "radius": 25, + "customLabel": "2361", + "detailstemplate": "2361$" + }, + { + "name": "IND", + "fillKey": "IND", + "latitude": 20.593684, + "longitude": 78.96288, + "radius": 25, + "customLabel": "5456", + "detailstemplate": "5456$" + }, + { + "name": "GBR", + "fillKey": "GBR", + "latitude": 55.378051, + "longitude": -3.435973, + "radius": 25, + "customLabel": "123", + "detailstemplate": "4894$" + }, + { + "name": "FRA", + "fillKey": "FRA", + "latitude": 46.227638, + "longitude": 2.213749, + "radius": 25, + "customLabel": "145", + "detailstemplate": "4456$" + }, + { + "name": "USA", + "fillKey": "USA", + "latitude": 37.09024, + "longitude": -95.712891, + "radius": 25, + "customLabel": "4231", + "detailstemplate": "4231$" + } +] +``` + +**Data for India Map**: + +```json +{ + "JH":{ + "fillKey":"MINOR", + "detailstemplate":"2361$" + }, + "MH":{ + "fillKey":"MINOR", + "detailstemplate":"5456$" + } +} +``` + +:::note +Do not change the structure of the dataset. Use the above data format. +::: + +8. Run the app and see the map displayed. + +[![datamap_runbasic](/learn/assets/datamap_runbasic.png)](/learn/assets/datamap_runbasic.png) + +## Editing or Adding More Functions + +Now that we have seen the usage of a basic datamap. Now, let us add some more properties to the Prefab which can add bubble and labels. + +These can be bound from the project containing the Prefab. + +1. From the **Project Dashboard**, go to the **Prefab** tab and click **Create**. + +2. Click **Config Prefab** from the **Settings** dropdown. + +![prefab project config](/learn/assets/prefab-project-config.png) + +### Adding More UI Properties + +From the **Properties** tab, set the **UI Properties** for the Prefab to configure from an app. + +![prefab ui properties](/learn/assets/prefab-ui-properties.png) + +| Name | Display Value | Data Type | Default Value | Binding Type | Widget Type | Data Options | +| --- | --- | --- | --- | --- | --- | --- | +|colormap|Color map|object||in-bound|text|| +show|Show|boolean|true|in-bound|checkbox|| +|highlight|Highlight|string|#46C8FF|in-bound|colorpicker|| +|height|Height|string|||text|| +|width|Width|string|||text|| +|bubblecolor|Bubblecolor|string|#ffc0cb|in-bound|text|| +|showbubbles|Showbubbles|boolean|false|in-bound|text|| +|legend|Legend|boolean|false|in-bound|text|| + +### Additional Custom Functions + +Go to the **Script** tab, and add the following lines code which adds new functions; these functions were referenced in the [example-code above](#add-custom-functions). It adds additional ability to display the label and bubbles on the Datamaps Prefab. + +```js +function resetLabels() { + var stdLabelKeys = {}; + if (Prefab.scope === 'india') { + stdLabelKeys = _.keys(Prefab.Variables.indiaStateCodes.dataSet); + } else { + stdLabelKeys = Prefab.datamap.worldTopo.objects.world.geometries; + } + + var labels = {}; + _.forEach(stdLabelKeys, function(value) { + var key = (Prefab.scope === 'india') ? value : value.id; + labels[key] = ' '; + }); + Prefab.map.labels({ + 'customLabelText': labels + }); + $($('.labels')).empty(); + +//generates custom labels for countries +function generateLabels() { + var stdLabelKeys = {}; + if (Prefab.scope === 'india') { + stdLabelKeys = _.keys(Prefab.Variables.indiaStateCodes.dataSet); + } else { + stdLabelKeys = Prefab.datamap.worldTopo.objects.world.geometries; + } + + if (Prefab.labeldata) { + var countryList = {}, + labelKeys = []; + //get all keys from the label data + _.forEach(Prefab.labeldata, function(value, key) { + labelKeys.push(key); + }); + //get all countries to prepare the list of key and value for labels + _.forEach(stdLabelKeys, function(value) { + var key = (Prefab.scope === 'india') ? value : value.id; + _.includes(labelKeys, key) ? countryList[key] = key : countryList[key] = ' '; + }); + Prefab.map.labels({ + 'customLabelText': countryList + }); + } +} + +function generateBubbles() { + if (Prefab.scope === 'india' && Prefab.dataset) { + const bubblearray = []; + _.forEach(Prefab.dataset, function(obj) { + bubblearray.push(obj); + }); + + Prefab.map.bubbles(bubblearray, { + popupOnHover: true, + highlightOnHover: Prefab.bubblecolor ? true : false, + highlightFillColor: Prefab.bubblecolor, + highlightBorderColor: Prefab.bubblecolor, + highlightBorderOpacity: 0.4, + popupTemplate: function(geo, data) { + return data["detailstemplate"]; + } + }); + } else { + Prefab.map.bubbles(Prefab.dataset, { + popupOnHover: true, + highlightOnHover: Prefab.bubblecolor ? true : false, + highlightFillColor: Prefab.bubblecolor, + highlightBorderColor: Prefab.bubblecolor, + highlightBorderOpacity: 0.3, + popupTemplate: function(geo, data) { + return data["detailstemplate"]; + } + }); + } +} +``` + +### Save and Publish + +Save and [publish](/learn/app-development/custom-widgets/creating-prefabs/#publish-prefab) the prefab. Now, the Prefab is ready for use with additional functionalities. + +## Using Prefab with Additional Functionality + +Now that you have made changes to the Prefab, we have to include these changes in the Project using the Prefab. There are two ways to achieve this. + +1. Update in Prefab in Project +2. Publish Prefab with an updated version + +### Update Prefab in Project + +1. From the Prefab, select Update Prefab in Project under the Export option and select the Project using the Prefab. + +[![](/learn/assets/datamap_update.png)](/learn/assets/datamap_update.png) + +2. Open the Project where Prefab was incorporated earlier. +3. You will see a dialog saying the updated version is available for usage. You can choose to **Revert** to the published version or **Continue** with the updated version. Click **Continue** to see the updated version. +4. You will see the Prefab in the Toolbox with **MOD** status indicating that it is the modified version. +5. You need to Publish the Prefab to get the updated version in the Artifacts. + +### Publish Prefab + +1. Publish the Prefab and increment the version number. +2. Open the Project where Prefab was incorporated earlier. +3. You will see a dialog saying the updated version is available for use. Thus, **Update** and **Reload**. + +You will find new properties displayed in the Properties panel. + +### Adding New Variable + +To set the colormap property, we will be using a **[Model Variables](/learn/assets/var_sel.png)** for ColorMap. As an example you can use the following. + +#### Colormap Variable + + +Data for the World map + +```json +{ + "USA": "#1f77b4", + "RUS": "#9467bd", + "IND": "#e377c2", + "GBR": "#8c564b", + "FRA": "#d62728", + "defaultFill": "#EDDC4E" +} +``` + +Data for India map + +```json +{ + "LOW": "FADCD9", + "MINOR": "#F8AFA6", + "MODERATE": "#FE8181", + "HIGH": "#FE5757", + "SEVERE": "#FE2E2E", + "CRITICAL": "#CB2424", + "defaultFill": "#dddddd" +} +``` + +[![](/learn/assets/colormap_var.png)](/learn/assets/colormap_var.png) + +- Bind ColorMaps Variable to the Colormap Property. +- Set ShowBubbles property to true. + + +[![](/learn/assets/datamap_bind.png)](/learn/assets/datamap_bind.png) + +Run the app, you can see the countries color-coded, along with the labels and bubbles. + +![bubbles](/learn/assets/bubbles-corona-tracker.png) + +## See Also + +[Prefab to compare two strings](/learn/how-tos/create-simple-prefab/) +[Prefab using 3rd Party UI Widgets](/learn/how-tos/create-prefab-using-third-party-ui-widgets/) +[Prefab Using D3 & NVD3 Charts](/learn/how-tos/create-prefab-using-d3-nvd3-charts/) +[Prefab Using JQuery Plugin - showcases using Events and Methods](/learn/how-tos/create-prefab-using-jquery-plugin/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-d3-nvd3-charts.md b/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-d3-nvd3-charts.md new file mode 100644 index 000000000..3645a8c8f --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-d3-nvd3-charts.md @@ -0,0 +1,255 @@ +--- +title: "Create Prefab Using D3 & NVD3 Charts" +id: "create-prefab-using-d3-nvd3-charts" +--- +--- + +D3 allows you to bind arbitrary data to a Document Object Model (DOM), and then apply data-driven transformations to the document. For example, you can use D3 to generate an HTML table from an array of numbers. Or, use the same data to create an interactive SVG bar chart with smooth transitions and interaction. The chart widgets which are offered by WaveMaker are based out of NVD3 charts, which are re-usable charts for D3 charts. and as such implementing any of the NVD3 & D3 charts becomes easy. Here we will see two simple examples - [line chart (D3)](#creationd3) and [line plus bar chart (NVD3)](#creationnvd3). + +## Implementing D3 Charts + +We will see the implementation of a simple d3 line chart using [the following example](http://www.sitepoint.com/creating-simple-line-bar-charts-using-d3-js/). + +:::note +This implementation is for D3 version: 3.5.17 charts. +::: + +1. Click on **Create** from the _Prefab_ tab of the [Project Dashboard](/learn/app-development/wavemaker-overview/product-walkthrough#dashboard-walkthrough) +2. Enter a name and description for the Prefab +3. **SAVE** the project setting without making any changes +4. Open the **SCRIPT** tab of the Main page + + - Add a variable `var data = [];` + - Add the following code to the **propertyChangeHandler** function. This code is taking the input data in the form of an object and generating the values to be represented on the sale- and year- attributes for the chart. **The input object, according to the below code snippet, is expected to have at least two fields named budget and year**. We are using this since in implementation we will show binding the chart to Department database. + + ```js + function propertyChangeHandler(key, newVal, oldVal) { + switch (key) { + case "dataset": + // debugger; + var year = 2000; + _.each(newVal.data, function (obj) { + data.push({ + "sale": obj.budget / 10000, + "year": year + }); + + year += 1; + }); + renderChart(); + break; + case "prop2": + // do something with newVal for property 'prop2' + break; + } + } + /* register the property change handler */ + Prefab.onPropertyChange = propertyChangeHandler; + ``` + - Enter the following code (you can copy and paste the same). This code is to set up the visual rendering of D3 chart. + + ```js + function renderChart() { + var vis = d3.select("#visualisation"), + WIDTH = 1000, + HEIGHT = 1000, + MARGINS = { + top: 20, + right: 20, + bottom: 20, + left: 50 + }, + xScale = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([2000, 2004]), + yScale = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([0, 350]), + xAxis = d3.svg.axis() + .scale(xScale), + yAxis = d3.svg.axis() + vis.append("svg:g") + .attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")") + .call(xAxis); + yAxis = d3.svg.axis() + .scale(yScale) + .orient("left"); + vis.append("svg:g") + .attr("transform", "translate(" + (MARGINS.left) + ",0)") + .call(yAxis); + var lineGen = d3.svg.line() + .x(function(d) { + return xScale(d.year); + }) + .y(function(d) { + return yScale(d.sale); + }); + vis.append('svg:path') + .attr('d', lineGen(data)) + .attr('stroke', 'green') + .attr('stroke-width', 2) + .attr('fill', 'none'); + ``` + + - Invoke the above function when Prefab loads: + + ```js + Prefab.onReady = function() { + renderChart(); + } + ``` + + [![](/learn/assets/d3_js.png)](/learn/assets/d3_js.png) + +5. In the **MARKUP** tab add the following code within the _wm-content_ tag: + + [![](/learn/assets/d3_html.png)](/learn/assets/d3_html.png) + ``` + + ``` + +6. [Import Resource](/learn/app-development/services/3rd-party-libraries), to import the [d3-min js](/learn/assets/d3-min.zip) file (download and extract the file) into the Resource folder of your Prefab. + +[![](/learn/assets/d3_import.png)](/learn/assets/d3_import.png) + +7. From [Project Configurations](/learn/app-development/wavemaker-overview/product-walkthrough/#project-workspace), choose Config Prefab under Settings: + - From Resources, add the js files + + [![](/learn/assets/d3_resource.png)](/learn/assets/d3_resource.png) + +:::note +You can expose many properties and set the values as static or dynamic to be bound. For details of the properties that can be exposed refer to the [D3 website](https://d3js.org/). +::: + +- **Add Property** - **dataset** with attributes _Widget_ set to **text**, _Type_ set to **object** (type it, if not selectable) and _Bindable_ set to **in-bound** + + [![](/learn/assets/d3_props.png)](/learn/assets/d3_props.png) + +8. You can set the display icon and mention the group for Prefab from the Packaging tab +9. You can publish the Prefab to a project for testing or publish it to EDN for making it available across the enterprise. +10. Save and Publish the Prefab. You can set the version for the Prefab and Publish it. Know more about publishing Prefabs from [here](/learn/app-development/custom-widgets/prefabs-overview#publishing-prefabs). +11. Once approved by the EDN Admin, the Prefab will be available for use across the Projects. You can see the entry in the Artifacts list from the Developer Utilities on the [Project Workspace](/learn/app-development/wavemaker-overview/product-walkthrough/#project-workspace). Import it to see the same in the Widget Toolbox of any Project within your workspace. + +## Using D3 Charts Prefab + +1. Open the app, where you want to incorporate this Prefab. +2. If you have published to the app, in the **Prefab section of the toolbox** on the left, you will see the newly imported Prefab. +3. Drag and drop the Prefab onto the canvas and Bind its dataset property. For this example, we have bound it to the HrdbDepartmentData dataset, which is available on the [import of sample database](/learn/app-development/services/database-services/working-with-databases/) + +[![](/learn/assets/d3_bind.png)](/learn/assets/d3_bind.png) + +4. **Preview** the app + +## Implementing NVD3 Charts + +In the previous section, we have seen a simple implementation using D3 Chart. This section we will see the implementation of NVD3 charts. **NVD3** is wrapper upon D3 which simplifies the implementation when compared to D3. These can also be incorporated easily into WaveMaker applications. In this section, we will see how to implement the Line Plus Bar Chart as [seen here](http://nvd3.org/examples/linePlusBar.html). + +:::note +his implementation is for NVD3 version: 1.8.4 charts. +::: + +1. Click on **Create** from the _Prefab_ tab of the [Project Dashboard](/learn/app-development/wavemaker-overview/product-walkthrough#dashboard-walkthrough) +2. Enter a name and description for the Prefab +3. **SAVE** the project setting without making any changes +4. [Import Resource](/learn/app-development/services/3rd-party-libraries) to import the following resource files: [nv-d3-min](/learn/assets/nv-d3-min.zip) & [nv-d3 file](/learn/assets/nv.d3.zip) into the Resource folder of your Prefab (download and extract the files). [![](/learn/assets/nvd3_import.png)](/learn/assets/nvd3_import.png) +5. Open the **SCRIPT** tab of the Main page +6. Enter the following code (you can copy and paste the same). This code generates the sin and cosine values that can be represented on the chart. Note that for the sin values, the bar attribute is set to true, thus the sine values are represented as bar chart while cosine values are represented as line graph. [Click here for the code](/learn/assets/nvd3_linegraph.txt). + + Enter the following function, too, within **Prefab.onReady** function after the above code. This code is to set up the visual rendering of NVD3 chart. [Click here for the code](/learn/assets/nvd3_onReady.txt) + + [![](/learn/assets/nvd3_js1.png)](/learn/assets/nvd3_js1.png) + +7. In the **MARKUP** tab add the following code within the _wm-content_ tag: + + [![](/learn/assets/nvd3_html.png)](/learn/assets/nvd3_html.png) + +```html + +``` + +8. **Preview** the app. + + [![](/learn/assets/nvd3_run.png)](/learn/assets/nvd3_run.png) + + Try selecting a part of the graph from the bottom miniature graph and see the UI changes +9. To be used as the Prefab, it would be nice to bind the data to an object in the app using the Prefab instead of static graph display. Next couple of steps will help do the same. + +10. From [Project Configurations](/learn/app-development/wavemaker-overview/product-walkthrough/#project-workspace), choose Config Prefab under Settings: + + - From Resources, include the script and css files imported earlier, you can pick from the drop down list + + [![](/learn/assets/nv_d3_library.png)](/learn/assets/nv_d3_library.png) + + OR, You can instead include http url in place of script and style files: https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.4/nv.d3.css https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.4/nv.d3.min.js + + + +:::note +You can expose many properties and set the values as static or dynamic to be bound. For details of the properties that can be exposed refer to the [NVD3 website](http://nvd3.org/). +::: + +- **Add property dataset**, with **text** as _widget_, **array** (type if not selectable) as _type_ and **in-bound** as the _bindable_ attributes. + + [![](/learn/assets/nvd3_props.png)](/learn/assets/nvd3_props.png) + + - Add the following code to the **propertyChangeHandler** function. This function is triggered when the Prefab property changes in the incorporated app. This replaces the data built in the onInitPrefab function. Here, instead of taking static data, we are using the object passed to the Prefab to calculate the values to be represented on the x- and y-axis. **The input object, according to the below code snippet, is expected to have two fields budget and q1**. We are using this since in the app incorporating this Prefab we will see the binding with Department database. Add the following variable declaration: + + ```js + var data = [], + sin = [], + cos = []; + + switch (key) { + case "dataset": + // debugger; + _.each(newVal.data, function(obj, index) { + sin.push({ + "y": obj.budget, + "x": index + }); + cos.push({ + "y": obj.q1, + "x": index + }); + + }); + + data = [{ + values: sin, + bar: true, + key: 'Sine Wave', + color: '#ff7f0e' + }, { + values: cos, + key: 'Cosine Wave', + color: '#2ca02c' + }]; + + break; + case "prop2": + // do something with newVal for property 'prop2' + break; + } + } + ``` + + [![](/learn/assets/nvd3_js1.png)](/learn/assets/nvd3_js1.png) + + - You can publish the Prefab to a project for testing or publish it to EDN for making it available across the enterprise. + - Save and Publish the Prefab. You can set the version for the Prefab and Publish it. Know more about publishing Prefabs from [here](/learn/app-development/custom-widgets/prefabs-overview#publishing-prefabs). + - Once approved by the EDN Admin, the Prefab will be available for use across the Projects. You can see the entry in the Artifacts list from the Developer Utilities on the [Project Workspace](/learn/app-development/wavemaker-overview/product-walkthrough/#project-workspace). Import it to see the same in the Widget Toolbox of any Project within your workspace. + +## Using NVD3 Charts Prefab + +1. Open the app, where you want to incorporate this Prefab +2. Since we published the Prefab, in the **Prefab section of the toolbox** on the left, you will see the newly imported Prefab +3. **Drag and drop the Prefab** onto the canvas and bind its **dataset** property. For this example, we have bound it to the _HrdbDepartmentData dataset_, [created from the Database CRUD APIs](/learn/assets/var_sel.png) available on the [import of sample database](/learn/app-development/services/database-services/working-with-databases/) + +[![](/learn/assets/nvd3_bind.png)](/learn/assets/nvd3_bind.png) + +4. **Preview** the app. + + [![nvd3_app_run](/learn/assets/nvd3_app_run.png)](/learn/assets/nvd3_app_run.png) + +## See Also + +[Prefab to compare two strings](/learn/how-tos/create-simple-prefab/) +[Prefab using 3rd Party UI Widgets](/learn/how-tos/create-prefab-using-third-party-ui-widgets/) +[Prefab Using D3 Library (DataMaps)](/learn/how-tos/create-prefab-using-d3-library-datamaps/) +[Prefab Using JQuery Plugin - showcases using Events and Methods](/learn/how-tos/create-prefab-using-jquery-plugin/) diff --git a/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-jquery-plugin.md b/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-jquery-plugin.md new file mode 100644 index 000000000..c4f07a707 --- /dev/null +++ b/website/versioned_docs/version-v11.8.5/how-tos/create-prefab-using-jquery-plugin.md @@ -0,0 +1,361 @@ +--- +title: "Create Prefab using JQuery Plugin" +id: "create-prefab-using-jquery-plugin" +--- +--- +This post walks you through the creation and usage of a Prefab using JQuery Plugin. This is to showcase the use of Events and Methods in a Prefab. + +Let us create a simple Prefab named TreeView which is interactive. We are going to use a JQuery plugin named `jsTree`. jsTree is a JQuery plugin, that provides interactive trees. jsTree is easily extendable, theme-able and configurable, it supports HTML & JSON data sources and AJAX loading. + +## Creating the Prefab + +From the **Project Dashboard**, go to the **Prefab** tab and click **Create**. + +![create prefab](/learn/assets/prefab_create.png) + +Enter a name and description of the Prefab. For example, TreeView2. + +### Download files + +Download the jsTree JQuery Plugin from [https://www.jstree.com/](https://www.jstree.com/). Unzip the file downloaded and use the files from the dist folder. + +![jstree_prefab_download](/learn/assets/jstree_prefab_download.png) + +From [File Explorer](/learn/app-development/services/3rd-party-libraries) add the JS and CSS files from the downloaded dist folder. Here we have created a folder `jsTree` to hold the same structure as the dist folder. + +![jstree_prefab_import](/learn/assets/jstree_prefab_import.png) + +### Project Configuration + +1. Click **Config Prefab** from the **Settings** dropdown. + +![prefab project config](/learn/assets/prefab-project-config.png) + +2. In the **Resources** tab, choose the css and js files. + +![jstree_prefab_resources](/learn/assets/jstree_prefab_resources.png) + +3. In the **Properties** tab, add an **inbound** property as an object, array (type if not selectable) which should consist of parent and child node names: + +![jstree_prefab_inbound](/learn/assets/jstree_prefab_inbound.png) + +4. In the **Events** tab, add events to be triggered when a node is Selected, Deselected, Expanded or Collapsed. + +:::note +By default, two events are already given - Load and Destroy. +::: + +![jstree_prefab_events](/learn/assets/jstree_prefab_events.png) + +5. In the **Methods** tab, add the following methods: + +- **SelectNode**: Method to select a node + - Parameters: Node, Type: any + - Return type: void +- **Redraw**: Method to redraw the whole tree + - Return type: void +- **selectAllNodes**: Method to select all Nodes + - Return type: void +- **deselectAllNodes**: Method to deselect all nodes + - Return type: void +- **deselectNode**: Method to deselect a node + - Parameters: Node, Type: any + - Return type: void + +![jstree_prefab_methods](/learn/assets/jstree_prefab_methods.png) + +## Custom Functions + +Once these properties, methods, and events are added to Prefab configuration in the Prefab Script the Method snippets will be auto-generated. You can fill with the code for the same. + +![jstree_prefab_script](/learn/assets/jstree_prefab_script.png) + +The following is the script for all methods. + +### Declare a variable + +```js +var treeMapInstance; + +Property Change event: + +Prefab.onPropertyChange = function(key, newVal, oldVal) { + switch (key) { + case "treedata": //UI Property for the node array + initJStreeView(); + break; + case "multiple": + case "dots": + _redraw(); + break; + } +}; +``` + +### Function to initialize the tree view + +```js +function initJStreeView() { + var treeViewELe = Prefab.Widgets.treeViewContainer.$element; + treeViewELe.jstree({ + core: { + multiple: true, + themes: { + dots: true, + }, + data: Prefab.treedata + } + }); + treeMapInstance = Prefab.Widgets.treeViewContainer.$element.jstree(true); + // treeViewELe.on("changed.jstree", function(node, action, selected, event) { + // console.log("The selected nodes are:"); + // console.log(action.selected); + // }); + + // select event + treeViewELe.on("select_node.jstree", function(e, data) { + Prefab.onSelect(e, data); + }); + + // deselect event + treeViewELe.on("deselect_node.jstree", function(e, data) { + Prefab.onDeselect(e, data); + }); + + // expand event + treeViewELe.on("open_node.jstree", function(e, data) { + Prefab.onExpand(e, data); + }); + + // collapse event + treeViewELe.on("close_node.jstree", function(e, data) { + Prefab.onCollapse(e, data); + }); +} +``` + +### Function to redraw the tree view + +```js + function _redraw() { + if (treeMapInstance) { + treeMapInstance.redraw(); + } + } + + Methods for the tree: + + /* + * Method to select all nodes + */ + Prefab.selectAllNodes = function() { + if (treeMapInstance) { + treeMapInstance.select_all(); + } + }; + + /* + * Deselect all nodes + */ + Prefab.deselectAllNodes = function() { + if (treeMapInstance) { + treeMapInstance.deselect_all(); + } + }; + + /* + * Method for selecting a node in the tree by id. + * preventOpen: If set to true parents of the selected node won't be opened + */ + Prefab.selectNode = function(node, preventOpen) { + if (treeMapInstance) { + treeMapInstance.select_node(node, false, preventOpen); + } + }; + + /* + * Method for deselecting a node in the tree. + */ + Prefab.deselectNode = function(node) { + if (treeMapInstance) { + treeMapInstance.deselect_node(node); + } + }; + + /* + * Re Draws the whole tree + */ + Prefab.redraw = function() { + _redraw(); + } +``` + +### Add Container tag + +Add a `wm-container tag` with the name **treeViewContainer** in the Markup, as follows: + +```js + +``` + +![jstree_prefab_html](/learn/assets/jstree_prefab_html.png) + +## Publish the Prefab + +1. Save and **Publish** the Prefab. +2. You can set the version for the Prefab and Publish it. For more information about publishing Prefabs, see [Publish Prefab](/learn/app-development/custom-widgets/creating-prefabs/#publish-prefab). +3. The Prefab will be available for use across the Projects. You can see the entry in the ![Artifacts](/learn/assets/artifact-sharing/artifacts-access.png) list and in the Widget Toolbox of any Project within your workspace. + +## Using the Prefab in Project + +1. Let us now use the above-created Prefab in an application. +2. We are using the WaveMaker non-enterprise version and have Published the Prefab to Workspace. +3. Create or Open an application. +4. You can see the Prefab in the Prefab Listing. +5. On the Main page drag and drop the TreeView2 Prefab. + +![jstree_prefab_appdnd](/learn/assets/jstree_prefab_appdnd.png) + +### Invoking Prefab Methods in Project + +The prefab has exposed methods which can be triggered by the application as shown below. + +1. To call the exposed methods, drag and drop **four Button Widgets** in the main page under the Prefab and give the **captions** for the buttons as `SELECT ALL`, `SELECT NODE`, `DESELECT NODE` and `DESELECT ALL`. We have **named** the buttons as `selectAll`, `selectNode`, `deselectNode` and `deselectAll`. +2. Create an `On Click` event for each button. + +![jstree_prefab_appmethods](/learn/assets/jstree_prefab_appmethods.png) + +3. This will create the snippet for the `