Unable to use controller as syntax to set up directive (scope mismatch) - angularjs

I am pulling my hair out trying to get a directive called webix-ui to assume the same scope level as parent scope. This code is the closest to making webix-ui work, but the element still sees childscope.
What am I doing wrong and why is my controller as not being picked up globally?
I am nearing the point of giving up as I have tried nearly 10-15 variations of my code, this one being the most promising and hopefully in the right direction.
I can provide additional details as necessary.
Module Controller
angular.module('Risk').controller('CreateRiskController', ['$http', '$resource', '$scope', '$state', '$window', '$timeout', '$interval', '$sce', 'CommonService', function($http, $resource, $scope, $state, $window, $timeout, $interval, $sce, CommonService){
refresh = false;
var vm = this;
vm.config = {}
vm.initDone = false;
vm.setup = {
done: false
}
vm.model = { elem: true }
vm.risk = {
risktitle: '',
riskstatement: '',
context: '',
closurecriteria: '',
likelihood:'',
technical:'',
schedule:'',
cost:''
};
vm.fields = [
'risktitle',
'riskstatement',
'context',
'closurecriteria',
'likelihood',
'technical',
'schedule',
'cost'
]
vm.risklevels = {
riskmaximum: '',
riskhigh: '',
riskmedium: '',
riskminimum: ''
}
vm.flags = {
disabled: true
}
vm.riskMatrix = [];
for(var l = 1; l <= 5; l++)
{
vm.riskMatrix[l] = [];
for (var c = 0; c <= 5; c++)
{
vm.riskMatrix[l][c] = '';
}
}
vm.riskLevel = function(l, c){
elem = document.querySelector("div[name='risk["+l+"]["+c+"]']");
risk = vm.riskMatrix[l][c];
if (risk == '')
return (elem && elem.hasAttribute('class'))?
elem.getAttribute('class') : '';
if (risk >= vm.risklevels.riskhigh)
return 'cell high';
else if (risk >= vm.risklevels.riskmedium && risk < vm.risklevels.riskhigh)
return 'cell med';
else if (risk < vm.risklevels.riskmedium)
return 'cell low';
}
vm.valid = function(){
return CommonService.riskFormValid(vm.fields, vm);
}
vm.invalidLevel = function(lvl){
return CommonService.invalidLevel(lvl);
}
$scope.$on("$destroy", function(){
formcheck = 0;
angular.element(document.querySelector('link[href="/app/tool/risk/CreateRisk.css"]')).remove();
});
vm.initRisk = function(data){
vm.risklevels.riskmaximum = data.Levels[0].riskmaximum;
vm.risklevels.riskhigh = data.Levels[0].riskhigh;
vm.risklevels.riskmedium = data.Levels[0].riskmedium;
vm.risklevels.riskminimum = data.Levels[0].riskminimum;
for (var idx = 0; idx < data.Thresholds.length; idx++)
{
var l = data.Thresholds[idx].likelihood;
var c = data.Thresholds[idx].consequence;
v = data.Thresholds[idx].level;
vm.riskMatrix[l][c] = v;
}
}
vm.init = function(){
return $http.get('/api/riskconfig').then(function(response){
if (response.data.Succeeded){
vm.initRisk(response.data.Result);
return response.data.Result;
}
else{
vm.msg = $sce.trustAsHtml(response.data);
}
});
}
vm.submit = function(){
if (!vm.valid())
vm.msg = "Please complete form and resubmit";
else{
//vm.actionitem.duedate = vm.split(vm.actionitem.duedate,'T')[0];
//vm.actionitem.ecd = vm.split(vm.actionitem.ecd, 'T')[0];
$http.post('/api/risks', vm.risk).then(function(response){
if (response.data.Succeeded){
vm.msg = response.data.Result;
}
else{
vm.msg = $sce.trustAsHtml(response.data);
}
});
}
}
}]);
Directive
angular.module('Risk').directive('config', ConfigElement);
function ConfigElement(){
var directive = {
restrict: 'A',
compile: function (){
return {
pre: function (scope, elem, attrs){
var vm = scope.vm;
vm.config[attrs.config] = {done: false}
},
post: ConfigController
}
},
controller: 'CreateRiskController',
controllerAs: 'vm',
bindToController: true,
scope: false
}
return directive;
}
function ConfigController(scope, element, attrs, DOMops, ValidationService){
//$scope.$watch('setup.done', function(dataReady,dataNotReady,scope){
// if (dataReady){
var vm = scope.vm;
var attr = attrs.config;
var type = attrs.type;
var width = attrs.width;
var height = attrs.height;
var maxlength = attrs.hasOwnProperty('maxlength')? attrs.maxlength: null;
var view;
if (type == "level")
view = "text";
else
view = type;
var config =
{
view: view,
value: vm.risk[attr],
on: {
"onTimedKeyPress": function(code){
var obj = this.eventSource || this;
ValidationService.handleKeyPress(obj, code, attr);
if (type == "level")
DOMops.assignRiskLevel(scope, obj);
},
"onBlur": function(code){
var obj = this.eventSource || this;
ValidationService.updateAndValidate(obj,code,attr);
}
},
responsive: true,
width: width,
height: height
};
if (maxlength)
config.attributes = {maxlength : maxlength};
config.done = true;
vm.config[attr] = config;
//$scope.$eval($attrs.onConfig, {$config: $scope.config[$attrs.name]});
// }
//});
}
Template
<div id="formcontainer" ng-app="Risk" ng-controller="CreateRiskController as vm" get-risk>
<div id="mycreateform" class="container" type="space" layout-padding="" ng-cloak="">
<form id="form" name="CreateRisk" role="form" ng-submit="vm.valid() && vm.submit()" novalidate>
<div id="details" class="layout" border="1">
<div class="tr">
<div class="td label">
Title
</div>
<div config="risktitle" class="td locked" width="500" height="30" type="text">
<div ng-if="vm.config.risktitle.done" ng-model="vm.config.risktitle" webix-ui="vm.config.risktitle" id="risktitle" name="risktitle"></div>
</div>
</div>
<div class="tr">
<div class="td label">
Risk Statement
</div>
<div config="riskstatement" class="td locked" width="500" height="97" type="textarea">
<div ng-if="vm.config.riskstatement.done" ng-model="vm.config.riskstatement" webix-ui="vm.config.riskstatement" id="riskstatement" name="riskstatement"></div>
</div>
</div>
<div class="tr">
<div class="td label">
Context
</div>
<div config="context" width="500" height="97" type="textarea" class="td locked">
<div ng-if="vm.conig.context.done" ng-model="vm.config.context" webix-ui="vm.config.context" id="context" name="context"></div>
</div>
</div>
<div class="tr">
<div class="td label">
Closure Criteria
</div>
<div config="closurecriteria" width="500" height="97" type="textarea" class="td locked">
<div ng-if="vm.config.closurecriteria.done" ng-model="vm.config.closurecriteria" webix-ui="vm.config.closurecriteria" id="closurecriteria" name="closurecriteria"></div>
</div>
</div>
<!--tr class="text">
<div class="td label">
Category
</div>
<div class="locked">
<div id="category" name="category" />
</div>
</div-->
</table>
<h2>Initial Risk Assessment</h2>
<div class="nested">
<div class="info">
<div id="details" class="table" border="1">
<div class="tr">
<div class="td label">
Likelihood
</div>
<div config="likelihood" width="30" height="30" maxlength="1" type="level" class="td locked">
{{config.likelihood}}<div ng-if="vm.config.likelihood.done" ng-model="vm.config.likelihood" webix-ui="vm.config.likelihood" id="likelihood" name="likelihood"></div>
</div>
</div>
<div class="tr">
<div class="td label" colspan="2">
Consequence
</div>
</div>
<div class="tr">
<div class="td label margin-left">
Technical
</div>
<div config="technical" width="30" height="30" type="level" maxlength="1" class="td locked">
{{config.technical}}<div ng-if="vm.config.technical.done" ng-model="vm.config.technical" webix-ui="vm.config.technical" id="technical" name="technical"></div>
</div>
</div>
<div class="tr">
<div class="td label margin-left">
Schedule
</div>
<div config="schedule" width="30" height="30" type="level" maxlength="1" class="td locked">
{{config.schedule}}<div ng-if="vm.config.webix" ng-model="vm.config.schedule" webix-ui="vm.config.schedule" id="schedule" name="schedule"></div>
</div>
</div>
<div class="tr">
<div class="td label margin-left">
Cost
</div>
<div config="cost" width="30" height="30" type="level" maxlength="1" class="td locked">
{{config.cost}}<div ng-if="vm.config.cost.done" ng-model="vm.config.cost" webix-ui="vm.config.cost" id="cost" name="cost"></div>
</div>
</div>
</div>
<div name="level"></div>
</div>
<div class="info" ng-if="vm.setup.done">
<table class="matrix" id="riskmatrix">
<tbody>
<tr ng-repeat="likelihood in [5,4,3,2,1]">
<td ng-if="likelihood == 2" class="vlabel">Likelihood</td>
<td ng-if="likelihood != 2"></td>
<td class="likelihood">{{likelihood}}</td>
<td ng-repeat="consequence in [1,2,3,4,5]" name="risk[{{likelihood}}][{{consequence}}]" ng-model="vm.riskMatrix[likelihood][consequence]" ng-class="[vm.riskLevel(likelihood,consequence)]"></td>
</tr>
<tr>
<td></td>
<td></td>
<td ng-repeat="consequence in [1,2,3,4,5]">{{consequence}}</td>
</tr>
<tr>
<td></td><td></td><td colspan="5">Consequence</td>
</tr>
</tbody></table>
</div>
</div>
<divider></divider>
<div class="tr">
<div class="tr">
<button id="submit" type="submit" disabled="disabled" class="raised primary">Create Risk</button>
</div>
</div>
<div class="tr">
<div class="msg" layout-align="center">
<span ng-bind-html="msg">{{msg}}</span>
</div>
</div>
</form>
</div>
</div>

