angularjs: trigger form validate programmatically (inside a controller) - forms

I have this situation in which I show 1 form in two steps. So to proceed to the second part of the form you have to click on a button. But before moving on I would like to perform form validation (all required fields need to be filled in). But because this is a normal button, the whole submit magic is not triggered and the validation does not happen. So the question I'm interested in is how can I trigger form validation in my controller ? It would even be better to trigger validation for specific fields. Just to give an idea, the form looks like
<form name="form" submit="save()">
<section id="step1">
<label for="username" required>Username</label>
<input type="text" name="username" ng-model="user.username" required />
.....
<button ng-click="proceed()">Proceed</button>
</section>
<section id="step2">
<label ...></label>
<input...>
....
<button type="submit">Save</button>
</section>
</form>
Also, I don't want to opt for disabling the button until all required fields are valid.

Take a look at the ng-form directive. It allows nesting forms (actually not HTML <form>s, but Angular NgFormControllers). So you can split your one form, used for posting to the server, into two logical forms, used for independent validation:
<form submit="save()">
<div ng-form="form1">
...controls...
<button ng-click="proceed()"
ng-disabled="form1.$invalid">Proceed</button>
</div>
<div ng-form="form2">
...controls...
<button type="submit"
ng-disabled="form2.$invalid || form1.$invalid">Submit</button>
</div>
</form>

You can access the $valid property from your controller. Something like this could work.
$scope.proceed = function(){
if($scope.form.username.$valid){
//username is valid we may proceed to the next step
}
};

<button ng-click="proceed()">Proceed</button>
Replace To :
<button ng-click="proceed()" ng-disabled="form.$invalid">Proceed</button>
Button will not visible button until all required fields are valid.
DEMO

Related

Input Group prepend - Bootstrap - can a reset button be included on the side of the input?

I have an input with a prepend from Bootstrap, looks nice and modifiable. I know I can put another button on the other side, but can that button be a reset? I have tried multiple things. Here is what I know and I will attach pictures below.
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Your calculation</span>
</div>
<input type="number" onkeypress="return isNumberKey(event)" onkeyup="return truncateDecimals(this, 2)" id="userInputMapOne" class="form-control" min="0" max="1000" step="0.01" aria-label="input value for your zone" value="e.g 12.34">
This is the current code I am using, it is NOT wrapped in a form. When I wrap it in a form things stop working for a strange reason. I am already having troubles with this, the min/max and step don't work (I have controlled min/max and step with JavaScript). So, is there a way to prepend (or append at the same time as a prepend) a second button onto that input and without being in a form and use that to clear the input field back to the default of ""?
It seemed like an easy job but this constantly interfered with the data being input. And for a weird reason, I can't seem to put a form just wrapping this input without upsetting the divs.
Note: While this would certainly work I think it would be in your bests
interests to review why a <form> is interfering with the
functionality of your code.
You cannot add a true <button type="reset">...</button> because you are not using a <form> and so the reset button doesn't know what to actually 'do'. You can quickly do something similar with just a few modifications of your existing code:
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">Your calculation</span>
</div>
<input type="number" id="calculation" onkeypress="return isNumberKey(event)" onkeyup="return truncateDecimals(this, 2)" id="userInputMapOne" class="form-control" min="0" max="1000" step="0.01" aria-label="input value for your zone" value="e.g 12.34">
<div class="input-group-append">
<button role="button" class="btn btn-secondary" onclick="document.getElementById('calculation').value = ''">Reset</button>
</div>
</div>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
First you need to add an ID to your input field so that you can easily target the field with a bit of JavaScript. Then you just need to add an .input-group-append to extend the input-group to include the new button we'll be adding.
The button operates just like any button would, with the exception that there is an onclick event:
document.getElementById('calculation').value = ''
This finds the field with an ID value of calculation and on a click event resets the value of that field to empty. It's not a reset in the true sense of how <button type="reset">...</button> would operate, but functionally it achieves the same result.

Wicket: access field from inner form

I have a Wicket page with this structure:
<form wicket:id="generalForm" method="post" class="form_recherche">
<input value="" type="text" wicket:id="myField_1" />
<form wicket:id="innerForm" method="post">
<input value="" type="text" wicket:id="myField_2"/>
<input type="submit" class="button-classic" wicket:id="accept_2"/>
</form>
<input type="submit" class="button-classic" wicket:id="accept_1" />
</form>
1 external form with 1 inner form. One field each. The fact is that when the "accept_2" button is clicked, the field "myField_1" is not submitted to the server (only the "myField_2" is submitted). And in fact, I would need the "field_1" field to do some validation.
What am I missing and why isn't the "myField_1" being filled on the server why "accept_2" is clicked?
You need to override Form#wantSubmitOnNestedFormSubmit() on the outer Form to return true. This way you will tell Wicket that you want the (outer) form to be submitted as well when one of its nested forms is submitted.
You used SO tags wicket-1.5 and wicket-1.6. I am not sure whether this method is available for your version of Wicket.

angular form disable submit button if field is empty

