Zengine Directives

Zengine provides several directives for you to use in your plugin html.


The zn-inline-filter directive allows you to insert a data filter builder directly into your plugin page. This is different from the znFiltersPanel service, which opens the filter builder in a modal. The filter returned can be used to query records, save to a data view, and build and run calculations.

The directive has 2 required parameters: zn-inline-filter and ng-model. zn-inline-filter is an object matching the options of the znFiltersPanel, excluding filter and onSave options.

ng-model should represent the $scope property for the filter.

plugin.controller('MyController', function($scope) {

	// Must Match All Conditions, Disable Linked Fields and Nested Conditions
	$scope.inlineOptions = {
		formId: 123,
		operators: ['and'],
		subfilters: false,
		groups: false,
		fieldTypeBlacklist: ['linked']

	// Data Filter
	$scope.filter = {};

	$scope.logFilter = function() {

<div zn-inline-filter="inlineOptions" ng-model="filter"></div>
<a href="#" ng-click="logFilter();">Log Filter</a>


The zn-datetimepicker-wrapper directive is a wrapper for the Angular bootstrap datepicker and timepicker. Both directives work perfectly fine on their own, but there are two main downsides:

  1. There isn’t a way to have a single datetime that is synced with both the datepicker and the timepicker.
  2. The model for the pickers needs to be a Date object. This is a problem if your model needs to be a string, which is likely if the date is being retrieved and/or saved via the Zengine API.

This directive solves both issues. You can use the directive on an element with model that’s a string type, and put a bootstrap datepicker (and optionally a timepicker) as children of the directive element. Then, changes in the directive model are reflected in the picker(s), and vice versa.

A few things to note:

  • The datepicker model must have a model called date.
  • The timepicker (if present) must have a model called time.
  • If you want the directive model to also sync with the timepicker, the directive element needs the attribute sync-time with a value that evaluates to true.

In addition, the directive provides the following useful scope properties:

  • format - the preferred user date format, which can be passed on as the display format of the datepicker
  • open - a function for opening the datepicker popup
  • opened - a boolean state of whether the datepicker popup is open or not
  • user - the entire User object.
  • dateOptions - a set of default datepicker settings used for all datepickers within the app.
<div ng-model="myDate" zn-datetimepicker-wrapper sync-time="true">
    <input type="text" placeholder="{{user.settings.dateFormat}}" ng-model="date" ng-focus="open($event)" is-open="opened" datepicker-popup="{{format}}" datepicker-options="dateOptions"/>
    <timepicker class="timepicker" ng-model="time" minute-step="1"></timepicker>


The ui-draggable directive is an AngularJS wrapper for jQuery UI draggable.

All the jQuery UI draggable options can be defined in your controller.

plugin.controller('MyController', function($scope) {
    $scope.items = ["One", "Two", "Three"];

    $scope.draggableOptions = {
        start: function(e, ui) { ... },
        stop: function(e, ui) { ... },
        connectToSortable: "#my-sortable",
        delay: 300

Apply the directive to your elements:

<ul ng-model="items">
    <li ng-repeat="item in items" ui-draggable="draggableOptions"></li>


The validate directive works in conjunction with the Angular form directive to add an error class to the element when it has any invalid child inputs. The directive only checks for invalid inputs when formName.submitted is true. An input is considered invalid if inputName.$valid is false. In the example below, after clicking , this directive will add an error class to the control-group div if myFormInput is invalid. In this case, the validity of myFormInput will depend on the ng-maxlength and required directives. Check out the Angular docs for more info on input validation.

<form name="myForm">
    <div class="control-group" validate="myFormInput">
        <label class="form-label">My Input</label>
        <div class="controls">
            <input type="text" name="myFormInput" required ng-maxlength="50"/>
    <input type="button"  class="btn btn-small btn-primary" ng-click="myForm.submitted = true" value="Save" />