Angularjs forms dynamic validity states of elements - javascript

Angularjs 1.3-beta.8
This is a table of inputs, which are embedded in a form that contains other form elements.
This question is in regards to this table only. Here are a few things to keep in mind.
There are no other nested forms, just one master form, which we will call masterForm and contains ALL form elements, not just this table.
Rows are added dynamically to the form using a button you cannot see. Rows can also be deleted by the red circle on the left of the table.
There may be hundreds of rows, or only one; but there must be at least one row.
The only rows that are relevant are the ones that have a payment amount entered.
Each input may have no validation or some validation (dynamically assigned from the server per input).
This means that each individual input will differ and could be this
$scope.masterForm.thisInput.$error = {required: true, format: true, somethingnew: true, etc...}
or it could be nothing as seen in the table picture; only the 'Account Number' and 'Total Due' fields have validation errors.
Question: How can I disregard the input validations in each row input, THAT HAS VALIDATION SET, and only when the 'Payment Amount' is filled in?
The question is a little misleading, as I know how to trigger a state change in Angularjs, however everything I have tried does not change the form validation.
Here is what I have tried -
I did search SO, but did not find an answer that worked in this case.
When the form is submitted, it flags all inputs that do not pass validation. I have hijacked the submit function to first run through the form object and $setValidity state of each "named" input, like so
loop through $scope.masterForm and look for input name fields
When you find the relevant fields of table inputs that have no payment amounts
then run through each input.$error and then input.$setValidity of each
$error (like required: true), set these to false (like required: false) - thanks
This does set each input to valid -
input.$valid (is true)
input.$invalid (is false)
input.$error (are all set to false)
However, all the inputs still show invalid as shown in the table.
There is also the masterForm object which does contain each input name object. In the form object there are also masterForm.$error objects which are the same as the input.$error objects, but just that ALL the form $error objects are gathered together. I have also tried to change these values, which does happen to the inputs I wanted to change, but the form is still invalid.
I have also tried to ng-if each row, meaning I removed them on submit if they didn't meet requirements, but still the form see's them and states the form is still invalid.
Even though I can setValidity for each input, the form does not care. Is this because I have to change the $error state in the form AND the input object? Shouldn't they change state together?
Is this just because I'm using 1.3-beta.8?
Is there an easier way to to this?
Could I have more control using the $validators pipeline available in 1.3-beta.12+?
There is no need for code as I have none that works. If you know how to do this please provide YOUR example.

Related

(Django) how to submit a form with empty fields?

I have a form with a drop down list with two options ("MCQ" and "SEQ") and some fields. Selecting "MCQ" would hide fields used by "SEQ" and vice versa. I want to submit this form but the "please filled out this field" notice pops up. What should I do to submit this form?
I've searched around Stack overflow before looking possible solutions, some suggested placing "required" or "disabled" beforehand, however I would like a dynamic way of doing if possible but based it on which option the user selects since the user might leave everything empty and just submit if nothing is required.
Additional Information:
I'm using forms.ModelForm, the fields came from there.
I'm using js to hide and show the relevant fields.
I Appreciate any help/suggestions. :)
Your model should not define those fields as required, this way they can be empty when the form is validated:
class MyModel:
my_field = models.CharField(blank=True, null=True, length=500)
...
blank=True will tell your forms not return an error if this field is empty

Get Input Field value using DTM on Submitting a form