Initializing my div directive with an object whose property was initially false and then using "as ctrl" in my template solved the issue finally. I had to use this in my controller and scope.ctrl.<property> in. It seems to have worked similar to the syntax as many references places suggesting use of this pointer instead of $scope.
The only thing that I changed was use of ng-show instead of ng-if. I have not used ng-if but I suspect it might still work too.
<div id="formcontainer" ng-app="Risk" ng-controller="CreateRiskController as ctrl" ng-cloak>
<get-risk></get-risk>
<div id="mycreateform" class="container" type="space" layout-padding="">
<form id="form" name="CreateRisk" role="form" ng-submit="ctrl.valid() && ctrl.submit()" novalidate>
<table id="details" class="layout" border="1">
<tr>
<td class="label">
Title
</td>
<td class="locked">
<div ng-show="ctrl.config.risktitle.done" config="risktitle" webix-ui="risktitle" width="500" height="30" type="text" id="risktitle" name="risktitle"></div>
</td>
</tr>
</table>
</form>
</div>
</div>
Directive
angular.module('Risk').directive('config', ConfigElement);
function ConfigElement(){
var directive = {
restrict: 'A',
link: linkFn,
controller: ConfigController
}
function linkFn(scope, elem, attrs){
var attr = attrs.config;
var type = attrs.type;
var width = attrs.width;
var height = attrs.height;
var maxlength = attrs.hasOwnProperty('maxlength')? attrs.maxlength: null;
var view;
if (type == "level")
view = "text";
else
view = type;
scope.ctrl.DOMops.setValidationServiceObj(scope.ctrl.ValidationService);
scope.ctrl.DOMops.setValue('risk', scope.ctrl.risk);
scope.ctrl.DOMops.setValue('riskMatrix', scope.ctrl.riskMatrix);
scope.ctrl.DOMops.setValue('risklevels', scope.ctrl.risklevels);
scope.ctrl.ValidationService.setValue('risk', scope.ctrl.risk);
scope.ctrl.ValidationService.setDOMobj(scope.ctrl.DOMops);
var config =
{
view: view,
value: scope.ctrl.risk[attr],
on: {
"onTimedKeyPress": function(){
var obj = this.eventSource || this;
code = this.getValue();
scope.ctrl.ValidationService.handleKeyPress(code, scope.ctrl, obj, attr);
if (type == "level")
scope.ctrl.DOMops.assignRiskLevel(obj);
},
"onBlur": function(){
var obj = this.eventSource || this;
code = this.getValue();
scope.ctrl.ValidationService.getTextValueAndValidate(code, scope.ctrl, obj, attr);
}
},
responsive: true,
width: width,
height: height
};
if (maxlength)
config.attributes = {maxlength : maxlength};
config.done = true;
scope.ctrl.config[attr] = config;
}
return directive;
}
function ConfigController($scope, $element, $attrs){
$scope.ctrl.config[$attrs.config] = {done: false};
}

