I found this perfect Sweet Alert module for Bootstrap and React (which I'm using in my Meteor app):
http://djorg83.github.io/react-bootstrap-sweetalert/
But I don't understand how you include this code inside a React component.
When someone clicks the Delete button in my app, I'd like a Sweet Alert prompt to pop up asking for confirmation.
Here is my component for the Delete button:
import React, {Component} from 'react';
import Goals from '/imports/collections/goals/goals.js'
import SweetAlert from 'react-bootstrap-sweetalert';
export default class DeleteGoalButton extends Component {
deleteThisGoal(){
console.log('Goal deleted!');
// Meteor.call('goals.remove', this.props.goalId);
}
render(){
return(
<div className="inline">
<a onClick={this.deleteThisGoal()} href={`/students/${this.props.studentId}/}`}
className='btn btn-danger'><i className="fa fa-trash" aria-hidden="true"></i> Delete Goal</a>
</div>
)
}
}
And here is the code that I copied from the Sweet Alert example:
<SweetAlert
warning
showCancel
confirmBtnText="Yes, delete it!"
confirmBtnBsStyle="danger"
cancelBtnBsStyle="default"
title="Are you sure?"
onConfirm={this.deleteFile}
onCancel={this.cancelDelete}
>
You will not be able to recover this imaginary file!
</SweetAlert>
Anyone know how to do this?
Working example based on your code http://www.webpackbin.com/VJTK2XgQM
You should use this.setState() and create <SweetAlert ... /> on onClick. You can use fat arrows or .bind() or any other method to be sure that proper context is used.
import React, {Component} from 'react';
import SweetAlert from 'react-bootstrap-sweetalert';
export default class HelloWorld extends Component {
constructor(props) {
super(props);
this.state = {
alert: null
};
}
deleteThisGoal() {
const getAlert = () => (
<SweetAlert
success
title="Woot!"
onConfirm={() => this.hideAlert()}
>
Hello world!
</SweetAlert>
);
this.setState({
alert: getAlert()
});
}
hideAlert() {
console.log('Hiding alert...');
this.setState({
alert: null
});
}
render() {
return (
<div style={{ padding: '20px' }}>
<a
onClick={() => this.deleteThisGoal()}
className='btn btn-danger'
>
<i className="fa fa-trash" aria-hidden="true"></i> Delete Goal
</a>
{this.state.alert}
</div>
);
}
}
if it doesn't work for someone the way you exposed the #hinok solution then you can modify this function like this:
deleteThisGoal() {
this.setState({
alert: ( <
SweetAlert success title = "Woot!"
onConfirm = {
() => this.hideAlert()
} >
Hello world!
<
/SweetAlert>
)
});
};
This was the code that I wrote:
showAlert(title, message, callBack, style) {
this.setState({
alert: (
<SweetAlert
warning
showCancel
confirmBtnText = "Sí"
cancelBtnText = "No"
confirmBtnBsStyle= {style ? style : "warning"}
cancelBtnBsStyle = "default"
customIcon = "thumbs-up.jpg"
title = {title}
onConfirm = {callBack()}
onCancel = {this.hideAlert}
>
{message}
</SweetAlert>
)
});
}
hideAlert = () => {
this.setState({
alert: null
});
}
updateCustomer = () => {..."a few lines of code here"}
This was the called from button:
{<Button color="primary" disabled={this.state.notChange} onClick={() => this.showAlert('Save changes for client', '¿Are you sure?', () => this.updateCustomer, null) } >Save changes</Button>}
Saludos!!
Related
I am new to React and let's suppose we have the following piece of code.
const showDetails = () => {
console.log('Show details')
}
const template = (
<div>
<h1>Vibility Toggle</h1>
<button onClick={showDetails}>Show details</button>
</div>
)
var app = document.getElementById('app')
ReactDOM.render(template, app)
What I want is to change the button's title from Show Details to Hide Details when it is clicked. So I' ve thinking to get the click event inside the function and change the title by using a ternary operator. How to do that?
Thanks
Theo.
you can use the state to handle toggle event in react. I have added a snippet of toggle handler.
import React, { Component } from 'react';
class App extends Component {
state = {
isVisible : true
}
toggleDetails = () => {
this.setState({
isVisible : !this.state.isVisible
});
}
render() {
return (<div>
<h1>Vibility Toggle ({this.state.isVisible ? "is Visible" : "is Not Visisble"})</h1>
<button onClick={this.toggleDetails}>{!this.state.isVisible ? "Show details" : "Hide details"}</button>
</div>)
}
}
export default App;
You can also keep it simple by doing something like:
let show = true;
const showDetails = event => {
show = !show;
event.target.innerHTML = show ? "Show Details" : "Hide Details";
};
const template = (
<div>
<h1>Vibility Toggle</h1>
<button onClick={showDetails}>Show Details</button>
</div>
);
var app = document.getElementById("app");
ReactDOM.render(template, app);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
you need to use state in React.please read this documentation for state in React
React State.
here is the sample code to change title using ternary operator in React
import React, { Component } from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
showDetails: true
}
}
showDetails = () => {
console.log('Show details')
this.setState({ showDetails: !this.state.showDetails })
}
render() {
return (
<div>
<h1>Vibility Toggle</h1>
<button onClick={() => this.showDetails()}>{this.state.showDetails ? 'Show Details' : 'Hide Details'}</button>
</div>
)
}
}
export default App
Probably a simple question and have so many people answered here but in this scenario, I cannot figure out why it doesn't work ...
In the parent I have
updateAccountNumber = value => {
console.log(value);
};
<Child updateAccountNumber={this.updateAccountNumber} />
In the child I have
<ListItem
button
key={relatedSub.office + relatedSub.account}
onClick={() =>
this.props.updateAccountNumber(
relatedSub.office + relatedSub.account
)
}
Even if I do parent like this, still no help..
<Child updateAccountNumber={() => this.updateAccountNumber()} />
if I have the below child item, then when I click on the menu that runs the child items, the component calls itself as many items as there are...
onClick={this.props.updateAccountNumber(
relatedSub.office + relatedSub.account
)}
It won't even run the below code, simple code, I can't see why it wouldn't kick of the handleClick event...
import React, { Component } from "react";
import List from "#material-ui/core/List";
import ListItem from "#material-ui/core/ListItem";
import ListItemText from "#material-ui/core/ListItemText";
const handleClick = () => {
debugger;
alert("sda");
console.log("bbb");
};
export default class RelatedSubAccounts extends Component {
Links = () => {
if (this.props.RelatedSubAccounts) {
let RelatedSubArray = this.props.RelatedSubAccounts;
let source = RelatedSubArray.map(relatedSub => (
<ListItem
button
onClick={handleClick}
key={relatedSub.office + relatedSub.account}
className={
relatedSub.office + relatedSub.account !== this.props.OfficeAccount
? ""
: "CurrentRelatedSub"
}
>
<ListItemText primary={relatedSub.office + relatedSub.account} />
</ListItem>
));
return (
<div id="RelatedSubLinks">
<List>{source}</List>
</div>
);
} else {
return "";
}
};
render() {
return this.Links();
}
}
Please ask if any other related code is missing, and I can share.
I was able to get an example that works with the code you shared by using RelatedSubAccounts like this:
<RelatedSubAccounts RelatedSubAccounts={[{ office: 1, account: 2 }]} />
Code Sandbox Example
I see a few things that stand out as potentially confusing. I will point them out in code below with comments:
import React, { Component } from "react";
import List from "#material-ui/core/List";
import ListItem from "#material-ui/core/ListItem";
import ListItemText from "#material-ui/core/ListItemText";
const handleClick = () => {
debugger;
alert("RelatedSubAccounts clicked");
console.log("bbb");
};
export default class RelatedSubAccounts extends Component {
// Capitalization like this in react normally indicates a component
Links = () => {
/*
Having a prop that is the same name as the component and capitalized is confusing
In general, props aren't capitalized like the component unless you are passing a component as a prop
*/
if (this.props.RelatedSubAccounts) {
// Again, capitalization on RelatedSubArray hints that this is a component when it really isn't
let RelatedSubArray = this.props.RelatedSubAccounts;
let source = RelatedSubArray.map(relatedSub => (
<ListItem
button
onClick={handleClick}
key={relatedSub.office + relatedSub.account}
className={
relatedSub.office + relatedSub.account !== this.props.OfficeAccount
? ""
: "CurrentRelatedSub"
}
>
<ListItemText primary={relatedSub.office + relatedSub.account} />
</ListItem>
));
return (
<div id="RelatedSubLinks">
<List>{source}</List>
</div>
);
} else {
return "";
}
};
render() {
return this.Links();
}
}
This is going to be strangest solution but might give you a lesson or two.. I found the cause of the issue here.
So I have a menu like this
When you click on that arrow to open up the menu, it becomes active and when you click away onBlur kicks in and that menu goes away.. (menu created used react-select Creatable)
DropdownIndicator = props => {
return (
<div
onBlur={() => {
this.setState({ Focused: false, RelatedSub: false });
}}
so I had to update it to below:
onBlur={() => {
this.setState({ Focused: false });
setTimeout(() => {
this.setState({ RelatedSub: false });
}, 100);
}}
I'm trying to hide a component when clicking a Yes or Not. I'm getting the correct output when clicking but the component that acts like a Popup keeps in the screen and I can not remove it.
This is my component
export default class MyPopUp extends React.Component {
constructor(props) {
super(props)
}
render() {
let { username } = this.props
return (
<div className="modal-wrapper">
<div className="modal">
Some Text
<br />
<MyButton
name={username}
surname="pewlas"
arguments={["yes"]}
>
[ Yes ]
</PostCommandButton>{" "}
<MyButton
name={username}
surname="pewlas"
arguments={["no"]}
>
[ No ]
</MyButton>{" "}
</div>
</div>
)
}
}
And this is MyButton
import { connect } from "react-redux"
import button from "../../../common/components/Button"
import { myButton } from "../actions/myButton"
const MyButton = connect(
undefined,
(dispatch, { name, surname, arguments: args = [] }) => ({
onClick: () => dispatch(button(name, username, args)),
}),
)(Button)
export default MyButton
And this is my button
export const MY_BUTTON = "MY_BUTTON"
export const myButton = (name, surname, args) => ({
type: MY_BUTTON,
name,
surname,
arguments: args,
})
How can I hide MyPopUp when clicking Yes or No? I do not find the way to link my PopUp component with the onClick from MyButton, how can I add a state so I can show it or not?
I'm going to try to help you maybe refactorizing some code.
First of all, I have seen that you are using redux with your Button, to do what you want to do you have some options:
const SURNAME = "pewlas"
export class MyPopUpComponent extends React.Component {
state = { hidden: false }
handleClick = value => {
this.props.myButton(this.props.username, SURNAME, value) //the action creator
this.setState({ hidden: true }) //**IMPORTANT**
}
render() {
const { username } = this.props
if (this.state.hidden) {
return null
}
return (
<div className="modal-wrapper">
<div className="modal">
Some Text
<br />
<button
name={username}
surname={SURNAME}
onClick={() => this.handleClick("yes")}
>
[ Yes ]
</button>{" "}
<button
name={username}
surname={SURNAME}
onClick={() => this.handleClick("no")}
>
[ No ]
</button>{" "}
</div>
</div>
)
}
}
const mapDispatchToProps = {
myButton
}
export const MyPopUp = connect(null, mapDispatchToProps)(MyPopUpComponent)
You can do something like that, first of all, you show the popup initializing state hidden to false. As you can see in the render you are going to show the text with buttons and as soon as a user press yes or now you can launch an action or do whatever you want and after that, you set hidden to true. The state has changed so the render function is called again returning null, hiding the component.
Hope it helps you
i m learning react and i trying to change my button text after sweetAlert2-react popup.
The original text on the button is 'ACTIVE' and
If i choose OK on the popup the text on the button must be 'activated' and if y choose CANCEL 'disabled'..
I do not know how or where to do the IF iteration
any help?
here is my code:
<button onClick={() => this.setState({ show: true })}>ACTIVE</button> <SweetAlert show={this.state.show} showCancelButton={this.state.show} title="Are you shore?" onConfirm={() => this.setState({ show: false })} />
Thanks!
Conditionally set the string internal to the button.
<button>
{this.state.active === 'active' && <div>ok</div>}
{this.state.active === 'disabled' && <div>idk</div>}
<button>
If there are only two states consider a ternary operator.
<button>
{this.state.active === 'active' ? <div>ok</div> : <div>idk</div>}
<button>
You could save the button's text in the state, (ex: this.state.buttonText), then you'll be able to set the buttonText when user click on OK/Cancel button.
You can use a common method (in the below example hideAlert) for manage both events (ok and cancel) and inside it, set the button's text.
See the following example please (click here to run):
import React, { Component } from "react";
import SweetAlert from "react-bootstrap-sweetalert";
import ReactDOM from "react-dom";
export default class HelloWorld extends Component {
constructor(props) {
super(props);
this.state = {
alert: null,
button: "active"
};
}
showAlert() {
const getAlert = () => (
<SweetAlert
show={this.state.show}
showCancel
onConfirm={() => this.hideAlert("disabled")}
onCancel={() => this.hideAlert("active")}
>
Are you sure?
</SweetAlert>
);
this.setState({
alert: getAlert()
});
}
hideAlert(text) {
this.setState({
alert: null,
button: text
});
}
render() {
return (
<div style={{ padding: "20px" }}>
<button onClick={() => this.showAlert()}>
{this.state.button}
</button>
{this.state.alert}
</div>
);
}
}
ReactDOM.render(<HelloWorld />, document.getElementById("app"));
I hope it helps you, bye.
I am using FlowRouter/Meteor with React, and am trying to pass a FlowRouter.go method to a react button to navigate to a new page when the button is pressed. I want to do this to keep the button as a reusable component, but am struggling to figure out how to pass the FlowRouter.go method into the stateless functional component. This is a simplified version of what I have right now:
import React, { Component } from 'react';
import { FlowRouter } from 'meteor/kadira:flow-router';
const ParentComponent = () => {
// define text and styles here
return (
<div>
<Button text={text} style={styles} action={FlowRouter.go("Register")}/>
</div>
);
}
and then my button component:
import React, { Component } from 'react';
// Call to action button
const Button = ({text, style, action}) => {
return (
<button className="btn" style={style} onClick={() => action()}>
{text}
</button>
);
}
Button.propTypes = {
text: React.PropTypes.string.isRequired,
style: React.PropTypes.object,
action: React.PropTypes.func
};
Button.defaultProps = {
text: "A button.",
style: {
height: "100%",
width: "100%",
},
action: null
};
export default Button
Does anyone know what syntax is required to load methods from third party libraries into React functional components?
You need to pass in a function. You are actually executing the FlowRouter.go function by calling FlowRouter.go("Register").
Try this:
const ParentComponent = () => {
// define text and styles here
return (
<div>
<Button text={text} style={styles} action={() => FlowRouter.go("Register")}/>
</div>
);
}
Also... as action is a function you can pass it directly to your onClick, like so:
<button className="btn" style={style} onClick={action}>