How to prevent onRowClicked when using a cellRenderer in AgGridReact - ag-grid-react

When using your own cell renderer for e.g. an action column - with links or buttons in it -, AgGridReact still triggers a onRowClicked event when you click on one of the links or buttons. event.stopPropagation and event.preventDefault do not help.
// list of rowActions ...
function RowActionsRenderer(props) {
let row = props.data;
return <div>{
rowActions.map((actionDef, index) =>
<Button onClick={(event) => {
event.stopPropagation();
event.preventDefault();
//_processAction(actionDef, row)
}}>{label(actionDef.name)}</Button>
)
}</div>;
}
Definition of cellRenderer:
// ...
columnDefs.push({
headerName: 'actions',
field: '-actions-',
width: 120,
sortable: false,
filter: false,
cellRenderer: 'rowActionsRenderer'
});
// ...
frameworkComponents: {
rowActionsRenderer: RowActionsRenderer
},
Registration of event listening:
onRowClicked={(row) => {
// always runs event when when clicked on button in the '-actions-' column !!!
}}
Now, how do you prevent onRowClicked being called when clicking anything in the '-actions-' column?

There are some rather complicated low level calls to the AgGrid api I like to avoid.
So my proposed solution would be:
First, do not listen to row clicks.
Second listen to cell clicks and filter out column id '-actions-'
onCellClicked={(cell) => {
if (cell.column.getColId() === '-actions-') {
return;
}
let row = cell.data;
// process row data ...
}

Related

Cannot insert data by pressing Enter in Combogrid after selection

I am using a combogrid for load data to insert into datagrid. I call the insert data to datagrid in onSelect. Thats mean when i select any data or press down key to scroll all my data then those rows will be selected any inserted automatically . But i want to look through the rows but only when i press inter then the selected row will be inserted.
I am trying this by using KeyUp function. But this wont working.
This is my previous code:
Combogrid add to row
function combogridData() {
var g = $('#itemListGrid').combogrid('grid'); // get datagrid object
var r = g.datagrid('getSelected'); // get the selected row
$('#itemListGrid').keyup(function(e){
if(e.keyCode == 13)
{
addrowtogrid(r);
}
});
$('#itemListGrid').combogrid('clear');
}
My Combogrid :
<select id="itemListGrid" class="easyui-combogrid" style="width:100%" data-options="
panelWidth: 600,
loader: myloader,
mode: 'remote',
idField: 'book_id',
textField: 'name',
method: 'get',
value: '',
columns: [[
{field:'book_id',title:'Item ID',width:'7%'},
{field:'name',title:'Book Name',width:'48%'},
{field:'retail',title:'retail',width:'5%',align:'right',hidden:true},
{field:'local_sale',title:'local',width:'7%',align:'right'},
{field:'whole_sale',title:'Whole',width:'8%',align:'right'},
{field:'isbn',title:'ISBN',width:'15%'},
{field:'authors',title:'Authors',width:'15%'},
]],
fitColumns: true,
labelPosition: 'top',
onSelect:combogridData ">
I am trying by using this code :
function combogridData() {
var g = $('#itemListGrid').combogrid('grid'); // get datagrid object
var r = g.datagrid('getSelected'); // get the selected row
$('#itemListGrid').keyup(function(e){
if(e.keyCode == 13)
{
addrowtogrid(r);
}
});
$('#itemListGrid').combogrid('clear');
}
I got My Own solution.
don't need to add onSelect anymore.
Just added
$('#itemListGrid').combogrid('textbox').bind('keyup', function(e){
if (e.keyCode == 13){ // when press ENTER key, accept the inputed value.
var g = $('#itemListGrid').combogrid('grid'); //get the combogrid
var r = g.datagrid('getSelected'); //get selected value
addrowtogrid(r); //add to another datagrid
}
});
under JQuery document.ready().
It's working perfectly. Thanks.

processAjaxOnInit: is set to "false" but Ajax is still called

I'm preloading my table using PHP and then have processAjaxOnInit: false in my config. What happens is that the call to my Ajax url is still made and instead of appending rows to the table it wipes out the rows that are there. I'm assuming that it's still making the call to get the total number of rows. Can I set this on page load and completely bypass calling the Ajax url?
Thanks
.tablesorterPager({
container: $(".pager"),
ajaxUrl : '/documents_table_data.php?page={page}&size={size}&{filterList:filter}&{sortList:column}',
// use this option to manipulate and/or add additional parameters to the ajax url
customAjaxUrl: function(table, url) {
// manipulate the url string as you desire
//url += '&archive=<?php echo $_GET[archive] ?>&wor=<?php echo $_GET[wor] ?>';
// trigger a custom event; if you want
$(table).trigger('changingUrl', url);
// send the server the current page
return url;
},
ajaxError: null,
ajaxObject: {
dataType: 'json'
},
ajaxProcessing: function(data){
if (data && data.hasOwnProperty('rows')) {
var r, row, c, d = data.rows,
total = data.total_rows,
headers = data.headers,
rows = [],
len = d.length;
for ( r=0; r < len; r++ ) {
row = [];
for ( c in d[r] ) {
if (typeof(c) === "string") {
row.push(d[r][c]);
}
}
// is there a way to do that here when it pushes the row onto the array
// or perhaps there is another funtion you have implemented that will let me do that
rows.push(row);
}
return [ total, rows, headers ];
}
},
// Set this option to false if your table data is preloaded into the table, but you are still using ajax
processAjaxOnInit: false,
output: '{startRow} to {endRow} ({totalRows})',
updateArrows: true,
page: 0,
size: 10,
savePages: true,
storageKey: 'tablesorter-pager',
pageReset: 0,
fixedHeight: false,
removeRows: false,
countChildRows: false,
// css class names of pager arrows
cssNext : '.next', // next page arrow
cssPrev : '.prev', // previous page arrow
cssFirst : '.first', // go to first page arrow
cssLast : '.last', // go to last page arrow
cssGoto : '.gotoPage', // page select dropdown - select dropdown that set the "page" option
cssPageDisplay : '.pagedisplay', // location of where the "output" is displayed
cssPageSize : '.pagesize', // page size selector - select dropdown that sets the "size" option
// class added to arrows when at the extremes; see the "updateArrows" option
// (i.e. prev/first arrows are "disabled" when on the first page)
cssDisabled : 'disabled', // Note there is no period "." in front of this class name
cssErrorRow : 'tablesorter-errorRow' // error information row
});
I just added a pager option named initialRows (currently only available in the master branch). When processAjaxOnInit is false and this option is set, no initial ajax call to the server is done (demo):
$(function(){
$('table').tablesorter({
widgets: ['pager'],
widgetOptions : {
pager_processAjaxOnInit: false,
pager_initialRows: {
// these are both set to 50 initially
// the server can return different values
// and the output will update automatically
total: 50,
filtered: 50
},
// other ajax settings...
}
});
});

Arrow from HeaderCell in Angular ui-grid

I need to know whether or not it is possible to remove the down chevron arrow from the headercell of the Angular ui-grid (as seen below):
Because the Sort Ascending and Sort Descending in the dropdown selection does not behave the same as the sort when clicking on column headings in the grid. Clicking on column headings automatically overrides any previous sorting, whereas selecting Sort Ascending or Descending from the dropdown requires that the user selects "Remove Sort" before selecting another column. My QA Team has asked me to "remove" it as they fear it would cause a user to believe that there is something wrong with the sorting feature if the tried to select another Sort Asc/Desc without first clicking Remove Sort. If the arrow cannot be removed, is it at least possible to remove Sort Ascending and Descending from the selection without preventing sorting using the column headings?
In order to remove the Sort Ascending, Sort Descending and Remove Sort from the dropdown menu, I commented out the following in the ui-grid.js file:
//{
// title: i18nService.getSafeText('sort.ascending'),
// icon: 'ui-grid-icon-sort-alt-up',
// action: function($event) {
// $event.stopPropagation();
// $scope.sortColumn($event, uiGridConstants.ASC);
// },
// shown: function () {
// return service.sortable( $scope );
// },
// active: function() {
// return service.isActiveSort( $scope, uiGridConstants.ASC);
// }
//},
//{
// title: i18nService.getSafeText('sort.descending'),
// icon: 'ui-grid-icon-sort-alt-down',
// action: function($event) {
// $event.stopPropagation();
// $scope.sortColumn($event, uiGridConstants.DESC);
// },
// shown: function() {
// return service.sortable( $scope );
// },
// active: function() {
// return service.isActiveSort( $scope, uiGridConstants.DESC);
// }
//},
//{
// title: i18nService.getSafeText('sort.remove'),
// icon: 'ui-grid-icon-cancel',
// action: function ($event) {
// $event.stopPropagation();
// $scope.unsortColumn();
// },
// shown: function() {
// return service.sortable( $scope ) &&
// typeof($scope.col) !== 'undefined' && (typeof($scope.col.sort) !== 'undefined' &&
// typeof($scope.col.sort.direction) !== 'undefined') && $scope.col.sort.direction !== null &&
// !service.suppressRemoveSort( $scope );
// }
//},
Now, the only thing that shows in the dropdown menu is "Hide Column". This solved my issue.
Hope this helps someone else!

jQuery UI Sortable with React.js buggy

I have a sortable list in React which is powered by jQuery UI. When I drag and drop an item in the list, I want to update the array so that the new order of the list is stored there. Then re-render the page with the updated array. i.e. this.setState({data: _todoList});
Currently, when you drag and drop an item, jQuery UI DnD works, but the position of the item in the UI does not change, even though the page re-renders with the updated array. i.e. in the UI, the item reverts to where it used to be in the list, even though the array that defines its placement has updated successfully.
If you drag and drop the item twice, then it moves to the correct position.
// Enable jQuery UI Sortable functionality
$(function() {
$('.bank-entries').sortable({
axis: "y",
containment: "parent",
tolerance: "pointer",
revert: 150,
start: function (event, ui) {
ui.item.indexAtStart = ui.item.index();
},
stop: function (event, ui) {
var data = {
indexStart: ui.item.indexAtStart,
indexStop: ui.item.index(),
accountType: "bank"
};
AppActions.sortIndexes(data);
},
});
});
// This is the array that holds the positions of the list items
var _todoItems = {bank: []};
var AppStore = assign({}, EventEmitter.prototype, {
getTodoItems: function() {
return _todoItems;
},
emitChange: function(change) {
this.emit(change);
},
addChangeListener: function(callback) {
this.on(AppConstants.CHANGE_EVENT, callback);
},
sortTodo: function(todo) {
// Dynamically choose which Account to target
targetClass = '.' + todo.accountType + '-entries';
// Define the account type
var accountType = todo.accountType;
// Loop through the list in the UI and update the arrayIndexes
// of items that have been dragged and dropped to a new location
// newIndex is 0-based, but arrayIndex isn't, hence the crazy math
$(targetClass).children('form').each(function(newIndex) {
var arrayIndex = Number($(this).attr('data-array-index'));
if (newIndex + 1 !== arrayIndex) {
// Update the arrayIndex of the element
_todoItems[accountType][arrayIndex-1].accountData.arrayIndex = newIndex + 1;
}
});
// Sort the array so that updated array items move to their correct positions
_todoItems[accountType].sort(function(a, b){
if (a.accountData.arrayIndex > b.accountData.arrayIndex) {
return 1;
}
if (a.accountData.arrayIndex < b.accountData.arrayIndex) {
return -1;
}
// a must be equal to b
return 0;
});
// Fire an event that re-renders the UI with the new array
AppStore.emitChange(AppConstants.CHANGE_EVENT);
},
}
function getAccounts() {
return { data: AppStore.getTodoItems() }
}
var Account = React.createClass({
getInitialState: function(){
return getAccounts();
},
componentWillMount: function(){
AppStore.addChangeListener(this._onChange);
// Fires action that triggers the initial load
AppActions.loadComponentData();
},
_onChange: function() {
console.log('change event fired');
this.setState(getAccounts());
},
render: function(){
return (
<div className="component-wrapper">
<Bank data={this.state.data} />
</div>
)
}
});
The trick is to call sortable('cancel') in the stop event of the Sortable, then let React update the DOM.
componentDidMount() {
this.domItems = jQuery(React.findDOMNode(this.refs["items"]))
this.domItems.sortable({
stop: (event, ui) => {
// get the array of new index (http://api.jqueryui.com/sortable/#method-toArray)
const reorderedIndexes = this.domItems.sortable('toArray', {attribute: 'data-sortable'})
// cancel the sort so the DOM is untouched
this.domItems.sortable('cancel')
// Update the store and let React update (here, using Flux)
Actions.updateItems(Immutable.List(reorderedIndexes.map( idx => this.state.items.get(Number(idx)))))
}
})
}
The reason jQuery UI Sortable doesn't work with React is because it directly mutates the DOM, which is a big no no in React.
To make it work, you would have to modify jQuery UI Sortable so that you keep the DnD functionality, but when you drop the element, it does not modify the DOM. Instead, it could fire an event which triggers a React render with the new position of the elements.
Since React uses a Virtual DOM, you have to use the function React.findDOMNode() to access an actual DOM element.
I would call the jQuery UI function inside the componentDidMount method of your component because your element has to be already rendered to be accessible.
// You have to add a ref attribute to the element with the '.bank-entries' class
$( React.findDOMNode( this.refs.bank_entries_ref ) ).sortable( /.../ );
Documentation - Working with the browser (everything you need to know is here)
Hope that makes sense and resolves your issue

Extjs4 set tooltip on each column hover in gridPanel

I am getting tooltip on mouse hover by each row for current column but I am unable to get next column tooltip on continue hover on same row.
But I can get it if I hover on another row & again hover any column of the previous row by using:
listeners:{
'itemmouseenter': function (view, record, item, index, e, eOpts) {
var gridColums = view.getGridColumns();
var column = gridColums[e.getTarget(this.view.cellSelector).cellIndex];
Ext.fly(item).set({ 'data-qtip': 'Des:' + column.dataIndex });
}
}
Can anyone show me what I'm missing or point me in the right direction?
I have an easy one, using the renderer function:
{
xtype : 'gridcolumn',
dataIndex : 'status',
text : 'Status',
renderer : function(value, metadata) {
metadata.tdAttr = 'data-qtip="' + value + '"';
return value;
}
}
I was looking through this. I could manage to get the tool tip for each cell by doing something like this:
Ext.getCmp('DynamicDemandGrid').getView().on('render', function(view) {
view.tip = Ext.create('Ext.tip.ToolTip', {
// The overall target element.
target: view.el,
// Each grid row causes its own seperate show and hide.
delegate: view.cellSelector,
// Moving within the row should not hide the tip.
trackMouse: true,
// Render immediately so that tip.body can be referenced prior to the first show.
renderTo: Ext.getBody(),
listeners: {
// Change content dynamically depending on which element triggered the show.
beforeshow: function updateTipBody(tip) {
var gridColums = view.getGridColumns();
var column = gridColums[tip.triggerElement.cellIndex];
var val=view.getRecord(tip.triggerElement.parentNode).get(column.dataIndex);
tip.update(val);
}
}
});
});
Let me know if it helps
{
text: name,
width: 80,
dataIndex: dataIndex,
sortable: true,
listeners: {
afterrender: function ()
{
Ext.create('Ext.ToolTip',
{
target: this.getEl(),
anchor: direction | "top",
trackMouse: true,
html: this.text
});
}
}
}

Resources