Observe value changes when submit button pressed in Angular - html

I have an edit form as below which contains data in the input fields.
<ng-form #infoForm="ngForm" novalidate>
<div>
<label for="firstName">First Name :</label>
<input type="text"
class="form-control"
id="firstName"
name="firstName"
[(ngModel)]="in.firstName">
</div>
<div>
<label for="lastName">Last Name :</label>
<input type="text"
autocomplete="on"
class="form-control"
id="lastName"
name="lastName"
[(ngModel)]="in.lastName">
</div>
<button type="button" class="btn btn-primary" (click)="updateInfo(infoForm.value)">Update
</button>
</ng-form>
And I have the function in the component as below:
updateInfo(info: any) {
console.log(info);
}
This form return all the values (to the console) in the form when the Update button clicked, but I want to submit only the edited values instead of whole form. How could I implement it?

For this you can pass the form instead of its value to 'updateInfo' function and process it there. If user change the control value its state becomes 'dirty' from 'touched/pristine' and we can filter controls based on that.
Change in html:
<button type="button" class="btn btn-primary" (click)="updateInfo(infoForm)">Update
</button>
Change in *.ts file:
updateInfo(info: NgForm) {
const changedValues = Object.keys(info.controls)
.filter(key => info.controls[key].dirty === true)
.map(key => {
return { control: key, value: info.controls[key].value }
});
console.log(changedValues);
}

Related

How to pass data to database in ASP.NET MVC?

I'm working on an MVC project. My requirement is to insert data to the database through a form. I've included the form inside a bootstrap modal.
My problem is, when I enter some data and click the save button, it inserts only null rows, not the entered values. Why does this happen? How do I make it to insert the real values instead of just passing nulls?
Here's the code for the modal.
#if (Model != null)
{
<div class="modal-content">
<!--modal header-->
<div class="modal-body">
<form id="actionForm">
<div class="form-group">
<label>Name</label>
<input type="text" name="Name" class="form-control" placeholder="Enter Accomodation Type Name...">
</div>
<div class="form-group">
<label>Description</label>
<textarea name="Description" class="form-control" placeholder="Enter Accomodation Type Description..."></textarea>
</div>
</form>
<div id="errorDiv">
</div>
</div>
<div class="modal-footer">
<button type="button" id="actionButton" class="btn btn-primary">Save changes</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
}
This is the script for the Save Changes button
<script>
$("#actionButton").click(function () {
$.ajax({
url: '#Url.Action("Action", "AccomodationTypes")',
type: "post",
data: $("actionForm").serialize()
})
.done(function (response) {
debugger;
if (response.Success) {
location.reload();
}
else {
$(".errorDiv").html(response.Message)
}
});
});
</script>
Since you are using $("actionForm").serialize() you have to bind the model to the form input controls:
<input type="text" asp-for"#Model.Name" name="Name" class="form-control"
placeholder="Enter Accomodation Type Name...">
// or you can try to replace asp-for by value="#model.Name"
<textarea asp-for="#Model.Description" name="Description" class="form-control"
placeholder="Enter Accomodation Type Description..."></textarea>
or if you using older versions of MVC you can try replace your input controls with this:
#Html.TextBoxFor(m => m.Name, new { #class = "form-control" })
#Html.TextAreaFor(m => m.Description, new { #class = "form-control" })
And you have an javascript bug too. Replace
$("actionForm").serialize()
with
$("#actionForm").serialize()
or even better:
$("#actionForm").serializeArray()

Radio Buttons in ngForm Angular2

I have two radio buttons on my HTML page for gender selection (M or F).
How to retrieve which button was clicked in my typescript file? Here's the code
<form>
<label> Gender </label>
<br>
<input type="radio" required name='gender' value='Male' [(ngModel)]='gender'>Male
<br>
<input type="radio" required name='gender' value='Female' [(ngModel)]='gender'>Female
<br>
<button id="signup" class="btn btn-primary" type="submit">Signup</button>
</form>
On clicking the button, I want to assign M or F to a string in my typescript file.
You code is correct. No need to change anything.
This is your template code.
<form (ngSubmit)="onSubmit()">
<label>Gender</label>
<input type="radio" required name='gender' value='Male' [(ngModel)]='gender'>Male
<input type="radio" required name='gender' value='Female' [(ngModel)]='gender'>Female
<button id="signup" type="submit">Signup</button>
</form>
In your .ts file,
export class TestComponent implements OnInit {
gender: string = "Male";
onSubmit() {
console.log(gender);
}
}
This will give you the selected gender value.
Because you have used two way binding. It updates the ngModel whenever the input changes.
you can retrieve which button click by add ngModelChange method
<label> Gender </label>
<br>
<input type="radio" required name='gender' value='Male' [(ngModel)]='gender' (ngModelChange)="youMethodName(gender)">Male
<br>
<input type="radio" required name='gender' value='Female' [(ngModel)]='gender' (ngModelChange)="youMethodName(gender)">Female
<br>
</div>
<button id="signup" class="btn btn-primary" type="submit" >Signup</button> </form>
in your ts file
youMethodName(model) {
console.log("TCL: youMethodName -> model", model)
}
Although, answer is already accepted. I want to give solution of this problem if you do not want to use Two way data binding. this way is useful for breaking down two way data binding. So, there is no need for [(ngModel)] . Complete Working Demo found here in StackBlitz Link
Your HTML ...
<form>
<fieldset id="group1">
<input type="radio" (change)="handleChange($event)" name="group1" value="Male"/>Male
<input type="radio" (change)="handleChange($event)" name="group1" value ="Female"/> Female
</fieldset>
<div *ngIf="_prevSelected"> {{ _prevSelected}} </div>
<button (click)="click()">Show</button>
<div *ngIf="clicked"> <span> selected value is {{_prevSelected}} </span></div>
</form>
Your class file is..
private _prevSelected: any;
clicked:boolean;
handleChange(evt) {
let target = evt.target;
if (target.checked) this._prevSelected = target.value;
}
click(){
this.clicked =true;
}

