I hope everyone is having a good day.
I am working with the bible.org API to create a learning app for the bible.
bible.org gives the option to input their widget on your own website.
When you finish creating your widgets they give you this:
Paste the following code into your website or blog.
BIBLESEARCH.widget({
"background": "FFFFFF",
"color": "E2615C"
});
I am using Reactjs and would like to implement it in my Header component.
I provided an example of my H
import React from 'react';
import {startNewBookAction} from '../Actions/index';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {Link} from 'react-router-dom';
import axios from 'axios';
import {bibleBooks} from '../../data/bibleBooks';
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {
book:"Genesis"
};
}//end of constructor
handleNewBook() {
let userBook = this.state.book;
console.log('The book chosen by the user', this);
this.props.startNewBookAction(userBook)
}//handleNewBook
handleLogout() {
console.log('loging out..');
axios.delete('/login').then(res => {
console.log('back from the server with', res);
window.location = "/?#/user";
})
}//end of handleLogout
showBibleBooks() {
//displays the option tag for every book in the bible
console.log('showing the books');
let books = bibleBooks;
return(
books.map((b, id) => {
return (
<option value={b} key={id}>{b}</option>
);
})
);//end of return
}//end og showBibleBooks
start() {
console.log('start', this)
}//end of start
render() {
return (
<div id="UserHeader">
<header className="main-header">
<div className="logo"><a href="index.html" >BBS</a></div>
<div className="navbar navbar-static-top">
<div className="btn-grps pull-right">
<a className="pink-btn dark-btn" onClick={this.handleLogout.bind(this)} >Logout</a>
<a className="pink-btn" data-toggle="modal" data-target="#myModal">New Book</a>
</div>
</div>
</header>
<div className="col-md-4 ">
<div id="myModal" className="modal fade" role="dialog">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal">×</button>
<form onSubmit={this.handleNewBook.bind(this)}>
<h4 className="modal-title" >New Book</h4>
<label htmlFor="book">Book:</label>
<select name="book" id="" onChange={event => this.setState({book:event.target.value})}>
{this.showBibleBooks()}
</select>
<input type="button" value="Start0" onClick={this.start.bind(this)}/>
</form>
</div>
<div className="modal-body">
</div>
<div className="modal-footer">
<button type="button" className='btn btn-success' data-dismiss="modal" id="signupSubmit" onClick={this.handleNewBook.bind(this)}> Enter</button>
</div>
</div>
</div>
</div>
</div>
</div>
);
}//end of render
}//end of classNameName
function mapDispatchToProps(dispatch) {
return bindActionCreators({
startNewBookAction
},
dispatch)
}
function mapStateToProps(state) {
return {
newBook:state
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Header);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
eader component. How can I implement this widget in my app.
Try to add after constructor:
componentWillMount () {
const script = document.createElement("script");
script.src = "//bibles.org/widget/client";
script.async = true;
document.body.appendChild(script);
}
Related
I just started watching some guide on youtube how to make simple fronend in React with bootstrap. I'm stuck for hours on one step since on react-router-dom v6 I can't use history anymore and as I'm using React class comp, I don't know how to implement "useNavigate" to my code. Thing that I want to do is when I add new book to go back to home page which is "/books". Here is my code:
import React, { Component } from 'react';
import {Link} from 'react-router-dom';
import BookService from '../services/BookService';
class CreateBookComponent extends Component {
constructor(props){
super(props)
this.state={
bookName: "",
authorName: ""
}
this.changeBookNameHandler = this.changeBookNameHandler.bind(this);
this.changeAuthorNameHandler = this.changeAuthorNameHandler.bind(this);
this.saveBook = this.saveBook.bind(this);
}
changeBookNameHandler = (event) => {
this.setState({bookName: event.target.value});
}
changeAuthorNameHandler = (event) => {
this.setState({authorName: event.target.value});
}
saveBook = (e) => {
e.preventDefault();
let book = {bookName: this.state.bookName, authorName: this.state.authorName};
console.log('book => ' + JSON.stringify(book));
BookService.createBook(book).then(res => {
**here is where did guy in guide called this.props.history.push('books');**
});
}
render() {
return (
<div>
<div className='container mt-2'>
<div className='row'>
<div className='card col-md-6 offset-md-3 offset-md-3'>
<h1 className='text-center'>Add Book</h1>
<div className='card-body'>
<form>
<div className='form-group'>
<label> Book Name</label>
<input placeholder='Book Name' name='bookName' className='form-control'
value={this.state.bookName} onChange={this.changeBookNameHandler}/>
</div>
<div className='form-group mt-2'>
<label> Author Name</label>
<input placeholder='Author Name' name='authorName' className='form-control'
value={this.state.authorName} onChange={this.changeAuthorNameHandler}/>
</div>
<button className='btn btn-success mt-2' onClick={this.saveBook}>Save</button>
<Link to="/books" className="btn btn-danger mt-2" style={{marginLeft: '10px'}}>Cancel</Link>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default CreateBookComponent;
You can try this:
saveBook = (e) => {
e.preventDefault();
let book = {bookName: this.state.bookName, authorName: this.state.authorName};
console.log('book => ' + JSON.stringify(book));
BookService.createBook(book).then(res => {
window.location.href = "youWebsiteUrl" + "/books"
});
}
I am working on a website where login, register and forgot password popups will appear alternatively (not at a time). So I want to create a modal with multiple body content components.
But I am unable to figure out how to display those. When I click on login or register button Modal content is attaching to modal, but not displaying
Footer.js
import React, { Component } from 'react'
import ModalTemplate from './modals/ModalTemplate'
class Footer extends React.Component {
render() {
return (<><ModalTemplate /></>)
}
}
export default Footer
Footer.js
import React, { Component } from 'react'
import ReactDOM from "react-dom"
import LoginModalBody from './modals/LoginModalBody'
import RegisterModalBody from './modals/RegisterModalBody'
class Header extends Component {
Login() {
ReactDOM.render(<LoginModalBody />, document.getElementById('common_modal_content'));
}
Register() {
ReactDOM.render(<RegisterModalBody />, document.getElementById('common_modal_content'));
}
render() {
return (
<div className='fd bg_Header height_100vh p_5'>
<div className='mainSize'>
<div className="fd">
<div className="row m_0 p_tb_15">
<div className="col-sm-4 col-md-4">
<img className="logoSize" src={Constants.Application.PUB_URL + "/img/logo.svg"} />
<img src={Constants.Application.PUB_URL + "/img/icons/menu.svg"} className="float-right m_r_15 pointer menuIcn"
width="30px" />
</div>
<div className="col-sm-8 col-md-8">
<span className="pointer" onClick={this.Login}>LOGIN
</span> | <span className="pointer" onClick={this.Register}>REGISTER </span>
</div>
</div>
</div>
</div>
)
}
}
export default Header
ModalTemplate.js
import React, { Component } from 'react'
class ModalTemplate extends React.Component {
render() {
return (<> <div id="common_modal" tabindex="-1" role="dialog" class="modal fade">
<div class="modal-dialog">
<div class="modal-content" id="common_modal_content">
</div>
</div>
</div></>);
}
}
export default ModalTemplate;
LoginModalBody .js
import React, { Component } from 'react'
class LoginModalBody extends React.Component {
showModal() {
document.getElementById('common_modal').classList.add('in')
document.getElementById('common_modal').classList.add('show')
}
hideModal() {
document.getElementById('common_modal').classList.remove('in')
document.getElementById('common_modal').classList.add('hide')
}
componentDidMount() {
this.showModal();
}
render() {
return (<>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Modal Header</h4>
</div>
<div class="modal-body">
<div className="fd">
<h6 className="p_t_15"><b>Log in continue</b></h6>
<input type="text" placeholder="Email address"
className="fd m_t_15 form-control bck_ligrey bdr_0" />
<input type="text" placeholder="Password"
className="fd m_t_15 form-control bck_ligrey bdr_0 brdr_grey" />
<div className="fd m_t_15">
<input type="checkbox" />
<font color="#ddd">Remember My password</font>
<p className="float-right font-12 m_0">Show password</p>
</div>
<button type="button" className="btn fd btn_orng font-12 m_tb_10"> Log in</button>
<div className="fd p_b_15 text-center">
<u><b>Forgot password?</b></u>
</div>
<p className="fd m_b_10 m_t_30 text-center"><span className="font-10">Don't have an account?</span> <b>Sign Up</b></p>
</div>
</div>
</>
);
}
}
export default LoginModalBody;
Add your modal component in separate file and import that in Footer or Header.
const [content, setContent] = useState(); State for your content.
You need to create a function that will define which modal content you want to display. You can pass type as follows: `onClick={() => callModalComponent('login')}
Your function will be like:
const callModalComponent = (type: string) => {
if(type === 'login'){
setContent(<LoginComponent />) // set state content as per your form requirement
} else if(type === 'register'){
setContent(<RegisterComponent />)
}
openModalContainer() // this will open your modal.
}
I'm studying Reactjs and I'm building a tasks project (CRUD) but I'm stuck at the point of editing, the editing part is in another component and I'm not able to send the index of the task that will be edit, I read the documentation but I'm not capable to make it, please if someone can see my code and tell what I'm doing wrong.
the app (main)code
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
// data
import { todos2 } from './todos.json';
// subcomponents
import TodoForm from './components/TodoForm';
import TodoFormEdit from './components/TodoFormEdit';
class App extends Component {
constructor() {
super();
this.state = {
todos2, mode:'view'
}
this.handleAddTodo = this.handleAddTodo.bind(this);
this.handleEdit2 = this.handleEdit2.bind(this);
}
removeTodo(index) {
this.setState({
todos2: this.state.todos2.filter((e, i) => {
return i !== index
})
});
}
handleAddTodo(todo) {
this.setState({
todos2: [...this.state.todos2, todo]
})
}
handleEdit2(i) {
this.setState({mode: 'edit'});
//const mode = mode === 'edit';
alert(i);
/* alert(this.state.todos2[i].title);
alert(this.state.todos2[i].priority);
alert(this.state.todos2[i].description);
alert(this.state.todos2[i].language);*/
}
render() {
const todosAll = this.state.todos2.map((todo, i) => {
return (
<div className="col-md-4" key={i}>
<div className="card mt-4">
<div className="card-title text-center">
<h3>{todo.title} - { i } </h3>
<span className="badge badge-pill badge-danger ml-2">
{todo.priority}
</span>
</div>
<div className="card-body">
<div>
{todo.description}
</div>
<div>
{todo.language}
</div>
</div>
<div className="card-footer">
<button
className="btn btn-danger"
onClick={this.removeTodo.bind(this, i)}>
Delete
</button>
<button
className="btn btn-warning ml-2"
onClick={this.handleEdit2.bind(this, i)}>
Edit
</button>
</div>
</div>
</div>
)
});
return (
<div className="App">
<nav className="navbar navbar-dark bg-dark">
<a className="navbar-brand" href="/">
Tasks
<span className="badge badge-pill badge-light ml-2">
{this.state.todos2.length}
</span>
</a>
</nav>
<div className="container">
<div className="row mt-4">
<div className="col-md-4 text-center">
<img src={logo} className="App-logo" alt="logo" />
{/* <TodoForm onAddTodo={this.handleAddTodo} ></TodoForm> */ }
{this.state.mode === 'view' ? (
<TodoForm onAddTodo={this.handleAddTodo} />
) : (
<TodoFormEdit index={this.state.i}/>
)}
</div>
<div className="col-md-8">
<div className="row">
{todosAll}
</div>
</div>
</div>
</div>
</div>
)
}
}
export default App;
and the Edit component:
import React, { Component } from 'react';
// data
import { todos2 } from '../todos.json';
class TodoFormEdit extends Component {
constructor (i) {
super(i);
this.state = {
todos2
};
}
render() {
return (
<div>
{this.state.todos2[0].title}
</div>
)
}
}
export default TodoFormEdit;
You're passing this.state.i:
<TodoFormEdit index={this.state.i}/>
It's not clear where you set it–I see mode and todos2 state properties, I don't see i anywhere.
I'm relatively new to React and I am trying to create a web application that creates the Rnd component when I click a button. When I click the button I can only get it to create one Rnd component even though it still registers all the clicks. Any help would be great.
import { Meteor } from 'meteor/meteor';
import React from 'react';
import ReactDOM from 'react-dom';
import { render } from 'react-dom';
import Rnd from 'react-rnd';
export default class App extends React.Component {
renderWidget() {
console.log('I was clicked');
const widget = React.createElement(Rnd, {default: {x: 0, y: 0, width: 320, height: 200}, className: 'box'}, React.createElement('p', {}, this.state.text));
ReactDOM.render(
widget,
document.getElementById('widget')
);
}
render () {
return (
<div>
<section className='hero is-dark'>
<div className='hero-body'>
<div className='container'>
<h1 className='title'>
Dashboard
</h1>
<h2 className='subtitle'>
At A Glance Data
</h2>
</div>
</div>
</section>
<section className='section'>
<div className='container has-text-right'>
<h2 className='subtitle'>
Create New Widget
</h2>
<button className='button is-dark is-outlined' onClick={this.renderWidget.bind(this)}>
<span className='icon'>
<i className='fas fa-plus'></i>
</span>
</button>
</div>
<div id='widget'>
</div>
</section>
</div>
);
}
}
Here's one way you could go about doing what you want:
import React from "react";
import { render } from "react-dom";
import Rnd from "react-rnd";
const Widget = () => <p>Hello World</p>;
export default class App extends React.Component {
constructor() {
super();
this.state = {
components: [],
text: "Hello to you"
};
}
renderWidget() {
console.log("I was clicked");
const newComponents = [...this.state.components, Widget];
this.setState({
components: newComponents
});
}
render() {
const { components } = this.state;
return (
<div>
<section className="hero is-dark">
<div className="hero-body">
<div className="container">
<h1 className="title">Dashboard</h1>
<h2 className="subtitle">At A Glance Data</h2>
</div>
</div>
</section>
<section className="section">
<div className="container has-text-right">
<h2 className="subtitle">Create New Widget</h2>
<button
className="button is-dark is-outlined"
onClick={this.renderWidget.bind(this)}
>
<span className="icon">
<i className="fas fa-plus" />
Click me
</span>
</button>
</div>
<div>
{components.length !== 0 &&
components.map((Widget, i) => <Widget key={i} />)}
</div>
</section>
</div>
);
}
}
render(<App />, document.getElementById("widget"));
I don't have possibility to run your code but at quick glance I would probably not use ReactDOM.render to render new component every time the button is clicked. Instead I'd add array e.g. "generatedComponents" to the App-component's state and every time you click the button, it would add a new component to that array. Then you render the components in that array at the App-components render method.
Also I wouldn't use variable type const in the renderWidget-function, but instead let or var.
First, I'm almost new to reactjs. I want to create a simple editing mask for getting deeper into reactjs.
What is the "Best Practice" for this situation?
I'm having a page, where you can simply add, change or delete a company entry.
What I want to achieve is, to open a modal dialog window, when I click on a company entry. In the modal dialog window then, the user can modify or delete the entry.
First I created a CompanyList component.
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="text" 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
The Company component looks like this:
import React, { Component } from 'react';
class Company extends Component {
constructor(props) {
super(props);
this.state = {
company: props.company,
onClick: props.onClick
};
}
render() {
return (
<div>
<li>
<div className="cursorPointer" >
{this.props.company.nummer} {this.props.company.bezeichnung}
</div>
</li>
</div>
);
}
}
export default Company
My issue is now, how and where to implement the modal dialog?
Is it best practice to create an own component for it e.g. CompanyOptions? Should it be part of Company or better one component added in CompanyList? But then, how to pass the current Company to the modal dialog.
Sorry, if I'm asking too many questions. But I want to find out how it is recommended in reactjs.
UPDATE
Now I've created an own component for it.
This component looks like this:
import React, { Component } from 'react';
class CompanyOptions extends Component {
constructor(props) {
super(props);
this.state = {
company: props.company,
css: props.css,
onClick: props.onClick
};
}
render() {
return (
<div>
<div className={this.state.css} 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.state.company.bezeichnung}"</h4>
</div>
<div className="modal-body">
<p>One fine body…</p>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" className="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default CompanyOptions
In the Company component I render it this way:
render() {
return (
<div>
<li>
<div className="cursorPointer" onClick={this.toggleOptionFields.bind(this)}>
{this.props.company.nummer} {this.props.company.bezeichnung}
</div>
<CompanyOptions company={this.state.currentCompany} css={this.state.optionFieldsCss} />
...
I've created a state and a method for the click event:
constructor(props) {
super(props);
this.state = {
company: props.company,
onClick: props.onClick,
editFieldsCss: "displayNone",
optionFieldsCss: "modal fade",
currentCompany: props.company,
};
}
and the method:
toggleOptionFields() {
var css = (this.state.optionFieldsCss === "modal fade in displayBlock") ? "modal fade" : "modal fade in displayBlock";
this.setState({
"optionFieldsCss":css,
currentCompany: this.company
});
}
But when I click on the company the css in the component call is updated. But not in the component itself:
Why? Anybody an idea?
The best way is to create a new component for a modal. This way it would be reusable.
Then you can include it where you need it and you can send all company info via props to that modal.
Add an state property showModal and set it to false. Then onClick event change showModal to true. Then in your render method you can check if(this.state.showModal) and then show modal.
Your state :
constructor(props){
super(props);
this.state = {
showModal: false,
currentCompanyName: "",
currentCompanyNumber: ""
}
}
Then onClick event:
handleClick(currentCompanyName, currentCompanyNumber){
this.setState({
showModal: true,
currentCompanyName: currentCompanyName,
currentCompanyNumber: currentCompanyNumber
})
}
And then in your render:
render(){
if(this.state.showModal)
return <MyModal companyName={this.state.currentCompanyName} companyNumber={this.state.currentCompanyNumber} />
return (
//Rest of the code
)
}