ng-repeat wont refresh WITH $apply - angularjs

This is the code I'm using (and have been using throughout the whole project), the scope is updated but ng-repeat wont refresh and I'm using scope.$apply.. Have no idea why, few devs also took a look at the code.. no solution..
Directive:
app.directive("addBrandSettings", function(){
return {
restrict: "A",
link: function(scope, element, attrs){
element.bind("keypress", function(e){
if(e.which === 13){
var brand = element.val();
scope.$apply(function(){
scope.settings.brands.push(brand);
console.log(scope.settings.brands);
})
element.val("");
}
})
}
}
});
HTML:
<input add-brand-settings type="text" placeholder="Add Brand"/>
<p ng-repeat="brand in settings.brands">{{brand}}<a remove-brand-settings index="{{$index}}" href="#"><i class="fa fa-times-circle"></i></a></p>
Scope:
$scope.settings = {
companyInfo: {
name: "",
email: "",
phone: "",
website: ""
},
users: [
{
username: "Supreme Manager",
role: "Super User",
password: "asdasd"
},
{
username: "Regular Grunt",
role: "User",
password: "asdasd"
}
],
brands: [
"Maxi",
"Chipsy",
"Bananice"
],
retailers: [
"Maxi",
"Ikea",
"Tempo"
]
}

Your code works perfectly, so you probably have some syntax problem or something, here's a working example:
var app=angular.module('App', []);
function ctrl($scope){
$scope.settings = {
companyInfo: {
name: "",
email: "",
phone: "",
website: ""
},
users: [
{
username: "Supreme Manager",
role: "Super User",
password: "asdasd"
},
{
username: "Regular Grunt",
role: "User",
password: "asdasd"
}
],
brands: [
"Maxi",
"Chipsy",
"Bananice"
],
retailers: [
"Maxi",
"Ikea",
"Tempo"
]
}
}
app.directive("addBrandSettings", function(){
return {
restrict: "A",
link: function(scope, element, attrs){
element.bind("keypress", function(e){
if(e.which === 13){
var brand = element.val();
scope.$apply(function(){
scope.settings.brands.push(brand);
console.log(scope.settings.brands);
})
element.val("");
}
})
}
}
});
html:
<div ng-app="App" ng-controller="ctrl">
<input add-brand-settings type="text" placeholder="Add Brand"/>
<p ng-repeat="brand in settings.brands">{{brand}}<a remove-brand-settings index="{{$index}}" href="#"><i class="fa fa-times-circle"></i></a></p>
</div>
Live example :http://jsfiddle.net/choroshin/7zVd2/

Related

angular dropdown multiselect to connect data between three dropdowns

I have three multiselect dropdowns:-
<label>Dropdown One</label>
<div ng-model="a.dp1" ng-dropdown-multiselect="" options="multiSelectArray" selected-model="dropDownOne" extra-settings="multiSelectSettings">
</div>
<label>Dropdown Two</label>
<div ng-model="a.dp2" ng-dropdown-multiselect="" options="multiSelectArray" selected-model="dropDownTwo" extra-settings="multiSelectSettings">
</div>
<label>Dropdown Three</label>
<div ng-model="a.dp3" ng-dropdown-multiselect="" options="multiSelectArray" selected-model="dropDownThree" extra-settings="multiSelectSettings">
</div>
Directive Code:-
(function () {
'use strict';
angular.module('myApp.components')
.directive('page', page);
page.$inject = ['$http', '$timeout', 'ApiServices'];
function page($http, $timeout, ApiServices) {
return {
restrict: 'EA',
scope: {},
controller: function ($scope) {
$scope.a = { };
$scope.dropDownOne = [];
$scope.dropDownTwo = [];
$scope.dropDownThree = [];
$scope.multiSelectArray = [{
name: "Ayan"
}, {
name: "Rita"
}, {
name: "Mohit"
}, {
name: "Shittal"
}, {
name: "Jayant"
}, {
name: "Sachin"
}, {
name: "Tina"
}, {
name: "Babita"
}, {
name: "Priya"
}];
$scope.multiSelectSettings = {
smartButtonMaxItems: 11,
scrollable: true,
displayProp: "name",
idProp: "name",
externalIdProp: "name"
};
},
templateUrl: 'js/folder/system/page.html'
};
}
})();
What I am trying to do here is when I select particular options from 'Dropdown One' the same options got selected in 'Dropdown Two' and 'Dropdown Three' and get disabled so that users can't unselect them. Also, the users can select more options in 'Dropdown Two' and 'Dropdown Three' if they want, but the options from 'Dropdown One' should be checked already and disabled.
I am trying to disable the options using 'disabled' attribute but not able to for selected options. Any idea how I can do that?

