Add '-' to a numeric input field - html

I am developing a website that is a responsive website, but i got stuck a little with a mobile issue.
When there is an input field that is a 'number' on mobile devices it will pop up the numeric keyboard, but it appears that the 'native' Samsung numeric keyboards doesn't have the minus sign ('-') which is needed in the website, so I've added a button that will appear in mobile browsers and will add the minus sign, but now there is a new problem:
Because the input field is a 'number' i can't add the minus sign programmatically, here is what I've tried to do but it fails:
<input type="number" ng-model="myNumber">
<button type="button" ng-click="myNumber = myNumber + '-'">Add Minus</button>
When the button is being pressed i am getting the error:
Expected '-' to be a number
It kinda make sense because it probably checks if it is a type of number (which is not) and throw this error, but if i will use a PC keyboard or a mobile numeric keyboard that has the minus sign it does accept it.
Is there a way to avoid this error somehow and do insert the minus sign into the input field?
Edit
What i wanted is that it will be the same effect that you get when you have a pc keyboard it means that -5645-56 is possible (because it does possible in an input field 'number') but i guess that even if it is possible it will be much harder to do, and there is not such a good reason for that so the approaches you suggested can work as well.
Thank you!

I think you should just do
<input type="number" ng-model="myNumber">
<button type="button" ng-click="myNumber = (myNumber > 0) ? -myNumber : myNumber">Add Minus</button>

Related

How to tell Chrome form does not contain credit card fields?

Chrome is being overzealous and thinks my HTML form contains credit card information and thus proposes to fill it in with credit card information.
Are there any attributes that I can use to tell Chrome that there is no credit card information to be filled in, in this form?
The field names it is trying fill in credit card information in are:
reg_id (it puts in a CC number here)
emergency_first_name (it puts in first name here)
emergency_last_name (it puts in last name here)
I don't want to have to disable autocomplete if I don't have to.
The frustrating thing here is the Chrome 'knows better' attitude, where it ignores any value to autocomplete, including off:
<input autocomplete="off" value="" size="10" maxlength="10" id="id_reg_id" name="reg_id" type="text">
Edit: updated following answers.
try
input type="custom"
or use textarea with a single row and resize off
Your browser shouldn't remember your credit card number by default -- I can only assume that you entered into a field that had a 'generic' autocomplete value on it. You can always force your browser to forget this information by simply hitting Delete when selecting it (with the arrow keys) in the dropdown of pre-fill options.
As for preventing it appearing in certain fields, it depends on what information you want each field to hold, but there's a wide array of autocomplete values that you can use. You can use number for IDs, and the other two fields you mentioned actually come with specialised autocomplete values, given-name and family-name:
<input name="reg_id" autocomplete="number" />
<input name="emergency_first_name" autocomplete="given-name" />
<input name="emergency_last_name" autocomplete="family-name" />
If number just won't cut it, you can also make use of a JavaScript regular expression to further restrict input:
const regex = new RegExp("^[a-zA-Z]+$");
const form = document.getElementsByTagName('form')[0];
const reg_id = document.getElementsByTagName('input')[0];
form.addEventListener('click', function(e) {
e.preventDefault();
if (regex.test(reg_id)) {
this.submit();
}
});
<form>
<input name="reg_id" autocomplete="number" />
<input name="emergency_first_name" autocomplete="given-name" />
<input name="emergency_last_name" autocomplete="family-name" />
</form>
I have been banging my head against the desk for a while because of this. We have forms to enter Instruments test data, and a field called "Test Card Number", as well as "Kit (Exp. Date)". Guess what Chrome thinks these fields are for?
Needless to say, I'm pretty sure the users would be VERY upset to see chrome us trying to pull their CC information when they're inputing clinical research data.
Even autocomplete="new-password" and autocomplete="nope" are failing to do any good, here.
I tried to load the field with no label and add it dynamically in javascript. No dice. Used html entities instead of characters. Nope.
Well, after a few hours of scouring the web with no solution in sight, I figured one out: insert a few random - within each word of the offending labels. (For me, with Test Card Number, it had to be in BOTH Card and Number. Test was fine left alone).
One could easily write a javascript extension/utility function to split the html of an offending label and slap that invisible span down the middle (and one to remove it in case of needing to use the label value).
Something like this (using jQuery and old js standards because we support old browsers, with no verifications if label is missing or empty, so adapt accordingly. In fact, I'm sure a regex or some other fancy stuff could be used, but I don't have the time to fiddle around with it atm):
jQuery.fn.breakAutofill = function () {
var $lbl = $("label[for='" + this[0].id + "']"),
finalText = $lbl.html().split(" "),
foilSpan = "<span style='display:none;'>-</span>";
for (var idx in finalText) {
var textVal = finalText[idx],
midPos = Math.floor(textVal.length / 2);
finalText[idx] = textVal.substr(0, midPos) + foilSpan + textVal.substr(midPos);
}
$lbl.html(finalText.join(" "));
}
Which you can then call on document ready :
$("your_input_selector").breakAutofill();
I hope that helps someone.

