clearvalidators not working in angular 6 form control - javascript

I have two form group names like below. Sometimes one form is not shown to user. When both are shown I have no issues. And I have a button which is visible when the form is valid.
<div
*ngIf="showPersonalInfo"
class="personalInfo"
formGroupName="personalInfo"
>
<div
*ngIf="showFamilyInfo"
class="familyInfo"
formGroupName="familyInfo"
>
<button
*ngIf="InfoForm.valid"
class="submitButton"
</button>
And I initialize my form using below code.
this.InfoForm = this.formBuilder.group({
personalInfo: this.getPersonalInfo(),
familyInfo: this.getFamilyInfo(),
});
The code in this.getFamilyInfo() will set showFamilyInfo to true or false and it initializes the form in both the cases otherwise my html throws familyInfo is not found.
One of our service sometimes looks for the member profile and pulls existing family info/personal info and fills the model and sets showPersonalInfo/showFamilyInfo to true.
when showFamilyInfo is false my InfoForm.FamilyInfo form control is showing as invalid. To avoid this error i am clearring validators using below code but it still shows the familyInfo form control status invalid. My PersonalInfo is valid though.
How can ignore everything related to FmilyInfo when showFamilyInfo is false so the button will be visible.
this.InfoForm.get('familyInfo').clearValidators();
this.InfoForm.get('familyInfo').updateValueAndValidity();

I think you need to clear the errors before you can update the Validity. In the linked post, the answer by Julia P. covers how to clear the errors. Then you run updateValueandValidity. How can I manually set an Angular form field as invalid?

I had the same issue, in my case, the code setErrors(null) solved the problem.
Try to do this:
this.InfoForm.get('familyInfo').clearValidators();
this.InfoForm.get('familyInfo').setErrors(null);
this.InfoForm.get('familyInfo').updateValueAndValidity();

Related

Angular, required check on controller throughout multiple forms

I am trying to find a simple solution to a required input type of scenario. I have multiple small forms that all send on one button save on the bottom of the page. What I am trying to accomplish is something like ngRequired, however across the whole controller, not just the individual forms. So the desired effect is pretty simple - if any of the inputs aren't filled out - set a boolean( or something) to false that disables the save button at the bottom.
So my first attempt is like this -
I have a model on each of the required items - there are 10 items
then I have a function that checks when you try to click the button how many are chcked like this
if($scope.modeltracker1){
//if there is anything inside model 1 add 1 to the tracker
$scope.modeltracker += 1;
}
and if the counter is not 10, don't do anything (all required are not filled out)
if($scope.modeltracker != 10){
//do nothing because all required are not filed out
}else{
//run save, all required all filed out
}
So - I feel like there should be a much easier solution than my first attempt here. Maybe something along the lines of checking if any individual one of these required fields is false, don't fire? I know that ngRequied would be great for this, but unfortunately the way this has to be structured, it cannot be one large form. There has to be a much easier way to accomplish this task with angular.
Any input would be much appreciated, thanks for reading!!
You can use ng-form to nest your multiple forms. It allows using nested forms and validating multiple forms as one form.
So, you need to nest your multiple forms in one root form.
<div ng-controller="demoController">
<form name="parentForm">
<ng-form name="firstForm">
<input type="text" ng-model="firstModel" required>
</ng-form>
<ng-form name="secondForm">
<input type="text" ng-model="secondModel" required>
</ng-form>
</form>
</div>
Then, all you need to do is to check parent form's validation status.
angular.module('formDemo', [])
.controller('demoController', ['$scope', function($scope) {
if($scope.parentForm.$valid) {
//run save, all required all filed out
} else {
//do nothing because all required are not filed out
}
}]);
you can use myForm.$invalid directive, as explained here: Disable submit button when form invalid with AngularJS

Issue in using checkbox in sign up form in Codeigniter

