I need to clear my inputs in modal after my data saved successfully, I've tried several solution I found here such as reset() or myData = ''; but none of them worked for me.
Code
Vue method
submit: function(e) {
axios.post('/api/saveVerse', this.verse)
.then(res => {
this.isLoading = false
$('#exampleModal').modal('toggle');
this.getVerses.push( res.data.verse );
})
.catch(error => {
this.errors = error.response.data.errors
this.isLoading = false
})
},
Vue Template
<form #submit.prevent="submit" class="needs-validation" novalidate>
<div class="modal-body">
<div class="form-row">
<div class="col-md-3 mb-3">
<label for="validationTooltip01">Verse Number</label>
<input type="text" class="form-control" id="validationTooltip01" v-model="verse.number" placeholder="Verse Number" required>
<div class="invalid-tooltip">
Verse Number Is Required.
</div>
</div>
<div class="col-md-9 mb-3">
<label for="validationTooltip01">Heading</label>
<input type="text" class="form-control" id="validationTooltip01" v-model="verse.heading" placeholder="Verse Heading">
<div class="valid-tooltip">
Heading Looks Good!
</div>
</div>
<div class="col-md-12 mb-3">
<label for="validationTooltip02">Verse</label>
<textarea name="body" class="form-control" id="validationTooltip02" v-model="verse.body" placeholder="Verse" cols="15" rows="5" required></textarea>
<div class="invalid-tooltip">
Verse Body Is Required.
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-success">Save</button>
</div>
</form>
Any idea?
Update
How I get my form data...
data() {
return {
//...
verse: {
number: '',
heading: '',
body: '',
book_id: '',
chapter_id: '',
}
}
},
try to bind the response like below.and verify please
submit: function(e) {
axios.post('/api/saveVerse', this.verse)
.then(res => {
this.isLoading = false
$('#exampleModal').modal('toggle');
this.getVerses.push( res.data.verse );
// resetting your v-model:
this.verse = {
number: '',
heading: '',
body: ''
};
}).bind(this)
.catch(error => {
this.errors = error.response.data.errors
this.isLoading = false
})
},
You can do something like this:
submit: function(e) {
axios.post('/api/saveVerse', this.verse)
.then(res => {
this.isLoading = false
$('#exampleModal').modal('toggle');
this.getVerses.push( res.data.verse );
// resetting your v-model:
this.verse = {
number: '',
heading: '',
body: ''
};
// Try this also...
e.preventDefault();
})
.catch(error => {
this.errors = error.response.data.errors
this.isLoading = false
})
},
Related
<template>
<div>
<div class="form-group">
<label for="name">Name</label>
<input type="text" class="form-control" v-model="firstName" placeholder="Enter your name">
</div>
<div class="form-group">
<label for="lastName">Last name</label>
<input type="text" class="form-control" v-model="lastName" placeholder="Enter your last name">
</div>
<div class="form-group">
<label for="message">Type Your message</label>
<textarea class="form-control" v-model="message" rows="3"></textarea>
</div>
<div class="form-group form-check" v-for="number in numbers" :key="number">
<input type="checkbox" :value="number.Broj" v-model="checkedNumbers">
<label class="form-check-label" >{{number.Broj}}</label>
</div>
<button type="submit" class="btn btn-primary" #click="sendMessage">Send message</button>
</div>
</template>
<script>
import http from "../http-common.js";
import userServices from "../services/userServices.js";
export default {
data()
{
return {
firstName: null,
lastName: null,
message: null,
numbers: "",
checkedNumbers: [],
};
},
methods:
{
async sendMessage()
{
await http.post("/message", {firstName: this.firstName, lastName: this.lastName, message: this.message, numbers: this.checkedNumbers});
this.$data.firstName = "",
this.$data.lastName = "",
this.$data.checkedNumbers = [],
this.$data.message = "";
},
retrieveNumbers() {
userServices.getNumbers().then(response => {
this.numbers = response.data;
console.log(response.data);
})
.catch(e => {
console.log(e);
});
}
},
created() {
this.retrieveNumbers();
}
}
</script>
How can I add success message to the user after clicking Send message button? For example "Message sent"
I have a perfectly working form I can insert data into database and through the form, writing data into text file. using axios after form validation. I am just struggling to show a success message after user clicks the button.
Thank you
You can do something after the Promise is returned, like :
await http.post("/message", {firstName: this.firstName, lastName: this.lastName, message: this.message, numbers: this.checkedNumbers}).then((response) => {
// Do something with the response
})
Then, you can pop a swal from SweetAlert documentation with the message you want to show.
I have a button that removes a photo from an object that holds multiple photos:
<button class="btn" onClick={()=> this.removePhoto(index)}>remove</button>
For some reason after the removePhoto function runs it continues to the onsubmit function. The only thing I can think that could be causing this is the bindings but I am still a fairly new to react so I am not sure how to fix this.
export default class Edit extends Component {
constructor() {
super();
this.state = {
id: '',
title: '',
description: '',
photos: [],
categories: [],
selectedFile: '',
selectedFiles: '',
photo: '',
tags: [],
tagName: '',
};
this.removePhoto = this.removePhoto.bind(this);
}
onSubmit = (event) => {
event.preventDefault();
const photoCatUpdate = this.state.photos.map((obj, index) => {
obj.tag = this.state.tagName
return obj
});
const photos = JSON.stringify(photoCatUpdate)
let body = {
title: this.state.title,
description : this.state.description,
photos: photos,
tags: this.state.tagName
}
let id = this.state.id
fetch('/api/categories/' + id, {
method: 'put',
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json'
}
})
.then(res => {
if (res.status === 200) {
console.log("WORKED!!")
this.props.closeModal()
this.props.getCategory()
} else {
const error = new Error(res.error);
throw error;
}
})
}
addPhoto = () => {
const photosNew = this.state.photos
const photo = this.state.photo
photosNew.push({
photo: photo,
title: '',
thumbnail: false,
image1: false,
image2: false,
tag: '',
});
this.setState({photos: photosNew});
this.setState({photo: '', selectedFile: '', selectedFiles: ''})
document.getElementById("myFile").value = "";
}
removePhoto = (i) => {
debugger
const photos = this.state.photos
const objIndex = photos.filter((obj, index) => {
if(index != i){
return obj
}
});
console.log("objIndex", objIndex)
this.setState({photos: objIndex})
}
updatePhotoObj = (event) => {
const { value, id } = event.target;
console.log("value", value)
console.log("event.target", event.target)
const objIndex = this.state.photos.map((obj, index) => {
if(index == id){
obj.title = value
}
return obj
});
this.setState({photos: objIndex})
}
handleInputChangeRadio = (event) => {
const { name, id} = event.target;
console.log("GET HERE!", name)
console.log("GET HERE!", id)
const objIndex = this.state.photos.map((obj, index) => {
if(index == id){
obj.thumbnail = true
}else{
obj.thumbnail = false
}
return obj
});
this.setState({photos: objIndex})
}
handleInputChangeOne = (event) => {
const { name, id} = event.target;
console.log("GET HERE!", name)
console.log("GET HERE!", id)
const objIndex = this.state.photos.map((obj, index) => {
if(index == id){
obj.image1 = true
}else{
obj.image1 = false
}
return obj
});
this.setState({photos: objIndex})
}
handleInputChangeTwo = (event) => {
const { name, id} = event.target;
console.log("GET HERE!", name)
console.log("GET HERE!", id)
const objIndex = this.state.photos.map((obj, index) => {
if(index == id){
obj.image2 = true
}else{
obj.image2 = false
}
return obj
});
this.setState({photos: objIndex})
}
render() {
const table = {
width: '100%',
paddingTop: '20px'
}
return (
<>
<div class="col-md-12">
<form onSubmit={this.onSubmit}>
<div class="form-group">
<label>Title</label>
<input
class="form-control"
type="text"
name="title"
placeholder="Enter title"
value={this.state.title}
onChange={this.handleInputChange}
/>
</div>
<div class="form-group">
<label>Description</label>
<textarea
class="form-control"
type="text"
rows="10"
name="description"
placeholder="Enter title"
value={this.state.description}
onChange={this.handleInputChange}
/>
</div>
<div class="form-group">
<label for="inputTag">Tag</label>
<select id="inputTag" class="form-control"
value={this.state.tagName}
name="tagName"
onChange={this.handleInputChange}
>
<option value="" disabled selected>Please Choose...</option>
{this.state.tags.map(s =>
<option selected>{s.name}</option>
)}
</select>
</div>
<div class="form-row">
<label>New Photo</label>
</div>
<div class="form-row">
<input type="file" id="myFile" onChange={this.singleFileChangedHandler}/>
<button className="btn btn-secondary" onClick={this.singleFileUploadHandler}>Add Photo</button>
</div>
<div class="form-row">
{this.state.photos.length > 0 ?
<div style={table}>
<div class="table-responsive-sm">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">photos</th>
<th scope="col"></th>
<th scope="col"></th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{this.state.photos.map((x, index) => {
return (
<>
<tr>
<td > <img src={x.photo} alt=""/></td>
<td></td>
<td></td>
<td></td>
<td>
<button class="btn" onClick={()=> this.removePhoto(index)}>remove</button>
<div class="form-check">
<input
class="form-check-input"
type="radio" name="thumb" id={index}
name="thumb"
checked={x.thumbnail}
onChange={this.handleInputChangeRadio}
/>
<label class="form-check-label" for="thumb">
Thumbnail
</label>
</div>
<div class="form-check">
<input
class="form-check-input"
type="radio" name="one" id={index}
name="one"
checked={x.image1}
onChange={this.handleInputChangeOne}
/>
<label class="form-check-label" for="one">
Image 1
</label>
</div>
<div class="form-check">
<input
class="form-check-input"
type="radio" name="two" id={index}
name="two"
checked={x.image2}
onChange={this.handleInputChangeTwo}
/>
<label class="form-check-label" for="two">
Image 2
</label>
</div>
</td>
</tr>
<tr>
<input
class="form-control"
type="text"
value={x.title}
id={index}
onChange={this.updatePhotoObj}
/>
</tr>
</>
);
})}
</tbody>
</table>
</div>
</div>
:
null
}
</div>
<div class="modal-footer">
<input type="submit" value="Submit" class="btn btn-primary"/>
<button type="button" class="btn btn-secondary" data-dismiss="modal" onClick={this.handleClose}>Close</button>
</div>
</form>
</div>
</>
);
}
}
Most importantly you have to add type to the button
<button type="button" class="btn" onClick={()=> this.removePhoto(index)}>remove</button>
Buttons Without type inside form is by default type="submit" so when you click on it, it will submit the form
I think there is better way to filter the array
const filterdPhotos = photos.filter((obj, index) => {
return index != i;
});
this.setState({photos: filterdPhotos})
The reason it triggers your onSubmit is because you have a button inside a form with no specified type.
I believe if you simply declare type="button" to prevent the browser from assuming it's a submit button you should be good to go.
So you would want:
<button class="btn" type="button" onClick={()=> this.removePhoto(index)}>remove</button>
i need to hide the authentication form when user is connected and show it when he click on logout button.
constructor (props) {
super(props);
this.state = {
cnx_mail: '',
cnx_pwd: '',
items: [],
errors: {},
formErrors: {cnx_mail: '', cnx_pwd: ''},
emailValid: false,
passwordValid: false,
formValid: false
}
this.handleUserInput = this.handleUserInput.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
The login button :
handleSubmit = (event) => {
event.preventDefault();
fetch(`${API}/api/connexion`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify ({
email: this.state.cnx_mail,
password: this.state.cnx_pwd,
})
})
.then(res => res.json())
.then(json => {
console.log(json);
//Here we get all the token
localStorage.setItem('head', json.result.split('.')[0]);
localStorage.setItem('payload', json.result.split('.')[1]);
localStorage.setItem('signature', json.result.split('.')[2]);
//Here we get the role to redirect user to accounts (if admin)
roole = JSON.parse(atob(json.result.split('.')[1])).account[0].role === 'admin';
this.setState({ therole : roole });
if(roole) {
console.log(json.result);
this.props.history.push('/accounts');
}
else {
console.log("is user");
}
return roole;
})
}
this code says that if it's a simple user (role == "admin") he will be redirected to accounts page, otherwse (role=="user") he will stay in the same page ("/") but i have to hide the authentication form which is normally logical.
This is the form :
<form className="demoForm" onSubmit={this.handleSubmit} noValidate encType="application/x-www-form-urlencoded">
<div className="alreadysubscribed-input">
<div className={`alreadysubscribed-field group-input ${this.errorClass(this.state.formErrors.cnx_mail)}`}>
<input type="email" required className="form-control fatb-input input-form" name="cnx_mail"
value={this.state.cnx_mail}
id="cnx_mail"
onChange={this.handleUserInput} error={errors.cnx_mail} />
<label className="fatb-label" htmlFor="cnx_mail">Email</label>
<div className="fatb-bar"></div>
</div>
<div className={`alreadysubscribed-field group-input ${this.errorClass(this.state.formErrors.cnx_pwd)}`}>
<input type="password" required className="form-control fatb-input input-form" name="cnx_pwd"
value={this.state.cnx_pwd}
id="cnx_pwd"
onChange={this.handleUserInput} error={errors.cnx_pwd} />
<label className="fatb-label" htmlFor="cnx_pwd">Mot de passe</label>
<div className="fatb-bar"></div>
</div>
</div>
<FormErrors formErrors={this.state.formErrors} />
<div className="btn-cnx">
{/* <span className="mas">Se connecter</span> */}
<button className="fatb-btn bubbly-button btn-anim3 w100p" type="submit" name="cnx_btn" disabled={!this.state.formValid}>se connecter</button>
</div>
</form>
Thank you
App is running on Node.js and React. In database (mongodb used) I have collection Rooms that contains details about particular room.
I have an option to add new room and there is an option to upload image for that particular room.
Here is code for room model.
SERVER PART
UserModel.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Define our model
const roomSchema = new Schema({
title: { type: String },
description: { type: String },
price: { type: Number },
room_type: { type: String },
nb_guests: { type: Number },
imageData: {type: String}
});
// Create the model class
const ModelClass = mongoose.model('room', roomSchema);
// Export the model
module.exports = ModelClass;
This is add route:
room.route.js
// Defined store route
roomRoutes.route('/add').post(function (req, res) {
let room = new Room(req.body);
room.save()
.then(room => {
res.status(200).json({'room': 'room is added successfully'});
})
.catch(err => {
res.status(400).send("unable to save to database");
});
});
And here is form where I add new room:
CreateRoom.js
export default class CreateRoom extends React.Component {
constructor(props) {
super(props);
this.onChangeTitle = this.onChangeTitle.bind(this);
this.onChangeDescription = this.onChangeDescription.bind(this);
this.onChangePrice = this.onChangePrice.bind(this);
this.onChangeGuests = this.onChangeGuests.bind(this);
this.onChangeRoomType = this.onChangeRoomType.bind(this);
this.onImageUpload = this.onImageUpload.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
title: '',
description: '',
price: '',
room_type: '',
nb_guests: '',
imageData: ''
}
}
onChangeTitle(e) {
console.log('title changed');
this.setState({
title: e.target.value
});
}
onChangeDescription(e) {
console.log('description changed');
this.setState({
description: e.target.value
});
}
onChangePrice(e) {
console.log('price changed');
this.setState({
price: e.target.value
});
}
onChangeGuests(e) {
console.log('guests changed');
this.setState({
nb_guests: e.target.value
});
}
onChangeRoomType(e) {
console.log('room changed');
this.setState({
room_type: e.target.value
});
}
onImageUpload = event => {
console.log('picture updated');
this.setState({
imageData: event.target.files[0]
});
}
onSubmit(e) {
e.preventDefault();
console.log(`Form submitted:`);
const newRoom = {
title: this.state.title,
description: this.state.description,
price: this.state.price,
nb_guests: this.state.nb_guests,
room_type: this.state.room_type,
imageData: this.state.imageData
}
axios.post('http://localhost:3090/admin/add', newRoom)
.then(res => console.log(res.data));
this.setState({
title: '',
description: '',
price: '',
room_type: '',
nb_guests: '',
imageData: ''
})
}
render() {
return (
<div>
<Header />
<div style={{ marginTop: 20 }}>
<div className="album py-5 bg-light">
<div className="container">
<h1 class="h3 mb-3 font-weight-bold">Create new room</h1>
<p>Provide all needed details</p>
<div className="row"></div>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label htmlFor="title" className="col-form-label">Title:</label>
<input
type="text"
value={this.state.title}
onChange={this.onChangeTitle}
className="form-control" id="title" />
</div>
<div className="form-group">
<label htmlFor="message-text" className="col-form-label">Description:</label>
<textarea
type="text"
value={this.state.description}
onChange={this.onChangeDescription}
className="form-control" id="description"></textarea>
</div>
<div className="form-group">
<label htmlFor="title" className="col-form-label">Price:</label>
<input
type="text"
value={this.state.price}
onChange={this.onChangePrice}
className="form-control" id="price" />
</div>
<div className="form-group">
<label htmlFor="exampleFormControlSelect1">Number of guests:</label>
<select onChange={this.onChangeGuests} className="form-control" id="exampleFormControlSelect1">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
</select>
</div>
<div className="form-group">
<label htmlFor="exampleFormControlSelect1">Room type:</label>
<select onChange={this.onChangeRoomType} className="form-control" id="exampleFormControlSelect1">
<option>Single</option>
<option>Double</option>
<option>Apartment</option>
</select>
</div>
<div class="form-group">
<label for="exampleFormControlFile1">Upload photo</label>
<input type="file" onChange={this.imageUpload} class="form-control-file" id="exampleFormControlFile1" />
</div>
<br />
<div className="form-group">
<input type="submit" value="Create room" className="btn btn-primary" />
</div>
</form>
</div>
</div>
</div>
</div>
)
}
}
After clicking on Create Room button data is added to database and "something" is added to imageData field in room collection but I think not correctly.
I am trying to display it on LandingPage like this:
LandingPage.js
const Room = props => (
<div className = "col-md-4" >
<div className="card mb-4 shadow-sm">
<img src={props.room.imageData} class="card-img-top" alt="..." width="100%" height="225" />
<div className="card-body">
<h5 class="card-title">{props.room.title}</h5>
<p className="card-text">{props.room.description}</p>
<div className="d-flex justify-content-between align-items-center">
<div className="btn-group">
<Link className="btn btn-sm btn-outline-secondary" to={"/view/"+props.room._id}>View</Link>
</div>
</div>
</div>
</div>
</div >
)
export default class LandingPage extends React.Component {
constructor(props) {
super(props);
this.state = {
rooms: [],
term:''
}
this.onSearchHandler = this.onSearchHandler.bind(this);
}
componentDidMount() {
axios.get('http://localhost:3090/admin/')
.then(response => {
this.setState({
rooms: response.data
})
.catch(function (error) {
console.log(error);
})
})
}
roomList = () => {
const { rooms, term } = this.state;
if (!term) {
return rooms.map(function(currentRoom, i) {
return <Room room={currentRoom} key={i} />;
});
} else {
return rooms
.filter(room => {
return room.nb_guests === term;
})
.map(matchingRoom => {
return <Room room={matchingRoom} />;
});
}
};
onSearchHandler = e => {
this.setState({
term: parseFloat(e.target.value)
});
};
render() {
return (
<div>
<LPheader />
<Carousel />
<div>
<div className="album py-5 bg-light">
<div className="container">
<div className="row">
<form>
<input
type="text"
onChange={this.onSearchHandler}
value={this.state.term}
/>
</form>
{this.roomList()}
</div>
</div>
</div>
</div>
</div>
)
}
}
Using this line of code I am trying to display it but it's not working:
<img src={props.room.imageData} class="card-img-top" alt="..." width="100%" height="225" />
I am not sure am I maybe uploading it wrong to database or am I displaying it wrong.
I have no error but image is just not being displayed.
Any tip is highly appreciated.
Just as you expected it is about the image not being handled correctly, what you saved to the database is the binary of the image represented as text (this might even cause corruption to the image) you need to handle saving the image yourself, and you have two options here:
1) You decide to save the image as a string, and then before saving the image you need to decode it to base64 to ensure that the database does not corrupt it's data, after that you display it directly in the image src, your image src should look something like this
<img src="data:image/png;base64, {base64data==}" />
2) You decide to save the image as file in your webserver, and you handle the link to the file to the image in the image src
I assume that there is some utility for your server out there that do one of the previous steps for you/ or do both depending on the image size. If you don't want to implement that yourself
i I want to insert my my in database.axios is perfect and enter data in db but I want a message 'data is entered' for the user ->
how it is important to insert the message.
thanks
<form>
<div class="well">
<h4> Add User</h4>
<div class="form-group">
<label class="pull-left"> First Name </label>
<input type="text" class="form-control" placeholder="First Name" v-model="User.first_name">
</div>
<div class="form-group">
<label class="pull-left"> Last Name </label>
<input type="text" class="form-control" placeholder="Last Namen" v-model="User.last_name">
</div>
<div class="form-group">
<label class="pull-left"> Email </label>
<input type="text" class="form-control" placeholder="Email " v-model="User.email">
</div>
</div>
<button type="submit" class="btn btn-large btn-block btn-primary full-width" #click="addToAPI">Submit</button>
<button class="btn btn-large btn-block btn-success full-width">Go User</button>
</form>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'hello',
data() {
return {
msg: 'Welcome to Your Vue.js App',
User: { first_name: '', last_name: '', email: '' }
}
},
methods: {
addToAPI() {
let newUser = {
first_name: this.User.first_name,
last_name: this.User.last_name,
email: this.User.email
}
console.log(newUser)
axios.post('http://localhost:3000/(localaccess)',newUser)
.then(response => {
console.log('success:', response)
})
.catch(error => {
console.log('error:', error)
})
}
}
}
</script>
Add a data object where you will store the message, like:
<script>
import axios from 'axios'
export default {
name: 'hello',
data() {
return {
msg: 'Welcome to Your Vue.js App',
User: { first_name: '', last_name: '', email: '' },
message: ''
}
},
methods: {
addToAPI() {
let self = this;
let newUser = {
first_name: this.User.first_name,
last_name: this.User.last_name,
email: this.User.email
}
axios.post('http://localhost:3000/(localaccess)',newUser)
.then(response => {
self.message = 'Data is entered'
})
.catch(error => {
self.message = 'Error'
})
}
}
}
</script>
And now add it to some place ih your template - {{message}}.