slickgrid - How to loop through rows which are outside canvas? - javascript

I am having some markers on map and same number of rows in slickgrid?
What I want is when a marker is clicked the id of marker is matched with all rows and corresponding row should get selected.
Here is my code:
var $canvas = $(grid.getCanvasNode());
var $allRows = $canvas.find('.slick-row');
$($allRows).each(function() {
if ($(this).rowID == selectedMarker) {
$(this).addClass("active-row");
grid.scrollRowIntoView($(this).index());
}
});
It works fine only when the row which I want is present in the grid but the grid DOM contains only 8 rows at a time (The grid has 30 rows).
How can I loop through all data?

You shouldn't be modifying SlickGrid's DOM at all. SlickGrid will overwrite any changes as it's only rendering the rows in view (with some buffer). When you scroll past that buffer any changes you made to the DOM are lost.
You have to change the row's data and allow SlickGrid to add the appropriate classes to the DOM when it's rendering.
Edit:
SlickGrid setup:
dataView.getItemMetadata = metadata(dataView.getItemMetadata);
function metadata(metadataProvider) {
return function(row) {
var item = this.getItem(row),
ret = metadataProvider(row);
if (item && item.isActive) {
ret = ret || {};
ret.cssClasses = (ret.cssClasses || '') + ' active-row';
}
return ret;
};
}
Then when you click on a marker:
var item = dataView.getItemById(selectedMarker);
var row = dataView.getRowById(selectedMarker);
item.isActive = true;
dataView.updateItem(item.id, item);
grid.scrollRowIntoView(row);

Related

How to get checked rows' values from html table on a sidebar using GAS?

