compile textbox using angularjs directive - angularjs

I want to compile textbox using directive in angularjs.
like custom textbox. can anyone help me?
when i am trying to complie line 1 textbox with tow argument it is problem.
Thanks in advance.
see on line no 1 -----------
it is tutorialspoint example i change some content in that.
<div ng-app="mainApp" ng-controller="StudentController">
<student name="Mahesh"></student><br/>
<student name="Piyush"></student>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
var mainApp = angular.module("mainApp", []);
mainApp.directive('student', function() {
var directive = {};
directive.restrict = 'E';
directive.template = "Student: <b>{{student.name}}</b> , Roll No: <b>{{student.rollno}} </b> <br/> <input name='{{student.mytype}}' type='{{student.mytype}}'> ";
directive.scope = {
student : "=name"
}
directive.compile = function(element, attributes) {
// element.css("border", "1px solid #cccccc");
var linkFunction = function($scope, element, attributes) {
element.html("Student: <b>"+$scope.student.name +"</b> , Roll No: <b>"+$scope.student.rollno+"</b><br/>" +
"<b> <input type='"+$scope.student.mytype+"' name='+$scope.student.mytype+' > "); -----line 1
//element.css("background-color", "#ff00ff");
}
return linkFunction;
}
return directive;
});
mainApp.controller('StudentController', function($scope) {
$scope.Mahesh = {};
$scope.Mahesh.name = "Mahesh Parashar";
$scope.Mahesh.rollno = 1;
$scope.Mahesh.mytype = "email";
$scope.Piyush = {};
$scope.Piyush.name = "Piyush Parashar";
$scope.Piyush.rollno = 2;
$scope.Piyush.mytype = "password";
});
</script>

I just updated the code like below. The issue was with the b tag, you didn't close it also you forgot to add double quotation in the name attribute.
var linkFunction = function($scope, element, attributes) {
element.html("Student: <b>"+$scope.student.name +"</b> , Roll No: <b>"+$scope.student.rollno+"</b><br/>" +
"<b> <input type='"+$scope.student.mytype+"' name='"+$scope.student.mytype+"' /></b> ");
}

Related

How to append a character to a number in an input field using AngularJS?