Call Controller function from the directive in angular JS

I am using angular JS right now, in the i am using ui-bootstrap typeahead
I am trying scroll on demand logic in typeahead
i have tried this:
HTML:
<div class='container-fluid' ng-controller="TypeaheadCtrl">
<pre>Model: {{selected| json}}</pre>
<input type="text" ng-model="selected" maxlength="5" typeahead="country.name for country in countries | filter:$viewValue | limitTo:8">
</div>
JS:
angular.module('plunker', ['ui.bootstrap'])
.controller('TypeaheadCtrl', function ($scope) {
$scope.selected = undefined;
$scope.countries = [
{ name: "Afghanistan", code: "AF" },
{ name: "Aland Islands", code: "AX" },
{ name: "Albania", code: "AL" },
{ name: "Algeria", code: "DZ" },
{ name: "American Samoa", code: "AS" },
{ name: "Andorra", code: "AD" },
{ name: "Angola", code: "AO" },
{ name: "Anguilla", code: "AI" },
{ name: "Antarctica", code: "AQ" },
{ name: "Antigua and Barbuda", code: "AG" },
{ name: "Argentina", code: "AR" },
{ name: "Armenia", code: "AM" },
{ name: "Aruba", code: "AW" },
{ name: "Ascension Island", code: "AC" },
{ name: "Australia", code: "AU" },
{ name: "Austria", code: "AT" },
{ name: "Azerbaijan", code: "AZ" },
{ name: "Bahamas", code: "BS" },
{ name: "Bahrain", code: "BH" },
{ name: "Bangladesh", code: "BD" },
{ name: "Barbados", code: "BB" },
{ name: "Belarus", code: "BY" },
{ name: "Zimbabwe", code: "ZW" }
];
$scope.call= function(){
alert('reached end');
};
})
.directive('ul', function () {
return {
restrict: 'E',
link: function ($scope, element, attrs) {
element.bind('scroll', function (e) {
if ($(this).scrollTop() + $(this).innerHeight() >= $(this)[0].scrollHeight) {
// alert('end reached');
$scope.call();
}
})
}
}
});
But in the above try $scope.call(); function is not calling. Any one pls help me
REFERENCE PLUNKER
My actual requirement is when the scroll reaches the end, remaining records has to show in the typeahead
Make these changes to your directive, add a callBack scope variable in directive and add a callBack attribute in HTML , type function
.directive('ul', function () {
return {
restrict: 'E',
scope: {
callBack:"&"
}
link: function (scope, element, attrs) {
scope.callBack();
})
}
}
<div ul callBack="functionName"></div>

ng-click does not call function in mdDialog

