I have the following shuttle boxes directive:
<shuttle-boxes ng-options="item for item in itemList" ng-model="myModel" />
My template looks like this:
template: '<div class="shuttle-boxes">' +
'<select multiple="multiple" class="shuttle-boxes-left"></select>' +
'<button class="shuttle-boxes-btn" type="button"><i class="icon icon-arrow-right"></i></button>' +
'<button class="shuttle-boxes-btn" type="button"><i class="icon icon-arrow-left"></i></button>' +
'<select multiple="multiple" class="shuttle-boxes-right"></select>' +
'</div>'
What I want to do is take the ng-options repeater from <shuttle-boxes> and use it to populate <select class="shuttle-boxes-left">.
The way I am trying to do it that isn't working is simply copying over the ng-options attribute to the select list like so:
var availableList = cElement.find('.shuttle-boxes-left'),
repeater = cAttrs.ngOptions;
availableList.attr('ng-options', repeater);
Here is the fiddle: http://jsfiddle.net/dkrotts/tHTAY/1/
What am I doing wrong?
I suggest you only pass the itemList to the directive (and myModel) and put the ng-options inside your template:
<shuttle-boxes items="itemList" ng-model="myModel"></shuttle-boxes>
Directive:
myApp.directive('shuttleBoxes', function($timeout) {
return {
restrict: 'E',
scope: { items: '=', ngModel: '='},
template: '<div class="shuttle-boxes">' +
'<select multiple="multiple" class="shuttle-boxes-left"
ng-options="item for item in items" ng-model="ngModel"></select>' +
'<button class="shuttle-boxes-btn" type="button">' +
'<i class="icon icon-arrow-right"></i></button>' +
'<button class="shuttle-boxes-btn" type="button">' +
'<i class="icon icon-arrow-left"></i></button>' +
'<select multiple="multiple" class="shuttle-boxes-right"></select>' +
'</div>',
replace: true
}
});
Fiddle.
Related
I am using ng-admin and I created a custom directive(following this example http://plnkr.co/edit/rYC3nd7undqJz2mr8Old) to upload a excel sheet, when I upload the file, I get the following TypeError: Cannot set property 'columnDefs' of undefined, my code
Module:
var myApp = angular.module('myApp', ['ng- admin','ngStorage','chart.js','ui.grid']);
Controller
myApp.controller('MainCtrl', ['$scope', function ($scope) {
var vm = this;
vm.gridOptions = {};
vm.reset = reset;
function reset() {
vm.gridOptions.data = [];
vm.gridOptions.columnDefs = [];
}
}]);
Directive:
myApp.directive('fileread', ['$http', function ($http) {
return {
restrict: 'E',
scope: {
opts: '='
},
link: function ($scope, $elm, $attrs) {
$elm.on('change', function (changeEvent) {
var reader = new FileReader();
reader.onload = function (evt) {
$scope.$apply(function () {
var data = evt.target.result;
var workbook = XLSX.read(data, {type: 'binary'});
var headerNames = XLSX.utils.sheet_to_json( workbook.Sheets[workbook.SheetNames[0]], { header: 1 })[0];
var datasheet = XLSX.utils.sheet_to_json( workbook.Sheets[workbook.SheetNames[0]]);
console.log(datasheet);
$scope.opts.columnDefs = [];
headerNames.forEach(function (h) {
$scope.opts.columnDefs.push({ field: h });
});
$scope.opts.data = datasheet;
var json_string = JSON.stringify($scope.opts.data);
console.log(json_string);
$elm.val(null);
});
};
reader.readAsBinaryString(changeEvent.target.files[0]);
});
}, template:
'<div ng-controller="MainCtrl as vm">'+
'<button type="button" class="btn btn-success"
ng-click="vm.reset()">Reset Grid</button>'+
'<br />'+
'<br />'+
'<div id="grid1" ui-grid="vm.gridOptions" class="grid">'+
'<div class="grid-msg-overlay"
ng-show="!vm.gridOptions.data.length">'+
'<div class="msg">'+
'<div class="center">'+
'<span class="muted">Select Spreadsheet File</span>'+
'<br />'+
'<input type="file" accept=".xls,.xlsx,.ods" fileread="" opts="vm.gridOptions" multiple="false" />'+
'</div>'+
'</div>'+
'</div>'+
'</div>'+
'</div>'
}
}]);
Template from I am calling the directive
var customDashboardTemplate =
'<div class="row dashboard-starter"></div>' +
'<question-stats></question-stats>'+
'<div ng-controller="MainCtrl" >'+
'<fileread>'+
'<button type="button" class="btn btn-success" ng-click="reset()">Reset Grid</button>'+
'<br />'+
'<br />'+
'<div id="grid1" ui-grid="gridOptions" class="grid">'+
'<div class="grid-msg-overlay" ng-show="!gridOptions.data.length">'+
'<div class="msg">'+
'<div class="center">'+
'<span class="muted">Select Spreadsheet File</span>'+
'<br />'+
'<input type="file" accept=".xls,.xlsx,.ods" fileread="" opts="gridOptions" multiple="false" />'+
'</div>'+
'</div>'+
'</div>'+
'</div>'+
'</fileread>'+
'</div>'+
'<div class="row dashboard-content">' +
'<div class="col-md-6">' +
'<div class="panel panel-green">' +
'<ma-dashboard-panel collection="dashboardController.collections.last_users" entries="dashboardController.entries.last_users" datastore="dashboardController.datastore"></ma-dashboard-panel>' +
'</div>' +
'</div>'+
'<div class="col-md-6">' +
'<div class="panel panel-yellow">' +
'<ma-dashboard-panel collection="dashboardController.collections.last_tips" entries="dashboardController.entries.last_tips" datastore="dashboardController.datastore"></ma-dashboard-panel>' +
'</div>' +
'</div>'+
'</div>'+
'</div>'
;
It may just be the space inside the template separating the ng-click calling the reset function:
(ng- click)
With that space you are not calling the reset therefore not actually assigning the defaults?
Edit:
You are calling the directive within the directive within the directive's template. This seems fishy. Can we see the HTML implementation of where you are calling the directive?
Sorry If this question has been asked before, but my issue is bit different and hope someone can help me out.
1) I have a Directive which has many buttons. I want to call a function on this buttons and inside a directive. But I don't know how.
// Directive for the login header to avoid the duplication of the code
angular.module('App').directive('mainHeader',function(){
return{
restrict: 'AE',
template:'<h1 class="logo"> My App </h1>'+
'<button class="btn btn-primary">New User</button>'+
'<button class="btn btn-primary">New Product</button>'+
'<span class="dropdown" on-toggle="toggled(open)">'+
'<a href class="dropdown-toggle">'+
'<img class="userProfile" src="" alt="User Profile">'+
'<b class="caret"></b>'+
'</a>'+
// Here on my profile ????
'<ul class="dropdown-menu pull-right">'+
'<li> My Profile </a> </li>'+
'<li class="divider"></li>'+
// Here on my logout ??????
// This does not work
'<li> <a href="" ng-click="logOut()"> Sign Out </li>'+
'</ul>'+
'</span>'
}
});
My controller
(function() {
var logOutController = function($scope){
$scope.logOut = function(){
// Want to call this
}
logOutController .$inject = ['$scope'];
angular.module('App').controller('logOutController ',logOutController );
}());
And my view will be only one line
<div main-header></div>
I don't know how to do this
Update 1: -
Please have a look at the Plunker
http://plnkr.co/edit/YONVyVvNm4pQGFMU6SkG?p=preview.
You will just need to add an isolate scope to your directive:
// Directive for the login header to avoid the duplication of the code
angular.module('App').directive('mainHeader', function () {
return {
restrict: 'AE',
template: '<h1 class="logo"> My App </h1>' +
'<button class="btn btn-primary">New User</button>' +
'<button class="btn btn-primary">New Product</button>' +
'<span class="dropdown" on-toggle="toggled(open)">' +
'<a href class="dropdown-toggle">' +
'<img class="userProfile" src="" alt="User Profile">' +
'<b class="caret"></b>' +
'</a>' +
// Here on my profile ????
'<ul class="dropdown-menu pull-right">' +
'<li> My Profile </a> </li>' +
'<li class="divider"></li>' +
// Here on my logout ??????
// This does not work
'<li> <a href="" ng-click="logOut()"> Sign Out </li>' +
'</ul>' +
'</span>',
scope: {
'logOut': '&onLogOut' //<- this ties your directive's logOut function to an attr on the HTML tag
}
}
});
Then you just modify your HTML to:
<div main-header on-log-out="logOut()"></div>
Plunker Example
i have a custom form directive which creates an ng-form inside it. i want to use this form in the transcluded elements, to disable buttons etc, but its not working.. PLUNKER LINK
app.directive("myform", function(){
var templateFn = function(tElement, tAttrs){
var html = '<div ng-form="' + tAttrs.name + '">'
html += '<div ng-transclude=""></div>'
html += '</div>'
return html;
};
return {
restrict: 'E',
template: templateFn,
scope: {list: '='},
transclude: true
}
});
this is how i am using it
<myform name="example">
<input type="text" required ng-model="name2"/>
<button ng-disabled="example.$invalid"> button </button>
</myform>
do i need to compile the template during link?? i thought as the template is used and the linking is happening latter, the $compile would be taking care of that..
the generated html is as expected, except that button is not disabled
<myform name="example" class="ng-isolate-scope">
<div ng-form="example" class="ng-pristine ng-invalid ng-invalid-required">
<div ng-transclude="">
<input type="text" required="" ng-model="name2" class="ng-scope ng-pristine ng-invalid ng-invalid-required">
<button ng-disabled="example.$invalid" class="ng-scope"> button </button>
</div>
</div>
</myform>
When you transclude the contents, have it link to the same isolated scope as ng-form (instead of the parent scope which is the default):
app.directive("myform", function(){
var templateFn = function(tElement, tAttrs){
var html = '<div ng-form="' + tAttrs.name + '">'
html += '<div></div>'
html += '</div>'
return html;
};
return {
restrict: 'E',
template: templateFn,
scope: {list: '='},
transclude: true,
link:function(scope, element, attr, ctrl, transcludeFn) {
var e = element.find('div');
transcludeFn(scope, function(clone) {
angular.element(e[1]).append(clone);
});
}
}
});
Demo Plunker
I'm using AngularJS and i'm writing my own directive. I want to use conditional logic in my custom directive. The problem is caused in the template part. Here's a piece of my code:
angular.module('myDirectives').directive('widget', function() {
return {
replace: true,
restrict: 'E',
template:
'<div class="widget">' +
'<div class="panel panel-default">' +
'<div class="panel-heading">' +
'<a href="" class="btn btn-default" ng-click="isCollapsed = !isCollapsed">' +
'<i class="fa" ng-class=" { 'fa-angle-up': !isCollapsed, 'fa-angle-down': isCollapsed } "></i>' +
'</a>' +
'</div>' +
'<div class="panel-body" collapse="isCollapsed">' +
'<p>Panel Content</p>' +
'</div>' +
'</div>' +
'</div>',
transclude: true
}
});
This line throws an error.
'<i class="fa" ng-class=" { 'fa-angle-up': !isCollapsed, 'fa-angle-down': isCollapsed } "></i>'
The '' around fa-angle-up and fa-angle-down are causing this.
There's probably a very simple workaround, but I haven't figured it out yet. So my question for you guys; Is there any other way to write this line?
You have to escape the apostrophes
'<i class="fa" ng-class=" { \'fa-angle-up\': !isCollapsed, \'fa-angle-down\': isCollapsed } "></i>'
I want the user to be able to toggle one option. If they toggle to another option within a section, it will toggle the other previously made selection to off. A user will also be able to deselect their selection (i.e).
Steps:-
Tap button 1(button 1 turns "off" to "on")
Tap button 1 again(it should turn "On" to "Off")
I used the following code
app.directive('kmItoggleRadio', function() {
return{
restrict:'E',
compile: function(element,attrs)
{
var leftTitle='';
if(angular.isUndefined(attrs.kmLeftTitle)) {
leftTitle='';
}
else {
leftTitle=attrs.kmLeftTitle;
}
var rightTitle='';
if(angular.isUndefined(attrs.kmRightTitle)) {
rightTitle='';
}
else {
rightTitle=" "+attrs.kmRightTitle ;
}
var show='false';
if(angular.isUndefined(attrs.kmShow)) {
show="true";
}
else {
show=attrs.kmShow;
}
var htmlText='<div><div ng-switch on="format">'+
'<div ng-switch-when="kmForm">'+
'<div ng-show='+show+'>'+
'<ul class="list">'+
'<li class="item item-toggle">'+
''+leftTitle+''+
'<label class="toggle toggle-positive">'+
'<input type="radio" value="'+attrs.kmValue+'" ng-model="'+attrs.kmModel+'" >'+
'<div class="track">'+
'<div class="handle"></div>'+
'</div>'+
'</label>'+
'</ul>'+
'</div>'+
'</div>'+
'<div ng-switch-when="kmPreview">'+
'<div ng-show='+show+'>'+
'<ul class="list">'+
'<li class="item item-toggle">'+
''+leftTitle+''+
'<label class="toggle toggle-positive">'+
'<input type="checkbox" disabled="true" value="'+attrs.kmValue+'" ng-model="'+attrs.kmModel+'">'+
'<div class="track">'+
'<div class="handle"></div>'+
'</div>'+
'</label>'+
'</ul>'+
'</div>'+
'</div>'+
'</div></div>';
element.replaceWith(htmlText);
}
}
})
In HTML
<km-itoggle-radio km-model="a.c" km-value="d" km-left-title="Dhoni"></km-itoggle-radio>
<km-itoggle-radio km-model="a.c" km-value="s" km-left-title="Kohli"></km-itoggle-radio>
I want to know how to make the radio button toggle on/off by tapping the button again (with out tapping the other button in same group).
Why not use the built in ion-toggle?
Ionic toggle Codepen Demo
<ion-toggle ng-repeat="item in settingsList"
ng-model="item.checked"
ng-checked="item.checked">
{{ item.text }}
</ion-toggle>