I have a form where users enter a surname. In case if they type it in all small case letters i want it to show up properly E.g. the user types in the word 'smith' but the response page will show 'Smith' instead?
<p>Name: <input type="text" name="surname"></p>
All you need to do is capitalize your input, look snippet below:
P.S. - I edited your p class so you don't get confused when you apply the style to input. Because it could affect every input you may have in your site if was applied to input itself.
.surname input {
text-transform: capitalize
}
<p class="surname">Name:
<input type="text" name="surname">
</p>
EDIT: here is jQuery solution, that will solve your problem with response page.
jQuery.fn.capitalize = function() {
$(this[0]).keyup(function(event) {
var box = event.target;
var txt = $(this).val();
var start = box.selectionStart;
var end = box.selectionEnd;
$(this).val(txt.replace(/^(.)|(\s|\-)(.)/g, function($1) {
return $1.toUpperCase();
}));
box.setSelectionRange(start, end);
});
return this;
}
$('.surname input').capitalize();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<p class="surname">Name:
<input type="text" name="surname">
</p>
You could check the input value in the browser using Javascript and modify the value if the first character is not upper case. I'd recommend JQuery for that. Or use CSS to capitalize it.
Also note that browser-side Javascript or CSS transformations don't guarantee that a POST of your form will only send capitalized input; whatever happens in the browser can be bypassed. Hence, server-side you will want to do the same (capitalize if necessary).
Speaking of surnames, would you capitalize "van der Vaart"?
CSS:
text-transform: capitalize;
<p>Name: <input type="text" style="text-transform: capitalize;" name="surname"></p>
Related
<input type="text" pattern="^[a-zA-Z1-9].*">
How can I restrict the following input element from having leading whitespace, ie, it should always start with a character except a whitespace.
This answer suggested I use pattern="^[a-zA-Z1-9].*" but it doesn't seem to work.
EDIT:
It works only if I wrap it in a form tag and a submit button. Clicking the button triggers the error. But I want to be able to restrict users from entering whitespace on the input box itself.
To achieve this without a form-tag we can use a JavaScript live input filter like this:
var noLeadingSpace = /^\w.*$/;
$("input")
.data("oldValue", "")
.bind("input propertychange", function() {
var $this = $(this);
var newValue = $this.val();
if (!noLeadingSpace.test(newValue))
return $this.val($this.data("oldValue"));
return $this.data("oldValue", newValue);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" />
It does work, but it will be validated if you try to send a form.
function myValidator(v){
var input = document.getElementById('uglyWay')
if(input){
input.value = input.value.replace(/ /g, '')
}
}
<form>
<input id="uglyWay" oninput='myValidator()' type="text" pattern="^[a-zA-Z1-9].*">
<button type="submit">Send</button>
</form>
The Following Regex mentioned in question Works without wrapping inside form tag
input[type="text"]:valid{
background:green;
}
input[type="text"]:invalid{
background:red;
}
<input type="text" pattern="^[a-zA-Z1-9].*">
I have an Angular form. The fields are validated using the ng-pattern attribute. I also have a reset button. I'm using the Ui.Utils Event Binder to handle the reset event like so:
<form name="searchForm" id="searchForm" ui-event="{reset: 'reset(searchForm)'}" ng-submit="search()">
<div>
<label>
Area Code
<input type="tel" name="areaCode" ng-model="areaCode" ng-pattern="/^([0-9]{3})?$/">
</label>
<div ng-messages="searchForm.areaCode.$error">
<div class="error" ng-message="pattern">The area code must be three digits</div>
</div>
</div>
<div>
<label>
Phone Number
<input type="tel" name="phoneNumber" ng-model="phoneNumber" ng-pattern="/^([0-9]{7})?$/">
</label>
<div ng-messages="searchForm.phoneNumber.$error">
<div class="error" ng-message="pattern">The phone number must be seven digits</div>
</div>
</div>
<br>
<div>
<button type="reset">Reset</button>
<button type="submit" ng-disabled="searchForm.$invalid">Search</button>
</div>
</form>
As you can see, when the form is reset it calls the reset method on the $scope. Here's what the entire controller looks like:
angular.module('app').controller('mainController', function($scope) {
$scope.resetCount = 0;
$scope.reset = function(form) {
form.$setPristine();
form.$setUntouched();
$scope.resetCount++;
};
$scope.search = function() {
alert('Searching');
};
});
I'm calling form.$setPristine() and form.$setUntouched, following the advice from another question here on Stack Overflow. The only reason I added the counter was to prove that the code is being called (which it is).
The problem is that even after reseting the form, the validation messages don't go away. You can see the full code on Plunker. Here's a screenshot showing that the errors don't go away:
I started with the comment from #Brett and built upon it. I actually have multiple forms and each form has many fields (more than just the two shown). So I wanted a general solution.
I noticed that the Angular form object has a property for each control (input, select, textarea, etc) as well as some other Angular properties. Each of the Angular properties, though, begins with a dollar sign ($). So I ended up doing this (including the comment for the benefit of other programmers):
$scope.reset = function(form) {
// Each control (input, select, textarea, etc) gets added as a property of the form.
// The form has other built-in properties as well. However it's easy to filter those out,
// because the Angular team has chosen to prefix each one with a dollar sign.
// So, we just avoid those properties that begin with a dollar sign.
let controlNames = Object.keys(form).filter(key => key.indexOf('$') !== 0);
// Set each control back to undefined. This is the only way to clear validation messages.
// Calling `form.$setPristine()` won't do it (even though you wish it would).
for (let name of controlNames) {
let control = form[name];
control.$setViewValue(undefined);
}
form.$setPristine();
form.$setUntouched();
};
$scope.search = {areaCode: xxxx, phoneNumber: yyyy}
Structure all models in your form in one place like above, so you can clear it like this:
$scope.search = angular.copy({});
After that you can just call this for reset the validation:
$scope.search_form.$setPristine();
$scope.search_form.$setUntouched();
$scope.search_form.$rollbackViewValue();
There doesn't seem to be an easy way to reset the $errors in angular. The best way would probably be to reload the current page to start with a new form. Alternatively you have to remove all $error manually with this script:
form.$setPristine(true);
form.$setUntouched(true);
// iterate over all from properties
angular.forEach(form, function(ctrl, name) {
// ignore angular fields and functions
if (name.indexOf('$') != 0) {
// iterate over all $errors for each field
angular.forEach(ctrl.$error, function(value, name) {
// reset validity
ctrl.$setValidity(name, null);
});
}
});
$scope.resetCount++;
You can add a validation flag and show or hide errors according to its value with ng-if or ng-show in your HTML. The form has a $valid flag you can send to your controller.
ng-if will remove or recreate the element to the DOM, while ng-show will add it but won't show it (depending on the flag value).
EDIT: As pointed by Michael, if form is disabled, the way I pointed won't work because the form is never submitted. Updated the code accordingly.
HTML
<form name="searchForm" id="searchForm" ui-event="{reset: 'reset(searchForm)'}" ng-submit="search()">
<div>
<label>
Area Code
<input type="tel" name="areaCode" ng-model="areaCode" ng-pattern="/^([0-9]{3})?$/">
</label>
<div ng-messages="searchForm.areaCode.$error">
<div class="error" ng-message="pattern" ng-if="searchForm.areaCode.$dirty">The area code must be three digits</div>
</div>
</div>
<div>
<label>
Phone Number
<input type="tel" name="phoneNumber" ng-model="phoneNumber" ng-pattern="/^([0-9]{7})?$/">
</label>
<div ng-messages="searchForm.phoneNumber.$error">
<div class="error" ng-message="pattern" ng-if="searchForm.phoneNumber.$dirty">The phone number must be seven digits</div>
</div>
</div>
<br>
<div>
<button type="reset">Reset</button>
<button type="submit" ng-disabled="searchForm.$invalid">Search</button>
</div>
</form>
JS
$scope.search = function() {
alert('Searching');
};
$scope.reset = function(form) {
form.$setPristine();
form.$setUntouched();
$scope.resetCount++;
};
Codepen with working solution: http://codepen.io/anon/pen/zGPZoB
It looks like I got to do the right behavior at reset. Unfortunately, using the standard reset failed. I also do not include the library ui-event. So my code is a little different from yours, but it does what you need.
<form name="searchForm" id="searchForm" ng-submit="search()">
pristine = {{searchForm.$pristine}} valid ={{searchForm.$valid}}
<div>
<label>
Area Code
<input type="tel" required name="areaCode" ng-model="obj.areaCode" ng-pattern="/^([0-9]{3})?$/" ng-model-options="{ allowInvalid: true }">
</label>
<div ng-messages="searchForm.areaCode.$error">
<div class="error" ng-message="pattern">The area code must be three digits</div>
<div class="error" ng-message="required">The area code is required</div>
</div>
</div>
<div>
<label>
Phone Number
<input type="tel" required name="phoneNumber" ng-model="obj.phoneNumber" ng-pattern="/^([0-9]{7})?$/" ng-model-options="{ allowInvalid: true }">
</label>
<div ng-messages="searchForm.phoneNumber.$error">
<div class="error" ng-message="pattern">The phone number must be seven digits</div>
<div class="error" ng-message="required">The phone number is required</div>
</div>
</div>
<br>
<div>
<button ng-click="reset(searchForm)" type="reset">Reset</button>
<button type="submit" ng-disabled="searchForm.$invalid">Search</button>
</div>
</form>
And JS:
$scope.resetCount = 0;
$scope.obj = {};
$scope.reset = function(form_) {
$scope.resetCount++;
$scope.obj = {};
form_.$setPristine();
form_.$setUntouched();
console.log($scope.resetCount);
};
$scope.search = function() {
alert('Searching');
};
Live example on jsfiddle.
Note the directive ng-model-options="{allowinvalid: true}". Use it necessarily, or until the entry field will not be valid, the model value is not recorded. Therefore, the reset will not operate.
P.S. Put value (areaCode, phoneNumber) on the object simplifies purification.
Following worked for me
let form = this.$scope.myForm;
let controlNames = Object.keys(form).filter(key => key.indexOf('$') !== 0);
for (let name of controlNames) {
let control = form [name];
control.$error = {};
}
In Short: to get rid of ng-messages errors you need to clear out the $error object for each form item.
further to #battmanz 's answer, but without using any ES6 syntax to support older browsers.
$scope.resetForm = function (form) {
try {
var controlNames = Object.keys(form).filter(function (key) { return key.indexOf('$') !== 0 });
console.log(controlNames);
for (var x = 0; x < controlNames.length; x++) {
form[controlNames[x]].$setViewValue(undefined);
}
form.$setPristine();
form.$setUntouched();
} catch (e) {
console.log('Error in Reset');
console.log(e);
}
};
I had the same problem and tried to do battmanz solution (accepted answer).
I'm pretty sure his answer is really good, but however for me it wasn't working.
I am using ng-model to bind data, and angular material library for the inputs and ng-message directives for error message , so maybe what I will say will be useful only for people using the same configuration.
I took a lot of look at the formController object in javascript, in fact there is a lot of $ angular function as battmanz noted, and there is in addition, your fields names, which are object with some functions in its fields.
So what is clearing your form ?
Usually I see a form as a json object, and all the fields are binded to a key of this json object.
//lets call here this json vm.form
vm.form = {};
//you should have something as ng-model = "vm.form.name" in your view
So at first to clear the form I just did callback of submiting form :
vm.form = {};
And as explained in this question, ng-messages won't disappear with that, that's really bad.
When I used battmanz solution as he wrote it, the messages didn't appear anymore, but the fields were not empty anymore after submiting, even if I wrote
vm.form = {};
And I found out it was normal, because using his solution actually remove the model binding from the form, because it sets all the fields to undefined.
So the text was still in the view because somehow there wan't any binding anymore and it decided to stay in the HTML.
So what did I do ?
Actually I just clear the field (setting the binding to {}), and used just
form.$setPristine();
form.$setUntouched();
Actually it seems logical, since the binding is still here, the values in the form are now empty, and angular ng-messages directive is triggering only if the form is not untouched, so I think it's normal after all.
Final (very simple) code is that :
function reset(form) {
form.$setPristine();
form.$setUntouched();
};
A big problem I encountered with that :
Only once, the callback seems to have fucked up somewhere, and somehow the fields weren't empty (it was like I didn't click on the submit button).
When I clicked again, the date sent was empty. That even more weird because my submit button is supposed to be disabled when a required field is not filled with the good pattern, and empty is certainly not a good one.
I don't know if my way of doing is the best or even correct, if you have any critic/suggestion or any though about the problem I encountered, please let me know, I always love to step up in angularJS.
Hope this will help someone and sorry for the bad english.
You can pass your loginForm object into the function ng-click="userCtrl.login(loginForm)
and in the function call
this.login = function (loginForm){
loginForm.$setPristine();
loginForm.$setUntouched();
}
So none of the answers were completely working for me. Esp, clearing the view value, so I combined all the answers clearing view value, clearing errors and clearing the selection with j query(provided the fields are input and name same as model name)
var modelNames = Object.keys($scope.form).filter(key => key.indexOf('$') !== 0);
modelNames.forEach(function(name){
var model = $scope.form[name];
model.$setViewValue(undefined);
jq('input[name='+name+']').val('');
angular.forEach(model.$error, function(value, name) {
// reset validity
model.$setValidity(name, null);
});
});
$scope.form.$setPristine();
$scope.form.$setUntouched();
I'm making a form where the user can enter a dollar amount using an html number input tag. Is there a way to have the input box always display 2 decimal places?
So if someone else stumbles upon this here is a JavaScript solution to this problem:
Step 1: Hook your HTML number input box to an onchange event
myHTMLNumberInput.onchange = setTwoNumberDecimal;
or in the html code if you so prefer
<input type="number" onchange="setTwoNumberDecimal" min="0" max="10" step="0.25" value="0.00" />
Step 2: Write the setTwoDecimalPlace method
function setTwoNumberDecimal(event) {
this.value = parseFloat(this.value).toFixed(2);
}
By changing the '2' in toFixed you can get more or less decimal places if you so prefer.
an inline solution combines Groot and Ivaylo suggestions in the format below:
onchange="(function(el){el.value=parseFloat(el.value).toFixed(2);})(this)"
An even simpler solution would be this (IF you are targeting ALL number inputs in a particular form):
//limit number input decimal places to two
$(':input[type="number"]').change(function(){
this.value = parseFloat(this.value).toFixed(2);
});
What other folks posted here mainly worked, but using onchange doesn't work when I change the number using arrows in the same direction more than once. What did work was oninput. My code (mainly borrowing from MC9000):
HTML
<input class="form-control" oninput="setTwoNumberDecimal(this)" step="0.01" value="0.00" type="number" name="item[amount]" id="item_amount">
JS
function setTwoNumberDecimal(el) {
el.value = parseFloat(el.value).toFixed(2);
};
The accepted solution here is incorrect.
Try this in the HTML:
onchange="setTwoNumberDecimal(this)"
and the function to look like:
function setTwoNumberDecimal(el) {
el.value = parseFloat(el.value).toFixed(2);
};
Pure html is not able to do what you want. My suggestion would be to write a simple javascript function to do the roudning for you.
You can use Telerik's numerictextbox for a lot of functionality:
<input id="account_rate" data-role="numerictextbox" data-format="#.00" data-min="0.01" data-max="100" data-decimals="2" data-spinners="false" data-bind="value: account_rate_value" onchange="APP.models.rates.buttons_state(true);" />
The core code is free to download
I used #carpetofgreenness's answer in which you listen for input event instead of change as in the accepted one, but discovered that in any case deleting characters isn't handled properly.
Let's say we've got an input with the value of "0.25". The user hits "Backspace", the value turns into "0.20", and it appears impossible to delete any more characters, because "0" is always added at the end by the function.
To take care of that, I added a guard clause for when the user deletes a character:
if (e.inputType == "deleteContentBackward") {
return;
}
This fixes the bug, but there's still one extra thing to cover - now when the user hits "Backspace" the value "0.25" changes to "0.2", but we still need the two digits to be present in the input when we leave it. To do that we can listen for the blur event and attach the same callback to it.
I ended up with this solution:
const setTwoNumberDecimal = (el) => {
el.value = parseFloat(el.value).toFixed(2);
};
const handleInput = (e) => {
if (e.inputType == "deleteContentBackward") {
return;
}
setTwoNumberDecimal(e.target);
};
const handleBlur = (e) => {
if (e.target.value !== "") {
setTwoNumberDecimal(e.target);
}
};
myHTMLNumberInput.addEventListener("input", handleInput);
myHTMLNumberInput.addEventListener("blur", handleBlur);
Look into toFixed for Javascript numbers. You could write an onChange function for your number field that calls toFixed on the input and sets the new value.
What I didn't like about all these solutions, is that they only work when a form is submitted or input field is blurred. I wanted Javascript to just prevent me from even typing more than two decimal places.
I've found the perfect solution for this:
<!DOCTYPE html>
<html>
<head>
<script>
var validate = function(e) {
var t = e.value;
e.value = (t.indexOf(".") >= 0) ? (t.substr(0, t.indexOf(".")) + t.substr(t.indexOf("."), 3)) : t;
}
</script>
</head>
<body>
<p> Enter the number</p>
<input type="text" id="resultText" oninput="validate(this)" />
</body>
https://tutorial.eyehunts.com/js/javascript-limit-input-to-2-decimal-places-restrict-input-example/
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.16/jquery.mask.min.js" integrity="sha512-pHVGpX7F/27yZ0ISY+VVjyULApbDlD0/X0rgGbTqCE7WFW5MezNTWG/dnhtbBuICzsd0WQPgpE4REBLv+UqChw==" crossorigin="anonymous"></script>
<input type="text" class = 'item_price' name="price" min="1.00" placeholder="Enter Price" value="{{ old('price') }}" step="">
<script>
$(document).ready(function() {
$('.item_price').mask('00000.00', { reverse: true });
});
</script>
give out is 99999.99
Can <div contenteditable="true">Some Text</div> be used instead of texarea and then passed trough form somehow?
Ideally without JS
Using HTML5, how do I use contenteditable fields in a form submission?
Content Editable does not work as a form element. Only javascript can allow it to work.
EDIT: In response to your comment... This should work.
<script>
function getContent(){
document.getElementById("my-textarea").value = document.getElementById("my-content").innerHTML;
}
</script>
<div id="my-content" contenteditable="true">Some Text</div>
<form action="some-page.php" onsubmit="return getContent()">
<textarea id="my-textarea" style="display:none"></textarea>
<input type="submit" />
</form>
I have tested and verified that this does work in FF and IE9.
You could better use:
<script>
function getContent(){
document.getElementById("my-textarea").value = document.getElementById("my-content").innerText;
}
</script>
NOTE: I changed innerHTML to innerText. This way you don't get HTML elements and text but only text.
Example: I submited "text", innerHTML gives the value: "\r\n text". It filters out "text" but it's longer then 4 characters.
innerText gives the value "text".
This is useful if you want to count the characters.
Try out this
document.getElementById('formtextarea').value=document.getElementById('editable_div').innerHTML;
a full example:-
<script>
function getContent() {
var div_val = document.getElementById("editablediv").innerHTML;
document.getElementById("formtextarea").value = div_val;
if (div_val == '') {
//alert("option alert or show error message")
return false;
//empty form will not be submitted. You can also alert this message like this.
}
}
</script>
`
<div id="editablediv" contenteditable="true">
Some Text</div>
<form id="form" action="action.php" onsubmit="return getContent()">
<textarea id="formtextarea" style="display:none"></textarea>
<input type="submit" />
</form>
`
Instead of this, you can use JQuery (if there is boundation to use JQuery for auto-resizing textarea or any WYSIWYG text editor)
Without JS it doesn't seem possible unfortunately.
If anyone is interested I patched up a solution with VueJS for a similar problem. In my case I have:
<h2 #focusout="updateMainMessage" v-html="mainMessage" contenteditable="true"></h2>
<textarea class="d-none" name="gift[main_message]" :value="mainMessage"></textarea>
In "data" you can set a default value for mainMessage, and in methods I have:
methods: {
updateMainMessage: function(e) {
this.mainMessage = e.target.innerText;
}
}
"d-none" is a Boostrap 4 class for display none.
Simple as that, and then you can get the value of the contenteditable field inside "gift[main_message]" during a normal form submit for example. I'm not interested in formatting, therefore "innerText" works better than "innerHTML" for me.
On one of my websites I have created a form that collects the persons name, email and a description of their idea.
I limited the characters of the description to 500 characters as I don't want to read a ton and I figured out how to have the text appear in the textarea before the user inputs what they want.
Currently the user has to delete "Description of your idea" themselves but I want to add the placeholder class where it deletes what I have written in the textarea when they click the textarea
I have looked on a few sites and couldn't figure out how to use it I placed it in my code, but usually the class just appeared as text inside my textarea.
Any help on using this class would be great thank you
Here is what I have written
Inside the head tags
<script language="javascript" type="text/javascript">
function limitText(limitField, limitCount, limitNum) {
if (limitField.value.length > limitNum) {
limitField.value = limitField.value.substring(0, limitNum);
} else {
limitCount.value = limitNum - limitField.value.length;
}
}
</script>
Inside the body tags
<form name="form1" method="post" action="ideas.php">
Your Name: <input type="text" name="name"><br>
Your Email: <input type="text" name="email"<br>
<textarea name="desc" cols=50 rows=10 onKeyDown="limitText(this.form.desc,this.form.countdown,500);"
onKeyUp="limitText(this.form.desc,this.form.countdown,500);">Description of your idea</textarea><br>
<font size="1">(Maximum characters: 500)<br>
You have <input readonly type="text" name="countdown" size="3" value="500"> characters left.</font>
<br>
<input type="submit" name="Submit" value="Submit!"> </form>
There is a feature in HTML5 called 'placeholders', which produces exactly this feature without you having to do any coding at all.
All you need to do is add a placeholder attribute to your form field, like so:
<input type='text' name='name' placeholder='Enter your name'>
Sadly, of course, only a few browsers currently support it, but give it a go in Safari or Chrome to see it in action. The good news is that it is being added to virtually all browsers in the near future.
Of course, you still need to cater for users with older browsers, but you may as well make use of the feature in browsers that can use it.
A good way to deal with it is to use the placeholder attribute, and only fall back to the Javascript solution if the browser doesn't support the feature. The Javascript solution can take the text from the placeholder attribute, so you only need to specify it in one place.
See this page for how to detect whether the placeholder feature is supported: http://diveintohtml5.ep.io/detect.html
(or, as it says on that page, just use Modernizr)
The Javascript fall-back code is fairly simple to implement. Exactly how you do it would depend on whether you want to use JQuery or not, but here are links to a few examples:
http://www.morethannothing.co.uk/2010/01/placeholder-text-in-html5-a-js-fallback/
http://www.hagenburger.net/BLOG/HTML5-Input-Placeholder-Fix-With-jQuery.html
And of course Google will give you loads more if you search for html5 placeholder fallback or something similar.
Hope that helps.
Check out http://www.ajaxblender.com/howto-add-hints-form-auto-focus-using-javascript.html I think it has what you are looking for.
Here is a simple page that has an email field on it that I quickly put together (pulled mostly from the tutorial).
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
// Focus auto-focus fields
$('.auto-focus:first').focus();
// Initialize auto-hint fields
$('INPUT.auto-hint, TEXTAREA.auto-hint').focus(function(){
if($(this).val() == $(this).attr('title')){
$(this).val('');
$(this).removeClass('auto-hint');
}
});
$('INPUT.auto-hint, TEXTAREA.auto-hint').blur(function(){
if($(this).val() == '' && $(this).attr('title') != ''){
$(this).val($(this).attr('title'));
$(this).addClass('auto-hint');
}
});
$('INPUT.auto-hint, TEXTAREA.auto-hint').each(function(){
if($(this).attr('title') == ''){ return; }
if($(this).val() == ''){ $(this).val($(this).attr('title')); }
else { $(this).removeClass('auto-hint'); }
});
});
</script>
</head>
<body>
<form>
Email: <input type="text" name="email" id="email" title="i.e. me#example.com" class="auto-hint" />
</form>
</body>
</html>
The title text is put in the field if it's empty, and removed once the user starts typing.