How to increment counter value for each dropdown selection - javascript

I am trying to increment the react state counter based on some option selection from the dropdown menu. The problem is I want to preserve the counter value and continuously increment based on condition like option "Test" is selected.
I am using below code to increment a counter if "Test" is selected in both the dropdown
{this.state.DownloadPrepare == "Test" ? this.state.Identify == "Test" : this.state.CalcNoOfObs+1}

You're probably looking for something like this: https://codesandbox.io/s/zealous-shirley-flznm
class App extends React.Component {
state = {
counter: 0,
listOne: null,
listTwo: null
};
incrementIfTest = event => {
console.log(event.target.name);
if (
//check if is already selected, do not want to double count
event.target.value === "Test" &&
this.state[event.target.name] !== "Test"
) {
//increment count
this.setState({
...this.state,
counter: this.state.counter + 1,
[event.target.name]: event.target.value
});
//decrease count if they remove Test selection, cannot be below 0.
} else if(this.state[event.target.name] === "Test"){
this.setState({
...this.state,
counter: this.state.counter > 0 ? this.state.counter - 1 : 0,
[event.target.name]: event.target.value
});
}
};
render() {
return (
<div>
<h4>{this.state.counter}</h4>
<select name="listOne" onChange={this.incrementIfTest}>
<option />
<option>DownloadPrepare</option>
<option>Test</option>
</select>
<select name="listTwo" onChange={this.incrementIfTest}>
<option />
<option>DownloadPrepare</option>
<option>Test</option>
</select>
</div>
);
}
}
Make use of the onChange() event-listener on the Dropdown (select tag). We can pass in the event and have access to the selected option through event.target.value. If it equals Test, we just increment the count

I made a script for on click you can do on the change as well I hope It's useful for you.
Thanks
constructor(props) {
super(props);
this.state = {
DownloadPrepare: "Test",
Identify: "",
CalcNoOfObs: 0
};
}
click() { // make your function what you want on change
this.state.DownloadPrepare == "Test"
? this.setState({
Identify: "Test"
})
: this.setState({
CalcNoOfObs: this.state.CalcNoOfObs + 1
});
}
<button onClick={() => this.click()}>click</button>

Related

Select only ONE or NONE of the checkbox inputs

My goal is to have two checkbox items, where the user can only select ONE or select NONE. While one is selected, the other should be disabled. I have this so far, but it is not working as I expected.
If there is a better way to this overall, please let me know!!
I have a class component with the following content:
constructor(props) {
super(props);
this.state = {
aSelected: false,
bSelected: false
}
}
handleCheckboxChange = (e) => {
const { checked, value } = e.target;
console.log( 'checked: ', checked );
if(value=="a") {
this.setState( {aSelected: checked}, () => {
console.log('aSelected: ', this.state.aSelected);
console.log("---")
});
}
if(value=="b") {
this.setState( {bSelected: checked}, () => {
// console.log('bSelected: ', this.state.bSelected);
// console.log("---")
});
}
}
Somewhere inside the render return, I have this:
<input>
type="checkbox"
value="a"
onChange={this.handleCheckboxChange}
disabled={ (this.state.aSelected || (!this.state.aSelected && !this.state.bSelected) ) ? false : true}
</input>
<input>
type="checkbox"
value="b"
onChange={this.handleCheckboxChange}
disabled={ (this.state.bSelected || (!this.state.aSelected && !this.state.bSelected) ) ? false : true}
</input>
Problems I'm having:
The disabled behavior is NOT matching up with how I detailed it in the first line.
this.state.aSelected and this.state.bSelected always log false no matter how many times I select and unselect the checkbox. The checked value is correctly toggled, though. (Below is the ouput for toggling the "a checkbox"):

Does React wait for render to update state?

