Angularjs focus on input text after 3 characters - angularjs

I am using Ionic Angularjs and want, after typing 3 characters into a input type text, to set the focus on the next input .
Can I use limitTo filter combining with another angularjs feature?

For this you can use AngularJS directives, combined with HTML5's input maxlength attribute:
The directive
angular.module('myApp', [])
.directive('focusAfter', function() {
return {
restrict: 'A',
scope: {
elemToFocus: '#'
},
link: function(scope, elem, attrs) {
var elementToFocus = document.getElementById(scope.elemToFocus);
elem.on('keyup', function() {
if(elem.val().length === 3) {
window.setTimeout(function() {
elementToFocus.focus();
});
}
});
}
};
});
View
<input type="text" maxlength="3" id="input1" focus-after elem-to-focus="input2">
<input type="text" maxlength="3" id="input2" focus-after elem-to-focus="input3">
<input type="text" maxlength="3" id="input3" focus-after elem-to-focus="input1">
Here's a plunkr: http://plnkr.co/edit/QvS0dwUNW3oAhHID1VRX?p=info

Related

AngularJS Custom Directive - Match More Than One Field?

I have a custom directive obtained from https://github.com/neoziro/angular-match that matches two form fields. However, how can I customize it to match more than one field? Here is better explanation of what I mean:
-Form Field 1
-Form Field 2
-Form Field 3
-Form Field 4
-Confirmation (I want this one to match either Field 1,2,3 OR 4.)
Currently, I can only match it up to one field.
HTML Form:
<input type="text"
name="correctAnswer"
ng-model="quiz.quizData.correctAnswer"
match="answer1">
<div ng-show="theQuiz.correctAnswer.$error.match && !theQuiz.correctAnswer.$pristine">Answers do not match!</div>
Directive:
angular.module('match', []).directive('match', ['$parse', matchDirective]);
function matchDirective($parse) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
scope.$watch(function () {
return [scope.$eval(attrs.match), ctrl.$viewValue];
}, function (values) {
ctrl.$setValidity('match', values[0] === values[1]);
}, true);
}
};
}
It might be easier to write your own directive for this, especially since angular-match plugin is no longer maintained.
To watch multiple form inputs, just pass the ng-model of each desired input to the directive. Here I called it match.
<input type="text" name="firstNameOne" ng-model="firstNameOne"/>
<input type="text" name="firstNameTwo" ng-model="firstNameTwo"/>
<input type="text" name="firstNameThree" ng-model="firstNameThree"/>
<input type="text" name="confirmFirstName" ng-model="confirm" match="{{[firstNameOne, firstNameTwo, firstNameThree]}}"/>
Now for the directive
app.directive('match', function() {
return {
restrict: 'A',
controller: function($scope) {
$scope.doValidation = function(matches) {
//Validation logic.
}
},
link: function(scope, element, attrs) {
scope.$watch('confirm', function() {
scope.matches = JSON.parse(attrs.match); //Parse the array.
scope.doValidation(scope.matches); //Do your validation here.
});
}
}
});
Here is a fiddle showing validation of form inputs: https://jsfiddle.net/cpgoette/und9t5ee/

How to disable special characters in angular Js input tag. Only allow alphanumeric(PAN Card Validation Regex)

How to disable special characters in angular js input tag. Only allow alphanumeric
just like we use
<input type="text" ng-trim="false" style="text-transform: uppercase" ng-pattern="/^[a-zA-Z0-9]*$/" class="form-text" id="pan_card_number" name="pan_card_number" ng-minlength="10" maxlength="10" required ng-model="registration.newTSP.panCardNumber">
you can use Regex with Ng-pattern and Display the message through ng-message
$scope.useOnlySpecialCharacters = /^[a-zA-Z0-9]*$/;
<input type="text" ng-model="specialcharacters"
ng-pattern="useOnlySpecialCharacters" />
show message through ng-message
<div ng-message="pattern"> Please Enter AlphaNumeric </div>
OR
Best Option is to use Directives
app.directive('noSpecialChar', function () {
return {
require: 'ngModel',
restrict: 'A',
link: function (scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function (inputValue) {
if (inputValue == null) {
return '';
}
var cleanInputValue = inputValue.replace(/[^\w\s]/gi, '');
if (cleanInputValue != inputValue) {
modelCtrl.$setViewValue(cleanInputValue);
modelCtrl.$render();
}
return cleanInputValue;
});
}
}
});
LINK
use ng-pattern="/[A-Z]{5}\d{4}[A-Z]{1}/i" in your HTML input tag
use the following
Controller
$scope.panCardRegex = '/[A-Z]{5}\d{4}[A-Z]{1}/i';
HTML
<input type="text" ng-model="abc" ng-pattern="panCardRegex" />
Use Directives to restrict Special characters:
angular.module('scPatternExample', [])
.controller('scController', ['$scope', function($scope) {
}])
.directive('restrictSpecialCharactersDirective', function() {
function link(scope, elem, attrs, ngModel) {
ngModel.$parsers.push(function(viewValue) {
var reg = /^[a-zA-Z0-9]*$/;
if (viewValue.match(reg)) {
return viewValue;
}
var transformedValue = ngModel.$modelValue;
ngModel.$setViewValue(transformedValue);
ngModel.$render();
return transformedValue;
});
}
return {
restrict: 'A',
require: 'ngModel',
link: link
};
});
<input type="text" ng-model="coupon.code" restrict-Special-Characters-Directive>
set pattern to allow only alphanumeric
/^[a-z0-9]+$/i

