Zengine provides several services for you to inject as dependencies when developing your plugin.
A service that displays a temporary alert message at the top of the page.
// Example controller including the 'znMessage' service.
plugin.controller('MyCntl', ['$scope', 'znMessage', function($scope, znMessage) {
$scope.onSubmit = function() {
znMessage('Your data was saved!', 'saved');
};
}]);
Param | Type | Details |
---|---|---|
message | string |
The message to display. |
type (optional) | string |
Determines the background color of the message. Valid types: 'info', 'saved', 'error', 'warning'. Default is 'info'. |
duration (optional) | integer |
How long the message is displayed in milliseconds. Default is 4000. |
Forces any open messages to close.
A service that displays a confirmation dialog.
var close = function() {
console.log('Closed');
};
znConfirm('Are you sure you want to close?', close);
Param | Type | Details |
---|---|---|
message | string |
The message to display in the dialog. |
callback (optional) | function |
If defined, will add a 'Yes' button to the dialog, which when clicked, will execute the callback. |
A service that displays a modal dialog. For an alternative modal service, try Angular bootstrap’s $modal
.
plugin.controller('myMainCntl', ['$scope', 'znModal', function($scope, znModal) {
$scope.onSubmit = function() {
znModal({
title: 'My Modal Dialog',
template: "<form ng-controller='myModalCntl' name='myForm'><input name='input' required></form>",
classes: 'my-dialog',
btns: {
'Save': {
primary: true,
action: function(scope) {
// on Save click
}
},
'Delete': {
danger: true,
action: function() {
// on Delete click
}
}
}
});
};
}]);
/*
* For enhanced control over modal buttons
*/
plugin.controller('myModalCntl', ['$scope', function($scope) {
$scope.setBtnAction('Save', function (callback) {
// See https://code.angularjs.org/1.2.21/docs/api/ng/directive/form for more details
var form = $scope.myForm; // value of the name attribute on the form.
if (!form.$valid) { // e.g. empty input
return false; // do nothing
}
var keepOpen = false; // close the modal afterwards
callback($scope, keepOpen); // call the original callback with $scope passed to it
});
}]);
Param | Type | Details |
---|---|---|
options | Object |
The object has the following properties:
|
znFiltersPanel is a service that allows you to view and build a data filter by opening a modal. This is different from the znInlineFilter directive, which displays the filter builder directly in the page. The filter returned from the panel can be used to query records, save to a data view, and build and run calculations.
plugin.controller('myMainCntl', ['$scope', 'znFiltersPanel', 'znData', function($scope, znFiltersPanel, znData) {
$scope.formId = 123;
$scope.openFiltersPanel = function() {
znFiltersPanel.open({
formId: formId,
filter: {
and: [{
prefix: '',
attribute: 'folder.id',
value: 0
}]
},
onSave: function(filter) {
// use filter to interact with API, e.g. query records
znData('FormRecords').get(
{
formId: $scope.formId,
filter: JSON.stringify(filter)
}
);
},
fieldTypeBlacklist: ['text-input', 'linked'],
attributeBlacklist: ['field123', 'createdByUser.id']
});
};
}]);
Param | Type | Details |
---|---|---|
options | Object |
The object has the following properties:
|
The znFilterMatcher service lets your plugin compare a record against a filter and determine if it’s a match. It uses the same matching as querying records using a filter or for conditional field rules. One case you might use this for is to filter down a list of records that have already been fetched without making an additional request to the API.
For the matching to work properly, the data you are filtering on must be present in the record. Additionally, subfilters of fields on other forms and dynamic conditions, such as logged-in-user
, are not supported.
var record = { 'field123': 'Chicago', 'field456': 2015 };
if (znFilterMatcher(record, { 'and': [{ 'prefix': '', 'attribute': 'field123', 'value': 'Chicago'}]})) {
// Record Matches field123 = Chicago
}
if (znFilterMatcher(record, { 'and': [{ 'prefix': 'min', 'attribute': 'field456', 'value': 2015}]})) {
// Record Matches field456 >= 2015
}
The znData service provides a collection of resources that should be used for accessing data via the Zengine REST API. After passing the name of the resource to the service, you get back an object that can use the methods described below: get
, query
, save
, update
, delete
, saveAll
, updateAll
and deleteAll
. All methods return a standard Angular promise object.
Performs a GET
request on a single object. The id param, if passed to params
, will be interpreted as a url parameter.
// Get single workspace member
// equivalent to: GET /workspaces/123/members/456
// response will be a JSON Object
znData('WorkspaceMembers').get({ workspaceId:123, id:456 }, function(member) {
$scope.member = member;
});
Performs a GET
request on an array of objects. The id param, if passed to params
, will be interpreted as a query parameter.
// Get list of workspace members
// equivalent to: GET /workspaces/123/members?id=456
// response will be an array
znData('WorkspaceMembers').query({ workspaceId:123, id: 456 }, function(members) {
$scope.member = members[0];
});
If params
is present and contains the id param, performs a PUT
. Otherwise performs a POST
request.
// Add a workspace member
// equivalent to: POST /workspaces/123/members
znData('WorkspaceMembers').save({ workspaceId:123 }, { 'inviteCode' : 123456 }, function(member) {
$scope.member = member;
});
// Update a workspace member to be an admin
// equivalent to: PUT /workspaces/123/members/456
znData('WorkspaceMembers').save({ workspaceId:123, id:456 }, { 'role.id' : 2 }, function(members) {
$scope.members = members;
});
// Make all admins of workspace 123 owners
// equivalent to: PUT /workspaces/123/members?role.id=1
znData('WorkspaceMembers').save({ workspaceId:123, 'role.id': 2 } , { 'role.id' : 1 }, function(members) {
$scope.members = members;
});
Works the same as the save
with the execption it will always performs a PUT
.
// Update a workspace member to be an admin
// equivalent to: PUT /workspaces/123/members/456
znData('WorkspaceMembers').update({ workspaceId:123, id:456 }, { 'role.id' : 2 }, function(members) {
$scope.members = members;
});
Performs a DELETE
request. Same as calling del(params, successCallback, errorCallback);
// Delete a workspace member
// equivalent to: DELETE /workspaces/123/members/456
znData('WorkspaceMembers').delete({ workspaceId:123, id:456 }, function() {
znMessage('Member removed from workspace', 'saved');
});
Performs a POST
request with multiple objects to be created.
// Create multiple tasks at once
// equivalent to: POST /tasks
$scope.tasks = [
{
"task":"Test 1",
"workspace":{"id":62},
"taskList":{"id":0},
"order":1,
"due":"2015-03-20",
"assignedToUser":{"id":9},
"priority":1,
"status":"open"
},
{
"task":"Test 2",
"workspace":{"id":62},
"taskList":{"id":0},
"order":1,
"due":"2015-03-20",
"assignedToUser":{"id":9},
"priority":1,
"status":"open"
},
{
"task":"Test 3",
"workspace":{"id":62},
"taskList":{"id":0},
"order":1,
"due":"2015-03-20",
"assignedToUser":{"id":9},
"priority":1,
"status":"open"
}
];
znData('Tasks').saveAll({}, $scope.tasks, function(data) {
znMessage('All tasks saved.', 'saved');
// `data` will contain IDs of created tasks
});
Performs a PUT
request.
The data
param needs to be an object with the properties to be updated for all record that matches the params/conditions.
// Update all tasks status to `closed` where the status is `in-progress`
// equivalent to: PUT /tasks/?status=in-progress
var params = { status: 'in-progress' };
var data = { status: 'closed' };
znData('Tasks').updateAll(params, data, function() {
znMessage('All tasks updated.', 'saved');
});
// Update all tasks status to `archived` where the IDs are 1, 2, 3
// equivalent to: PUT /tasks/?id=1|2|3
var params = { id: '1|2|3' };
var data = { status: 'archived' };
znData('Tasks').updateAll(params, data, function() {
znMessage('All tasks archived.', 'saved');
});
Performs a DELETE
request.
// Delete all tasks with status `archived`
// equivalent to: DELETE /tasks/?status=archived
var params = { status: 'archived' };
znData('Tasks').deleteAll(params, function() {
znMessage('All tasks deleted.', 'saved');
});
// Delete all tasks with IDs 1, 2, 3
// equivalent to: DELETE /tasks/?id=1|2|3
var params = { id: '1|2|3' };
znData('Tasks').deleteAll(params, function() {
znMessage('All tasks deleted.', 'saved');
});
Param | Type | Details |
---|---|---|
params (optional) | Object |
Optional if the resource has no required URL parameters and a POST is desired. Valid URL parameters are defined for each resource here. If the params object is passed, any keys that aren't URL parameters are sent as query parameters in the request. Some examples of valid query parameters are limit, related, sort, and attributes. If the id param is included in this object, a PUT is made. If not, a POST is made.
|
data | Object |
Sent as the payload of the request. |
successCallback | function(data, metaData, headers) |
The function to execute if the request succeeds.
|
errorCallback | function(resp) |
The function to execute if the request fails. Click here for more info about the format of the failure response. |
The parameterized URL is used to query the Zengine REST API. For example, if the resource name is FormFields, the parameterized URL is /forms/:formId/fields/:id. In this case, formId
is a required URL paramter, and must be passed to the params
argument of any get()
, query()
, delete()
, or save()
called on znData('FormFields')
. The id
parameter on the other hand, may or may not be passed, depending on whether the request is intended for a single object or multiple objects. This is true for the id
parameter of any resource URL.
The Zengine REST API has more querying options for pagination, sorting, filtering, and relational data.
Resource Name | Parameterized URL |
---|---|
Activities | /activities/:activityId |
AppTemplates | /app_templates/:id |
AppTemplateInstallJobs | /app_template_install_jobs/:id |
BinaryExportBatch | /binary_export_jobs/:binaryExportJobId/batches/:id |
BinaryExportJob | /binary_export_jobs/:id |
Calculate | /calculate |
CalculationSettings | /calculation_settings/:id |
DataViews | /data_views/:id |
Events | /events/:id |
Files | /files/:id |
Forms | /forms/:id |
DefaultFormPermissions | /forms/permissions |
FormFields | /forms/:formId/fields/:id |
FormFieldTaxonomy | /form_field_taxonomy |
FormFolders | /forms/:formId/folders/:id |
FormGroups | /forms_groups/:id |
FormRecordPermissions | /forms/:formId/records/permissions |
FormRecords | /forms/:formId/records/:id |
FormUploads | /forms/:id/uploads |
Notes | /notes/:id |
NoteReplies | /notes/:noteId/replies/:id |
Notifications | /notifications/:id |
NotificationEmails | /notification_emails/:id |
Plugins | /plugins/:pluginId |
PluginScreenshots | /plugins/:pluginId/screenshots |
PluginServices | /plugins/:pluginId/services/:id |
PluginServiceUploads | /plugins/:pluginId/services/:serviceId/uploads |
WorkspacePluginLinks | /workspace_plugin_links/:id |
RecordImportFiles | /record_import_files/:id |
RecordImportJobs | /record_import_jobs/:id |
RecordExportJobs | /record_export_jobs/:id |
ScheduledWebhooks | /scheduled_webhooks/:id |
Tasks | /tasks/:id |
TaskLists | /task_lists/:id |
TaskPriorities | /task_priorities |
TaskStatuses | /task_statuses |
TaskPreferences | /users/:userId/task_preferences |
Users | /users/:id |
Roles | /workspaces/:workspaceId/roles/:id |
WebhookEvents | /webhook_events/:id |
Webhooks | /webhooks/:id |
Workspaces | /workspaces/:id |
WorkspaceCopyJobs | /workspace_copy_jobs |
WorkspaceInvitees | /workspaces/:workspaceId/invitees/:id |
WorkspaceMembers | /workspaces/:workspaceId/members/:id |
WorkspaceTransferRequests | /workspaces/:workspaceId/transfer_requests/:id |
WorkspaceTaskPreferences | /workspaces/:workspaceId/members/:memberId/task_preferences |
WorkspaceLogo | /workspaces/:workspaceId/logo |
Countries | /countries |
States | /states |
Subscriptions | /subscriptions/:id |
The znPluginData service is used to communicate with Plugin Services, similar to how znData makes requests to the REST API. Instead of passing a resource name, you pass the plugin namespace and service route. The methods available are: get
, post
, put
, and delete
. The methods return an Angular promise object.
The param workspaceId
is always required and must be a workspace where the plugin is installed. Query string parameters should be passed as params
.
Performs a GET
request.
// equivalent to: GET https://plugins.zenginehq.com/workspaces/123/myPlugin/my-route?id=456
znPluginData('myPlugin').get('/my-route', { workspaceId: 123, params: { id: 456 }}, function(results) {
$scope.results = results;
});
Performs a POST
request.
// equivalent to: POST https://plugins.zenginehq.com/workspaces/123/myPlugin/my-route
znPluginData('myPlugin').post('/my-route', { workspaceId: 123 }, { name: $scope.name }, function(result) {
$scope.result = result;
});
Performs a PUT
request.
// equivalent to: PUT https://plugins.zenginehq.com/workspaces/123/myPlugin/my-route?id=456
znPluginData('myPlugin').put('/my-route', { workspaceId: 123, params: { id: 456 }}, { email: $scope.email }, function(result) {
$scope.result = result;
});
Performs a DELETE
request.
// equivalent to: DELETE https://plugins.zenginehq.com/workspaces/123/myPlugin/my-route?id=456
znPluginData('myPlugin').delete('/my-route', { workspaceId: 123, params: { id: 456 }}, function(result) {
// Deleted
});
znPluginEvents is service that acts as a wrapper for the Angular pub-sub system, and is meant for communication between plugins and the core app.
Same as Angular $on. This method can be used to listen for the following broadcasted events:
resource-name
-action
resource name
is the hyphenated version of the resource names listed here. The action
can be one of the following: read
, saved
, deleted
, saved-all
, updated-all
or deleted-all
. For example, calling znData('FormRecords').save()
will trigger the 'zn-data-form-records-saved'
event.Important: Make sure to deregister your listeners when your plugin is destroyed. Not deregistering listeners will cause listeners to duplicate and pile up, which will degrade the performance of your plugin and the app. The code below shows listeners being registered and deregistered on $scope $destroy.
/**
* Plugin testPluginEvents Controller
*/
plugin.controller('testPluginEventsCntl', ['$scope', 'znPluginEvents', function ($scope, znPluginEvents) {
// zn-ui-record-overlay-record-loaded
var recordLoaded = znPluginEvents.$on('zn-ui-record-overlay-record-loaded', function(evt, record) {
console.log(record);
});
// zn-data-[resource name]-saved
var recordSaved = znPluginEvents.$on('zn-data-form-records-saved', function(evt, record, created, params) {
if (created) {
console.log('Record ' + record.id + ' was created in form ' + params.formId);
} else {
console.log('Record ' + record.id + ' was updated in form ' + params.formId);
}
});
// zn-data-[resource name]-deleted
var recordDeleted = znPluginEvents.$on('zn-data-form-records-deleted', function(evt, params) {
console.log('Record ' + params.id + ' was deleted');
});
// zn-data-[resource name]-read
var recordRead = znPluginEvents.$on('zn-data-form-records-read', function(evt, records, params) {
angular.forEach(records, function(record) {
console.log(record);
});
});
// zn-data-[resource name]-saved-all
var taskSaveAll = znPluginEvents.$on('zn-data-tasks-saved-all', function(evt, data, params) {
console.log('Tasks IDs created: ' + data.join(','));
// `data` will be an array of IDs
});
// zn-data-[resource name]-updated-all
var taskUpdateAll = znPluginEvents.$on('zn-data-tasks-updated-all', function(evt, params) {
console.log('Tasks was updated');
// `params` will contain the path and query params used
});
// zn-data-[resource name]-deleted-all
var taskDeleteAll = znPluginEvents.$on('zn-data-tasks-deleted-all', function(evt, params) {
console.log('Tasks was deleted');
// `params` will contain the path and query params used
});
// Deregister listeners
$scope.$on("$destroy", function() {
if (recordLoaded) recordLoaded();
if (recordSaved) recordSaved();
if (recordDeleted) recordDeleted();
if (recordRead) recordRead();
if (taskSaveAll) taskSaveAll();
if (taskUpdateAll) taskUpdateAll();
if (taskDeleteAll) taskDeleteAll();
});
}]);
This service gives you basic access to browser local storage and fallbacks to browser cookies if support is not available.
Set an item in browser local storage.
/**
* Plugin testLocalStorage Controller
*/
plugin.controller('testLocalStorageCntl', ['$scope', 'znLocalStorage', function ($scope, znLocalStorage) {
znLocalStorage.set('lastSaved', new Date());
}]);
Get an item in browser local storage.
/**
* Plugin testLocalStorage Controller
*/
plugin.controller('testLocalStorageCntl', ['$scope', 'znLocalStorage', function ($scope, znLocalStorage) {
znLocalStorage.get('lastSaved');
}]);
Remove an item in browser local storage.
/**
* Plugin testLocalStorage Controller
*/
plugin.controller('testLocalStorageCntl', ['$scope', 'znLocalStorage', function ($scope, znLocalStorage) {
znLocalStorage.remove('lastSaved');
}]);
Checks if the browser support local storage.
/**
* Plugin testLocalStorage Controller
*/
plugin.controller('testLocalStorageCntl', ['$scope', 'znLocalStorage', function ($scope, znLocalStorage) {
if (znLocalStorage.isSupported) {
// is supported
} else {
// not supported
}
}]);
This service gives you basic access to browser cookies.
Set an item in browser cookies.
/**
* Plugin testLocalStorage Controller
*/
plugin.controller('testCookiesCntl', ['$scope', 'znCookies', function ($scope, znCookies) {
znCookies.set('lastSaved', new Date());
}]);
Get an item in browser cookies.
/**
* Plugin testLocalStorage Controller
*/
plugin.controller('testCookiesCntl', ['$scope', 'znCookies', function ($scope, znCookies) {
znCookies.get('lastSaved');
}]);
Remove an item in browser cookies.
/**
* Plugin testLocalStorage Controller
*/
plugin.controller('testCookiesCntl', ['$scope', 'znCookies', function ($scope, znCookies) {
znCookies.remove('lastSaved');
}]);
Checks if the browser support cookies.
/**
* Plugin testLocalStorage Controller
*/
plugin.controller('testCookiesCntl', ['$scope', 'znCookies', function ($scope, znCookies) {
if (znCookies.isSupported) {
// is supported
} else {
// not supported
}
}]);