iOS Safari HTML form next/previous buttons - how do they work?

Disclaimer: I am using JQuery Mobile.
I have a bunch of pages with different forms on, but some of them seem to exhibit different behaviour when pressing the next/previous buttons.
All forms are set up with tab index.
Form 1 works perfectly, except it skips the JQuery Mobile flip switches and radio buttons, which isn't really a problem as they are a bit different.
Form 2, the element with tabindex="0" has focus set to it using $("#myElement").focus(); and then the next button is disabled, and pressing the previous button goes to the bottom of the form, i.e. the next/prev order seems to be 1, 2, 0.
Form 3 seems to be completely erratic, this time going downwards in order but some fields seem to be setting the focus to the label first, then pressing next again causes the input field to be selected.
Form 4 works fine, apart from the last select field seems to be ignored. Then the tabindex jumps to some anchor elements on the page before continuing to the flip switches.
Form 5 has the same behaviour as Form 4, again the last select field in the form is ignored.
I will continue to investigate this, and produce a fiddle, but has anyone experienced these kind of issues or has some insight into how they should work?
OK all these are my errors but it might help someone, so here goes.
The next/previous order does seem to be directly related to the tabindex attribute, with no strings attached.
However to my error, tabindex starts at 1 not 0. http://www.w3schools.com/tags/att_global_tabindex.asp. So for Form 2, it started at 1, then 2, then 0.
I was using knockoutjs to bind the tabindex attribute to the $index() of an observableArray item that represented each field and field value, which made the error harder to spot. So I had to change it to $index() + 1.
For the radio buttons, the index was being taken from the collection of options, not the parent, so I had to use $parentContext.index() + 1 for those (see here: https://stackoverflow.com/a/11013401/1061602).
Attempting the same approach for flip switches doesn't seem to do anything.
The completely erratic form was because there was another form still existing on the DOM that had tabindex attributes set to a similar set of values, so it is tabbing between the two forms in turn. The easiest solution for me was to hide the existing form, see here: https://stackoverflow.com/a/5494043/1061602.
The commonality between Form 4 and Form 5 was also that they had the same tabindex (6) however this was a red herring. Still investigating why the last select field is skipped in Chrome - however on iOS Safari it works as expected, so problems solved!!
At least for Firefox/Chrome, you can use mozactionhint:
<input name="foo" tabindex="1" mozactionhint="Next"> // will go to next: "bar"
<input name="bar" tabindex="2" mozactionhint="Next"> // will submit the form
<input type="submit" tabindex="3">Submit</input>

Signup form, placeholder is acting like input

A client of mine has come to me with an error on his website's signup form.
Please see this url for an example.
All of the fields marked with an a asterisk is required but the placeholders in some (Date of birth, Flat / House number, etc.) are acting as input and allowing the form to be submitted without and actual content being entered.
Does anyone have any idea of a solution?
You could just use "real" placeholders (+ modernizr), instead of faking it. But to solve your problem you could check the value against its defaultValue. You could also do this on the inputs instead of hard-coding the values.
if (input.value !== input.defaultValue && (otherchecks))
And for emptying the input you could use this instead of checking for a hard-coded value
onblur="if(this.value=='')this.value=this.defaultValue;" onfocus="if(this.value==this.defaultValue)this.value='';"

Angular/Breeze - Unable to enter decimal point in an HTML text input

In my HTML markup I have an input of type text which has a two-way binding (using ng-model) to a decimal property. The object which contains this decimal property is fetched using a Breeze query on the client side. I can see that the Breeze query has successfully fetched the data and can see the initial value of the property (i.e. 1.25) in the text input. If I delete the decimal point and try to type it in again it will not allow me to do so and at this point I can only type in a number - effectively what I end up with is an integer value.
Can anyone tell me if Angular or Breeze is doing something behind the scenes that is limiting a text input to only being able to accept numbers instead of any text. I've inspected the input element in question in the browser to see if anything extra was "bolted on" that may have caused this but nothing jumps out. The "fix" or workaround would be change the input type to number and set the step attribute to "any" but nevertheless I would still like to understand the cause so any help will be greatly appreciated.
Thanks
I'm having the same issue and I think the problem is that due to the two-way binding the value is expected to be valid at any given moment. Apparently "1." is not a valid number so it doesn't like it. If you type "125" and then go back and insert the "." it will accept "1.25".
My current solution is to use debounced updates:
<input type="{{type}}" ng-model="ngModel" ng-model-options="{ updateOn: 'default blur', debounce: { default: 1000, blur: 0 } }">
If you do not want timeouts at all you could use just:
ng-model-options="{ updateOn: 'blur' }
More on this here: https://docs.angularjs.org/api/ng/directive/ngModelOptions
Depending on your localization settings, the numeric input field may accept only numbers and commas (not decimal points). As the validation is done on unser input, angular is able to set the value with the decimal point without failing.
By the way, why would you want to use breeze, when AngularJS has all you need to link your fields to the model?

Show numeric keyboard in iPhone using input text

Notice that using input type="number" can display a numeric keyboard as below:
Is it possible to use input type="text" to display the same numeric keyboard? I do not want to display a number pad using pattern="\d*" because it is possible that the value will contain a decimal place.
The reason I would like to use input type="text" instead of input type="number" is that I cannot get back the value if I input a non-number for a number field. For example, if I input ABC, it will become empty automatically. It seems to me that using input type="text" will be easier for this kind of control.
If your input is a true number, integer or decimal then use the HTML5 type="number" input. This will bring up correct keyboard on Android devices (assume Windows phone too).
Then the trick is to place a pattern="[0-9]*" on that attribute to force the special numeric keypad on iOS. Note that:
This will not mark a decimal or minus sign as invalid because the pattern attribute is actualy NOT valid on a type="number" field! and
This is the ONLY way to get the iOS numeric keyboard. See difference between the number section of the alpha keyboard (as in your screenshot above) compared to the true numeric keyboard.
One last note, be sure NOT TO use the type number field for inputs that are not true numbers (eg. zipcodes with leading zeros or product codes with comas or spaces). A numeric input field MAY NOT SUBMIT values that are not true numbers! (depending on browser/device)
The numeric keyboard provided by Apple on iOS is sad joke. But, you can fix this using:
inputmode="decimal"
Work fine on Android, off course.
:)
use this code:
<input type="number" pattern="[0-9]*" />
There are other types which can display numeric keyboard.
With type="number" you can do nothing. It won't accept anything but numbers. But if you use type="tel", it's an ugly hack, but it works.
Here's my zip code example:
<input type="tel" id="Address_ZipCode" class="zip-code" pattern="^\d{2}-\d{3}$" maxlength="6">
There will however be a problem with "-" key on some screen keyboards, you can work around this problem with adding the dash after specified number of characters in JavaScript like this:
// Zip Code dashes
$('input[type="tel"].zipCode').keyup(function(event) {
var t = event.target, v = t.value;
if (v.length == 2) { t.value = v + '-'; }
});
(Please excuse jQuery).
Instead of using type="tel" you can use type="text" and pattern property, but I haven't tested it yet. Most likely it wouldn't work with most browsers.
I couldnt find any solution for that as of now.
But one possible trick you could do is use type="number" and change it in javascript with document.getElementById("element").type="text";
but however this would also clear the ABC but it would accept numbers commas and decimals
Try this workarround. Worked for me.
It will turn type to number then return back to text.
This will force ios to switch to numeric keybord on the first prop change.
The setSelectionRange is for select the input value.
$(function(){
$("input[type='text']").on('mouseup', function(e){
e.preventDefault();
});
$("input[type='text']").on('focus click', function(e){
$(this).prop('type', 'number');
var obj = $(this);
setTimeout(function(){
obj.prop('type', 'text');
document.getElementById(obj.attr('id')).setSelectionRange(0, 9999);
}, 50);
});
});
I tested a few options on different iOS devices
The most supported way is to use the pattern attribute, e.g <input type="text" pattern="[0-9]*" />, since it works on several iOS versions:
Iphone 13 (iOS 15.1)
Iphone 8 (iOS 11.4)
Iphone 6 (iOS 8.1)
If you only need to support iOS 12.2+, using only the inputmode attribute works fine