My sign up form was previously working well. However, I had to add an acceptance page or terms and conditions before sign up can be successful. I thought it would be better to include it in sign up page rather than after sign up (before being presented with member's homepage). Problem is, it's having a lot of issues. It's not working properly.
Here's my code in view page: (i added this at the bottom of all fields before sign up button)
Please proceed only if you accept our <a target="blank" href="<?php site_url("in/terms_and_conditions");?>">terms and conditions</a>.
<input type='checkbox' name='terms' value='checked' id='terms' required autofocus/><br/>
Right now, it seems to work fine (codeigniter built in validation prompts up a message telling the user to click before he can proceed). Issue is 1. the link ("in/terms_and_conditions") does not show properly. Whenever the corresponding text is clicked, instead of showing the proper page, it just opens up a new sign up page.
Second issue is the presence of errors as follows:
Message: Undefined index: c_terms in model Line Number: 24
Line 24 is this:
'terms'=> $post_obj['c_terms']
I tried to add this to my array. Was it actually correct?
The second error shown is:
Column 'terms' cannot be null
INSERT INTO `client` (`first_name`, `last_name`, `email_address`, `password`, `address`, `tagline`, `profile`, `interests`, `billing_mode`, `terms`) VALUES ('dsfhkds', 'hfdskhflk', 'test#yahoo.com', '123456', 'fsdkfhsdk', 'sdkfhsdkf', 'sdklhfslkdhflsdhf', 'kdslhflks', 'Escrow', NULL)
What I did to my original table is I added column which I named "terms", set it to text type and no default value.
Please help me fix this.
Thanks!
Issue 1:
Did you create the page "in/terms_and_conditions" ? make sure?
Controller Name: in
Action Name : terms_and_conditions
Issue 2:
You have named checkbox as "terms". then, you should get the posted value as follows
'terms'=> $post_obj['terms']
Issue 3:
Set "terms" column default value as "NULL"
I see three problems:
You're not echoing the result of the site_url function. Just put echo in front of it.
If $post_obj is your '$_POSTarray you have to use thename` attribute of the HTML input as the key:
'terms' => $post_obj['terms']
Your problem is that you're not setting any text to be saved in terms. Add it to the second parameter of $this->db->insert('table', $data) like this: $data['terms'] = '...'

KnockoutJS: Posting only visible form elements

I have just started using Knockout.js My form has elements which I call questions. I hide/show them based on user selections. When user hits the submit button I want to post only the visible questions at the time of submit. What I have is this:
// length of Results(questionArray) is 260
var vmToPost = viewModel;
delete vmToPost.__ko_mapping__;
ko.utils.arrayForEach(vmToPost.Results(), function (question) {
if (!(vmToPost.getQuestion(question.QuestionID()).visible())) {
ko.utils.arrayRemoveItem(vmToPost.Results(), question);
}
});
The util function arrayForEach is behaving strange. It loops through the array very differntly. I had to hit the submit button 7 times to get all the visible elements and come out of the util function. It doesnt throw any error message in the console or the fiddler.
What am I doing wrong. Please help.
Html contains a built-in way to skip items from being submitted. It's the disabled attribute, which can be controlled using Knockout with the enable or disable bindings.
<div data-bind="visible: visible">
<label>Name: <input name="name" data-bind="enable: visible"></label>
</div>

Disabling form password autocompletion but not other fields

I know you can disable the autocomplete on a form by setting autocomplete="off" on the form itself.
The problem I have is, I want to prevent the browser from populating the password field but do not want to disable username or other fields.
The other thing to consider is legacy data. Using autocomplete="off" on the form (or even the field itself) does not prevent existing users with saved passwords from getting a free-pass. Or ones that use web inspector, change the value of autocomplete and submit, allowing themselves to save the password.
I know it is possible to change the password field name attribute to a random/new one on every visit. Regretfully, I am working with a java/spring back-end and I am being told this is NOT easily manageable without a huge refactor/override.
How would you architect this? How would you enforce that the field always starts empty? There is no consistent way for browsers to event notify you of pre-population by a password manager - some may fire an onChange, others may not.
I guess I can move fields around with javascript and build the real form on the fly and submit it but once again, this will have implications with spring security and validations etc. Any other ideas?
you can made a temp variable when onFocus is call to set a variable to true ( like userFocus )
and on the onChange attribut but a short code for reseting "value" to NULL if userFocus== false) kind of overkilling imo but migth work
EDIT
function reset()
{
if (document.getElementById("hidden").value!=" ")
{
document.getElementById("demo").value=" ";
}
else;
}
function getfocus()
{
document.getElementById("hidden").value=" ";
}
else;
}
<input type="password" id="pwd" onchange="reset()" onfocus="getfocus()"/>
<input type="hidden" id="hidden" value="not focus"/>
I had to find this solution for IE 11 (since it ignores the autocomplete attribute). It works fine in other browsers. Really more of a work around, but it works.
https://stackoverflow.com/a/20809203/1248536
I was recently faced with this problem, and with no simple solution since my fields can be prepopulated, I wanted to share an elegant hack I came up with by setting password type in the ready event.
Don't declare your input field as type password when creating it, but add a ready event listener to add it for you:
function createSecretTextInput(name,parent){
var createInput = document.createElement("input");
createInput.setAttribute('name', name);
createInput.setAttribute('class', 'secretText');
createInput.setAttribute('id', name+'SecretText');
createInput.setAttribute('value', 'test1234');
if(parent==null)
document.body.appendChild(createInput);
else
document.getElementById(parent).appendChild(createInput);
$(function(){
document.getElementById(name+'SecretText').setAttribute('type', 'password');
});
};
createSecretTextInput('name', null);
http://jsfiddle.net/N9F4L/

