In short, how can I show a drop down menu floating over a table and not rendered inside the table cell?
I am using this example code to show a drop down menu inside a table cell:
window.someObj.showSocs = function(index){
var pSubMenu = new DropDownMenu({});
pSubMenu.addChild(new MenuItem({
label: "Cut",
iconClass: "dijitEditorIcon dijitEditorIconCut"
}));
pSubMenu.addChild(new MenuItem({
label: "Copy",
iconClass: "dijitEditorIcon dijitEditorIconCopy"
}));
pSubMenu.addChild(new MenuItem({
label: "Paste",
iconClass: "dijitEditorIcon dijitEditorIconPaste"
}));
pSubMenu.placeAt("socs-" + index.toString());
pSubMenu.startup();
}
where DropDownMenu is "dijit/DropDownMenu" and MenuItem is "dijit/MenuItem".
Then I am using this code to add a link to a table cell (it's executed inside a dgrid renderCell function but I believe it is not relevant for this problem):
var link = document.createElement("a");
var linkText = "javascript:someObj.showSocs(" + index + ")";
link.setAttribute("href", linkText);
link.innerHTML = "DropNew";
td.appendChild(link);
td.setAttribute("id", "socs-" + index.toString());
Now when I click the link the dropdown is being rendered but inside the table cell, not over it. This causes the current table row to expand. I guess it's down to some CSS properties that I can't figure out. I am not overriding any CSS properties so I would expect the dropdown to be placed over the table instead of inside a cell automatically?
You place menu's DOM node into the cell, so it stretches the cell. You can place the menu into <body> and position it absolutely with the help of dijit/place around the required node.
I would use built-in functionality for context menus, e.g.:
// var Menu = require("dijit/Menu");
var menu = new Menu({
leftClickToOpen: true,
targetNodeIds: ["table1"],
selector: "a.dropNew"
});
See it in action: http://jsfiddle.net/phusick/TBWXL/
Related
I have setup my table in Tabulator with responsiveLayout:"collapse" and responsiveLayoutCollapseStartOpen:false.
My table display properly with collapsed columns.
I added formatter:"responsiveCollapse" as column and I properly get the column with + and - icons and can manually expand/collapse the columns.
But for usability on a smartphone, the icon renders really a bit small.
I want to add to expand/collapse based on callback rowClick.
I found responsiveCollapse and toggleList in tabulator.js, so I think I know what needs to happen. However I am totally struggling how to return it out of rowClick.
Thank you very much for a hint in advance.
In the tabulator constructor I have:
columns:[
{ formatter:"responsiveCollapse", width:30, minWidth:30,
hozAlign:"center", resizable:false, headerSort:false, responsive:0 },
{ title:"Ren.", field:"Race_Number", sorter:"number",
hozAlign:"center", minWidth:60, widthGrow:1, responsive:0 },
]
And basically I want to achieve the some functionality as formatter:"responsiveCollapse" in rowClick:
rowClick:function(e, id, data, row){
//trigger an alert message when the row is clicked
//what to do here to achieve same as formatter:"responsiveCollapse"
},
You could copy some of the code from the built-in responsiveCollapse formatter to achieve this. It will involve accessing some private variables, which is a bit naughty, but it will do the job:
rowClick:function(e, id, data, row){
var config = cell.getRow()._row.modules.responsiveLayout; //get the responsive config object for the row
var collapseEl = config.element; //get the collapsible element for the row
if(collapseEl){ //check if the row has any collapsed data
config.open = !config.open; toggle the open state
//toggle the collapse element
if(config.open){
el.classList.add("open");
collapseEl.style.display = '';
}else{
el.classList.remove("open");
collapseEl.style.display = 'none';
}
}
}
this was very helpful, remember to comment out "toggle the open state" and also update
el.classList.remove("open");
to
collapseEl.classList.remove("open");
I've got a sap.ui.table.Table with Input fields and the table gets the data via JSON which works well. However, if I edit the value in the first row for example, and try to scroll down, the value "stays" in the first row until a different value hits this field. So it basically updates every cell except the edited one while scrolling. After that, I scroll up again to see the value I changed, but this value now has the old value from the load at the beginning again.
I think something with my binding isn't correct at all, because I haven't seen anything like this yet. I know that tables only update the row contexts but I can't figure out how to do this.
Here is a example: https://jsbin.com/yuvujozide/6/edit?html,console,output
Edit the right "Gates" and scroll, to see how it disappears and edit the left value and scroll to see how the value scrolls with the table.
I tried to remove/set the VisibleRowCount and logged to see if the data gets loaded multiple times but that's not the case.
var oModel = new sap.ui.model.json.JSONModel();
var oTable = new sap.ui.table.Table({
visibleRowCount: 12,
selectionMode: sap.ui.table.SelectionMode.Single,
visibleRowCountMode: sap.ui.table.VisibleRowCountMode.Fixed,
editable: true
});
oModel.setData({ rows: tableRows.value, columns: columnArray });
oTable.setModel(oModel);
var counter = 0;
oTable.bindColumns("/columns", function (sId, oContext) {
var columnName = columnArray[counter];
var defaultTemplate = new sap.m.Input({
value: "{" + columnName + "}"
}).bindProperty("value", columnName, function (cellValue) {
return returnRange(this, oTable, cellValue, columnName, counter, dic);
});
counter++;
return new sap.ui.table.Column({
label: columnName,
template: defaultTemplate,
flexible: true,
autoResizable: true,
width: 'auto',
multiLabels: [
new sap.ui.commons.Label({ text: columnName }),
new sap.ui.commons.Label({ text: dic[Number(counter - 1)].value[0] + " - " + dic[Number(counter - 1)].value[1] })
]
});
});
oTable.bindRows("/rows");
As you can see I separated the rowData and columnNames in two arrays:
tableRows and columnArray
The returnRange function checks some values and just returns the cellValue
I would expect that the Input fields keeps the changed values (which is probably normal), so I can change several Input fields and then I can Update the table via Ajax-Call.
The problem is that sap.ui.table.Table has a custom scrolling behaviour that is different from the default browser scrolling. Instead of creating a row for each record, it will create a fixed number of rows and re-bind these rows after each scroll.
If the table is editable and bound to a JSONModel, it will usually create a two-way-binding and update the model values upon user input, hence scrolling works fine. But since you have provided a custom formatter function for the binding (returnRange), a two-way-binding is not possible anymore. This means that any user input is lost after scrolling.
If you remove the formatter function like this
var defaultTemplate = new sap.m.Input({
value: "{" + columnName + "}"
});
it will work fine.
In case you want to validate the user input, you should listen to the input's change event and use InputBase#setValue to set it to a different value. This will also reflect your changes in the JSONModel.
It looks like a simple task, but I already spent 4 hours to find a solution. How can I highlight the entire row by cell click?
On register api I have next
$scope.gridOptions.onRegisterApi = function(gridApi){
$scope.gridApi = gridApi;
gridApi.cellNav.on.navigate($scope,function(selected){
if('.ui-grid-cell-focus '){
console.log("fired class")
$(selected.row.entity).addClass('ui-grid-cell-focus')
}
console.log("fired cell")
$(selected.row.entity).addClass('ui-grid-cell-focus')
});
};
I see how click on cell is fired, but I cannot force to color the row and I don't want to select the row, because I use check box selection for this purpose, I just want to highlight the row by click on any cell in this row. Could somebody tell me where my mistake is?
Attached plunker
One way to accomplish what you want is to add a cellClass definition to your columnDefs. That function takes two params: grid and row.
$scope.gridOptions.columnDefs = [{
name: 'id',
width: '150',
cellTemplate: "",
cellClass: getCellClass
}, {
name: 'name',
width: '200',
cellClass: getCellClass
} ...
];
function getCellClass(grid, row) {
return row.uid === selectedRow ? 'highlight' : '';
}
On click you could set a variable to the uid of the row, and inside the cellClass function you can check if the uid of the current row matches the uid of the selected, if so, you can set the class to a class that properly reflects the background color of the selected row.
var selectedRow = null;
gridApi.cellNav.on.navigate($scope, function(selected) {
if ('.ui-grid-cell-focus ') {
selectedRow = selected.row.uid;
gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN);
}
});
Here's a link to your updated plunker: http://plnkr.co/edit/AgpAI2cmdqgNsSLVNjYA?p=preview
If you don't like the cellClass approach you could define custom cellTemplates and similarly react to a property you set on the row entity.
I have created a tab panel in extjs4.2 , and what i'm trying to do is access the values in the form of a tab while being in the other tab. For example the user is on tab A and have access to the values in tab B. How can access the other tab?
tabPanel = Ext.create('Ext.tab.Panel', {
region: 'center',
activeTab: 0,
autoScroll: true,
items: [
{
id:"panel_A",
title: "${tr.A}",
html: "<iframe src= '"+A_url +"' width='100%' height='100%' id='frm_A' name='frm_A' frameborder=0 />",
},{
id:"panel_B",
title: "${tr.B}",
//disabled:tabs_status,
//hidden:hidden,
html: "<iframe src='"+B_url +"' width='100%' height='100%' id='frm_B' name='frm_B' frameborder=0 />",
}]
});
viewport = new Ext.Viewport({
layout:'border',
items:[tabPanel]
});
In this part on a click of a button i'm able to access the current frame.
new Ext.Toolbar.Button({
id:"btn_show",
text: "${tr.Show}",
tooltip: "${tr.Show}",
handler: function(){view(frmid);}
}),
function view(frmid) {
var A_key = window.frames[frmid].RECORD.getKey();
/* var B_key = window.frames[...].RECORD.getField("HISTORY").getRealValue();*/
}
To select Ext.ComponentView you can use Ext.ComponentQuery.
Provides searching of Components within Ext.ComponentManager (globally) or a specific Ext.container.Container on the document with a similar syntax to a CSS selector. Returns Array of matching Components, or empty Array.
More about selectors for DOM Elements and ExtJS Components in this answer.
Basic example of how you can access another tab of a tabpanel:
Working fiddle
// If you button is child / parent button of a tabpanel its efficient to use down() / up() methods
// Since we get button component reference as listener function arguments we can select parent tabpanel component,
// and after it select child component panel (because panel is default xtype for tabpanel items and textfield after it
panelBTextFieldValue = button.up('tabpanel').down('panel[id=panel_B] textfield[name=panel_B_text_field]').getValue();
// If your button is somewhere else you can use Ext.ComponentQuery.query()
panelBTextFieldValue = Ext.ComponentQuery.query('tabpanel[id=myPanel] panel[id=panel_B] textfield[name=panel_B_text_field]').getValue();
// or just if selector textfield[name=panel_B_text_field] specific enought for whole your application
panelBTextFieldValue = Ext.ComponentQuery.query('textfield[name=panel_B_text_field]').getValue();
I have a template column in my gridpanel containing a URL:
{
xtype: 'templatecolumn',
tpl: Ext.create('Ext.XTemplate',
'Edit'
)
}
When a user mouses over a particular row in the gridpanel, I want the link to be visible:
listeners: {
'itemmouseenter': function(gridpanel, record, item) {
var editLink = Ext.select(Ext.query('a.x-leave-request-edit', item, 'select', true));
editLink.setVisible(true);
},
'itemmouseleave': function(gridpanel, record, item) {
var editLink = Ext.select(Ext.query('a.x-leave-request-edit', item, 'select', true));
editLink.setVisible(false);
}
}
This works fine. The problem though is that by default, I want the links in the tpl to be invisible.
How can I achieve this?
I tried using similar code as above in onRender(), afterRender() and finishRender() but the Ext.query() always returns an empty array.
Instead of all that query ugliness, you can just use:
item.down('.x-leave-request-edit').
To make it not visible the initially, just add display: none; in the inline style.
return 'Edit';