Material Design Lite *ngIf on Form Input Field Angular 5 - forms

I want to build some dynamic form fields.
When I put an *ngIf in fron of the div the material design does not work properly (no effects etc.).
Here is the input field that works
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="number" id="playerCount" [(ngModel)]="playerCount" (ngModelChange)="setPlayerCount(playerCount)">
<label class="mdl-textfield__label" for="playerCount">Anzahl Spieler</label>
</div>
and the one that does not work
<div *ngIf="players" class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="text" id="stuff">
<label class="mdl-textfield__label" for="stuff">stuff</label>
</div>
The second div should appear as soon as the first has been filled out.

You have to register new elements to MDL's componentHandler since *ngIf actually removes the element from the dom, you have to register that element every time Angular removes/inserts it.
You can either call componentHandler.upgradeAllRegistered(); every time *ngIf inserts the element or replace *ngIf with something that is just hides the element but not remove it.

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.

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.

Angular 2 - Click to edit form fields

I want to replace label with input textbox and vice versa by clicking a button in Angular 2. I knowi have to use ngIf of somekind, but i am a little bit confused on how to do.
HTML:
<form>
<div class="information">
<label *ngIf="editMode">{{textValue}}</label>
<input *ngIf="editMode" [ngModel]="name">
<button (click)="editMode=true">Edit</button>
<button (click)="editMode=false">Save</button>
</div>
</form>
The only thing you need to add to one of your *ngIf's, is exclamation mark:
<label *ngIf="!editMode">{{textValue}}</label>
which means that label is shown when editMode is false. The exclamation mark is the NOT operator, which is used as truth tests on a variable. More here: What does an exclamation mark before a variable mean in JavaScript

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

when using angular nested form, the first inner form can not be referred in scope

When form is nested, the first inner form can not be referred in the controller scope.
I have created a minimal test to reproduce this issue at Plunker
angular version: 1.2.16
Browser: Chrome, Safari
What's the problem? is there any way to remedy?
I recommend a book called Mastering Web Application Development with AngularJs
There's a section called nesting forms and there it says that you have to nest the forms with ng-include. like so:
<script type="text/ng-template" id="password-form">
<ng-form name="passwordForm">
<div ng-show="user.password != user.password2">
Passwords do not match
</div>
<label>Password</label>
<input ng-model="user.password" type="password" required>
Creating Advanced Forms
[ 158 ]
<label>Confirm Password</label>
<input ng-model="user.password2" type="password" required>
</ng-form>
</script>
<form name="form1" novalidate>
<legend>User Form</legend>
<label>Name</label>
<input ng-model="user.name" required>
<ng-include src="'password-form'"></ng-include>
</form>
We define our subform in a partial template. In this case it is inline in a script block
but it could be in a separate file also. Next we have our container form, form1,which
includes the subform by using the ngInclude directive.
The subform has its own validity state and related CSS classes. Also, notice
that because the subform
I have found a workaround for this issue, just replace outer form tag with ng-form tag then the first inner form is added to the scope. see this plunker