using ng-model in ng-repeat angularjs - angularjs

I am having some problems with angular. Now I have a following code :
<div ng-repeat='item in items'>
<span>{{item.title}}</span>
<input ng-change="test()" ng-model='abc'> {{abc}}
<span>{{item.price| currency}}</span>
<span>{{item.price * item.quantity| currency}}</span>
<button ng-click="remove($index)">Remove</button>
</div>
<script type="text/javascript" src="libs/angular.min.js"></script>
<script>
function CartController($scope) {
$scope.items = [
{title: 'Paint pots', quantity: 8, price: 3.95},
{title: 'Polka dots', quantity: 17, price: 12.95},
{title: 'Pebbles', quantity: 5, price: 6.95}
];
$scope.test = function() {
console.log($scope.abc);
}
$scope.remove = function(index) {
$scope.items.splice(index, 1);
}
}
</script>
I wanna know why I can not console.log abc value in controller? My English is bad, pls help me. Thanks in advance

Try changing
$scope.test = function() {
console.log($scope.abc);
}
to
$scope.test = function() {
console.log(this.abc);
}
"this" will resolve to the current scope object and you should be able to print the value as you keep changing the text.

What happens if you declare abc as a variable before trying to use it?
function CartController($scope){
var $scope.abc = 'foo';
...

Related

Angularjs: evaluate expression inside HTML tag

Note this question is a bit different from the similar titled here or here. What I want to do is to "evaluate inside the HTML tag" not inside a directive (or in the controller). This description can be wrong or hard to understand but I cannot find a better way; so I made bellow self-contained code to illustrate. You may copy and past and save as "xyz.html" and see what I mean.
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.6/angular.min.js"></script>
<script>
'use strict';
let app = angular.module('myApp', []);
app.controller('myCtrl', ['$scope', function ($scope) {
let d = DATA_TYPE;
let e = EDIT_TYPE;
$scope.tbContents = {
fields: [
{name: 'name', dataType: d.text, editType: e.text, refs:[]},
{name: 'catalog', dataType: d.text, editType: e.dropdown, refs: ['catalog1', 'catalog2', 'catalog3']},
{name: 'status', dataType: d.int, editType: e.dropdown, refs: [1, 2, 3, 4]}],
rows: [
{name: 'name1', catalog: 'catalog1', status: 1},
{name: 'name2', catalog: 'catalog1', status: 1},
{name: 'name3', catalog: 'catalog2', status: 2}
]
};
$scope.refNameKey = '';
$scope.setRefNameKey = function(key) {
$scope.refNameKey = key;
};
$scope.getRefByNameKey = function(key) {
let res = [];
for(let i = 0; i < $scope.tbContents.fields.length; i++) {
if($scope.tbContents.fields[i].name == key) {
return $scope.tbContents.fields[i].refs;
}
}
};
}]);
app.filter('filterDropdown', function () {
return function (fields) {
let output = [];
for (let i = 0; i < fields.length; i++) {
if (fields[i].editType == EDIT_TYPE.dropdown) {
output.push(fields[i]);
}
}
return output;
};
});
const DATA_TYPE = {
int: 1,
text: 2,
//...
};
const EDIT_TYPE = {
dropdown: 1,
test: 2,
//...
};
</script>
</head>
<body>
<div ng-controller="myCtrl">
<div>
<!--<p ng-repeat="field in tbContents.fields | filterDropdown">{{field.name}}</p>-->
<p ng-repeat="field in tbContents.fields | filterDropdown">{{field.name}}</p>
</div>
<hr />
<div ng-show = "refNameKey">
<p ng-repeat = "ref in getRefByNameKey(refNameKey)">{{ref}}</p>
</div>
</div>
</body>
</html>
What I want is the line I commented in the HTML code, refNameKey=field.name instead of setRefNameKey(field.name). I don't know why refNameKey=field.name does not work, but I don't like creating the setRefNameKey function for this simple task.
ng-repeat creates child scope for each iteration. So your refNameKey variable is created in each child scope and its not referring to the refNameKey in parent scope. You can fix this by modifying it like this:
<p ng-repeat="field in tbContents.fields | filterDropdown">{{field.name}}</p>
Plunker : http://plnkr.co/edit/mcDvGqd6SFCfmqyfUNRc?p=preview

Replace option values

I'm trying to update the options after 3 seconds.
In my HTML I have the code that generates the options.
<select
ng-model="selectedOperator"
ng-options="operator as operator.name for operator in operators">
</select>
And in the same HTML, I have
$(function() {
$('select').material_select();
});
that initializes the Materialize dropdown.
In my Javascript:
.controller('MainCtrl', function ($scope, $timeout) {
// initialize old(first) values
$scope.operators = [
{ value: 1, name: 'Old-One' },
{ value: 2, name: 'Old-Two' }
];
$scope.selectedOperator = null; // no default selected value
// after three seconds, replace the old value with new one.
$timeout(function() {
$scope.operators = [{ value: 10, name: 'New Awesome' }];
// reinitialize the materialize select.
$('select').material_select();
}, 3000);
});
However it's not being updated, it's still generating the old value.
In the HTML, the value of {{ operators }} is the new value.
I'm new to Angular, any help would be greatly appreciated.
Cheers
Update: I'm like 70% sure they don't play well with each other, made a temporary fix by replacing select with radio button.
<select name="repeatSelect" id="repeatSelect" ng-model="selectedOperator">
<option ng-repeat="operator in operators" value="{{operator.value}}">{{operator.name}}</option>
</select>
DOC
This is sample example you can change this values later, its working fine.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
$(function() {
$('select').material_select();
});
angular.module('myApp', []).controller('namesCtrl', function($scope, $timeout) {
$scope.operators = [
{ value: 1, name: 'Old-One' },
{ value: 2, name: 'Old-Two' }
];
$scope.selectedOperator = null; // no default selected value
// after three seconds, replace the old value with new one.
$timeout(function() {
$scope.operators = [{ value: 10, name: 'New Awesome' }];
// reinitialize the materialize select.
$('select').material_select();
}, 3000);
});
</script>
</head>
<body>
<div ng-app="myApp" ng-controller="namesCtrl">
<h1>Angular JS Application</h1>
<select ng-model="selectedOperator" ng-options="operator as operator.name for operator in operators">
</select>
</div>
</body>

Repeating multidimensional array object in angular

I have an array that looks like this:
[Object{ 82893u82378237832={ id=8, no=1, type="event", name="Sample1"}}, Object{ 128129wq378237832={ id=9, no=1, type="event", name="Sample2"}} ]
Now ignoring the first part which is just a random token i want to get the array inside that. i.e. id,no,type,name and display them in an ng-repeat, how can i achieve this?
This is how i create the above array:
var obj = {};
obj[data.responseData] = {
id: 8,
no: 1,
type: 'event',
name: ''
}
$scope.items.push(obj);
Your example doesn't include an array.
Anyway here's a good example.
Use map to transform an array to another array and use ng-repeat in a similar way that I've done.
Html:
<div ng-app="app">
<div ng-controller="ctrl">
<div ng-repeat="item in myArr">
{{item}}
</div>
</div>
</div>
JS:
angular.module('app', []).
controller('ctrl', function ($scope) {
var arr = [{
myId: '82893u82378237832',
id: 8,
no: 1,
type: "event",
name: "Sample1"
}, {
myId: '128129wq378237832',
id: 9,
no: 1,
type: "event",
name: "Sample2"
}];
// mapped the new object without myId
$scope.myArr = arr.map(function (item) {
return {
id: item.id,
no: item.no,
type: item.type,
name: item.name
}
});
});
JSFIDDLE.

How to chain AngularJS filters in controller

I have few filters in view
<tr ng-repeat="x in list | filter:search| offset:currentPage*pageSize| limitTo:pageSize ">
In my project to achieve good result, i have to make this filtering in controller not in view
i know the basic syntax $filter('filter')('x','x') but i don't know how to make chain of filters in controller, so everything will work as in my example from template.
I found some solution, now just with one filter, but should work with many ;)
$scope.data = data; //my geojson from factory//
$scope.geojson = {}; //i have to make empty object to extend it scope later with data, it is solution i found for leaflet //
$scope.geojson.data = [];
$scope.FilteredGeojson = function() {
var result = $scope.data;
if ($scope.data) {
result = $filter('limitTo')(result,10);
$scope.geojson.data = result;
console.log('success');
}
return result;
};
and i use this function in ng-repeat works fine, but i have to check it with few filters.
You can just re-filter what you get returned from your first filter. So on and so forth.
var filtered;
filtered = $filter('filter')($scope.list, {name: $scope.filterParams.nameSearch});
filtered = $filter('orderBy')(filtered, $scope.filterParams.order);
Below plunkr demonstrates the above.
http://plnkr.co/edit/Ej1O36aOrHoNdTMxH2vH?p=preview
In addition to explicitly applying filters to the result of the previous one you could also build an object that will chain multiple filters together.
Controller
angular.module('Demo', []);
angular.module('Demo')
.controller('DemoCtrl', function($scope, $filter) {
$scope.order = 'calories';
$scope.filteredFruits = $scope.fruits = [{ name: 'Apple', calories: 80 }, { name: 'Grapes', calories: 100 }, { name: 'Lemon', calories: 25 }, { name: 'Lime', calories: 20 }, { name: 'Peach', calories: 85 }, { name: 'Orange', calories: 75 }, { name: 'Strawberry', calories: 65 }];
$scope.filterFruits = function(){
var chain = new filterChain($scope.fruits);
$scope.filteredFruits = chain
.applyFilter('filter', [{ name: $scope.filter }])
.applyFilter('orderBy', [ $scope.order ])
.value;
};
function filterChain(value) {
this.value = value;
}
filterChain.prototype.applyFilter = function(filterName, args) {
args.unshift(this.value);
this.value = $filter(filterName).apply(undefined, args)
return this;
};
});
View
<!doctype html>
<html ng-app="Demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
<script src="script.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="DemoCtrl">
<input type="text" ng-model="filter" ng-change="filterFruits()" placeholder="Filter Fruits" />
<select ng-model="order">
<option value="name">name</option>
<option value="calories">calories</option>
</select>
<div ng-repeat="fruit in filteredFruits">
<strong>Name:</strong> {{fruit.name}}
<strong>Calories:</strong> {{fruit.calories}}
</div>
</div>
</body>
</html>
This is a typical case for FP libraries like lodash or Ramda. Make sure your common data is applied as last arg to each filter. (in this case columns)
$scope.columnDefs = _.compose(
$filter('filter3'),
$filter('filter2'),
$filter('filter1')
)($scope.columns)
or with extra args
$scope.columnDefs = _.compose(
$filter('filter3').bind(null, optionalArg1, optionalArg2),
$filter('filter2').bind(null, optionalArg1),
$filter('filter1')
)($scope.columns)

