How to make the ionic radio toggle on/off? - angularjs

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>

Related

Calling function inside a directive in Angular

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

angularjs ng-form inside directive

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

Conditional logic in ng-class in directives template

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>'

How to get the name of model passed into the function in AngularJS?

I have a scenario where i need to know the value and name of model passed in to the function.
I tried the following
$scope.rad='fff';
app.directive('kmRadio', function() {
return{
restrict:'E',
compile: function(element,attrs)
{
var model = {l:''};
model.l = attrs.kmModel;
var str1="n in ";
var str2=attrs.kmOption;
var repeat=str1.concat(str2);
var htmlText='<div><div ng-switch on="format">'+
'<div ng-switch-when="kmForm">'+
'<div>'+
'<div class="floatLeft">'+
''+attrs.title+''+
'</div>'+
'<ul>'+
'<li class="rowlist" ng-repeat="'+repeat+'"> {{n}}<input type="radio" ng-model="'+attrs.kmModel+'" name="a" ng-click="radioValueChanged(n,'+attrs.kmModel+')"/></option>'+
'</ul>'+
'{{'+attrs.kmModel+'}}'+
''+attrs.kmModel+''+
''+model.l+''+
'</div>'+
'</div>'+
'<div ng-switch-when="kmPreview">'+
'<div>'+attrs.title+'<input type="radio" ng-model="'+attrs.kmModel+'" disabled="true"/></div>'+
'</div>'+
'</div></div>';
element.replaceWith(htmlText);
}
}
})
The following code is responsible for calling the function
'<li class="rowlist" ng-repeat="'+repeat+'"> {{n}}<input type="radio" ng-model="'+attrs.kmModel+'" name="a" ng-click="radioValueChanged(n,'+attrs.kmModel+')"/></option>'+
$scope.radioValueChanged = function (value,model) {
//alert("Changed value"+value + model);
alert(value +" and " + model);
//alert("model "+ model );
}
In HTML , i have a code like below
<km-radio km-model="rad" title="Gender" km-option="['De','CM','PM']"></km-radio>
When i tap on radio button in html, i am getting the o/p De and fff, but what i need is o/p De and rad
See the plunker code and check the directive kmRadio
I rewrote your directive to get the binding from the attributes parameter of the link function:
app.directive('kmRadio', function($parse) {
return {
restrict: 'E',
replace: true,
templateUrl: 'kmRadio.html',
scope: true,
link: function(scope, element, attr) {
scope.kmModel = scope.$eval(attr.kmModel);
scope.binding = attr.kmModel;
scope.title = attr.title;
scope.kmOption = scope.$eval(attr.kmOption);
}
}
})
where kmRadio.html is:
<div>
<div ng-switch on="format">
<div ng-switch-when="kmForm">
<div>
<div class="floatLeft">{{title}}</div>
<ul>
<li class="rowlist" ng-repeat="n in kmOption">
{{n}} <input type="radio" ng-model="$parent.kmModel" ng-click="radioValueChanged(n, binding)" ng-value="n"/>
</li>
</ul>
bound to: {{binding}}, value: {{kmModel}}
</div>
</div>
<div ng-switch-when="kmPreview">
<div>{{title}}
<input type="radio" ng-model="kmModel" disabled="true" />
</div>
</div>
</div>
</div>
Here is a working demo: http://plnkr.co/edit/2q8a8B4zNGpQ0C5V1x8D?p=preview

Using ngOptions inside directive

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.

Resources