Having trouble with ReactJS and Bootstrap in Codepen.io - javascript

I'm getting two specific errors in my project I can't figure out for the life of me. The first one is:
Warning: Each child in an array or iterator should have a unique 'key'
prop.
The next one is as follows:
Cannot read property 'map' of undefined
Yet I know for a fact that each element in my DOM Rendering has a key property and the {recipe.ingredients.map()} is defined and spelled the same everywhere. Any help will be greatly appreciated. Please find my code below.
class RecipeApp extends React.Component {
constructor(props) {
super(props);
this.state = {
currentIndex: 0,
recipes: [
{
recipeName: "Sample Recipe1",
ingredients: ["item1", "item2", "item3", "item4"],
image:
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfkpHkg_PvY3OGFI3FOO80RyvShYc6wfdsbfbMSpnEDDhzzcUJQw",
id: "item1",
method: "In here we have the method with which to assemble the recipe into an edible dish"
},
{
recipeName: "Sample Recipe2",
ingredients: ["item1", "item2", "item3", "item4"],
image:
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRMVo-OeRcXXk-d2F7ymofbRMHBJzrXx8izKbva15aWR0l9Sf1g7A",
id: "item2",
method: "In here we have the method with which to assemble the recipe into an edible dish"
},
{
recipeName: "Sample Recipe3",
ingredients: ["item1", "item2", "item3", "item4"],
image: "http://clubsinnyc.com/img/noimage.jpg",
id: "item3",
method: "In here we have the method with which to assemble the recipe into an edible dish"
}
],
newRecipe: { recipeName: "", ingredients: [], image: "", id: "", method: "" }
};
//console.log(this.state.recipes);
}
updateNewRecipe(recipeName, ingredients, image, method){
this.setState({newRecipe: {recipeName: recipeName, ingredients: ingredients, image: image, method: method}})
}
saveNewRecipe(){
let recipes = this.state.recipes.slice();
var id = function(){
return '_' + Math.random().toString(36).substr(2, 9);
}
recipes.push({recipeName: this.state.newRecipe.recipeName, ingredients: this.state.newRecipe.ingredients, image: this.state.newRecipe.image, id: id, method: this.state.newRecipe.method});
localStorage.setItem("recipes", JSON.stringify(recipes));
this.setState({recipes});
this.setState({newRecipe: {recipeName: "", ingredients: [], image: "", method: ""}});
}
render() {
var { recipes, newRecipe, currentIndex } = this.state;
//console.log(recipes);
return (
<div className="container w3-card">
<div>
{recipes.map((recipe, index) => (
<div className="panel-group w3-margin" id="accordion">
<div className="panel panel-primary">
<div className="panel-heading" eventkey={index} key={index}>
<h2 className="text-center" data-toggle="collapse" data-target={"#" + recipe.id}>{recipe.recipeName}</h2>
</div>
<div className="panel-collapse collapse row" id={recipe.id}>
<div className="panel-body">
<ol className="list-group pull-left col-md-5 w3-margin">
{recipe.ingredients.map((item) => (
<li className="list-group-item" key={item}>{item}</li>
))}
</ol>
<div className="pull-right img-responsive col-md-7" id="image">
<img className="thumbnail" src={recipe.image} alt="recipe-image" id="image" key={index} />
</div>
<div className="container-fluid w3-card pull-left col-md-12" id="method" key={index}>
{recipe.method}
</div>
</div>
</div>
</div>
</div>
))}
<div className="modal fade" tabIndex="-1" role="dialog" id="newModal">
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header w3-black">
<button type="button" className="btn btn-danger pull-right" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 className="modal-title text-center">Add Recipe</h4>
</div>
<div className="modal-body">
<div className="form-group">
<div className="control-label">Recipe Name</div>
<input
className="form-control"
type="text"
value={recipes.recipeName}
onChange={(event) => this.updateNewRecipe(event.target.value, newRecipe.ingredients, newRecipe.image, newRecipe.method)}
placeholder="Please Enter Recipe Name..."
/>
</div>
<div className="form-group">
<div className="pull-left">List Ingredients:</div><br/>
<textarea
className="pull-left"
type="textarea"
value={recipes.ingredients}
onChange={(event) => this.updateNewRecipe(newRecipe.recipeName, event.target.value.split(","), newRecipe.image, newRecipe.method)}
placeholder="Please list the ingredients [Seperated by commas]"
/>
<div className="pull-right">Image Link:</div><br/>
<input
className="pull-right"
type="text"
value={recipes.image}
onChange={(event) => this.updateNewRecipe(newRecipe.recipeName, newRecipe.ingredients, event.target.value, newRecipe.method)}
placeholder="Supply a link to an image."
/>
</div>
<br/>
<div className="form-group">
<div className="control-label">Method:</div>
<textarea
className="form-control"
type="textarea"
value={recipes.method}
onChange={(event) => this.updateNewRecipe(newRecipe.recipeName, newRecipe.ingrediets, newRecipe.image, event.target.value)}
placeholder="Enter recipe method here..."
/>
</div>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" className="btn btn-primary" data-dismiss="modal" onClick={(event) => this.saveNewRecipe()}>Save Recipe</button>
</div>
</div>
</div>
</div>
</div>
<button type="button" className="btn btn-primary btn-lg w3-margin" data-toggle="modal" data-target="#newModal">New Recipe</button>
</div>
);
}
}
ReactDOM.render(<RecipeApp />, document.getElementById("content"));

