Editing model property inside ngRepeat, error undefined - angularjs

I'm quite inexperienced with AngularJS.
I've read some answers that might be related but they were not clear enough for me.
My code- Plunker
I've created a table using ngRepeat and I want to change the websites name inside this table
only after clicking save button.
But I get error undefined.
My Code:
var webApp = angular.module('webApp', []);
//controllers
webApp.controller ('websitesCtrl', function ($scope, Websites) {
//$scope.x = new Website('1','3343','32434','name','privKey','pubKey','userID');
$scope.websites = Websites.get();
//This function displayes site details
$scope.expandWeb = function(website) {
console.log('expand');
$scope.websiteNew = angular.copy(website);
$scope.showName = true;
};
$scope.saveWeb = function(websiteNew) {
$scope.website.name = websiteNew.name;
$scope.showName = false;
};
});
//services
webApp.factory('Websites', function(){
var websites = {};
websites.get = function() {
return [{
id: '1',
created: '223112',
updated: '222212',
name: 'google.com',
secretKey: 'dhsd#22%$',
publicKey: '234233###',
userIdentification:'COOKIES'
},
{
id: '2',
created: '1111112',
updated: '444412',
name: 'walla.com',
secretKey: 'dhsd#22%$',
publicKey: '234233###',
userIdentification:'NONE-COOKIES'
},
{
id: '3',
created: '1111112',
updated: '444412',
name: 'Umms.com',
secretKey: 'dhsd#22%$',
publicKey: '234233###',
userIdentification:'NONE-COOKIES'
}
]
};
return websites;
});
My HTML:
<html ng-app="webApp">
<head>
<script data-require="angular.js#1.0.7" data-semver="1.0.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="app.js"></script>
</head>
<body ng-controller='websitesCtrl'>
<table >
<tr ng-repeat="website in websites">
<td>
{{website.name}}
<button ng-click='expandWeb(website)'>edit name</button>
</td>
</tr>
</table>
<div ng-show="showName">
<input ng-model="websiteNew.name"/>
<button ng-click='saveWeb(websiteNew)'>save</button>
</div>
</body>
</html>

$scope.webSite is undefined in saveWeb method. You should probably set it in expandWeb method.
$scope.expandWeb = function(website) {
console.log('expand');
$scope.website = website;
$scope.websiteNew = angular.copy(website);
$scope.showName = true;
};
http://plnkr.co/edit/beExyHMpXigVlCgJyfkF?p=preview

Related

Load Initial Image to Page AngularJS

I have a list of names from the model that are listed on the page when the page loads. When i click the name, the corresponding image from the model appears on the page. Is there a way within this to load an initial
image [0]when the page loads? This could be a random image or the first image in the model data set.
<!DOCTYPE html>
<html ng-app = "myApp"><head>
<meta charset="UTF-8">
<title>Cat Clicker</title>
<link rel="stylesheet" type="text/css" href="bootstrap.min.css">
<link rel ="stylesheet" type "text/css" href ="clicker.css">
<script type = "text/javascript" src="Libs/angular.js"></script>
<script type = "text/javascript" src="js/CatClickerMe.js"></script>
<body>
<div ng-controller = "MainController as vm">
<div ng-repeat = "cat in vm.options.catList">
<h3 ng-click = "vm.selectCat(cat)">{{cat.name}}</h3>
</div>
<hr>
<h3>{{vm.selectedCat.name}}</h3>
<img ng-src ="{{vm.selectedCat.images}}">
</div>
</div>
</div>
</body>
</html>
JS
"use strict";
angular.module('myApp',[]);
angular.module('myApp').controller('MainController', function($scope) {
var vm = this;
vm.selectCat=selectCat;
vm.options = {
catList:[
{
name: 'Fluffy',
images: 'images/Fluffy.jpeg'
},
{
name: 'Blacky',
images: 'images/blacky.jpeg'
},
{
name: 'Tabby',
images: 'images/tabby.jpeg'
},
{
name: 'Cleo',
images: 'images/Cleo.jpeg'
}
],
};
function selectCat(pos) {
vm.selectedCat = pos;
};
});
Load first image by setting vm.selectedCat just below vm.options
vm.selectedCat = vm.options.catList[0];
Below is the jsfiddle link for your reference
jsfiddle : https://jsfiddle.net/Lpaudwf8/21/
Can you Try this :-
"use strict";
angular.module('myApp',[]);
angular.module('myApp').controller('MainController', function($scope) {
var vm = this;
vm.selectCat=selectCat;
vm.options = {
catList:[
{
name: 'Fluffy',
images: 'images/Fluffy.jpeg'
},
{
name: 'Blacky',
images: 'images/blacky.jpeg'
},
{
name: 'Tabby',
images: 'images/tabby.jpeg'
},
{
name: 'Cleo',
images: 'images/Cleo.jpeg'
}
],
};
function selectCat(pos) {
vm.selectedCat = pos;
};
function Init(){
vm.selectedCat = vm.options.catList[0];
}
Init();
});

