Table of Contents
< All Topics
Print

Views

Views are used for the Gnosis no-code App, custom User Interface, Application Logic, and Web API.

Gnosis Identity Permissions manage Access Control to views. To render or execute the View, a User must be a Member of the Identity granted Permission.

View Name

The View Name can be any string of letters, digits, spaces, underscores, and dashes but cannot be empty or whitespace only. However, several names are reserved and used for specific purposes. In addition, Gnosis automatically generates several standard names.

Reserved View Names

Standard View Names

  • All Sub-types
  • Archived
  • Import
  • Items
  • New
  • Read
  • SideDetails
  • Update

Action Views

Item Type Views with an Action keyword prefix are shown as Action menu items for the Gnosis no-code Items View.

Views with the ItemAction prefix keyword are also shown as Action menu items when one or more rows are selected for the Gnosis no-code Items View.

Documenting Gnosis Script Views

Views can be documented using the Gnosis Script Documentation comment directives.

Custom Type View

Custom-type Views are used to create custom Application Logic.

Custom-type Views with gs and gshtml format can be called with the Web GET method.

The Gnosis v1 Web API endpoint to GET gs and gshtml Views:

/api/View/Content/{SolutionName}[.{ItemTypeName}].{ViewName}

Custom-type Views with gsAction format can be called with Web POST and PUT methods.

The Gnosis v1 Web API endpoint to POST/PUT gsAction Views:

/api/View/Action/{SolutionName}[.{ItemTypeName}].{ViewName}

The Gnosis v2 Web API endpoint to GET gs and gshtml Views, and POST/PUT gsAction Views:

/v2/View/{SolutionName}[.{ItemTypeName}].{ViewName}

Solution and Item Type Static Functions

Gnosis Script Views are Solution—and Item-Type Static functions that can be called in Gnosis Script, similar to Expression-type properties, which are also Item-Type Static functions.

The Gnosis Identities Permissions on the View control access to call the Views as Web API endpoints.

$Item Variable

If you pass the Item ID as the itemId parameter for v1 API endpoints and the itemPath parameter for v2 API endpoints, the $Item variable will hold the Item object.

For Solution and Item Type Static functions, you pass a Dictionary to the function, with $Item as a key and the Item object as the value.

$Params Dictionary

The query string parameters and the JSON request body are passed to gs, gshtml, and gsAction Views and are available in the Gnosis Scripts as the special $Params dictionary.

For example, the parameter name is passed in the query string for the View named About as a custom Web API endpoint:

/v2/View/App.About?name=Tom

In the About View, the query string name parameter is available in the $Params dictionary:

if (not $Params?.name) Error("A name is required.")

Response Dictionary

The response dictionary is how to return special keys from the Gnosis Script View. Place the response dictionary at the end of the script:

{
	$AffectedItems = true,
	$Commit = "Some transaction comment",
	$Cookies = { SomeCookie = "Some value" }
}

$Cookies

The $Cookies key is how to set and remove cookies. It can be used in GET (gs) and POST (gsAction) Views.

$Commit

The $Commit key sets a transaction message that appears in the Item History if the Item Type has History enabled. It is only valid for POST (gsAction) Views.

$AffectedItems

The $AffectedItems key holds the affected items. It is only valid for POST (gsAction) Views.

Affected Items are automatically tracked when you set the key to true:

$AffectedItems = true

You can use the AffectItem() function to set affected items explicitly.

Message

A text message to show in a Toast dialog that automatically hides after a few seconds when the Task is invoked from the Action menu.

Important

Messages are shown in a persistent dialog rather than the Toast dialog, ensuring the message is not missed.

EventHandler Type View

EventHander-type Views implement Event logic. Name the View after the Event Name. When the event occurs, all matching Views are executed.

Generator Type View

Generator-type Views generate other Views and are mainly used to dynamically generate the Items, Read, New, and Update No-Code views.

Views with the auto format are generated using the Generator View for the View Type. The Generator to use for the View is an option in the View or can be configured as an App Configuration Setting.

There is one built-in View Generator – ExtJS.

Import Type View