Not going to specific URL this.router.navigate() in AngularJs

I am making a registration form in angularJS and I use the bootstrap template for design.
This is my form and path to the form page is http://localhost:4200/signup
<form method="post" (submit)='register(username.value,email.value,password.value)'>
<div class="form-group">
<label for="name">Full name</label>
<input type="text" id="name" #username class="form-control" placeholder="Enter your name">
</div>
<div class="form-group">
<label for="remail">Email address</label>
<input type="email" id="remail" #email class="form-control" placeholder="Enter email">
</div>
<div class="form-group">
<label for="rpassword">Password</label>
<input type="password" #password class="form-control" id="rpassword" placeholder="Password">
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
But the problem is that it when I click submit button or hit enter, It automatically refresh the page and shows Cannot POST /signup.
As this is my component.ts file
register(name,email,password) {
this.userService.registerUser(name, email, password).subscribe(data => {
if (data.success) {
console.log('reaches');
this.router.navigate(['user']);
} else {
console.log('error');
}
});
}
It is trying to go to the /signup path in post method but in component.ts file I give the path to '/user'
How can it automatically go-to /signup? And how to stop that.
Your form is trying to post data to a server. It sounds like you don't have a server which can handle the post, so you get the error.
To fix the problem, you need a server which can handle the form post.

Form submit to a text field

How to make a form that submit to a text field below
<form action="">
Text: <input type="text" name="firstname">
<input type="submit" value="Submit"><br><br>
Post text: <input type="text" name="firstname">
</form>
You will need to use JavaScript for that:
<script>
function submitted() {
formValue = document.getElementsByName("firstname")[0].value;
document.getElementsByName("firstname")[1].setAttribute("value", formValue); // Copy the value
return false;
}
</script>
<form onsubmit="return submitted()"> <!-- Call submitted when the form is submitted -->
Text: <input type="text" name="firstname">
<input type="submit" value="Submit"><br><br> Post text: <input type="text" name="firstname">
</form>
However, there is no need for a form for that. The onsubmit attribute is mostly used for when you want to alert the user that the form was submitted; the actual submission is done on the server through PHP or something else, and not through JavaScript (since the user has access to the JavaScript code and could change the input checking process as he wishes). Here you could simply have something like this:
<script>
function submitted() {
formValue = document.getElementById("firstname").value;
document.getElementById("postFirstname").setAttribute("value", formValue); // Copy the value
}
</script>
Text: <input type="text" id="firstname">
<button onclick="submitted()">Submit</button>
<br><br> Post text: <input type="text" id="postFirstname">

HTML - Get data for each button

I'm trying to have a login and register button, when the login button gets clicked I want to specify it's a login action and when it's a register action I want to specify that in the URL. Is there some sort of attribute to define default get data which is always in there URL (plus the input data)?
This is my current code:
<form class="login-form" onsubmit="return validate();" method="get" action="php/login.php">
<input class="login-element credential" placeholder="Username" id="username" name="username"/>
<button class="login-element button" type="submit">Login</button>
<button class="login-element button" type="submit">Register</button>
</form>
<form class="login-form" onsubmit="return validate();" method="get" action="php/login.php">
<input class="login-element credential" placeholder="Username" id="username" name="username"/>
<button class="login-element button" name="login" type="submit">Login</button>
<button class="login-element button" name="register" type="submit">Register</button>
</form>
in login.php file your code goes like this.
if(isset($_POST['login']))
{
//your code goes here...
}
else
{
//your code goes here...
}
if(isset($_POST['register']))
{
//your code goes here...
}
else
{
//your code goes here...
}
You can add a 'data' attribute to each button and then change the 'action' of the form based on that. e.g:
<button class="login-element button" type="submit" data-action="login">Login</button>
<button class="login-element button" type="submit" data-action="register">Register</button>
You can 'grab' the data attribute in jQuery as follows:
$('.login-element').click(function(){
var action = $(this).date('action');
if(action == "register"){
// -- do register stuff
}else{
// -- do login stuff
};
});