Is there any examples that show how to make a single column grid sortable and draggable? (unmanaged dragging)
The onRowDragMove event doesn't fire properly.
Each row is an object with only two key-value pairs: name and path. This is what I've tried
function onRowDrag(e) {
console.log('row drag()')
let movingNode = e.node;
let overNode = e.overNode;
let rowStore = e.api.getRenderedNodes();
console.dir(rowStore);
let rowNeedsToMove = movingNode !== overNode;
if (rowNeedsToMove) {
// the list of rows we have is data, not row nodes, so extract the data
let movingData = movingNode.data;
let overData = overNode.data;
let fromIndex = rowStore.indexOf(movingData);
let toIndex = rowStore.indexOf(overData);
let newStore = rowStore.slice();
moveInArray(newStore, fromIndex, toIndex);
rowStore = newStore;
e.api.setRowData(newStore);
e.api.clearFocusedCell();
}
function moveInArray(arr, fromIndex, toIndex) {
var element = arr[fromIndex];
arr.splice(fromIndex, 1);
arr.splice(toIndex, 0, element);
}
}
Related
I have the following code that works great when the header row is row 1
readerData(rawFile) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = e => {
const data = e.target.result;
const workbook = XLSX.read(data, { type: "array" });
const firstSheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[firstSheetName];
const header = this.getHeaderRow(worksheet);
const results = XLSX.utils.sheet_to_json(worksheet,{ header: 0, range: 0, defval: ""});
this.generateData({ header, results });
this.loading = false;
resolve();
};
reader.readAsArrayBuffer(rawFile);
});
},
generateData({ header, results }) {
this.excelData.header = header;
this.excelData.results = results;
this.excelData.original_results = [...results];
this.onSuccess && this.onSuccess(this.excelData);
var grid = this.$refs.membersGrid.ej2Instances;
grid.dataSource = this.excelData.results;
grid.refresh();
},
getHeaderRow(sheet) {
const headers = [];
const range = XLSX.utils.decode_range(sheet["!ref"]);
let C;
const R = range.s.r;
/* start in the first row */
for (C = range.s.c; C <= range.e.c; ++C) {
/* walk every column in the range */
const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })];
/* find the cell in the first row */
let hdr = "UNKNOWN " + C; // <-- replace with your desired default
if (cell && cell.t) hdr = XLSX.utils.format_cell(cell);
headers.push(hdr);
}
return headers;
},
It works great and put all of the Header values into the excelData.header and it put all of the named array data into the excelData.results. My problem is it all goes to a mess when the first row or first two rows are blank or I need to skip them. I've tried
https://github.com/SheetJS/sheetjs/issues/463
but I'm using "xlsx": "^0.17.1" . When I used
range.s.r = 1;
I was able to change my range to A2 but I could not get my named array of data. Any help is appreciated .
After a few days of digging and a lot of trial and error code I got my solution that I will post for others to use if they have the same problem. I used the same code up to this point.
readerData(rawFile) {
let fileName = rawFile.name;
this.showLoading();
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = e => {
var data = e.target.result;
var workbook = XLSX.read(data, { type: "array" });
var firstSheetName = workbook.SheetNames[0];
var worksheet = workbook.Sheets[firstSheetName];
var range = XLSX.utils.decode_range(worksheet['!ref']);
var header = this.getHeaderRow(worksheet,range);
The reason for this is that it gives me the file name, the first sheets name and the value in the first row. From there I can determine where my header row is and where the data row starts. The data row does not have to be the row after the header so my next line of code could be:
range.s.r = 1; // <-- zero-indexed, so setting to 1 will skip row 0
worksheet['!ref'] = XLSX.utils.encode_range(range);
header = this.getHeaderRow(worksheet,range);
range.s.r = 2;
var results = XLSX.utils.sheet_to_json(worksheet,{ header: header, range: range, defval: ""});
The results are based upon the values header and range that have been adjusted using the:
range.s.r = 1 or 2 or whatever number you need
I can now read all of the Excel sheets and make a clean named array for data processing. Hope this helps someone.
rather than my original 0's
I have a loop in which I am calling rec_append() recursively, apparently the first pass alone works, then the loop stops.
I have an array of 4 elements going into that $.each loop but I see only the first element going into the function recursively. Help!
I switched it for a element.forEach but that gives me only the second element and I am stuck, is there a better solution to process a tree of elements? My array is a part of a tree.
var data = JSON.parse(JSON.stringify(result))
var graph = $(".entry-point");
function rec_append(requestData, parentDiv) {
var temp_parent_details;
$.each(requestData, function (index, jsonElement) {
if (typeof jsonElement === 'string') {
//Element construction
//Name and other details in the form of a : delimited string
var splitString = jsonElement.split(':');
var details = document.createElement("details");
var summary = document.createElement("summary");
summary.innerText = splitString[0];
details.append(summary);
temp_parent_details = details;
parentDiv.append(details);
var kbd = document.createElement("kbd");
kbd.innerText = splitString[1];
summary.append(' ');
summary.append(kbd);
var div = document.createElement("div");
div.className = "col";
details.append(div);
var dl = document.createElement("dl");
div.append(dl);
var dt = document.createElement("dt");
dt.className = "col-sm-1";
dt.innerText = "Path";
div.append(dt);
var dd = document.createElement("dd");
dd.className = "col-sm-11";
dd.innerText = splitString[2];
div.append(dd);
var dt2 = document.createElement("dt");
dt2.className = "col-sm-1";
dt2.innerText = "Type";
div.append(dt2);
var dd2 = document.createElement("dd");
dd2.className = "col-sm-11";
dd2.innerText = splitString[1];
div.append(dd2);
} else {
$.each(jsonElement, function (jsonElementArrIndx, jsonChildElement) {
rec_append(jsonChildElement, temp_parent_details); //Only 1 pass works, rest skip
});
}
});
}
rec_append(data, graph);
Sample data:enter image description here
I'm trying to set checkboxes in a range. The firebase_id array must match column B in the range. If matching? Set row to TRUE. But i'm get some randomly checked checboxxes..
What am I doing wrong..?
function setCheckboxIfValueKinguinIdExist() {
const AS = SpreadsheetApp.getActiveSpreadsheet();
const SHEET_TESTING = AS.getSheetByName("Testing");
let get_firebase_items = getSelectedIdsFromFirebase();
let firebase_ids = get_firebase_items.map(function(item){return item.kinguinId}); // [ '17','2962','9798']
let last_row = SHEET_TESTING.getLastRow();
let values = SHEET_TESTING.getRange("A2:B"+last_row).getValues();
let row = 1;
for(let a in values) {
let item = values[a][1];
if(firebase_ids.includes(item) === true){
SHEET_TESTING.getRange(row,1).setValue("TRUE");
}
row++;
}
}
Try this:
function setCheckboxIfValueKinguinIdExist() {
const AS = SpreadsheetApp.getActiveSpreadsheet();
const SHEET_TESTING = AS.getSheetByName("Testing");
let get_firebase_items = getSelectedIdsFromFirebase();
let firebase_ids = get_firebase_items.map(function(item){return item.kinguinId}); // [ '17','2962','9798']
var last_row = SHEET_TESTING.getLastRow();
var values = SHEET_TESTING.getRange("A2:B"+last_row).getValues();
var row = 1;
values.forEach((r,i)=>{
if(firebase_ids.includes(r[1])) {
SHEET_TESTING.getRange(i+2,1).setValue("TRUE");
}
});
}
I am new to ReactJS and I am trying to work with React Data Grid.
When I filter my table, make a change to a cell, then unfilter the table, the change reverts back to its previous value.
If I change
const rows = this.state.rows.slice(0);
to
const rows = Selectors.getRows(this.state);
my changes stay, but then I can not unfilter the table.
Here is how I am handling Grid Rows to Update:
handleGridRowsUpdated = ({ fromRow, toRow, updated }) => {
const rows = this.state.rows.slice(0);
// const rows = Selectors.getRows(this.state);
for (let i = fromRow; i <= toRow; i++) {
const rowToUpdate = rows[i];
const updatedRow = update(rowToUpdate, { $merge: updated });
rows[i] = updatedRow;
if (!rows[i].Date) {
const index = this.state.counter;
newRows[index] = rows[i];
this.handleUpdate(rows[i]);
this.setState({ newRows });
} else {
updatedRows[rows[i].Date] = rows[i];
this.handleUpdate(rows[i]);
this.setState({ updatedRows });
}
}
this.setState({ originalRows: rows });
};
I have looked at the RDG docs and examples. In their filter example, they don't allow you to edit cells.
Thanks in advance!
the state is unmutable, its a bad idea to keep slicing data as that, before you need to make a copy and then manipulate it, thus you can do
const rows = Object.assign([],this.state.rows)
btw a living example or the type of data your holding on rows will be a great help
I figured out a solution, I used the npm library Lodash and their function _.unionBy.
This solution merges the updated rows array with the original states' rows array, on the SN key for each object, into a variable then sets the state with the result:
handleGridRowsUpdated = ({ fromRow, toRow, updated }) => {
const rows = Selectors.getRows(this.state);
const rowsTwo = Object.assign([], this.state.rows);
for (let i = fromRow; i <= toRow; i++) {
const rowToUpdate = rows[i];
const updatedRow = update(rowToUpdate, { $merge: updated });
rows[i] = updatedRow;
if (!rows[i].Date) {
const index = this.state.counter;
newRows[index] = rows[i];
this.handleUpdate(rows[i]);
this.setState({ newRows });
} else {
updatedRows[i] = rows[i];
this.handleUpdate(rows[i]);
}
}
const result = _.unionBy(updatedRows, rowsTwo, 'SN');
this.setState({ rows: result });
};
I have a ToDo list, using localStorage... I need to be able to remove the item from the ToDo list... I try to use "dataArray.splice();" But the problem is I don't know how i can remove the object when the position is unknown...
function getTodoItems() {
for (var i = 0; i < dataArray.length; i++) {
if (!dataArray[i].listItem.length) return;
var itemList = document.getElementById("my-todo-list");
var list = document.createElement("li");
itemList.appendChild(list);
list.innerHTML = dataArray[i].listItem;
var spanItem = document.createElement('span');
spanItem.style.float = 'right';
var myCloseSymbol = document.createTextNode('\u00D7');
spanItem.classList.add("closeBtn");
spanItem.appendChild(myCloseSymbol);
listItems[i].appendChild(spanItem);
close[i].onclick = function() {
var div = this.parentElement;
div.style.display = "none";
console.log(dataArray);
}
var list = document.getElementsByTagName('li');
list[i].onclick = function() {
this.classList.toggle("checked");
}
}
}
Then probably get its position:
const position = dataArray.indexOf(/*whatever*/);
dataArray.splice(position, 1);
You can get the position of the element using 'indexOf'
let pos = dataArray.indexOf(element);
dataArray.splice(pos,1)
IndexOf() wont work if you are trying to find the index of an entire object or array inside the array.
If you need to find the index of an entire object inside your array, you test each one's value to find out if it is the correct one. I would use findIndex();
Try this in your console:
var array = [];
for (var i = 0; i < 10; i++ ){ array.push({item: i}) }
console.log('Current Array: ', array);
var indexOfResult = array.indexOf({item: 3});
console.log('indexOf result: ',indexOfResult);
var findIndexResult = array.findIndex(object => object.item === 3);
console.log('findIndex result: ',findIndexResult)