Import-type Views are used as UI for import operations and can declare property options for the import process. The Item Type Import Script handles the import process for an item type.

Items Type View

Items-type Views are used when navigating a Solution with the Gnosis No-code App.

Layout Type View

Layout-type Views provide the ability to create any user interface you want.

The View format can be straight HTML, JSON, Gnosis Script (gs), or the most common gshtml Gnosis Markup Script format.

The View is accessible by URL:

/app/{SolutionName}.{ViewName}

If there is only one Layout-type View for the Solution, the URL can be simplified:

/app/{SolutionName}

If there are multiple Layout-type Views, the lowest-order View will be used.

In addition, set the Default Solution for the Users and Teams in the Gnosis Identities App to the Solution with the Start View.

Start View

The Launch Pad is the default landing page for the Gnosis no-code App. However, if a Solution Layout-type View is named Start, the Gnosis App begins with this View.

New Type View

New-type Views are used to create new Items.

Override Type View

Override-type Views are used to override the ExtJS UI components.

Print Type View

Print-type Views are used to create a readable print view of the Item.

Read Type View

Read-type Views are used to get an Item.

Report Type View

Report-type views generate reports. They appear in the Reports toolbar menu and can be run from there.

Task Type View

Task-type Views are gsAction Gnosis Scripts that can be executed as commands by the CreateTask function, as Solution and Item Type Static functions, with the View Render function, or as Custom Web API endpoints. In all cases, the Task runs in the background.

During development, the Gnosis View IDE automatically executes the Task View in the foreground using Simulation Mode for debugging.

Task Only Functions

There are a few functions that are special to Task Command Scripts.

Progress function

The Progress function will show a progress message in the Gnosis Task App and for Action Task Views invoked from the Actions menu.

// Pass in a message for the Task Status.
Progress(message)
// Pass in an integer between 0 and 100 to show the progress.
Progress(percentage)
// Pass in both a message and progress percentage.
Progress(percentage, message)

The message for the Task is shown in the Status column.

The progress is shown as a meter in the Progress column for the Task.

Commit function

The Commit function allows you to commit the changes in the Script rather than at the end of the Task.

Commit(message?, clearCache?)

The commit message is written to the history if the Item Type History is configured.

Clearing the cache frees up memory and increases performance. It should be used when there are many changes in the Task.

Sleep function

The Sleep function will pause the Script for the time in milliseconds passed as the argument.

Task Example

The following Task-type View will update all the Example items:

/**
 * Updates Example(s).
 * @group Update
 * @result Dict
 * @example 
 * CreateTask("PlayPen.Task");
 */

var items = @.Example.Items;
var count = items.Count();

items.ForEach((item, i) => (
	item.UpdateItem({
		"Description": "Solution 'Task View' invoked on: {Date()}"
	});
	Sleep(1000);
	Progress(
	  i * 100 / count,
	  "{i} of {count} : Updating {item.Identifier}, waiting 1 second...")
));

/*
	Return results dictionary.
*/
{
	Message = 'Task completed.',
	Important = true 
}

Testing the Task View

// Get Authorization header with the OAuth access token.
OAuth(username, password) => (
	var url = $ServerUrl + "/v2/OAuth";
	var cred = {
	  "username": username,
	  "password": password,
	  "grant_type": "password"};
	var oauth = Ajax(url, cred, "POST");
	
	// The object is the last statement so it is the return value.
	{ "Authorization": "Bearer " + oauth.access_token }
);

// Credential variables
var user = "email";
var pwd = "password";

// The gsAction View path.
var gsAction = "PlayPen.Task";

// Execute the gsActin using CreateTask function.
CreateTask(gsAction);

// Render the gsAction using the View function.
ActionView(gsAction).Render();
	
// POST the gsAction using Gnosis v1 API.
Ajax.Call({
	url = $ServerUrl + "/api/View/Action/" + gsAction,
	method = "POST",
	user = user,
	password = pwd
});

// POST the gsAction using Gnosis v2 API.
Ajax(
	$ServerUrl + "/v2/View/" + gsAction,
	missing,
	"POST",
	missing, missing, missing,
	OAuth(user, pwd));

