I'm trying to handle my select all function , but at the moment i got some issues .I'm trying to fill an object with all check boxes . Can somebody give me a hand ?
This is my function to handle single checkbox :
constructor(props) {
super(props);
this.state = { docList:{} }
handleCheckboxClick = (e) => {
let parsedVal = JSON.parse(e.target.value);
let newDocList = { ...this.state.docList };
if (e.target.checked) {
newDocList[parsedVal.documentId] = parsedVal.documentNumber;
} else {
delete newDocList[parsedVal.documentId];
}
this.setState({
docList: newDocList,
}, () => {
console.log(this.state.docList)
});
};
The render :
<MaterialTable options={{
showSelectAllCheckbox:false,
selection: true,
selectionProps: rowData => ({
onClick: (event , rowData) => this.handleCheckboxClick(event,rowData),
value: JSON.stringify({ documentId: rowData.documentId, documentNumber: rowData.documentNumber })
}),
And this is handle select all :
handleAllCheckboxes = (e) => {
if(e.target.value){
this.setState(state=> ({selected: state.data.map(rowData=> rowData.documentId)
}))
console.log(this.state.selected)
return;
}
this.setState({ selected: [] });
}
And the render :
<Checkbox
onClick={this.handleAllCheckboxes}
indeterminate
/> Select All
Included an example of select all or deselect all. Alternatively, click one at a time :)
https://codesandbox.io/s/select-deselect-checkboxes-jugl2
Related
Hello I've got a problem with refreshing component, it doesn't work, in console log shows properly data. I want after click on div to change clicked element on true and add to this element changed class name
below is jsx
{tabObjects.map((item) => (
<div
key={item.key}
id={item.key}
className={item.isChecked ? checked : notChecked}
onClick={() => selectItem(item.key)}
>
<i className={item.icon}></i>
<p className="hide-sm">{item.pText}</p>
</div>
))}
after clicking selectItem I want to change class name to checked and rest of them set checked as false so:
const selectItem = (e) => {
tabObjects.map((item) => {
item.isChecked = false;
if (e === item.key) {
item.isChecked = true;
}
});
setTabObjects(tabObjects);
};
and sample data json
const [tabObjects, setTabObjects] = useState([
{
key: "sample1",
isChecked: true,
icon: "sample1i",
pText: "Test text",
},
{
key: "sample2",
isChecked: false,
icon: "sample2i",
pText: "Test text",
},
]);
let checked = "sampleClass checked";
let notChecked = "sampleClass";
What Am I doing wrong? Clicking on any div with console log working fine
Missing return statement is the reason.
const selectItem = (e) => {
const objects = tabObjects.map((item) => {
item.isChecked = false;
if (e === item.key) {
item.isChecked = true;
}
return item;
});
setTabObjects(objects);
};
I am using react antd . I have got array of objects that's groupKey .I am mapping checkbox by using Groupkey and also I have got two different types of checkbox . One is Select All Checkbox . it actually works when user click on the Select All or User select on all individual checkbox . Other is individual checkbox , user can Select on individually . when user submit on Button , then it's give me this data format ["manage_books","manage_journals","manage_deals"]
here is my trying code :
let defaultCheckedList = ["manage_deals"];
state = {
groupKey: [{
id: 1,
key: "manage_books",
label: "books"
},
{
id: 2,
key: "manage_journals",
label: "journals"
},
{
id: 3,
key: "manage_deals",
label: "deals"
}
],
checkedList: defaultCheckedList,
output: [],
indeterminate: true,
checkAll: false
};
onCheckAllChange = e => {
this.setState({
checkedList: e.target.checked ?
this.state.groupKey.map(item => item.key) :
[],
indeterminate: false,
checkAll: e.target.checked
});
};
onChange = (e, value) => {
this.setState({
checked: e.target.checked,
output: this.state.output.concat(value)
});
};
onSubmit = () => {
console.log(this.state.output)
}
render(UI)
<
div >
<
div className = "site-checkbox-all-wrapper" >
Select All <
Checkbox
indeterminate = {
this.state.indeterminate
}
onChange = {
this.onCheckAllChange
}
checked = {
this.state.checkAll
}
/> <
/div>
I am looping checkbox by groupKey.I am passing key using onChange method. {
this.state.groupKey.map(item => ( <
div className = "userpermission-content"
key = {
item.id
} > {
item.label
} <
Checkbox onChange = {
(e, value) => this.onChange(e, item.key)
}
value = {
item.key
}
/>{" "} <
/div>
))
} <
button onClick = {
this.onSubmit
} > submit < /button> <
/div>
);
}
}
In this code, you can see that two individual checkbox is initial select, I need to get completely like this: https://codesandbox.io/s/4k6qi
this is my codesanbox: https://codesandbox.io/s/check-all-ant-design-demo-vhidd?file=/index.js
Here is what I have come up with
https://codesandbox.io/s/check-all-ant-design-demo-6cm2v?file=/index.js
import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Checkbox } from "antd";
const CheckboxGroup = Checkbox.Group;
class App extends React.Component {
state = {
groupKey: [
{ id: 1, key: "manage_books", label: "books" },
{ id: 2, key: "manage_journals", label: "journals" },
{ id: 3, key: "manage_deals", label: "deals" }
],
checked: {},
output: [],
indeterminate: true,
checkAll: false
};
onCheckAllChange = e => {
const { groupKey } = this.state;
const checked = groupKey.reduce((prev, curr) => {
return { ...prev, [curr.key]: e.target.checked };
}, {});
this.setState({ checked, checkAll: e.target.checked });
};
checkAll = () => {};
onChange = (e, value) => {
// this.setState({
// checked: e.target.checked,
// output: this.state.output.concat(value)
// });
this.setState(
state => ({
checked: { ...state.checked, [value]: e.target.checked }
}),
() => {
const { checked, groupKey } = this.state;
const values = Object.values(checked);
if (values.length === groupKey.length && values.every(v => v)) {
this.setState({ checkAll: true });
} else {
this.setState({ checkAll: false });
}
}
);
};
render() {
console.log(this.state.output);
const { checked, checkAll } = this.state;
return (
<div>
<div className="site-checkbox-all-wrapper">
Select All
<Checkbox
// indeterminate={this.state.indeterminate}
onChange={this.onCheckAllChange}
checked={checkAll}
/>
</div>
{this.state.groupKey.map(item => (
<div className="userpermission-content" key={item.id}>
{item.label}
<Checkbox
onChange={e => this.onChange(e, item.key)}
value={item.key}
checked={checked[item.key]}
/>{" "}
</div>
))}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("container"));
I am using React-autosuggest in my code but the issue i am facing is this that whenever i am clikcing any suggestion i am getting error that
Uncaught TypeError: Cannot read property 'trim' of undefined
Here is my code
var subjectsToBeSearched= []
const getSuggestions = value => {
const inputValue = value.trim().toLowerCase();
const inputLength = inputValue.length;
return inputLength === 0
? []
:subjectsToBeSearched.filter(
lang => lang.name.toLowerCase().slice(0, inputLength) === inputValue
);
};
const getSuggestionValue = suggestion => suggestion.name;
`
const renderSuggestion = suggestion => <div>{suggestion.name}</div>;
export default class Searchbar extends Component {
state = {
language_id: "",
subjects: [],
value: "",
suggestions: []
};
onChange = event => {
this.setState({
value: event.target.value
},()=>console.log(this.state.value));
};
onSuggestionsFetchRequested = ({ value }) => {
this.setState({
suggestions: getSuggestions(value)
});
};
onSuggestionsClearRequested = () => {
this.setState({
suggestions: []
});
};
componentWillMount() {
let languageid = localStorage.getItem("language_id");
var userdata = window.localStorage.getItem("userdata");
if (languageid == null) {
localStorage.setItem("language_id", 0);
}
this.setState({ language_id: languageid, userdata: JSON.parse(userdata) });
this.getAllSubjects();
}
getAllSubjects = async () => {
let details = {
language_id: this.state.language_id
};
this.setState({
response: fetch("http://18.221.47.207:3000/get_subjects", {
method: "GET",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Cache-Control": "max-age=31536000"
}
})
.then(response => response.json())
.then(responseJson => {
this.setState(
{
subjects: responseJson
},
() => {
let subjectsToBeFind = this.state.subjects.map(item => {
return { id: item.subject_id, name: item.subject_name };
});
subjectsToBeSearched=subjectsToBeFind
}
);
})
.catch(error => {
this.setState({
loading: false
});
swal("Warning!", "Check your network!", "warning");
console.log(error);
})
});
};
render() {
const { value, suggestions } = this.state;
const inputProps = {
value,
onChange: this.onChange
};
return (
<div className={`${styles.InputHeaderSearchDiv} `}>
<Autosuggest
inputProps={inputProps}
className={`${styles.InputHeaderSearch}`}
suggestions={suggestions}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
// alwaysRenderSuggestions={true}
getSuggestionValue={getSuggestionValue}
renderSuggestion={renderSuggestion}
/>
<div className={`${styles.SearchIcon}`}>
<img src={SearchIcon} alt="search" />
</div>
</div>
);
}
}
So when i click on any suggestion i just need to console and do some stuff but right away it throws error
When you click a suggestion, the value of the "value" key in the inputProps is undefined thats the reason that you are getting a cannot trim error.
A workaround I did is add a props called "onSuggestionSelected" ( Documentation for onSuggestionSelected found here ) and added a function that set the value of the "value" key in the inputProps to whatever value you want your input tag should have after the click event.
THIS IS HOW MY AUTOSUGGEST LOOKSLIKE
HERE IS MY FUNCTION
in my case simply setting value of inputProps to string did it
<Autosuggest
inputProps: {
value: whateverValue.toString()
I am working on search filter in ReactJS and I face a problem. Problem is about when User does some search and wants to click on next (because I have pagination in app) then the User will click twice to load other pages of data.
I need to avoid this behaviour: I mean when user does single click on next it should be "load a data" instead of "double click".
I am new to ReactJS, please expert help me
Code
btnClick() {
const { Item,skip , filtered, data } = this.state
if(filtered.length>0 || !data.length ){
window.alert("Hello,")
this.setState({
filtered:[],
skip:0
},()=>this.getData());
return false
}else {
window.alert("Hello , Dear")
this.setState(
{
Item,
skip: skip + pageSize
},
() => this.getData()
);}
}
You can have a isLoading state and set the disabled prop on the button when in this state which will not allow the button to be clicked again while the data is being fetched.
btnClick() {
const {
Item,
skip,
filtered,
data
} = this.state;
if (filtered.length > 0 || !data.length) {
window.alert("Hello,")
this.setState({
filtered: [],
skip: 0
}, () => this.fetchData());
return false
} else {
window.alert("Hello , Dear")
this.setState({
Item,
skip: skip + pageSize
},
() => this.fetchData()
);
}
}
fetchData() = async() => {
this.setState({ isLoading: true });
await this.getData();
this.setState({ isLoading: false });
}
render() {
const {
isLoading
} = this.state;
const buttonProps = isLoading ? { disabled: true} ? {};
return (
<button onClick={this.btnClick} { ...buttonProps }>
Click to fetch
</button>
);
}
Print selected radio button value in console.
If all radiogroup is answered then print in console only the selected= true radioValue. for example: if NO radiobutton= true its value is 2. It should print value 2. Like that all true radiovalue should print in console.
Thanks
//array of cards coming from the backend
const data = [
{
cardName: 'Do you want sugar in your coffee',
options: [
{ radioName: 'Yes',radioValue: '1', selected: false },
{ radioName: 'No',radioValue: '2', selected: false }]
},
{
cardName: 'Do you want milk in your coffee',
options: [
{ radioName: 'Yes',radioValue: '1', selected: false },
{ radioName: 'No',radioValue: '2', selected: false }]
},
{
cardName: 'Do you want low-fat-milk in your coffee',
options: [
{ radioName: 'Yes',radioValue: '1', selected: false },
{ radioName: 'No',radioValue: '2', selected: false }]
}
];
class CardsList extends React.Component {
constructor(props) {
super(props);
this.state = {
cards: [],
};
}
componentDidMount() {
setTimeout(() => {
// mimic an async server call
this.setState({ cards: data });
}, 1000);
}
onInputChange = ({ target }) => {
const { cards } = this.state;
const nexState = cards.map(card => {
if (card.cardName !== target.name) return card;
return {
...card,
options: card.options.map(opt => {
const checked = opt.radioName === target.value;
return {
...opt,
selected: checked
}
})
}
});
this.setState({ cards: nexState })
}
onSubmit = () => {
console.log(this.state.cards.map(({ cardName, options }) => {
const option = options.filter(({ selected }) => selected)[0]
return ` ${option.radioValue}`
}))
};
onReset = () => {
this.setState({cards:[]});
}
render() {
const { cards } = this.state;
return (
<div>
{
cards.length < 1 ? "Loading..." :
<div>
{cards.map((card, idx) => (
<ul>
{card.cardName}
{card.options.radioName}
{
card.options.map((lo, idx) => {
return <input
key={idx}
type="radio"
name={card.cardName}
value={lo.radioName}
checked={!!lo.selected}
onChange={this.onInputChange}
/>
})
}
</ul>
))
}
< button onClick={this.onSubmit}>Submit</button>
< button onClick={this.onReset}>Clear</button>
</div>
}
</div>
);
}
}
ReactDOM.render(<CardsList />, document.getElementById('root'));
<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="root"></div>
Change your log in onSubmit to this
console.log(this.state.cards.map(({ cardName, options }) => {
const option = options.filter(({ selected }) => selected)[0]
return `${cardName}: ${option.radioName}`
}))
This way you filter the options to the one, where selected is truthy, and take the first one.
To address your first question, just map over your this.state.cards array before doing the log and check, if there is exactly 1 option, where selected is true. If this is not the case, tell the user in whatever way you want.
Also you can remove your constructor and change it to that:
state = {
cards: [],
}
Because you do not access your props in your constructor
You can go with the answer of #george,
for you to check if either of the radio buttons is clicked for each card, you can run a validation check
let unselectedCards = this.state.cards.filter((card) => {
return !card.options[0].selected && !card.options[1].selected
});
use the unselectedCards variable to highlight the cards.
you can use map options again inside the cards map if you would be having more options.