Re-focus input field right after blur event in AngularJS - javascript

i have a html input field and would like to stay focussed on it no matter what happens. I know how to achieve it with JQuery but i only want to embed it if i really need to. My code example doesn't work.
My thoughts for code so far:
HTML
<input type="text" ng-blur="refocus()" autofocus>
AngularJS (inside my controller)
$scope.refocus = function($scope, $element) {
$element.focus();
};
I hope you guys have the right inspiration or better solution to solve this :)

You can keep an element focused with the following directive:
angular.module('test', []).directive('stayFocused', function(){
return {
link: function($scope, $element){
$element.on('blur', function(){
$element[0].focus();
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
First
<input type="text" stay-focused="" autofocus>
<br />
Second
<input type="text" stay-focused="" autofocus>
</div>

Related

Permit of submitting an input value only when it fulfils a pattern

I want to make a list of items, double-clicking on one item makes it editable. Currently, while editing an item, clicking outside (ie, blur) or enter by keyboard submits the new value.
I want to be able to submit the new change only when it is not empty or fulfil a pattern (eg, a file name with .).
I tried ng-required="true", it did not work.
Does anyone know how to set this restriction?
JSBin
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<style>
input {
font-size: 20px;
border:none;
background-color:transparent;
}
</style>
</head>
<body ng-app="app" ng-controller="Ctrl">
<table>
<tr ng-repeat="item in items">
<td>
<input type="text" value="{{item.name}}" ng-blur='eEditable = -1' ng-readonly='$index !== eEditable' ng-dblclick="eEditable = $index" ng-keypress="keypress($event)" ng-required="true"/>
</td>
</tr>
</table>
<script>
var app = angular.module('app', []);
app.controller('Ctrl', ['$scope', function ($scope) {
$scope.items = [{ name: "item #1" }, { name: "item #2" }, { name: "item #3" }];
$scope.eEditable = -1;
$scope.keypress = function ($event) {
if ($event.keyCode === 13)
$event.target.blur()
}
}])
</script>
</body>
</html>
Edit 1: the existing answers suggest to use form, but I don't want to use form or submit button.
One solution would be verifying the new value in a myBlur function: if the pattern is not satisfied, we could set the focus back to the input field and let users modify the value again. Here is another JSBin.
Does anyone know how to set the focus back to the input field?
Does anyone know how to set the focus back to the input field?
If you are validating the inputs in the ngKeypress event you can use the $event.
If the validation fails, set focus back to the input with
angular.element($event.currentTarget).focus();
use ng-pattern with a regular expression
<input type="text" ng-model="model" id="input" name="input" ng-pattern="regex" />
I found this site helpful making regex http://regexr.com/
You could prevent submission by using a <form> with ng-submit, ng-required, and, ng-pattern directives:
<form name="myForm" ng-submit="submitClicked($event, myForm)">
<input type="text" ng-required="true" ng-pattern="/.)/">
<input type="submit">
</form>
$scope.submitClicked = function($event, form) {
if (!form.$valid) {
$event.preventDefault();
}
}

Trigger a button whenever a button is entered on a textarea

This is a textarea element
<textarea id="textfield" paceholder="type anything here"></textarea>
This is a button
<button type="button" class="btn btn-danger" id="button">Alert</button>
I can trigger the button above to alert the value of a textarea using jquery
<script>
$(function() {
$('#button').click(function() {
var value = $('#textfield').val();
alert(value);
});
});
</script>
Is there a way I can use angular to trigger the button alert by default whenever a text or value enters into the textarea
I am trying to use something like this
$scope.$watch('textfield', function () {
//pop alert if textarea has a value
but somehow lost along the line.
You can use the built in ngKeyup directive of Angular
<div ng-app="myapp" ng-controller="myctrl">
<textarea ng-keyup="show($event)" name="" id="" cols="30" rows="10"></textarea>
</div>
Your js
angular.module("myapp",[])
.controller("myctrl", function($scope){
$scope.show = function($event){
alert($event.target.value);
}
})
If you need to force a button click everytime text is entered alter your show function as follows
angular.module("myapp",[])
.controller("myctrl", function($scope){
$scope.show = function($event){
alert($event.target.value);
document.querySelector(".btn").click();
}
})
note: ngKeyup fires every time that key is released, if you need to listen for each character entered in the textaread use the ngChange event
<div ng-app="myapp" ng-controller="myctrl">
<textarea ng-change="show($event)" name="" id="" cols="30" rows="10"></textarea>
</div>
ng-change will help:
<input type="textbox" ng-model="text" ng-change="change()" />
In controller:
$scope.change = function() {
alert($scope.text);
};

$event not defined in ng-change on text input

I hope my issue is simple to solve, I can't access the value by ng-model because i have multiple of these boxes as they are rendered as part of a list of inputs in a form. I am trying to get the ID and text value of a text box with ng-change. heres my html:
<input type="text" class="other-box" ng-model="test" id="4" ng-change="otherBoxUpdate(this)"/>
(ng-model is required, which is why it's in there). Hers is my controller snippet:
$scope.otherBoxUpdate = function (obj, $event) {
console.log(obj)
console.log($event)
console.log($event.target)
}
obj seems to return a scope value, however from what i've read I need to access $event.target, however $event is not defined. What am i doing wrong?
ng-change not allow to pass $event as parameter.
ng-change="otherBoxUpdate(test)"
var myapp = angular.module('app', []);
myapp.controller('Ctrl', function ($scope) {
$scope.otherBoxUpdate = function (obj) {
console.log(obj);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="Ctrl as vm">
<input type="text" class="other-box" ng-model="test" id="4" ng-change="otherBoxUpdate(4)"/>
</div>
If you only need to identify the input that was clicked, you can pass some other piece of identifying information to your handler. For example, we can pass the id:
<input type="text" class="other-box" ng-model="test" id="4" ng-change="otherBoxUpdate(4)"/>

Using ng-disabled on a group of inputs based on one value

I'm currently using one check box to toggle the disabled attribute on 8 form elements. I've used the ngDisabled Directive on each element. I'm searching for a way that I wouldn't have to put the directive on each of the 8 elements. Is this possible?
Checkbox Toggle
<input type="checkbox" ng-model="aircraftOnGround" />
Current working Disabled directive being used on each form element
ng-disabled="aircraftOnGround"
Codepen here:
CodePen
You can use a fieldset to disable every field inside it.
var $scope = {};
var myApp = angular.module('myApp', []);
myApp.controller('formCtrl', ['$scope', function($scope){
$scope.aircraftOnGround = 'true';
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<form ng-controller="formCtrl">
<fieldset ng-disabled='aircraftOnGround'> <!-- USE NG_DISABLE HERE -->
<input type="text">
<input type="text">
</fieldset>
<br>
<b>aircraftOnGround:</b> <button type="button" ng-click="aircraftOnGround = !aircraftOnGround"><span ng-bind="aircraftOnGround"></span></button>
</form>
</body>
You can disable a collection of DOM elements using a watcher in your controller.
myapp.controller('mainCtrl', function($scope, $element){
$scope.aircraftOnGround = false;
$scope.name = "abdullah";
$scope.$watch('aircraftOnGround',function(value) {
$element.find('.form-control').prop('disabled',value);
});
});
Note: I'm using jQuery in the example.

How to manually trigger a form's submit in AngularJS?

I have a form that I wanted be nested, but it is not possible since HTML can't accept nested form. Is there a way I can manually invoke the submit(triggers the validation, e.g. required) on first form on AngularJS?
Here's how the code looks like:
<div ng-conroller="ContactController">
<form ng-submit="saveHeaderAndDetail()">
<label for="Description">Description</label>
<input type="text" ng-model="Description" required/>
<input type="text" style="visibility:hidden" />
</form>
<form ng-submit="addToDetail()">
...
</form>
<input type="button"
ng-click="what code could trigger the first form's submit?"/>
</div>
Btw, both forms are under one controller if that helps
Try creating a directive that catches an event:
var app = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.triggerSubmit = function() {
$scope.$broadcast('myEvent');
console.log('broad');
};
$scope.onSubmitted = function() {
alert('submitted!');
};
}
app.directive('submitOn', function() {
return {
link: function(scope, elm, attrs) {
scope.$on(attrs.submitOn, function() {
//We can't trigger submit immediately, or we get $digest already in progress error :-[ (because ng-submit does an $apply of its own)
setTimeout(function() {
elm.trigger('submit');
});
});
}
};
});
<link href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css" rel="stylesheet"/>
<script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="http://code.angularjs.org/1.0.0/angular-1.0.0.js"></script>
<div ng-controller="MyCtrl">
<form submit-on="myEvent" ng-submit="onSubmitted()">
Form...
</form>
<hr />
<a class="btn" ng-click="triggerSubmit()">Submit</a>
</div>
Original source:
http://jsfiddle.net/unWF3/
I've answered a similar question here AngularJS - How to trigger submit in a nested form
Basically, you can trigger validation by firing $validate event
isFormValid = function($scope, ngForm) {
$scope.$broadcast('$validate');
if(! ngForm.$invalid) {
return true;
}
For working code example & a small utility method which is helpful in showing validation messages, see answer in the above link.
You can have nested forms with ng-form directive. It will be like:
<form name="accountForm">
<div data-ng-form="detailsForm">
<input required name="name" data-ng-model="name">
</div>
<div data-ng-form="contactsForm">
<input required name="address" data-ng-model="address">
</div>
<button type="submit">Save</button>
</form>
That way when submit will be triggered for the accountForm it will validate nested ng-forms also.
There's an easier way to do that, You can give a name for each form that you have in your app, then you'll be able to send the entire angular object of the form that you want to trigger or do whatever you want with it. Example:
<div ng-conroller="ContactController">
<form name="myFirstForm" ng-submit="saveHeaderAndDetail()">
<label for="Description">Description</label>
<input type="text" ng-model="Description" required/>
<input type="text" style="visibility:hidden" />
</form>
<form name="mySecondForm" ng-submit="addToDetail()">
...
</form>
<input type="button"
ng-click="saveHeaderAndDetail(myFirstForm)"/>
</div>
Then in your function
saveHeaderAndDetail (myFirstForm) {
myFirstForm.$submitted = true
...
}
We can always submit a form directly using the submit
() function from javascript.
document.getElementById("myform").submit()
In this way, we can validate the form using angularjs first and if the form is valid then submit it using the submit method.

Categories

Resources