The issue seems to be that you weren't binding your functions properly. For example, saveNewRecipe. You can bind your function easily like so:
saveNewRecipe = () => {}
I've fixed it for you here: https://codesandbox.io/s/yjp6npx14v

Related

Vue.JS 3, Bootstrap 5, Laravel 9 - Modal Not Displaying

I am building a registration form. It contains a button which opens a Bootstrap 5 modal over the top of the form. I intent to use it to allow the potential user to verify their account ownership.
However, the Modal it doesn't display at all.
Troubleshooting performed so far
I have added a console.log to the openmodal method and it's logging correctly.
I have also attempted to load the modal on mount, however this also did not work.
Code
<template>
<!-- Modal -->
<div
class="modal fade"
tabindex="-1"
role="dialog"
id="verificationModal"
ref="verificationModal"
v-if="showModal"
>
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Verify Summoner Account</h5>
<button
type="button"
class="btn-close"
data-dismiss="modal"
aria-label="Close"
#click="closeModal"
></button>
</div>
<div class="modal-body">
<p>
Please change your summoner account icon to the following image:
</p>
<div class="summoner-icon-container">
<img
:src="randomSummonerIcon"
alt="Random Summoner Icon"
class="summoner-icon"
/>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" #click="verifySummoner">
Verify
</button>
<button
type="button"
class="btn btn-secondary"
data-dismiss="modal"
#click="closeModal"
>
Close
</button>
</div>
</div>
</div>
</div>
<!-- Form -->
<div>
<form #submit.prevent="submitForm">
<div class="form-group">
<label for="username">Username</label>
<input
v-model="form.username"
type="text"
class="form-control"
id="username"
aria-describedby="usernameHelp"
placeholder="Enter username"
/>
<div v-if="errors.username" class="invalid-feedback">
{{ errors.username[0] }}
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input
v-model="form.password"
type="password"
class="form-control"
id="password"
placeholder="Enter password"
/>
<div v-if="errors.password" class="invalid-feedback">
{{ errors.password[0] }}
</div>
</div>
<div class="form-group">
<label for="email">Email</label>
<input
v-model="form.email"
type="email"
class="form-control"
id="email"
aria-describedby="emailHelp"
placeholder="Enter email"
/>
<div v-if="errors.email" class="invalid-feedback">
{{ errors.email[0] }}
</div>
</div>
<div class="form-group">
<label for="summoner_name">Summoner Name</label>
<input
v-model="form.summoner_name"
type="text"
class="form-control"
id="summoner_name"
placeholder="Enter summoner name"
/>
<div v-if="errors.summoner_name" class="invalid-feedback">
{{ errors.summoner_name[0] }}
</div>
</div>
<button
type="submit"
v-if="form.summoner_verified"
class="btn btn-primary"
>
Submit
</button>
</form>
<button
v-if="!form.summoner_verified"
#click="openModal"
class="btn btn-secondary"
>
Verify Summoner
</button>
</div>
</template>
<script>
import axios from "axios"
export default {
data() {
return {
form: {
username: "",
password: "",
email: "",
summoner_name: "",
summoner_verified: false,
},
errors: {},
showModal: false,
}
},
mounted() {
$(this.$refs.verificationModal).modal()
},
methods: {
openModal() {
this.showModal = true
console.log("Model Opened")
},
closeModal() {
this.showModal = false
console.log("Model Closed")
},
submitForm() {
axios
.post("/api/register", this.form)
.then((response) => {
// redirect to dashboard or display success message
})
.catch((error) => {
this.errors = error.response.data.errors
})
},
verifySummoner() {
axios
.post("/api/verify-summoner", {
summoner_name: this.form.summoner_name,
})
.then((response) => {
this.form.summoner_verified = response.data.summoner_verified
this.form.rank = response.data.rank
if (this.form.summoner_verified) {
this.closeModal()
}
})
.catch((error) => {
console.log(error)
})
},
},
}
</script>

