I need to dynamically add a column to a page that has already been loaded. The column is represented by an object that is created AFTER the .ascx page is loaded (via user interaction). On the JavaScript side of things, I have a Panel with a TabPanel:
var reportPanel = new Ext.Panel({
layout: 'fit',
items: [
new Ext.TabPanel({
id: 'reportTabs',
renderTo: 'reportTabContainer',
activeTab: 0,
autoHeight: true,
minHeight: 600,
plain: true,
stateful: true,
deferredRender: false,//allows both reports to run at once
defaults:
{
autoHeight: true
},
items: tabsConfig
})
]
});
};
an item in tabsConfig looks like this:
{{ id: 'totalOperation', title: 'Total Operation', autoLoad: {{url: '" +Url.Action("Detail","OverallReport") +"', params: 'null', scripts: true, timeout: '9000000', method: 'POST'}}
My problem is that once the column object has been created, I need to re-render the ascx page (aka the extJSpanel) after a specific AJAX call. I have tried panel.removeAll(true) as well as panel.doLayout(false,true), and that does not remove any of the elements in the panel, or refresh the page.
In short--I need to destroy an .ascx page before an AJAX call to the controller, and let the return of the AJAX call re-populate the ascx control (using return PartialView(...) ).
Any suggestions would be greatly appreciated.
Answered my question-this little snippet of code solved it:
var contentPanel = Ext.getCmp('totalOperation');
contentPanel.autoLoad = {
url: 'URL path of controller method'
};
contentPanel.doAutoLoad();
Related
I have a simple Sencha App that has a main view. The view extends the Ext.navigation.View so that I can "push" to a new view when the user selects an item in the list. This happens by setting up a listener and then calling the push function on the MainView object.
However, I'm having problems getting the data across to that view. I tried using the answer from this StackOverflow question, but it didn't work.
In that answer it suggests that you use the record parameter of the itemTap() function, but this returns as an empty object.
Why does record return as an empty object?
Perhaps I'm going about this the wrong way?
In my case, I have a list of "brands", each with a title, image and description. I'd like to use that in the panel that slides in.
The launch function of my app which creates the view and ads to the viewport
launch: function() {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
// Create instance of the main view so we can use it's functions
SenchaTest.MainView = Ext.create('SenchaTest.view.Main');
// Initialize the main view
Ext.Viewport.add(SenchaTest.MainView);
},
Here is my view
Ext.define('SenchaTest.view.Main', {
extend: 'Ext.navigation.View',
xtype: 'main',
requires: [
'Ext.TitleBar',
'Ext.Video',
'Ext.carousel.Carousel',
'Ext.Img'
],
config: {
fullscreen: true,
items: [
{
title: 'Test',
layout: {
type: 'vbox',
align: 'stretch'
},
items: [{
xtype: 'highlightscarousel',
flex: 0.35
}, {
xtype: 'list',
displayField: 'title',
flex: 0.65,
store: Ext.create('SenchaTest.store.Brands'),
itemTpl: '<img src="{image}" class="listThumb"><h1 class="listTitle">{name}</h1><span class="clearFloat"></span>',
listeners: {
itemtap: function(nestedList, list, index, element, post, record) {
}
}
}]
}
]
}
});
Based on the Sencha Touch docs, the signature of the itemtap listener is:
(this, index, target, record, e, eOpts)
you're using:
(nestedList, list, index, element, post, record)
so that might be why the record is an empty object. If that's not the case, could you post a JSFiddle or some kind of working example of the problem?
I have been working on developing a custom extjs console to enable author drop an asset using html5smartfile component. But somehow, the html5smartfile component is not working the way it should. The Area where an author can drop an asset is not displaying. The same is working fine if I am creating a CQ5 dialog. But in my case where i have created a window it's not working.
I have declared my smartfile component like this:
var assetLinkDropField = {
xtype: 'html5smartfile',
fieldLabel: 'Asset Link',
ddAccept: 'video/.*',
ddGroups: 'media',
fileReferenceParameter: './linkUrl',
name: './linkUrl',
allowUpload: false,
allowFileNameEditing: false,
allowFileReference: true,
transferFileName: false
};
But this is rendering like this:
After a lot of work, I found out that the CQ5 dialog updates the view for the component but in case of my window, I have to update it myself. Thus, with a slight manipulation, i just succeeded in displaying the drag area by tweaking the declaration like this:
var assetLinkDropField = {
xtype: 'html5smartfile',
fieldLabel: 'Asset Link',
ddAccept: 'video/.*',
ddGroups: 'media',
fileReferenceParameter: './linkUrl',
name: './linkUrl',
allowUpload: false,
allowFileNameEditing: false,
allowFileReference: true,
transferFileName: false,
listeners: {
afterlayout: function () {
this.updateView();
}
}
}
So now the panel looks like:
But still the Drag and Drop is not working. My Window declaration is like this:
win = new CQ.Ext.Window({
height : 750,
width : 700,
layout : 'anchor',
// animateTarget : btn.el,
closeAction : 'close', // Prevent destruction on Close
id : 'manageLinkWindow',
title : '<b>Multi Link Widget Dialog</b>',
frame : true,
draggable : false,
modal : false, //Mask entire page
constrain : true,
buttonAlign : 'center',
items : [assetLinkDropField]
});
}
I think you should not use
ddAccept: 'video/.*',
This allows only videos from the content finder to be dragged and dropped. It should be "image/".
Verify your other extjs properties / configs for html5smartfile if the above doesn't resolves your problem.
I'd like to use the Fuel UX datagrid to display some data I am retrieving from my database. The page is served from a ruby on rails server.
The javascript example code for building the data object:
var dataSource = new StaticDataSource({
columns: [{
property: 'toponymName',
label: 'Name',
sortable: true
}, {
property: 'countrycode',
label: 'Country',
sortable: true
}, {
property: 'population',
label: 'Population',
sortable: true
}, {
property: 'fcodeName',
label: 'Type',
sortable: true
}],
data: sampleData.geonames,
delay: 250
});
$('#MyGrid').datagrid({
dataSource: dataSource,
stretchHeight: true
});
$('#datagrid-reload').on('click', function () {
$('#MyGrid').datagrid('reload');
});
If I am understanding the code, I am going to be defining my columns and some attributes in the columns object inside of the dataSource variable, and the data object is being loaded by sampleData.geonames.
The sampleData is here
What can I do using the rails conventions to replace the sampleData.geonames? I tried tweaking this a few ways to load rails objects in to here.
For example, I modified my columns' property fields to correspond to some properties of my User model. I tried replacing the
data: sampleData.geonames,
to
data: <%= #users.to_json %>,
I'm a little restricted on gems and versions, currently using Rails 2.3.
Thanks for any help.
If you want the datagrid to make a background AJAX request to load the data from your app, please see this tutorial which will be closer to what you need:
http://dailyjs.com/2012/10/29/fuel-ux
This would have the benefit of an immediate page load followed by asynchronous loading of data.
If you would rather stick with the StaticDataSource approach just embed a small script on your page similar to this:
<script>
var myData = { ... };
</script>
Then, load that with:
var dataSource = new StaticDataSource({
columns: [ ... ],
data: myData,
delay: 250
});
I posted this at the Ext forums a couple of days ago, but no response, so maybe better luck here.
I currently have a combo box loading data from php through ajax. Everything works fine except that when my results are returned, the DataView covers the ComboBox (fig 2.) I have included the relevant code below, so any help would be greatly appreciated.
I may be wrong, but I think I've eliminated CSS problems, as the DataView element is rendered with an absolute position.
alt text http://img.skitch.com/20100216-8t4pmbc3e6mydqqrac9qm9ucj.jpg
fig 1.
alt text http://img.skitch.com/20100216-n5t44g8rua7fawkwjrj49fk7t4.jpg
fig 2.
var dataStore = new Ext.data.JsonStore({
url: '/ajaxGateway.php',
root: 'data',
baseParams: {
useClass: 'App_GeoIP_GeoIP',
useMethod: 'getLocationsStartingWith'
},
fields: [
{name:'text', mapping:'TITLE'},
{name:'stateName', mapping:'STATE_NAME'},
{name:'regionHierarchy', mapping:'REGION_HIERARCHY'},
{name:'id', mapping:'ID', type:'int'},
{name:'lat', mapping:'LATITUDE', type:'float'},
{name:'lng', mapping:'LONGITUDE', type:'float'}
]
});
_
var resultTpl = new Ext.XTemplate(
'<tpl for="."><div class="search-item" style="text-align:left">',
'<span>{text}, <small>{stateName}</small></span>',
'</div></tpl>'
);
_
var locationBasedRulesTree = new Ext.tree.TreePanel({
title: 'Location Based Regions',
height: 329,
width: 480,
autoScroll: true,
useArrows: true,
animate: false,
rootVisible: false,
frame: true,
enableDrag: true,
root: new Ext.tree.AsyncTreeNode({
id:'custom_root'
}),
tbar: new Ext.Toolbar(),
listeners:
{
listenersHandlers...: function(){}
}
});
_
locationBasedRulesTree.getTopToolbar().addField(
new Ext.form.ComboBox({
store: dataStore,
displayField: 'text',
typeAhead: false,
loadingText: 'Finding...',
blankText: "Search for a Place...",
width: (Ext.isIE6) ? 155:200,
hideTrigger: true,
forceSelection: true,
selectOnFocus:true,
tpl: resultTpl,
itemSelector: 'div.search-item',
enableKeyEvents: true,
onSelect: function(record)
{
selectHandler...();
},
listeners:
{
keypress : function(comboBox, event) {
keypressHandler...();
}
}
})
);
Hard to say. The first thing I would do is rip the combo box out of your layout and try rendering it to a plain page and see if you still have this issue (should be simple to do). That will immediately confirm or rule out that it's related to your particular layout. You also did not mention whether or not this happens only in particular browser/OS combinations -- if so, it could be an Ext bug. If it happens in any browser, then it's probably an issue with your layout. Try narrowing it down first then maybe it will be more obvious where to go next.
It looks almost like the listAlign or hideParent are set wrong.. I'm not seeing that in your definition, but would double-check... try setting those to configuration options manually. I've also had issues with IE when not setting the listWidth config property.
I am working on my first project using ExtJS.
I have a Data Grid sitting inside a Tab that is inside a Window.
I want to add a link or button to the each element of the grid (I am using extended elements at the moment with HTML content through the RowExpander) that will make an AJAX call and open another tab.
I actually worked this out in the end. Pretty convoluted, and let's just say I will not be involving myself with ExtJS again if I can help it.
I am using the Grid.RowExpander to place HTML inside the Grid using XTemplate.
My links are therefore fairly straight forward:
Add to Cart
Where {product_id} is from JSON data loaded from an Ajax query. This is important, as you will see below.
Finding these events is much more difficult ... the Grid can tell you the row, but I actually needed to grab elements from a table inside the grid row. Long story, but I inherited some of this code.
Then in my parent component I have attached an event to the Grid itself.
this.on({
click :{scope: this, fn:this.actionGridClick}
});
To find the actual link, I search for the link in the target that has the correct class. In this case "add_cart_btn"
actionGridClick:function(e) {
// Looking for a click on a cart button
var addCartEl = Ext.get(e.getTarget('.add_cart_btn'));
if(addCartEl) {
productID = addCartEl.id;
// Once we have the ID, we can grab data from the data store
// We then call to the server to complete the "add to cart" functionality
}
}
Mpst of this is not very helpful except in my case, but it's here for posterity if anyone needs something similar in the future.
Try this :
// create grid
var grid = new Ext.grid.GridPanel({
store: store,
columns: [
{header: 'NAME', width: 170, sortable: true, dataIndex: 'name'},
{header: 'PHONE #', width: 150, sortable: true, dataIndex: 'phone'},
{header: 'BIRTHDAY', width: 100, sortable: true, dataIndex: 'birthday',
renderer: Ext.util.Format.dateRenderer('d/m/Y')},
{header: 'EMAIL', width: 160, sortable: true, dataIndex: 'email',
renderer: renderIcon }
],
title: 'My Contacts',
autoHeight:true,
width:600,
renderTo: document.body,
frame:true
});
See this :
{header: 'EMAIL', width: 160, sortable: true, dataIndex: 'email', renderer: renderIcon }
the renderer will be defined as this :
//image path
var IMG_EMAIL = '/gridcell-with-image/img/email_link.png';
//renderer function
function renderIcon(val) {
return ''+ '<img src="' + IMG_EMAIL + '"> ' + val +'';
}
And here you are :)
If you are looking to add the link to the grid itself, you can specify another column in your ColumnModel and apply a renderer to the column. The function of the renderer is to return formatted content to be applied to that cell, which can be tailored according to the value of the dataIndex of the column (you should have a dataIndex, even if it is a duplicate of another column), and the record of that row.
function myRenderer(value,meta,record,rowIndex,colIndex,store){
// Do something here
}
Your link might have a click event to call a method, opening another tab
function myClickEvent(value1, value2){
var myTabs = Ext.getCmp('myTabPanel');
myTabs.add(// code for new tab);
}
If you're adding the links to your expanded area, within the RowExpander, then you'll have to write the rendering into the Template you're using for your expanded content area.