How can I add/remove rows in ag-Grid? - reactjs

I've using ag-Grid with my React - Typescript project I can set data and get selected data from table but I don't know how to add new empty field and how to remove selected field, I've find on its documents but does not found :(

Using setRowData to set rows so when I want to add new empty field I have to do like
const allNodesData = Array<any>()
this.gridApi.forEachNode((node) => {
allNodesData.push(node.data)
})
allNodesData.push({})
this.gridApi.setRowData(allNodesData)
And when I want to remove selected field I have to do like
const selectedNodes = this.gridApi.getSelectedNodes()
const allNodesData = Array<any>()
this.gridApi.forEachNode((node) => {
if (selectedNodes.indexOf(node) < 0)
allNodesData.push(node.data)
})
this.gridApi.setRowData(allNodesData)

Related

How to keep the check box checked , when navigating to other page of react pagination

I want to ask , how to keep save the id's of the check boxes in a state , and whenever i switched back to first page it automatically search the element with id and mark check boxes automatically.
and if i unmark the checkbox , it deletes the id from the state.
i am able to think about the logic , but cant able to code,it
Small help ,will leads to solve this problem
While switching to other pages, i am succesfully saving the data ,by updating the state
`
// push all the unique objects (combination of previous state of selectedPayments and data from list)
setSelectedPayments((prevState) => {
var arr = [...prevState, ...list];
var newState = [
...new Map(arr.map((item) => [item.id, item])).values(),
];
return newState;
});
console.log('Selected payments are', selectedPayments);
`
Also , removing the objects , if again the checkbox is unchecked ,and updating the state
`
// pull all the objects , which got unChecked
setSelectedPayments((prevState) => {
var newState = prevState.filter(function (objFromA) {
return !list.find(function (objFromB) {
return objFromA.id === objFromB.id;
});
});
return newState;
});
`
Only facing issue with keeping track of the checked boxes, i have implimented this, this is keeping track of main(parent checkbox).
How to extract the ids saved and check the checkboxes when we naviagete from one page to another
`
let elementId = e.target.id;
if (selectedBoxes.includes(elementId)) {
const newArray = selectedBoxes.filter((e) => e !== elementId);
setSelectedBoxes(newArray);
} else {
setSelectedBoxes((prevState) => {
return [...prevState, elementId];
});
}
`
First i modified the Res Json , so that it set's a property isSelected = true,
by comparing the element from the selectedPayments
inAll check handler , i set the selectedPayments like this
And render using this
This is how ,i solved this problem.
** Better and improved answers are always welcome, please share your views.

Relay Modern: delete record in optimisticUpdater

In my app I have a mutation where I want to use the optimisticUpdater to update the view before the server response. For that I need to remove some records from a list into the relay store, like that:
optimisticUpdater: storeProxy => {
storeProxy.delete(recordDataID)
}
The problem is that relay don't remove the record, but it transforms the record in null.
This can be annoying because I have to filter the list every time I use it in my app.
Some one know how can I remove the record ?
thx
You have to remove your records from the list
optimisticUpdater: (store) => {
const listOfRecords = store.getRoot().getLinkedRecords('list')
const newList = listOfRecords.filter(record => record.getDataID() !== recordDataID)
store.getRoot().setLinkedRecords(newList, 'list')
}
In this example I assume your list is placed at the root of your graph
If you decorate your query with #connection, then you can use the ConnectionHandler to easily remove records:
const query = graphql`query WidgetListQuery {
widgets(first: 10) #connection(key: "WidgetList_widgets") {
...
}
}`
optimisticUpdater(store) {
const widgets = ConnectionHandler.getConnection(store.getRoot(), 'WidgetList_widgets');
ConnectionHandler.deleteNode(widgets, deleted_widget.id)
}

Dropdown list not showing default item

I am using the semantic-ui-react dropdown list, which I have working just fine. The problem is, on my form I am pulling data from a database using the Mobx store. I have a array setup for the options in the dropdown list. when the form loads from the store the text field for the dropdown list is blank, if I click on the dropdown I can see that the selected option is highlight (bold). How do I get the text field to show the default options. I have included some code below if anyone can look at it and give me an idea of what I need to do.
Thanks for all your help.
Here is the code for the dropdown list:
<div className="col-sm-3">
<div className="bg-primary text-white text-center">
Driver
</div>
<div>
<Dropdown
selection
fluid
id="driver"
name="driver"
ref="driver"
onChange={this.handleChange}
value={this.props.EquipmentStore.truck_detail.driver}
options={this.props.EquipmentStore.driver_list}/>
</div>
</div>
Here is how I am building the driver_list, I am basically getting a list of users from the database and create an array with value and text fields
let newUserItem = {
value: getUser.id,
text: getUser.first_name + " " + getUser.last_name
};
this.driver_list.push(newUserItem)
The value in the truck_detail.driver is a numberic value that the same value in the value field in the driver_list value field...that is all working fine, I can not get the text value to show in the text field for the dropdown list by default.
Here is the code that I use to build the options list:
async loadDriverList() {
let endpoint = '/api/users/profile/?owner=True';
this.driver_list.length = 0;
let lookupOptions = {
method: "GET",
headers: {
'Content-Type': 'application/json'
}
};
try {
const response = await fetch(endpoint, lookupOptions);
const profile_list = await response.json();
const userItem = {value:0, text:'Select Driver'};
this.driver_list.push(userItem);
let array_length = profile_list.length;
for (let i = 0; i < array_length; i++) {
let ownerId = profile_list[i].user;
let endpoint = '/api/users/users/' + ownerId + '/';
let userList = await fetch(endpoint, lookupOptions);
let getUser = await userList.json();
let newUserItem = {
value: getUser.id,
text: getUser.first_name + " " + getUser.last_name
};
this.driver_list.push(newUserItem)
}
} catch(e) {
console.log(e)
}
}
After a lot of conversation with Predrag Beocanin I have solved this issue. What it boils down to is my form (with the Dropdown) was getting render before the options list was fully populated. In my application I have a form that shows a list of items, once you click on the item it will render a detailed form of that listed item. Originally I wall trying to populate my options list once you click on the item you wanted to view the details on. Because the options list is basically a static list, I am now populating that list when you are view the first form. Now when you click on the item to view the Dropdown options are fully populated and working just as I had expected.
Thanks for your help Predrag.

