dataTables button collection: programmatically enable/disable nested buttons - javascript

I am using a jQuery DataTable. On the top, there are many buttons that will eventually call different actions for the selected rows.
Two of these buttons actually hold a collection of buttons.
The buttons should only be enabled under certain conditions, depending on which rows are selected.
The main buttons are very easy to enable/disable as found in the examples https://datatables.net/extensions/buttons/examples/api/enable.html
$(document).ready(function() {
var table = $('#example').DataTable({
dom: 'Bfrtip',
select: true,
buttons: [{
text: 'Action1',
enabled: false
}, {
text: 'More actions',
enabled: false,
extend: 'collection',
buttons: [{
text: 'Sub-action1',
enable: false
}, {
text: 'Sub-action2',
enable: false
}]
}, {
text: 'Action2'
enable: true
}]
});
});
To enable Action1 or Action2, I simply use their indexed position:
table.button(0).enable(condition); // Changes Action1
table.button(2).enable(condition); // Changes Action2
But I also need to enable/disable buttons within a collection. In this example: Sub-Action1 and Sub-Action2.
How do I access those?

hey refer to this link :- https://datatables.net/reference/type/button-selector
this may help !

Related

jqGrid inline editing not working after adding new row

I'm currently using free-jqGrid version 4.14.1 (using cdn hyperlink). I would like to let the users add a new row with their input values, and edit the row if they want to make any change by clicking the row. For adding new row, I created an adding button (not using jqGrid pager).
I'm now facing two different issues:
1) I refered this demo for inline editting. According to this demo code, I need to use the line
grid.jqGrid('restoreRow', lastSelection);
However, with this line, everytime I am adding new row, the previous row is deleted and only newly added row is displayed. Please check this fiddle.
2) Due to 1), I commented out that line(I don't think I supposed to do that for proper functioning), and tried to run. The previously added rows remain after adding new row, but all rows displayed is showing in textbox like this(fiddle):
What I would like to have is only after user clicks the row to modify, it changes to the textboxes like the guriddo demo.
I have not found any post related to this issues. Is there anyone please help me??
============================================
Add:
I started with some base table value just for verification. The base data rows were functioning as I wanted (click the row for modification), but the new rows were not. It seems like new rows are not selected and not focused when I click, and not exiting the edit mode after hitting enter key..
============================================
============================================
The below is the code of grid just for reference:
$(document).ready(function () {
Load_Bin();
$('#Bin-QtyBin').focus();
$('#btnEnter-Bin').click(function () {
var valNumBin = $('#Bin-numBin').val();
//if bins are dropbox: select enabled one
var valQtyBin = $('#Bin-QtyBin').val();
var paramRow = {
rowId: "new_row",
initdata: {
numBin: valNumBin,
QtyPutAway: valQtyBin
},
position: "first" //"last"
}
$("#tbBin").jqGrid('addRow', paramRow);
$('#Bin-numBin').val('');
$('#Bin-QtyBin').val('');
});
});
var lastSelection;
function Load_Bin() {
var tbBinArea = $('#tbBin');
tbBinArea.jqGrid({
datatype: "local",
colModel: [
{ label: 'Bin', name: 'numBin', sorttype: 'text', searchoptions: { clearSearch: true }, width: 310, editable: true },
{ label: 'Put Away Qty.', name: 'QtyPutAway', sorttype: 'number', searchoptions: { clearSearch: true }, width: 310, editable: true }],
rowNum: 10,
rowList: [10, 15, 30, "10000:All"],
prmNames: {
page: 'defaultPageNumber',
rows: 'rowsPerPage'
},
//forceClientSorting: true,
rownumbers: true,
//autowidth: true,
viewrecords: true,
loadonce: true,
multiselect: false,
multiPageSelection: false,
iconSet: "fontAwesome",
pager: true,
height: 250,
onSelectRow: editRow,
searching: {
searchOperators: true,
defaultSearch: 'cn',
closeOnEscape: true,
searchOnEnter: false,
multipleSearch: true
}
});
}
function editRow(id) {
if (id && id !== lastSelection) {
var grid = $("#tbBin");
grid.jqGrid('restoreRow', lastSelection);
grid.jqGrid('editRow', id, { keys: true });
lastSelection = id;
}
};
(p.s. thanks to the owner of this fiddle since I was struggling to move the code to fiddle, and sorry for not addressing him/her since I lost the original answer link for that fiddle... )
I ended up just reload the whole grid after adding new row. It works fine, except that newly added line does not turn to edit mode since it doesn't detect whether user clicks it or not since it is already highlighted when it was created..
After creating new row, just added this code:
var reloaddata = $('#tbBin').jqGrid("getGridParam", "data");
$('#tbBin')
.jqGrid('setGridParam',
{
datatype: 'local',
data: reloaddata
})
.trigger("reloadGrid");

jqGrid - how to delete row from local data?

I am really new to the jqGrid. I'm loading local file (I'm parsing csv file into json and then transfer the array to jqGrid). Table generated through jqGrid should allow user to modify, add and delete the data in the grid. I tried to resolve my problem using various answers from here like:
Adding new row to jqGrid using modal form on client only
There I have found the example made by Oleg for the 4.7 version of jqGrid and reproduced the same code for my purpose. The result was that I am able to delete row which I added after the grid initialisation but I am unable to delete any other row which was loaded from the array.
Another interesting thing is that I am able to modify the rows loaded from array, the only thing I cannot do with the grid is to delete rows loaded from array. I appreciate any advices.
Here is part of the code with jqGrid:
var delSettings = {
onclickSubmit: function () {
var $this = $(this), p = $this.jqGrid("getGridParam"), newPage = p.page;
if (p.lastpage > 1) {// on the multipage grid reload the grid
if (p.reccount === 1 && newPage === p.lastpage) {
// if after deliting there are no rows on the current page
// which is the last page of the grid
newPage--; // go to the previous page
}
// reload grid to make the row from the next page visable.
setTimeout(function () {
$this.trigger("reloadGrid", [{page: newPage}]);
}, 50);
}
return true;
}
};
$("#jqGrid").jqGrid({
datatype: "local",
data: results.data,
editurl: "clientArray",
colModel: [
{
label: 'Id',
name: 'Id',
width: 60,
editable: true,
key: true,
sorttype: 'number'
},
{
label: 'Company',
name: 'Company',
width: 90,
editoptions: {size: 40},
editable: true,
sorttype: 'string'
},
{
label: 'Address',
name: 'Address',
width: 100,
editoptions: {size: 40},
editable: true
},
{
label: 'City',
name: 'City',
width: 80,
editoptions: {size: 40},
editable: true
}
],
height: '100%',
viewrecords: true,
caption: "Baza klientów Klimatest",
pager: "#jqGridPager",
sortable: true,
ignoreCase: true,
cmTemplate: {editable: true, searchoptions: {clearSearch: true }},
rowNum: 5,
rowList: [5, 10, 20],
});
// toolbar searching
$('#jqGrid').jqGrid('filterToolbar', { defaultSearch: 'cn'});
$('#jqGrid').jqGrid('navGrid',"#jqGridPager",
{ edit: true, add: true, del: true, search: true, refresh: true, view: true},
// options for the Edit Dialog
{
editCaption: "The Edit Dialog",
recreateForm: true,
closeAfterEdit: true,
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
},
// options for the Add Dialog
{
closeAfterAdd: true,
recreateForm: true,
errorTextFormat: function (data) {
return 'Error: ' + data.responseText
}
},
// options for the Delete Dialog
delSettings,
// options for the Search Dialog
{
},
// options for the View Dialog
{
});
// add first custom button
$('#jqGrid').navButtonAdd('#jqGridPager',
{
buttonicon: "ui-icon-calculator",
title: "Column chooser",
caption: "Columns",
position: "last",
onClickButton: function() {
// call the column chooser method
jQuery("#jqGrid").jqGrid('columnChooser');
}
});
EDIT
Data source is the result of parsed CSV file via Papaparse.js plugin (array of objects), which looks like this:
Id: "100,1"
Address: "Strefowa 8"
Company: "DSSE Sp. z o.o."
City: "Warsaw"
I edited the code just like Oleg suggested and I'm still able to delete only records which are added via interface of jqGrid.
I don't know if it may help, but when I click delete icon and confirm that I want to delete selected row, that row is no longer highlighted, but still visible. Thanks for feedback.
You have clear error in your code near // options for the View Dialog block. The View option should be included after delete and search options (see the documentation). So your current code don't use delSettings options.
I recommend you additionally to include test data in your next questions, because some problems exist only with some specific format of input data.
UPDATED: The problem is in the data which you use. The value for Id which you use contains comma ("100,1"). It's not allowed for jqGrid. First of all id in HTML should not use characters which have special meaning in CSS. The second problem: delGridRow method uses commas in separator to delete multiple rows at once. So the usage of id="100,1" will follows to attempt to delete tow rows: one row with id=100 and the second one with the id=1. By the way I'm developing now jqGrid in my fork of GitHub. I fixed many restrictions with the usage of special characters in ids. So you will be do able to use id="100,1" and successfully delete the rows if you would use jqGrid from my fork.
I recommend you to use underscore if you need to construct id which consist from multiple numbers: Id: "100_1" instead of Id: "100,1".

