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();
}
}
Related
I have a form, let's call it myForm similar to this:
<form name="myForm" class="vertical grid-block shrink" ng-init="initSearch()" ng-submit="doSearch(myForm.$valid)" novalidate>
And three input fields: one with keeps details, second which is a starting date and third which is a ending date.
The fields look like this:
<input id="details" type="text" ng-model="myObject.details" placeholder="DETAILS_PLACEHOLDER">
<input id="from" class="uppercase" type="text" name="from" placeholder="{{datePlaceHolder}}" ng-model="myObject.from" required/>
<input id="until" class="uppercase" type="text" name="until" placeholder="{{datePlaceHolder}}" ng-model="myObject.until"/>
And I want to display a button based on the form fields. If the form fields have not changed the button should be hidden.
I tried using $dirty but the problem is $dirty remains true even if the user types in details and then deletes the text.
Anyone has any solution for this?
Also the solution must work even if I come back to the form from another page which probably has another controller.
Any help is appreciated. Thank you
This should fix that. It checks for $pristine, ie untouched.
<button ng-show="myForm.$pristine"></button>
Take a look at sample below, basically you need $viewValue for displaying/hiding submit button.
var app = angular.module('app', []);
app.controller('ctrl', function($scope) {
$scope.myObject = {};
$scope.datePlaceHolder = 'from date';
$scope.datePlaceHolder2 = 'until date';
$scope.doSearch = function() {
alert('submit');
}
$scope.initSearch = function() {
console.log('init search called');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<p>Need to fill FROM and UNTIL values to submit</p>
<form name="myForm" ng-init="initSearch()" ng-submit="doSearch(myForm.$valid)" novalidate>
<input id="details" type="text" ng-model="myObject.details" placeholder="DETAILS_PLACEHOLDER">
<input id="from" type="text" name="from" placeholder="{{datePlaceHolder}}" ng-model="myObject.from" required/>
<input id="until" type="text" name="until" placeholder="{{datePlaceHolder2}}" ng-model="myObject.until" />
<button type="submit" ng-show="myForm.from.$viewValue && myForm.until.$viewValue">Submit</button>
</form>
</div>
You can add more conditions to
ng-show="myForm.from.$viewValue && myForm.until.$viewValue"
Notice that if you delete value from input, submit button disappears
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)"/>
I'm running into an interesting problem while trying to restrict user input to a number.
My HTML looks like so:
<input name="activeDate" type="number" class="form-control" ng-model="account.tag.activeDate"></input>
...and my relevant Angular controller code like so(this is inside a click handler):
tag.activeDate = moment.utc().add(tag.activeDate, tag.tagDurationType).toISOString();
Unfortunately when I click the button which submits my form and calls that click handler I get this error in my console:
[ngModel:numfmt] Expected `2015-08-27T22:09:18.919Z` to be a number
Looks like my input is checked upon submitting, when it's converted to a date within my controller. How do I limit user input to numbers without running into this?
Use ng-pattern="/^(\d)+$/" - it's simple regex expression
var app = angular.module('num', []);
app.controller('numCtrl', function($scope, $http){
$scope.digits = {};
});
angular.bootstrap(document.body, ['num']);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-controller="numCtrl">
<form class="digits" name="digits" ng-submit="getGrades()" novalidate >
<input type="text" placeholder="digits here plz" name="nums" ng-model="nums" required ng-pattern="/^(\d)+$/" />
<p class="alert" ng-show="digits.nums.$error.pattern">Numbers only, please.</p>
<br>
<input class="btn" type="submit" value="Do it!" ng-disabled="!digits.$valid" />
</form>
</body>
Select your input element, then do the following you have to look up value of number0Key and number9Key:
myElement.on("keypress", function(e) {
if (e.which < number0Key || e.which > number9Key) {
e.stopPropagation();
}
});
The whole form should not be valid until stuff[] has at least one item added to it. When the user enters in a value into the text box and then clicks add it then adds the value to stuff[], only at this point when a value has been added to stuff[] should the submit button be enabled. However, as soon as the user types anything into the text box without clicking add, and thus nothing in stuff[], it makes the form valid and enables the submit button.
<form ng-app="myApp" ng-controller="myCtrl" name="myForm" ng-submit="submit()" novalidate>
<div ng-repeat="things in stuff">
<table><tr><td>{{things}}</td></tr></table>
</div>
<input type="text" name="app" ng-model="input" ng-required="!stuff[0]" />
<button ng-disabled="!input" ng-click="add()">
<span> add</span>
</button>
<input type="submit" value="Submit" ng-disabled="myForm.$invalid" />
<script>
angular.module('myApp', []).controller('myCtrl', function ($scope) {
$scope.stuff = [];
$scope.input = null;
$scope.add = function () {
var l = $scope.stuff.length;
$scope.stuff[l] = $scope.input;
$scope.input = null;
};
$scope.submit = function () {};
});
</script>
</form>
[EDIT]
To answer your question directly: !stuff[0] is TRUE when there is nothing in the array, and FALSE otherwise. When it is TRUE, then input is required, making the form 'initially' invalid. As soon as you type something into the input, then the requirement is now fulfilled, meaning that the form is valid, and you can now click the submit button. The condition actually has nothing to do with actually putting something into the array.
This is fixable by attaching a condition to stuff.length as proposed by my answer below. It won't make the form invalid (which you can easily do with this condition elsewhere) but it will at least disable the submit button.
[/EDIT]
I don't understand why you have ng-required there, as you are wanting to disable the submit button, meaning the logic should be attached to the submit button, not the input text box.
I would do this instead:
<input type="text" name="app" ng-model="input"/>
<button ng-disabled="!input" ng-click="add()">
<span> add</span>
</button>
<input type="submit" value="Submit" ng-disabled="stuff.length == 0" />
Which will disable the submit button if there is nothing in stuff.
I have a simple html form:
<form id="formD" action="/somewhere" method="POST">
<input type="hidden" name="i[value]" ng-model="i.value" value={{i.value}}
<button type="button" ng-click="changevalue()) Change Value
With a form controller:
function myFormController($scope)
{
$scope.saveAsDraft = function(){
$scope.i.value="true";
console.log($scope);
document.getElementById("formD").submit();
};
}
On inspecting the console log, value is changing within the $scope, but after submitting, i.value is always empty! Where am I making a mistake?
Another approach that I took was to make that input field as text:
<input type='text' name="i[value]" id="something"
ng-model='i.value' style="display:none;">
Please help. How can I change the value of this hidden field just before submitting the form data?
You are separating attributes with commas. That is incorrect. They should be separated with spaces only, like in this example:
<input type="text" name="i[value]" id="something"
ng-model="i.value" style="display:none;">