How to checked/uncheck all checkbox in react js? - javascript

I want when I checked the child checkbox all the column checkbox should be checked in a row will be check
I want if I checked the parent one all the table checkboxes should be check how i implement I need code example if you have
Note: I am using functional react component with my custom table created by own not any table library.
Thanks every one !

You can do it by this way
Here I am assuming that the data will be in following way:
permissons = [
{create:false, read:false, edit: true, delete:true}
{create:false, read: true, edit: false, delete:true}
]
const checkAll = (event, index) => {
const { checked } = event.target;
const newPermission = [...permissions];
if (checked === true) {
// console.log("Checked");
newPermission[index].create = true;
newPermission[index].read = true;
newPermission[index].edit = true;
newPermission[index].delete = true;
} else if (checked === false) {
// console.log("Unchecked");
newPermission[index].create = false;
newPermission[index].read = false;
newPermission[index].edit = false;
newPermission[index].delete = false;
}
setpermissions([...newPermission]);
};
Pass event and index as props in checkAll function.

You can try the following logic for your first requirement. The logic for second Requirement is similar. You can define some hooks for each row to make it cleaner.
const [row, setRow] = useState({ allChecked: true, permissions: [-1, 1, 1, 1, -1, -1, 1]});
// -1 = does not allow change, 0 = unchecked, 1 = checked
// each index represents a permission, you can use enum to make it clearer
useEffect(() => {
// for update child checkbox
if (row.allChecked && row.permissions.includes(0) {
let updatePermission = ow.permissions.map(permission => permission || 1); // if permission is 0 it will be changed to 1
let updateRow = Object.assign({}, row);
updateRow.permission = updatePermission;
setRow(updateRow);
}
}, [row]}
useEffect(() => {
let updateRow = Object.assign({}, row);
// for update permission checkboxs
if (!row.permissions.includes(0) && !row.allChecked) {
updateRow.allChecked = true;
setRow(updateRow);
} else if (row.permssions.includes(0) && row.allChecked {
updateRow.allChecked = false;
setRow(updateRow);
}
}, [row]);

You need to create a pattern for row and column
For instance
For every row add index of row to each checkbox class like checkbox_${index}
Use queryselectorAll to target them and just trigger click
document.querySelectorAll(`row_${index}`).forEach(el=>el.click())
Similar the case for all checkbox in a column.

Related

React - CheckboxTree filter

So i am using this package "react-checkbox-tree" to make a checkbox, but since this is made on classes components and i need to do it with functions and hooks, this is being a bit tricky to my actual skills.
//Checkbox Tree
const [checkedTree, setCheckedTree] = useState([]);
const [expandedTree, setExpandedTree] = useState(["1"]);
const [filterText, setFilterText] = useState("");
const [nodesFiltered, setNodesFiltered] = useState();
///FILTER LOGIC /////
const onFilterChange = (e) => {
setFilterText(e.target.value);
if (e.target.value) {
filterTree();
}
};
const filterTree = () => {
// Reset nodes back to unfiltered state
if (!filterText || filterText === "" || filterText.length === 0) {
setNodesFiltered(nodes);
return;
}
const nodesFiltered = (nodes) => {
return nodes.reduce(filterNodes, []);
};
setNodesFiltered(nodesFiltered);
};
const filterNodes = (filtered, node) => {
const children = (node.children || []).reduce(filterNodes, []);
if (
// Node's label matches the search string
node.label.toLocaleLowerCase().indexOf(filterText.toLocaleLowerCase()) >
-1 ||
// Or a children has a matching node
children.length
) {
filtered.push({ ...node, ...(children.length && { children }) });
}
return filtered;
};
//
My first problem is that when i search for the parent, i only get the last children of the array for some reason.
The Second is that when i use the backspace button, the filter stops working until i clean every char.
I made a codesandbox to help you guys to understand the problems:
https://codesandbox.io/s/checkboxtree-6gu60
This is the example on with classes:
https://github.com/jakezatecky/react-checkbox-tree/blob/master/examples/src/js/FilterExample.js
Tks in advance!
For your second problem, I solved it by passing through onKeyDown as well as onChange from my search input:
<input
type="text"
onChange={onFilterChange}
onKeyDown={onBackspace}
/>
which calls
// If the user deletes the search terms, reset to unfiltered
const onBackspace = e => {
var key = e.keyCode || e.charCode
// magic numbers are backspace and delete. Naming them didn't work.
if (key == 8 || key == 46) {
setFilterText("")
filterTree()
}
}

How can I force update?

I'm making a page for posts that can be viewed by newest or most likes.
I manage this with drop-down lists and arrays.
And whenever the dropdown list is clicked, I have to force update this to match its value.
async selectPosts ({...} = {}, forceUpdate = false) {
let goodOrderByDir = 'desc'
let dateOrderByDir = 'desc'
const db = getFirestore()
let constraints = [ //This array determines the viewing order.
orderBy('date', dateOrderByDir), orderBy('good', goodOrderByDir)]
var hw = document.getElementById('dropDowmListID') //It is linked to a drop-down list.
hw.addEventListener('change', function() {
if (hw.value == 1) { //newest
constraints = [
orderBy('date', dateOrderByDir), orderBy('good', goodOrderByDir)]
}
if (hw.value == 2) { //most likes
constraints = [
orderBy('good', goodOrderByDir), orderBy('date', dateOrderByDir)]
}
})
if (forceUpdate) {
this._lastSelectPostsOptions = {}
}
constraints.push(limit(pageSize))
const queryRef = query(collection(db, 'posts'), ...constraints)
return Promise.all((await getDocs(queryRef)).docs.map(async item => {
this._lastSelectPostsDoc = item
const data = item.data()
return {
...data
}
}))
}
When doing a forced update, the default value is false in the current code.
async selectPosts ({...} = {}, forceUpdate = false)
So when I change the dropdown list I was told it must be true to get the next value.
So I changed the code like this
async selectPosts ({...} = {}, forceUpdate = true)
But I couldn't get the value I wanted...
How can I force an update to apply the changed array values?

How to reset a select field onChange

I have a dropdown select component that is populated by what is selected from a set of buttons. Before a selection from the button list is made the dropdown has no choices. But I have created an issue where if a button is selected then another is selected the dropdown still holds the value from the previous selection even tho that item is not suppose to be in the list of options in the drop down. I am trying to figure out a way to reset or clear the selection:
const [location, setLocation] = useState("");
const [thvchecked, setThvChecked] = useState(false);
const [pvchecked, setPvChecked] = useState(false);
const [osvchecked, setOsvChecked] = useState(false);
let emCodeOptions = [];
if (location === "telehealthVisit") {
emCodeOptions = telehealthVisitEMCode;
} else if (location === "telephoneVisit") {
emCodeOptions = telephoneVisitEMCodeChoices;
} else if (location === "onSiteVisit") {
emCodeOptions = onSiteVisitEMCodeChoices;
} else {
emCodeOptions = [];
}
const handleEMCodeChange = (selected) => {
props.onUpdate("emCode", selected.value);
};
const onLocationSelection = (event) => {
let loc = event.target.name;
if (loc === "telehealthVisit") {
setLocation("");
setThvChecked(!thvchecked);
props.onUpdate("visitLocation", loc);
} else if (loc === "telephoneVisit") {
setLocation("");
setPvChecked(!pvchecked);
props.onUpdate("visitLocation", loc);
} else if (loc === "onSiteVisit") {
setLocation("");
setOsvChecked(!osvchecked);
props.onUpdate("visitLocation", loc);
}
setLocation(loc);
};
I though I could do this by resetting the state in the onLocationSlection function but this doesnt seem to work beyond the first time I change my selection.
React doesn't call render method each time u setLocation . It will accumulate the values and smartly call the render with the last value. So setLocation to '' doesn't have the desired effect.
This piece of code looks logically correct to me. Are you updating arrays telehealthVisitEMCode, telephoneVisitEMCodeChoices else where?

Ag-grid: clear cell when "agSelectCellEditor" is used

As stated in the ag-grid documentation:
The default editor will clear the contents of the cell if Backspace or
Delete are pressed.
But this doesn't work when the "agSelectCellEditor" is used. If you press Delete or Backspace the cell will enter in EDIT mode and you can choose only the values that are provided as options.
Any idea how can I achieve the same behavior?
I found an article that explain how to write the delete cells logic. This works also for multiple cells. Please check this article: https://blog.ag-grid.com/deleting-selected-rows-and-cell-ranges-via-key-press/
Basically you override the default behavior of the DELETE or BACKSPACE keys using suppressKeyboardEvent callback in our default column definition:
defaultColDef: {
suppressKeyboardEvent: params => {
if (!params.editing) {
let isBackspaceKey = params.event.keyCode === 8;
let isDeleteKey = params.event.keyCode === 46;
if (isBackspaceKey || isDeleteKey) {
params.api.getCellRanges().forEach(range => {
let colIds = range.columns.map(col => col.colId);
let startRowIndex = Math.min(
range.startRow.rowIndex,
range.endRow.rowIndex
);
let endRowIndex = Math.max(
range.startRow.rowIndex,
range.endRow.rowIndex
);
clearCells(startRowIndex, endRowIndex, colIds, params.api);
}
}
return false;
}
}
And the delete method:
function clearCells(start, end, columns, gridApi) {
let itemsToUpdate = [];
for (let i = start; i <= end; i++) {
let data = gridApi.rowModel.rowsToDisplay[i].data;
columns.forEach(column => {
data[column] = "";
});
itemsToUpdate.push(data);
}
gridApi.applyTransaction({ update: itemsToUpdate });
}
This works as expected.
This was fixed in 28.2.0, now delete key always clears the cell without entering the "editing mode".
Reference: https://github.com/ag-grid/ag-grid/releases/tag/v28.2.0, AG‑4801

How to prevent a div from increasing the value of an upvote after one click using react

I have this div that perform an onclick event by increasing the value of an upvote when a user click on the div. It increment which is fine, but I only want it to increment only once even when the user clicks on the div multiple times.
Here is my code
btnUpvote(data) {
let feeds = [...this.state.feeds]
let feed = feeds.find(x => x.id === data.id)
// feed.upvote +1
let get = feed.upvote + 1
console.log(get)
if (feed.upvote !== get) {
}
this.setState({
feeds
})
}
The value of the feed.upvote is stored in an array of object, any help would be appreciated.
Try adding this condition :
let get = 0
if(!feed.upvote){
get= feed.upvote + 1}
You could use an array to store the id which has already been upvoted.
Check it and handle your clicks accordingly.
let allowOneClicks = [];
function allowOnce(id, callback) {
if (allowOneClicks.includes(id)) return;
allowOneClicks.push(id);
callback();
}
In your case, it can be like this.
// outside your component;
const upvotedIds = [];
btnUpvote(data) {
let feeds = [...this.state.feeds]
let feed = feeds.find(x => x.id === data.id)
if (upvotedIds.includes(id)) return;
upvotedIds.push(id);
// upvote here.
}
you can try this.
onHandleClick = (id) => {
this.setState({
feed: {
...this.state.feed,
[id]: (this.state.feed[id] || 0) + 1
}
})
}

Categories

Resources