Template Type View

Template-type Views are textual templates. The content of a template is rendered on the fly from context using special template macro syntax.

The rendered content is then used according to View Format (dynamic HTML, dynamic JavaScript, dynamic CSS, or even dynamic Gnosis Script).

Update Type View

Update-type Views are used to update the Item.

View Format

The View Format is the expected format of the View content. It is applicable based on the View Type and is like a file extension.

auto

The content is JSON auto-generated based on the Generator specified. You can configure the auto View using the Gnosis IDE.

control

The content is JavaScript and is used by the ExtJS UI.

controller

The content is JavaScript and is a controller of any UI.

({
	init: function () {
		this.view.$.height(this.view.$.parent().height());
		this.view.$.find('> .chat').height(this.view.$.height());

		this.view.$.find('input').on('keypress', e => {
			if (e.which === 13 && this.chatId) {
				runViewAction('Chat.ChatRoom.Send', {
					itemId: this.chatId,
					message: $(e.target).val()
				});
				$(e.target).val('');
			}
		});
	},

	setContext: function (context) {
		this.unsubscribe();
		this.subscribe(context && context.itemId || null);

		if (this.chatId) {
			getViewItems('Chat.ChatMessage.Items', {
				parentId: this.chatId,
				includeState: false, includeTransitions: false, includePermissions: false,
				props: 'CreatedOn,CreatedBy,Name', sort: '!CreatedOn', limit: 50
			}).then(data => {
				data.items.reverse().forEach(item => {
					this.appendMessage(null, { 
					  username: item['CreatedBy$Display'],
					  time: item.CreatedOn,
					  message: item.Name
					});
				});
			});
		}
	},

	subscribe: function (chatId) {
		if (chatId) {
			this.chatId = chatId;
			server.on('chat', this.chatId, this.appendMessage, this);
		}
	},

	unsubscribe: function () {
		if (this.chatId) {
			server.un('chat', this.chatId, this.appendMessage, this);
			this.chatId = null;
		}
	},

	appendMessage: function (id, data) {
		var messages = this.view.$.find('.messages');
		createDiv('message')
			.append(createDiv('message-time')
			  .text(this.view.factory.app.render.datetime(data.time)))
			.append(createDiv('username').text(data.username))
			.append(createDiv('message-body').text(data.message))
			.appendTo(messages);
		messages[0].scrollTop = messages[0].scrollHeight - messages[0].offsetHeight;
	},

	destroy: function () {
		this.unsubscribe();
	}
})

The controller can be linked to a View with a JSON View with the following values:

{
  factory: "Html",
  html: "...markup...",
  controller: "controllerView"
}

The View can also be HTML or gsHtml with a comment to specify the controller View:

<!-- controller: controllerView -->
<div class="chat">
	<div class="messages"></div>
	<input placeholder="Enter new message here..." />
</div>

css

The content is CSS.

function

The content is JavaScript function.

gsAction

The content is Gnosis Script, which implements Application Logic. Gnosis gsAction Views are used to modify Items and are transactional and are called with PUT/POST Web API methods.

The following is a sample Custom gsAction View named CreateActionItem for the App Solution. It will create an ActionItem and return an HTML page.

/**
 * Creates an Action Item.
 * @group Demo
 * @param Name : string // The Action Name.
 * @param Description : string // The Action Description
 * @result HTML 
 * @example $.Actions.CreateActionItem({"Name":"Test", "Description":"Test"});
 */

/*
	If no Name is passed in, generate a random name.
*/
var name = $Params?.Name
	? Name // Name is short for $Params.Name
	: "Random Name {Random(1, 100)}";

/*
	If no Desctiontion is passed in, set Lorem Ipsum text.
*/
var desc = $Params?.Description 
	? Description  // Description is short for $Params.Description
	: "Lorem Ipsum gestas eget aliquet praesent cursus in habitasse platea";

/*
	Create a new ActionItem and catch any error.
*/
var item = Safe(CreateItem($.Actions.ActionItem, {
	Name = name,
	Description = desc
	// Catch and return a clone of the Error.
	// Otherwise, the error is rethrow.
}), e => { Error = e });

