Assign dynamic ng-model in a template for radio buttons - angularjs

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",
// ...
};

Related

AngularJS multi screen validation on last step

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);
}
};
});

ion-slides, each overlap with ng-repeat

I'm real newbie in ionic, html, angular and java script. I have an app that take some JSON data and display it with ng-repeat.
But when I tried to switch to the next slide, it overlap. and I have an $interval that refresh JSON each 5 sec, it reset to the first slide also.
here html:
<ion-view title="home">
<ion-content ng-controller="temperatureCtrl">
<div ng-init="init()"></div>
<ion-slides options="options" slider="data.slider" >
<ion-slide-page ng-repeat="channel in channels">
<div class="list">
<h2><center>canal# {{channel.canal}}</center></h2>
<br/>
<center>
<button class="button button-stable" ng-click="switchChannel(channel, channel.canal)" ng-model="channel.status">
{{channel.status}}
</button>
</center>
<div class="list">
<label class="item item-input">
<input type="text" style="text-align:center;" placeholder="Channel name" ng-model="channel.name" ng-focus="stopRefresh()" ng-blur="restartRefresh()">
</label>
</div>
<h4><center>
<span class="Ainput" ><h3>{{channel.temperature}}ºC</h3></span>
</center></h4>
<h3><center>Setpoint= {{channel.setPoint}}</center></h3><br>
<div class="item range range-positive">
<i class="icon ion-minus-round"></i>
<input type="range" name="setpoint" min="5" max="30" step="0.5" value="33" ng-model="channel.setPoint" ng-focus="stopRefresh()" ng-blur="restartRefresh()">
<i class="icon ion-plus-round"></i>
</div>
<centrer>
<button class="button button-dark button-block padding " ng-click="channelsClk(channel, channel.setPoint)">ok</button>
</centrer>
<h3>
<span class="permRun">{{channel.permission}}</span>
</h3>
<h3>
<span class="AoutputChannel">{{channel.percentOut}}%</span>
</h3>
</ion-slide-page>
</ion-slides>
</ion-content>
and the controler:
main.controller("temperatureCtrl", ["$scope", "$interval", "ArduinoService", function($scope, $interval, service) {
var autoRefresh;
$scope.channels = [];
$scope.options = {
loop: false,
effect: 'fade',
speed: 500,
}
$scope.data = {};
$scope.$watch('data.slider', function(nv, ov) {
$scope.slider = $scope.data.slider;
})
function startRefresh(){
autoRefresh = $interval(function() {
updateAjax();
}, 5000);
}
function updateAjax() {
service.getChannels(function(err, result) {//get json data
if (err) {
return alert(err);
}
// puis les mets dans le scope
$scope.channels = result.channels;
})
};
$scope.init = function() { //on load page first get data
updateAjax();
startRefresh()
}
$scope.switchChannel = function($scope, channel) { // change name function
var switchCh = {canal : $scope.canal, status : $scope.status}
service.switchChannel(switchCh, function() {
});
updateAjax();
};
$scope.channelsClk = function($scope, channel) {
var chanObj = {setPoint : $scope.setPoint, name : $scope.name, canal : $scope.canal
};
service.putChannels(chanObj, function() {
});
}
$scope.stopRefresh = function() { //ng-mousedown
$interval.cancel(autoRefresh);
};
$scope.restartRefresh = function() {
startRefresh();
};
$scope.$on('$destroy', function() {
// Make sure that the interval is destroyed too
$scope.stopRefresh();
});
}]);
remove option fade solve the problem.
$scope.options = {
loop: false,
//effect: 'fade', /* <-- */
speed: 500,
}

Accessing $scope of another controller - ngDialog in AngularJS