How to update array in Angular?

Hi I am developing web application in Angular 5. I have one array and I want to update the same array based on the value of another array. For example, I have createarray as below.
I have another object as below.
data:{
checked:true,
name:infomodel
}
Now there is checked true in data. So for infomodel in createarray I want to update the checked property.
I tried as below.
let copyCreate = Object.assign({}, node.data);
copyCreate.checked = true;
const targetIdxCreate = this.createnode.map(item => item.name).indexOf(copyCreate.name);
this.createnode[targetIdxCreate] = copyCreate;
let copyUpdate = Object.assign({}, node.data);
copyUpdate.checked = false;
const targetIdxUpdate = this.updatenode.map(item => item.name).indexOf(copyUpdate.name);
this.updatenode[targetIdxUpdate] = copyUpdate;
In the above code, It updates createnode checked with true. Also I am making updatenode chcked to false. After executing the above code, both arrays will have checked property false.
can someone help me to do this?
I would suggest to add the check based on 'id' field that you have in your record that you want to update with. In that case the ideal way to update the record would like like below:
// Assuming updateWith is the object that you want to update with
const targetIdx = this.createnode.map(item => item.id).indexOf(this.updateWith.id);
this.createnode[targetIdx] = this.updateWith;
if you still prefer to use 'name' as a parameter that you want to check the condition for, then you can just change the id to name in the map function like so:
// Assuming updateWith is the object that you want to update with
const targetIdx = this.createnode.map(item => item.name).indexOf(this.updateWith.name);
this.createnode[targetIdx] = this.updateWith;
Hope this solves your problem :)
Simply use array = array.slice().
That will create a new Array Object, trigger ChangeDetection etc
Try replacing your code with this
let item = this.createnode.find(item => item.name == data.name)
item.checked = data.checked;
this.createnode = [...this.createnode, item];

How to verify sorting of multiple ag-grid columns in Protractor

I am using protractor for e2e testing.
There is a ag-grid table where multiple columns are sorted in ascending order.
How do i go about verifying this?
Picture of Sample table
In AgGrid the rows might not always be displayed in the same order as you insert them from your data-model. But they always get assigned the attribute "row-index" correctly, so you can query for it to identify which rows are displayed at which index.
So in your E2E-tests, you should create two so-called "page objects" (a selector fo something in your view, separated from the text-execution code, google for page object pattern) like this:
// list page object
export class AgGridList {
constructor(private el: ElementFinder) {}
async getAllDisplayedRows(): Promise<AgGridRow[]> {
const rows = $('div.ag-body-container').$$('div.ag-row');
await browser.wait(EC.presenceOf(rows.get(0)), 5000);
const result = await rows.reduce((acc: AgGridRow[], elem) => [...acc, new AgGridArtikelRow(elem)], []);
return await this.sortedRows(result);
}
private async sortedRows(rows: AgGridRow[]): Promise<AgGridRow[]> {
const rowsWithRowsId = [];
for (const row of rows) {
const rowIndex = await row.getRowIndex();
rowsWithRowsId.push({rowIndex, row});
}
rowsWithRowsId.sort((e1, e2) => e1.rowIndex - e2.rowIndex);
return rowsWithRowsId.map(elem => elem.row);
}
}
// row page object
export class AgGridRow {
constructor(private el: ElementFinder) {}
async getRowIndex(): Promise<number> {
const rowIndexAsString: string = await this.el.getAttribute('row-index');
return parseInt(rowIndexAsString, 10);
}
}
And in your test:
it('should display rows in right order', async () => {
const rows = await gridList.getCurrentDisplayedRows(); // gridList is your AgGridList page object, initialised in beforeEach()
// now you can compare the displayed order to the order inside your data model
});
What this code does: you make page objects for accessing the table as a whole and for accessing elements within a row. To accessing the list in the same order as it is displayed in the view, you have to get all displayed rows (with lazy loading or pagination it should be below 100, otherwise your implementation is bad), get the rowIndex from each of them, sort by it and only then return the grid-list to the test-execution (.spec) file.

Resources