I am a little new to AngularJS but I cannot figure out why the ng-click here will not call th addingSt() function, I wonder if it has something to do with the fact that it is being called from a mdDialog. Thanks for your help.
Heres my html for the mdDialog:
<md-dialog aria-label="Send Email">
<md-dialog-content>
<h3>Issue Details</h3>
<h4>Description</h4>
<md-input-container>
<label>Add description:</label>
<textarea class="form-control input-lg" style="width: 500px; height:100px;"></textarea>
</md-input-container>
<h3>Sub-tasks:</h3>
<md-list-item ng-repeat=" subtask in subtasks">
<p>{{subtask.content}}</p>
<md-checkbox aria-label="blarg" class="md-secondary" style="padding-right:60px;" ng-click="removeSubTask(subtask,$index)"></md-checkbox>
<md-list-item ng-if="addingTask === true"> <input ng-if="addingTask===true" ng-model="task.content" aria-label="blarg" placeholder="Add Subtask Here"></input>
</md-dialog-content>
<md-dialog-actions>
<md-button ng-show="addingTask === false" ng-click="addingSt()" class="btn btn-primary">
Add Sub-Task
</md-button>
<md-button ng-show="addingTask === true" ng-click="addingSt()" class="btn btn-primary">
cancel
</md-button>
<md-button ng-show="addingTask === true" ng-click="addSubTask()" class="btn btn-primary">
Submit
</md-button>
<md-button ng-click="closeDialog()" class="btn btn-primary">
Close
</md-button>
Here's the controller for the parent of the above mdDialog, (the controller for the mdDialog is nested inside it and works fine for all functions accept the addingSt() function)
var app = angular.module('epr')
app.controller('adminMainCtr',[ '$scope','$mdDialog',function($scope, $mdDialog) {
$scope.issues = [
{ name: 'Blizzard', img: 'img/100-0.jpeg', WardMessage: true, index:0, subtasks:[{content:"Shovel Sister Pensioner's Driveway "},
{content:"Clear downed trees at the Bush's home "}]},
{ name: 'Tornado', img: 'img/100-1.jpeg', WardMessage: false, index:1, subtasks:[{content:"",index:0}] },
{ name: 'Peterson Family Car Crash', img: 'img/100-2.jpeg', WardMessage: false, index:2, subtasks:[{content:"",index:0}] },
{ name: 'Flood', img: 'img/100-2.jpeg', WardMessage: false, index:3, subtasks:[{content:"",index:0}] },
{ name: 'School Shooting', img: 'img/100-2.jpeg', WardMessage: false, index:4, subtasks:[{content:"",index:0}] }
];
$scope.goToIssue = function(issue, event) {
var parentEl = angular.element(document.body);
$mdDialog.show({
//parent: parentEl,
templateUrl:'views/issue.html',
locals: {
items: $scope.items,
issue: issue
},
controller: DialogController
});
function DialogController($scope, $mdDialog) {
$scope.subtasks = issue.subtasks;
$scope.addingTask = false;
$scope.task={content:""};
$scope.closeDialog = function() {
console.log($scope.addingTask);
$mdDialog.hide();
}
$scope.removeSubTask = function(subtask,index){
$scope.subtasks.splice(index,1);
}
}
$scope.addSubTask = function() {
console.log("here");
}
$scope.addingSt = function() {
if($scope.addingTask === false) {
console.log($scope.addingTask);
$scope.addingTask = true;
return;
}
if($scope.addingTask === true) {
$scope.addingTask = false;
return;
}
}
}
}]);
Any help that you can lend me would be very appreciated!!!
You messed with the HTML and angylar code.
Errors found:
1) angular module initialization.
var app = angular.module('MyApp', ['ngMaterial'])
2) You placed some function outside the DialogController
3) md-list-item HTML has no end tags.
Created working Plunkr here. https://plnkr.co/edit/Sl1WzLMCd8sW34Agj6g0?p=preview . Hope it will solve your problem.
(function() {
'use strict';
var app = angular.module('MyApp', ['ngMaterial'])
app.controller('adminMainCtr', ['$scope', '$mdDialog', function($scope, $mdDialog) {
$scope.issues = [{
name: 'Blizzard',
img: 'img/100-0.jpeg',
WardMessage: true,
index: 0,
subtasks: [{
content: "Shovel Sister Pensioner's Driveway "
}, {
content: "Clear downed trees at the Bush's home "
}]
}, {
name: 'Tornado',
img: 'img/100-1.jpeg',
WardMessage: false,
index: 1,
subtasks: [{
content: "",
index: 0
}]
}, {
name: 'Peterson Family Car Crash',
img: 'img/100-2.jpeg',
WardMessage: false,
index: 2,
subtasks: [{
content: "",
index: 0
}]
}, {
name: 'Flood',
img: 'img/100-2.jpeg',
WardMessage: false,
index: 3,
subtasks: [{
content: "",
index: 0
}]
}, {
name: 'School Shooting',
img: 'img/100-2.jpeg',
WardMessage: false,
index: 4,
subtasks: [{
content: "",
index: 0
}]
}];
$scope.goToIssue = function(issue, event) {
var parentEl = angular.element(document.body);
$mdDialog.show({
templateUrl: 'mddialog.html',
locals: {
message: {
items: $scope.items,
issue: issue
}
},
controller: DialogController
});
}
function DialogController($scope, $mdDialog, message) {
console.log(message)
//$scope.subtasks = message.issue.subtasks;
$scope.addingTask = false;
$scope.task = {
content: ""
};
$scope.closeDialog = function() {
console.log($scope.addingTask);
$mdDialog.hide();
}
$scope.removeSubTask = function(subtask, index) {
$scope.subtasks.splice(index, 1);
}
$scope.addSubTask = function() {
console.log("here");
}
$scope.addingSt = function() {
if ($scope.addingTask === false) {
console.log($scope.addingTask);
$scope.addingTask = true;
return;
}
if ($scope.addingTask === true) {
$scope.addingTask = false;
return;
}
}
}
}]);
})();