I'm instantiating ngDialog like below;
ngDialog.open({
template: 'mod-details',
className: "ngDialog-theme-large",
showClose: false,
closeByDocument: false,
closeByEscape: false,
controller: ['$scope', function($scope) {
// controller logic
$scope.isValid = true;
$scope.orderItem = orderItem;
$scope.countSelection = function() {
var count = 0;
angular.forEach($scope.modifier.menu_modifier_items, function(item){
count += item.selected ? 1 : 0;
});
console.log(item);
return count;
}
}]
});
I then use $scope.orderItem with ng-repeat like below;
<div ng-repeat="modifier in orderItem.menu_modifier_groups">
<div class="menu--modifiers-group" modifier="modifier">
<div class="group-title" ng-class="{'group-hasError': !isValid}">
<div class="title-s ng-binding" ng-bind="modifier.name"></div>
<div class="clearfix"></div>
<span class="text-muted ptop5" ng-if="modifier.instruction" ng-bind="modifier.instruction"></span>
</div>
<div class="group-items" ng-if="modifier.max_selection_points > 1 || (modifier.max_selection_points == 1 && modifier.min_selection_points == 0)">
<div ng-repeat="item in modifier.menu_modifier_items" class="modifier-item multiple">
<label for="<%modifier.id + '_' + item.id%>" ng-click="modifierClicked(item)">
<input id="<%modifier.id + '_' + item.id%>"
class="checkbox-branded"
type="checkbox"
name="<%item.name%>"
ng-model="item.selected"
ng-class="{'not-available': !item.available}"
title="<%item.name%>"
value="<%item.id%>"
ng-disabled="!item.selected && countSelection() == modifier.max_selection_points"
ng-click="modifierClicked(item)"
ng-change="modifierSelected(item, false)">
<span class="item-name">
<span ng-bind="item.name"></span>
<span ng-bind="priceDelta(modifier, item)"></span>
</span>
</label>
</div>
</div>
</div>
</div>
</div>
I'm not able to access modifier in ng-repeat="modifier in orderItem.menu_modifier_groups" or modifier.menu_modifier_items in ng-repeat="item in modifier.menu_modifier_items" in my countSelection function
I've attached a screenshot of ng-inspector.
$scope.modifier is never created into your controller. Your countSelection function can't know which item of the array is being selected this way. One way you could do, is to pass a reference of the array to your function when calling it. Like this:
countSelection(modifier.menu_modifier_items);
And, on the controller:
$scope.countSelection = function(selection) {
var count = 0;
angular.forEach(selection, function(item){
count += item.selected ? 1 : 0;
console.log(item);
});
return count;
}

Angular JS: update controller when data change in second controller

