Revolutionizing ServiceNow Portals with FC Core Page Builder

Posted by admin on October 22, 2024

Anatomy of a Page

Description

FC pages are structured similarly to ServiceNow widgets, encapsulating the template, client script, and server script into a unified entity. Adopting the MVC (Model-View-Controller) approach, the server script generates the model object, which is passed to the client for manipulation or transformation. The transformed data is then rendered through the template for presentation.

Server Script Overview


This server script is designed to execute automatically when the page is requested, initializing a model that helps control access to the page based on the current logged-in user. The script uses URL parameters (params) to pass additional data, if needed.

(function (params) {

	function initialize() {
		var model = {
			condition: true
		};
		return model;
	}


	return {
		initialize: initialize
	};

})(params);

Key Components

  • Immediately-Invoked Function Expression (IIFE): The script is encapsulated in an IIFE, meaning it runs immediately when the page is requested. This prevents global variable conflicts and ensures the logic is contained.
  • initialize Method: The initialize method is executed automatically during the page load. It generates a model object with a condition property. This property is intended for developers to set access control rules, determining whether the current logged-in user has permission to view the page. For example, developers can modify the condition based on user roles or other business logic to restrict or grant access.
  • Additional Methods: Developers can implement additional methods within the server script. Any method included as part of the returned object (along with initialize) can be directly called from the client script. This allows developers to execute server-side logic from the client script when needed, providing flexibility and extending the functionality of the page.

Return Object

The script returns an object containing the initialize method and any additional methods you implement. These methods, if included in the returned object, can be invoked directly from the client script. This setup facilitates seamless communication between the client and server, allowing the client script to make requests to the server script as needed.

The params parameter, representing data from the URL, can be used in conjunction with user information to adjust logic dynamically within both the initialize method and any other implemented methods.

Client Script Overview


The client script contains an execute function, which is automatically invoked when the page loads. It provides methods that can be accessed and used within the template.

function execute(helpers){
    function myFunction(){
        return 'Hello World!';
    }

    return {
        myFunction: myFunction
    };
}

Key Components

  • execute Method: This function is called when the page is loaded, and it receives a helpers parameter. The helpers object is populated by the Angular component. It contains useful references like service, model, id, and recordWatch, which can be utilized in the script.
  • myFunction Method: Inside the execute method, a sample function myFunction is defined, which returns the string "Hello World!". Any method returned from the execute function (such as myFunction) becomes available to the template, allowing for direct interaction within the view.

Key Parameters

  • helpers Object: The helpers parameter is an object passed from the Angular component, containing several key elements that can be used within the execute method.
    • service: This represents an exposed service used to interact with other parts of the application or to execute business logic.
      • call(methodName: string, parameters: any[] = [], pageId: string): Calls a server-side method via a REST API, allowing client scripts to execute actions on the server.
      • search(query: any): Updates the URL with the given query parameters for search functionality.
      • navigateToPage(pageId: string, queryParams: any = ): Navigates to a specific page with optional query parameters.
      • navigate(url: string): Navigates directly to a specific URL.
      • snackbar(message: string): Displays a message to the user using a Snackbar UI component.
      • showLoading() / hideLoading(): Toggles the loading indicator for user feedback.
      • confirm(message: string): Opens a confirmation dialog with the given message, returning an observable that resolves to the user's response (confirm or cancel).
      • postAsync(url: string, payload: any) / getAsync(url: string): Performs asynchronous HTTP POST and GET requests, allowing for flexible interactions with external data sources.
    • model: This is a copy of the model object returned from the server script. Its main purpose is for initialization only and does not represent the actual model used by the template. This separation allows the client script to perform initial data setup without affecting the data structure used directly by the template.
    • id: The sys_id of the current page, used to reference or perform actions specific to the page's identity.
    • recordWatch: An optional parameter used to monitor changes to records, allowing real-time updates or additional dynamic interactions when data changes.

Return Object

The execute method returns an object with methods, such as myFunction, that can be accessed and used in the template. The use of the helpers parameter ensures that the client script has access to important contextual information and services, while keeping the model for initialization purposes separate from the model used in the template.

Example Usage of call Method Calls a server-side method via REST API.

call(methodName: string, parameters: any[] = [], pageId?: string)

service.call('getPageData', ['param1', 'param2'], 'page123')
    .then(response => {
        console.log('Success:', response);
    })
    .catch(error => {
        console.error('Error:', error);
    });

OR

 try {
        const response = await service.call('getPageData', ['param1', 'param2'], 'page123');
        console.log('Success:', response);
    } catch (error) {
        console.error('Error:', error);
    }

In the example above, 'getPageData' is a method returned from the server script.

Example Usage of search Method Navigates to a specific page, optionally passing query parameters.

search(query: any)

const searchQuery = { term: 'keyword', filter: 'active' };
service.search(searchQuery);

Example Usage of navigateToPage Method Navigates to a specific page, optionally passing query parameters.

navigateToPage(pageId: string, queryParams: any = )

service.navigateToPage('page456', { section: 'overview', userId: 'user789' });

Example Usage of navigate Method Navigates directly to a URL.

navigate(url: string)

service.navigate('?id=home');

Example Usage of snackbar Method Displays a message in a Snackbar UI component.

snackbar(message: string)

service.snackbar('Data saved successfully!');

Example Usage of showLoading/hideLoading Method Shows a loading indicator/Hides the loading indicator

service.showLoading() service.hideLoading();

service.showLoading();
// Some async operation
service.hideLoading();

Example Usage of confirm Method Displays a confirmation dialog with a message and returns an observable with the user's response.

confirm(message: string): Observable<boolean>

service.confirm('Are you sure you want to delete this item?').subscribe(result => {
    if (result) {
        console.log('User confirmed');
    } else {
        console.log('User canceled');
    }
});

Example Usage of postAsync Method Sends an asynchronous POST request with a payload.

postAsync(url: string, payload: any)

const payload = { name: 'John Doe', role: 'admin' };
service.postAsync('/api/user/create', payload)
    .then(response => {
        console.log(response);
    });
```

Example Usage of getAsync Method Sends an asynchronous GET request to retrieve data.

getAsync(url: string)

service.getAsync('/api/user/list')
    .then(response => {
        console.log(response);
    });

Template Overview

This template is designed to create a dynamic, interactive interface using Alpine.js for reactivity. This template is structured to maximize reactivity and data flow between the client-side and server-side scripts, using Alpine.js to manage interactivity. By encapsulating data and methods in the $scope variable, it simplifies the flow of information between the server and the user interface. The design allows for dynamic rendering and filtering, creating an interactive and responsive user experience.

Key Components of the Template

  • Alpine.js for Reactivity: The template leverages Alpine.js to provide dynamic interactivity within the HTML. All the data and methods used in the template are encapsulated in the $scope variable, making it easy to reference and manipulate.
  • Bootstrap for Responsive Layout: The template uses the latest version of Bootstrap for responsive grid-based layout and modern UI components. This ensures that the design works across various screen sizes and devices, providing a polished and professional look.

Click for more information on AlpineJS, Bootstrap 5

Copyright © Formcloud LLC 2024