displaying a multiple matching values from array using filter

I am having trouble displaying the multiple values form text box i.e an entered values is matching with an values of array we need to display the matching value,for me displaying only one value. please help me to find out the solution.
in this example if type "ball" it's displaying if we type "ball all" it has to show both "ball" "all" but for it's not displaying bcoz here we are not returning an array if i assign to array it's throwing an errors.can any one help me where i did mistake.
var app = angular.module('angularPracticeApp');
app.controller('AppController', function ($scope) {
$scope.match = {};
$scope.words = [
{ title: "ball", type: 'object' },
{ title: "wall", type: 'object' },
{ title: "all", type: 'word' },
{ title: "alloy", type: 'material' }
];
});
app.filter('exact', function(){
return function(items, match){
var matching = [], matches,resultArray = [];
angular.forEach(items, function(item){ // e.g. { title: "ball" }
matches = true;
angular.forEach(match, function(value, key){ // e.g. 'all', 'title'
var stringArray = value.split(/(\s+)/);
console.log(stringArray);
for(var i=0;i<stringArray.length;i++){
if(!!value){ // do not compare if value is empty
matches = matches && (item[key] === stringArray[i]);
/* if(item[key] === stringArray[i]){
console.log(stringArray[i]);
resultArray.push(stringArray[i]);
}*/
}
}
});
if(matches){
console.log(resultArray);
matching.push(item);
}
});
return matching;
}
});
<!doctype html>
<html ng-app="plunker">
<head>
<script src="http://code.jquery.com/jquery-2.0.0.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/js/bootstrap.min.js"></script>
<script src="script.js"></script>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css" rel="stylesheet">
<link rel="stylesheet" href="main.css" />
</head>
<body ng-controller="AppController">
<div>
Find words that exactly match title:
<input ng-model="match.title" />
<br>
<table>
<tr ng-repeat="word in words | exact:match">
<td>{{word.title}}</td>
</tr>
</table>
</div>
</body>
</html>
Sorry could not debug your filter, so I made my own, please use it as reference.
JSFiddle Demo
JS:
var app = angular.module('myApp', []);
app.controller('MyController', function MyController($scope) {
$scope.match = {};
$scope.words = [
{ title: "ball", type: 'object' },
{ title: "wall", type: 'object' },
{ title: "all", type: 'word' },
{ title: "alloy", type: 'material' }
];
});
app.filter('exact', function($filter){
return function(items, match){
console.log(match);
if(Object.keys(match).length !== 0){
match = match.title.split(" ");
}else{
console.log("itesm", items);
return items;
}
if(match){
return $filter("filter")(items, function(listItem){
return match.indexOf(listItem.title) != -1;
});
}
};
});
Ok I think I understand what you want and I think there might be better approach. Here's solution I prepared for you, it's much cleaner:
http://jsfiddle.net/U3pVM/33950/
HTML:
<div ng-app>
<div ng-controller="SomeCtrl">
<div>
Find words that exactly match title:
<input ng-model="match.title" />
<br>
<table>
<tr ng-repeat="word in wordsCopy">
<td>{{word.title}}</td>
</tr>
</table>
</div>
</div>
</div>
and JS:
function SomeCtrl($scope) {
$scope.words = [{
title: "ball",
type: 'object'
}, {
title: "wall",
type: 'object'
}, {
title: "all",
type: 'word'
}, {
title: "alloy",
type: 'material'
}];
$scope.wordsCopy = $scope.words;
$scope.$watch('match.title', (newVal, oldVal) => {
if (newVal) {
$scope.wordsCopy = $scope.words.filter((val, index) => {
return newVal.split(' ').indexOf(val.title) !== -1;
});
} else {
$scope.wordsCopy = $scope.words;
}
});
};

Custom directive not outputting correct result