ng-repeat inside popover not work angularjs

I know that there are a lot of answers on this issue but I tried everything and nothing work. If the element popover work, I can't see any content inside.
My last test :
On my html template :
<div class="momentctrl" ng-controller="ButtonsMomentCtrl">
<div class="btn-group-checkbox">
<button class="btn btn-primary" ng-model="checkModel.daybutton" ng-click="momentChange('daybutton')" type="button" btn-checkbox prevent-default bs-popover items="momentdays", title="Moment of day">Day</button>
<script type="text/ng-template" id="popover_template.html">
<div ng-repeat='momentday in momentdays'>
<label>
<input type='checkbox' ng-model='momentday.isChecked' ng-change='changeMomentDay(momentday)'/> <span class='ng-binding-advancedsearch'>{{momentday.name}}</span>
</label>
</div>
</script>
</div>
</div>
on my controllers :
angular.module('my.controllers',['ui.bootstrap'])
.controller('ButtonsMomentCtrl', ['$scope', '$rootScope', function ($scope, $rootScope) {
$scope.checkModel = {
allbutton:true,
nowbutton: false,
daybutton: false,
tonightbutton: false
};
$scope.momentdays = [
{
name: "All",
id: 0,
isChecked: true,
col: 1
},
{
name: "Morning",
id: 0,
isChecked: false,
col: 1
},
{
name: "Afternoon",
id: 1,
isChecked: false,
col: 1
},
{
name: "Early evening",
id: 1,
isChecked: false,
col: 1
},
{
name: "Evening",
id: 1,
isChecked: false,
col: 1
},
{
name: "Night",
id: 1,
isChecked: false,
col: 1
}
];
$scope.momentChange = function(moment){
console.log("momentChange");
}
$scope.changeMomentDay = function(momentDay) {
console.log("changeMomentDay");
};
}])
on my directives :
angular.module('my.directives', [])
.directive('bsPopover', function($compile, $templateCache) {
console.log("directive bs popover");
var getTemplate = function () {
$templateCache.put('templateId.html', 'This is the content of the template');
return $templateCache.get("myPopoverTemplate.html");
}
return {
restrict: "A",
transclude: true,
template: "<span ng-transclude></span>",
link: function (scope, element, attrs) {
var popOverContent;
var html = getTemplate();
popOverContent = $compile(html)(scope);
console.log("popOverContent = "+popOverContent);
var options = {
content: popOverContent,
placement: "bottom",
html: true,
title: scope.title
};
element.popover(options);
},
scope: {
title: '#',
items: '='
}
};
});

