How to use Tooltip in react-redux - reactjs

I am new to react.
I want to have a tool tip on the label
The following serves my request
<div class="sds_sp_2xl sds-cb_font--primary">
To see Tooltip positioned on the right,
<a role="button" tabindex="0" aria-describedby="tooltip-cb-02" class="sds-cb_tooltip">
hover over me.
<div role="tooltip" class="sds-cb_tooltip__content sds-cb_tooltip__content--right" id="tooltip-cb-02">Contextual helper text</div>
</a>
</div>
I want to have the tooltip when we hover on the label pertained to checkbox
form
<Field
name='checkMe'
label='check'
component={Checkbox}
checked={checkMe}
{...this.checkboxActions}
/>
checkbox
export const Checkbox = (inputProps) => {
const { input, label, checked } = inputProps
const { name } = input
const className = 'sds-cb_checkbox-a__input'
return (
<label className='sds-cb_checkbox-a' >
<input {...input} className={className} checked={checked} type='checkbox' />
<div className='sds-cb_checkbox-a__box' id={name} />
<span className='sds-cb_checkbox-a__label sds_font-size--14'>{label}</span>
</label>
)
}
How do I embed it to work. So that it would be useful for the fields as well ? Thanks in advance!

Refrence of React-tooltip
This will surely help you.
class Tooltip extends React.Component {
constructor(props) {
super(props)
this.state = {
displayTooltip: false
}
}
hideTooltip=()=>{
this.setState({displayTooltip: false})
}
showTooltip=()=>{
this.setState({displayTooltip: true})
}
render() {
let message = this.props.message
let position = this.props.position
return (
<span className='tooltip'
onMouseLeave={this.hideTooltip}
>
{this.state.displayTooltip &&
<div className={`tooltip-bubble tooltip-${position}`}>
<div className='tooltip-message'>{message}</div>
</div>
}
<span
className='tooltip-trigger'
onMouseOver={this.showTooltip}
>
{this.props.children}
</span>
</span>
)
}
}
class App extends React.Component {
render() {
return (
<div className='container'>
<p>Here is a <Tooltip message={'Hello, I am a super cool
tooltip'} position={'top'}>tooltip</Tooltip> on top.</p>
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
)

First off you should not wrap the label around the input element but set the for attribute to the correct id of the input. So when clicking the label the input gets focused. And to show a tooltip or start any other action use the standard javascript events onMouseEnter and onMouseLeave, set some state according to this and use this state as conditional rendering of the tooltip element:
<label for="someId" onMouseEnter={()=>this.setState({showTooltip:true})} onMouseLeave={()=>this.setState({showTooltip:false})}>Labeltext</label>
<input id="someId" .../>
{this.state.showTooltip && <div>Tooltip</div>}
This will also work when you're setting and using some redux state.

Related

ReactDOM.render() is not working when called again after making the changes in template

The render() function is working fine on the initial call. But when I call it again, via one of the event handler function, it doesn't work. The chrome dev. tools console is not showing any errors at all.
The changes are made on the options array and then I have to display them as list items in the Unordered list.
Sorry for the bad English.
let options = ["example"];
let t =
<div>
<h1>indicition app</h1>
<p>Put your life into the hands of the computer</p>
<p>Here are your options</p>
<ul>
{options.map(text => <li key={text}>{text}</li> )} //Changes occur here but not showing.
</ul>
<form onSubmit={submit}>
<input type="text" name="input" />
<button>Add Item</button>
</form>
</div>;
function submit(e)
{
e.preventDefault();
if (!e.target.elements.input.value) return;
options.push(e.target.elements.input.value);
console.log(options);
ReactDOM.render(t, document.getElementsByTagName("div")[0]); // Here it is not working.
}
ReactDOM.render(t, document.getElementsByTagName("div")[0]); //Here it works for once.
Render function is automatically called when your state has changed. To do that, create a new class and save your options in the state. After that append your options and save them in the state, using this.setState. See the example:
import React, { Component } from 'react';
export default class MyClass extends Component {
state = {
options: ['example'],
};
render() {
return (
<div>
<h1>indicition app</h1>
<p>Put your life into the hands of the computer</p>
<p>Here are your options</p>
<ul>
{this.state.options.map((text) => (
<li key={text}>{text}</li>
))}
//Changes occur here but not showing.
</ul>
<form onSubmit={this.submit}>
<input type='text' name='input' />
<button>Add Item</button>
</form>
</div>);
}
submit = (e) => {
e.preventDefault();
if (!e.target.elements.input.value) return;
let { options } = this.state;
options = options.concat(e.target.elements.input.value);
this.setState({ options });
};
}
ReactDOM.render(MyClass, document.getElementsByTagName("div")[0]); //Here it works for once.

React - get value of input on click

I'm pretty new to React. I have a simple app where text is entered into an input field and then sent to a server when a button is clicked. How can I get the value of the input field? This is incredbily easy in jQuery but I can't figure it out with React.
Here's my code:
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props){
super(props)
this.state = {
terms: ''
}
this.updateTerms = this.updateTerms.bind(this);
}
updateTerms(evt) {
this.setState({
terms: evt.target.value
})
}
search() {
alert(this.state.terms)
}
render() {
const btn1 = {
width: '100%',
backgroundColor: 'white'
}
return (
<div className= 'wrapper'>
<div className= 'item1'>
Specials Fact Tree Demo
</div>
<div className= 'item2'>
Search Term(s):<br/>
<input className= 'form-control' type="text" onChange={this.updateTerms} />
<br/>
<div id = 'results' >
<div id='resultsWrap' >
<select className= 'form-control' id= 'styles' ></select>
<select className= 'form-control' id= 'similar' ></select>
<div id= 'attsDiv' className= 'form-control' >
<dl id= 'atts'></dl>
</div>
</div>
</div>
<button className="btn btn-default" style = {btn1} id= 'search' onClick={this.search}>Search</button>
<div id="activeTraining" >
</div>
</div>
</div>
);
}
}
export default App;
Any help would be greatly appreciated. Plus, easy points!
You forgot to bind the search method as well (inside the constructor):
this.search = this.search.bind(this);
If you are already familar with ECMAScript 6 you can just use arrow functions and save on the bindings like:
search = () => {
alert(this.state.terms)
}

How to call specific Object from ObjectArray

Trying to get e.target.data from the objects generated. console.log displays they have props with the data value I assigned them with. How are event specific objects called? I need to access the original value and also want to onClick delete them. But so far everything i tried, only returns _this2 TypeError (is not a function), or data i tried to pass with the onClick handler wasn't passed. this.props.plz_zwischenis a simple array of strings and passed from parent Component.
import React, { Component } from 'react';
export default class checkBox extends Component {
constructor(){
super();
this.state = {
checkboxState: false
};
this.toggle = this.toggle.bind(this);
}
toggle(e){
console.log('toggle was triggered');
}
render(){
let miniBox = this.props.plz_zwischen.map(function(a, index){
return <li key={index} data={a}> <label> {a} </label> <input type="checkbox" onClick={(e) => this.toggle()} /></li>;
});
return(
<div>
<ul id="rowlist">
{miniBox}
</ul>
</div>
);
}
}
When you need to access the another prop in map, it is always a good idea to abstract it to a separate component
function ListItem(props) {
return (
<li>
<label> {props.data} </label>
<input type="checkbox" onClick={(e) => props.toggle(props.data)} />
</li>
);
}
class CheckBox extends React.Component {
constructor(props){
super(props);
this.state = {
checkboxState: false
};
this.toggle = this.toggle.bind(this);
}
toggle(a){
console.log(a);
}
render(){
let miniBox = this.props.plz_zwischen.map((a, index)=>{
return <ListItem key={index} data={a} toggle={this.toggle} />;
});
return(
<div>
<ul id="rowlist">
{miniBox}
</ul>
</div>
);
}
}
ReactDOM.render(<CheckBox plz_zwischen={['a','b','c']}/>, document.getElementById('app'));
<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>
<div id="app" />
That way you can access the single prop in the child component.
Another way to perform the same thing would be to attach it to the DOM as a custom attribute (since it is a string).
<li data-item={a} key={index} data={a}> <label> {a} </label> <input type="checkbox" onClick={(e) => this.toggle()} /></li>
and then in on click:
event.target.getAttribute('data-item')
Do note that components must begin with capital letters

All checkbox are checked upon clicking

I'm fairly new to react, and I'm trying to create a simple form. The form app has many elements including the 3 checkbox. And to simplify my issue, I'm only showing the checkboxes. Here what I'm doing
When I click on a checkbox, the value of the label will be pushed
into an array and saved into the App state.
I'm using event.target.name because I have multiple inputs in the
form and I wanted to keep just in case to make my problem more
descriptive.
When I click on submit, it should clear the checkbox.
The problem is when I click on checkbox all the 3 of get checked and it won't be cleared after hitting submit. Is there any way to overcome this? or why its happening?
function CheckBox(props) {
var style= {
padding:10,
marginLeft:5
}
return(
<div style={style} >
{props.checkboxList.map((item,index) =>
<div key={index}>
<input type="checkbox"
onChange={props.changeHandler}
checked={props.checkStatus} name={props.name} value={item.val} />
<label>{item.num}) {item.val}</label>
</div>)}
</div>
)
}
class App extends React.Component{
constructor(props) {
super(props);
this.state={item:[],checked:false}
this.changeHandler=this.changeHandler.bind(this)
this.submitHandler=this.changeHandler.bind(this)
}
changeHandler(event) {
if(event.target.name=="choice") {
var arr=this.state.item.slice()
arr.push(event.target.value)
this.setState({item:arr, checked:event.target.checked}, ()=> console.log(this.state.item +"--"+ this.state.checked))
}
else{ console.log('error')}
}
submitHandler(){
this.setState({item:[],checked:false})
}
render() {
return(
<div>
<CheckBox checkboxList={[
{num:"a", val:"choice 1"},
{num:"b", val:"choice 2"},
{num:"c", val:"choice 3"}]} changeHandler={this.changeHandler} name="choice" checkStatus={this.state.checked} />
<button onClick={this.submitHandler}>Submit</button>
</div>
)
}
}
ReactDOM.render(
<App/>,
document.getElementById("root")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
<div id="root"></div>
The main approach is to add state key to the each checkbox:
constructor(props) {
super(props);
this.state={item:[],checked:{}}
this.changeHandler=this.changeHandler.bind(this)
this.submitHandler=this.submitHandler.bind(this)
}
changeHandler(event) {
if(event.target.name=="choice") {
var arr=this.state.item.slice()
arr.push(event.target.value)
this.setState({item:arr, checked:{
...this.state.checked,
[event.target.value]: event.target.checked
}}, ()=> console.log(this.state.item +"--"+ this.state.checked))
}
else{ console.log('error')}
}
submitHandler(){
this.setState({item:[],checked:{}})
}
and for checkbox:
{props.checkboxList.map((item,index) =>
<div key={index}>
<input type="checkbox"
onChange={props.changeHandler}
checked={props.checkStatus[item.val]} name={props.name} value={item.val} />
<label>{item.num}) {item.val}</label>
</div>)}

