Can ng-invalid parameters work similarly to a conditional ng-required? - html

This is my first time asking something here so I tried to put as much information as possible to help in my predicament.
I have a question pertaining to an HTML form I'm building that uses some AngularJS which I'm learning more about as I go along.
The form itself uses some mathematics in it which I'm generating a dividend from 2 fields at a time while also factoring in a total number of people. The page itself will generate the dividend on the page itself to give the user a real-time look at their math, so there are already ng-models on most if not all fields. The catch is that the dividend itself for the fields cannot exceed 1 as I'm doing percentages from 0-100%.
Previously if the numerator was higher than the denominator, or the denominator was higher than the max amount of people I would have an explanation field that was previously be a non-required field toggle to required like so:
<textarea rows="4.5" cols="50" id="My_Fields_Notation__c" tabindex="11"
name="My_Fields_Notation__c" maxlength="255"
ng-required='fieldDen < fieldNum || fieldDen > numberOfPeople'
type="text"></textarea>
My question is if I was to remove the ng-required on this field and add a separate ng-invalid on the numerator and denominator each
(ng-invalid='fieldDen < fieldNum' on the numerator and ng-invalid='fieldDen > numberofPeople' on the denominator)
Would that cause the field to not submit if those parameters are met? (ex. if a user has Numerator: 100, Denominator: 50 and/or Number of people: 100, Denominator: 101 would the form not submit since the numbers don't meet those parameters I'm trying to set)
EDIT: If this helps to better explain my situation. I have several numerators and denominators for this form all with their own ng-model names.
The numerator cannot be higher than the denominator
The denominator cannot be higher than the number of people
If either or happens on any of the numerators and denominators, I want to block submission of the form
At the same time the form is in a drupal page and the only JS file I've been able to successfully call in was the angular file so far, so I think any additional script needs to be coded in the page itself if I need to create any controllers.

If your form submit's or doesn't submit depends on how you do the submission.
It will submit if you use:
<button ng-click='mySubmitFunction()'>Submit</button>
It will not submit if you use:
<button ng-click='formValid() && mySubmitFunction()'>Submit only if valid</button>
To check if your validation condition is met add a validation function:
$scope.formValid = {
return ($scope.fieldDen < $scope.numberofPeople) && ($scope.fieldDen < $scope.fieldNum)
}
If you only want to validate a certain input you can also write a validation directive for this. This let's you show i.e. custom error messages if a certain condition is not met like the format, example plunkr taken from the docs: http://plnkr.co/edit/7ewLoTgWWwyeo7HAvTqU?p=preview

you can add a ngPattern to the input you want to validate and then you just can use the $valid given by angularjs to validate that element.
<form name="myForm">
<input type="text" name="userName" ng-model="user.name" ng-pattern="{string}" >
</form>
//to test just use
{myForm.userName.$valid}

Related

What is the correct and most safe way to check if HTML form checkboxes and such have been POST-set?

This has confused me since the early days. Maybe it's just in my head, but it seems to me as if this has varied over time, between browsers, and possibly even depending on the local language/locale.
Basically, whenever I need to check if a HTML input of type "radio" or "checkbox" has been set, I always do:
if (isset($_POST['the_name']) && trim($_POST['the_name']))
// do stuff
This just makes sure that the POST variable is sent whatsoever (which in itself doesn't mean that it was actually checked/selected, as far as I can tell, since its "value" can be an empty string) and that it's something other than '' (empty string). It seems like this has worked for a long time, but I have two problems with it:
It's ugly. I need to abstract it into a function, but then I want to know if it's a good idea in the first place, or wrong somehow.
It makes the assumption that any non-empty string value means "checked" or "selected", whereas the standard may say a specific string value such as "on", or maybe any number of such strings depending on the language/locale.
Are there cases where my above code falls apart? Do browsers ever submit POST forms where they include names which have no user input/selection in the HTTP request? Or does the existence of a name in the POST blob mean that that "field" has been actively changed/set/checked/selected?
The idea behind checkboxes is that the value is sent over to the server only if the checkbox was checked when submitting the form. The value can be anything, even an empty string. As long as the field is part of the transmitted form it means the box was ticked.
The value attribute is one which all <input>s share; however, it serves a special purpose for inputs of type checkbox: when a form is submitted, only checkboxes which are currently checked are submitted to the server, and the reported value is the value of the value attribute. If the value is not otherwise specified, it is the string on by default.
This means you could have a form like this:
<form action="" method="get">
<input type="checkbox" name="c1" value="">
<input type="submit" value="Send">
</form>
If the checkbox is not checked when submitting then $_GET will be an empty array.
If the checkbox is checked then the value of $_GET will be:
array('c1' => '');
To check whether the box was ticked when sending the form you only need isset()
if (isset($_POST['c1']) {
// The box was checked!
}
Sometimes you would like to assign a value attribute to your checkbox. In such situations you can use the shorthand operator for isset() function ??.
// Create a variable from the checkbox value or assign an empty string if the box was not checked
$nyCheckbox = $_POST['c1'] ?? '';

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.

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='';"

Updating a form field with a link

I have access to form field in the administrative view.
Example
<label>Number:</label>
<input type="text" name="title" size="50"/><br/>
I do not have access to modify the html syntax, the only thing i can do is updating the form field with a value.
In the form field i want to update it with a number. I also want to have a link assigned to that number.
So when i click that number it directs us to the link.
Is there a way i can do that?
This method is tedious, but you could use the jQuery nth-selector to select the specific form element that you are dealing with.
http://api.jquery.com/nth-child-selector/
This method is risky, however, since you might add other form elements before it, altering the index of your target input element.
Afterwords, you could use the .val() jQuery method to change your input value.
Nonetheless, again, this method is not safe because the index of the form element could change. I would beg the powers of be to be able to add an ID or some identifying attribute to that form element.

How not to pass a specific form field?

I'm writing a landing page to test a business idea.
For testing purpose, I want to write a Credit card number field, to see if the customer is actually ready to buy the product.
As it is only a test, I don't want this value to be submitted.
Actually for security purposes I don't even want this value to be sent in the request.
Is a separate form enough?
<form> Sensitive info</form>
<form>Info I want
<input type="submit">
</form>
Yes, only the elements from the one form will be sent (whichever one was submitted).
Alternatively, you could:
mark the input as disabled (either from the start, or onsubmit)
remove the name attribute of the input
put another input later in the form with the same name (it will override the value of the first)
Yes, that will work.