How to use input field value attribute while using formControlName? [Angular] - javascript

What I want to achieve: I want pre-populated data in my form and I also want to use formControlName as I want the data too.
My html file -
<div class="container">
<p class="h4 my-5">Add New Result</p>
<div class="row">
<div class="col">
<form (ngSubmit)="editStudent()" [formGroup]="studentEditForm" name="myForm">
<div class="mb-3">
<label for="roll-no" class="form-label">Roll No.</label>
<input type="number" class="form-control" id="roll-no" name="rollno" formControlName="rollno" value="{{student.rollNo}}" placeholder="{{student.rollNo}}" autocomplete="off" required>
</div>
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" name="name" formControlName="name" value={{student.name}} required>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input type="email" class="form-control" id="email" name="email" formControlName="email" value={{student.email}} required>
</div>
<div class="mb-3">
<label for="score" class="form-label">Score</label>
<input type="number" class="form-control" id="score" name="score" formControlName="score" value={{student.score}} required>
</div>
<button type="submit" class="btn btn-primary" ng-click="submitForm(myForm.$valid)">Submit</button><button type="submit" class="btn btn-dark mx-4">Clear</button>
</form>
</div>
<div class="col"></div>
<div class="col"></div>
</div>
</div>
In Input Tag, I want to use value attribute so I can get a default value but I get Empty fields and I think it is because formControlName is controlling the data in my form. Is there a way to get pre-populated data using value attribute along with formControlName attribute?
Placeholder attribute works fine but I want a default value.

if you want a default value simply initialize the form with values, for example:
form = new FormGroup({
name: new FormControl('defaultNameValue'),
email: new FormControl('defaultEmailValue')
})

You should be doing it in you component instead of using value attribute. While defining the form example
studentEditForm= new FormGroup({
rollNo: new FormControl(this.student.rollNo)
})
or if student data is not available at the time of definition then use formcontrol.setValue after you initialize the student data something like
this.studentEditForm.controls.rollNo.setValue(this.student.rollNo)

Using the value and the CVA (Control Value Accessor: formControlName, formControl, and ngModel) to control the value of the input will override each other each time you change anyone of them.
Instead, it's better to rely only on one of them. If the CVA is used, then you can pass an initial value (default value) to the form-control while defining it:
studentEditForm = new FormGroup({
score: new FormControl(YOUR_INITIAL_VALUE),
});
For more info, check here how Angular passes the value from CVA to the value property when using both of them:
default_value_accessor.ts

Used value and CVA to control value
try this :
studentEditForm = new FormGroup({
score: new FormControl(VALUE),
});

Related

How can I reset text input values to the old values, after disabled input fields in a form after button click

I have the following code:
<form id="formexample">
<div class="row g-5">
<div class="col">
<h5><strong>Informations</strong></h5>
<br />
<label class="form-label" for="">Sample Value</label>
<input type="text" class="form-control" disabled="#isDisabled"
#bind="#binded_value" #oninput="#((e) => { binded_value=(string)e.Value!;})" placeholder="" style="margin-bottom:1rem">
<label for="exampleFormControlTextarea1">Remarks on the tool concept</label>
<input type="text" class="form-control" disabled="#isDisabled"
#bind="#second_binded_value" #oninput="#((e) => { second_binded_value=(string)e.Value!;})" placeholder="" style="margin-bottom:1rem">
</div>
</div>
Now I want to show the binded values, when I click on a button, that allows me to disable the textfield in the form. When I change the binded values manually, the new values are still shown after the form is disabled and not available for any changes. I hope the description of the problem is accurate enough.

Form in HTML with button assigns the value of the last button, no matter which one was selected

