The revive directive is a trancluding directive that enable you bring alive "dead" regions of html and create imaginative select-like components. You take advantage of the directive's ability to interface with ngModel to porpagate changes between the model and view and vice versa. You enable and disable regions by broadcasting disable/enable events, and as the ability to reset the transcluded directive and start afresh.
The revive sole dependency is on AngularJS 1.5.6 get AngularJS
What we have here is a simple "dead" map-like html element (div containing 4 other divs with no logic whatsoever_. However, once we transclude the container inside the Revive directive and implement a simple interface (4 events), the "dead" div regions become live and manifest a select-like behavior. As you can see, you gain full programmatic control over the transcluded html elemnt. You can set the number of selections allowed, select and de-select items as well as enabe / disable those any of the items.
Selected regions:
{{mapSelections}}
Number of selections: {{maxSelections}}
Setting up the necessary events is trivial and require only a few lines of code.
// attach click event to every region in transcluded directive
$scope.clickEvent = function (event, id) {
// item is disabled - do nothing
if (meDisabled) {
return;
}
// communicate selected value to revive
$scope.$emit(MessageItemSelected, id); br>
};
// controller level variables
var meDisabled = false; //signify item is disabled
$scope.enabledStateClass = 'map-region-enabled' // use ng-class to toggle region enabled/disabled state
// listen to disble event from revive
$scope.$on(MessageDisableItems, function (event, disabledList) {
if (-1 < disabledList.indexOf($scope.$parent.location.location)) {
$scope.enabledStateClass = 'map-region-disabled';
meDisabled = true;
} else {
$scope.enabledStateClass = 'map-region-enabled';
meDisabled = false;
}
});
// listen to selection changed event
selectionChangedEvent = $scope.$on(MessageSelectionChanged, function (event, selections) {
if (-1 < selections.indexOf($scope.$parent.location.location)) {
$scope.selectedStateClass = 'map-region-selected';
} else {
$scope.selectedStateClass = "";
}
});
// listen to reset event
SelectResetEvent = $scope.$on(MessageSelectReset, function (event) {
$scope.selectedStateClass = "";
});
Below is a detailed description of the revive proerties and events
The directive exihibts the following properties
Two way binding between the directive and the model. Changes to the model are instantaneously reflected in the view and vice-versa.
An array of items (identifiers) that cannot be manipulated (selected or de-selected should appear disabled) by the user. Content of the array is immediatelly propagated to the transcluded directive via a $broadcast event. It's the responsibility of the transcluded directive to act upon the event and disable/enable to appropriate selective data (regions).
Resets the directive state - clears the selections list and broadcasts a reset event to the underline directive. This is a one-way binding of a scope variable and you initiate a reset event by simply changing the value of the scope variable (true/false or 0/1 will do). Any change in value from the current value will initiate a reset event. Use this event with caution. You want to send a reset event, only if the state of your underline directive has changes in a major way and you want to start afresh.
Sets the mode of selection. If the multiple attribute is missing from the directive list of attributes then the directive allows only a single selection (combobox mode). When the directive is in a single selection mode, the value of the ngModel input variable should be a string, as this is the type of the output provided by the directive back to the ngModel. if the multiple attribute appears in the directive's attribute list, then the directive allows multiple selections to be made (listbox mode). if the multiple attribute has no value or its value is not a positive integer (i.e. multiple, multiple="true", multiple="false", etc' - take note that a value of 'false' has no bearing on the directive behavior) then the number of allowed selections is unlimited. However, if the value of the multiple attribute is a positive integer, then that number is taken to be the maximum number of selections allowed. That is, if multiple="2", then only 2 selections are allowed. Selections are cyclical, so the third object selected by the user will remove the first selected object from the selected item list. When the directive is in multiple selections mode, the value of the ngModel input variable should be an array, as this is the type of the ouput provided by the directive back to the ngModel. When operating in a single selection mode: repeated selections of the same item - selectes that item repeatedly, if you wish to de-select an item without selecting another, use null. When operating in a multiple selections mode: selecting a selected item - de-select that item.
You only need to implement those events which you intend to respond to. If you are not intending to disable any items or reset the directive, then you do not need to implement those events.
The event is transmitted by the transcluded directive or one of its children with the 'id' of the of the newly selected item. This is usually done from the directive's 'click' event handler (but that of course depends on your logic). Use the conteroller $scope (or scope from link function) rather than $rootscope to transmit the event if use more than one revive directives in your page. The following piece of code is the kind of logic you will need to implement in your directive:
$scope.clickEvent = function (event, id) {
if (I'm Disabled - do nothing) {
return;
}
$scope.$emit(MessageItemSelected, id);
};
The event is broadcasted from the directive to its transcluded directive and its children in response to a change in the list of selected items, either by user interaction or model intervention. This gives the transcluded directive and/or its children the opprtunity to update (redraw) its/their selected and non-selected items (areas) accordingly. br> br> The following piece of code is the kind of logic you will need to implement in your directive:
$scope.$on(MessageSelectionChanged, function (event, selections) {
if (I'm in selected list) {
show that I'm selected
} else {
show my normal representation
}
});
Whenever the list of disabled items is changes by the model, the directive will broadcast the updated list to its transcluded directive and its children. This will give the transcluded directive and its children the chance to update (redraw) the view based on changes made by the model. br> br> The following piece of code is the kind of logic you will need to implement in your directive:
$scope.$on(MessageDisableItems, function (event, disabledList) {
if (I'm in list of disabled items) {
disable myself
} else {
enable myself
}
});
You should use the reset event only if you made major changes to the underline directive in a way that requires the transcluded directive and/or its children to start afresh. br> br> The following piece of code is the kind of logic you will need to implement in your directive:
$scope.$on(MessageSelectReset, function (event) {
reset logic - such as if I'm selected, de-select myself
});
When you install with bower, you only get the javascript source file and the README.md file. If you want to download the example, get the zip or tar files from Github.