I have two input fields that had the user access card and password. and the user click on submit button to authenticate.
I'm using DTM in my app to capture the user navigation but I want also to get the values of those field to my DTM so I would know who the user is.
And here is what I tried but with no luck.
Created Data element as below:
And created Event based rule. But not sure how to get the values to be shown in my report:
Thanks for your help.
Example Form
Since you did not post what your form code looks like, here is a simple form based on what I see in the screenshots you posted, that I will use in my examples below.
<form id='someForm'>
User Name <input type='text' name='userName'><br>
Password <input type='password' name='userPass'><br>
<input type='submit' value='submit' />
</form>
Data Elements
Okay first, let's go over what you did wrong.
1) You said you want to capture two form fields, but you only have one data element...maybe? You didn't really convey this in your question. I just assumed as much because of what you did throughout the rest of the screenshots. But to be clear: you should have two separate data elements, one for each field.
2) The CSS Selector Chain value you used is just input, so it will select the first input field on the page, which may or may not coincide with one of the input fields you are looking to capture. So, you need to use a CSS selector that is unique to the input field you want to capture. Something as simple as input[name="userName"] will probably be good enough (but I cannot confirm this without seeing your site). You will need to do the same for the 2nd Data Element you create for the other input field (e.g. input[name="userPass"])
3) In the Get the value of dropdown, you chose "name". This means that if you have for example <input type='text' name='foo'>, it will return "foo". Since you want to capture the value the user inputs, you should select "value" from the dropdown.
Solution
Putting all the above together, you should have two Data Elements that look something like this (one for the user name field and one for the password field; only one shown below):
Event Base Rule
Okay first, let's go over what you did wrong.
1) The value you specified in Element Tag or Selector is input. You aren't submitting an input field; you are submitting a form. Input fields don't even have a submit event handler! Your Event Type is "submit", so at a minimum, Element Tag or Selector should be form. But really..
2) Ideally, you should use a CSS Selector that more directly and uniquely targets the form you want to trigger the rule for. For example, maybe the form has an id attribute you can target in your CSS Selector. Or maybe the form is on a specific page, so you can add additional conditions based on the URL. What combination of CSS Selector or other conditions you use to uniquely identify your form depends on how your site is setup. In my example form above, I added an id attribute, so I can use form#someForm as the CSS Selector.
3) You checked the Manually assign properties & attributes checkbox, and then added two Property = Value items. This tells DTM to only trigger the rule if the input has a name attribute with value of "userName" AND if it has a name attribute value of "userPass". Well name can't have two values at the same time, now can it!
<input name='foo' name='bar'> <!-- bad! -->
All of this needs to be removed, because again (from #1), you should be targeting a form, not an input field.
4) For good measure, looks like you added a Rule Condition of type Data > Custom, but the code box is empty. The rule will only trigger if the box returns a truthy value. Since there is no code in the box, it will return undefined (default value returned by a javascript function if nothing is returned), which is a falsey value. This also needs to be removed.
Solution
Putting all the above together, the Conditions section of the Event Based Rule should look something like this:
But again, ideally your conditions should be more complex, to more uniquely target your form.
Referencing the Data Elements
Lastly, you can reference the input fields to populate whatever fields in the various Tool sections with the %data_element% syntax. For example, you can populate a couple of Adobe Analytics eVars like this (data element names reflect the examples I created above):
Or, you can reference them with javascript syntax in a custom code box as e.g. _satellite.getVar('form_userName');
Additional Notes
1) I Strongly recommend you do not capture / track this type of info. Firstly, based on context clues in your post, it looks like this may count as Personally Identifiable Information (PII), which is protected under a number of laws, varying from country to country. Secondly, in general, it is a big security risk to capture this information and send it to Adobe (or anywhere else, really). Overall, capturing this sort of data is practically begging for fines, lawsuits, etc.
2) Note that (assuming all conditions met), the "submit" Event Type will track when the user clicks the submit button, which is not necessarily the same thing as the user successfully completing the form (filling out all the form fields with valid input, etc.). I don't know the full context/motive of your requirements, but in general, most people aim to only capture an event / data on successful form completion (and sometimes separately track form errors).

Enable ASP.Net validator without immediately running validation

