ng-click is not working when passing function into directive - angularjs

I try to store menu information in an array(menu_entries in the example) and render them with a directive(myMenu), but the functions stored in the array seem not to work with ng-click.
Here is the example: http://jsfiddle.net/5CaQx/
menu1 and menu2 are not working, but menu3 works.
JS code:
var my_app;
my_app = angular.module('myApp', []);
my_app.controller('myPageCtrl', [
'$scope', function($scope) {
$scope.menu_entries = [
{
name: 'menu1',
onclick: $scope.onMenu1Click
}, {
name: 'menu2',
onclick: $scope.onMenu2Click
}
];
$scope.say_something = "";
$scope.onMenu1Click = function() {
return $scope.say_something = "lalala";
};
$scope.onMenu2Click = function() {
return $scope.say_something = "wawawa";
};
return $scope.onMenu3Click = function() {
return $scope.say_something = "rarara";
};
}
]);
my_app.directive("myMenu", [
"$compile", function($compile) {
return {
restrict: 'E',
replace: true,
scope: {
menue: '='
},
link: function(scope, elem, attrs) {
elem.html('<div ng-repeat="me in menue"><li><div class="menu-btn" ng-click="me.onclick()"><div class="menu-text">{{me.name}}</div></div></li></div>');
return $compile(elem.contents())(scope);
}
};
}
]);
HTML:
<!DOCTYPE html>
<html>
<head>
<link href="../css/app.css" rel="stylesheet" />
<script src="../js/angular.min.js"></script>
<script src="../js/app.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="myPageCtrl">
<p>
{{say_something}}
</p>
<ul>
<my_menu menue="menu_entries"></my_menu>
<li>
<div class="menu-btn" ng-click="onMenu3Click()">
<div class="menu-text">
menu3
</div>
</div>
</li>
</ul>
</div>
</body>
</html>

Try this:
$scope.onMenu1Click = function() {
return $scope.say_something = "lalala";
};
$scope.onMenu2Click = function() {
return $scope.say_something = "wawawa";
};
//Move this code after the creating $scope.onMenu1Click and $scope.onMenu2Click
$scope.menu_entries = [
{
name: 'menu1',
onclick: $scope.onMenu1Click //onMenu1Click instead of menu1Click
}, {
name: 'menu2',
onclick: $scope.onMenu2Click //onMenu2Click instead of menu2Click
}
];
Update fiddle

Related

Webix + angularjs datatable from controller

