Checkbox Directive in angular - javascript

I want create directive for checkbox input with this structure:
<label for="sameID" class="style">
<input type="checkbox" id="sameID" name="name" />
<span>some text here</span>
</label>
And the put the simple tag like <checkbox></checkbox> in my html.
and this directive should handle checked event for me. And i can check if this checkbox checked or not in code.
Here is my js code when try create this directive:
app.directive("checkbox", function($compile){
var check = "{{check}}";
if (check == true) {
var inputCheck = '<input class="checkbox" checked type="checkbox" ng-change="isChecked()" name="{{for}}" id="{{for}}" />';
} else {
var inputCheck = '<input class="checkbox" ng-change="isChecked()" type="checkbox" name="{{for}}" id="{{for}}" />';
}
var temp = '<label for="{{for}}" class="hello">'+inputCheck+' <svg width="100%" v-pressable id="checkboxsvg" height="100%" viewBox="0 0 23 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve">'+'<g transform="matrix(1,0,0,1,-262.373,-219.494)">'+'<g id="checkbox-background" transform="matrix(1,0,0,1,73.0395,6.16767)"><path d="M211.114,216.192C211.114,215.089 210.218,214.192 209.114,214.192L192.199,214.192C191.095,214.192 190.199,215.089 190.199,216.192L190.199,233.107C190.199,234.211 191.095,235.107 192.199,235.107L209.114,235.107C210.218,235.107 211.114,234.211 211.114,233.107L211.114,216.192Z"/></g><g id="checkbox-check" transform="matrix(1,0,0,1,35.2522,0.0159298)"><path d="M234.362,231.155L237.395,234.188L243.299,228.283"/></g></g></svg><span>{{p}}</span></label>';
return {
restrict: "E",
template : temp,
scope : {},
link : function(scope, element, attrs, ctrl){
scope.type = attrs.type;
scope.p = attrs.p;
scope.for = attrs.for;
scope.check = attrs.check;
scope.isChecked = function() {
console.log("checked");
}
}
};
});
How i can do that?