AngularJS Autocomplete IE9 Issue

I am new to Angular JS and I am doing form validation for login page using Angular Js. If I enter username and password, it is working fine But if I choose remember credentials in browser and choose autocomplete options next time, my Submit button is not enabled. I am facing this issue only in IE9. for rest of the browsers its working fine. Any suggestions for this. My login.html looks like this:
<input ng-model="username"
class="login"
value=""
name="userId"
type="text"
required/>
<input ng-model="password"
class="login"
value=""
name="password"
type="password"
required/>
<button class="primaryButton"
type="submit"
ng-click="loginUser()"
ng-disabled="loginForm.$invalid"/>
Also, as per one blog, I tried adding directive for this. By adding directive, If I choose autocomplete options and just mouse click somewhere, submit button is enabled. But I don't want to click after choosing autocomplete option.
My directive looks like this:
angular.module('sampleModule').directive('autofill', function autofill(){
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
scope.$watch(function () {
return element.val();
}, function(nv, ov) {
if(nv !== ov) {
ngModel.$setViewValue(nv);
}
});
}
};
})
You may need to apply a timeout to your directive's logic to force it to alert IE that it needs to re-render.
angular.module('sampleModule').directive('autofill', ['$timeout',
function autofill($timeout){
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
scope.$watch(function () {
$timeout(function () {
return element.val();
}, 0);
}, function(nv, ov) {
$timeout(function () {
if(nv !== ov) {
ngModel.$setViewValue(nv);
}
}, 0);
});
}
};
}]);
Try to copy at interval times, because IE9 (and chrome) doesn't emit events for user and password autocomplete.
Set respective ids for inputs, and then:
app.controller('yourController', function($scope, $interval) {
$interval(function() {
$scope.username = $('#username').val();
$scope.password = $('#password').val();
}, 1000); // each 1 second
});
of course, you can adapt this soluction to your directive.
try a directive to call change from element:
directive('monitorAutoFill', function($timeout) {
return {
restrict: 'A',
link: function(scope, el, attrs, ctrl) {
$timeout(function() {
el.trigger('change');
}, 500);
}
};
});
and, on your inputs:
<input ng-model="username"
class="login"
value=""
name="userId"
type="text"
required
monitor-auto-fill />
<input ng-model="password"
class="login"
value=""
name="password"
type="password"
required
monitor-auto-fill />

Conditional focus