Custom React component(react-hook) not re-rendering

I have a component that fetches data from my mongoDB it then renders a list of child components. It the "list" component I have a post that adds a new member to the database. Upon addition im trying to get the list to re-fetch the data and re-render the list component.
List Component:
import React, { useState, useEffect } from "react";
import axios from "axios";
import Spinner from "react-bootstrap/Spinner";
import { toast } from "react-toastify";
import DatePicker from "react-datepicker";
import useForm from "react-hook-form";
import { css } from "glamor";
import "react-toastify/dist/ReactToastify.css";
import "react-datepicker/dist/react-datepicker.css";
import "../Styles/ReactDatePicker.css";
import Member from "./Member";
const { getFamily, getMembers, postMember } = require("../Utils/Service");
const MemberList = () => {
const [family, setFamily] = useState({});
const [familyMembers, setFamilyMembers] = useState([]);
const [loading, setLoading] = useState(true);
const [date, setDate] = useState(new Date());
const { handleSubmit, register, errors } = useForm();
async function fetchData() {
getFamily.then(result => {
setFamily(result);
});
getMembers.then(result => {
try {
setFamilyMembers(
result.map((child, index) => (
<Member
key={index}
index={child._id}
balance={child.balance}
firstName={child.firstName}
lastName={child.lastName}
birthday={child.birthday}
role={child.role[0]}
/>
))
);
} catch (e) {
toast.error("500: Error with Service Call", {
position: "top-right",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
className: css({
background: "#ed5565 !important"
})
});
} finally {
setLoading(false);
}
});
}
useEffect(() => {
if (loading) {
fetchData();
}
}, [loading]);
// const handleDateChange = date => {
// setDate(date)
// }
const onSubmit = data => {
data.familyId = "5dddf14df965552b3da57be1";
postMember(data).then(
????????????
);
};
return (
<div className="ibox">
<div className="ibox-title">
<h5>{family.name}</h5>
<div className="ibox-tools">
<span className="label label-warning-light float-right">
{familyMembers.length} Member(s)
</span>
</div>
</div>
<div className="ibox-content">
<div className="feed-activity-list">
{loading ? (
<Spinner animation="grow" role="status" variant="dark">
<span className="sr-only">Loading...</span>
</Spinner>
) : (
familyMembers
)}
</div>
<div className="d-flex">
<a
className="btn btn-primary text-white m-t"
data-toggle="modal"
data-target={"#newMemberModel"}
>
<i className="fa fa-plus"></i> New Member
</a>
<a
className="btn btn-danger text-white m-t m-l"
data-toggle="modal"
data-target={"#removeMemberModel"}
>
<i className="fa fa-minus"></i> Remove Member
</a>
</div>
</div>
{/* New Member Model */}
<div
className="modal inmodal"
id={"newMemberModel"}
tabIndex="-1"
role="dialog"
style={{ display: "none" }}
aria-hidden="true"
>
<div className="modal-dialog">
<div className="modal-content animated fadeIn">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
<span className="sr-only">Close</span>
</button>
<h4 className="modal-title">New Family Member</h4>
</div>
<form onSubmit={handleSubmit(onSubmit)}>
<div className="modal-body">
<div className="row">
<div className="col">
<div className="form-group">
<label>First Name</label>
<input
type="text"
placeholder="First Name"
className="form-control"
name="firstName"
ref={register({
required: true,
pattern: {
value: /^[a-zA-Z]+$/i,
message: "Invalid First Name"
}
})}
/>
<div className="text-danger">
{errors.firstName && errors.firstName.message}
</div>
</div>
<div className="form-group">
<label className="font-normal">Birthday</label>
<div className="input-group date">
{/* <DatePicker
selected={date}
onChange={handleDateChange}
placeholderText="Click to select a date"
isClearable
peekNextMonth
showMonthDropdown
showYearDropdown
dropdownMode="select"
ref={e =>register({
name: "Birthday",
required: false
})}
/> */}
<input
type="text"
placeholder="01/01/01"
className="form-control"
name="birthDate"
ref={register({
required: false
})}
/>
</div>
</div>
</div>
<div className="col">
<div className="form-group">
<label>Last Name</label>
<input
type="text"
placeholder="Last Name"
className="form-control"
name="lastName"
ref={register({
required: true,
pattern: {
value: /^[a-zA-Z]+$/i,
message: "Invalid Last Name"
}
})}
/>
<div className="text-danger">
{errors.lastName && errors.lastName.message}
</div>
</div>
<div className="form-group">
<label>Role</label>
<select
className="custom-select"
name="role"
ref={register({ required: true })}
>
<option defaultValue>Select Role</option>
<option value="Adult">Adult</option>
<option value="Child">Child</option>
</select>
</div>
</div>
</div>
</div>
<div className="modal-footer">
<button
type="button"
className="btn btn-white"
data-dismiss="modal"
>
Close
</button>
<button type="submit" className="btn btn-primary">
Add Member
</button>
</div>
</form>
</div>
</div>
</div>
{/* Remove Member Model */}
<div
className="modal inmodal"
id={"removeMemberModel"}
tabIndex="-1"
role="dialog"
style={{ display: "none" }}
aria-hidden="true"
>
<div className="modal-dialog">
<div className="modal-content animated fadeIn">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
<span className="sr-only">Close</span>
</button>
<h4 className="modal-title">Remove Family Member</h4>
</div>
<div className="modal-body"></div>
<div className="modal-footer">
<button
type="button"
className="btn btn-white"
data-dismiss="modal"
>
Close
</button>
<button type="button" className="btn btn-danger">
Remove Member
</button>
</div>
</div>
</div>
</div>
</div>
);
};
export default MemberList;
within the code in the onSubmit function with posts the data inside the .then is where im trying to re-render the entire component and/or fetch the data agin.
right now, your useEffect is only dependent on the property loading, if you change the property then the effect will run again.
https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect
In your component, you can call this.forceUpdate() to force a rerender.
I think you can also call your fetchData function again inside your .then() block, if you make the callback inside the .then() an async function.
postMember(data).then(
async () => this.fetchData()
);
or
postMember(data).then(
() => this.forceUpdate()
);