I have the problem, because datatable is empty, data doesn't binding.
html:
<div id="usersFormDiv" ng-controller="adminController">
<div webix-ui="usersGrid"></div>
</div>
controller
$scope.usersGrid ={
view:"datatable",
id:"usersGridWebix",
autoConfig:true,
select:"row",
data : [
{ id:1,"lp":1, "name":1994,"surname":678790,"email":"xxx#xp.pl","organ":"ogran","location":"Lokalizacja 1, Lokalizacja 2"}
],
columns:[
{ header:"Lp", id:"lp", width:50},
{ header:"ImiÄ™", id:"name", width:50},
{ header:"Nazwisko", id:"surname", width:100},
{ header:"Email", id:"email", width:150},
{ header:"Organ", id:"organ", width:100},
{ header:"Lokalizacja", id:"location", width:150}
]
// url: "./app/model/users.json"
};
with webix-ui attribute in div use webix-data="data"
also put
$scope.data = { id:1,"lp":1, "name":1994,"surname":678790,"email":"xxx#xp.pl","organ":"ogran","location":"Lokalizacja 1, Lokalizacja 2"}
I have the same problem, i fixed using this way, for more details refer:-
http://docs.webix.com/desktop__angular.html
You can define the data table structure either on html or within controller as well.
if (window.angular)
(function() {
function id_helper($element) {
//we need uniq id as reference
var id = $element.attr("id");
if (!id) {
id = webix.uid();
$element.attr("id", id);
}
return id;
}
function locate_view_id($element) {
if (typeof $element.attr("webix-ui") != "undefined")
return $element.attr("id");
return locate_view_id($element.parent());
}
//creates webix ui components
angular.module("webix", [])
.directive('webixUi', ["$parse", function($parse) {
return {
restrict: 'A',
scope: false,
link: function($scope, $element, $attrs, $controller) {
var dataname = $attrs["webixUi"];
var callback = $attrs["webixReady"];
var watch = $attrs["webixWatch"];
var wxRoot = null;
var id = id_helper($element);
$element.ready(function() {
if (wxRoot) return;
if (callback)
callback = $parse(callback);
//destruct components
$element.bind('$destroy', function() {
if (wxRoot && !wxRoot.$destructed && wxRoot.destructor)
wxRoot.destructor();
});
//ensure that ui is destroyed on scope destruction
$scope.$on('$destroy', function() {
if (wxRoot && !wxRoot.$destructed && wxRoot.destructor)
wxRoot.destructor();
});
//webix-ui attribute has some value - will try to use it as configuration
if (dataname) {
//configuration
var watcher = function(data) {
if (wxRoot) wxRoot.destructor();
if ($scope[dataname]) {
var config = webix.copy($scope[dataname]);
config.$scope = $scope;
$element[0].innerHTML = "";
wxRoot = webix.ui(config, $element[0]);
if (callback)
callback($scope, {
root: wxRoot
});
}
};
if (watch !== "false")
$scope.$watch(dataname, watcher);
watcher();
} else {
//if webix-ui is empty - init inner content as webix markup
if (!$attrs["view"])
$element.attr("view", "rows");
var ui = webix.markup;
var tmp_a = ui.attribute;
ui.attribute = "";
//FIXME - memory leaking, need to detect the moment of dom element removing and destroy UI
if (typeof $attrs["webixRefresh"] != "undefined")
wxRoot = ui.init($element[0], $element[0], $scope);
else
wxRoot = ui.init($element[0], null, $scope);
ui.attribute = tmp_a;
if (callback)
callback($scope, {
root: wxRoot
});
}
//size of ui
$scope.$watch(function() {
return $element[0].offsetWidth + "." + $element[0].offsetHeight;
}, function() {
if (wxRoot) wxRoot.adjust();
});
});
}
};
}])
.directive('webixShow', ["$parse", function($parse) {
return {
restrict: 'A',
scope: false,
link: function($scope, $element, $attrs, $controller) {
var attr = $parse($attrs["webixShow"]);
var id = id_helper($element);
if (!attr($scope))
$element.attr("hidden", "true");
$scope.$watch($attrs["webixShow"], function() {
var view = webix.$$(id);
if (view) {
if (attr($scope)) {
webix.$$(id).show();
$element[0].removeAttribute("hidden");
} else
webix.$$(id).hide();
}
});
}
};
}])
.directive('webixEvent', ["$parse", function($parse) {
var wrap_helper = function($scope, view, eventobj) {
var ev = eventobj.split("=");
var action = $parse(ev[1]);
var name = ev[0].trim();
view.attachEvent(name, function() {
return action($scope, {
id: arguments[0],
details: arguments
});
});
};
return {
restrict: 'A',
scope: false,
link: function($scope, $element, $attrs, $controller) {
var events = $attrs["webixEvent"].split(";");
var id = id_helper($element);
setTimeout(function() {
var first = $element[0].firstChild;
if (first && first.nodeType == 1)
id = first.getAttribute("view_id") || id;
var view = webix.$$(id);
for (var i = 0; i < events.length; i++) {
wrap_helper($scope, view, events[i]);
}
});
}
};
}])
.directive('webixElements', ["$parse", function($parse) {
return {
restrict: 'A',
scope: false,
link: function($scope, $element, $attrs, $controller) {
var data = $attrs["webixElements"];
var id = id_helper($element);
if ($scope.$watchCollection)
$scope.$watchCollection(data, function(collection) {
setTimeout(function() {
var view = webix.$$(id);
if (view) {
view.define("elements", collection);
view.refresh();
}
}, 1);
});
}
};
}])
.directive('webixData', ["$parse", function($parse) {
return {
restrict: 'A',
scope: false,
link: function($scope, $element, $attrs, $controller) {
var data = $attrs["webixData"];
var id = id_helper($element);
if ($scope.$watchCollection)
$scope.$watchCollection(data, function(collection) {
if (collection) {
setTimeout(function() {
loadData($element, id, collection, 0);
}, 1);
}
});
}
};
}]);
function loadData($element, id, collection, num) {
if (num > 10) return;
var first = $element[0].firstChild;
if (first && first.nodeType == 1)
id = first.getAttribute("view_id") || id;
var view = webix.$$(id);
if (view) {
if (view.options_setter) {
view.define("options", collection);
view.refresh();
} else {
if (view.clearAll)
view.clearAll();
view.parse(collection);
}
} else {
webix.delay(loadData, this, [$element, id, collection], 100, num + 1);
}
}
})();
{
"student": [ {
"firstName": "Ajinkya", "lastName": "Chanshetty", "contact": 9960282703, "email": "aajinkya#hotmail.com"
}
,
{
"firstName": "Sandip", "lastName": "Pal", "contact": 9960282703, "email": "sandip#hotmail.com"
}
,
{
"firstName": "Neha", "lastName": "Sathawane", "contact": 99608882703, "email": "neha#hotmail.com"
}
,
{
"firstName": "Gopal", "lastName": "Thakur", "contact": 9960000703, "email": "gopal#hotmail.com"
}
]
}
<!doctype html>
<html lang="en" ng-app="webixApp">
<head>
<meta charset="utf-8">
<title>Webix - Angular : Layouts</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.webix.com/edge/webix.css">
<script type="text/javascript" src="https://cdn.webix.com/edge/webix.js"></script>
<script type="text/javascript" src="index.js"></script>
<script type="text/javascript">
var app = angular.module('webixApp', ["webix"]);
app.controller('jsonCtrl', function($scope, $http) {
$http.get('data.json').then(function(response) {
$scope.content = response.data.student
})
})
app.controller('extCtrl', function($scope, $http) {
$scope.myTable = {
view: "datatable",
columns: [{
id: "name",
header: "Name",
css: "rank",
width: 150
},
{
id: "username",
header: "UserName",
width: 150,
sort: "server"
},
{
id: "email",
header: "Email ID",
width: 200,
sort: "server"
},
{
id: "website",
header: "Website",
width: 150
}
],
autoheight: true,
autowidth: true,
url: "https://jsonplaceholder.typicode.com/users"
}
})
</script>
</head>
<body>
<div webix-ui type="space">
<div height="35">Welcome to Angular Webix App </div>
<div view="cols" type="wide" margin="10">
<div width="200">
<input type="text" placeholder="Type something here" ng-model="app"> Hello {{app}}!
</div>
<div view="resizer"></div>
<div view="tabview" ng-controller="jsonCtrl">
<div header="JSON Data Fetch Example">
<div ng-controller="jsonCtrl">
<div webix-ui view="datatable" webix-data="content" autoheight="true" select="row" fillspace="true">
<div autowidth="true" view="column" id="firstName" sort="int" css="rating" scrollY="true">First Name</div>
<div view="column" id="lastName" sort="int">Last Name</div>
<div view="column" id="contact" sort="int">Contact</div>
<div view="column" id="email" sort="string" width="200">E mail</div>
</div>
</div>
</div>
</div>
<div view="resizer"></div>
<div view="tabview" ng-controller="extCtrl">
<div header="External Source Data Table">
<div webix-ui="myTable"></div>
</div>
</div>
</div>
</div>
</body>
</html>