/*
	Use a Raw Template String to return HTML with embedded Gnosis Script.
*/
"""
<h1>Hello, {$User}</h1>

{:
	// If there is an Error show the message.
	if (item?.Error) (
		"<div>{item.Error.Message}</div>"
	) else (
		var created = item.CreatedOn.ToString('MMM dd, yyyy');
		"<div>{item?.Name} was created on {created}</div>"
	)
:}
""";

Test POST Web API

You can test the gsAction View using the Gnosis Scripting Console.

To execute the gsAction View, use the ActionView function to get the View. The false argument will force the function to return null if there is no View by the path provided rather than an error. Pass the parameters for the View through the Render function:

ActionView("App.CreateMyItem", false)?.Render({
	"Name": "Testing " + Random(1, 100),
	"Description": "Created by ActionView function"
})

You can also call the gsAction View as a Solution Static function, passing the View parameters through the function:

$.App.CreateMyItem({
	"Name": "Testing " + Random(1, 100),
	"Description": "Created by View function"
})

You can use the Ajax function in the Gnosis Scripting Console to test POST/PUT Web API gsAction Views:

// Get Authorization header with the OAuth access token.
OAuth(username, password) => (
	var url = $ServerUrl + "/v2/OAuth";
	var cred = {
	  "username": username,
	  "password": password,
	  "grant_type": "password"};
	var oauth = Ajax(url, cred, "POST");
	
	// The object is the last statement so it is the return value.
	{ "Authorization": "Bearer " + oauth.access_token }
);

// Credential variables
var user = "email";
var pwd = "password";

// The gsAction Solution View path.
var gsAction = "App.CreateActionItem";

// POST to the gsAction View using Gnosis v1 API.
Ajax.Call({
	url = $ServerUrl + "/api/View/Action/" + gsAction,
	params = {
		"Name": "Testing " + Random(1, 100),
		"Description": "Created by {gsAction} Web v1 API"
	},
	method = "POST",
	user = user,
	password = pwd
});

// POST to the gsAction View using Gnosis v2 API.
Ajax(
	$ServerUrl + "/v2/View/" + gsAction,
	{
		"Description": "Created by {gsAction} Web v2 API"
	},
	"POST",
	missing, missing, missing,
	OAuth(user, pwd));

gshtml

The content is HTML markup with embedded Gnosis Script, which is used for custom UI.

Gnosis gs and gshtml Views are read-only (GET) Web API endpoints.

For example, the following gshtml View will return an HTML page of the items the user created:

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">

<style>{'''
.landing-page h1 {
	color: #9999FF;
	font-family: "Poppins", sans-serif;
	font-weight: 300;
	line-height: 1.1em;
}

.landing-page h2 {
	color: #6666FF;
	font-family: "Poppins", sans-serif;
	font-weight: 500;
	line-height: 1.1em;
}

.tile-layout {
	display: flex;
	flex-flow: row wrap;
	justify-content: start;
	gap: 2em;
}

.action-tile {
  	transition: .6s;
	padding: 0 2em 1em 2em;
	border: none;
	border-radius: 8px;
	box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
	cursor: pointer;
}

.action-tile:hover {
    transform: scale(1.05);
	box-shadow: rgba(149, 157, 165, 0.4) 0px 8px 24px;
}

.action-tile .info {
	font-family: "Poppins", sans-serif;
	font-weight: 500;
	display: flex;
	flex-flow: row wrap;
	justify-content: space-between;
	top: -.7em;
	left: -1em;
	position: relative;
	font-size: 1.2em;
	text-shadow: 2px 2px 4px rgba(0, 0, 0, .3);
}

.action-tile .name {
	font-size: 1.125em;
}

.todo {
	background: rgb(255, 255, 0, .4);
}

.done {
	background: rgb(200, 200, 255, .4);
	color: #888888;
}

.done .name {
	text-decoration-line: line-through;
}

.doing {
	background: rgb(0, 255, 0, .4);
}

.pending {
	background: rgb(255, 255, 255, .6);
}
'''}</style>