How to push values into state by calling single onChange function - react

I am new to reactive. I am working on react+flux+alt with ES6.
I have a form for creating new record.
Component
import React from 'react';
import { Input, Button, Glyphicon, ButtonToolbar } from 'react-bootstrap';
import AttributeSectionStore from 'stores/attributeSection/AttributeSectionStore';
import TextBoxesSet from '../descriptionTextBoxes';
import styles from 'scss/_common';
export default class AttributeSection extends React.Component {
constructor(props) {
super(props);
}
_onCreate = () => {
console.log('___________', this.state);
}
onChangeName = (evt) => {
this.setState({name: evt.target.value});
};
onChangeRank = (evt) => {
this.setState({rank: evt.target.value});
};
static getPropsFromStores() {
return recordStore.getState();
}
render() {
return (
<div className="container">
<div className={styles.mainheader}>
<h2 >New Record</h2>
</div>
<div className="col-md-9">
<form className="form-horizontal">
<div className="row">
<div className="col-md-12">
<Input type="text" label="Name" labelClassName="col-xs-2"
wrapperClassName="col-xs-4" value={this.props.name}
onChange={this.onChangeName}/>
</div>
</div>
<div className="row">
<div className="col-md-12">
<Input type="number" label="Rank" labelClassName="col-xs-2"
wrapperClassName="col-xs-4" value={this.props.rank}
onChange={this.onChangeRank}/>
</div>
</div>
<div className="row">
<div className="col-md-4 col-md-offset-2">
<ButtonToolbar className={styles.formBtnGrp}>
<Button bsStyle="primary" onClick={this._onCreate}>Create</Button>
<Button type="reset">Cancel</Button>
</ButtonToolbar>
</div>
</div>
</form>
</div>
</div>
);
}
}
AttributeSection.propTypes = {
name: React.PropTypes.string
rank: React.PropTypes.number
};
Using above component now I'm getting data into state but form may have more than 2 fields. I'm using two functions to update state instead of that how can use single function to update state object?Is there any other best practice is there?
The most common pattern to solve this is using bind() to curry a value to the onchange callback. This is was #knowbody referenced (React.js: Identifying different inputs with one onChange handler)
An alternate, but similar, pattern is adding a second tag within the element to identify the name of the state property to change. I'll show an example using label from your code (obviously you want to use a dedicated tag since label is for display and would be localized).
onInputChanged(evt) {
var newState = this.state,
propName = evt.target.label.toLowerCase();
newState[propName] = evt.target.value;
this.setState(newState);
};

Resources