I have a table whose rows consist of 3 columns. 1º is a checkbox, 2º contains the colors and the 3º contains the hex.
As the user selects the colors desired by ticking the checkboxes, i imagine the colors being pushed into an arrat, that will be written to a cell as the user clicks on the save button.
I've borrowed this snippet from Mark, but it doesn't seem to run in my context:
var checkboxes = document.getElementsByTagName("input");
var selectedRows = [];
for (var i = 0; i < checkboxes.length; i++) {
var checkbox = checkboxes[i];
checkbox.onclick = function() {
var currentRow = this.parentNode.parentNode;
var secondColumn = currentRow.getElementsByTagName("td")[1];
selectedRows.push(secondColumn);
};
console.log(selectedRows)
}
This is the javascript part running to load and populate the table and I'm not sure where the above snippet woud go into:
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
/**
* Run initializations on sidebar load.
*/
$(function() {
// Assign handler functions to sidebar elements here, if needed.
// Call the server here to retrieve any information needed to build
// the dialog, if necessary.
google.script.run
.withSuccessHandler(function (record) { //<-- with this
showRecord(record);
})
.withFailureHandler(
function(msg, element) {
showStatus(msg, $('#button-bar'));
element.disabled = false;
})
.getRecord();
});
/**
* Callback function to display a "record", or row of the spreadsheet.
*
* #param {object[]} Array of field headings & cell values
*/
function showRecord(record) {
if (record.length) {
for (var i = 0; i < record.length-1; i++) {
// Adds a header to the table
if(i==0){
$('#sidebar-record-block').append($($.parseHTML('<div class="div-table-row"><div class="div-table-header">Sel</div><div class="div-table-header">Color</div><div class="div-table-header">Hex</div></div>')));
}
// build field name on the fly, formatted field-1234
var str = '' + i;
var fieldId = 'field-' + ('0000' + str).substring(str.length)
// If this field # doesn't already exist on the page, create it
if (!$('#'+fieldId).length) {
var newField = $($.parseHTML('<div id="'+fieldId+'"></div>'));
$('#sidebar-record-block').append(newField);
}
// Replace content of the field div with new record
$('#'+fieldId).replaceWith('<div id="'+fieldId+'" class="div-table-row"></div>');
$('#'+fieldId).append('<input type="checkbox" class="div-table-td" id=CB"'+fieldId+'"name="checkBox" </input>')
.append($('<div class="div-table-td">' + record[i].heading + '</div>'))
.append('<div class="div-table-td">' + record[i].cellval + '</div>')
}
}
}
</script>
Sample of how to get the checked tickboxes an button click
Assuming all your checkboxes are tied to a row, you can loop through all checkboxes with a query selector,
access their checked status
and save the indices of those checkboxes.
Those indices will be the same as when looping through the corresponding table rows.
Sample implementing a button click event:
var saveButton = document.getElementById("myButtonId");
saveButton.onclick = function(){
var checkedRowIndices = [];
$('input[type=checkbox]').each(function( index ) {
if($(this)[0].checked{
checkedRowIndices.push(index);
}
});
};
//now get the rows with those indeices and do something with them

Inquiry regarding array reactivity in Vue.js 2

I have written a grid component that supports child rows, i.e a togglable row with a cell that spans the entire width of the table, under each normal row. In order to keep track of the child rows state I am using a data property called openChildRows which defaults to an empty array. When the user clicks on the toggle icon which is present on the first column of each row, the child row of that row opens. An additional click closes it. The openChildRows array contains the ids of the open rows.
The issue I am having is that when I use a component for the child row, all open rows that come after the one toggled will be remounted. This is clearly inefficient, especially if the child row component sends an ajax request when mounted. Ideally, what I would want is that only the new child row will be mounted.
I have written the grid using JSX for templates. Below is the relevant code:
Rows template:
module.exports = function(h, that) {
var rows = [];
var columns;
var rowKey = that.opts.uniqueKey;
var rowClass;
var data = that.source=='client'?that.filteredData:that.tableData;
var recordCount = (that.Page-1) * that.limit;
data.map(function(row, index) {
index = recordCount + index + 1;
columns = [];
if (that.hasChildRow) {
var childRowToggler = <td><span on-click={that.toggleChildRow.bind(that,row[rowKey])} class={`VueTables__child-row-toggler ` + that.childRowTogglerClass(row[rowKey])}></span></td>;
if (that.opts.childRowTogglerFirst) columns.push(childRowToggler);
}
that.allColumns.map(function(column) {
let rowTemplate = that.$scopedSlots && that.$scopedSlots[column];
columns.push(<td class={that.columnClass(column)}>
{rowTemplate ? rowTemplate({ row, column, index }) : that.render(row, column, index, h)}
</td>)
}.bind(that));
if (that.hasChildRow && !that.opts.childRowTogglerFirst) columns.push(childRowToggler);
rowClass = that.opts.rowClassCallback?that.opts.rowClassCallback(row):'';
rows.push(<tr class={rowClass} on-click={that.rowWasClicked.bind(that, row)} on-dblclick={that.rowWasClicked.bind(that, row)}>{columns} </tr>);
// Below is the code that renders open child rows
if (that.hasChildRow && this.openChildRows.includes(row[rowKey])) {
let template = this._getChildRowTemplate(h, row);
rows.push(<tr class='VueTables__child-row'><td colspan={that.allColumns.length+1}>{template}</td></tr>);
}
}.bind(that))
return rows;
}
Toggle method code:
module.exports = function (rowId, e) {
if (e) e.stopPropagation();
if (this.openChildRows.includes(rowId)) {
var index = this.openChildRows.indexOf(rowId);
this.openChildRows.splice(index,1);
} else {
this.openChildRows.push(rowId);
}
};
The _getChildRowTemplate method:
module.exports = function (h, row) {
// scoped slot
if (this.$scopedSlots.child_row) return this.$scopedSlots.child_row({ row: row });
var childRow = this.opts.childRow;
// render function
if (typeof childRow === 'function') return childRow.apply(this, [h, row]);
// component
return h(childRow, {
attrs: {
data: row
}
});
};
I changed:
if (that.hasChildRow && this.openChildRows.includes(row[rowKey])) {
let template = this._getChildRowTemplate(h, row);
rows.push(<tr class='VueTables__child-row'><td colspan={that.allColumns.length+1}>{template}</td></tr>);
}
to:
rows.push(that.hasChildRow && this.openChildRows.includes(row[rowKey])?
<tr class='VueTables__child-row'><td colspan={that.allColumns.length+1}>{this._getChildRowTemplate(h, row)}</td></tr>:h());
And voila!

JQuery datatable change cell styling according to content without redrawing the whole table

I have jquery datatable and want to set styling properties (color and background color) according to cell content.
Table is changed very dynamically so I cannot redraw the whole table each time cell content is changed.
Is there a way to do this?
I considered using column rendering which is called each time cell is edited and can control data displaying, but I'm not sure this is the best way. in addition render callback gets cell data and not td.
Thanks!!
When calling from rowDrawCallback I used:
"fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
if (!aData || aData.length == 0) return;
if(columns.indexOf(INDEX_STAT) >= 0) {
var state = aData[INDEX_STAT].state;
var exitCode = aData[INDEX_STAT].exitCode;
var statIndex = columns.indexOf(INDEX_STAT);
var statSelector = $('td', nRow).eq(statIndex);
if (!state)
log("undef state");
ResultsModule.updateStatusCellInfo(statSelector, state, exitCode);
}
}
var ResultsModule = {
updateStatusCellInfo: function(selector, state, exitCode){
var mapper = ResultsModule.getTestResults(state, exitCode).map;
var currentStatusString = mapper.status;
var currentStatusColor = mapper.color;
var currentStatusBgColor = mapper.bgcolor;
if (currentStatusString) selector.text(currentStatusString); // updating status as text
else selector.text(Status.None);
if (currentStatusColor) selector.css('color',currentStatusColor); // seting status color from mapper
if (currentStatusBgColor) selector.css('background-color',currentStatusBgColor); // seting status color from mapper
}
}
I used for this column.render, that called for the cell before it is drawed.
Maybe it is not function target, but it does the work :).
Getting td can be done by:
var cell = meta.settings.aoData[meta.row].anCells[meta.col];
var statSelector = $(cell);
selector.css('color', "");
selector.css('background-color',"");
see this discussion for more information on getting DOM cell from render function.

