directive not generating html - javascript

I am having a problem with my code basically i have this span (dynamically created via ng-repeat)
<span my-size id="abc"></span>
<span my-size id="def"></span>
<span my-size id="ghi"></span>
what I need to achieve is to get the id of each span and split its character and created checkbox and used the split[] i get when i split the id to be its value
<span id="abc">
<input type="checkbox" value="a">
<input type="checkbox" value="b">
<input type="checkbox" value="c">
</span>
<span id="def">
<input type="checkbox" value="d">
<input type="checkbox" value="e">
<input type="checkbox" value="f">
</span>
<span id="ghi">
<input type="checkbox" value="g">
<input type="checkbox" value="h">
<input type="checkbox" value="i">
</span>
could anyone help me do this in angular js directives
this is all i have so far :
myApp.directive('mySize', function () {
return {
restrict: 'E',
scope: { html: '#' },
template: '<span ng-bind-html="html"></span>',
link : function (scope, element, attrs) {
scope.html="<h1>sample html </h1>";
}
}
});
I can't go further since my directives wont generate html tags

I'm not sure what your initial intention was when writing the directive, because there is really no need to either use a link-function or ng-bind-html.
For what you've asked the directive could be as simple as:
(function (app, ng) {
'use strict';
app.directive('mySize', function () {
return {
restrict: 'A',
scope: { id: '#id' },
template: '<input type="checkbox" data-ng-repeat="char in id track by $index" value="{{ char }}">'
}
});
}(angular.module('app', []), angular));
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js"></script>
<div data-ng-app="app">
<span data-my-size id="abc"></span>
<span data-my-size id="def"></span>
<span data-my-size id="ghi"></span>
</div>
Edit
If you you want to add extra information just fiddle with the template. E.g.:
(function (app, ng) {
'use strict';
app.directive('mySize', function () {
return {
// actually obsolute, because it's the default setting
restrict: 'A',
// reusing the directive name to simplify the required view-html,
// but mapping it to a more fitting name when used internally
scope: { str: '#mySize' },
// the actual template (this time using a label)
template: '<label data-ng-repeat="char in str track by $index"><input type="checkbox" value="{{ char }}"> {{ char }}</label>'
}
});
}(angular.module('app', []), angular));
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js"></script>
<div data-ng-app="app">
<div data-my-size="abc"></div>
<div data-my-size="def"></div>
<div data-my-size="ghi"></div>
</div>

It doesn't work because you restricted it's usage to element and use it as attribute. Change restrict: 'E' to restrict: 'A'.

var app = angular.module('app', []);
app.directive('mySize', function($sce) {
return {
restrict: 'EA',
scope: {
id: '#'
},
template: '<label ng-repeat="i in array"><input type="checkbox" ng-value="i" >{{i}}<label>',
link: function(scope, element, attrs) {
scope.array = scope.id.split("")
}
}
});
app.controller('homeCtrl', function($scope) {
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="homeCtrl">
<span my-size id="abc"></span>
<span my-size id="def"></span>
<span my-size id="ghi"></span>
</div>
</div>

The directive can look like this:
.directive('mySize', function() {
return {
restrict: 'AE',
link: function(scope, element, attrs) {
element[0].id.split('').map(function(el) {
element.append('<label><input type="checkbox" value="' + el + '"> ' + el + '</label>');
});
}
}
});
Demo: http://plnkr.co/edit/nZMEdUjMXG3MDYv19H5C?p=preview

Related

AngularJS filter infinite loop

I've written a filter in AngularJS, which was working fine when using it with ng-options on an input select.
Since I needed a more powerful select box with additional functionality, I've written a directive.
The directive has an isolated scope with the filtered options being passed via a two-way binding. Unfortunately, my filter produces a "10 $digest() iterations reached"-error.
This is my filter:
angularAMD.filter('gasUsableInSpacer', function(){
return function(gasTypes, isSealed) {
var filtered = [];
angular.forEach(gasTypes, function(gasType){
if(isSealed){
if(gasType.usableInSealedSpacer)
filtered.push(gasType);
}
if(!isSealed){
if(gasType.usableInSecondarySpacer)
filtered.push(gasType);
}
});
return filtered;
};
});
and this is how I included my directive:
<filter-select options="allGasTypes | gasUsableInSpacer:element.sealed" element="element.gasType" id="gasTypeX"></filter-select>
The above way isn't working, while this is working fine:
<select class="form-control" ng-model="element.gasType" ng-options="gasType as gasType.naturalName for gasType in allGasTypes | gasUsableInSpacer:element.sealed track by gasType.id" name="gasTypeX" id="gasTypeX">
</select>
This is my directives controller:
angularAMD.directive("filterSelect", function (angularLoad) {
return {
templateUrl: 'rmlModMainApp/directives/filterSelect.html',
restrict: 'E',
scope: {
options : '=',
element: '='
},
link: function(scope, element, attr) {
angularLoad.loadCSS(requirejs.toUrl('rmlModMainApp/directives/filterSelect.css'));
scope.listVisible = false;
scope.selectOption = function(option){
scope.element = option;
scope.toggleList();
};
scope.toggleList = function(){
scope.listVisible = !scope.listVisible;
}
}
}
});
});
And the part of the view that is supposed to render the options:
<div class="filterSelect">
<div class="filterSelectContent" ng-show="listVisible">
<form class="filterSelectSearch">
<div class="input-group col-xs-12">
<input type="text" class="form-control" id="filterText" ng-model="search.text" placeholder="filter" ng-model-options="{debounce: {'default':500, 'blur':0}}">
<span class="input-group-addon"><i class="fa fa-lg fa-filter"></i></span>
</div>
</form>
<div class="filterSelectList">
<ul>
<li ng-repeat="option in options track by option.id" ng-click="selectOption(option)">{{option.x}} <span ng-if="option.y">({{option.y}}mm)</span> [{{option.z}}] </li>
</ul>
</div>
</div>
</div>
I have no idea what I'm doing wrong.