Pls check this out
var jimApp = angular.module("mainApp", []);
jimApp.controller('mainCtrl', function($scope){
})
.directive("checkbox", function() {
return {
restrict : "E",
require: 'ngModel',
scope:{ name:"#" , ngModel:"=" },
template : "<label class='style'><input type='checkbox' name='name' ng-model='ngModel' /><span>{{name}}</span></label>"
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="mainApp" ng-controller="mainCtrl">
<checkbox name="some text here" ng-model="value" ></checkbox>
{{value}}
</div>

Related

How to add input forms dynamically in Angular JS

I want to change the form inputs dynamically , and i have tried doing it using ng-bind-html , but only label is getting displayed , text box doesn't appears on the DOM. Here what has to be written inside ctrl.content depends upon the values from the server.
Note
type value will be coming from server , and it can be dynamic
HTML
<div ng-bind-html="ctrl.content">
Controller
function myCtrl(type) {
var ctrl = this;
switch (type) {
case 1:
ctrl.content = " <div> Input : <input type=\"text\" > </div> ";
break;
case 2:
ctrl.content = " <div> Input : <input type=\"textarea\" > </div> ";
break;
default:
}
Dom Element :
<div class="padding ng-binding ng-scope" ng-bind-html="addMeassurments.content"> <div> Input : </div> </div>
First, your assignment is all wrong
ctrl.content = " <div> Input : <input type=\"text\" > </div> ";
You should be assigning the markup to a $scope property. e.g.
$scope.content = " <div> Input : <input type=\"text\" > </div> ";
Secondly you should use the $sce service to sanitize the html. Here's a plnkr where this code demonstrates the intended behavior
var app = angular.module('plunker', []);
app.controller('Ctrl', function($scope, $sce) {
$scope.name = 'World';
var ctrl = this;
$scope.click = function myCtrl(type) {
switch (type) {
case 1:
$scope.content = $sce.trustAsHtml("<div> Input : <input type=\"text\" > </div> ");
break;
case 2:
$scope.content = $sce.trustAsHtml(" <div> Input : <textarea></textarea> </div> ");
break;
default:
}
}
});
Note also that I changed your markup from input type="textarea" to a textarea element.
You should use $sce service with ngSanitize module:
angular.module('app', ['ngSanitize'])
.controller('MyController', ['$scope', '$sce', function($scope, $sce) {
$scope.html = function(){
return $sce.trustAsHtml(`<div> Input : <input type=\"${$scope.type == 0 ? 'text' : 'textarea'}\" > </div>`);
}
}]);
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<script src="//code.angularjs.org/snapshot/angular-sanitize.js"></script>
<body ng-app="app">
<div ng-controller="MyController" ng-init='type="0"'>
text: <input type="radio" ng-model="type" value="0">
textarea: <input type="radio" ng-model="type" value="1">
<div ng-bind-html="html()"></div>
</div>
</body>
A textarea can not render HTML input type like <input type=\"textarea\" >..
and try with $sce.
var app = angular.module('exApp',[]);
app.controller('ctrl', function($scope,$sce){
$scope.text = $sce.trustAsHtml("<div> Input : <input type=\"text\" > </div> ");
$scope.textArea = $sce.trustAsHtml(" <div> Input : <textarea></textarea> </div> ");
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body ng-app="exApp" ng-controller="ctrl">
<div ng-bind-html="text"></div><br>
<div ng-bind-html="textArea"></div><br>
</body>
Use ng-if instead of ng-bind-html.
Something like this:
<div>
<div ng-if="type===1">Input : <input type="text"></div>
<div ng-if="type===2">Input : <input type="textarea"></div>
</div>
And in your controller, you will only need to dynamically assign type either 1 or 2 as value.

Angular - Combine two input ng-model into one

I am new to Angular, please help me. I have two input fields, one with area code and other with the number.
// First input field for area code
<input area-input type="tel" required="true" name="area"
ng-model="employee.home.area"></input>
// Second input field for number
<input phone-input type="tel" required="true"
name="number" ng-model="employee.home.number"></input>
I want to combine them into one like area code + number.
Thanks in advance. Any suggestions or help would be appreciated.
You can write custom directive, and use parsers and formatters from ngModelControllers
So you can get something like this:
angular.module('app', []).
controller('ctrl', function($scope,$timeout) {
$scope.employee = {home : {area:'area', number:'number'}};
})
.directive('phone', function() {
function formatPhone(value) {
console.log('format',value);
if (!value) return;
if (!value.number) return value.area;
value.area = value.area||'';
return value.area + "-" + value.number;
}
return {
require: 'ngModel',
scope:{
ngModel:'='
},
link: function(scope, element, attrs, ngModel) {
scope.$watch(function(){return scope.ngModel;},function(n){
if(!n) scope.ngModel={area:"",number:""}
console.log('watch',n);
ngModel.$viewValue= formatPhone(n);
ngModel.$render();
},true);
ngModel.$formatters.push(formatPhone);
ngModel.$parsers.push(function(value) {
console.log(value, value.split('-'));
var parts = value.split('-');
return {
area: parts[0],
number: parts[1]||''
};
});
}
};
})
<script data-require="angular.js#1.4.6" data-semver="1.4.6" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<div ng-app="app" ng-controller="ctrl">
<h1>Hello Plunker!</h1>
// First input field for area code<br/>
<input area-input="" type="tel" required="true" name="area" ng-model="employee.home.area" />
<br/>// Second input field for number<br/>
<input phone-input="" type="tel" required="true" name="number" ng-model="employee.home.number" />
<br/><br/>
//custom field. format: area-number<br/>
<input data-phone type="tel" required="true" ng-model="employee.home" />
{{employee}}
</div>
You can use {{employee.home.area}}+{{employee.home.number}} in your html on
use `employee.home.area+employee.home.number` in your `controller`
Hope this helps

Radio is not getting checked after cancel in angularJS

I have 2 radio buttons, then is ng-change event is applied on NO radio button.
I am showing a confirmation box , on ng-change event of NO radio button.
if he click cancel, Then I want to check the Yes Radio button.
But it's not working .
HTML
<body ng-app="myapp" ng-controller="MyCtrl">
<div>
Yes:
<input type="radio" ng-model="ModelVal" value="true" name="ff">
<br>No:
<input type="radio" ng-model="ModelVal" value="false" ng-change="chck('ModelVal')" name="ff">
<br>
<hr>{{ModelVal}}
<div ng-if="ModelVal == 'true'">Helll</div>
</div>
</body>
JS
// Code goes here
var myapp=angular.module('myapp',[]);
myapp.controller('MyCtrl',function($scope){
$scope.ModelVal='true';
$scope.chck=function(chkM){
var getV=confirm('Sure to Cancel ?');
if(getV) {
$scope[chkM]='false';
}else {
$scope[chkM]='true';
}
};
});
as you can see from demo, after clicking on NO radio button, I'm not changing model, unless he click on OK or cancel.
PLUNKER
Using a $timeout() seems to have solved the problem
// Code goes here
var myapp = angular.module('myapp', []);
myapp.controller('MyCtrl', function ($scope, $timeout) {
$scope.ModelVal = 'true';
$scope.chck = function (chkM) {
var getV = confirm('Sure to Cancel ?');
$timeout(function () {
$scope[chkM] = getV ? 'false': 'true';
})
}
});
// Code goes here
var myapp = angular.module('myapp', []);
myapp.controller('MyCtrl', function($scope, $timeout) {
$scope.ModelVal = 'true';
$scope.chck = function(chkM) {
var getV = confirm('Sure to Cancel ?');
$timeout(function() {
$scope[chkM] = getV ? 'false' : 'true';
})
}
});
<script type="text/javascript" src="//code.jquery.com/jquery-1.11.0.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.js"></script>
<div ng-app="myapp" ng-controller="MyCtrl">
<div>
Yes:
<input type="radio" ng-model="ModelVal" value="true" name="ff">
<br>No:
<input type="radio" ng-model="ModelVal" value="false" ng-change="chck('ModelVal')" name="ff">
<br>
<hr>{{ModelVal}}
<div ng-if="ModelVal == 'true'">Helll</div>
</div>
</div>

AngularJS directive to display/hide either templates

I have a checkbox as follows, and I want to show/hide taxid input or chkno input when it is checked or not.
<input type="checkbox" id="chks" ng-model='chks' chk-no>
Inorder to do this I have written a directive as follows, but it isn't working. what exactly is the issue in my directive?
app.directive('chkNo', function($compile,$log)
{
var template_taxid = "<label id='taxidlbl'>Tax ID Number</label><br/><input type=text' id='taxid' name='taxid' placeholder='Tax ID Number' ng-model='taxid' required>";
var template_chkno = "<label id='chklbl'>Check Number</label><br/><input type='text' id='chn' placeholder='Checking Number' ng-model='chn' required>";
var getTemplate = function(chks)
{
var template = '';
if(chks){
template = template_taxid;
}
else
{
template = template_chkno;
}
}
var linker = function(scope,element, attrs)
{
element.html(getTemplate(scope.chks)).show();
$compile(element.contents())(scope);
}
return{
restrict : 'EA',
replace : true,
link : linker
}
});
you can just use ng-show ng-hide
<input type="checkbox" ng-model='chks'>
<div ng-show"chks">
<label >Tax ID Number</label>
<br/>
<input type=text' name='taxid' placeholder='Tax ID Number' ng-model='taxid' required>"
</div>
<div ng-hide"chks">
<label>Check Number</label>
<br/>
<input type='text' placeholder='Checking Number' ng-model='chn' required>
</div>

Attribute directive in AngularJS

I am trying to create a attribute directive that will insert a label before the input field. Judging by the alert statement, the html looks correct. However I am not compiling or doing the angular element correctly. Any help would would be much appreciated.
The fiddle is http://jsfiddle.net/2suL9/
This is the JS code.
var myApp = angular.module('myApp', []);
myApp.directive('makeLabel', function ($compile) {
return {
restrict: 'A',
replace: false,
link: function (scope, inputFld, attrs) {
var ForInput = attrs['name'];
var LabelSize = attrs['labelSize'];
var LabelText = attrs['makeLabel'];
var htmlStart = '<label for="' + ForInput + '" class="label-control ' + LabelSize + '">';
var htmlStar = '';
if (attrs['required'] ) {
htmlStar = '<span style="color:red">*</span>';
}
var htmlEnd = LabelText + ":</label> ";
var htmlTotal = htmlStart + htmlStar + htmlEnd;
alert(htmlTotal);
// Now add it before the input
var newLabel = angular.element(htmlTotal);
inputFld.prepend(($compile(htmlTotal)));
}
};
});
This is the HTML
<!DOCTYPE html>
<html class="no-js" data-ng-app="myApp">
<head>
<title></title>
</head>
<body>
<div class="container">
<div class="row">
<form name="TestLabelForm" class="form-horizontal">
<div class="form-group">
<input type="text" name="Simple" required="" make-label="Test Label" label-size="col-md-7" />
</div>
</form>
</div>
<br />
Should look like
<br />
<div class="row">
<form name="ExampleForm" class="form-horizontal">
<div class="form-group">
<label for="Simple2" class="col-md-7"><span style="color:red">*</span>Test Label:</label>
<input type="text" name="Simple2" required="" />
</div>
</form>
</div>
</div>
<!-- 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/TestLabelAttr.js"> </script>
</body>
</html>
Did you see the DOM Exception, which was thrown? It could not find the elements, which you created. You have to use document.createElement() and introduce the newly created element to the scope via $compile(scope)(newElement). Here is a working fiddle of this: http://jsfiddle.net/2suL9/26/ Please note that I didn't implement the if condition of your example, you have to add it!
The javascript part looks like this:
var myApp = angular.module('myApp', []);
myApp.directive('makeLabel', function ($compile) {
return function (scope, inputFld, attrs) {
var el = inputFld[0];
var newEl = document.createElement("label");
newEl.setAttribute("for", attrs['name']);
newEl.setAttribute("class", "label-control");
var subEl = document.createElement("span");
subEl.setAttribute("style", "color:red");
subEl.innerHTML = "*";
var endText = document.createTextNode("Test Label:");
$compile(scope)(newEl);
$compile(scope)(subEl);
$compile(scope)(endText);
newEl.appendChild(subEl);
newEl.appendChild(endText);
inputFld.parent().prepend(newEl);
}
});
Note: Changing the dom elements outside of the directive is not a good practice. Rather use another directive for the label, which should be shown in front of the input. You can centralise the logic in your controller and use broadcast to inform the directives, when they should change.

Categories