I have a modal view(.jsp) that has integrated directive (named as 'querybuilder', Yellow part in the picture - a js file). Controller(named as 'addEditRuleSetCtrl') and directive is included from upper level and inclusion seems fine. We have initiated the directive from the view as :
<div ng-init="addEditRuleSetCtrl.initSelectors()">
<query-builder group="addEditRuleSetCtrl.filter.group"
rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
fields="addEditRuleSetCtrl.fieldCodes"
></query-builder>
</div>
Where "addEditRuleSetCtrl.initSelectors()" initiates all the params passed to the directive as :
self.initSelectors = function()
{
self.getRuleConditionOperators();
self.getRuleConditionSetOperators();
self.fieldCodes = self.getCorrespondingFields();
console.log("initSelectors : fieldCodes: " + JSON.stringify(self.fieldCodes ));
}
self.getCorrespondingFields = function()
{
return self.origin == 'DDE' ? self.fieldsDDE : self.fieldsATT;
};
And the params were declared in the controller in this way:
self.fieldsDDE = [
{ name: 'FirstnameDDE' },
{ name: 'LastnameDDE' },
{ name: 'BirthdateDDE' },
{ name: 'CityDDE' },
{ name: 'CountryDDE' }
];
self.fieldsATT = [
{ name: 'FirstnameATT' },
{ name: 'LastnameATT' },
{ name: 'BirthdateATT' },
{ name: 'CityATT' },
{ name: 'CountryATT' }
];
self.fieldCodes = [];
self.ruleConditionSetOperators = [];
self.ruleConditionOperators = [];
The problem is: one ( the param 'fieldCodes')of the four params that passed to the directive is "undefined" Although they were defined ,passed in similar way. I have cleaned the cache and tested all possible ways but nothing made any difference.As a result the associated dropdown is empty (in the red-arrowed dropdown in the screenshot).Any clue?
The full view :
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="UTF-8"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<link
href="<c:url value='aviato/ruleEngine/addEditRuleSet/css/addeditruleset.css' />"
rel="stylesheet">
</link>
<%--<script src="aviato/ruleEngine/addEditRuleSet/directive/addEditRuleSet_directive.js"></script>--%>
<form name="addEditRuleSetModalForm" novalidate class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
{{addEditRuleSetCtrl.windowHeader}}
<button type="button" class="btn btn-danger btn-sm pull-right"
ng-click="addEditRuleSetCtrl.close()" data-toggle="uibtooltip" title="Cancel" >
<span class="glyphicon glyphicon-remove-sign"></span>
</button>
</h4>
</div>
<div class="modal-body">
Hello world [origin] : {{ addEditRuleSetCtrl.origin }}
<br />
Hello world [iceField] : {{ addEditRuleSetCtrl.iceField }}
Output: {{ addEditRuleSetCtrl.output }}
<div class="alert alert-info">
<strong>Example Output</strong><br>
Output: {{ addEditRuleSetCtrl.output }}
</div>
<div ng-init="addEditRuleSetCtrl.initSelectors()">
<query-builder group="addEditRuleSetCtrl.filter.group"
rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
fields="addEditRuleSetCtrl.fieldCodes"
></query-builder>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" ng-click="addEditRuleSetCtrl.test()" data-toggle="tooltip" ><span class="glyphicon glyphicon-ok-sign" ></span></button><span></span>
</div>
</div>
</form>
<script type="text/ng-template" id="/queryBuilderDirective.html">
<div class="alert alert-warning alert-group">
<div class="form-inline">
<select ng-options="o as o.operator for o in ruleConditionSetOperators" ng-model="group.operator" class="form-control input-sm"></select>
<button style="margin-left: 5px" ng-click="addCondition()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Condition</button>
<button style="margin-left: 5px" ng-click="addGroup()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Group</button>
<button style="margin-left: 5px" ng-click="removeGroup()" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span> Remove Group</button>
</div>
<div class="group-conditions">
<div ng-repeat="rule in group.rules | orderBy:'index'" class="condition">
<div ng-switch="rule.hasOwnProperty('group')">
<div ng-switch-when="true">
<query-builder group="rule.group"
rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
fields="addEditRuleSetCtrl.fieldCodes"
></query-builder>
</div>
<div ng-switch-default="ng-switch-default">
<div class="form-inline">
<select ng-options="t.name as t.name for t in fields" ng-model="rule.field" class="form-control input-sm"></select>
<select style="margin-left: 5px" ng-options="c as c.operator for c in ruleConditionOperators" ng-model="rule.condition" class="form-control input-sm"></select>
<input style="margin-left: 5px" type="text" ng-model="rule.data" class="form-control input-sm"/>
<button style="margin-left: 5px" ng-click="removeCondition($index)" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</script>
The Directive:
AddEditRuleSetApp.directive('queryBuilder', ['$compile', function ($compile) {
return {
restrict: 'E',
scope: {
group: '=',
ruleConditionOperators: '=',
ruleConditionSetOperators: '=',
fields: '='
},
templateUrl: '/queryBuilderDirective.html',
compile: function (element, attrs) {
var content, directive;
content = element.contents().remove();
return function (scope, element, attrs) {
scope.fields = scope.$parent.fieldCodes;
scope.ruleConditionOperators = scope.$parent.ruleConditionOperators;
scope.ruleConditionSetOperators = scope.$parent.ruleConditionSetOperators;
window.alert("HEYYYYYY I'M CHANGING!!!!!! "
+ JSON.stringify(scope.group)
+ " ; "+ JSON.stringify(scope.ruleConditionOperators)
+ " ; "+ JSON.stringify(scope.ruleConditionSetOperators)
+ " ; "+ JSON.stringify(scope.fields));
scope.addCondition = function () {
scope.group.rules.push({
condition: '=',
field: 'Firstname',
data: ''
});
};
scope.removeCondition = function (index) {
scope.group.rules.splice(index, 1);
};
scope.addGroup = function () {
scope.group.rules.push({
group: {
operator: 'AND',
rules: []
}
});
};
scope.removeGroup = function () {
"group" in scope.$parent && scope.$parent.group.rules.splice(scope.$parent.$index, 1);
};
directive || (directive = $compile(content));
element.append(directive(scope, function ($compile) {
return $compile;
}));
}
}
}
}]);
The controller:
AddEditRuleSetApp.controller( 'AddEditRuleSetModalController', [ '$scope', '$rootScope', '$uibModalInstance','RuleEngineService', 'origin', 'iceField','FileService',
function( $scope, $rootScope , $uibModalInstance, RuleEngineService, origin, iceField, FileService )
{
var self = this;
self.origin = origin;
self.iceField = iceField;
self.data = '{"group": {"operator": "AND","rules": []}}';
self.output = 'bologna';
self.filter = JSON.parse(self.data);
self.fieldsDDE = [
{ name: 'FirstnameDDE' },
{ name: 'LastnameDDE' },
{ name: 'BirthdateDDE' },
{ name: 'CityDDE' },
{ name: 'CountryDDE' }
];
self.fieldsATT = [
{ name: 'FirstnameATT' },
{ name: 'LastnameATT' },
{ name: 'BirthdateATT' },
{ name: 'CityATT' },
{ name: 'CountryATT' }
];
self.fieldCodes = [];
self.ruleConditionSetOperators = [];
self.ruleConditionOperators = [];
self.initSelectors = function()
{
self.getRuleConditionOperators();
self.getRuleConditionSetOperators();
self.fieldCodes = self.getCorrespondingFields();
console.log("initSelectors : fieldCodes: " + JSON.stringify(self.fieldCodes ));
}
self.getRuleConditionOperators = function()
{
if ( self.ruleConditionOperators.length == 0 )
{
RuleEngineService.getAllRuleConditionOperators()
.then(
function( d )
{
self.ruleConditionOperators = d;
},
function( errResponse )
{
console.error( 'Error while fetching rule-condition-operators' );
}
);
}
return self.ruleConditionOperators;
};
self.getRuleConditionSetOperators = function()
{
if ( self.ruleConditionSetOperators.length == 0 )
{
RuleEngineService.getAllRuleConditionSetOperators()
.then(
function( d )
{
self.ruleConditionSetOperators = d;
},
function( errResponse )
{
console.error( 'Error while fetching rule-condition-operators' );
}
);
}
return self.ruleConditionSetOperators;
};
self.htmlEntities = function(str)
{
return String(str).replace(/</g, '<').replace(/>/g, '>');
};
self.displayErrorMessages = false;
self.createSuccess = '';
self.createHeader = '';
self.backendErr = "";
self.windowHeader = "Create/Edit Rule Group";
self.close = function()
{
$uibModalInstance.close();
};
self.getCorrespondingFields = function()
{
return self.origin == 'DDE' ? self.fieldsDDE : self.fieldsATT;
};
self.computed = function(group)
{
window.alert("Inside controller: computed");
if (!group) return "";
for (var str = "(", i = 0; i < group.rules.length; i++) {
i > 0 && (str += " <strong>" + group.operator + "</strong> ");
str += group.rules[i].group ?
self.computed(group.rules[i].group) :
group.rules[i].field + " " +
//htmlEntities(group.rules[i].condition)
group.rules[i].condition
+ " " + group.rules[i].data;
}
return str + ")";
};
$scope.$watch('filter', function (newValue)
{
//self.json = JSON.stringify(newValue, null, 2);
//TODO: do we need this??
//if( angular.isDefined( newValue ) )
//{
//window.alert("I am here again in watch!!!!" + JSON.stringify(newValue));
self.output = self.computed(newValue);
// self.ruleConditionOperators = self.getAllRuleConditionOperators();
// window.alert("I am HERE - end watch!!!!");
//}
}, true);
self.test = function()
{
window.alert(JSON.stringify( self.filter) );
};
}
]);
The screenshot:
At my first glance of the directive, I think you probably should change from:
var test = scope.$parent.fieldCodes;
scope.fields = scope.$parent.fields;
To:
//var test = scope.$parent.fieldCodes;
scope.fields = scope.$parent.fieldCodes;
Related
I use a directive to add images and radio buttons (per image). I also create dynamically ng-models. Now with my approach, the radio buttons will not be set. What's wrong? Thank your for your hints.
JS
.directive('oct', function() {
return {
restrict : 'E',
template : `
<div class="oImg" ng-repeat="image in images">
<a href="#" class="removeImage" ng-click="vm.removeImg(image)"
ng-show="isActive($index)"><i class="fa fa-trash"></i>
</a>
<img ng-src="{$image.src$}" class="images-item"
ng-show="isActive($index)"><span ng-show="isActive($index)" class="imgName">{$image.name$}</span>
<div class="sideSelect" ng-show="isActive($index)">
<div class="checkbox"><label>
<input type="radio" ng-model="eyeChanger[image.name]"
name="optionsEye"
ng-change="vm.changeEye(image, eyeChanger[image.name])"
value="RA">RA</label>
</div>
<div class="checkbox"><label>
<input type="radio" ng-model="eyeChanger[image.name]"
ng-change="vm.changeEye(image, eyeChanger[image.name])"
name="optionsEye" value="LA">LA</label>
</div>
</div>
</div>
`,
controller : ['$scope', '$http',
function($scope, $http) {
$scope._Index = 0;
// if current image is same as requested image
$scope.isActive = function(index) {
return $scope._Index === index;
};
// prev image
$scope.showPrev = function() {
if ($scope._Index != 0) {
$scope._Index = ($scope._Index > 0) ? --$scope._Index : $scope.images.length - 1;
}
};
// next image
$scope.showNext = function() {
if ($scope._Index < $scope.images.length - 1) {
$scope._Index = ($scope._Index < $scope.images.length - 1) ? ++$scope._Index : 0;
};
};
}]
};
})
vm.changeEye = function(img, value) {
$scope['eyeChanger'+img.name] = value;
...
Use:
vm.changeEye = function(img, value) {
̶$̶s̶c̶o̶p̶e̶[̶'̶e̶y̶e̶C̶h̶a̶n̶g̶e̶r̶'̶+̶i̶m̶g̶.̶n̶a̶m̶e̶]̶ ̶=̶ ̶v̶a̶l̶u̶e̶;̶
$scope.eyeChanger[img.name] = value;
...
There is no need to do this with ng-change as the ng-model directive does it automatically.
<div ng-repeat="image in images">
<img ng-src="{{image.src}}" />
<div class="checkbox"><label>
<input type="radio" ng-model="eyeChanger[image.name]"
name="optionsEye"
̶n̶g̶-̶c̶h̶a̶n̶g̶e̶=̶"̶v̶m̶.̶c̶h̶a̶n̶g̶e̶E̶y̶e̶(̶i̶m̶a̶g̶e̶,̶ ̶e̶y̶e̶C̶h̶a̶n̶g̶e̶r̶[̶i̶m̶a̶g̶e̶.̶n̶a̶m̶e̶]̶)̶"̶
value="RA">RA</label>
</div>
<div class="checkbox"><label>
<input type="radio" ng-model="eyeChanger[image.name]"
̶n̶g̶-̶c̶h̶a̶n̶g̶e̶=̶"̶v̶m̶.̶c̶h̶a̶n̶g̶e̶E̶y̶e̶(̶i̶m̶a̶g̶e̶,̶ ̶e̶y̶e̶C̶h̶a̶n̶g̶e̶r̶[̶i̶m̶a̶g̶e̶.̶n̶a̶m̶e̶]̶)̶"̶
name="optionsEye" value="LA">LA</label>
</div>
</div>
The radio buttons can be initialized:
$scope.images = [
{ name: "name1", src: "..." },
{ name: "name2", src: "..." },
// ...
];
$scope.eyeChanger = {
name1: "RA",
name2: "LA",
// ...
};
I have an angularJS application. I have implemented a generic workflow using $routeProvider, templateUrl & Controllers.
Each step(screen) is verified when user click on next button and moves to the next step if validation passes. If validation fails user is required to fix all the error, displayed on the screen, before moving to next step.
When user has visited all the screens(passed validation for each screen) all the breadcrumbs get enabled and now user can move freely between those steps/breadcrumbs.
Requirement:
Now I want to allow user to move freely between steps by clicking on the breadcrumbs and when user clicks on the lodge button, on the last step, validation for current as well as for all previous steps should be invoked, and clicking on the error user should be able taken to the relevant step/screen.
Also I want to keep the functionality of validating the individual steps on the click of next button.
As you can see each screen has a separate controller along with the scope.
Once user move from one step to another it can't access the previous scope.
Initially I thought of storing scope of each screen in an array, but once I move between steps new scope is created (as it should) and only current step has a form with valid data model and "valid" flag as false.
Form object at current step
Form object of other screen without and fields attached
I'm not very well versed with Angularjs and trying to get some idea weather
Is it possible what I'm trying to achieve keeping the existing functionality intact. (My understanding is that I can't have a single controller since I need to keep the functionality of validating each step individually)?
Is there a better way to trying to achieve this functionality?
PS: Sadly I can't upgrade to newer version of Angular.
Any help will be highly appreciated.
Form Validation
validator.validate = function($scope, submitCallback, additionalOptions) {
var options = {};
$.extend(options, commonOptions, additionalOptions);
var form = $scope[options.formName];
hideErrorMessages(options.errorContainerSelectorId);
if (form.$valid) {
submitCallback();
return;
}
showErrorMessages({message: composeAngularValidationErrors(form),
errorContainer: $('#' + options.errorContainerSelectorId)});
};
View:
<#assign temp=JspTaglibs["http://www.test.com/tags"]>
<div ng-controller="LodgeApplicationWorkflowController" ng-cloak>
<workflow-breadcrumbs></workflow-breadcrumbs>
{{model | json}}
<div ng-view>
</div>
<script type="text/ng-template" id="applicant-details">
<form name="form" method="post" action="#" class="standard">
<h3>Primary contact details</h3>
<div class="row">
<div class="span3">
<label for="owner-primary-contact">Primary contact:</label>
<select class="span3" id="owner-primary-contact" required name="applicantDetails.primaryContact"
ng-model="model.applicantDetails.primaryContactId"
ng-options="user.id as user.fullName for user in refData.contactInfos"
>
<option value=""></option>
</select>
</div>
<div class="span3">
<label for="owner-primary-contact-phone">Phone:</label>
<input type="text" class="span3" id="owner-primary-contact-phone" name="applicantDetails.primaryContactPhone"
readonly
ng-model="model.applicantDetails.primaryContactPhone"/>
</div>
<div class="span3">
<label for="owner-primary-contact-email">Email:</label>
<input type="text" class="span3" id="owner-primary-contact-email" name="applicantDetails.primaryContactEmail"
readonly
ng-model="model.applicantDetails.primaryContactEmail"/>
</div>
</div>
</form>
</script>
<script type="text/ng-template" id="lgc-methodology">
<form name="form" method="post" action="#" class="standard">
<h3>Describe the Your Methodology</h3>
<div class="row">
<div class="span9">
<label for="methodology">Describe the methodology which you propose to employ:
</label>
<textarea class="span9" id="methodology" name="methodology"
rows="10"
ng-maxlength="4000"
ng-model="model.methodology" required>
</textarea>
</div>
</div>
</form>
</script>
<script type="text/ng-template" id="approval-details">
<form name="form" method="post" action="#" class="standard">
<div class="row" ng-if="model.approvalDetails.planningApprovalsObtained === 'true'">
<div class="span9">
<label for="planning-approvals-details">Approval details:</label>
<textarea class="span6" id="planning-approvals-details"
name="approvalDetails.planningApprovalDetails"
ng-if="model.approvalDetails.planningApprovalsObtained === 'true'"
required ng-maxlength="4000"
ng-model="model.approvalDetails.planningApprovalDetails"></textarea>
</div>
</div>
<div class="row" ng-if="model.approvalDetails.planningApprovalsObtained === 'false'">
<div class="span9">
<label for="planning-approvals-details">Reasons:</label>
<textarea class="span6" id="planning-approvals-details"
name="approvalDetails.planningApprovalDetails"
ng-if="model.approvalDetails.planningApprovalsObtained === 'false'"
required ng-maxlength="4000"
ng-model="model.approvalDetails.planningApprovalDetails"></textarea>
</div>
</div>
<div >
<div class="row" >
<div class="span9">
<label for="environment-approval-details">Approval details:</label>
<textarea class="span6" id="environment-approval-details"
name="approvalDetails.environmentApprovalDetails"
ng-maxlength="4000"
ng-required="model.approvalDetails.environmentApprovalsObtained === 'true'"
ng-model="model.approvalDetails.environmentApprovalDetails"></textarea>
</div>
</div>
<div class="row" ng-if="model.approvalDetails.environmentApprovalsObtained === 'false'">
<div class="span9">
<label for="environment-approval-details">Reasons:</label>
<textarea class="span6" id="environment-approval-details"
name="approvalDetails.environmentApprovalDetails"
ng-maxlength="4000"
ng-required="model.approvalDetails.environmentApprovalsObtained === 'false'"
ng-model="model.approvalDetails.environmentApprovalDetails"></textarea>
</div>
</div>
</div>
</form>
</script>
<script type="text/ng-template" id="confirmation">
<form id="form" method="post" name="form" action="#" class="standard">
<div class="row">
<div class="span9">
<span class="checkbox inline">
<label for="confirm-information">
<input type="checkbox" id="confirm-information" name="confirmInformation"
ng-model="model.Confirmed" required />
I confirm that all the details are correct
</label>
</span>
</div>
</div>
</form>
</script>
<div class="form-actions">
<input type="button" class="btn" value="Cancel" ng-click="cancel()"/>
<div class="pull-right btn-toolbar">
<input id="previous" type="button" class="btn" value="Previous"
ng-click="workflow.handlePrevious()" ng-show="!workflow.isFirstStep()" ng-cloak/>
<input id="save-and-close" type="button" class="btn" value="Save draft and close"
ng-show="model.canSaveDraftAndClose && !workflow.isLastStep()"
ng-click="saveDraftAndClose()" ng-cloak/>
<input id="submit" type="button" class="btn btn-primary" value="{{workflow.getNextLabel()}}"
ng-disabled="!workflow.canNavigateToNextStep()"
ng-click="workflow.handleNext()" ng-cloak/>
</div>
</div>
</div>
Controllers:
angular.module('Test')
.config(function ($routeProvider) {
$routeProvider
.when('/applicant-details', {
templateUrl: 'applicant-details',
controller: 'ApplicantDetailsController'
})
.when('/methodology', {
templateUrl: 'methodology',
controller: 'MethodologyController'
})
.when('/approval-details', {
templateUrl: 'approval-details',
controller: 'ApprovalDetailsController'
})
.when('/confirmation', {
templateUrl: 'confirmation',
controller: 'ConfirmationController'
})
.otherwise({redirectTo: '/applicant-details'});
})
;
function LodgeApplicationWorkflowController( $scope, ctx, workflow, workflowModel, server, navigation) {
workflow.setSteps([
{
name: 'Applicant details',
path: 'applicant-details',
validationUrl: '/some url'
},
{
name: 'Methodology',
path: 'methodology'
},
{
name: 'Approval details',
path: 'approval-details'
},
{
name: 'Confirmation',
path: 'confirmation',
nextButtonLabel: 'Lodge',
onSubmit: function () {
disable('submit');
$scope.model.lodgeApplication = JSON.stringify($scope.model);
server.post({
url: ctx + '/some url' ,
json: JSON.stringify($scope.model),
successHandler: function () {
},
completeHandler: function () {
enable('submit');
},
validationErrorTitle: 'The request could not be completed because of the following issues:'
});
}
}
]);
function postInit() {
// To DO
}
function loadLodgement() {
// To DO
}
$scope.workflow = workflow;
$scope.model = workflowModel.model();
$scope.refData = workflowModel.refData();
$scope.accountDetails = {};
$scope.userDetails = {};
$scope.model.canSaveDraftAndClose = true;
server.getReferenceData([
'/URL1'
], function onAllReferenceDataRetrieved(data) {
$scope.$apply(function() {
$scope.refData.fuelSourceOptions = data[0];
$scope.refData.contactInfos = data[1].result;
$scope.refData.address = data[2];
$scope.refData.yearOptions = data[3];
$scope.refData.nmiNetworkOptions = data[4];
});
loadLodgement();
loadDraft();
});
$scope.saveDraftAndClose = function () {
var command = {};
server.post({
url: ctx + '/URL',
json: JSON.stringify(command),
successHandler: function (data) {
},
validationErrorTitle: 'The request could not be completed because of the following issues:'
});
};
$scope.cancel = function() {
navigation.to('Some URL');
};
}
function ApplicantDetailsController($scope, workflow, workflowModel, addressService, applicantServiceFactory) {
var applicantService = applicantServiceFactory();
if (!workflow.setCurrentScope($scope)) {
return;
}
$scope.model = workflowModel.model();
$scope.model.applicantDetails = _.extend({
owner: { address: {} },
operator: { address: {} }
}, $scope.model.applicantDetails);
addressService.initialiseAddress($scope.model.applicantDetails);
}
function MethodologyController($scope, workflow, workflowModel) {
if (!workflow.setCurrentScope($scope)) {
return;
}
$scope.model = workflowModel.model();
// Do something
}
function ApprovalDetailsController($scope, workflow, workflowModel) {
if (!workflow.setCurrentScope($scope)) {
return;
}
$scope.model = workflowModel.model();
$scope.model.approvalDetails = $scope.model.approvalDetails || {};
// Do something
}
function ConfirmationController($scope, workflow, workflowModel) {
if (!workflow.setCurrentScope($scope)) {
return;
}
$scope.model = workflowModel.model();
$scope.model.confirmation = { owner: {}, operator: {} };
$scope.model.confirmationConfirmed = false;
// Do something
}
WorkFlow
angular.module('Test')
.service('workflowModel', function() {
var refData = {};
var workflowModel = {};
return {
reset: function() {
workflowModel = {};
},
get : function(fragmentName) {
if (!workflowModel[fragmentName]) {
workflowModel[fragmentName] = {};
}
return workflowModel[fragmentName];
},
model : function(newWorkflowModel) {
if (newWorkflowModel) {
workflowModel = newWorkflowModel;
} else {
return workflowModel;
}
},
refData : function() {
return refData;
},
toJSON: function() {
return JSON.stringify(workflowModel);
}
};
})
.directive('workflowBreadcrumbs', function() {
return {
restrict: 'E',
template: '<ul class="breadcrumb">' +
'<li ng-class="{\'active\': workflow.currentStepPathIs(\'{{step.path}}\')}" ng-repeat="step in workflow.configuredSteps" ng-cloak>' +
'{{step.name}}<span ng-if="!workflow.visitedStep(step.path)">{{step.name}}</span><span class="divider" ng-if="!$last">/</span>' +
'</li>' +
'</ul>',
transclude: true
};
})
.factory('workflow', function ($rootScope, $location, server, validator, workflowModel, $timeout) {
function getStepByPath(configuredSteps, stepPath) {
return _.find(configuredSteps, function(step) { return step.path === stepPath; });
}
function validateServerSide(currentStep, callback) {
if (currentStep.validationUrl) {
server.post({
url: ctx + currentStep.validationUrl,
json : JSON.stringify(workflowModel.model()),
successHandler : function() {
$rootScope.$apply(function() {
callback();
});
}
});
} else {
callback();
}
}
function navigateNext(configuredSteps, currentStep) {
var currentStepIndex = _.indexOf(configuredSteps, currentStep);
navigateTo(configuredSteps[currentStepIndex + 1]);
}
function navigateTo(step) {
$location.path(step.path);
}
return {
setCurrentScope: function(scope) {
this.currentScope = scope;
this.firstStep = _.first(this.configuredSteps);
this.lastStep = _.last(this.configuredSteps);
this.currentStep = this.getCurrentStep();
if (!(this.currentStep === this.firstStep || this.hasEverVisitedSteps())) {
this.reset();
return false;
}
this.currentStep.visited = true;
hideErrorMessages();
this.focusOnFirstInputElementAndScrollToTop();
return true;
},
setSteps: function(steps) {
this.configuredSteps = steps;
},
focusOnFirstInputElementAndScrollToTop: function() {
$timeout(function() {
angular.element('select, input, textarea, button', '[ng-view]')
.filter(':visible')
.first()
.one('focus', scrollToTitle)
.focus();
scrollToTitle();
});
},
hasEverVisitedSteps: function() {
return _.find(this.configuredSteps, function(step) {
return step.visited;
}) !== undefined;
},
isFirstStep: function() {
return this.currentStep === this.firstStep;
},
isLastStep: function() {
return this.currentStep === this.lastStep;
},
currentStepPathIs: function(stepPath) {
return this.currentStep && stepPath === this.currentStep.path;
},
visitedStep: function(stepPath) {
return getStepByPath(this.configuredSteps, stepPath).visited;
},
getNextLabel: function() {
if (this.currentStep && this.currentStep.nextButtonLabel) {
return this.currentStep.nextButtonLabel;
}
return (this.isLastStep()) ? 'Submit' : 'Next';
},
handlePrevious: function() {
if (!this.isFirstStep()) {
var currentStepIndex = _.indexOf(this.configuredSteps, this.currentStep);
navigateTo(this.configuredSteps[currentStepIndex - 1]);
}
},
canNavigateToNextStep: function() {
return this.currentScope && (!this.currentScope.canSubmit || this.currentScope.canSubmit());
},
handleNext: function() {
var configuredSteps = this.configuredSteps;
var currentStep = this.currentStep;
if(this.isLastStep()) {
this.validateCurrentStep(this.currentStep.onSubmit);
} else {
this.validateCurrentStep(function() {
navigateNext(configuredSteps, currentStep);
});
}
},
validateCurrentStep: function(callback) {
var currentStep = this.currentStep;
if (this.currentScope.form) {
validator.validate(this.currentScope, function() {
validateServerSide(currentStep, callback);
});
} else {
validateServerSide(currentStep, callback);
}
},
getCurrentStep: function() {
return getStepByPath(this.configuredSteps, $location.path().substring(1));
},
reset: function() {
_.each(this.configuredSteps, function(step) { step.visited = false; });
this.firstStep.visited = true;
navigateTo(this.firstStep);
}
};
});
We are following an example from http://mfauveau.github.io/angular-query-builder/ and modifying it to fit into our requirement.
We have a modal view(.jsp) that has integrated directive (named as 'querybuilder', Yellow part in the picture - a js file). Controller(named as 'addEditRuleSetCtrl') and directive is included from upper level and inclusion seems fine.
We have initiated the directive from the view (.jsp file)as :
<div ng-init="addEditRuleSetCtrl.initSelectors()">
<query-builder group="addEditRuleSetCtrl.filter.group"
rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
fields="addEditRuleSetCtrl.getCorrespondingFields()"
></query-builder>
</div>
And we have included the template for the directive in view/.jsp as (notice that the directive is initiated here again when new group is created):
<script type="text/ng-template" id="/queryBuilderDirective.html">
<div class="alert alert-warning alert-group">
<div class="form-inline">
<select ng-options="o as o.operator for o in ruleConditionSetOperators" ng-model="group.operator" class="form-control input-sm"></select>
<button style="margin-left: 5px" ng-click="addCondition()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Condition</button>
<button style="margin-left: 5px" ng-click="addGroup()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Group</button>
<button style="margin-left: 5px" ng-click="removeGroup()" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span> Remove Group</button>
</div>
<div class="group-conditions">
<div ng-repeat="rule in group.rules | orderBy:'index'" class="condition">
<div ng-switch="rule.hasOwnProperty('group')">
<div ng-switch-when="true">
<query-builder group="rule.group"
rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
fields="addEditRuleSetCtrl.getCorrespondingFields()"
></query-builder>
</div>
<div ng-switch-default="ng-switch-default">
<div class="form-inline">
<select ng-options="t.name as t.name for t in fields" ng-model="rule.field" class="form-control input-sm"></select>
<select style="margin-left: 5px" ng-options="c as c.operator for c in ruleConditionOperators" ng-model="rule.condition" class="form-control input-sm"></select>
<input style="margin-left: 5px" type="text" ng-model="rule.data" class="form-control input-sm"/>
<button style="margin-left: 5px" ng-click="removeCondition($index)" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
Our problem is : the first layer of the tree/group has right value of all the parameters(fields,rule-condition-set-operators,rule-condition-operators). Hence, in the first layer , all the associated dropdowns have displayed right values. But when I click the button "add group" in the first layer, all the params are now "undefined" and hence all the dropdowns starting from the 2nd layer is empty ( showed by the red arrow sign in the picture).
Questions are :
Is that correct that starting from the 2nd layer of group, the
params are out of scope of the controller because they are defined
outside the view block?
How to make the params available to all layers of the group?
Here is the view (.jsp file):
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="UTF-8"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<link
href="<c:url value='aviato/ruleEngine/addEditRuleSet/css/addeditruleset.css' />"
rel="stylesheet">
</link>
<%--<script src="aviato/ruleEngine/addEditRuleSet/directive/addEditRuleSet_directive.js"></script>--%>
<form name="addEditRuleSetModalForm" novalidate class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
{{addEditRuleSetCtrl.windowHeader}}
<button type="button" class="btn btn-danger btn-sm pull-right"
ng-click="addEditRuleSetCtrl.close()" data-toggle="uibtooltip" title="Cancel" >
<span class="glyphicon glyphicon-remove-sign"></span>
</button>
</h4>
</div>
<div class="modal-body">
Hello world [origin] : {{ addEditRuleSetCtrl.origin }}
<br />
Hello world [iceField] : {{ addEditRuleSetCtrl.iceField }}
Output: {{ addEditRuleSetCtrl.output }}
<div class="alert alert-info">
<strong>Example Output</strong><br>
Output: {{ addEditRuleSetCtrl.output }}
</div>
<div ng-init="addEditRuleSetCtrl.initSelectors()">
<query-builder group="addEditRuleSetCtrl.filter.group"
rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
fields="addEditRuleSetCtrl.getCorrespondingFields()"
></query-builder>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" ng-click="addEditRuleSetCtrl.test()" data-toggle="tooltip" ><span class="glyphicon glyphicon-ok-sign" ></span></button><span></span>
</div>
</div>
</form>
<script type="text/ng-template" id="/queryBuilderDirective.html">
<div class="alert alert-warning alert-group">
<div class="form-inline">
<select ng-options="o as o.operator for o in ruleConditionSetOperators" ng-model="group.operator" class="form-control input-sm"></select>
<button style="margin-left: 5px" ng-click="addCondition()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Condition</button>
<button style="margin-left: 5px" ng-click="addGroup()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Group</button>
<button style="margin-left: 5px" ng-click="removeGroup()" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span> Remove Group</button>
</div>
<div class="group-conditions">
<div ng-repeat="rule in group.rules | orderBy:'index'" class="condition">
<div ng-switch="rule.hasOwnProperty('group')">
<div ng-switch-when="true">
<query-builder group="rule.group"
rule-condition-operators="addEditRuleSetCtrl.ruleConditionOperators"
rule-condition-set-operators="addEditRuleSetCtrl.ruleConditionSetOperators"
fields="addEditRuleSetCtrl.getCorrespondingFields()"
></query-builder>
</div>
<div ng-switch-default="ng-switch-default">
<div class="form-inline">
<select ng-options="t.name as t.name for t in fields" ng-model="rule.field" class="form-control input-sm"></select>
<select style="margin-left: 5px" ng-options="c as c.operator for c in ruleConditionOperators" ng-model="rule.condition" class="form-control input-sm"></select>
<input style="margin-left: 5px" type="text" ng-model="rule.data" class="form-control input-sm"/>
<button style="margin-left: 5px" ng-click="removeCondition($index)" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</script>
The Directive (.js file):
AddEditRuleSetApp.directive('queryBuilder', ['$compile', function ($compile) {
return {
restrict: 'E',
scope: {
group: '=',
ruleConditionOperators: '=',
ruleConditionSetOperators: '=',
fields: '='
},
templateUrl: '/queryBuilderDirective.html',
compile: function (element, attrs) {
var content, directive;
content = element.contents().remove();
return function (scope, element, attrs) {
scope.addCondition = function () {
window.alert("[addCondition] : " + "group : " + JSON.stringify( scope.group) + "...BREAK..."
+"fields : " + JSON.stringify( scope.ruleConditionOperators) + "...BREAK..."
+"Condition : "+JSON.stringify(scope.ruleConditionOperators) + "...BREAK..."
+"Condition set: "+JSON.stringify(scope.ruleConditionSetOperators));
scope.group.rules.push({
condition: '=',
field: 'Firstname',
data: ''
});
};
scope.removeCondition = function (index) {
scope.group.rules.splice(index, 1);
};
scope.addGroup = function () {
window.alert("[addGroup] :" + "group : " + JSON.stringify( scope.group) + "...BREAK..."
+" fields : " + JSON.stringify( scope.fields) + "...BREAK..."
+"Condition : "+JSON.stringify(scope.ruleConditionOperators) + "...BREAK..."
+"Condition set: "+JSON.stringify(scope.ruleConditionSetOperators));
scope.group.rules.push({
group: {
operator: 'AND',
rules: []
}
});
};
scope.removeGroup = function () {
"group" in scope.$parent && scope.$parent.group.rules.splice(scope.$parent.$index, 1);
};
directive || (directive = $compile(content));
element.append(directive(scope, function ($compile) {
return $compile;
}));
}
}
}
}]);
The controller :
AddEditRuleSetApp.controller( 'AddEditRuleSetModalController', [ '$scope', '$rootScope', '$uibModalInstance','RuleEngineService', 'origin', 'iceField','FileService',
function( $scope, $rootScope , $uibModalInstance, RuleEngineService, origin, iceField, FileService )
{
var self = this;
self.origin = origin;
self.iceField = iceField;
self.data = '{"group": {"operator": "AND","rules": []}}';
self.output = 'bologna';
self.fieldsDDE = [
{ name: 'FirstnameDDE' },
{ name: 'LastnameDDE' },
{ name: 'BirthdateDDE' },
{ name: 'CityDDE' },
{ name: 'CountryDDE' }
];
self.fieldsATT = [
{ name: 'FirstnameATT' },
{ name: 'LastnameATT' },
{ name: 'BirthdateATT' },
{ name: 'CityATT' },
{ name: 'CountryATT' }
];
self.ruleConditionSetOperators = [
];
self.ruleConditionOperators = [
];
self.filter = JSON.parse(self.data);
self.initSelectors = function()
{
self.getRuleConditionOperators();
self.getRuleConditionSetOperators();
}
self.getRuleConditionOperators = function()
{
if ( self.ruleConditionOperators.length == 0 )
{
RuleEngineService.getAllRuleConditionOperators()
.then(
function( d )
{
self.ruleConditionOperators = d;
},
function( errResponse )
{
console.error( 'Error while fetching rule-condition-operators' );
}
);
}
return self.ruleConditionOperators;
};
self.getRuleConditionSetOperators = function()
{
if ( self.ruleConditionSetOperators.length == 0 )
{
RuleEngineService.getAllRuleConditionSetOperators()
.then(
function( d )
{
self.ruleConditionSetOperators = d;
},
function( errResponse )
{
console.error( 'Error while fetching rule-condition-operators' );
}
);
}
return self.ruleConditionSetOperators;
};
self.htmlEntities = function(str)
{
return String(str).replace(/</g, '<').replace(/>/g, '>');
};
self.displayErrorMessages = false;
self.createSuccess = '';
self.createHeader = '';
self.backendErr = "";
self.windowHeader = "Create/Edit Rule Group";
self.close = function()
{
$uibModalInstance.close();
};
self.getCorrespondingFields = function()
{
// window.alert("---------------Reached client side controller to getCorrespondingFields");
return self.origin == 'DDE' ? self.fieldsDDE : self.fieldsATT;
};
self.computed = function(group)
{
window.alert("Inside controller: computed");
if (!group) return "";
for (var str = "(", i = 0; i < group.rules.length; i++) {
i > 0 && (str += " <strong>" + group.operator + "</strong> ");
str += group.rules[i].group ?
self.computed(group.rules[i].group) :
group.rules[i].field + " " +
//htmlEntities(group.rules[i].condition)
group.rules[i].condition
+ " " + group.rules[i].data;
}
return str + ")";
};
$scope.$watch('filter', function (newValue)
{
self.output = self.computed(newValue);
}, true);
self.test = function()
{
window.alert(JSON.stringify( self.filter) );
};
}
]);
The screenshot:
May I get any help here? Thanks in advance.
This is my workaround (Addeed this to the directive) and that helped:
scope.fieldCodes = scope.$parent.fieldCodes;
scope.ruleConditionOperators = scope.$parent.ruleConditionOperators;
scope.ruleConditionSetOperators = scope.$parent.ruleConditionSetOperators;
So, the directive now looks like:
AddEditRuleSetApp.directive('queryBuilder', ['$compile', function ($compile) {
return {
restrict: 'E',
scope: {
group: '=',
ruleConditionOperators: '=',
ruleConditionSetOperators: '=',
fieldCodes: '='
},
templateUrl: '/queryBuilderDirective.html',
compile: function (element, attrs) {
var content, directive;
content = element.contents().remove();
return function (scope, element, attrs) {
scope.fieldCodes = scope.$parent.fieldCodes;
scope.ruleConditionOperators = scope.$parent.ruleConditionOperators;
scope.ruleConditionSetOperators = scope.$parent.ruleConditionSetOperators;
scope.addCondition = function () {
scope.group.rules.push({
condition: '=',
field: 'Firstname',
data: ''
});
};
scope.removeCondition = function (index) {
scope.group.rules.splice(index, 1);
};
scope.addGroup = function () {
scope.group.rules.push({
group: {
operator: 'AND',
rules: []
}
});
};
scope.removeGroup = function () {
"group" in scope.$parent && scope.$parent.group.rules.splice(scope.$parent.$index, 1);
};
directive || (directive = $compile(content));
element.append(directive(scope, function ($compile) {
return $compile;
}));
}
}
}
}]);
I have a modal view(.jsp) that has integrated directive (named as 'querybuilder', Yellow part in the picture - a js file). Controller(named as 'addEditRuleSetCtrl') and directive is included from upper level and inclusion seems fine. We have initiated the directive from the view as :
<query-builder group="addEditRuleSetCtrl.filter.group"
ruleConditionOperators="addEditRuleSetCtrl.getRuleConditionOperators()"
fields="addEditRuleSetCtrl.getCorrespondingFields()"
></query-builder>
Now the problem, I am seeing is 'addEditRuleSetCtrl.getCorrespondingFields()' works fine (reaches controller , maps data to 'field' and hence the associated dropdown field displays right data) but looks like 'addEditRuleSetCtrl.getRuleConditionOperators()' does not even reach the function defined inside the controller (I have an window.alerm() inside the function in the controller that does not show up)and hence the associted dropdown is empty (In the screenshot , it is pointed by the upside arrow).
We are using angularjs 1.4.4 and java 1.8
Below are the details of the description , Here is my JSP-view, directive and controller:
Modal view (This is a JSP file and this includes the template, used by the directive):
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="UTF-8"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<link
href="<c:url value='aviato/ruleEngine/addEditRuleSet/css/addeditruleset.css' />"
rel="stylesheet">
</link>
<%--<script src="aviato/ruleEngine/addEditRuleSet/directive/addEditRuleSet_directive.js"></script>--%>
<form name="addEditRuleSetModalForm" novalidate class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">
{{addEditRuleSetCtrl.windowHeader}}
<button type="button" class="btn btn-danger btn-sm pull-right"
ng-click="addEditRuleSetCtrl.close()" data-toggle="uibtooltip" title="Cancel" >
<span class="glyphicon glyphicon-remove-sign"></span>
</button>
</h4>
</div>
<div class="modal-body">
Hello world [origin] : {{ addEditRuleSetCtrl.origin }}
<br />
Hello world [iceField] : {{ addEditRuleSetCtrl.iceField }}
ahahahhaahahahahaahahhg1111!!!!! {{ addEditRuleSetCtrl.output }}
<div class="alert alert-info">
<strong>Example Output</strong><br>
<%--<span ng-bind-html="addEditRuleSetCtrl.output"></span>--%>
ahahahhaahahahahaahahhg!!!!! {{ addEditRuleSetCtrl.output }}
</div>
<query-builder group="addEditRuleSetCtrl.filter.group"
ruleConditionOperators="addEditRuleSetCtrl.getRuleConditionOperators()"
fields="addEditRuleSetCtrl.getCorrespondingFields()"
></query-builder>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-sm" ng-click="addEditRuleSetCtrl.test()" data-toggle="tooltip" ><span class="glyphicon glyphicon-ok-sign" ></span></button><span></span>
</div>
</div>
</form>
<script type="text/ng-template" id="/queryBuilderDirective.html">
<div class="alert alert-warning alert-group">
<div class="form-inline">
<select ng-options="o.operator as o.name for o in ruleConditionSetOperators" ng-model="group.operator" class="form-control input-sm"></select>
<button style="margin-left: 5px" ng-click="addCondition()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Condition</button>
<button style="margin-left: 5px" ng-click="addGroup()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Group</button>
<button style="margin-left: 5px" ng-click="removeGroup()" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span> Remove Group</button>
</div>
<div class="group-conditions">
<div ng-repeat="rule in group.rules | orderBy:'index'" class="condition">
<div ng-switch="rule.hasOwnProperty('group')">
<div ng-switch-when="true">
<query-builder group="rule.group"></query-builder>
</div>
<div ng-switch-default="ng-switch-default">
<div class="form-inline">
<select ng-options="t.name as t.name for t in fields" ng-model="rule.field" class="form-control input-sm"></select>
<%--<select style="margin-left: 5px" ng-options="c.name as c.name for c in ruleConditionOperators" ng-model="rule.condition" class="form-control input-sm"></select>--%>
<select style="margin-left: 5px" ng-options="c.name as c.name for c in ruleConditionOperators" ng-model="rule.condition" class="form-control input-sm"></select>
<input style="margin-left: 5px" type="text" ng-model="rule.data" class="form-control input-sm"/>
<button style="margin-left: 5px" ng-click="removeCondition($index)" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</script>
The Directive: ( This is a .js file. If I uncomment 'scope.ruleConditionOperators' here, the red-arrow-pointed dropdown displays data)
AddEditRuleSetApp.directive('queryBuilder', ['$compile', function ($compile) {
return {
restrict: 'E',
scope: {
group: '=',
ruleConditionOperators: '=',
fields: '='
},
templateUrl: '/queryBuilderDirective.html',
compile: function (element, attrs) {
var content, directive;
content = element.contents().remove();
return function (scope, element, attrs) {
scope.ruleConditionSetOperators = [
{ name: 'AND' },
{ name: 'OR' }
];
/* scope.ruleConditionOperators = [
{ name: '=' },
{ name: '<>' },
{ name: '<' },
{ name: '<=' },
{ name: '>' },
{ name: '>=' }
];*/
scope.addCondition = function () {
scope.group.rules.push({
condition: '=',
field: 'Firstname',
data: ''
});
};
scope.removeCondition = function (index) {
scope.group.rules.splice(index, 1);
};
scope.addGroup = function () {
scope.group.rules.push({
group: {
operator: 'AND',
rules: []
}
});
};
scope.removeGroup = function () {
"group" in scope.$parent && scope.$parent.group.rules.splice(scope.$parent.$index, 1);
};
directive || (directive = $compile(content));
element.append(directive(scope, function ($compile) {
return $compile;
}));
}
}
}
}]);
The Controller:
AddEditRuleSetApp.controller( 'AddEditRuleSetModalController', [ '$scope', '$rootScope', '$uibModalInstance','RuleEngineService', 'origin', 'iceField',
function( $scope, $rootScope , $uibModalInstance, RuleEngineService, origin, iceField )
{
var self = this;
self.origin = origin;
self.iceField = iceField;
self.data = '{"group": {"operator": "AND","rules": []}}';
self.output = 'bologna';
self.fieldsDDE = [
{ name: 'FirstnameDDE' },
{ name: 'LastnameDDE' },
{ name: 'BirthdateDDE' },
{ name: 'CityDDE' },
{ name: 'CountryDDE' }
];
self.fieldsATT = [
{ name: 'FirstnameATT' },
{ name: 'LastnameATT' },
{ name: 'BirthdateATT' },
{ name: 'CityATT' },
{ name: 'CountryATT' }
];
self.ruleConditionOperators = [
{ name: '=' },
{ name: '<>' },
{ name: '<' },
{ name: '<=' },
{ name: '>' },
{ name: '>=' }
];
self.clientChanged = function( selCleintId )
{
self.getAllMachinesForClientForDuplication( self.duplicateClient );
self.displayErrorMessages = false;
}
self.getRuleConditionOperators = function()
{
window.alert("--------*******---------Reached client side controller to getAllRuleConditionOperators");
return self.ruleConditionOperators;
/* RuleEngineService.getAllRuleConditionOperators( )
.then(
function( d )
{
self.ruleConditionOperators = d;
},
function( errResponse )
{
console.error( 'Error while fetching rule-condition-operators' );
}
);
*/
};
self.htmlEntities = function(str)
{
return String(str).replace(/</g, '<').replace(/>/g, '>');
};
//self.output = null;
self.displayErrorMessages = false;
self.createSuccess = '';
self.createHeader = '';
self.backendErr = "";
self.windowHeader = "Create/Edit Rule Group";
self.close = function()
{
$uibModalInstance.close();
};
self.getCorrespondingFields = function()
{
// window.alert("---------------Reached client side controller to getCorrespondingFields");
return self.origin == 'DDE' ? self.fieldsDDE : self.fieldsATT;
};
self.computed = function(group)
{
window.alert("Inside controller: computed");
if (!group) return "";
for (var str = "(", i = 0; i < group.rules.length; i++) {
i > 0 && (str += " <strong>" + group.operator + "</strong> ");
str += group.rules[i].group ?
self.computed(group.rules[i].group) :
group.rules[i].field + " " +
//htmlEntities(group.rules[i].condition)
group.rules[i].condition
+ " " + group.rules[i].data;
}
return str + ")";
};
//self.json = null;
self.filter = JSON.parse(self.data);
$scope.$watch('filter', function (newValue)
{
self.output = self.computed(newValue);
}, true);
self.test = function()
{
window.alert(JSON.stringify( self.filter) );
};
}
]);
The screenshot:
I have 3 Questions each i have given 5 stars,after user submit i need to convert to 5 how to do this using this formula x1w1 + x2w2 + x3w3 ... xnwn/Total.
http://help.surveymonkey.com/articles/en_US/kb/What-is-the-Rating-Average-and-how-is-it-calculate.i have done something but its not right way i think so?
//--------------------------------------review controller--------------
.controller('ReviewCtrl', [
'$scope', '$http', '$location', '$window',
function($scope, $http, $location, $window) {
$scope.rating1 = {};
$scope.rating2 = {};
$scope.rating3 = {};
$scope.isReadonly = true;
$scope.rateFunctionone = function(rating) {
window.localStorage.setItem("rating1", rating);
};
$scope.rateFunctiontwo = function(rating) {
window.localStorage.setItem("rating2", rating);
};
$scope.rateFunctionthree = function(rating) {
window.localStorage.setItem("rating3", rating);
};
$scope.submit = function() {
var bookingid= window.localStorage.getItem("reviewbookingid");
var storeid = window.localStorage.getItem("reviewstoreid");
var cusname = window.localStorage.getItem("username").replace(/\"/g, "");
var rating1 = window.localStorage.getItem("rating1");
var rating2 = window.localStorage.getItem("rating2");
var rating3 = window.localStorage.getItem("rating3");
var totrating = (parseInt(rating1) + parseInt(rating2) + parseInt(rating3)) / 15;
console.log(totrating);
$http.get('******').success(function(data, response) {
var totcustomer = data.length + 1;
var totcustreview =data.length;
console.log(totcustreview);
if (data.length == 0) {
var caltotrating = (0 + totrating) / totcustomer;
} else
{
var caltotrating = (parseInt(data[0].Rating) + parseInt(totrating)) / totcustomer;
}
var credentials = {};
credentials = {
"Customet_Name": cusname,
"Timely_delivery": rating1,
"Quality_of_service": rating2,
"Value_for_money": rating3,
"Average": totrating,
"Rating": caltotrating,
"Comments": $scope.command,
"Booking_id": bookingid,
"Store_id": storeid
}
var scredentials = {};
scredentials = {
"S_Ratings": caltotrating,
"S_Noofpeoplegivenreview": totcustomer,
}
$http.put('***').success(function(data, status, headers, config, response) {
});
$http.post('***').success(function(data, status, headers, config, response) {
});
});
}
}
])
//---------------------------------------------------------------------
.directive("starRating", function() {
return {
restrict: "EA",
template: "<ul class='rating' ng-class='{readonly: readonly}'>" +
" <li ng-repeat='star in stars' ng-class='star' ng-click='toggle($index)'>" +
" <i class='ion-star'></i>" + //★
" </li>" +
"</ul>",
scope: {
ratingValue: "=ngModel",
max: "=?", //optional: default is 5
onRatingSelected: "&?",
readonly: "=?"
},
link: function(scope, elem, attrs) {
if (scope.max == undefined) {
scope.max = 5;
}
function updateStars() {
scope.stars = [];
for (var i = 0; i < scope.max; i++) {
scope.stars.push({
filled: i < scope.ratingValue
});
}
};
scope.toggle = function(index) {
if (scope.readonly == undefined || scope.readonly == false) {
scope.ratingValue = index + 1;
scope.onRatingSelected({
rating: index + 1
});
}
};
scope.$watch("ratingValue", function(oldVal, newVal) {
if (newVal) {
updateStars();
}
});
}
};
})
<ion-content ng-controller="ReviewCtrl" >
<form data-ng-submit="submit()">
<div class="row">
<div class="col item item-divider">Timely Delivery </div>
<div class="col item item-divider">
<div star-rating ng-model="rating1" max="5" on-rating-selected="rateFunctionone(rating)"></div>
</div>
</div>
<br>
<div class="row">
<div class="col item item-divider">Quality of Service </div>
<div class="col item item-divider">
<div star-rating ng-model="rating2" max="5" on-rating-selected="rateFunctiontwo(rating)"></div>
</div>
</div>
<br>
<div class="row">
<div class="col item item-divider"> Value for Money </div>
<div class="col item item-divider">
<div star-rating ng-model="rating3" max="5" on-rating-selected="rateFunctionthree(rating)"></div>
</div>
</div>
<br>
<ul >
<li class="item item-checkbox">
<label class="checkbox checkbox-energized">
<input type="checkbox" ng-model="recommend" ng-true-value="'yes'" ng-false-value="'no'">
</label>
Would you recommend this dealer to your friends?
</li>
</ul>
<label class="item item-input item-floating-label" >
<span class="input-label">Say! how you feel</span>
<textarea placeholder="Say! how you feel" rows="4" ng-model="command"></textarea>
</label>
<div class="padding">
<button class="button button-full button-stable" type="submit" > Submit
</button>
</form>
</div>
</ion-content>
Use this RateIt for rating its quite easy you just need bower to install it and include the js and css.