<div class="landing-page">
	<div class="landing-page-content">
		<h2 class="animate__animated animate__zoomIn">Hello, {$User}</h2>
		<h1 class="animate__animated animate__lightSpeedInLeft animate__delay-1s animate__slow">Here are your To-Do & Action Items</h1>
		
		<div class=" animate__animated animate__fadeInUp animate__delay-1s animate__slow tile-layout">
			{:
			var baseUrl = $ServerUrl + "/#/Actions/Explore/item:";
			
			FindItems($.Actions.ToDoItem)
				.IncludeDerived()
				.Filter(i => i.CreatedBy == $User)
				.Map(i => (
					var url = baseUrl + i.Id;
					var cls = i.Status.ToLower().Replace(' ', '');
					var date = i?.Completed ? i.CompletedOn : i.CreatedOn;
					var when = (i?.Completed ? 'Completed' : 'Created') + " On: {date?.ToString('MMMM, d, yyyy h:mm tt')}";
					var due = i?.DueDate ? "<div>Due <strong>{i.DueDate.ToString('MMMM, d, yyyy')}</strong></div>" : '';
					var type = i.Status.Contains('Done') ? i.Status : i.$ItemType.Label;
					var status = not i.Status.In(['To Do', 'Done']) ? i.Status : '';
					var act = (i.$ItemType.Name == 'ActionItem');
					var desc = i?.Description ? "<p>{i.Description}</p>" : '';
					
					"<div class='action-tile {cls}' onclick=location='{url}'>
						<div class='info'>
							<div>{type}</div>
							<div><strong>{status}</strong></div>
						</div>
						<div class='name'><span class='{i.$ItemType.FontIcon}'></span> {i.Name}</div>
						<div style='font-size:.8em;'>{when}</div>
						{due}
						{desc}
					</div>";
				));
			:}
		</div>
	</div>
</div>

Test the gshtml View

You can test gs and gshtml Views using the Gnosis Scripting Console. Call the View using the Solution Static function:

$.App.Actions()

You can use the browser to test gs or gshtml Views using the Gnosis v1 Web API:

/api/View/Content/App.Actions

Alternatively, to get a gs or gshtml View with Gnosis v2 Web API:

/v2/View/App.Actions

gs

The content is Gnosis Script for Application Logic, intended to get data.

gridview

The content is JSON and is used by the ExtJS UI.

End users typically create gridview Views using the Gnosis No-code App to configure and save as Items Views.

html

The content is HTML, used for static custom UI.

image

The content is binary. The image format is set when the image file is uploaded.

js

The content is JavaScript.

json

The content is JSON.

{
	"xtype": "dataview",
	"selector": ".item",
	"itemTpl": {
		"gnosis": {
			"load": ".ToDoItem.ToDoItemsTpl"
		}
	},
	"store": {
		"autoLoad": true,
		"proxy": {
			"type": "ajax",
			"reader": "json",
			"url": "/api/ItemType/Actions/ToDoItem/Values"
		}
	}
}

report

The content is ???

settings

The content is JSON.

{
	"PickListNew": true,
	"PickListExpand": true,
	"PickListEdit": true,
	"TOCLayout": "Details",
	"TOC": true,
	"StateIcons": {
		"Pending": {
			"Icon": true,
			"Button": false,
			"Menu": true,
			"Order": 1
		},
		"Archived": {
			"Icon": true,
			"Button": false,
			"Menu": true,
			"Order": 4
		},
		"Doing": {
			"Icon": true,
			"Button": false,
			"Menu": true,
			"Order": 2
		},
		"Done": {
			"Icon": true,
			"Button": false,
			"Menu": true,
			"Order": 3
		}
	}
}

svg

The content is SVG.

template

The content is HTML with XTemplate substitutions.

<div class="item">
	<div>
		<b>{Name}</b>
		<tpl if="Status == 'Done'"> COMPLETED</tpl>
	</div>
	<div>{Description}</div>
</div>

viewModel

The content is JSON and is used by the ExtJS UI.

XML

The content is XML.