what i m doing:
simple html file shows first page , in this page i have one title and button, initially i set $scope.index = 0. so, we set first position of array. when we click on next button it finds firstCtrl and first.html page. in this controller i update $scope.index by 1. so, my question is when i update $scope.index of myCtrl then $scope.index is changed on another controller i wants to change myCtrl. is it possible ? if it is then help me.
index.html:
<body ng-controller="myCtrl">
<div id="navbar">
<div class="setToggle">
<input id="slide-sidebar" type="checkbox" role="button" />
<label for="slide-sidebar"><span class="glyphicon glyphicon-menu-hamburger"></span></label>
</div>
<div class="setQuestion">
<h2>{{surveys[index].questionTitle}}</h2>
</div>
</div>
<div class="content-wrapper" class="container-fluid">
<div class="sidebar-left">
<div class="first">
<ul ng-repeat="cat in surveys[index].category" class="list-unstyled" ng-hide="checkSubCategoryValueIsNull.length">
<li class="category">
<a ng-click="expand=!expand">
<span class="glyphicon" ng-class="{'glyphicon-plus': !expand, 'glyphicon-minus': expand}">
{{cat.categoryName}}
</span>
</a>
</li>
<ul ng-repeat="subcategory in cat.categoryItemDto" class="list-unstyled">
<li ng-show="expand">
<label class="label-style-change">
<input type="checkbox" ng-click="toggleSelectionCheckbox(surveys[index], subcategory)" ng-model="subcategory.selectValue" ng-disabled="disableCheckbox">
<span class="subcategory-item" ng-disabled="disableCheckbox">{{subcategory.subCategoryName}}</span>
</label>
</li>
</ul>
</ul>
</div>
<div class="second">
<input type="button" name="Submit" value="Submit" ng-click="submitSelection()" ng-hide="hideSubmitButton" ng-disabled="!selections[index].length">
<input type="button" name="Edit" value="Edit" ng-click="EditSelection()" ng-show="hideEditButton">
</div>
</div>
<div class="portfolio">
<div id="main">
<div ng-view></div>
</div>
</div>
</div>
</body>
controller.js
(function() {
var app = angular.module("app.controllers", ["app.service"]);
app.controller("myCtrl", ["$scope", "$http", "$location", "$timeout", "surveyService", "Data",
function ($scope, $http, $location, $timeout, surveyService, Data) {
surveyService.getData(function(dataResponse) {
$scope.surveys = dataResponse;
$scope.selections = [];
/* create 2d array mannually */
var numInternalArrays = $scope.surveys.length;
for (var i = 0; i < numInternalArrays; i++) {
$scope.selections[i] = [];
};
$scope.index = 0;
var toggleCheckboxFlag = 0;
/* PRIVATE FUNCTION
for find value from selections array and replace it
*/
function findAndRemove(array, property, value) {
array.forEach(function(result, index) {
if(result[property] === value) {
array.splice(index, 1);
toggleCheckboxFlag = 1;
}
});
}
$scope.toggleSelectionCheckbox = function (QuestionId, value) {
toggleCheckboxFlag = 0;
if (!value) return;
findAndRemove($scope.selections[$scope.index], 'categoryId', value.subCategoryId);
if (toggleCheckboxFlag != 1) {
$scope.selections[$scope.index].push({
questionId: QuestionId.questionId,
categoryId: value.subCategoryId,
categoryName: value.subCategoryName,
storeId: 1,
comment: ""
});
}
};
$scope.submitSelection = function() {
$scope.value = $scope.selections[$scope.index];
$scope.hideSubmitButton = true;
$scope.disableCheckbox = true;
$scope.hideEditButton = true;
$location.path("/question/1");
}
});
$scope.EditSelection = function() {
$scope.hideEditButton = false;
$scope.hideSubmitButton = false;
$scope.disableCheckbox = false;
$scope.value = false;
}
$scope.$watch('index', function (newValue, oldValue) {
if (newValue !== oldValue) Data.setIndex(newValue);
});
console.log("controller", Data.getIndex())
}]);
})();
app.js
var app = angular.module('app', ['ngRoute','app.service', 'app.controllers']);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/question/1', {
templateUrl: 'views/first.html',
controller: 'sidebarCtrl'
})
.when('/question/2', {
templateUrl: 'views/second.html',
controller: 'mainCtrl'
})
.otherwise({
redirectTo: '/'
});
}]);
first.html
<div id="content-wrapper" ng-show="value">
<div class="col-lg-offset-1 col-lg-8 col-md-12 col-sm-12 col-xs-12">
<h2 class="subCategoryLabel"><span class="label">{{value[inc].categoryName}}</span></h2>
</div>
<div class="row">
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4">
<button class="btnNext" ng-hide="inc == 0" ng-click="prev()">
<i class="glyphicon glyphicon-menu-left"></i>
</button>
</div>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-4">
<form name="myForm">
<div ng-repeat="item in surveys[index].optionCategoryItemDto" class="formStyle">
<label class="text-center">
<input type="radio" name="radio" id="{{item.itemId}}" ng-value="item.itemId" ng-model="selections[index][inc].answer" required>
{{item.itemName}}
</label>
</div>
<br/>
<br/>
</form>
</div>
<div class="col-lg-3 col-lg-offset-1 col-md-offset-1 col-md-3 col-sm-4 col-xs-4">
<button class="btnNext" ng-hide="selections[index].length == inc + 1" ng-disabled="myForm.radio.$error.required" ng-click="next()">
<i class="glyphicon glyphicon-menu-right"></i>
</button>
<button class="btnNext" ng-show="selections[index].length == inc + 1" ng-disabled="myForm.radio.$error.required" ng-click="nextQuestion()">
<i class="glyphicon glyphicon-forward"></i>
</button>
</div>
</div>
<div class="col-lg-offset-3 col-lg-4 col-md-offset-3 col-md-6 col-sm-offset-3 col-sm-6 col-xs-4">
<textarea type="text" id="text" class="form-control txtArea" ng-model="selections[index][inc].comment" placeholder="Write comment..."></textarea>
</div>
</div>
sidebarCtrl.js
in this controller i update $scope.index when we call nextQuestion(). here $scope.index increment by one and $watch function also get latest value of index. but myCtrl is not update. i wants to update myCtrl.
(function() {
var app = angular.module("app.controllers");
app.controller("sidebarCtrl", ['$scope', "$location", "Data", function($scope, $location, Data) {
$scope.inc = 0;
$scope.next = function() {
$scope.inc += 1;
}
$scope.prev = function() {
$scope.inc -= 1;
}
$scope.nextQuestion = function() {
$scope.index += 1;
$location.path("/question/2");
}
$scope.$watch('index', function (newValue, oldValue) {
console.log("SASAS", newValue)
if (newValue !== oldValue) Data.setIndex(newValue);
});
}]);
})();
service.js
(function() {
var app = angular.module("app.service", []);
app.service("surveyService", function($http) {
this.getData = function (callbackFunc) {
$http({
method: "GET",
data: {something: true},
contentType: 'application/json',
dataType: 'jsonp',
url: "http://localhost:8080/TheSanshaWorld/sfcms/fetch-survey-details"
}).success(function(data){
callbackFunc(data);
}).error(function(){
alert("error");
});
};
this.setData = function(value) {
if (confirm('Do you wanna to submit?')) {
$http.post("http://localhost:8080/TheSanshaWorld/sfcms/save-survey-result-data", value).success(function(data, status) {
window.open("../index.html","_self");
});
} else {
return false;
}
};
});
app.factory('Data', function () {
var data = {
Index: ''
};
return {
getIndex: function () {
return data.Index;
},
setIndex: function (index) {
data.Index = index;
console.log("service", data.Index)
}
};
});
})();
Because sidebarCtrl is nested within myCtrl, therefore you can reach myCtrl $scope.index from sidebarCtrl using it $scope.$parent.index,
Try it by test: add any parameter value to myCtrl $scope.name='Bob';
then log it in sidebarCtrl console.log($scope.$parent.name); you should see printed 'Bob'. Do the same with index.

how to make dynamic 5 star rating using angularjs?

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>" + //&#9733
" </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.

Resources