Angular2 Form : trigger or update validation properly & programmatically - javascript

I'm building a Wizard in Angular2 - Redux. I'm using Reactive Forms to handle & submit data for every step inside. I need to trigger form validation programmatically, because the declaration of my call-to-action button, in order to go to the next step, is in a separated component from the stepComponent. See wireframe below
Components's wireframe
Current Behavior
Only when a change has ocurred on a form's control, its own validation
runs. And it's touched & valid property is updated accordingly.
As I am in a Redux environment, I dispatch an action to get the
current-step form data in order to be applied to the payload. When
that's is finished, I trigger another action to save data.
Actually, I know when the form is valid or invalid by using:
submitForm(form: FormGroup):void{
if(form.valid){
this.actionsStep.saveStep(form.value);
}else{
console.log('Form invalid ')
}
}
As my forms uses controls's properties to render a custom message
when a error has happened, I want to re-run validation
by submit the form or by using another function to be able to use
the control's properties again to notify where an error has occurred.
StepComponent.ts : Form declaration
this.stepForm = this.formBuilder.group({
name: ['', Validators.required],
email: ['', Validators.required]
});
step-component.html : Form HTML
<form id="ngForm" [formGroup]="stepForm" (ngSubmit)="submitForm(stepForm.value)" class="form-horizontal form-box-content">
<div class="form-group row" [ngClass]="{'has-danger' :name.invalid && name.touched}">
<label class="col-md-2 col-form-label">Name:</label>
<div class="col-md-10">
<input
name="titulo" class="form-control required"
formControlName="name" placeholder="" type="text" [ngClass]="{'form-control-danger' :name.invalid && name.touched}" >
<small class="form-control-feedback text-danger" *ngIf="name.invalid && name.touched && name.hasError('required')">
The name is required
</small>
</div>
</div>
Attemps
I tried to use
Update Validity:
this.stepForm.updateValueAndValidity();
Update Validity providing params:
this.stepForm.updateValueAndValidity({ onlySelf: false, emitEvent: true });
Mark each control as touched (To trigger event as I've typed something)
for (var i in this.stepForm.controls) {
this.stepForm.controls[i].markAsTouched();
}
The solutions which requires submit function to be called from the HTML
will not work for me because the button and the form are in separated components.
5. Is there any way to trigger or update validation programmatically or at least to submit a form properly in a function?
Previous Research
I found many help links to achieve this, however,those solutions work only when the button is declared in the same component. And also, when button is inside the form tag:
Angular2 - Validate and submit form from outside : Work only in
the same component
angular2 validate form on button click : Work only in the same component
Angular 2 Submit button outside of form : Not working
Is there a way to
submit an Angular 2 model-driven form (reactive form) from a outside
button? : Refers to previous link

I basically had the same setup, and got around it by doing the equivalent of
(this.stepForm as any).submitted = true

In case someone else is still trying to do this. I did this by using ViewChild to grab references to the referenced components and stepper. Then control the next button click and do not have matStepperNext on the button.
<button mat-button (click)="onStepOneNextClick()">Next</button>
#ViewChild(MatStepper) stepper: MatStepper;
#ViewChild(StepOneComponent, { static: true }) stepOneComponent: StepOneComponent;
onStepOneNextClick() {
if (this.stepOneComponent.form.invalid) {
this.stepOneComponent.form.markAllAsTouched();
}
else {
this.stepper.next();
}
}

Related

How to show a warning sign while building a form in html5?

I have a form as shown below in which I placing an alt text which will display on the webpage.
<form action="/action_page.php">
Alt <input type="text" name="e1_alt" required>
<input type="submit">
</form>
The form here will not save because I have used the required field in it. What I want to achieve is that a warning sign should be displayed if it is empty but it should not stop the user from saving it.
Problem Statement: I am wondering what changes I should make in the HTML code above or JavaScript code I need to add so that a warning sign should be displayed if it is empty
but it should not stop the user from saving it.
You can't really do it purely in HTML. Javascript would need to handle the validation. HTML5 forms will not submit if you have a required field empty, since that's how the browsers handle them. You could add novalidate to the form as an attribute, but you'd still need to have some javascript to handle showing the 'warning sign
Here is a working fiddle to show you how you might go about using JS to show the warning:
$('[name="e1_alt"]').blur(function(e) {
var value = $(e.currentTarget).val();
if (value.length === 0) {
$('.error').show();
}
});

How to check the condition and pass extra parameter to the semantic-ui search?

I am working in a search module. I have a text field of class UI & search. When I start to type it will call this URL and get the result.
Now I have a new requirement. When I start to type I want to check the condition. If that condition is true then I want to pass a new parameter to this URL and if the condition is false then continue the process.
I am trying to find out how to check the condition in below function before calling URL and passing the params.
HTML
<div class="ui search">
<input class="prompt" type="text" placeholder="Search Here....">
<i class="search icon"></i>
</div>
</div>
JS
$('.ui.search').search({
apiSettings: {
url: '/api/v2/demo/suggest?q={query}',
onResponse: function (res) {
console.log("res", res);
Any help will be appreciated. Thank You.
I think you can do using Behaviors of Form Validation
$('.foo').form('behavior name', argumentOne, argumentTwo)
Validating Programmatically
Form validation provides additional behaviors to programmatically trigger validation for either the form or an individual field, and check validation on the form or individual fields.
https://semantic-ui.com/behaviors/form.html#behaviors

Use form data to update web page

Before I provide a bunch of code I'd like to first find out if what I'm trying to do is even possible.
I've created a web based version of the dice game called PIG using HTML & JavaScript. The user can change some of the game's settings by clicking on a "Settings" button on the main page. This button brings up a modal window containing an HTML form (). I'd like to use the data that the users enters and submits on this form to update various settings on the game's main page.
I chose to use an HTML5 form because was hoping to use the native HTML5 form validation capabilities rather than try and replicate that validation checking logic myself using JavaScript.
So my approach was to use javascript to get the data off the form on submit. I tried two different approaches to get this to work:
1) Using an "onsubmit=function getSettings()" on the tag
2) Using a submit button for the form with an onclick="getSettings()".
With both of these approaches I was able to successfully get all the values from the form on submit and use those values to successfully populate the main game page using the gettSettings() function however when I exit the getSettings() function the webpage values that I updated don't stick...they revert back to the original values regardless of which of these two approaches I use.
I know the values were successfully updated because when I set a break point on the last statement of the getSettings() method I can see that all of the values on the main page have been updated to reflect what was filled in on the form...so I know I'm grabbing all of the data successfully and updating the main page with those values.
I'm puzzled as to why the values that I successfully change on the web page simply revert back to their original value upon exit of the getSettings() function.
Maybe it's just not possible to do what I'm trying to do? And if not does anyone know why given I can see the values are successfully changed before they revert back to their original value. What am I missing?
Again I'm using a Form and collecting the data on submit so that I can leverage the "native" HTML5 form validation capabilities.
Regards.
***** EDIT TO ADD KEY SEGMENTS OF CODE *******
Here is the code HTML Code for the modal form:
<form name="config-settings" onsubmit="getSettings()">
<!-- <form name="config-settings">-->
<span class="errMsg"></span>
<div class="row clearfix">
<div>
<label>Player 1:</label>
</div>
<div>
<input type="text" name="input-name-0" id="input-name-0" maxlength="10" placeholder="Enter name" pattern="^\S+$">
</div>
</div>
<div class="row clearfix">
<div>
<label>Player 2:</label>
</div>
<div>
<input type="text" name="input-name-1" id="input-name-1" maxlength="6" placeholder="Enter name" pattern="^\S+$">
</div>
</div>
<div class="row clearfix">
<div>
<label>Winning Score:</label>
</div>
<div>
<input type="number" name="winning-score" id="winning-score" default="100" placeholder="Enter winning score">
</div>
</div>
<div class="row clearfix">
<div>
<label>Number of Dice:</label>
</div>
<div>
<select name="diceValues" id="dice-value">
<option value=""> - Select - </option>
<option value="dice-1">One Dice</option>
<option value="dice-2">Two Dice</option>
</select>
</div>
</div>
<!-- Below is alt method I used to submit form..yields same results -->
<!-- <input type="submit" value="Submit" onclick="getSettings()">-->
<input type="submit" value="Submit">
</form>
Here are the global variables defined and used in getSettings() method:
// Global variables
var scores, roundScore, activePlayer, gamePlaying, gamesWonCount, playerNames, winningScore, numOfDice, matchScore, msgs;
var player0, player1, score;
var player0Field = document.getElementById('name-0');
var player1Field = document.getElementById('name-1');
var scoreField = document.getElementById('winScore');
Here is the listener for the Settings button on the main web page that brings up the setting modal window containing the settings form:
//*********************************************************
// Open Settings Modal Windows
//*********************************************************
document.querySelector('.btn-settings').addEventListener('click', function () {
// Settings can't be changed if game is actively underway
if (!gamePlaying || roundScore === 0) {
document.querySelector('#modal-settings').style.display = 'block';
} else {
// Make error message visible
msgs.style = 'block';
// Create message to indicate settings successfully updated
msgs.textContent = "Settings can't be updated during game";
msgs.style.backgroundColor = 'pink';
fadeOut(msgs);
}
});
Here is the getSettings() javaScript function (note: there are no local variables defined in this function...they are all defined as global values (first few lines of javaScript app).
function getSettings() {
// Alternative call if I want this function to be called via eventListner
//document.querySelector('.btn-save').addEventListener('click', function () {
console.log("getSettings method called");
player0 = document.forms["config-settings"]["input-name-0"].value;
player1 = document.forms["config-settings"]["input-name-1"].value;
score = document.forms["config-settings"]["winning-score"].value;
// Reset msgs so they will be displayed each time
msgs.style = 'block';
playerNames[0] = player0;
player0Field.innerHTML = playerNames[0];
playerNames[1] = player1;
player1Field.textContent = playerNames[1];
// Set Winning score on UI to value on form
scoreField.textContent = score;
// numOfDice = document.getElementById('dice-value').value;
// Create message to indicate settings successfully updated
msgs.textContent = "Successfully updated settings";
msgs.style.backgroundColor = 'lightgreen';
fadeOut(msgs);
document.querySelector('#modal-settings').style.display = 'none';
}
I don't know exactly what this getSettings() function of yours is supposed to do, but I can try to give you a piece of advice:
Some of the form validation capabilities of HTML5 are not entirely supported on all of the used browsers(some users don't fancy to update their browser). Therefore relying on the "native" validation of HTML5 isn't exactly best practice.
If you want to manipulate the form values in any way before submitting the form I would rather add a listener to the submit button for click events, prevent any other action, make the checks/ manipulation of the form data and then manually submit the form. Anyways, front-end validation isn't entirely safe, so if you're peddling sensitive data it's mandatory that you'll make checks on serverside(if your app uses a server).
To exemplify what I've explained earlier:
document.getElementById("myBtn").addEventListener("click", function(event){
//Stops the form submitting.
event.stopImmediatePropagation();
//Do the checks here.
//Sends the form.
document.getelementById("myForm").sumbit();
);
If you change local variables inside this getSettings() function, the variables will be changed only within the function scope. You might want to read about scope in javascript. (this was just an educated guess).
I hope you find this useful, good luck!
Okay...I finally figured it out! The problem was not a scoping problem but instead and issue with how "onSubmit" works.
The solution involved making two changes:
1) Adding a return statement to the "onsubmit" attribute when calling the "getSettings()" function;
<form name="config-settings" onsubmit="return getSettings()">
2) Returning false at the end of the gettSettings();
return false;
Note: I had previously tried returning true but not false. I was errantly under the impression that returning false value from getSettings() function would disable HTML5 "native" validation and force me to implement all of the error checking myself...which was not what I wanted. It is now my understanding that returning false merely prevents the form from being submitted..but it doesn't disable the HTML5 native validations.
This solution worked perfectly for me because my goal was not to submit the form to the server (as there is no server component here) but merely to use the "native" HTML5 form checking and then update the values on the local web page.
With all of that said I'm still not entirely sure why when I didn't provide the return statement or when I returned true why all of my changes reverted back to their originally value. If anyone can shed some light on why I'd appreciate it.
Cheers

AngularJS: How can I $setPristine after submit the form

I want some input element be $setPristine when I submit the form. Because after I submit the form, I would empty the model bind to the input element, in case of user can totally input something new again. But once I empty the model, the input element would empty too, so the validate information would show, for required.
So I want $setPristine after submit the form. I figure out two ways:
One:
I use expression in the ng-submit, like:
<form ng-controller="FormController" name="userForm" ng-submit="userForm.$valid?submitForm(),userForm.keywordsInput.$setPristine(): ''">
But this syntax seems wring because angular report error information in the console.
Two
I could pass form to the submit function, then $setPristine in the submit function :
$scope.submit = function (form) {
form.keywordsInput.$setPristine()
}
But I also don't this is a good practice, because in the angular official reference site, it suggest:
Do not use controllers to:Manipulate DOM.
Is this way a kind of manipulating DOM?
So is there a better way to achieve this job?
I had the same issue logging undefined $setPristine(). But,in the view it works.
<button class="button button-stable button-block " type="submit" ng-click="register(registerData);formName.$setPristine();"> Submit </button>
When you submit the form, you must have set some function to run in the "ng-click" attribute
Add formName.$setPristine(); after it

MVC3: Clicking a submit button to submit a form does not render partial view

Ok here is the deal: Im using BeginRouteForm to submit a search. Anyway, when the button is not set to submit and I click the button, it runs the search just fine and it behaves as it should, meaning that the content is rendered properly. When the button IS set to a type of submit and the button is clicked, the content that is returned is simply some text and the HTML is not rendered at all.
It is important to note that the controller is attempted to return a partial view that is using javascript to replace some of the content using ajax (this means the content type is 'text/javascript').
Controller Method:
public ActionResult Search()
{
[Do Some Work]
return JsView("Index.js");
}
JsView("Index.js") just sets the content type to 'text/javascript' and returns the partial view that coincides with the parameter that was passed
Form Snippit:
<div style="float:right;">
#using (Html.BeginRouteForm(ControllerActionName, SearchRouteValues, FormMethod.Get, new { id = "worklistSearch" }))
{
<input type="text" placeholder="Search Cases" id="SearchCriteria" name="SearchCriteria" value="" />
<input class="search image-button no-text filter" value="Filter" id="worklist-search-button" />
}
</div>
PS: I seem to need to make the button a type of submit in order to get the form to submit using the enter key.
I would like to know how I can make this work so that it renders the view properly and allows me to click the submit button.
Based on your description, it appears that you want to capture the submit event for your form, then make your AJAX call to your controller. If this is what you want, you then need to prevent the submit event from propagating, so that no POST occurs.
Using jquery, do something like this:
$("form").submit(function() {
// make AJAX submission to controller
// process JS returned from controller
// stop submit event from propagating
return false;
});

Categories

Resources