I have an input field of type text and bound to a property in a scope.
<input type=text= ng-model="vm.someProperty">
If someProperty has a value of 4.32, I want the input to display 4.32%. I don't want someProperty to equal 4.32%. The value stays the same. Only the display changes. When the page renders, the % character shows up after the value. When the user is changing the input value, only the number shows and when the input loses focus, the % shows again.
I know this can be done using a directive but I am not sure how. I am not proficient in AngularJS.
Use this
angular
.module("docsSimpleDirective", [])
.controller("Controller", [
"$scope",
function($scope) {
$scope.text = '';
}
])
.directive("percent", function() {
return {
restrict: "A",
transclude: true,
scope: {},
link: function(scope, element, attr) {
element.on("focusout", function() {
var str = element.val();
element.val(str + "%");
});
element.on("focus", function() {
var str = element.val();
element.val(str.substring(0, str.length - 1));
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="docsSimpleDirective">
<input type "text" id="someProperty" percent ng-model="text"> {{text}}
</div>
vm.percentSymbol = function (type) {
vm.someProperty = vm.replace(/\%/g, '') + '%';
};
<input type=text= ng-model="vm.someProperty" ng-blur = "vm.percentSymbol()">
In your html
<input ng-focus="onFocus(someProperty)" ng-blur="onBlur(someProperty)" ng-model="someProperty" />
in your controller
$scope.someProperty= '';
$scope.onFocus = function(someProperty) {
$scope.someProperty = (someProperty.length >0)? someProperty.split("%")[0] : '';
}
$scope.onBlur = function(someProperty) {
$scope.someProperty = (someProperty.length >0)? someProperty+'%' : '';
}
This working fine.. Hope this will help.

ng-click not working when element compiled in controller

How do I use $compile to get ng-click working on a block of code? My code currently displays a suggestion box when the parameters for a particular event are met. However, I want to let the user hide the suggestion box by clicking on the close button.
View
<textarea class="form-control suggest"
ng-keyup="vm.suggestActivate($event.keyCode)"
ng-mouseenter="vm.suggestActivate(32)"
rows="3"
ng-model="vm.summaryData"></textarea>
Controller
var vm = this;
var suggestionElement = document.createElement('div');
vm.suggestActivate = function(keyCode) {
if(keyCode === 32) {
if(vm.summaryData) {
var words = vm.words;
var suggestions = null;
suggestions = '<div style="padding-bottom: 20px"><strong>Suggested next word:</strong></div>'
for(var i = 0; i < 5; i++) {
suggestions += '<div style="padding-bottom: 20px">' + words[Math.floor(Math.random() * words.length)] + '</div>';
}
suggestions += '<div class="btn btn-default" ng-click="vm.suggestDeactivate()">Close</div>'
suggestionElement.innerHTML = suggestions;
suggestionElement.setAttribute('style', 'background: #B0B0B0; padding: 20px; position: relative; top: -3.9em; width: 25%');
suggestionElement.style.display = 'block';
var targetElement = event.srcElement;
targetElement.parentNode.appendChild(suggestionElement);
}
}
else {
suggestionElement.style.display = 'none';
}
};
try with $compile
targetElement.parentNode.appendChild($compile(suggestionElement)($scope));
mention that you have to inject $compile first.
ADD:
use angular.element to add new elements to DOM.
refer below demo:
angular.module("app", [])
.controller("myCtrl", function($scope, $compile) {
$scope.add = function() {
var strNewElement = document.createElement('div');
strNewElement.innerHTML = '<button ng-click="test()">Test</button>';
angular.element(event.srcElement.parentNode).append($compile(strNewElement)($scope));
};
$scope.test = function() {
alert('I am new element.');
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
<textarea ng-keypress="add()" rows="3"></textarea>
</div>

Substr in angularJS to fetch the initials of the full name

My question is related to creating substr in Angular.JS
Suppose i have a model:
$scope.myName = 'John Smith'
but when during the rendering of the model on the page i need only the initials of the name like:
<p>{{myName | some directive/filter }}<p>
Output should be :: JS
i tried creating many directives but unable to fetch the exact output even i have tried the limitTo filter but it give only the starting first 2 letters of the name.
Workbook is here
With assumption that name tokens are separated by SPACE , as given in your question
<body>
<div ng-app="myApp" ng-controller="namesCtrl">
<label>Name : {{name}}</label><br/>
<label>Short Name : {{name|shortName}}</label>
</div>
<script>
var app = angular.module('myApp', []);
app.filter('shortName', function() {
return function(x) {
var shortName="", nameTokens=[];
nameTokens = x.split(" ");
nameTokens.forEach(function(token){ shortName+=token[0] });
return shortName;
};
});
app.controller('namesCtrl', function($scope) {
$scope.name = 'John Smith';
});
</script>
</body>
angular
.module('myApp',[])
.run(function($rootScope){
$rootScope.title = 'myTest Page';
})
.controller('testController', ['$scope', function($scope){
$scope.myName = 'saurabh raman';
}]).filter('filter', function() {
return function(input) {
var name = input;
var inls = name.match(/\b\w/g) || [];
inls = ((inls.shift() || '') + (inls.pop() || '')).toUpperCase();
return inls;
}
});
view
<p>{{myName | filter}}</p>
</body>
</html>
I was hoping there was a built-in filter for it, but it seems there isn't one, so I've created this filter:
var relConclusaoApp = angular.module("relatorioConclusaoApp", []);
relConclusaoApp.filter('onlyinitials', [function () {
return function (input) {
if (input) {
return input
.split(/\s+/)
.filter(s => s.length > 2)
.map(s => s.charAt(0).toLocaleUpperCase())
.join(".")
.concat(".")
}
return input;
}
}])
This filter is going to transform Floor Jansen into F.J. (e.g.)
It should be used in your template as:
{{nameToBeTransformed | onlyinitials}}

Why I cannot change a value of angular property in html?

I have a tooltip which popups on focus using angular popovers. What I need to do is when I click a button, to change it to popup on blur. It changes but doesn't change the tooltip behavior.
Here is the plunkr: http://plnkr.co/edit/L1oeZQrQdF0AdJMKVsG6?p=preview
Below is the code:
<input type="text"
ng-model="value"
value="{{value}}"
uib-popover-template="htmlPopover"
popover-trigger="{{triggerOn}}"
popover-popup-close-delay="1000"
class="form-control">
<script type="text/ng-template" id="myPopoverTemplate.html">
<div>
<button ng-click="test()"><b style="color: red">Add message</b></button>
</div>
</script>
controller
function ($scope) {
$scope.value = "Click me!";
$scope.dynamicPopover = {
content: 'Hello, World!',
templateUrl: 'myPopoverTemplate.html',
title: 'Title'
};
$scope.message = 'Trigger: none';
$scope.triggerOn = "focus";
$scope.changeTrigger = function(){
$scope.triggerOn = "blur";
$scope.message = "Should trigger on blur";
}
$scope.test = function(){
$scope.value = "test me click";
}
$scope.htmlPopover = 'myPopoverTemplate.html';
});
Looking at the source code for the uib-popover directive, one can that the triggers are set when the directive is linked.
compile: function(tElem, tAttrs) {
var tooltipLinker = $compile(template);
return function link(scope, element, attrs, tooltipCtrl) {
var tooltip;
var tooltipLinkedScope;
var transitionTimeout;
var showTimeout;
var hideTimeout;
var positionTimeout;
var appendToBody = angular.isDefined(options.appendToBody) ? options.appendToBody : false;
//TRIGGERS SET AT LINK TIME
var triggers = getTriggers(undefined);
var hasEnableExp = angular.isDefined(attrs[prefix + 'Enable']);
var ttScope = scope.$new(true);
var repositionScheduled = false;
var isOpenParse = angular.isDefined(attrs[prefix + 'IsOpen']) ? $parse(attrs[prefix + 'IsOpen']) : false;
var contentParse = options.useContentExp ? $parse(attrs[ttType]) : false;
var observers = [];
var lastPlacement;
If one wants to change how the directive triggers, the directive needs to be re-compiled with the $compile service on each change to the triggers.

Dynamic default values for input box in angularJs

I have a value which i get from a controller and two input box.
I need that whenever i enter any value in one input box. difference of the value retrieved from controller and input box get displayed in the other input box using angularJs.
e.g:-
{{sum}} --> is the value which I get from controller.
<input type="number" ng-model="firstnumber" />
<input type="number" ng-model="secondnumber"/>
What I tried was making service for setting and getting the sum value and watch to change the value every time a value is changed.
My service is :-
angular.module('myapp').service("cmModalService", function($scope){
var sum= ={};
getSum = function(){
return sum;
}
setSum = function(value){
sum=value;
};
});
In a controller I have defined
$scope.$watch('firstnumber', function(newValue, oldValue) {
var sum=cmModalService.getSum();
if(newValue!=null)
{ secondnumber = sum -firstnumber;
}
});
$scope.$watch('secondnumber', function(newValue, oldValue) {
var sum=cmModalService.getSum();
if(newValue!=null)
{ firstnumber = sum -secondnumber;
}
});
But whenever i change values in input box the flow never goes to watch method, and the values doesn't change.
Is there any other method also to achieve this.?
I have tried using ng-change also but still not able to get the exact result.
And inside controller i have defined the change methods as
$scope.changefirstnumber=function(firstnumber, sum){
$scope.secondnumber = sum- firstnumber;
};
$scope.changesecondnumber=function(secondnumber, sum){
$scope.firstnumber= sum- secondnumber;
};
and in html
[Plunker link]
You are not setting the scoped variable. Try this.
$scope.$watch('firstnumber', function(newValue, oldValue) {
var sum=cmModalService.getSum();
if(newValue!=null)
{ $scope.secondnumber = sum -$scope.firstnumber;
}
});
$scope.$watch('secondnumber', function(newValue, oldValue) {
var sum=cmModalService.getSum();
if(newValue!=null)
{ $scope.firstnumber = sum - $scope.secondnumber;
}
});
Working Plunkr
EDIT
With some new information you provided, is this what you're after? http://jsfiddle.net/37gv1kbe/
var app = angular.module('myApp',[]);
app.controller('MyController', function($scope,cmModalService)
{
$scope.firstnumber = 5;
$scope.secondnumber = 10;
$scope.$watch('firstnumber', function()
{
$scope.total = cmModalService.getSum() - $scope.firstnumber
});
$scope.$watch('secondnumber', function()
{
$scope.total = cmModalService.getSum() - $scope.secondnumber;
});
});
app.controller('MySecondController', function($scope,cmModalService)
{
$scope.rand = Math.round(Math.random() * 100);
cmModalService.setSum($scope.rand);
});
app.service('cmModalService', function()
{
var sum;
return {
getSum: function()
{
return sum;
},
setSum: function(value)
{
sum = value;
}
}
});
ORIGINAL ANSWER
regarding my comment, if you need to access the total in your controller, you can just save the val of firstnumber and secondnumber like so
http://jsfiddle.net/pvqm4tcw/
var app = angular.module('myApp',[]);
app.controller('MyController', function($scope)
{
$scope.firstnumber = 5;
$scope.secondnumber = 10;
$scope.$watch('firstnumber', function()
{
$scope.total = $scope.firstnumber + $scope.secondnumber;
});
$scope.$watch('secondnumber', function()
{
$scope.total = $scope.firstnumber + $scope.secondnumber;
});
});
html:
<body ng-app="myApp">
<div ng-controller="MyController">
<input type="number" ng-model="firstnumber" />
<br>
<input type="number" ng-model="secondnumber"/>
<br>
{{total}}
</div>
</body>
If you're using Angular 1.3+ they have a $watchGroup which can make the code even smaller
var app = angular.module('myApp',[]);
app.controller('MyController', function($scope)
{
$scope.firstnumber = 5;
$scope.secondnumber = 10;
$scope.$watchGroup(['firstnumber','secondnumber'], function()
{
$scope.total = $scope.firstnumber + $scope.secondnumber;
});
});

Resources