I want to create a form with HTML with different types of inputs (such as name, surname, dates, and radio-button options), and when I want to print the object with the data inputted in the form on the console, the value from the radio-buttons is not stored correctly.
First of all, this is my first project on this area and also my first posted question on stackoverflow, so I would appreciate some suggestions on how to pose the question better if I'm forgetting some crucial data.
I have been following help from different resources (mostly youtube videos such as: https://www.youtube.com/watch?v=GrycH6F-ksY ) to create this form and submit the data with AJAX, and the code of my javascript application comes mainly from that video.
All the data is stored correctly and I can see it in the console, except from the data comming from the radio-buttons. No matter what option is selected (either "male" or "female"), the console always shows the value of the last button, which in this case is "female". I suppose I am doing something wrong when defining these buttons, and why they are not being "selected" (I suppose that's what is happening since the data shown is always the last default value) but I haven't been able to find out where I am doing something wrong.
I'm including the part of the code that I think might be relevant
<form action="ajax/contact.php" method="post" class="ajax">
<div class="form-row">
<div class="form-group col-md-6">
<label>Name</label>
<input type="text" class="form-control" name="inputName" required>
</div>
<div class="form-group col-md-6">
<label>Surname</label>
<input type="text" class="form-control" name="inputSurname" required>
</div>
</div>
<div class="form-group">
<label>Date of birth</label>
<input type="date" class="form-control" name="inputDate">
</div>
<div class="form-group">
<label>Email</label>
<input type="email" class="form-control" name="inputEmail" required>
</div>
<div class="form-row">
<div class="form-group col-md-4">
<label>Gender</label>
</div>
<div class="form-group col-md-4">
<div class="radio-inline"><input type="radio" name="inputGender"
value="male">Male</div>
</div>
<div class="form-group col-md-4">
<div class="radio-inline"><input type="radio" name="inputGender"
value="female">Female</div>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label>Number of children</label>
</div>
<div class="form-group col-md-6">
<input type="number" class="form-control" name="inputNumber">
</div>
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
Javascript function
$('form.ajax').on('submit', function() {
var that = $(this),
url = that.attr('action'),
method = that.attr('method'),
data = {};
that.find('[name]').each(function(index, value) {
var that = $(this),
name = that.attr('name'),
value = that.val();
data[name] = value;
});
console.log(data);
return false;
});
PHP file
<?php
if (isset($_POST['inputName'],$_POST['inputSurname'],$_POST['inputDate'],$_POST['inputEmail'],$_POST['inputGender'],$_POST['inputNumber'])) {
print_r($_POST);
}
In the console I'm getting this:
${inputName: "myName", inputSurname: "mySurname", inputDate: "2019-12-13",
$inputEmail: "myMail#gmail.com", inputGender: "female", …}
$inputDate: "2019-12-13"
$inputEmail: "myMail#gmail.com"
$inputGender: "female"
$inputName: "myName"
$inputNumber: "1"
$inputSurname: "mySurname"
$_proto_: Object
but I thought it would be showing:
$...
$inputGender: "male"
$...
when the male option is selected.
Thank you very much
The problem is in your JS. You're looping through everything with a name attribute, in order, and adding its value to your submit data. In the case of radio buttons, you have to check if they're selected and only add if so, otherwise, the last one always wins, as you're seeing.
And since you appear to be using jQuery, you can probably just let its serialize helper do this work for you.

input text isn't updating angular model in one case that is identical to another in the same form

I have a simple form (reduced from the actual form to demonstrate the problem):
<pre>Name: {{currentChild.name}}</pre>
<pre>Annual College Expense: {{currentChild.annualCollegeExpense}}</pre>
<form name="childForm" novalidate>
<div class="form-inline">
<div class="form-group">
<label>Name:</label>
<input type="text" name="name" class="form-control" ng-minlength="1" ng-model="currentChild.name" ng-required="true">
<div class="help-block"
ng-messages="childForm.name.$error"
ng-show="childForm.$submitted || childForm.name.$dirty || (childForm.name.$invalid && childForm.name.$touched)">
<p ng-message="required" ng-hide="childForm.name.$valid">Your name is required.</p>
<p ng-message="minlength" ng-hide="childForm.name.$valid">Your name is too short.</p>
</div>
</div>
<div class="form-group">
<label>Annual Expenses:</label>
<input type="text" name="annualCollegeExpense" class="form-control" ngModel="currentChild.annualCollegeExpense" />
</div>
</div>
</form>
When I fire up the form, I see the expected data in the pres at the top of the form. When I type into the name field, the name in the pre changes. When I type into annual expense field, the annual expense pre does NOT change.
Since these are IDENTICAL and appear to obey all the usual ng-model rules, i.e., use a . to reference the data in the model, I'm stumped.
Anybody got a suggestion?
you used ngModel instead of ng-model so you should use
ng-model="currentChild.annualCollegeExpense"
instead of
ngModel="currentChild.annualCollegeExpense"
use
<input type="text" name="annualCollegeExpense" class="form-control" ng-model="currentChild.annualCollegeExpense" />

How to create an HTML5 custom validation that check if the value inserted into 2 email inout field is the same?

I am pretty new in HTML 5 and I have the following doubt.
I have a form like this:
<form class="form-horizontal" action="/IDES/salvaRegistrazione" method="POST" name="formRegistrazione">
<div class="form-group">
<label class="control-label col-sm-2" for="inputNome">Nome</label>
<div class="col-sm-10">
<input id="inputNome" class="form-control" type="text" value="" required="required" placeholder="Nome" name="nome">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="inputEmail">E-mail</label>
<div class="col-sm-10">
<input id="inputEmail" class="form-control" type="email" value="" required="required" placeholder="E-mail" name="email">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="inputEmail2">E-mail</label>
<div class="col-sm-10">
<input id="inputEmail2" class="form-control" type="email" placeholder="Inserisci nuovamente E-mail" name="inputEmail2">
</div>
</div>
<input id="submitRegistrazione" class="btn btn-default pull-right" type="submit" value="Registrati" name="submitRegistrazione">
</form>
As you can see the input tag have setted the required="required" attribute and as you can see in this JSFiddle if you don't insert the value into the input tag it is automatically shown an HTML error message popup:
https://jsfiddle.net/fntwyn9j/
Now my problem is that into my form I have also 2 field having type="email".
My problem is that I want that if the second email value (the one inserted in the field having id="inputEmail2") is not equal to the first email value (the one inserted into the field having id="inputEmail") appear a custom message (in the same HTML5 style) that say to me that the 2 fields have not the same value and the form is not submitted.
Searching on the web I found this example that use event listener to add custom message: http://jsfiddle.net/B4hYG/9/
But is seems to me that don't work and I have no idea about how to implement the previous requirement.
How can I solve this issue and implement this kind of HTML5 custom validation?
Solved by myself:
$(document).ready(function() {
document.getElementById("inputEmail2").addEventListener("input", function (e) {
valoreInpitEmail = $('#inputEmail').val();
valoreInpitEmail2 = $('#inputEmail2').val();
//alert("value inputEmail: " + valoreInpitEmail + " value inputEmail2: " + valoreInpitEmail2);
//if (e.target.value != "") {
if(valoreInpitEmail != valoreInpitEmail2) {
alert("EMAIL DIVERSE");
//alert("BLABLABLA");
e.target.setCustomValidity("Le E-mail inserite non corrispondono, per favore inserirle nuovamente");
}
else {
// Let the browser decide whether this is a valid email address
// This actually prevents that the call of setCustomValidity()
// in the IF doesn't get removed thus the user cannot submit the form
//alert("ELSE");
e.target.setCustomValidity("");
}
});
});

How to $setdirty to a single input

I've got a little problem. I want to set to dirty a single input, I mean, because when I give a value automatically it stays in pristine class, doesn't change, and doesn't save the new value.
If I edit it, it works and change the class. I want to cancel that pristine class.
If anyone know please let me know.
<form class="form-horizontal" ng-repeat="studiant in studiants" name="form" id="form">
<input type="hidden" name="id" value="{{studiant.studiant_id}}" class="form-control" disabled>
<div class="form-group">
<label for="school" class="col-md-2 control-label">School</label>
<div class="col-md-1">
<input type="text" id="school" name="school" class="form-control" ng-init="studiant.school=studiant.studiant_school" ng-model="studiant.school">
</div>
</div>
<div class="form-group">
<label for="name" class="col-md-2 control-label">Student's Name</label>
<div class="col-md-10">
<input type="text" id="name" name="name" class="form-control" ng-init="studiant.name=studiant.studiant_name" ng-model="studiant.name">
</div>
</div>
</form>
And the script:
document.getElementbyId('name').value = "anything";
Or, if I doing wrong and I have to change the value with ng-model or something, please help me.
http://plnkr.co/edit/bVoljJqiK3CLB2xqZ6Zm?p=preview
You can see a working example there.
Make sure you have the name attr set for the form and the input.
HTML Example:
<button id="dirty-button" ng-click="addText(); myForm.myText.$setDirty()">Make Dirty</button>
<hr>
<form name="myForm">
<input name="myText" id="myTextInput" type="text" ng-model="myText" required>
</form>
<br/>
<span ng-show="myForm.myText.$dirty">it's dirty now</span>
A simple function:
$scope.addText = function() {
$scope.myText = "now I'm dirty";
}
$scope.$on('$viewContentLoaded'){
$scope.form.fieldName.$dirty = true;
}
When your view is loaded then angular calls viewContentLoaded event is called. After that you can set the field dirty. And also if you want to call some method ,that should be executed after the content is loaded than you should call that method inside this $scope.$on('$viewContentLoaded'){..}
This should do the job
angular.element(document.querySelector('form')).scope().formname.fieldname.$setDirty()

Categories

Resources