How to use checkboxes to filter data in angular smart table?

I'm trying to filter data with checkboxes because I just need yes or no options.
<div class="col-xs-3">
<input type="checkbox" data-st-search="option1" checked>
</div>
<div class="col-xs-3">
<input type="checkbox" data-st-search="option2" checked>
</div>
<div class="col-xs-3">
<input type="checkbox" data-st-search="option3" checked>
</div>
<div class="col-xs-3">
<input type="checkbox" data-st-search="option4" checked>
</div>
It sends just the last one always on
Laurent sugest creating a directive to work with checkboxes in Filtering with a checkbox.
I adapted his approach to my scenario and got the following result:
Html:
<div st-pipe="vm.FilterData" st-table="Data">
<st-checkbox id="IdForClick" text="Text for Label" predicate="ModelName"></st-checkbox>
<table>
...
</table>
</div>
Controller:
vm.FilterData= function (tableState) {
console.log(tableState.search)
//filter logic
};
Directive:
angular.module('App').directive('stCheckbox', function () {
return {
restrict: 'E',
scope: {
predicate: '#',
id: '#',
text: '#'
},
replace: 'true',
require: '^stTable',
template:
'<div class="checkbox checkbox-primary checkbox-inline" ng-click="stCheckChange()">' +
'<input type="checkbox" id="{{id}}" ng-model="sel" ng-checked="sel">' +
'<label for="{{id}}"> {{text}}</label>' +
'</div> ',
link: function (scope, element, attr, ctrl) {
scope.stCheckChange = function () {
scope.sel = !scope.sel;
ctrl.search(scope.sel, scope.predicate);
};
}
};
})
Result:
I solved but not the prettiest solution.
<input type="checkbox"
st-search="option1"
value="{{modelOption1}}"
ng-model="modelOption1"
ng-true-value="true"
ng-false-value="false"/>
You can use a directive with require: '^stTable' then, when checkbox model change, use table.search(value, scope.predicate);
OR
<input type="checkbox" data-st-search="option3" ng-true-value="'YES'" ng-false-value="'NO'" checked>

Angular Js : access data in directive and create form control

I have a array with form questions which has label(_text), type(QuestionData._fieldType). on basis of fieldtype I want to creata directive.
Here I am stuck how to pass parameters to directives and use inside directive.
html
<div ng-controller="autoQuoteCtrl">
<form class="form-horizontal text-center" role="form" name="DTOstep1" ng-submit="onSubmit()">
current page:{{$state.current.name}}
<div ng-repeat="que in questions[$state.current.name]">
<div ng-if="que.QuestionData._fieldType === 'text'" >
text - <code>{{que.QuestionData._attributeName}}</code>
<text-control-dir data="que"></text-control-dir>
<!-- <question-dir>print from directive</question-dir> -->
</div>
<div ng-if="que.QuestionData._fieldType === 'select'" >
select - <code>{{que.QuestionData._attributeName}}</code>
<select-control-dir data="que"></select-control-dir>
</div>
<div ng-if="que.QuestionData._fieldType === 'radio'" >
select - <code>{{que.QuestionData._attributeName}}</code>
<radio-control-dir data="que"></radio-control-dir>
<!-- <question-dir>print from directive</question-dir> -->
</div>
<div ng-if="que.QuestionData._fieldType === 'hidden' && que.QuestionData._attributeName != 'CBQ'" >
hidden - <code>{{que.QuestionData._attributeName}}</code>
<hidden-control-dir data="que"></hidden-control-dir>
<!-- <question-dir>print from directive</question-dir> -->
</div>
</div>
<input type='hidden' id="save_quote_email" name="save_quote_email" ng-model="AutoQuote.postAutoQuoteObj.ApplicationInfo.GeneralPartyInfo.ContactInfo.Emails[0].EmailAddress" value="praveend06#gmail.com" />
{{AutoQuote.postAutoQuoteObj.ApplicationInfo.GeneralPartyInfo.ContactInfo.Emails[0].EmailAddress}}
<input type="submit" value="Save" />
{{AutoQuote.postAutoQuoteObj.SessionInfo.StateCode}}
</form>
</div>
controlDirective.js
(function () {
"use strict";
angular
.module("autoQuote")
.directive('textControlDir', [textControlDir])
.directive('selectControlDir', [selectControlDir])
.directive('radioControlDir', [radioControlDir])
.directive('hiddenControlDir', [hiddenControlDir]);
function textControlDir(data)
{
console.log('here in text directive');
console.log(data);
return {
transclude: true, // append html
restrict: 'E',
template: "<div ng-transclude></div>\n\
\n\
<label>{{data._text}} </label><input type='text' name='' id='' value='' >"
};
}
function selectControlDir()
{
console.log('here in select directive');
return {
transclude: true,
template: "<h1>Made by a select directive!</h1>"
};
}
function radioControlDir()
{
console.log('here in radio directive');
return {
transclude: true,
template: "<h1>Made by a radio directive!</h1>"
};
}
function hiddenControlDir()
{
console.log('here in hidden directive');
return {
transclude: true,
template: "<h1>Made by a hidden directive!</h1>"
};
}
}());
please check my plunker link for complete code. http://plnkr.co/edit/Op1QDwUBECAosPUC7r3N?p=preview
when you want to define the template of your directive, instead of template itself you can use a function of the form:
angular.module("autoQuote")
.directive('question', function() {
return {
template: function(elem, attrs) {
if (angular.isDefined(attrs["type"])) {
switch attrs["type"]:
case "text":
return "<input type='text' name='' id='' value='' >"
case "radio":
// return radio template
}
}
....
}
});
and you can write a general directive like question and use it like this: <question type="{{que.QuestionData._fieldType}}"></question>.
Also you can check this answer for more information.
Hope it helps