I am checking the state of one of my keys twice within a function. However, even after operations are done on the key value it still reports the same value.
So I have a function called clickMe that will run from an onClick event for a button I have in the return for the component. When it's clicked the function should check to see the current state of totalRemaining before performing operations. If totalRemaining is greater than 0 it should uptick clicks and downtick totalRemaining. After that operation it should check to see if totalRemaining is still greater than 0. If it isn't it should disable the button. However, before and after the operation the value of totalRemaining is the same even though after render it is clear that it has been updated.
import React from 'react';
class Item extends React.Component{
constructor(props){
super(props);
this.state = {
clicks: 0,
totalRemaining: 10,
disabled: false,
}
}
clickMe(){
if(this.state.totalRemaining>0){
console.log(`Clicks: ${this.state.clicks}`)
console.log(`Total Remaining: ${this.state.totalRemaining}`)
this.setState({
clicks: this.state.clicks + 1,
totalRemaining: this.state.totalRemaining - 1
});
console.log(`Clicks: ${this.state.clicks}`)
console.log(`Total Remaining: ${this.state.totalRemaining}`)
if(this.state.totalRemaining===1){
this.setState({
disabled: true
})
}
}else{
this.setState({
disabled: true
})
}
}
render() {
return(
<div>
<button onClick={() => this.clickMe()} disabled={this.state.disabled}>Click Me {this.props.name}</button>
<input placeholder={this.state.totalRemaining}/>
<input placeholder={this.state.clicks}/>
</div>
)
}
}
export default Item;
Here is the console output:
this.state.totalRemaining
10
MyItem.js:18 Clicks: 0
MyItem.js:19 Total Remaining: 10
this.state.totalRemaining
10
this.state.totalRemaining
10
MyItem.js:25 Clicks: 0
MyItem.js:26 Total Remaining: 10
this.setState({
clicks: this.state.clicks + 1,
totalRemaining: this.state.totalRemaining - 1
},() => {this.state.totalRemaining < 1 ? this.setState({
disabled: true
}) : null});
reference: https://stackoverflow.com/a/54713679/11229002

Blur validation gets triggered before input selection fills the data field - ReactJS

Following is my country selector drop down which pops in as soon as user Focus the input field. I have made a validation onBlur as data cannot be remains empty in the input field. Problem is on selecting the value from the list onBlur fires immediately and then the values gets populated in the dropdown which is causing onBlur validation message to appear on screen.
Let me know how can I manage the situation by removing the onBlur validation once user selects the value from the list.
React Code -
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
blurText: "Field Cannot be left blank",
listData: [],
selectedValue: "",
showList: false,
showBlurText: false
};
}
componentDidMount() {
this.setState({
listData: [
{ id: 1, name: "Australia" },
{ id: 2, name: "Germany" },
{ id: 3, name: "France" }
]
});
}
handleBlur = e => {
if (!e.target.innerHTML) {
this.setState({
showBlurText: true
});
} else {
this.setState({
showBlurText: false
});
}
};
showDataList = () => {
this.setState({
showList: true
});
};
handleSelection = e => {
this.setState({
selectedValue: e.target.innerHTML
});
};
handleChange = e => {
this.setState({ selectedValue: e.target.value });
};
render() {
return (
<div className="App">
<h3>Test Select</h3>
<input
type="text"
name="autosuggest"
value={this.state.selectedValue}
onFocus={this.showDataList}
onBlur={this.handleBlur}
onChange={this.handleChange}
/>
{this.state.showList && (
<ul>
{this.state.listData.map(x => {
return (
<li key={x.id} onClick={this.handleSelection}>
{x.name}
</li>
);
})}
</ul>
)}
<hr />
{this.state.showBlurText && (
<p style={{ color: "red" }}>{this.state.blurText}</p>
)}
</div>
);
}
}
Working Codesandbox with the scenario - https://codesandbox.io/s/charming-brook-h7kin
I have a solution, you can check on this link:
Codesandbox: Click catcher on blur
The issue is you put the onBlur prop to the input element, so when you click an item in the ul element, the onBlur gets triggered.
So what I did is to create a simple click-catcher so when you click outside of input or ul, it will be triggered.
Hope this helps.
Instead of using onBlur you can check validations on onChange event, check the working sandbox here
some tips below that will make your code clean:
Instead of using if-else while validating emptyefields you can directly use !(negate operator) in your handleBlur function.
handleBlur = e => {
this.setState({
showBlurText: !e.target.innerHTML
})
}