Related

weird behavior of ngrepeat in angularJS

I am having issue with ng-repeat , its replacing all values with latest one.
E.g. I am adding a value to textbox then adding that value in ng-repeat div but its replacing all values with last value entered.
Here is Jsfiddle
https://jsfiddle.net/mahajan344/9bz4Lwxa/656/
This is happening because you have only one statusObj and you are modifying it every time someone clicks the Add New Status button. Delete the statusObj you have now, and have the AddNewStatus method create a new one each time:
var xyzApi = xyzApi || {
sayHello: function() {
return "hey there\n";
}
};
angular.module('demoApp', [])
.controller('MainController', MainController)
.provider('xyzApi', function XyzApiProvider() {
this.$get = function() {
var xyzApiFactory = {
otherFunction: function() {
//$log.log('other function called');
return 'other function \n';
}
};
//console.log(xyzApiFactory, xyzApi);
angular.merge(xyzApiFactory, xyzApi);
return xyzApiFactory;
};
});
function MainController(xyzApi) {
var vm = this;
vm.test = '';
vm.listOfStatus = [];
vm.showStatusError = false;
vm.statusText = "";
vm.sayHello = function() {
vm.test += xyzApi.sayHello() + xyzApi.otherFunction();
}
vm.AddNewStatus = function(statusText) {
if (statusText.length < 1) {
vm.showStatusError = true;
return;
} else {
vm.showStatusError = false;
}
var statusObj = {
StatusComment: statusText,
scId: 0,
scTimeStamp: new Date(),
JobNum: 0,
IsNew: 0,
};
vm.listOfStatus.push(statusObj);
vm.statusText = "";
};
vm.RemoveStatus = function(index) {
vm.listOfStatus.splice(index, 1);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-rc.0/angular.js"></script>
<div ng-app="demoApp" ng-controller="MainController as mainCtrl">
<pre>{{mainCtrl.test}}</pre>
<button ng-click="mainCtrl.sayHello()">
say hello!!
</button>
<div id="DivStatus">
<div class="form-group">
Status
<div class="col-md-3 col-sm-3 col-xs-12">
<input type="text" ng-model="mainCtrl.statusText" id="txtStatus" class="form-control col-md-7 col-xs-12">
<div class="text-danger error-message" id="txtStatusError" ng-show="showStatusError">Please enter new status</div>
</div>
<div class="col-md-3 col-md-3x col-sm-3 col-xs-12">
<input type="button" class="btn" ng-click="mainCtrl.AddNewStatus(mainCtrl.statusText)" value="Add New Status" />
</div>
</div>
<div class="form-group" ng-repeat="statusObj in mainCtrl.listOfStatus track by $index">
<div class="col-md-3 col-sm-3 col-xs-12">
<input type="text" value="{{statusObj.StatusComment}}" ng-disabled="true" class="form-control col-md-7 col-xs-12">
</div>
<span class="remove-record" ng-click="mainCtrl.RemoveStatus($index)" style="cursor:pointer"><i class="fa fa-times"></i></span>
</div>
</div>
</div>

calling function within td element to set the text

I am trying to call a function within a <td> element that is part of a ng-repeat. Any ideas how to get this to work? I have tried so many things and no joy. The issue is the cartperf.perf_desc binding.
<table class="table table-striped table-condensed" >
<tr ng-repeat="cartperf in $ctrl.cartSummary">
<td class="cs-cart-sum-td">{{cartperf.id}}</td>
<td class="cs-cart-sum-td" ng-bind="$ctrl.myNewHtml(cartperf.perf_desc)"></td>
<td class="cs-cart-sum-td">{{cartperf.perf_dt}}</td>
<td class="cs-cart-sum-td">{{cartperf.theater}}</td>
<td class="cs-cart-sum-td">{{cartperf.num_tkts}}</td>
<td class="cs-cart-sum-td">{{cartperf.due_amt}}</td>
<td class="cs-cart-sum-td">
<button type="button" data-perf='cartperf' class="btn btn-link cs-btn-delete" ng-click="$ctrl.confirmDelete(cartperf)">{{cartperf.RemoveBtnTxt}}</button>
</td>
</tr>
</table>
Controller that drive the template
function cartSummaryController() {
this.$onInit = function () {
//Get content from Parent
this.globalContent = this.getGlobalContent;
this.cartSummary = this.cartPerfs;
this.myHtml = this.myNewHtml;
}; //End $onInit
}
Main Controller
function subAppController($sce) {
this.$onInit = function () {
//Get content from Parent
this.globalContent = this.getGlobalContent;
}; //End $onInit
this.continueClick = function () {
console.log("Continue Selected");
};
this.currentStep = 1;
this.contentJson = pcContent;
this.globalContentJson = pcGlobalContent;
this.cartPerfs = pcCartPerfs
//Called from the template to get global content.
this.getGlobalContent = function (module, item) {
var globalContent = new contentProvider(this.globalContentJson);
var result = globalContent.get(module, item);
return result;
}
this.myNewHtml = function (item) {
var result = $sce.trustAsHtml(item);
return result;
}
//Get the current count of valid performance in the cart
// We use this to determine if we hide/disable the continue buttons.
this.min_perfs = this.contentJson.required_min_perfs;
this.curr_perf_count = this.cartPerfs.length;
this.continueActive = this.curr_perf_count >= this.min_perfs;
}
Main Template
<div class="container-fluid">
<!--Top (Bread crumbs and Cart Summary)-->
<div class="cs-app-top row">
<div class="cs-app-left col-sm-3">
<div class="pull-left">
<div class="bcrumbs">Step 1 > Step2</div>
<div>
<label class="cs-page-title">{{$ctrl.contentJson.page_title}}</label>
</div>
</div>
</div>
<div class="cs-app-right pull-right col-sm-9">
<cart-summary content-json="$ctrl.contentJson"
get-global-content="$ctrl.getGlobalContent(module,item)"
cart-perfs="$ctrl.cartPerfs"
my-new-html="$ctrl.myNewHtml(item)">
</cart-summary>
<div class="cs-continue-btn-div pull-right">
<button class="cs-continue-btn cs-btn"
ng-bind="$ctrl.globalContent('subpackage','continueBtnText')"
ng-class="{'hidden': !$ctrl.continueActive}"
ng-disabled="!$ctrl.continueActive"
ng-click="$ctrl.continueClick()" ></button>
</div>
</div>
</div>
<!--Header Content-->
<div class="cs-header row">
<div ng-bind-html="$ctrl.myNewHtml($ctrl.contentJson.page_header)"></div>
</div>
<!--Main Section (perf-list)-->
<div class="cs-app-main row">
<div>
<perf-list ng-if="$ctrl.currentStep == 1"
content-json="$ctrl.contentJson"
get-global-content="$ctrl.getGlobalContent(module,item)">
</perf-list>
</div>
</div>
<!--Footer-->
<div class="cs-app-footer row">
<div class="cs-continue-btn-div pull-right">
<button class="cs-continue-btn cs-btn"
ng-bind="$ctrl.globalContent('subpackage','continueBtnText')"
ng-disabled="!$ctrl.continueActive"
ng-click="$ctrl.continueClick()"></button>
</div>
</div>
</div>
--Module
var myApp = angular.module('subPackages', ['ngMaterial', 'ngMessages','ngSanitize']).config(function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist([
// Allow same origin resource loads.
'self',
// Allow loading from our assets domain. Notice the difference between * and **.
'Protected content**'
]);
});
(function (app) {
'use strict';
app.component('appComponent', {
templateUrl: '../subpackages/templates/app-template.html',
controller: subAppController
});
app.component('cartSummary', {
templateUrl: '../subpackages/templates/cart-summary.template.html',
controller: cartSummaryController,
bindings: {
contentJson: '<',
cartPerfs: '<',
getGlobalContent: '&',
myNewHtml: '&'
},
});
app.component('perfList', {
templateUrl: '../subpackages/templates/perf-list.templateV3.html',
controller: PerfListController,
bindings: {
contentJson: '<',
getGlobalContent: '&'
},
});
})(myApp);
You could create a custom directive as show in Execute a function inside ng-repeat in AngularJS
Found the solution. Instead of doing this
<td class="cs-cart-sum-td" ng-bind="$ctrl.myNewHtml(cartperf.perf_desc)"></td>
I did this.
<td class="cs-cart-sum-td" ng-bind-html="$ctrl.myHtml({item: cartperf.perf_desc})"></td>

AngularJs - How to use method of one controller in multiple controllers?

I am bit new to AngularJS.
Here is my code:
table.js
.controller('ModalDemoCtrl', function ($scope, $rootScope, $uibModal, $log, tableService) {
$rootScope.$on("openRootDialog", function(event, html){
$scope.openDialog(html);
});
$scope.openDialog = function (html) {
// TODO: replace option dialog with your options:
var modalInstance = $uibModal.open({
animation: true,
templateUrl: html + '.html',
controller: 'ModalInstanceCtrl',
size: 'md',
backdrop: 'static',
keyboard: true,
resolve: {
content: function () {
return $scope.modalContent;
}
}
});
modalInstance.result.then(function (result) {
// Add user in you database
tableService.addUserData(result);
// Add user in your view
$scope.data.push(result)
$scope.tableEdit.reload();
});
}
})
.controller('ModalInstanceCtrl', function ($scope, $modalInstance, content) {
$scope.modalContent = content;
$scope.ok = function () {
$modalInstance.close($scope.user);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
})
//user
.controller('tableUserCtrl', function($scope, $rootScope, $uibModal, $log, $filter, $sce, ngTableParams, tableService) {
//var data = tableService.data;
var selfUser = this;
$scope.data = [];
//selfUser.obj = null;
var promise = tableService.getUserData();
promise.then(
function(payload) {
$scope.data = payload.data;
$scope.tableEdit = new ngTableParams({
page: 1, // show first page
count: 10, // count per page
sorting: {
name: 'asc' // initial sorting
}
}, {
total: $scope.data.length, // length of data
getData: function($defer, params) {
//$defer.resolve(selfUser.data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
//sorting
var orderedData = params.sorting() ? $filter('orderBy')($scope.data, params.orderBy()) : $scope.data;
//filtering
orderedData = params.filter() ? $filter('filter')(orderedData, params.filter()) : orderedData;
//orderedData = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count());
//params.total(orderedData.length);
//$defer.resolve(orderedData);
$defer.resolve(orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
},
function(errorPayload) {
$log.error('failure loading movie', errorPayload);
});
//to update data
$scope.updateUser = function(w) {
tableService.updateUserData(w);
}
$scope.removeUser = function(id, w) {
tableService.removeUserData(id)
//alert(JSON.stringify($scope.data))
$scope.data.splice($scope.data.indexOf(w), 1);
$scope.tableEdit.reload();
//alert(JSON.stringify($scope.data))
}
$scope.openUserDialog = function(html) {
$rootScope.$emit("openRootDialog", {});
}
})
view.html
<div class="container" data-ng-controller="tableUserCtrl">
<!--<div class="p-t-0" data-ng-controller="ModalDemoCtrl"> -->
<script type="text/ng-template" id="adduser.html">
<div class="modal-header">
<!--<h4 class="modal-title">Add User</h4>-->
</div>
<form role="form" ng-submit="insertInfo(userInfo);" name="userForm" novalidate>
<div class="modal-body m-l-15">
<div class="row">
<div class="form-group fg-float m-b-30">
<div class="fg-line">
<input type="text" class="input-sm form-control fg-input" name="name" ng-model="user.name" required="">
<label class="fg-label">Name</label>
</div>
<div ng-show="userForm.$submitted || userForm.name.$touched">
<div ng-show="userForm.name.$error.required" class="error">This field is required.</div>
</div>
</div>
...
</div>
</div>
<div class="modal-footer">
<button class="btn btn-link" ng-click="ok(user);" ng-disabled="userForm.$invalid">Submit</button>
<button class="btn btn-link" ng-click="cancel()">Cancel</button>
</div>
</form>
</script>
<button class="btn btn-default pull-right" ng-click="openUserDialog('adduser')">Add User</button><br/><br/>
<!--</div>-->
<div class="card">
<div class="card-header">
<h2>Users <small></small></h2>
</div>
<div class="card-body">
<div class="table-responsive">
<table ng-table="tableEdit" class="table table-striped table-vmiddle" show-filter="true">
<tr ng-repeat="w in $data" ng-class="{ 'active': w.$edit }">
<td data-title="'Name'" filter="{ 'name': 'text' }" sortable="'name'">
<span ng-if="!w.$edit">{{ w.name }}</span>
<div ng-if="w.$edit"><input class="form-control" type="text" ng-model="w.name" /></div>
</td>
...
<td data-title="'Actions'">
<button type="button" class="btn btn-default" ng-if="!w.$edit" ng-click="w.$edit = true"><i class="zmdi zmdi-edit"></i></button>
<button type="button" class="btn btn-default" ng-if="!w.$edit" ng-click="removeUser(w.user_id, w)"><i class="zmdi zmdi-close"></i></button>
<button type="button" class="btn btn-success" ng-if="w.$edit" ng-click="w.$edit = false; updateUser(w)"><i class="zmdi zmdi-check"></i></button>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
I am passing html template name in openUserDialog function from view as I need to use that name in openDialog function written in ModalDemoCtrl so I can use dynamic templates in modal.
I have searched a lot but couldn't get exact things that how can I pass args to openRootDialog from openUserDialogfunction written in tableUserCtrl?
can anyone please help me? is there any syntax issue? I don't have any idea about $emit, $on etc. as am using it first time.
Use $rootscope,
this is example:
app.run(function($rootScope) {
$rootScope.someMethod=function(){
//do staff
}
}
in another controller just use $scope.someMethod(), in view someMethod().
it is global method now.

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