react js form getting submitted twice - html

I have below code which calls save form
<div className="col-md-4">
<button onClick={saveCredit} className="btn btn-success">
Submit
</button>
I have onclick handler function as
const saveCredit = () =>{
//validate form
// call api to save form attributes
CreditTransactionDataService.create(data)
.then(response => {
setSubmitted(true);
console.log(response.data);
})
.catch(e => {
console.log(e);
});
}
after successful save , I will show successful message as below.
{submitted ? (
<div>
<h4>You submitted successfully!</h4>
<button className="btn btn-success mr-2" onClick={newCreditTransaction}>
Add
</button><Link style={{ fontWeight: 'bold' }} className="btn btn-warning" to={"/creditTransactionList"}>
return to List
</Link>
</div>
)
but the problem is, my form is getting submitted twice, and creating duplicate records with same values.... couple of save options, i restricted with unique key column at database level, but few tables still need to handled at code level..

I´m unable to reproduce it in codepen, but one solution a little bit hacky could be check in the method if it is submitted already
const saveCredit = {
//Check if it is submitted
if(!submitted){
//validate form
// call api to save form attributes
CreditTransactionDataService.create(data)
.then(response => {
setSubmitted(true);
console.log(response.data);
})
.catch(e => {
console.log(e);
});
}
}
This may not be the best but could do the job
Also a thing I did notice is that your saveCredit function not look like a function.
Why not declare as an arrow function? Like:
const saveCredit = () => { //Your code }

Your button doesn't need onClick event handler if it's responsible for submitting a certain form. You should add type="submit" to button and onSubmit to form tag itself.
You should go for this approach to handle submitting correctly (clicking of the button or hitting enter by the user are covered).

Related

How to send data from table row to post api

I have a table in React.
<Table>
<tr>
<td><TextField/></td>
</Table>
<Button onClick={(e)=> submit()}> SUBMIT </Button>
Now i want to send the input of the textField to a post api call when i click the submit button.
const submit = () => {
asyncPost(url, data_to_be_sent).then((response) => {console.log(“ok”)})
I need to send the value i enter in the textfield to the asyncPost. How should i do that?
You have to use hooks (if you use functional component) to be able to store value from <TextField/> inside it. Later you can use it when clicking on a button. You can find an example here
You create hook by:
const [inputValue, setInputValue] = useState(null)
The difference is that you will use onChange event on <TextField/> like:
<TextField onChange={e => setInputValue(e.target.value)} />
so later you can use it like:
const submit = () => {
asyncPost(url, inputValue).then((response) => {console.log(“ok”)})

Vue.js edit post by id

I'm starting with vue.js and I was reading this question to help me loading some posts from DB with v-for.
Below each post there are Edit and Delete buttons. I can delete each post by its ID correctly. And I can open the input to edit post title correctly too.
But I cannot save input changes when I click on save button. It returns to the initial text.
And when I click to edit it opens all the inputs titles.
Is there a way to open the specific post title and keep the changes after save it?
<div id="app" class="row mb-50">
<div v-for="(item, index) in tours" v-bind:key="item.id" id="tours" class="col-md-12 mb-30">
<div class="tour-list">
<div class="tour-list-title">
<p>
<input type="text" ref="item.id" :value="item.title" :disabled="!editingTour"
:class="{view: !editingTour}" />
</p>
</div>
<div class="tour-list-description">
<p>
{{ item.description }}
</p>
</div>
<div class="tour-list-options">
<div class="row">
<div class="col-md-6">
<span>
<button #click="editingTour = !editingTour" v-if="!editingTour"
class="btn border btn-circle tour-list-edit-btn">Edit</button>
</span>
<span>
<button #click="save" v-if="editingTour"
class="btn border btn-circle tour-list-edit-btn">Save</button>
</span>
<span>
<button #click="editingTour = false" v-if="editingTour"
class="btn border btn-circle tour-list-delete-btn">Cancel</button>
</span>
<span>
<button #click="deleteTour(item.id, index)" v-if="!editingTour"
class="btn border btn-circle tour-list-delete-btn">Delete</buton>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
vue.js:
let app = new Vue({
el: '#app',
data: {
editingTour: false,
tours: null,
errored: false,
edited: false,
deleted: false,
item: {
title: null,
description: null
}
},
created: function () {
this.searchTour()
},
methods: {
searchTour: function () {
axios.post('getPosts.php', { "token": param }).then((response) => {
this.tours = response.data;
}).catch((error) => {
this.errored = error;
});
},
editTour: function (id) {
axios.post('editPosts.php', { "token": token, "tourID": id }).then((response) => {
this.edited = response.data;
}).catch((error) => {
this.errored = error;
});
},
deleteTour: function (id) {
if (confirm('Are You sure?')) {
const index = this.tours.findIndex(item => item.id === id);
if (~index) {
axios.post('deletePosts.php', { "token": token, "tourID": id }).then((response) => {
this.deleted = response;
this.tours.splice(index, 1);
}).catch((error) => {
this.errored = error;
});
}
}
},
save: function () {
this.item.title = this.$refs['item.id'].value;
this.editingTour = !this.editingTour;
console.log(this.item.title);
}
}
});
In console.log(this.item.title); is returning undefined.
I have changed ref="item.id" to ref="title" and this.item.title = this.$refs['item.id'].value; to this.item.title = this.$refs['title'].value; but it did not work.
You should use in your input v-model instead of ref it will bind your model with the value you are editing, in general in vue we avoid direct DOM manipulation when possible, like so:
<input type="text" ref="item.id" v-model="item.title" :disabled="!editingTour"
:class="{view: !editingTour}" />
Where calling your function e.g. editTour you can pass it the item (if it's in the template to save the updated version like so:
#click="editTour(item)"
You can use the v-model directive to create two-way data bindings on form input, textarea, and select elements. It automatically picks the correct way to update the element based on the input type. Although a bit magical, v-model is essentially syntax sugar for updating data on user input events, plus special care for some edge cases.
Source : https://v2.vuejs.org/v2/guide/forms.html
Example:
<input v-model="description" placeholder="my description">
The above input value will then be binded to the description element of your data object and vice-versa - if one changes, the other is updated to the same value:
data:{
description: "default value"
}
So, when you DB request is ready you can update the value of the description within the DB method:
this.description=db.result.description
and the value of the input will also update.
Likewise, if the user changes the value of the input field, the value bound to the data element will be updated also. So, when saving back to DB:
db.update({description:this.description})
(note: the db methods here are for example purposes only. Replace with the relevant DB methods for your backend service.)

HTML Form Linking

As a newbie to HTML, I am seeking your help and guidance.
I am trying to create a page which will have only two Buttons like:
Create User and Log In
Depending on which button is clicked a form will be processed.
It's similar to a concept of Register or LogIn.
PS: I am trying to use java for the script part
Please Guide me to achieve the above mentioned scenario
As I understood from your descriptions you have a page with only two buttons in it. So there is no form in this page but then when you click on any of buttons they lead you to another page with a form.
then you can have a tag like this:
<a href="">
<div style="width: 60px; height: 30px; border: solid 1px; text-align: center">Log In</div>
</a>
The below code will send different data to the server, depending on which button was clicked
var formElm = document.forms[0];
formElm.addEventListener('submit', function(){
return false; // disable normal form submit so the page won't refresh
})
// when button number #1 gets clicked, send the form to the server
formElm.querySelector('.do1').addEventListener('click', function(){
fetch('/url',{ method:'POST', body:new FormData(formElm) })
.then(function(response) {
console.log('request succeeded with JSON response', JSON.parse(data))
})
.catch(function(error) {
console.log('request failed', error)
})
});
// when button number #1 gets clicked, do something else..you choose.
formElm.querySelector('.do2').addEventListener('click', function(){
// send something else to the server
// ...
});
<form>
<input name='something' value='foo'>
<button type='button' class='do1'>button 1</button>
<button type='button' class='do2'>button 2</button>
</form>

click event in subscribe method angular 2

I have 2 button one of them of type file -which is hidden- if the user click the first button a confirmation dialog opens if user click Ok the second button must be clicked.
The problem is that all the logic is subscribe method -of confirmation dialog - are execute expect clickEvent for the second button.
Can anyone explain why and provide me with a solution?
#ViewChild('fileBrowser') fileInput: ElementRef;
dialogRef: MdDialogRef<ConfirmationDialog>;
clickUpload(){
this.dialogRef = this.dialog.open(ConfirmationDialog);
this.dialogRef.afterClosed().subscribe((result) => {
if (result) {
// some code
this.fileInput.nativeElement.click();
}
this.dialogRef = null;
});}
//HTML Code
<button md-button (click)="clickUpload()" > upload</button>
<input #fileBrowser id="fileBrowser" type="file" hidden="true">
"this.fileInput.nativeElement.click();" this is the problem line
I found the solution, i changed dialogRef's method from afterClosed to beforeClose
The new code
this.dialogRef.beforeClose().subscribe((result) => {
if (result) {
// some code
this.fileInput.nativeElement.click();
}
this.dialogRef = null;
});}

Saving vs. submitting a form

I am working on an application process using Laravel 4.2.
Users applying with my form need to be able to save their form input for later, or submit it. So right now I have two different buttons, Save and Submit.
The key difference between saving and submitting would be a status. When a user saves their application, their application status will be marked as "in progress", when they submit their application the status would be marked as "completed".
My question is:
In terms of my form HTML structure, How do I differentiate between a saved and submitted application? Just checking whether or not they have filled out all the required inputs would not be reliable, because there is the possibility that the user wanted to add more to it later.
I tried doing a form inside of a form, but quickly realized this would not work.
Does anyone have an idea as to how to accomplish this?
You can have two submit buttons inside a form with different names and values:
<button type="submit" name="action" value="save">Save</button>
<button type="submit" name="action" value="submit">Submit</button>
You can then check the value in your controller action:
public function postSubmission()
{
if (Request::get('action') == 'save')
{
// Save form for later
}
elseif (Request::get('action') == 'submit')
{
// Immediately submit form
}
}
Lets say your code is something like this (this is from Laravel5 but as far as i remember it's mostly the same).
{!! Form::open(array('route' => array('admin.editApplication'), 'method' => 'PATCH')) !!}
....
<button type="submit" name="save" value="save">Save</button>
<button type="submit" name="edit" value="edit">Edit</button>
{!! Form::close() !!}
Then in your controller you can do something like this (check if the value is set in edit (you might want to call it something else than edit and save)
public function editApplication(Request $request) {
if(isset($request->input('save')){
// Your code to save here
}else{
// Your code to edit here.
}
}