Data-binding only part of a DataSource with Kendo UI

I am using OData and Kendo UI to fetch data, expanding into relations, and presenting them in nested Kendo Grids. Because it seems all of this data is part of one data source, whenever any change happens anywhere in the data, the whole grid is regenerated.
I've reproduced the problem using Northwind data here.
I have a master grid:
$("#grid").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Employees?$expand=Orders"
},
pageSize: 6,
serverPaging: true,
serverSorting: true
},
height: 550,
sortable: true,
pageable: false,
editable: "inline",
detailInit: detailInit});
and a detail grid with an add button.
function detailInit(e) {
$("<div/>").appendTo(e.detailCell).kendoGrid({
dataSource: {
data: e.data.Orders.results,
schema: { ... }
},
editable: true,
columns: [ ... ],
toolbar: [{ name: "create", text: "Add Order" }]
});
}
If you expand one of the rows, then click Add Order, the expanded row is immediately collapsed. I've put this down to the entire grid being regenerated.
In Telerik's example this conveniently doesn't happen, a) because they are not editable grids and b) because they are separate endpoints and therefore separate datasources.
Can I force it to only databind the detail grid and prevent this happening?

EXTJS: How can I add an click event on Icon node in a Tree Panel

I try to get an event click on the node's Icon in a tree panel.
I have a tree with many node and in front of the leaf node, I have an Icon.
For the moment, when I click on a node I display a PDF file.
I want to do a specific action when I click on the Icon of this node.
Someone have an idea for do that?
Thanks a lot for your futur answers!
EDIT:
Thanks for your answer,
#Hown_: Ok, but I must do an specific action which depends to the select node. With a CSS selector, I can't do that. I'm wrong?
#budgw: Yes, it's a good solution, but my icon must be in front of the text node :(
I guess the simplest way would be to add itemclick event to your TreePanel and check in the handler fn if the tree icon was clicked by checking the target of the event. It works as simple as this:
You may have to change the css selector of the getTarget fn for your specific use. ( e.g. only leaf elements or pdf icons or something like that )
Ext.onReady(function() {
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [{
text: "detention",
leaf: true
}, {
text: "homework",
expanded: true,
children: [{
text: "book report",
leaf: true
}, {
text: "alegrbra",
leaf: true
}]
}, {
text: "buy lottery tickets",
leaf: true
}]
}
});
Ext.create('Ext.tree.Panel', {
title: 'Simple Tree',
width: 200,
store: store,
rootVisible: false,
renderTo: Ext.getBody(),
listeners: {
itemclick: function(treeModel, record, item, index, e, eOpts){
var iconElClicked = e.getTarget('.x-tree-icon');
if(iconElClicked){
//tree icon clicked
//do something in here
console.log('tree icon clicked');
}
}
}
});
});
I don't think you can do that with the icon in front of the node (maybe I'm wrong).
But I usually solve this kind of use case by using a treepanel with 2 columns :
a treecolumn
an action column like in this example here.
The trick is to use the config property 'hideHeaders:true' on the tree panel to make it looks like a classic tree.
You can select the dom elements of the icons via css selector and add a click event after the render method.
here is an example:
https://fiddle.sencha.com/#fiddle/8kd
UPDATE:
exmaple:
Ext.onReady(function() {
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [{
text: "detention",
leaf: true
}, {
text: "homework",
expanded: true,
children: [{
text: "book report",
leaf: true
}, {
text: "alegrbra",
leaf: true
}]
}, {
text: "buy lottery tickets",
leaf: true
}]
}
});
Ext.define('MyPanel', {
extend: 'Ext.tree.Panel',
title: 'Simple Tree',
width: 200,
onTreeIconClick: function(treeModel, record, item, index, e, eOpts){
// DO SOMETHING IN HERE
console.log('onTreeIconClicked');
},
render: function(){
this.callParent(arguments);
var domEls = this.el.dom.querySelectorAll('#' + this.getId() + ' .x-tree-icon', this.el.dom);
for(var i = 0; i<domEls.length; i++){
Ext.get(domEls[i]).on('click', function(){
//click on tree icon
this.on('itemclick', this.onTreeIconClick, this, { single: true });
}, this);
}
}
});
Ext.create('MyPanel', {
store: store,
rootVisible: false,
renderTo: Ext.getBody()
});
});