Clear default values using onsubmit

I need to clear the default values from input fields using js, but all of my attempts so far have failed to target and clear the fields. I was hoping to use onSubmit to excute a function to clear all default values (if the user has not changed them) before the form is submitted.
<form method='get' class='custom_search widget custom_search_custom_fields__search' onSubmit='clearDefaults' action='http://www.example.com' >
<input name='cs-Price-2' id='cs-Price-2' class='short_form' value='Min. Price' />
<input name='cs-Price-3' id='cs-Price-3' class='short_form' value='Max Price' />
<input type='submit' name='search' class='formbutton' value=''/>
</form>
How would you accomplish this?
Read the ids+values of all your fields when the page first loads (using something like jquery to get all "textarea", "input" and "select" tags for example)
On submit, compare the now contained values to what you stored on loading the page
Replace the ones that have not changed with empty values
If it's still unclear, describe where you're getting stuck and I'll describe more in depth.
Edit: Adding some code, using jQuery. It's only for the textarea-tag and it doesn't respond to the actual events, but hopefully it explains the idea further:
// Keep default values here
var defaults = {};
// Run something like this on load
$('textarea').each(function(i, e) {
defaults[$(e).attr('id')] = $(e).text();
});
// Run something like this before submit
$('textarea').each(function(i, e){
if (defaults[$(e).attr('id')] === $(e).text())
$(e).text('');
})
Edit: Adding some more code for more detailed help. This should be somewhat complete code (with a quality disclaimer since I'm by no means a jQuery expert) and just requires to be included on your page. Nothing else has to be done, except giving all your input tags unique ids and type="text" (but they should have that anyway):
$(document).ready(function(){
// Default values will live here
var defaults = {};
// This reads and stores all text input defaults for later use
$('input[type=text]').each(function(){
defaults[$(this).attr('id')] = $(this).text();
});
// For each of your submit buttons,
// add an event handler for the submit event
// that finds all text inputs and clears the ones not changed
$('input[type=submit]').each(function(){
$(this).submit(function(){
$('input[type=text]').each(function(){
if (defaults[$(this).attr('id')] === $(this).text())
$(this).text('');
});
});
});
});
If this still doesn't make any sense, you should read some tutorials about jQuery and/or javascript.
Note: This is currently only supported in Google Chrome and Safari. I do not expect this to be a satisfactory answer to your problem, but I think it should be noted how this problem can be tackled in HTML 5.
HTML 5 introduced the placeholder attribute, which does not get submitted unless it was replaced:
<form>
<input name="q" placeholder="Search Bookmarks and History">
<input type="submit" value="Search">
</form>
Further reading:
DiveintoHTML5.ep.io: Live Example... And checking if the placeholder tag is supported
DiveintoHTML5.ep.io: Placeholder text
1) Instead of checking for changes on the client side you can check for the changes on the client side.
In the Page_Init function you will have values stored in the viewstate & the values in the text fields or whichever controls you are using.
You can compare the values and if they are not equal then set the Text to blank.
2) May I ask, what functionality are you trying to achieve ?
U can achieve it by using this in your submit function
function clearDefaults()
{
if(document.getElementById('cs-Price-2').value=="Min. Price")
{
document.getElementById('cs-Price-2').value='';
}
}

Categories