Disable table-hover on certain row in Angular Bootstrap

I have a table that displays selectable information. Sometimes there are child rows that are selectable.
I want the parent rows to be selectable if they have no children, otherwise only the child rows should be selectable. This is a select-only-one type of table.
This table works as expected. However, I want to disable the hover on the non-selectable parent row.
Here is a working plunker: http://plnkr.co/edit/Z0cgHKx2qxpekEE36O1K?p=preview
Here is an example of some of the code in the controller:
scope.parentSelected = [];
$scope.childSelected = [];
$scope.getParentDetails = function(parentObj) {
if(!parentObj.jobs || parentObj.jobs.length === 0) {
nonSelectOtherRows();
var index = $scope.pro.indexOf(parentObj);
$scope.parentSelected[index] = !$scope.parentSelected[index];
// get details for parent row using parentObj
console.log(parentObj);
}
};
$scope.getChildDetails = function(parentObj, childObj) {
nonSelectOtherRows();
var parentIndex = $scope.pro.indexOf(parentObj);
var childIndex = parentObj.jobs.indexOf(childObj);
$scope.childSelected[parentIndex] = [];
$scope.childSelected[parentIndex][childIndex] = !$scope.childSelected[parentIndex][childIndex];
// get details for parent and child rows using parentObj and childObj.
// childObj is the childRow selected
console.log(parentObj);
console.log(childObj);
}
Remove table-hover attribute.
Implement your ng-mouseover and ng-mouseleave functions.
$scope.hoverIn = function(row){
row.hoverEdit = true;//check selectable or not
};
$scope.hoverOut = function(row){
row.hoverEdit = false;
};
Define css class for hover.
.custom-hover {
background-color: red;
}
Finally add class to your tr
`'custom-hover': x.hoverEdit`
here is: http://plnkr.co/edit/CJxi86GyM8jMbtehPQgU?p=preview
Add your selectable control inside hoverIn and it will be work.
try to use ng-class. it will help you.

Hide row in Extjs grid view not work

I need to hide duplicate rows in master/detail grid. I found this fiddle http://jsfiddle.net/tPB8Z/1465/ that hides some cells based user choice, but when I applied this in my code http://jsfiddle.net/alebotello/axvhtrcL/21/ method addRowCls() from view grid, it did not work for rows. Master and detail grids shared same store, and I only want to change rows visibility in master grid, without modify store or create a new one.
In master grid listeners:
afterrender: function (comp) {
var st = comp.getStore();
var arr = [];
var i = 0;
var view = comp.getView();
st.each(function (record) {
// console.log(record);
if (arr.indexOf(record.data['idOrden']) === -1) {
arr.push(record.data['idOrden']);
} else {
view.removeRowCls(record, 'x-grid-view');
view.addRowCls(record, 'oculto');
// console.log(view);
}
i++;
});
css
.oculto{
display: none;
}
Fix is very simple, change the master grid listener from 'afterrender' to 'viewready'.
For most of the Ext.view.View based Components like Grid, List developers should use viewready events instead of afterrender to perform post render DOM manipulations.
This is documented in their API Doc and Guides.
viewready: function (comp) {
var st = comp.getStore();
var arr = [];
var i = 0;
var view = comp.getView();
st.each(function (record) {
debugger;
if (arr.indexOf(record.data['idOrden']) === -1) {
arr.push(record.data['idOrden']);
} else {
view.removeRowCls(record, 'x-grid-view');
view.addRowCls(record, 'oculto');
console.log(view);
}
i++;
});
}
Working example forked from above jsfiddle:- http://jsfiddle.net/chetanbh/rpbdq4ex/

Categories

Resources