How to dynamically change exportable Datatable button names after they have already instantiated? Or how do I get my fnDeleteRow method to "activate" dynamically so that the existing buttons dynamically rename themselves? If they don't refresh themselves, I would like for the Do Stuff button to change the names of the other two (Excel and PDF) button names. (Isn't fnDeleteRow supposed to update ALL parts of the datatable? Are the button names cached?)
Here's part of the datatabe:
,"dom": 'B<"ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix">'
,"columnDefs": [
{
"targets": [ 0, 1, 2, 3],
"visible": false,
"searchable": false
}
]
, buttons: [
{
extend: 'excelHtml5',
name: 'excelBtn',
text: function ( dt, button, config ) {
return 'Export all ' + dt.data().count() + ' entries to Excel'
}
},
{
extend: 'pdfHtml5',
orientation: 'landscape',
name: 'pdfBtn',
action: function(e, dt, button, config) {
config.text = 'Export all ' + dt.data().count() + ' entries to PDF';
$.fn.dataTable.ext.buttons.pdfHtml5.action(e, dt, button, config);
}
,header: true
,title: 'System'
,fontSize: '15'
,exportOptions: {
columns: [ 0, 1, 2, 3]
}
,customize: function ( doc ) {
doc["footer"] = function(currentPage, pageCount) {
return { text: ' Page ' + currentPage.toString() + ' of ' + pageCount + ' \r \n ' + getCurrentDateTime() , alignment: 'center' };
};
doc.content.splice( 1, 0, {
margin: [ 0, 0, 0, 12 ],
alignment: 'center',
bold: true,
style: 'header',
text: 'All Search Results'
}
);
}
},
{
text: 'Do Stuff',
action: function ( e, dt, node, config ) {
alert( 'Button to DO Stuff activated' );
if (confirm('Are you sure you want to "Do Stuff"?') == true) {
$.ajax({
method: "POST",
url: "...",
contentType: 'application/json',
data: {items: stuffToDo, year:$('#year').val()},
success: function( data, textStatus, jqXHR) {
Blockquote
Inside success (here), insert/modify code (or buttons.text above?) to update other button names after (this) button was pressed and all buttons were previously already initialized
??($('#searchDatatableResultsTable').dataTable()).button('pdfBtn:name' )???
Related
I tried several ways to set an icon, in the displayfield, when an item of the combo is selected with not luck, this is the fiddle for anyone to want try to help with this. very much appreciated any light.
fiddle example
The only solution is to transform the input type combo in a div with this:
fieldSubTpl: [
'<div class="{hiddenDataCls}" role="presentation"></div>',
'<div id="{id}" type="{type}" style="background-color:white; font-size:1.1em; line-height: 2.1em;" ',
'<tpl if="size">size="{size}" </tpl>',
'<tpl if="tabIdx">tabIndex="{tabIdx}" </tpl>',
'class="{fieldCls} {typeCls}" autocomplete="off"></div>',
'<div id="{cmpId}-triggerWrap" class="{triggerWrapCls}" role="presentation">',
'{triggerEl}',
'<div class="{clearCls}" role="presentation"></div>',
'</div>', {
compiled: true,
disableFormats: true
}
],
Override the setRawValue method of the combo like this:
setRawValue: function (value) {
var me = this;
me.rawValue = value;
// Some Field subclasses may not render an inputEl
if (me.inputEl) {
// me.inputEl.dom.value = value;
// use innerHTML
me.inputEl.dom.innerHTML = value;
}
return value;
},
and style your fake combo div like you want.
Thats because an input on HTML can't have HTML like value inside it.
Keep attenction, the get Value method will return you the HTML inside the div, and maybe you should also override it, but thats the only one method.
You will be able to get the selected value with this method:
Ext.fly(combo.getId()+'-inputEl').dom.innerHTML.replace(/<(.|\n)*?>/gm, '');
If I were you I would like to do something like this:
combo.getMyValue();
So add this property to your combo:
getMyValue:function(){
var combo=this;
if(Ext.fly(combo.id+'-inputEl'))
return Ext.fly(combo.id+'-inputEl').dom.innerHTML.replace(/<(.|\n)*?>/gm, '');
},
Here is a working fiddle
Perhaps my solution is similar to a hack, but it works in 6.7.0 and is a bit simpler.
Tested in Chrome. Theme - Material. For another theme will require minor improvements.
Sencha Fiddle live example
Ext.application({
name: 'Fiddle',
launch: function () {
var store = new Ext.data.Store({
fields: [{
name: 'class',
convert: function (value, model) {
if (value && model) {
var name = value
.replace(/(-o-)|(-o$)/g, '-outlined-')
.replace(/-/g, ' ')
.slice(3)
.trim();
model.data.name = name.charAt(0).toUpperCase() + name.slice(1);
return value;
}
}
}, {
name: 'name'
}],
data: [{
class: 'fa-address-book'
}, {
class: 'fa-address-book-o'
}, {
class: 'fa-address-card'
}]
});
var form = Ext.create('Ext.form.Panel', {
fullscreen: true,
referenceHolder: true,
items: [{
xtype: 'combobox',
id: 'iconcombo',
queryMode: 'local',
editable: false,
width: 300,
valueField: 'class',
displayField: 'name',
store: store,
itemTpl: '<div><i class="fa {class}"></i> {name}</div>',
afterRender: () => {
var component = Ext.getCmp('iconcombo');
var element = document.createElement('div');
element.className = 'x-input-el';
element.addEventListener('click', () => component.expand());
component.inputElement.parent().dom.prepend(element);
component.inputElement.hide();
component.addListener(
'change', (me, newValue, oldValue) => {
component.updateInputValue.call(me, newValue, oldValue);
},
component
);
var method = component.updateInputValue;
component.updateInputValue = (value, oldValue) => {
method.call(component, value, oldValue);
var selection = component.getSelection();
if (selection) {
element.innerHTML =
'<div><i class="fa ' + selection.get('class') + '"></i> ' + selection.get('name') + '</div>';
}
};
}
}, {
xtype: 'button',
text: 'getValue',
margin: '30 0 0 0',
handler: function (component) {
var combo = Ext.getCmp('iconcombo');
alert(combo.getValue());
}
}]
});
form.show();
}
});
I'm working Extjs 4.2. I have grid with rowediting plugin. Problem is when starting edit row, columns with align:center not showing correctly, but align:right works correct on editor row. I searched problem, but didn't find solve. Please Help with this.
This is my editor:
buildPlugins: function () {
var rowEditing = Ext.create("Ext.grid.plugin.RowEditing",{
autoCancel: false,
pluginId: 'rowedit',
errorSummary: false
});
return [rowEditing];
},
This is last three column code
{
text: Message.cameralGrid.columns.menu5,
menuDisabled: true,
columns: [
{
text: Message.cameralGrid.columns.cameralMustHoldDate,
dataIndex: "cameralMustHoldDate",
width: 120,
sortable: false,
xtype: "datecolumn",
style: "text-align:left;",
align: "center"
},
{
text: Message.cameralGrid.columns.cameralHoldDate,
dataIndex: "cameralHoldDate",
width: 100,
sortable: false,
xtype: "datecolumn",
style: "text-align:left;",
align: "center",
editor: {
xtype: "datefield",
format: "d.m.Y",
allowBlank: false
}
},
{
text: Message.cameralGrid.columns.fineSum,
dataIndex: "fineSum",
width: 120,
sortable: false,
xtype: "numbercolumn",
style: "text-align:left;",
align: "right",
editor: {
xtype: "numberfield",
minValue: 0,
allowBlank: false
}
}
]
}
Thanks for Help!
I needed to override Ext.grid.RowEditor class. After this problem is solved.
Ext.define('helper.RowEditor', {
override: 'Ext.grid.RowEditor',
requires: [
'Ext.grid.RowEditor'
],
addFieldsForColumn: function(column, initial) {
var me = this,
i,
length, field;
if (Ext.isArray(column)) {
for (i = 0, length = column.length; i < length; i++) {
me.addFieldsForColumn(column[i], initial);
}
return;
}
if (column.getEditor) {
// Get a default display field if necessary
field = column.getEditor(null, {
xtype: 'displayfield',
// Override Field's implementation so that the default display fields will not return values. This is done because
// the display field will pick up column renderers from the grid.
getModelData: function() {
return null;
}
});
if (column.align === 'right') {
field.fieldStyle = 'text-align:right';
}
// this block is added -------------------------------->
if (column.align === 'center') {
field.fieldStyle = 'text-align:center';
}
// <-----------------------------------------------------
if (column.xtype === 'actioncolumn') {
field.fieldCls += ' ' + Ext.baseCSSPrefix + 'form-action-col-field'
}
if (me.isVisible() && me.context) {
if (field.is('displayfield')) {
me.renderColumnData(field, me.context.record, column);
} else {
field.suspendEvents();
field.setValue(me.context.record.get(column.dataIndex));
field.resumeEvents();
}
}
if (column.hidden) {
me.onColumnHide(column);
} else if (column.rendered && !initial) {
// Setting after initial render
me.onColumnShow(column);
}
}
}
});
I have this custom field in my form. But when i do the form.getValues() the values for this field is empty. Is this the right way to create custom form fields.
Ext.define("Tasks.view.BarcodeField", {
extend: 'Ext.Container',
alias:'widget.barcodeField',
xtype: 'barcodefield',
config: {
layout: 'hbox',
id: 'barcodeField',
itemId: 'barcodeField',
items: [
{
xtype: 'textfield',
label: 'Barcode',
labelWidth: '37.4%',
flex: 4
},
{
xtype: 'image',
id : 'barcodeScanner',
itemId : 'barcodeScanner',
src: 'resources/images/barcodes.png',
padding: '6 0 0 0',
flex: 1,
listeners: {
tap: function() {
console.log("Starting the barcode Scanner");
function success(result) {
alert("We got a barcode\n" +
"Result: " + result.text + "\n" +
"Format: " + result.format + "\n" +
"Cancelled: " + result.cancelled);
}
function fail(error) {
alert("Scanning failed: " + error);
}
cordova.plugins.barcodeScanner.scan(success, fail);
}
}
}
]
},
getValue : function()
{
console.log(this.getItems().getAt(0).getValue());
return this.getItems().getAt(0).getValue();
},
setValue : function(newvalue) {
this.getItems().getAt(0).setValue(newvalue);
}
});
Instead of extending from the Container i extended the Ext.field.Field and added the items as children to that component.
Ext.define("Tasks.view.BarcodeField", {
extend: 'Ext.field.Field',
alias:'widget.barcodeField',
xtype: 'barcodefield',
config: {
layout: 'hbox',
id: 'barcodeField',
itemId: 'barcodeField',
isField:false,
component : {
xtype:'panel',
layout:'hbox',
items: [
{
xtype: 'input',
label: 'Barcode',
labelWidth: '37.4%',
flex: 4,
id:'barcodeTextField',
itemId:'barcodeTextField'
},
{
xtype: 'image',
id : 'barcodeScanner',
itemId : 'barcodeScanner',
src: 'resources/images/barcodes.png',
padding: '6 0 0 0',
flex: 1,
listeners: {
tap: function() {
console.log("Starting the barcode Scanner");
var text = Ext.ComponentQuery.query("#barcodeTextField")[0];
text.setValue("123456");
}
}
}
]
}
},
getValue : function()
{
console.log(this.getComponent().getItems().getAt(0).getValue());
return this.getComponent().getItems().getAt(0).getValue();
},
setValue : function(newvalue) {
this.getComponent().getItems().getAt(0).setValue(newvalue);
}
});
You can easily add a formpanel as the first child wich will contain a textfield inside in.
And afterward do the formpanel.getValues() to get the values from every field inside that formpanel.
and the other thing is you can do
this.getItems()[0].getValue();
this.getItems()[0].setValue('someDesiredValue');
but that being said I will really prefer doing that on the controller class.
I've been trying to make sure that the load event in the Rally.ui.grid.Grid is firing since I have a problem because my Grid is not filtering. I tried calling the methods myStore.setFilter() and myStore.load(), these two are firing, but I can't be sure the Grid is working properly since the first time, when it all loads, it does the filtering right, but then when I change the dropdown or combobox it doesn't.
This is how I load myStore:
this.myStore=Ext.create("Rally.data.wsapi.Store",{
model:"Task",
autoLoad:true,
filters: myFilters,
listeners:{
load:function(myStore,myData,success){
if(!this.myGrid) //IT CREATES THE GRID FOR THE FIRST TIME
{
this._loadGrid(myStore)
console.log('Grid Created!');
// this.myStore.setFilter();
// this.myStore.load();
}
else
{
this.myStore.setFilter();
//this.myStore.load();
console.log('Grid reloaded!');
console.log(myFilters);
}
},
scope:this
},
fetch:["FormattedID","State","Iteration", "Release"]
}
)
}
And this is how I load myGrid:
_loadGrid:function(myStoryStore){
this.myGrid = Ext.create("Rally.ui.grid.Grid",{
store:myStoryStore,
columnCfgs:["FormattedID","State","Iteration", "Release"],
listeners: {
load: function(myGridy){
console.log('myGrid did load!');
},
scope:this
}
});
this.add(this.myGrid);
}
Here is an example by David Thomas from his videos on building Rally apps that uses reconfigure method to which a store is passed: _myGrid.reconfigure(myStore)
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
var relComboBox = Ext.create('Rally.ui.combobox.ReleaseComboBox',{
listeners:{
ready: function(combobox){
//console.log('loaded release name', combobox.getRecord().get('Name')); //getRecord() returns currently selected item
var releaseRef = combobox.getRecord().get('_ref');
this._loadStories(releaseRef);
//console.log('what is this', this);
},
select: function(combobox){
var releaseRef = combobox.getRecord().get('_ref');
this._loadStories(releaseRef);
},
scope: this
}
});
this.add(relComboBox);
},
_loadStories: function(releaseRef){
console.log('loading stories for ', releaseRef);
var myStore = Ext.create('Rally.data.WsapiDataStore',{
model: 'User Story',
autoLoad:true,
fetch: ['Name','ScheduleState','FormattedID'],
filters:[
{
property : 'Release',
operator : '=',
value : releaseRef
}
],
listeners: {
load: function(store,records,success){
console.log("loaded %i records", records.length);
this._updateGrid(myStore);
},
scope:this
}
});
},
_createGrid: function(myStore){
console.log("load grid", myStore);
this._myGrid = Ext.create('Ext.grid.Panel', {
title: 'Stories by Release',
store: myStore,
columns: [
{text: 'ID', dataIndex: 'FormattedID', flex: 1},
{text: 'Story Name', dataIndex: 'Name', flex: 2},
{text: 'Schedule State', dataIndex: 'ScheduleState', flex: 2}
],
height: 400
});
this.add(this._myGrid);
},
_updateGrid: function(myStore){
if(this._myGrid === undefined){
this._createGrid(myStore);
}
else{
this._myGrid.reconfigure(myStore);
}
}
});
I have a category and a subcategory column in a Jqgrid. I have enabled inline editing, both category and subcategory are dropdownlists columns (edittype:'select'). I need to filter the subcategory list based on the selected category. I wonder how can I acheive this functionlity?
I tried the below event but its not working for me
afterEditCell: function(rowid, celname, value, iRow, iCol) {
//to do here
}
the above event doesn't get fired. my all column are editable
Thanks,
This question will be often asked. So I wrote a small code example which demonstrate how to implement such scenario with local data only (for jqGrid starting with 3.7.x). For data editing (inline editing) I use here the double-click event. The modified data will be saved after pressing of the "enter" key. For the filling of select elements I use ids. If you prefer use texts of the categories and subcategories instead you should remove formatter:'select' and make the corresponding changes in building of <option> elements (see code of dataEvents event handler).
var categories = ["sport", "science"];
var subcategories = ["football", "formel 1", "physics", "mathematics"];
var mydata = [
{Name:"Lukas Podolski", Category:0, Subcategory:0},
{Name:"Michael Schumacher", Category:0, Subcategory:1},
{Name:"Albert Einstein", Category:1, Subcategory:2},
{Name:"Blaise Pascal", Category:1, Subcategory:3}
];
var subcategoriesOfCategory = [
["football", "formel 1"],
["physics", "mathematics"]
];
var grid = jQuery("#list").jqGrid({
data: mydata,
datatype: 'local',
colModel: [
{ name: 'Name', width: 200 },
{ name: 'Category', width: 200, editable:true, formatter:'select',
edittype:'select', editoptions: {
value: categories,
dataInit : function (elem) {
var v = $(elem).val();
grid.setColProp('Subcategory', {
editoptions:{value:subcategoriesOfCategory[v]}});
},
dataEvents: [
{ type: 'change',
data: { id: 7 },
fn: function(e) {
var v=$(e.target).val();
var sel = grid.getGridParam('selrow');
grid.setColProp('Subcategory', { editoptions:
{value:subcategoriesOfCategory[v]}});
var res = '';
var sc = subcategoriesOfCategory[v];
for (var i=0; i<sc.length; i++) {
res += '<option role="option" value="' + i + '">' +
sc[i] + '</option>';
}
$("select#"+sel+"_Subcategory").html(res);
}
}
]
}
},
{ name: 'Subcategory', width: 200, editable:true, formatter:'select',
edittype:'select', editoptions: {value: subcategories} }
],
onSelectRow: function(id) {
if (id && id !== lastSel) {
grid.restoreRow(lastSel);
lastSel = id;
}
},
ondblClickRow: function(id, ri, ci) {
if (id && id !== lastSel) {
grid.restoreRow(lastSel);
lastSel = id;
}
grid.editRow(id, true);
return;
},
editurl: 'clientArray',
sortname: 'Name',
viewrecords: true,
rownumbers: true,
sortorder: "desc",
pager: '#pager',
caption: "Inline Editing example"
}).navGrid('#pager', { edit: false, add: false, del: false,
search: false, view: false });
This example can be of cause modified for the case of building of select option from the server.