close multiselect dropdown directive on clicking outside dropdown

I have tried codes from this links
AngularJS dropdown directive hide when clicking outside,
http://plnkr.co/edit/ybYmHtFavHnN1oD8vsuw?p=preview,
closing dropdown single or multiselect when clicking outside.
But did not help.
<html>
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css">
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
'use strict';
var app = angular.module('myApp', ['app.directives']);
app.controller('AppCtrl', function($scope){
$scope.roles = [
{"id": 1, "name": "Manager", "assignable": true},
{"id": 2, "name": "Developer", "assignable": true},
{"id": 3, "name": "Reporter", "assignable": true}
];
$scope.member = {roles: []};
$scope.selected_items = [];
});
var app_directives = angular.module('app.directives', []);
app_directives.directive('dropdownMultiselect', function($document){
return {
restrict: 'AE',
scope:{
model: '=',
options: '=',
pre_selected: '=preSelected'
},
template: "<div class='btn-group' data-ng-class='{open: open}'>"+
"<button class='btn btn-small'>Select</button>"+
"<button class='btn btn-small dropdown-toggle' data-ng-click='open=!open;openDropdown()'><span class='caret'></span></button>"+
"<ul class='dropdown-menu' aria-labelledby='dropdownMenu'>" +
"<li><a data-ng-click='selectAll()'><i class='icon-ok-sign'></i> Check All</a></li>" +
"<li><a data-ng-click='deselectAll();'><i class='icon-remove-sign'></i> Uncheck All</a></li>" +
"<li class='divider'></li>" +
"<li data-ng-repeat='option in options'> <a data-ng-click='setSelectedItem()'>{{option.name}}<span data-ng-class='isChecked(option.id)'></span></a></li>" +
"</ul>" +
"</div>" ,
link: function postLink(scope, element, attrs)
{
console.log("in on click");
var onClick = function (event) {
var isChild = element[0].contains(event.target);
var isSelf = element[0] == event.target;
var isInside = isChild || isSelf;
if (!isInside) {
scope.$apply(attrs.dropdownMultiselect)
}
}
scope.$watch(attrs.isActive, function(newValue, oldValue) {
if (newValue !== oldValue && newValue == true) {
$document.bind('click', onClick);
}
else if (newValue !== oldValue && newValue == false) {
$document.unbind('click', onClick);
}
});
},
controller: function($scope){
$scope.openDropdown = function(){
$scope.selected_items = [];
for(var i=0; i<$scope.pre_selected.length; i++){ $scope.selected_items.push($scope.pre_selected[i].id);
}
};
$scope.selectAll = function () {
$scope.model = _.pluck($scope.options, 'id');
console.log($scope.model);
};
$scope.deselectAll = function() {
$scope.model=[];
console.log($scope.model);
};
$scope.setSelectedItem = function(){
var id = this.option.id;
if (_.contains($scope.model, id)) {
$scope.model = _.without($scope.model, id);
} else {
$scope.model.push(id);
}
console.log($scope.model);
return false;
};
$scope.isChecked = function (id) {
if (_.contains($scope.model, id)) {
return 'icon-ok pull-right';
}
return false;
};
}
}
});
</script>
<body>
<div ng-app="myApp" ng-controller="AppCtrl">
<dropdown-multiselect pre-selected="member.roles" model="selected_items" options="roles" is-active="isDropdownOpen()"></dropdown-multiselect>
<pre>selected roles = {{selected_items | json}}</pre>
</div>
</body>
</html>
Please suggest changes for this.
I solved it finally using below code.
<html>
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css">
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
'use strict';
var app = angular.module('myApp', ['app.directives']);
app.controller('AppCtrl', function($scope){
$scope.roles = [
{"id": 1, "name": "Manager", "assignable": true},
{"id": 2, "name": "Developer", "assignable": true},
{"id": 3, "name": "Reporter", "assignable": true}
];
$scope.member = {roles: []};
$scope.selected_items = [];
});
var app_directives = angular.module('app.directives', []);
app_directives.directive('dropdownMultiselect', function($document){
return {
restrict: 'AE',
scope:{
model: '=',
options: '=',
pre_selected: '=preSelected'
},
template: "<div class='btn-group' data-ng-class='{open: open}'>"+
"<button class='btn btn-small'>Select</button>"+
"<button class='btn btn-small dropdown-toggle' data-ng-click='open=!open;openDropdown()' ><span class='caret'></span></button>"+
"<ul class='dropdown-menu' aria-labelledby='dropdownMenu' ng-show='open'>" +
"<li><a data-ng-click='selectAll()'><i class='icon-ok-sign'></i> Check All</a></li>" +
"<li><a data-ng-click='deselectAll();'><i class='icon-remove-sign'></i> Uncheck All</a></li>" +
"<li class='divider'></li>" +
"<li data-ng-repeat='option in options'> <a data-ng-click='setSelectedItem()'>{{option.name}}<span data-ng-class='isChecked(option.id)'></span></a></li>" +
"</ul>" +
"</div>" ,
link: function(scope, elem, attr, ctrl)
{
//console.log("in click");
elem.bind('click', function(e) {
console.log("in click");
// this part keeps it from firing the click on the document.
e.stopPropagation();
});
$document.bind('click', function() {
// magic here.
console.log("click in document");
scope.$apply(attr.dropdownMulti);
/*var myElement= document.getElementsByClassName('btn btn-small dropdown-toggle');
angular.element(myElement).triggerHandler('click');*/
})
},
controller: function($scope){
$scope.openDropdown = function(){
$scope.selected_items = [];
for(var i=0; i<$scope.pre_selected.length; i++){
$scope.selected_items.push($scope.pre_selected[i].id);
}
};
$scope.selectAll = function () {
$scope.model = _.pluck($scope.options, 'id');
console.log($scope.model);
};
$scope.deselectAll = function() {
$scope.model=[];
console.log($scope.model);
};
$scope.setSelectedItem = function(){
var id = this.option.id;
if (_.contains($scope.model, id)) {
$scope.model = _.without($scope.model, id);
} else {
$scope.model.push(id);
}
console.log($scope.model);
return false;
};
$scope.isChecked = function (id) {
if (_.contains($scope.model, id)) {
return 'icon-ok pull-right';
}
return false;
};
}
}
});
</script>
<body>
<div ng-app="myApp" ng-controller="AppCtrl">
<dropdown-multiselect pre-selected="member.roles" model="selected_items" options="roles" is-active="isDropdownOpen()" dropdown-multi="open=false"></dropdown-multiselect>
<pre>selected roles = {{selected_items | json}}</pre>
</div>
</body>
</html>