Bind inner directive to its parent form

Having a directive, my-drtv , with <input ng-required="true"> within <div ng-form="myForm"> .
Currently the inner ng-required isn't bind to its form (myForm) , how could I set to my-drtv the same form as its parent ?
(so that in the initial state myForm.$valid should be false)
JS:
var myAppModule = angular.module('myAppModule', []).
directive('myDrtv',function(){
return {
restrict: 'A',
template: '<div><input ng-required="true"></div>'
}
});
HTML:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<html ng-app="myAppModule">
<body>
<div ng-form="myForm">
<div my-drtv>
</div>
<br>
{{myForm.$valid}}
</div>
</body>
</html>
In order to have validation behaviour input fields must have both ngModel and name attributes. Then it will be registered as control under form controller. So you could do
.directive('myDrtv', function() {
return {
restrict: 'A',
template: '<div><input name="inp" ng-model="inp" ng-required="true"></div>'
}
});
or better pass model and name from outside, then directive will become much more reusable:
.directive('myDrtv', function() {
return {
restrict: 'A',
scope: {
model: '=ngModel'
},
template: function(element, attrs) {
return '<div><input name="' + attrs.name + '" ng-model="model" ng-required="true"></div>';
}
}
});
and use it like this:
<div ng-form="myForm">
<div my-drtv name="some" ng-model="someField"></div>
</div>
Demo: http://plnkr.co/edit/FV7jeiuLvqPmIlVyyXWr?p=preview

How data is passed from custom directive view to controller?

code for the directive template
//"textBox.html"
<div class="well">
<label class="control-label">Text</label>
<div class="controls">
<input id="label" type="text" class="txt span3" ng-model="label" placeholder='Label for text field...'>
<input type="text" class="span3" ng-model="value" placeholder='Default value...'>
<input type="text" class="span3" ng-model="helpText" placeholder="Help text...">
<input type="checkbox" class="span1" ng-model="required" ng-true-value="true" ng-false-value="false">Required
<input type="checkbox" class="span1" ng-model="advanced" ng-true-value="true" ng-false-value="false">Advanced?
<img src="../../images/bullet_cross.png" alt="Remove" style="cursor: pointer" id="text" border="0" ng-click="deleteField($event)">
</div>
</div>
directive is using like this in main html page
//"algorithm.html"
<text-box></text-box>
controller for the custom directive
//"controller.js"
var algorithm = angular.module('algorithmController',[]);
/***********directive to render text field***********/
algorithm.directive('textField' , function(){
return{
restrict: 'E',
templateUrl: '../partials/algorithm/textBox.html',
require: 'ngModel',
replace: true,
link: function(scope, iElement, iAttrs, ngModelCtrl) {
// how should i get updated data(i.e. if user change after typing) over here entered by user??
}
};
});
You can create an isolate scope using the '=' syntax, which will create two way binding to your controller and the directive. You don't even necessarily need ngModel required in your directive.
.directive("textField", function () {
return {
restrict : "E",
template : "<input type='text' ng-model='val'/>",
scope : {
val : "="
}
};
});
Here is a very simple example doing what you requested;
http://jsfiddle.net/smaye81/xaohrv53/2/

Categories