Question
Can I enable an ASP.Net validator without running validation immediately (i.e. giving the user a chance to input values before running it, but still force running validation on form submit)?
Background
I have a form that allows a person to input their family data when they check in their child(ren) into a public daycare system. We have five fields that I need to force parents to actively consider (allergies, special needs, etc). The values are not actually required, so too many parents were just skipping over the fields when their children should have had values specified.
My solution is to have a required field validator that's disabled if they click an N/A checkbox next to the textbox. (If someone has a better solution, I'm all ears; the UI of this form--which I inherited--makes me want to gouge out my eyes.)
The other thing is that when the "Add Family" button is clicked, four empty rows are auto-generated: two adults and two children. Whether a row represents a child or an adult is determined by a drop-down in that row. If "adult" is selected, or if the first name textbox in that row is empty, the validators are disabled.
The validators of all five fields are enabled as soon as both the drop-down selected value is "child" AND the first name textbox is not empty. The issue is that running ValidatorEnable() causes the form to validate. In the common case, the fields will be empty, since first name and "family role" (adult/child) will be inputted before whether that person has allergies or are potty trained. This means as soon as they input the name into a row specified as child, ASP.Net's all like "HEY, DUMMY, YOU HAVE AN INVALID FIELD!!!1!".
So, I would like to enable the validator, but prevent validation until the user actually either inputs an empty value into the allergy textbox, or they try to submit the form.
Is this possible?
Note, I would use a custom field validator, but validation isn't run on empty fields; afaik, only required field validators do that.
I've just adapted the answer here: http://veskokolev.blogspot.co.uk/2007/11/how-to-disable-validation-group-with.html to enable some validators client-side with jQuery. Once they were enabled, the validation function did run - I don't know how to stop it (without modifying the ASP.NET JS code, which I guess is an option?); so I simply hid the messages until the validation is run again (which is easy enough with $(x).hide()).
Considering all the client-side code does is show the warning and stop you submitting I think this is OK. The usual things that will cause the validator to re-run will re-show the message.
So if I have validators like:
<asp:Validator runat="server" CssClass="js-validator-set-a" />
I can use this Javascript:
toggleValidators('.js-validator-set-a', true);
function toggleValidators(selector, enable) {
// get the page validators into a jQuery object
var vals = getJqueryObjectFromArrayOfEls(Page_Validators)
vals.filter(selector).each(function (i, o) {
ValidatorEnable(o, enable);
$(o).hide();
});
};
function getJqueryObjectFromArrayOfEls(elsArray) {
var x = $();
$.each(Page_Validators, function (i, o) {
x = x.add($(o));
});
return x;
}
I just came across a similar requirement. WhatI did was first to set a valid value to the compnent to be validated, then enable the validator and finally I cleared the value in the component again. Something like
$('#<%= tbxValue.ClientID %>').val('X'); // set a value to the textbox
ValidatorEnable(<%= rfvValue.ClientID %>, true); // enable the required field validator
$('#<%= tbxValue.ClientID %>').val(''); // clear the value from the textbox
Yes, it's possible in a variety of ways. The two most common and perhaps sensible things to do are :
Have validation occur completely in the code-behind via code only
Have ASP.NET validators that are set to enabled=false and then turn them on and call Page.Validate()
Instead of using that function, you can make your own function that has some of the same code as ValidatorEnable, but wont trigger the validation.
function myValidatorEnable(val, enable) {
val.enabled = (enable != false);
}

Jquery Validation Plugin - Fields still producing errors

I have a checkbox field which determines whether the proceeding client ID field has an attribute of data-validate required:true, or data-validate required:false which drives my forms validation.
<input type="text" name="stID" id="stID" data-validate="required:true" />
Using jquery i can change the requirement in real-time, along with show/hide and add/remove the error classes associated with that field.
$("#input[name='stID']").attr("data-validate","required:false");
var form=$("#standard");
form.validate().resetForm();
The issue lies when someone tries to submit the form, then changes the initial checkbox option (if true, ID isn't required otherwise if false, ID is required).
When this happens, despite the data-validate required:false being set and the error classes being hidden, the validation is still occurring and flagging the stID field.
Does the jquery validator plug in have a cache/array of fields which resulted in errors that it determines on submit and possibly isn't being cleared/reset when the resetForm function on our validation is called?
Found the solution, still needed to clear the data attribute associated with these fields producing errors after changing its requirement. This was done by
$("#stID").removeData();

Jquery validation engine ajax, two fields same function?

The jQuery validation engine plugin has the ability to do ajax validation; which works gret except for one small catch...
It sends off the field ID instead of the field name to be validated.
Why is this an issue?
I have a simple item that to create it only requires one textbox to be filled out; so we have this as a modal on every page for managing said item.
We use the jQuery validation engine plugin to validate that the entered value is unique.
Now this also means that the modal shows up on the edit page. Which obviously has the title in a field as well for you to edit.
And we want this field to be validated as well but because the validation engine sends across the field ID instead of the field name we must give the two fields different ID's
e.g. createtitle and edittitle and then on the backend have
if($fieldId == 'createtitle' || $fieldId == 'edittitle'){$fieldId = $fieldId}
Which really is an ugly approach; is there any way to get it to use the name; or another attribute instead?
Maybe this plugin could help you. It uses class names of your element to validate.

Categories