AngularJS template in directive not display text

I try to create directive in angularjs:
JavaScript and HTML code:
'use strict';
var app = angular.module('myApp', ['app.directives']);
app.controller('AppCtrl', function($scope){
$scope.roles = [
{"id": 1, "name": "Michael"},
{"id": 2, "name": "Max"},
{"id": 3, "name": "John"}
];
$scope.dummyData = "Dummy!!!";
$scope.member = {roles: []};
$scope.selected_items = [];
});
var app_directives = angular.module('app.directives', []);
app_directives.directive('dropdownMultiselect', function(){
return {
restrict: 'E',
scope:{
testElem: '=',
model: '=',
options: '=',
pre_selected: '=preSelected'
},
template: "<div class='btn-group' data-ng-class='{open: open}'>"+
"<button class='btn btn-small'>{{testElem}}</button>"+
"<button class='btn btn-small dropdown-toggle' data-ng-click='open=!open;openDropdown()'><span class='caret'></span></button>"+
"<ul class='dropdown-menu' aria-labelledby='dropdownMenu'>" +
"<li><a data-ng-click='selectAll()'><i class='icon-ok-sign'></i> Check All</a></li>" +
"<li><a data-ng-click='deselectAll();'><i class='icon-remove-sign'></i> Uncheck All</a></li>" +
"<li class='divider'></li>" +
"<li data-ng-repeat='option in options'> <a data-ng-click='setSelectedItem()'>{{option.name}}<span data-ng-class='isChecked(option.id)'></span></a></li>" +
"</ul>" +
"</div>" ,
controller: function($scope){
$scope.openDropdown = function(){
$scope.selected_items = [];
for(var i=0; i<$scope.pre_selected.length; i++){ $scope.selected_items.push($scope.pre_selected[i].id);
}
};
$scope.selectAll = function () {
$scope.model = _.pluck($scope.options, 'id');
console.log($scope.model);
};
$scope.deselectAll = function() {
$scope.model=[];
console.log($scope.model);
};
$scope.setSelectedItem = function(){
var id = this.option.id;
if (_.contains($scope.model, id)) {
$scope.model = _.without($scope.model, id);
} else {
$scope.model.push(id);
}
console.log($scope.model);
return false;
};
$scope.isChecked = function (id) {
if (_.contains($scope.model, id)) {
return 'icon-ok pull-right';
}
return false;
};
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<div ng-app="myApp" ng-controller="AppCtrl">
<dropdown-multiselect pre-selected="member.roles" model="selected_items" testElem = "dummyData" options="roles"></dropdown-multiselect>
In template in the directive definition I have this row:
<button class='btn btn-small'>{{$scope.testElem}}</button>
As you can see with help of this row I try to display text inside $scope.testElem variable.
But the text does not appears.What I am missing? Why I don't see text on the declared button?

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>

Resources