Change color of selected page number (pagination)

I have created a simple React component with a table displaying 10 rows of data per page. The implementation of the pagination works as intended, but I want to be able to highlight the selected page.
In my constructor I have an initial state "active: null", which I then modify in a handleClick function.
constructor(props) {
super(props);
this.state = {
currentPage: 1,
eventsPerPage: 10,
active: null,
};
this.handleClick = this.handleClick.bind(this);
}
handleClick(index) {
this.setState({ currentPage: Number(index.target.id) });
if (this.state.active === index) {
this.setState({ active: null });
} else {
this.setState({ active: index });
}
}
And a function for setting the font-weight to bold.
myStyle(index) {
if (this.state.active === index) {
return 'bold';
}
return '';
}
Here is what I render.
const renderPageNumbers = pageNumbers.map((number, index) => (
<p
style={{ fontWeight: this.myStyle(index) }}
key={number}
id={number}
onClick={index => this.handleClick(index)}
>
{number}
</p>
));
return (
<div id="page-numbers">
{renderPageNumbers}
</div>
);
FYI: It's not the complete code.
I am not quite sure where I go wrong, any help is appreciated :)
pageNumbers.map((number, index) => index is zero based and am sure number starts from 1 so when index === 0 and number === 1, you would have this.myStyle(0) but
this.handleClick(0) will not work because you first #id === 1 not 0
why not just use number for your functions and remove index to safe confusion
You need to bind the context of the class to myStyle function in order to use this inside it.
So, in your constructor you should add it like this:
(see the last line)
constructor(props) {
super(props);
this.state = {
currentPage: 1,
eventsPerPage: 10,
active: null,
};
this.handleClick = this.handleClick.bind(this);
this.myStyle = this.myStyle.bind(this);
}

Hide element onClick React based on Id

I have a list of 3 filters that will show based on their id, when clicked it will show the filters matching the id but I would like to hide it if clicked again. So if Filter 1 is clicked it should show and then if clicked again it should hide
https://www.webpackbin.com/bins/-KpFE0uZN94N_RY2lavn
import React, { Component } from 'react'
export default class Catalogue extends Component {
constructor(props) {
super(props)
this.state = {
filterListShow: false,
active: false
}
this.handleShowFilterList = this.handleShowFilterList.bind(this)
}
// Show Filter checklist onClick
handleShowFilterList(id) {
this.setState({
filterListShow: id,
active: false })
}
render() {
const { filterListShow } = this.state
let test = ''
if (filterListShow === 1) {
test = (<div>show 1</div>)
}
else if (filterListShow === 2) {
test = (<div>show 2{console.log(2)}</div>)
}
else if (filterListShow === 3) {
test = (<div>show 3{console.log(3)}</div>)
}
return (
<div >
<div onClick={()=> this.handleShowFilterList(1)}>
Show Filter 1
</div>
<div onClick={()=> this.handleShowFilterList(2)}>
Show Filter 2
</div>
<div onClick={()=> this.handleShowFilterList(3)}>
Show Filter 3
</div>
{test}
</div>
)
}
}
Just add another check in the onClick handler to check whether the current state is the same as the id of the element clicked,
// Show Filter checklist onClick
handleShowFilterList(id) {
if(this.state.filterListShow !== id) {
this.setState({
filterListShow: id,
active: false })
} else {
this.setState({filterListShow: false})
}
}
DEMO
Simply put the condition in handleShowFilterList function, if same item has been clicked again then reset the state value of filterListShow variable.
Like this:
handleShowFilterList(id) {
this.setState(prevState => ({
//if same then reset otherwise assign new id
filterListShow: prevState.filterListShow == id ? false : id,
active: false
}))
}
Working Code.

Categories

Resources