I have three seperate tab panels with each being a table in my database. What i'm trying to do is that on a click of a button is save the content of all the three tabs in the database at the same time. I managed to get the PK "Aid" of the current active tab, however when i try to access the second inactive tab B with window.frames["frm_B"] and alerting the result, i'm getting undefined. Any help would be much appreciated.
tabPanel = Ext.create('Ext.tab.Panel', {
region: 'center',
activeTab: 0,
autoScroll: true,
tbar: [{
xtype: 'button',
text: 'Save',
handler:function(){saveForm("frm_A", save);}
}],
items: [
{
id:"panel_A",
html: "<iframe src= '"+A_url +"' width='100%' height='100%' id='frm_A' name='frm_A' frameborder=0 />",
},{
id:"panel_B",
html: "<iframe src='"+B_url+"' width='100%' height='100%' id='frm_B' name='frm_B' frameborder=0 />",
},{
id:"panel_C",
html: "<iframe src= '"+C_url+"' width='100%' height='100%' id='frm_C' name='frm_C' frameborder=0 />",
}]
});
viewport = new Ext.Viewport({
layout:'border',
items:[tabPanel]
});
function save(record){
var Aid = record.getKey();
var doc = window.frames["frm_B"];
alert(doc);
try {
doc.RECORD.getField("A_ID").setRealValue(Aid);
doc.RECORD.update(closeAndRefresh, viewExtError);
}
catch(e){
showError(e);
}
}
I guess your problem is that your <iframe name='frm_B'> is not rendered (added to DOM) when you try to get it with window.frames["frm_B"].
When you create tab panel with Ext.create('Ext.tab.Panel', {}); you just create JS object, not all of its items: [] added to DOM immediatelly.
A Container's child Components are rendered by that Container's layout
manager when the Container is first rendered.
For example tabpanel tabs added to DOM when you first time open that tab.
Fiddle to illustrate it
Solution for your question depends on your code actually, but as workaround you can use .render() method of tab panel child panels...
Related
I apologize, but I'm not able to provide a working jsFiddle snippet. I will update the question if I understand how to put the code below in it.
Using dojox/mobile I populate an EdgeToEdgeStoreList with custom ListItems. Some code:
html (jade)
div(data-dojo-type="dojox/mobile/View")
h1(data-dojo-type="dojox/mobile/Heading") Device List
div(data-dojo-type="dojox/mobile/ScrollablePane")
ul#list(data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" data-dojo-props="itemRenderer: DeviceListItem, select: 'single'")
js
var store;
var list = registry.byId("listDevices");
var devices = JSON.parse("a string received from server");
store = new Memory({data: devices, idProperty: "label"});
list.setStore(store);
DeviceListItem
define([
"dojox/mobile/ListItem",
"dijit/_TemplatedMixin",
"dojo/_base/declare"
], function (ListItem, TemplatedMixin, declare) {
var template =
"<div class='deviceDone${done}'>" +
" ${id} - <div style='display: inline-block;' data-dojo-attach-point='labelNode'></div>" +
" <div class='deviceCategory'>${category}</div>" +
"</div>";
TemplatedListItem = declare("DeviceListItem",
[ListItem, TemplatedMixin], {
id: "",
label: "",
category: "",
done: "false",
templateString: template
}
);
});
It works fine, that is I will see my custom ListItems.
But if I resize the window (on desktop browsers) or change orientation (on mobile ones) only the ${id} field remains visible. The others (label and category) disappear. The behavior is the same in all browsers (that I tried).
After debugging I discovered the following. Before any resize the actual html of a ListItem looks like this:
<div id="item1728" class="deviceDoneFalse mblListItem mblListItemUnchecked" tabindex="0" widgetid="item1728" aria-selected="false" role="option">
item1728 -
<div style="display: inline-block;" data-dojo-attach-point="labelNode">n.a.</div>
<div class="deviceCategory">General purpose</div>
</div>
and it's like the template string. After a resize the inner div becomes:
<div style="display: block;" data-dojo-attach-point="labelNode">n.a.</div>
without "inline" all the layout will mess-up and thus the fields "disappear" (actually go below, behind the next row).
I wonder why this happens - the display style is hardcoded into the template strings!
Furthermore, I inspected the CSS rules at runtime, and it's not due to them, it's the html that has changed - indeed.
ListItem (source in dojox/Mobile/ListItem.js) has the following function:
resize: function(){
if(this.variableHeight){
this.layoutVariableHeight();
}
// labelNode may not exist only when using a template (if not created by an attach point)
if(!this._templated || this.labelNode){
// If labelNode is empty, shrink it so as not to prevent user clicks.
this.labelNode.style.display = this.labelNode.firstChild ? "block" : "inline";
}
},
This function is called after a resize and as you can see sets the labelNode display style to "block".
You can replace this function when you define your DeviceListItem, keeping the original source as is but changing the display style.
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 would like to add a toolbar to a tab, but I cannot find anything regarding that in the documentation. I understand a tab is basically a panel. Is it possible to access that and add the toolbar?
My goal is to have a toolbar in each tab with for example a submit button that submits a form in the tab.
I am using the following code to add the tabs:
function addTab(title, url){
if ($('#main-tabs').tabs('exists', title)){
$('#main-tabs').tabs('select', title);
} else {
var content = '<iframe scrolling="auto" frameborder="0" src="'+url+'" style="width:100%;height:100%;"></iframe>';
$('#main-tabs').tabs('add',{
title:title,
content:content,
closable:true
});
}
}
Thanks in advance!
Michael
jeasyui has a toolbar function within the tabs. It's good enough for my purpose so I'll go with that for now.
$('#tt').tabs({
tools:[{
iconCls:'icon-add',
handler:function(){
alert('add')
}
},{
iconCls:'icon-save',
handler:function(){
alert('save')
}
}]
});
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';
I managed to add a images in the extjs combo selection list however after selecting an item did not manage to have the same images displayed int he collapsed combo. I tried changing the template (displayTpl) by adding some custom HTML however it will get escaped. any help would be appreciated.
Thanks
this.chartCombo = Ext.create('Ext.form.field.ComboBox', {
height: '20',
fieldLabel: 'Chart Type',
displayField: 'chartLabel',
valueField: 'chartValue',
store: chartComboDataSource,
queryMode: 'local',
listConfig: {
getInnerTpl: function() {
this.cls = 'option-list-chart-img';
return "<img class='{cssClassName}'/> {chartLabel}";
}
}
});
It doesn't work because the collapsed combo is just a simple <input> element that can't contain HTML. I suggest you set the image as a background image to the <input>, switching it programmatically when selection changes.