I have the following custom directive customerDirective :
var app = angular.module('directiveApp', []);
var dirController = app.controller('DirectiveController', function() {
this.customer = {
name: 'James',
address: 'Mellieha'
};
});
dirController.directive('customerDirective', function() {
return {
template: 'Name: {{customer.name}} Address: {{customer.address}}'
};
});
And I invoked it in index.html as follows :
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-example12-production</title>
<script src="../../bower_components/angular/angular.min.js"></script>
<script src="directive.js"></script>
</head>
<body ng-app="directiveApp">
<div ng-controller="DirectiveController">
<div customer-directive></div>
</div>
</body>
</html>
However the result outputted is not as expected:
Name: Address:
For some reason, the angular expressions containing the customer details are not being captured. I resigned to the fact that I am probably overlooking something very obvious but alas I have not managed so far.
PS: This example is taken directly from the AngularJS Developer Guide particularly from this section
You have two options to solve this:
Example with $scope:
var app = angular.module('directiveApp', []);
app.controller('DirectiveController', function($scope) {
$scope.customer = {
name: 'James',
address: 'Mellieha'
};
});
app.directive('customerDirective', function() {
return {
template: 'Name: {{customer.name}} Address: {{customer.address}}'
};
});
Example with controller-as (without $scope):
app.controller('DirectiveController', function() {
this.customer = {
name: 'James',
address: 'Mellieha'
};
});
app.directive('customerDirective', function() {
return {
template: 'Name: {{dirCtrl.customer.name}} Address: {{dirCtrl.customer.address}}'
};
});
<body ng-app="directiveApp">
<div ng-controller="DirectiveController as dirCtrl">
<div customer-directive></div>
</div>
</body>
If you change this -- > $scope its working
var app = angular.module('directiveApp', []);
var dirController = app.controller('DirectiveController', function($scope) {
// Here Change
$scope.customer = {
name: 'James',
address: 'Mellieha'
};
});
dirController.directive('customerDirective', function() {
return {
template: 'Name: {{customer.name}} Address: {{customer.address}}'
};
});

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)

I can not get the select working correctly in angularjs

I tried to do as this article recommends to get select-options working in AngularJS.
http://gurustop.net/blog/2014/01/28/common-problems-and-solutions-when-using-select-elements-with-angular-js-ng-options-initial-selection/
However I have got it messed up some how. Here is a fiddlerjs of the code
http://jsfiddle.net/8faa5/
Here is the HTML
<!DOCTYPE html>
<html class="no-js" data-ng-app="TestModule">
<head>
<title></title>
</head>
<body data-ng-controller="TestController">
<h3>Test Select</h3>
Current Value: {{ ourData.CurrentSelected}} <br>
<select ng-init="ourData._currVal = {Value: ourData.CurrentSelected}"
ng-change="ourData.CurrentSelected = ourData._currVal.Value"
ng-model="ourData._currVal"
ng-options="oneItem.Value as oneItem.Disp
for oneItem in ourData.StuffForDropDown track by oneItem.Value"></select>
<!-- Get Javascript -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script>
<script src="js/data.js"></script>
</body>
</html>
Here is js/data.js
(function() {
"use strict";
var smallData = {
StuffForDropDown: [
{
Disp: "01-Prospect",
Value: 5
},
{
Disp: "02-Constituet Issue",
Value: 10
}
],
CurrentSelected: "10"
};
var myModule = angular.module("TestModule", ['ui.mask']);
myModule.controller("TestController", ["$scope",
function ($scope){
$scope.ourData = smallData;
}
]);
})();
First of all, your jsfiddle is messed up. You have defined angularjs twice, once in the jsfiddle options and the second time in the code. Also you overcomplicated your code. I made a simple rewrite of your code that is working in this jsfiddle.
<div data-ng-app="TestModule">
<div data-ng-controller="TestController">
<h3>Test Select</h3>
Current Value: {{ ourData._currval}}
<br>
<select ng-init="ourData._currVal = {Value: ourData.CurrentSelected}"
ng-model="ourData._currval" ng-options="oneItem.Value as oneItem.Disp
for oneItem in ourData.StuffForDropDown"></select>
</div>
</div>
(function () {
"use strict";
var smallData = {
StuffForDropDown: [{
Disp: "01-Prospect",
Value: 5
}, {
Disp: "02-Constituet Issue",
Value: 10
}],
CurrentSelected: "10"
};
var myModule = angular.module("TestModule", []);
myModule.controller("TestController", ["$scope",
function ($scope) {
$scope.ourData = smallData;
}]);
})();
**Edit:
OK, I have revised my code according to your new request int the comment. The code goes as follows (new plunker)
<div data-ng-app="TestModule">
<div data-ng-controller="TestController">
<h3>Test Select</h3>
Current Value: {{ currentItem.Value}}
<br>
<select ng-model="currentItem" ng-options="u as u.Disp for u in items track by u.Value"></select>
</div>
</div>
(function () {
"use strict";
var myModule = angular.module("TestModule", []);
var ctrl = function ($scope) {
$scope.items = [{
Disp: "01-Prospect",
Value: 5
}, {
Disp: "02-Constituet Issue",
Value: 10
}];
$scope.currentItem = $scope.items[1];
};
myModule.controller("TestController", ctrl)
})();

Resources