Custom directive not outputting correct result - angularjs

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

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

handsontable in an angularjs directive - render an anchor that has an ng-click

So I'm using Handsontable to render a grid. (Yes, I am NOT using the ngHandsontable. I started out with that but ran into problems and so I went with just rendering a Handsontable from an angularjs directive.)
I want one column to hold an anchor tag.
I want the anchor tag to have the angularjs ng-click directive.
Everything renders correctly but the ng-click is not called.
Here is my example.
var APP = angular.module('APP', ['controllers']);
angular.module('controllers',[])
.controller('testController', function ($scope) {
$scope.doNgClick = function() {
alert('ng-click');
// console.log('ng-click');
};
$scope.simple = [
{
test: "<a href='javascript:void(0);' ng-click='doNgClick()'>Test</a>"
// test: "<a ng-click='doNgClick()'>Test</a>"
}
];
});
APP.directive('htable',function($compile) {
var directive = {};
directive.restrict = 'A';
directive.scope = {
data : '='
};
directive.link = function(scope,element,attrs) {
var container = $(element);
// var safeHtmlRenderer = function (instance, td, row, col, prop, value, cellProperties) {
// var escaped = Handsontable.helper.stringify(value);
// td.innerHTML = escaped;
// return td;
// };
var settings = {
data: scope.data,
readOnly: true,
colHeaders: ['Link'],
columns: [
{
data: "test",
renderer: "html",
// renderer: safeHtmlRenderer,
readyOnly: true
}
]
};
var hot = new Handsontable( container[0], settings );
hot.render();
// console.log(element.html());
// $compile(element.contents())(scope);
};//--end of link function
return directive;
});
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="//handsontable.com/dist/handsontable.full.css">
</head>
<body>
<div ng-app="APP">
<div ng-controller="testController">
<div htable data="simple"></div>
</div
</div>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.24/angular.min.js"></script>
<script src="//handsontable.com/dist/handsontable.full.js"></script>
</body>
</html>
After much reading and digging here is my own answer.
//-- With help from the following:
//--
//-- http://stackoverflow.com/questions/18364208/dynamic-binding-of-ng-click
//-- http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters
//--
var APP = angular.module('APP', ['controllers']);
angular.module('controllers',[])
.controller('testController', function ($scope) {
$scope.click = function(msg) {
console.log('ctrl_doNgClick: ng-click: msg: '+msg);
};
$scope.simple = [
{
test: "<a href='javascript:void(0);' ng-click='dir_ctrl_click(\"blah1,blah1\")'>Test 1</a>"
},
{
test: "<a href='javascript:void(0);' ng-click='doClick(\"blah2,blah2\")'>Test 2</a>"
},
{
test: "<a href='javascript:void(0);' ng-click='doClick(\"blah3,blah3\")'>Test 3</a>"
}
];
});
APP.directive('htable',function($compile) {
var directive = {};
directive.restrict = 'A';
directive.scope = {
data : '=',
click : '&'
};
directive.controller = function($scope) {
$scope.dir_ctrl_click = function( msg ) {
console.log('controller: dir_ctrl_click: click via the directive controller method');
$scope.click()(msg);
};
};
directive.link = function(scope,element,attrs) {
var container = $(element);
scope.doClick = function(msg) {
console.log('link: doClick: click via the directive link method');
scope.click()(msg);
};
var linkHtmlRenderer = function (instance, td, row, col, prop, value, cellProperties) {
//-- here is the magic that works
//-- the method, in ng-click, must either be defined here in the link method or in the controller method (the example data contains both)
var el = angular.element(td);
el.html($compile(value)(scope));
return el;
};
var settings = {
data: scope.data,
readOnly: true,
colHeaders: ['Link'],
columns: [
{
data : "test",
renderer : linkHtmlRenderer,
readyOnly : true
}
]
};
var hot = new Handsontable( container[0], settings );
// hot.render();
};//--end of link function
return directive;
});
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="http://handsontable.com/dist/handsontable.full.css">
</head>
<body>
<div ng-app="APP">
<div ng-controller="testController">
<div htable data="simple" click="click"></div>
</div
</div>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.24/angular.min.js"></script>
<script src="http://handsontable.com/dist/handsontable.full.js"></script>
</body>
</html>

Mithril with angularjs

I am a newbie to Mithril JS framework and trying to integrate Mitril view with angularJS. Has anyone tried this before?
I want to check how can we bind the angular controller methods to click events of elements created in Mitril.
I got this working by having this code
var e = document.getElementById('elementId');
var scope = angular.element(e).scope();
m("a[href='javascript:;']", {
onclick : scope.someMethod
}, "Test");
But I am not sure if this is right way to do this.
I'd say that is not idiomatic angular code.
A more idiomatic way might be to use a directive on the Angular side, and pass in an event dispatcher controller to the view on the mithril side:
//mithril code
var testWidget = function(ctrl) {
return m("a[href='javascript:;']", {onclick: ctrl.onclick}, "Test")
}
//angular code
angular.module("foo").directive("testWidget", function() {
return {
restrict: "E",
link: function($scope, element, attrs) {
var template = testWidget({
onclick: function() {
$scope.$apply(function() {
$scope.$eval(attrs.onclick)
})
}
})
m.render(element, template)
}
}
})
angular.module("foo").controller("MyCtrl", function() {
this.doStuff = function() {
console.log("called doStuff")
}
})
<div ng-controller="MyCtrl as c">
<test-widget onclick="c.doStuff()"></test-widget>
</div>
// Code goes here
(function() {
'use strict';
angular
.module('app', [])
.directive('testMithrilScope', testMithrilScope)
.controller('MyCtrl', MyCtrl);
var testMithrilWidgetScope = function(ctrl) {
return m("a[href='javascript:;']", {onclick: ctrl.directiveclick}, ctrl.text)
}
var htmllinks = [
{text: "Link 1 "},
{text: "Link 2 "},
{text: "Link 3 "},
{text: "Link 4 "},
{text: "Link 5 "},
{text: "Link 6 "}
];
function testMithrilScope() {
return {
restrict: "E",
scope : {
htmlclick: '&'
},
link: function($scope, element, attrs) {
function makeList1() {
return m('ul', htmllinks.map(function(a, index){
return m('li', testMithrilWidgetScope({
directiveclick : function() {
var data = {
arg1: a.text
}
$scope.htmlclick(data);
},
text : a.text
})
);
}));
}
var template1 = makeList1();
m.render(element[0], template1)
}
}
}
function MyCtrl() {
this.doStuff = function(text) {
console.log("You clicked: " + text)
}
}
})();
<!DOCTYPE html>
<html>
<head>
<script data-require="angularjs#1.5.8" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<script data-require="mithril#0.2.4" data-semver="0.2.4" src="https://cdn.jsdelivr.net/mithril/0.2.4/mithril.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="app">
<div ng-controller="MyCtrl as ctrl">
<test-mithril-scope htmlclick="ctrl.doStuff(arg1)"></test-mithril-scope>
</div>
</body>
</html>

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

Editing model property inside ngRepeat, error undefined

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

Resources