I have this directive:
(function () {
'use strict';
var app = angular.module('myAppName');
app.directive('smFocus', [ '$timeout', function ($timeout) {
return {
restrict: 'A',
link: function (scope, element) {
scope.$on('sm:focus', function () {
$timeout(function() {
element[0].focus();
}, 10);
});
}
};
}]);
})();
I also have these two controls:
<input type="text"
name="nickname"
id="nickname"
ng-model="currentDynamicRule.nickname"
class="form-control"
ng-disabled="!isNew"
placeholder="Nickname"
required
ng-maxlength="10"
sm-focus />
and another one
<input type="text" name="descrip" id="descrip" ng-model="currentDynamicRule.descrip" class="form-control"
placeholder="Description" required ng-maxlength="30"
sm-focus />
So, two controls where the first one is only enabled when it's a new row (disabled in Edit mode). I want to have the first control focused when it's a new record and the second control focused when it's in edit mode.
I am using ASP.NET MVC. Right now in both edit and new modes I have the second control focused. I am not sure how to make this focus conditional.
hmm I had written a directive before wherein it accepts an event and an element id to focus when that event has been triggered.
It's something like this(Plunker DEMO):
JAVASCRIPT
.directive('eventFocus', function($timeout) {
return function(scope, elem, attr) {
elem.on(attr.eventFocus, function() {
// timeout makes sure that is invoked after any other event has been triggered.
// e.g. click events that need to run before the focus or
// inputs elements that are in a disabled state but are enabled when those events
// are triggered.
$timeout(function() {
var element = document.getElementById(attr.eventFocusId);
if(element)
element.focus();
});
});
scope.$on('$destroy', function() {
element.off(attr.eventFocus);
});
};
})
HTML (Possible implementation)
<input type="text" id="pet-desc" ng-model="pet.desc">
<button type="button" event-focus="click" event-focus-id="pet-desc">Edit</button
When Edit Button is clicked, input with id="pet-desc" is focused.
UPDATE:
To identify between which sm-focus element is the target for the sm:focus event, you can add an argument(the id of the element to focus to) within your $rootScope.$broadcast(). See this PLUNKER.
e.g.
Controller
$rotoScope.$broadcast('sm:focus', 'pet-id');
Directive
directive('smFocus', function($timeout) {
return function(scope, elem, attr) {
scope.$on('sm:focus', function(event, id) {
$timeout(function() {
if(attr.id == id)
elem[0].focus();
});
});
};
})
Here is my current implementation that seems to be working! Need to test more:
app.directive('smFocus', [ '$timeout', function ($timeout) {
return {
restrict: 'A',
scope: {
noFocus: "=?"
},
link: function (scope, element) {
var noFocus = angular.isDefined(scope.noFocus) ? scope.noFocus : false;
// console.log('noFocus=' + noFocus)
if (!noFocus) {
scope.$on('sm:focus', function () {
$timeout(function () {
element[0].focus();
}, 10);
});
}
}
};
And my form controls are:
<input type="text"
name="nickname"
id="nickname"
ng-model="currentDynamicRule.nickname"
class="form-control"
ng-disabled="!isNew"
placeholder="Nickname"
required
ng-maxlength="10"
no-focus="!isNew"
sm-focus />
And similar for description:
<input type="text" name="descrip" id="descrip" ng-model="currentDynamicRule.descrip" class="form-control"
placeholder="Description" required ng-maxlength="30"
no-focus="isNew"
sm-focus />
The form works as I want it. I am going to test few more forms to make sure this change didn't break anything.

AngularJS - Focusing an input element when a checkbox is clicked

Is there a cleaner way of delegating focus to an element when a checkbox is clicked. Here's the dirty version I hacked:
HTML
<div ng-controller="MyCtrl">
<input type="checkbox" ng-change="toggled()">
<input id="name">
</div>
JavaScript
var myApp = angular.module('myApp',[]);
function MyCtrl($scope, $timeout) {
$scope.value = "Something";
$scope.toggled = function() {
console.debug('toggled');
$timeout(function() {
$('#name').focus();
}, 100);
}
}
JSFiddle: http://jsfiddle.net/U4jvE/8/
how about this one ? plunker
$scope.$watch('isChecked', function(newV){
newV && $('#name').focus();
},true);
#asgoth and #Mark Rajcok are correct. We should use directive. I was just lazy.
Here is the directive version. plunker I think one good reason to make it as directive is you can reuse this thing.
so in your html you can just assign different modals to different sets
<input type="checkbox" ng-model="isCheckedN">
<input xng-focus='isCheckedN'>
directive('xngFocus', function() {
return function(scope, element, attrs) {
scope.$watch(attrs.xngFocus,
function (newValue) {
newValue && element.focus();
},true);
};
});
Another directive implementation (that does not require jQuery), and borrowing some of #maxisam's code:
myApp.directive('focus', function() {
return function(scope, element) {
scope.$watch('focusCheckbox',
function (newValue) {
newValue && element[0].focus()
})
}
});
HTML:
<input type="checkbox" ng-model="focusCheckbox">
<input ng-model="name" focus>
Fiddle.
Since this directive doesn't create an isolate scope (or a child scope), the directive assumes the scope has a focusCheckbox property defined.
If you want to make it more interesting, and support for any expression to be evaluated (not only variables), you can do this:
app.directive('autofocusWhen', function ($timeout) {
return {
link: function(scope, element, attrs) {
scope.$watch(attrs.autofocusWhen, function(newValue){
if ( newValue ) {
$timeout(function(){
element.focus();
});
}
});
}
};
});
And your html can be a little more decoupled, like that:
<input type="checkbox" ng-model="product.selected" />
{{product.description}}
<input type="text" autofocus-when="product.selected" />
A cleaner way is to use a directive to perform the toggle:
app.directive('toggle', function() {
return {
restrict: 'A',
scope: {
selector: '='
},
link: function(scope, element, attrs) {
element.on('change', function() {
$(scope.selector).focus();
scope.$apply();
});
}
}:
});
Your html would be sth like:
<input type='checkbox' toggle selector='#name'>

Resources