Sounds so simple but I've tried quite a few things and none work.
I'm using Angular 4 and my form is template-driven:
<form #form="ngForm" novalidate>
<label for="insz">{{ 'SEARCH_PAGE.searchInszNumber' | translate }}</label>
<input type="text" name="insz" [placeholder]="'SEARCH_PAGE.searchInszNumber' | translate" #input required>
<button (click)="onSearch(input.value)" ><span>{{'SEARCH_PAGE.search' | translate }}</span></button>
</form>
I want to disable the button when the (one and only) input field is empty.
You are missing ngModel in your input, for your input field to actually be a form control:
<input type="text" name="insz" ngModel
[placeholder]="'SEARCH_PAGE.searchInszNumber' | translate" #input required>
and then you need to disable the button of course if form is not valid:
<button [disabled]="!form.valid" (click)="onSearch(input.value)" >Submit</button>
You could take a look at reactive forms. I had no knowledge of them until a week ago, but they're so powerful !
This means all you need to do is add a Validator (Validators.required in your case), and add a disabled condition to your button. And that's it, you're set.

Questions about grails form

Assuming that i have the following data in my params
params:[input:[1, 2, 3]]
And i have the following form in my Grails app
<div class="block1">
<label class="control-label">
<g:message code="input.label" default="Input"/>
</label>
<div class="controls">
<g:textField id="input1" name="input" value="${input}" readonly="${actionName != 'show' ? false : true}"/>
</div>
</div>
<div class="block2">
<label class="control-label">
<g:message code="input.label" default="Input"/>
</label>
<div class="controls">
<g:textField id="input2" name="input" value="${input}" readonly="${actionName != 'show' ? false : true}"/>
</div>
</div>
<div class="block3">
<label class="control-label">
<g:message code="input.label" default="Input"/>
</label>
<div class="controls">
<g:textField id="input3" name="input" value="${input}" readonly="${actionName != 'show' ? false : true}"/>
</div>
</div>
The form design above is correct, because in my form design, there will be several inputs of the same name (but each will be saved to the database under different primary keys) and it can be increases and decreases according to user selection.
Few questions using the above
How do i make it so that the value for input1 is params.input[0], input2 is params.input[1] and input3 is params.input[2] in the view? I can pass the model from controller without problem, but i couldn't distribute the value properly to each input on the form.
Is there any way to change the value ${input} dynamically? As in if i want to change the value to ${input[0]} or ${input[1]}
Can i automatically set the amount of block appended into the form using the g:each tag? Say like if from controller i want to set the rendering block amount to 3, so can i use the g:each tag to render the block 3 times in the form?
Thanks
The links are examples of how to use ajax/jquery to get values from a remote call and replace html element (divId) within a page - this divId could be the entire
<input type="text" name="input" value="newvalue"/>
upon triggering some form of call as above to get the new value.. in regards to
g:textField
yes it works like all other grails tags in the end they are transformed back to the correct HTML terminology...
The actual variable value is dynamic if you defined
<input name="existingvariable" value="${something}" ...
where something was a parameter from the given controller - and then you updated the call so
://YOURHOST:8080/yourapp/controller?existingvariable=newvalue
and refreshed or clicked this link which is what ajax would be doing for you doing a new call to either another controller to generate new values or same and passing new value to it and then grabbing data and pushing it back onto the divId ... (all in the background)
Groovy loading into divs
Grails - Select menu not rendering
I want my selects dropdowns to auto populate with Ajax in Grails website
The above are all related to using ajax to populate / update existing form elements
If you wish to update a live form with a new live value (non existant in DB) take a look at modaldynamix plugin. //github.com/vahidhedayati/modaldynamix

Grails cache issue with forms in show.gsp (view)

I have this very odd issue and I've picked my code apart and taken out any caching changes that I think would cause this but it still remains.
Here is whats happening:
I add an Address in my app, named "q", I save it and get id 1 for
example.
If I add another address names "q" (q isn't restricted to unique), then save it I get id 2.
If I repeat 2 I get a new item with id 3.
Here is the weird part, if I put the mouse over the Edit button for 2 or 3 it has a link to 1. If I look at the HTML generated I get this section for the form:
<form action="/CRM/address/delete/1" method="post" ><input type="hidden" name="_method" value="DELETE" id="_method" />
<fieldset class="buttons">
Edit
<input type="submit" name="_action_delete" value="Delete" class="delete" onclick="return confirm('Are you sure?');" />
</fieldset>
</form>
If I look at the show.gsp it's just the basic code from the generated scaffold:
<g:form url="[resource:addressInstance, action:'delete']" method="DELETE">
<fieldset class="buttons">
<g:link class="edit" action="edit" resource="${addressInstance}"><g:message code="default.button.edit.label" default="Edit" /></g:link>
<g:actionSubmit class="delete" action="delete" value="${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" />
</fieldset>
</g:form>
The controller has the following action:
def show(Address addressInstance) {
respond addressInstance
}
When i print the addressInstance it looks like the correct one.
Does anyone have any idea why I get ID 1 instead of the proper id in this form which is on the show screen of address 2 and 3???
I've tested it in H2 and PostgreSQL, Grails 2.3.3, locally and on Heroku.
Looks like a bug linkGenerator cache in Grails 2.3.0-2.3.4.
I've created a Jira: http://jira.grails.org/browse/GRAILS-10883
You can disable the cache in your config file:
grails.web.linkGenerator.useCache = false