AngularJS select directive not working in jsfiddle

I was playing around with some jsfiddle examples and changed it for some tests. Unfortunately it is not working anymore and i have no clue why. Can anyone have a quick look at this fiddle and give me a hint:
http://jsfiddle.net/w8LrL8xr/2/
javascript:
var myApp = angular.module("myApp");
myApp.controller("MyCtrl", function($scope) {
$scope.fonts = [
{title: "Arial" , text: 'Url for Arial' },
{title: "Helvetica" , text: 'Url for Helvetica' }
];
$scope.change= function(option){
alert(option.title);
}
}
HTML:
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<select ng-model="opt" ng-options="font.title for font in fonts" ng-change="change(opt)">
</select>
<p>{{opt}}</p>
</div>
</div>
Your module definition is incorrect, you need to supply a list of dependencies to init it correctly or an empty [] if you have none.
e.g.
var myApp = angular.module("myApp", []);
You are also missing a trailing ) when you register your controller.
var myApp = angular.module("myApp", []);
myApp.controller("MyCtrl", function($scope) {
$scope.fonts = [
{title: "Arial" , text: 'Url for Arial' },
{title: "Helvetica" , text: 'Url for Helvetica' }
];
$scope.change= function(option){
alert(option.title);
};
});
Fixed fiddle

Resources