I have a text box and a directive to restrict showing negative values in on the screen, and the ng-model should contain that negative value.
In the below directive I am always getting "" as the value for inputValue, How to get the ng-model value for the inputValue
app.directive('numberOnly', function () {
return {
require: 'ngModel',
link: function (scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function (inputValue) {
if (inputValue == undefined) return '';
var transformedInput = inputValue.replace(/[^0-9]/g, '');
if (transformedInput != inputValue) {
modelCtrl.$setViewValue(transformedInput);
modelCtrl.$render();
}
return transformedInput;
});
}
};
});
Your code works well:
HTML
<div ng-app="myModule">
<div ng-controller="myController">
<input type="text" number-only ng-model="model"/>
</div>
</div>
JS
var module = angular.module("myModule", []);
module.controller('myController', ['$scope', function($scope) {
$scope.model = '01234';
}]);
module.directive('numberOnly', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function(inputValue) {
// Value prints here
console.log(inputValue);
if (inputValue == undefined) return '';
var transformedInput = inputValue.replace(/[^0-9]/g, '');
if (transformedInput != inputValue) {
modelCtrl.$setViewValue(transformedInput);
modelCtrl.$render();
}
return transformedInput;
});
}
};
});
Demo
https://jsfiddle.net/bdmqxr5y/720/
Related
Can someone help me to understand this code? I've found this code in a project and I need a directive that allows only numeric input in text areas, can this help me?
controllerManager.directive('chars', function () {
'use strict';
return {
require: 'ngModel',
restrict: 'A',
link: function ($scope, $elem, attrs, ctrl) {
var regReplace,
preset = {
'specialChars': "^\x20-\x22\x27-\x3F\x41-\x59\x61-\x7B\x7D",
'integer': "0-9"
},
filter = preset[attrs.chars] || attrs.chars;
$elem.on('input', function () {
regReplace = new RegExp('[' + filter + ']', 'ig');
ctrl.$setViewValue($elem.val().replace(regReplace, ''));
ctrl.$render();
var max = $elem.attr('maxLength');
var len = $elem.val().length;
document.getElementById($elem.attr('id')+"Count").innerHTML = max - len;
});
}
};
});
Use below directive. It will only allow integer values to be entered and will discard any other character.
app.directive('integerOnly', ['$compile', function ($compile) {
return {
restrict: 'A',
require: "ngModel",
scope: {
ngModel: '='
},
link: function (scope, element, attrs, ngModelCtrl) {
var oldValue = null;
element.addClass('text-right');
element.bind('focus', function () {
return scope.$apply(function () {
return oldValue = element.val();
});
});
return ngModelCtrl.$parsers.unshift(function (inputValue) {
var val = inputValue ? inputValue.toString().replace(/[^0-9]/g, '') : "";
while (val < "1" && val != val.replace(/[^1-9]/, '')) {
val = val.replace(/[^1-9]/, '');
}
if (val !== inputValue) {
ngModelCtrl.$setViewValue(val);
ngModelCtrl.$render();
}
return val;
});
}
};
}]);
I resolved with this change:
controllerManager.directive('chars', function () {
'use strict';
return {
require: 'ngModel',
restrict: 'A',
link: function ($scope, $elem, attrs, ctrl) {
var regReplace,
preset = {
'specialChars': "^\x20-\x22\x27-\x3F\x41-\x59\x61-\x7B\x7D",
'integer': "^0-9"
},
filter = preset[attrs.chars] || attrs.chars;
$elem.on('input', function () {
regReplace = new RegExp('[' + filter + ']', 'ig');
ctrl.$setViewValue($elem.val().replace(regReplace, ''));
ctrl.$render();
var max = $elem.attr('maxLength');
var len = $elem.val().length;
document.getElementById($elem.attr('id')+"Count").innerHTML = max - len;
});
}
};
});
So now this work:
<input type="text" chars="integer"/>
Directive to validate IP:PORT
myApp.directive("validateServerAddress", ['input', function (input) {
var linker = function (scope, element, attrs) {
alert('Tese');
var parts = input.split(":");
var ip = parts[0].split(".");
var port = parts[1];
return validateNum(port, 1, 65535) &&
ip.length == 4 &&
ip.every(function (segment) {
return validateNum(segment, 0, 255);
});
scope.validateNum = function(input, min, max) {
var num = +input;
return num >= min && num <= max && input === num.toString();
}
};
return {
restrict: "EA",
link: linker
};
}]);
HTML Input
<div class="input-group">
<input type="text" validate-serveraddress placeholder="255.255.255.255:5000" name="serveraddress" id="serveraddress" class="color-tooltip form-control" ng-model="serveraddress" required>
</div>
Until user types a valid IP:PORT address, I need to show custom error message 'Invalid Server Address'. The directive works well. Below could be used and custom class can be applied, but I need to show the message just like bootstrap shows for required field.
document.querySelector("input").oninput = function (e) {
this.className = validateIpAndPort(this.value) ? "" : "invalid";
}
.invalid {
color: red;
}
How can I show custom validation using ngMessages via directive as shown in below image ?
Quick directive to validate ip:port I created for you
app.directive("validateAddressPort", function() {
function validateIpAndPort(input) {
var parts = input.split(":");
var ip = parts[0].split(".");
var port = parts[1];
return validateNum(port, 1, 65535) &&
ip.length == 4 &&
ip.every(function (segment) {
return validateNum(segment, 0, 255);
});
}
function validateNum(input, min, max) {
var num = +input;
return num >= min && num <= max && input === num.toString();
}
return {
restrict: "A",
require: "ngModel",
link: function(scope, element, attributes, ngModel) {
ngModel.$validators.invalidaddressport = function(input) {
if(!input) {
return false;
}
return validateIpAndPort(input);
}
}
};
});
html:
<form name="myForm">
<div class="input-group">
<input type="text" ng-model="serveraddress" validate-address-port placeholder="255.255.255.255:5000" name="serveraddress" id="serveraddress" class="color-tooltip form-control" ng-model="serveraddress" required>
</div>
</form>
and now, you can use ngMessages like:
<div ng-messages="myForm.serveraddress.$error" style="color:red" role="alert">
<div ng-message="required">You did not enter a field</div>
<div ng-message="invalidaddressport">Invalid Address:port</div>
</div>
my plunkr: https://plnkr.co/edit/KI9jAqPRkLTYm5EvBKza?p=preview
This is my directive.I want to append the array specific array value in existing array
localStorage.getItem('albumcomments') = "[{"id":1,"photocomment":"sdfsdfs"}]";
angular.module('albumlikeFeature',[]).directive('albumlikeFeature', ['$filter', '$route', function ($filter, $route) {
return {
restrict: 'E',
scope: {},
templateUrl: 'app/components/album/albumlikefeature.html',
link : function(scope, element, attrs) {
scope.likeCount = 0;
scope.unlikeCount = 0;
scope.likeClick = function (dataid) {
scope.likeCount += 1;
if(JSON.parse(localStorage.getItem('albumcomments'))){
var newDataLike = [];
angular.forEach(localStorage.getItem('albumcomments'), function(likeCount, item){
console.log('test');
newDataLike.push({id:item.id, photocomment:item.photocomment, like:likeCount});
});
console.log(newDataLike);
localStorage.setItem('albumcomments',JSON.stringify(newDataLike));
}
};
My expected output is
[{"id":1,"photocomment":"test","like":"1","unlike":"1"}
Now output is
[{"like":"["},{"like":"{"},{"like":"\""},{"like":"i"},{"like":"d"},{"like":"\""},{"like":":"},{"like":"1"},{"like":","},{"like":"\""},{"like":"p"},{"like":"h"},{"like":"o"},{"like":"t"},{"like":"o"},{"like":"c"},{"like":"o"},{"like":"m"},{"like":"m"},{"like":"e"},{"like":"n"},{"like":"t"},{"like":"\""},{"like":":"},{"like":"\""},{"like":"s"},{"like":"d"},{"like":"f"},{"like":"s"},{"like":"d"},{"like":"f"},{"like":"s"},{"like":"\""},{"like":"}"},{"like":"]"}]
Try this hope it will help
angular.module('albumlikeFeature',[]).directive('albumlikeFeature', ['$filter', '$route', function ($filter, $route) {
return {
restrict: 'E',
scope: {},
templateUrl: 'app/components/album/albumlikefeature.html',
link : function(scope, element, attrs) {
scope.likeCount = 0;
scope.unlikeCount = 0;
scope.likeClick = function (dataid) {
scope.likeCount += 1;
if(JSON.parse(localStorage.getItem('albumcomments'))){
var newDataLike = [];
angular.forEach(JSON.parse(localStorage.getItem('albumcomments')), function(likeCount, item){
newDataLike.push({id:likeCount.id, photocomment:likeCount.photocomment, like:scope.likeCount,unlike:scope.unlikeCount});
});
localStorage.setItem('albumcomments',JSON.stringify(newDataLike));
}
};
scope.unlikeClick = function (dataid) {
scope.unlikeCount += 1;
if(JSON.parse(localStorage.getItem('albumcomments'))){
var newDataUnlike = [];
angular.forEach(JSON.parse(localStorage.getItem('albumcomments')), function(i, item){
newDataUnlike.push({id:i.id, photocomment:i.photocomment,like:scope.likeCount,unlike:scope.unlikeCount});
});
console.log(newDataUnlike);
localStorage.setItem('albumcomments',JSON.stringify(newDataUnlike));
}
};
}
}
}]);
I guess you should create a new array and then you can push the things while iterating:
var data = [{"id":1,"photocomment":"test"},{"id":1,"photocomment":"test1"}];
var newData = [];
$.each(data, function(i, item){
newData.push({id:item.id, photocomment:item.photocomment, like:i, unlike:i});
});
console.log(newData);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
localStorage.getItem('albumcomments') = JSON.parse('[{"id":1,"photocomment":"sdfsdfs"}]');
angular.module('albumlikeFeature',[]).directive('albumlikeFeature', ['$filter', '$route', function ($filter, $route) {
return {
restrict: 'E',
scope: {},
templateUrl: 'app/components/album/albumlikefeature.html',
link : function(scope, element, attrs) {
scope.likeCount = 0;
scope.unlikeCount = 0;
scope.likeClick = function (dataid) {
scope.likeCount += 1;
if(localStorage.getItem('albumcomments').length > 0){
var newDataLike = [];
$.each(localStorage.getItem('albumcomments'), function(value, key){
$(this) = $this;
console.log('test');
newDataLike.push( {id: $this.id, photocomment: $this.photocomment, like: scope.likeCount} );
});
console.log(newDataLike);
localStorage.setItem('albumcomments',JSON.stringify(newDataLike));
}
};
Try that
I am using angular type ahead from here
http://pineconellc.github.io/angular-foundation/#/typeahead
I have made a directive where template is
<div>
<input type="text"
ng-model="user.selected"
placeholder="Type to select . . ."
typeahead="item as item.name for item in getData($viewValue)"
typeahead-loading="loadingData"
class="form-control">
<i ng-show="loadingData" class="glyphicon glyphicon-refresh"></i>
</div>
and directive is
return {
restrict: 'AE',
replace: true,
scope: true,
templateUrl: 'type.html',
link: function (scope, elem, attrs) {
var url = window.location.origin + attrs.url;
scope.getData = function (val) {
return $http.get(url, {
params: {
q: val
}
}).then(function (response) {
return response.data.map(function (item) {
return item;
});
});
};
}
};
i am using like this
<my-directivw url="api/user"> </my-directive>
Now instead of writing ng-model="user.selected" in template . i want to something like this
ng-model="somevar"
<my-directivw url="api/user" somevar="user.selected"> </my-directive>
How can i do that
It might help you.
The HTML code look like this.
<div ng-app="app" ng-controller="Ctrl as ctrl">
<form name="theform">
<range ng-model="ctrl.theRange" name="myRange" required="true"></range>
</form>
<button ng-click="ctrl.theRange = '10/100'">SET</button>
</div>
The JavaScript code look like this
var app = angular.module("app",[]);
app.controller("Ctrl", function($scope) {
this.theRange = "1/7";
});
app.directive("range", function() {
var ID=0;
function constructRangeString(from, to) {
var result;
if( !from && !to ) {
result = null;
}
else if( from ) {
result = from + "/" + (to || "");
}
else if( to ) {
result = "/" + to;
}
return result;
}
return {
require: "ngModel",
restrict: "E",
replace: true,
scope: {
name: "#"
},
template:
'<div ng-form="{{ subFormName }}">' +
'<input type="text" ng-model="from" class="range-from" />' +
'<input type="text" ng-model="to" class="range-to" />' +
'</div>',
link: function(scope,elem,attrs,ngModel) {
var re = /([0-9]+)\/([0-9]+)/;
if( scope.name ) {
scope.subFormName = scope.name;
}
else {
scope.subFormName = "_range" + ID;
ID++;
}
ngModel.$render = function() {
var result, from, to;
result = re.exec(ngModel.$viewValue);
if( result ) {
from = parseInt(result[1]);
to = parseInt(result[2]);
}
scope.from = from;
scope.to = to;
};
scope.$watch("from", function(newval) {
var result = constructRangeString(newval, scope.to);
ngModel.$setViewValue(result);
});
scope.$watch("to", function(newval) {
var result = constructRangeString(scope.from, newval);
ngModel.$setViewValue(result);
});
}
};
});
I have this HTML:
<input type="date" date="MM-dd-yyyy" required data-ng-model="customerFormData.customer.BirthDate" />
And this is my directive (from this fiddle of P. Kozlowski)
app.directive('date', function (dateFilter) {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
debugger;
var dateFormat = attrs['date'] || 'yyyy-MM-dd';
var minDate = Date.parse(attrs['min']) || 0;
var maxDate = Date.parse(attrs['max']) || 9007199254740992;
ctrl.$parsers.unshift(function (viewValue) {
var parsedDateMilissec = Date.parse(viewValue);
if (parsedDateMilissec > 0) {
if (parsedDateMilissec >= minDate && parsedDateMilissec <= maxDate) {
ctrl.$setValidity('date', true);
return parsedDateMilissec;
}
}
// in all other cases it is invalid, return undefined (no model update)
ctrl.$setValidity('date', false);
return undefined;
});
ctrl.$formatters.unshift(function (modelValue) {
return dateFilter(modelValue, dateFormat);
});
}
};
});
But my date field doesn't get a value, it keeps saying dd-mm-jjjj (Duth notation).
I set the value of customerFormData.customer.BirthDate in the code to new Date().getTime(); to test this, but like I said, it doesn't work.
What I want to achieve is that a input type date is bind to my date fields.