Update value in Firebase and React

I have added a menu in my database in firebase and now I want to edit the menu in the database. But whenever I send a request to update the menu it only updates the first menu. No matter which menu I choose, it always updates the first menu in the database.
This is my part of an editMenu component which has a button that links to EditmenuForm.
`
contentMenuKeys.map(t=>{
// if (t === this.state.Appetizer)`
return(
<div className="text-center">
<h4>{t}</h4>
<div className="row">
{Object.keys(this.props.menu[t]).map(menu=>{
return(
[this.props.menu[t][menu]].map(item=>{
return(
<div className="col-md-6 menuItems" >
<div className="textM d-flex">
<div className="one-half">
<h3>{item.Name}</h3>
<p><span>{item.Description}</span></p>
</div>
<div className="one-forth">
<span className="price">${item.Price}</span>
<p><span>
<button type="button" className="btn btn-primary" data-toggle="modal" data-target="#MenuEditModal">Edit</button ><MenuEditForm Menu_Type={t} Name={item.Name}Description={item.Description} Price={item.Price}iID={menu} rID={queryString.parse(this.props.location.search).id }/>{" "}
<button type="submit" onClick={()=>{this.props.deleteMenu({rID:queryString.parse(this.props.location.search).id,Menu_Type:t,iID:menu})}} className="btn btn-danger ml-2">Remove</button>
</span></p>
</div>
</div>
</div>
)
})
)
})
}`
And below is MenuEditForm component which has edit menu form.
`import React,{Component} from 'react'
import {connect} from "react-redux"
import propTypes from "prop-types"
import { editMenu } from "../../actions/addMenu"
export class MenuEditForm extends Component {
state={
Name:"",
Description: "",
Price:"",
Menu_Type:"",
rID:""
}static propTypes={
editMenu: propTypes.func.isRequired
}`
onChange=e=> this.setState({[e.target.name]:e.target.value});
onSubmit=e=>{
console.log("reached");
e.preventDefault();
const { Name, Description, Price, rID, Menu_Type } = this.state;
const menu = { Name, Description, Price, Menu_Type, rID, iID:this.props.iID };
this.props.editMenu(menu);
this.setState({
Name:"",
Description: "",
Price:"",
Menu_Type:"",
});
}
componentDidMount(){
this.setState({rID:this.props.rID})
}
render(){const {Name, Description, Price, Menu_Type}=this.state;
return(
<div>
<form onSubmit={this.onSubmit}>
<div className="modal fade" id="MenuEditModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title" id="exampleModalLabel">Edit Items</h5>
<button type="button" className="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<div>
<div className="modal-body">
<div className="ml-4 mr-4 mt-4 mb-4">
<div className="form-group">
<label>Menu_Type</label>
<select name="Item Type" id="Item-Type" value={Menu_Type} onChange={this.onChange} name="Menu_Type">
<option value="None">None</option>
<option value="Appetizers">Appetizers</option>
<option value="Entrees">Entrees</option>
</select>
</div>
<div className="form-group">
<label>Name</label>
<input
className="form-control"
type="text"
name="Name"
onChange={this.onChange}
value={Name}
required
/>
</div>
<div className="form-group">
<label>Description</label>
<input
className="form-control"
type="text"
name="Description"
onChange={this.onChange}
value={Description}
required
/>
</div>
<div className="form-group">
<label>Price</label>
<input
className="form-control"
type="text"
name="Price"
onChange={this.onChange}
value={Price}
required
/>
</div>
</div>
<div className="modal-footer">
<button type="button" id="cancel" className="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="submit" className="btn btn-primary" >Change Items</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
)
}}export default connect(null,{editMenu})(MenuEditForm)
This is my editMenu action
export const editMenu =(item) =>(dispatch)=>{
axios
.post("/api/database/editMenu", item)
.then(res => {
dispatch({
type:EDIT_MENU,
payload:res.data
});
})
.catch(err=>
dispatch(returnErrors(err.response.date,err.response.status)));
My editMenuAPI
class editMenuAPI(generics.GenericAPIView):
permission_classes=[
permissions.AllowAny
]
def post(self, request):
try:
print(request.data)
db = firebase.editMenu(request.data)
return Response({
"status": "success"
})
except:
return Response({
"status":"Disconnected",
"msg": 'There was a problem'
})
This is editMenu function in firebase.
def editMenu(request):
db=credentials().database()
mType = request['Menu_Type']
rID=request['rID']
iID =request['iID']
print(request)
request.pop("Menu_Type")
request.pop('rID')
request.pop('iID')
return db.child('Restaurants').child(rID).child("Menu").child(mType).child(iID).update(request)

email real time component in react

I'm trying to create a mailbox component in order to get the real-time data displayed in my mailbox component I use trumbowyg for creating the WYSIWYG editor and bootstrap but I can't manage to get it real-time
<script type="text/babel">
var Modal = React.createClass({
render: function () {
return (
<div className="modal fade" tabIndex="-1" role="dialog">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" ><span>×</span></button>
<h4 className="modal-title">{this.props.title}</h4>
</div>
<div className="modal-body">
{this.props.body}
</div>
<div className="modal-footer">
<div className="btn-toolbar pull-right" role="toolbar">
<div className="btn-group" role="group">
<button type="button" className="btn btn-danger outline" data-dismiss="modal">Close</button>
</div>
</div>
<div className="clearfix" />
</div>
</div>
</div>
</div>
);s
}
});
var Editor = React.createClass({
getDefaultProps: function () {
return {
body: "",
placeholder: "Enter your message here..."
};
},
componentWillReceiveProps: function (nextProps) {
if (nextProps.body == ""){
$('#editor').trumbowyg('empty');
}
},
componentDidMount: function () {
var that = this;
$('#editor').trumbowyg({
fullscreenable: false
})
.on('tbwchange', function (){
that.props.onChange($('#editor').trumbowyg('html'));
});
$('#editor').trumbowyg('html', this.props.body);
},
render: function () {
return <div id="editor" placeholder={this.props.placeholder} ></div>;
}
});
var Mailbox = React.createClass({
getInitialState: function () {
return {
"emailTo": "",
"emailCC": "",
"emailBCC": "",
"emailSubject": "",
"emailBody": ""
}
},
render: function () {
return (
<div className="panel panel-default">
<div className="panel-heading">
<div className="row">
<div className="col-xs-8 center">
<div className="inbox-title">
<span className="glyphicon glyphicon-envelope center"></span>
<h2 className="center">{this.props.title}</h2>
</div>
</div>
<div className="col-xs-4 center">
<div className="inbox-avatar text-right">
<img src={this.props.urlImage} />
<div className="inbox-avatar-name"><a href={this.props.link}>{this.props.username}</a></div>
</div>
</div>
</div>
<hr />
<div className="row">
<div className="col-xs-12">
<form className="form-horizontal">
<div className="form-group">
<label htmlFor="email-to" className="col-sm-1 control-label">To</label>
<div className="col-sm-11">
<input type="email"
className="form-control"
id="email-to"
value={this.state.emailTo}
placeholder="Ex: hello#example.com"
onChange={this.handleEmailToChange}/>
</div>
</div>
<div className="form-group">
<label htmlFor="email-cc" className="col-sm-1 control-label">CC</label>
<div className="col-sm-11">
<input type="email"
className="form-control"
id="email-cc"
value={this.state.emailCC}
onChange={this.handleEmailCCChange}/>
</div>
</div>
<div className="form-group">
<label htmlFor="email-bcc" className="col-sm-1 control-label">BCC</label>
<div className="col-sm-11">
<input type="email"
className="form-control"
id="email-bcc"
value={this.state.emailBCC}
onChange={this.handleEmailBCCChange}/>
</div>
</div>
<div className="form-group">
<label htmlFor="email-subject" className="col-sm-1 control-label">Subject</label>
<div className="col-sm-11">
<input type="email"
className="form-control"
id="email-subject"
value={this.state.emailSubject}
onChange={this.handleEmailSubjectChange}/>
</div>
</div>
</form>
</div>
</div>
</div>
<div className="panel-body">
<Editor onChange={this.handleEditorChange}
body={this.state.emailBody} />
</div>
<div className="panel-footer">
<div className="btn-toolbar pull-right" role="toolbar">
<div className="btn-group" role="group">
<button type="button" onClick={this.handleCancelClick} className="btn btn-danger">CANCEL</button>
<button type="button" onClick={this.handleSaveClick} className="btn btn-success">SAVE</button>
</div>
<div className="btn-group" role="group">
<button type="button" onClick={this.handleSendClick} className="btn btn-primary outline">SEND</button>
</div>
<Modal ref="modalSend" title="Email sent!" body="Your email has been successfully sent!" />
<Modal ref="modalSave" title="Email saved!" body="Your email has been successfully saved!" />
</div>
<div className="clearfix" />
</div>
</div>
);
},
handleEditorChange: function (emailBody) {
this.setState({ "emailBody": emailBody });
},
handleEmailToChange: function (e) {
this.setState({ "emailTo": e.target.value });
},
handleEmailCCChange: function (e) {
this.setState({ "emailCC": e.target.value });
},
handleEmailBCCChange: function (e) {
this.setState({ "emailBCC": e.target.value });
},
handleEmailSubjectChange: function (e) {
this.setState({ "emailSubject": e.target.value });
},
handleCancelClick: function () {
this.setState({
"emailTo": "",
"emailCC": "",
"emailBCC": "",
"emailSubject": "",
"emailBody": ""
});
},
handleSaveClick: function () {
$(ReactDOM.findDOMNode(this.refs.modalSave)).modal();
},
handleSendClick: function () {
$(ReactDOM.findDOMNode(this.refs.modalSend)).modal();
}
});
var options = {
username: "Michel lompret",
link: "https://google.com",
urlImage: "http://lorempicsum.com/futurama/350/200/1",
title: "React Mailbox Editor"
};
var element = React.createElement(Mailbox, options);
ReactDOM.render(element, document.querySelector('.container'));
</script>
Is there a way to get back my gmail or outlook mails in my mailbox component and send email from it like a real time app ?
From their docs....
https://developers.google.com/gmail/api/guides/push
You would need to setup a watch, then callback when your watch changes...
Also from their docs....
https://developers.google.com/gmail/api/guides/sync

How to delete an item from a list from another component

I'm new to reactjs. I'm trying to get closer to it by creating a simple page where you can add, modify and delete some entries.
My question is now: How can I achieve to delete an entry from a list. I have the following components:
This one is for displaying the list (component CompanyList):
import React, { Component } from 'react';
import Company from './Company';
class CompanyList extends Component {
constructor(props) {
super(props);
this.state = {
search: '',
companies: props.companies
};
}
updateSearch(event) {
this.setState({ search: event.target.value.substr(0,20) })
}
addCompany(event) {
event.preventDefault();
let nummer = this.refs.nummer.value;
let bezeichnung = this.refs.bezeichnung.value;
let id = Math.floor((Math.random()*100) + 1);
$.ajax({
type: "POST",
context:this,
dataType: "json",
async: true,
url: "../data/post/json/companies",
data: ({
_token : window.Laravel.csrfToken,
nummer: nummer,
bezeichnung : bezeichnung,
}),
success: function (data) {
id = data.Nummer;
this.setState({
companies: this.state.companies.concat({id, nummer, bezeichnung})
})
this.refs.bezeichnung.value = '';
this.refs.nummer.value = '';
}
});
}
render() {
let filteredCompanies = this.state.companies.filter(
(company) => {
return company.bezeichnung.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1;
}
);
return (
<div>
<div className="row">
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">Search</div>
<div className="col-xs-12 col-sm-12 col-md-9 col-lg-9">
<div className="form-group">
<input className="form-control" type="text" value={this.state.search} placeholder="Search" onChange={this.updateSearch.bind(this)} />
</div>
</div>
</div>
<form onSubmit={this.addCompany.bind(this)}>
<div className="row">
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">Create new entry</div>
<div className="col-xs-12 col-sm-12 col-md-3 col-lg-3">
<div className="form-group">
<input className="form-control" type="number" ref="nummer" placeholder="New company no." required />
</div>
</div>
<div className="col-xs-12 col-sm-12 col-md-3 col-lg-3">
<div className="form-group">
<input className="form-control" type="text" ref="bezeichnung" placeholder="New company name" required />
</div>
</div>
<div className="col-xs-12 col-sm-12 col-md-3 col-lg-3">
<div className="form-group">
<button type="submit" className="btn btn-default">Add new company</button>
</div>
</div>
</div>
</form>
<div className="row">
<div className="col-xs-10 col-sm-10 col-md-10 col-lg-10">
<ul>
{
filteredCompanies.map((company)=> {
return (
<div>
<Company company={company} key={company.id} />
</div>
);
})
}
</ul>
</div>
</div>
</div>
);
}
}
export default CompanyList
As you can see, I have another Company component, where each company is displayed. This is the component Company:
import React, { Component } from 'react';
import CompanyOptions from './CompanyOptions';
class Company extends Component {
constructor(props) {
super(props);
this.state = {
company: props.company,
onClick: props.onClick,
editFieldsCss: "displayNone",
optionFieldsCss: "modal fade",
deletionFieldsCss: "displayNone",
currentCompany: props.company,
};
}
editCompany(event) {
event.preventDefault();
let nummer = this.refs.companyNummer.value;
let bezeichnung = this.refs.companyBezeichnung.value;
let id = this.state.company.id;
$.ajax({
type: "POST",
context:this,
dataType: "json",
async: true,
url: "../data/post/json/companies/edit",
data: ({
_token : window.Laravel.csrfToken,
nummer: nummer,
bezeichnung : bezeichnung,
}),
success: function (data) {
this.props.company.id = id;
this.props.company.nummer = nummer;
this.props.company.bezeichnung = bezeichnung;
this.toggleEditFields();
this.toggleOptionFields();
$('#' + this.props.company.id).modal('hide');
}
});
}
deleteCompany(event) {
event.preventDefault();
let nummer = this.refs.companyNummer.value;
let bezeichnung = this.refs.companyBezeichnung.value;
let id = this.state.company.id;
$.ajax({
type: "POST",
context:this,
dataType: "json",
async: true,
url: "../data/post/json/companies/delete",
data: ({
_token : window.Laravel.csrfToken,
id : id,
nummer: nummer,
bezeichnung : bezeichnung,
}),
success: function (data) {
if(data == true) {
this.toggleEditFields();
this.toggleOptionFields();
$('#' + this.props.company.id).modal('hide');
this.setState({company:""});
}
}
});
}
toggleEditFields() {
var css = (this.state.editFieldsCss === "displayNone") ? "displayBlock" : "displayNone";
this.setState({"editFieldsCss":css});
}
toggleDeletionFields() {
var css = (this.state.deletionFieldsCss === "displayNone") ? "displayBlock" : "displayNone";
this.setState({"deletionFieldsCss":css});
}
toggleOptionFields() {
/*
var css = (this.state.optionFieldsCss === "modal fade in displayBlock") ? "modal fade" : "modal fade in displayBlock";
this.setState({
"optionFieldsCss":css,
currentCompany: this.company
});
*/
$('#' + this.state.company.id).modal();
}
render() {
return (
<div>
<li>
<div className="cursorPointer" onClick={this.toggleOptionFields.bind(this)}>
{this.props.company.nummer} {this.props.company.bezeichnung}
</div>
<div className={this.state.optionFieldsCss} id={this.state.company.id} tabIndex="-1" role="dialog">
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 className="modal-title">Company entry "{this.props.company.bezeichnung}"</h4>
</div>
<div className="modal-body">
<div key={this.state.company.id}>
<div>
<form onSubmit={this.editCompany.bind(this)}>
<div className="row">
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<strong>Modify company entry:</strong>
</div>
</div>
<div className="row">
<div className="col-xs-4 col-sm-4 col-md-4 col-lg-4">
Company no.
</div>
<div className="col-xs-4 col-sm-4 col-md-4 col-lg-4">
<div className="form-group">
<input className="form-control" type="number" min="1" step="1" ref="companyNummer" placeholder="Company no." defaultValue={this.state.company.nummer} required />
</div>
</div>
</div>
<div className="row">
<div className="col-xs-4 col-sm-4 col-md-4 col-lg-4">
Company name
</div>
<div className="col-xs-4 col-sm-4 col-md-4 col-lg-4">
<div className="form-group">
<input className="form-control" type="text" ref="companyBezeichnung" placeholder="Company name" defaultValue={this.state.company.bezeichnung} required />
</div>
</div>
</div>
<div className="row">
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<div className="form-group">
<button type="submit" className="btn btn-success"><span className="glyphicon glyphicon-edit"></span> Save edits</button>
</div>
</div>
</div>
</form>
<form onSubmit={this.deleteCompany.bind(this)}>
<div className="row">
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<div className="form-group">
<button type="button" onClick={this.toggleDeletionFields.bind(this)} className="btn btn-danger"><span className="glyphicon glyphicon-remove"></span> Delete company entry</button>
</div>
</div>
</div>
<div className="row" className={this.state.deletionFieldsCss}>
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
Please confirm deletion!
</div>
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12 ">
<div className="form-group">
<button type="submit" className="btn btn-default">Yes</button>
<button type="button" className="btn btn-default marginLeft15px" onClick={this.toggleDeletionFields.bind(this)}>No</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</li>
</div>
);
}
}
export default Company
How gets the CompanyList now the information, when I delete an item in Company? In Company I cannot access CompanyList, can I?
I wouldn't pass whole parent object to the children because that kind of breaks encapsulation. Instead I would pass it only a function which would get called when item is deleted in the Company. This function would be of CompanyList.
So in CompanyList you would have function, e.g.
onCompanyItemDelete = function(arg){
...
}
when rendering companies you would have something like:
<Company onItemDelete={this.onCompanyItemDelete.bind(this)} company={company} key={company.id} />
and in Company you would call function when needed as this.props.onItemDelete.
To know more, you can check some other SO posts about passing function to child components or here.
Of course you can.
For example you can pass a reference to the CompanyList as one of the props in Company component:
<Company parent={this} company={company} key={company.id} />
And then call any methods available in the CompanyList to notify it of changes, upon call CompanyList might update its state and trigger rerender.

Categories

Resources