Dynamically binding custom directive to ng-repeat

my controller has the json for my form then i have a directive that gets repeated to produce the form elements. based on the 'type' passed to the directive, the directive should know how to render the element.
but i don't know why it's not rendering the form templates properly here but that's a separate issue.
my immediate issue is, i can't seen to pass the ng-model and bind it correctly to the template.
does anyone see my problem?
var myApp = angular.module('myApp', []);
myApp.directive('ioProductElement', ['$compile', function ($compile) {
var dropdownTemplate = '<select ng-model="model" ng-options="option.Text for option in data"></select>';
var textAreaTemplate = '<textarea ng-model="model" class="form-control">{{ data }}</textarea>';
var radioListTemplate = '<span ng-repeat="item in data.Items"><input ng-model="model" type="radio" name="{{ data.Name }}" ng-checked="item.Selected" /><label>{{ item.ProductLabel }}</label> </span>';
return {
restrict: 'E',
replace: true,
scope: {
model: '=',
type: '=',
data: '='
},
link: function (scope, element) {
var getTemplate = function (type) {
var template = '';
switch (type) {
case 'SelectListItem':
template = dropdownTemplate;
scope.model = _.find(scope.data, {
Selected: true
});
break;
case 'TextArea':
template = textAreaTemplate;
break;
case 'RadioList':
template = radioListTemplate;
break;
}
return template;
};
element.html(getTemplate(scope.type));
$compile(element.contents())(scope);
}
};
}]);
myApp.controller('DynamicFormController', function () {
this.productElement = {};
this.product = {
ProductName: 'Online Form',
Company: 'TEST',
Data: []
};
this.productItems = [{
ProductLabel: "Status",
ProductType: "SelectListItem",
ProductData: [{
"Text": "Item1",
"Value": "1",
Selected: true
}, {
"Text": "Item2",
"Value": "2"
}]
}, {
ProductLabel: "Publication",
ProductType: "SelectListItem",
ProductData: [{
Text: 'Item1',
Value: '1'
}, {
Text: 'Item2',
Value: '2',
Selected: true
}]
}, {
ProductLabel: "Caption",
ProductType: "TextArea",
ProductData: "this is some data for the textarea"
}, {
ProductLabel: "Display Advertising",
ProductType: "RadioList",
ProductData: {
Name: "classifiedAdvertising",
Items: [{
Text: 'Full Page',
Selected: true
}, {
Text: '1/2 Page'
}]
}
}, {
ProductLabel: "Status2",
ProductType: "SelectListItem",
ProductData: [{
"Text": "Item1",
"Value": "1"
}, {
"Text": "Item2",
"Value": "2"
}, {
"Text": "Item3",
"Value": "3",
Selected: true
}]
}, ];
this.save = function () {
this.product.Data = this.productItems;
console.log('in save', this.product);
};
});
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.4.0/lodash.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<div class="col-sm-12" ng-app="myApp">
<br />
<form class="form-horizontal" ng-controller="DynamicFormController as ctrl">
<div class="form-group" ng-repeat="item in ctrl.productItems">
<label class="col-sm-2 control-label">{{ item.ProductLabel }}</label>
<div class="col-sm-10">
<io-product-element data-model="ctrl.productElement[item.ProductLabel]" data-type="item.ProductType" data-data="item.ProductData"></io-product-element>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="button" class="btn btn-info" data-ng-click="ctrl.save()" value="Submit" />
product: {{ ctrl.product | json }}
</div>
</div>
</form>
</div>
Try To add a break statement in the first switch case
//[...]
switch (type) {
case 'SelectListItem':
template = dropdownTemplate;
scope.model = _.find(scope.data, {
Selected: true
});
break;
case 'TextArea':
template = textAreaTemplate;
break;
case 'RadioList':
template = radioListTemplate;
break;
}
//[...]

Resources