ExtJS: HTMLEditor loses content on Accordion re-expand

I have an accordion panel with typical settings. In each of the panels there used to be a textarea and everything worked fine.
Now I replaced each textarea with an htmleditor. When I collapse a panel and re-expand it, the content of the htmleditor is lost. This didn't happen when I used textarea. How to solve this problem?
Edited: also, when re-expanded, the htmleditor freezes, and I can't input anything. But the buttons work (bold, insert link, switch to source editing, etc). What's more strange, when I toggle 'switch to source' button twice, the content reappears, in a different font!
Using the Accordion:
myDataStore.load({params: ...}, callback: onLoadSuccess);
......
onLoadSuccess: function() {
// for each data item, create a new panel and add it to myListPanel
for (var i = 0; i < myDataStore.getTotalCount(); i++) {
var dataItem = myDataStore.getAt(i);
var newFormPanel = new Ext.FormPanel({
labelAlign: 'top',
items : [{
xtype: 'htmleditor',
fieldLabel: 'Content',
autoScroll: true,
enableFont: false,
enableLists: false,
value: dataItem.get('content');
}],
buttons: [{...}]
});
// add this panel to the accordion
myListPanel.add({
title: 'Another panel',
items: [newFormPanel]
});
}
myListPanel.doLayout();
}
Current Accordion config:
var myListPanel = new Ext.Panel({
autoHeight : true,
autoWidth: true,
autoScroll : true,
layout : 'accordion',
layoutConfig : {
titleCollapse: true,
animate: true,
fill : false,
autoWidth: true,
hideCollapseTool: true,
},
});
For me a htmleditor does not lose the content when collapsing and expanding it.
However, one solution would be to listen for the collapse event and store the current editor content to a property.
On the expand event, you place it again in the editor.

Categories