I am using ExtJs 4.1.0 and I am new to extjs. I have used fleXcroll for applying custom scrollbars to windows and panels. They are working fine so far, but when I am trying to resize the window, the scrollbars are not getting updated and also they are getting hidden from the screen.
Here is the code:
var samplePanel=new Ext.panel.Panel({
title:'Panel1',
height:350,
width:350
});
var sampleWindow=new Ext.window.Window({title:'Window',
items:[samplePanel],
renderTo:Ext.getBody(),
height:300,
width:300,
listeners:{
afterLayout:function(c){
fleXenv.fleXcrollMain(c.body.id);
},resize:function(c,w,h,o){
if(c.body.dom.fleXcroll)
fleXenv.updateScrollBars(); }
}
});
Does anyone had similar problem? Please help me.
After struggling for long time I finally found the actual problem.
Let us see what is happening when we apply scrollbars to a window. The contents inside window goes into its body where we need to display the scrollbars. FleXcroll will add two additional divs inside the target div(in this case, body) with ids of the form targetDivID_mcontentwrapper and targetDivID_scrollbarwrapper. The contents of the body will go to _mcontentwrapper and scrollbars will be displayed in the later.
Scrollbars will be displayed if the contentSize is greater that size of contentwrapper-div which is same as target div.
Here is the structure of divs after applying flexcroll
window-body(target div)
-- mcontentwrapper
-- contentwrapper
-- actual content
-- scrollbarwrapper
After resize the window the content is going into window-body rather than contentwrapper. So the content size in contentwrapper will be zero and hence scrollbar disappears.
structure after resize:
window-body(target div)
-- actual content
-- mcontentwrapper
-- contentwrapper
-- scrollbarwrapper
Now we need to put the actual_content into contentwrapper before updating the scrollbars.
Here is the code for doing that:
listeners:{afterLayout:function(c){
fleXenv.fleXcrollMain(c.body.id);
},
resize:function(c){if(c.body.dom.fleXcroll){
var a=c.body.dom.childNodes;
var b=[];
for (var i=0,j=0;i<a.length ;i++ )
{
if(a[i].id!=c.body.id+"_mcontentwrapper" && a[i].id!=c.body.id+"_scrollwrapper")
{
b[j]=a[i];
j++;
}
}
var el=Ext.get(c.body.id+"_contentwrapper");
for(var i=0;i<b.length;i++)
el.appendChild(b[i]);
}
}
}
I hope it is useful.
Related
I have an app that uses ExtJS 3.3.0. It uses an EditorGridPanel in which after the store is reloaded - I would like it to preserve the scroll position of the grid rather than sending it back up to the top.
Since it's an earlier version of ExtJS - this does not work.
viewConfig: {
preserveScrollOnRefresh: true
}
I thought I had found a solution per Zeke's suggestion to use a scrollTo function like so:
//Save position
var top = grid.getView().scrollergetScroll().top;
//Restore position
grid.getView().scroller.scrollTo('top',top);
This works great - except that after it's done reloading it goes right back up to the top. Basically this would be a perfect solution if only I didn't need preserve the cursor position after reloading the store.
grid().getStore().reload({
callback: function (response) {
//Works at this point
grid.getView().scroller.scrollTo('top',top);
}
}
//However the cursor pops right back up to the top after popping out of
//reload() block
Thanks in advance
This is a little kludgy - maybe the best strategy is just not to use older versions of ExtJS - but this seems to work okay.
Basically just declare some global variables that can be seen from anywhere in the file - one is a flag to indicate that the event that triggers the reload has occured (rowClicked), and one to represent the last known position of the scrollbar
var rowClicked = false;
var prevScrollPosition = -1;
When the event occurs that will trigger the re-load - set the global variable rowClicked to true
rowclick: function(grid, rowIndex, event) {
rowClicked = true;
Then in the listeners of the grid use the rowClicked variable to determine when to re-position the scrollbar.
listeners : {
bodyscroll: function(sl, st) {
if (rowClicked) {
getScenarioLineOrderNumbersGrid().getView().scroller.scrollTo('top',prevScrollPosition);
rowClicked = false;
}
prevScrollPosition = st;
}
Kludgy - but it works.
I have an interesting issue with collectionView, specifically, didSelectItemAtIndexPath.
My app has one particular view with a background image, which is accessed via an SQL. Within that view is a popover, with a collectionView, to change the parent view's background, and access other "sets" available for purchase.
My issue is with the changing of the background. All items display correctly in the collection view and the parent's background will change as it should. The problem is that the item selected is not the one that displays, even though via NSLog, I can see that the correct image is being selected and passed back to the parent. There is a corresponding NSLog in the parent, which shows the same image id as the popover's NSLog.
The first item in the collectionView, when tapped, will change the background of the parent to white, as if there was no image available. Tapping the second cell will display the first cell's image. Tapping the third cell will display the second cell's image... and so on. There are 15 images available to select from.
This is the didSelect method:
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
if ([_currentView isEqualToString:#"New_Journal"])
{
MyAppDelegate *appDelegate = (MyAppDelegate *)[UIApplication.sharedApplication delegate];
// to get the variable back to the parent
appDelegate.loadBackgroundID = indexPath.row;
// interact with the SQL via _settingsDao
[_settingsDao updateJournalBackgroundId:_journalId withBackgroundId:appDelegate.loadBackgroundID];
NSLog(#"Selected background: %d", indexPath.row);
// notification to let EntryView know the background has changed
[NSNotificationCenter.defaultCenter postNotificationName:#"aBackgroundChanged" object:self];
}
}
Edit to show SQL interaction method:
-(void)updateJournalBackgroundId:(int)journalID withBackgroundId:(int)newBackgroundId
{
NSString *query = #"UPDATE BgIconBorderSettings SET background_id = ? WHERE journal_id = ?";
FMDatabase *db = [dbUtils sharedDB];
[db executeUpdate:query,[NSNumber numberWithInt:newBackgroundId],[NSNumber numberWithInt:journalID]];
if([db hadError])
{
NSLog(#"Error %d: %#",[db lastErrorCode],[db lastErrorMessage]);
}
}
Anyone have any ideas on how to get the correct image of the tapped cell to display? Thanks for any assistance in solving this issue.
As jhilgert pointed out... it was the SQL database. It started at 1 and not 0. Changed the ids and it works as expected.
i'm using Extjs 4.1 grid panel.
i'm looking for a way to hide a column from the grid.
i can use setHidden but then the user can "unhide" the column again from the menu in the column header.
it seems that the hideable propery just doesnt cut it...
Ok.
Eventually i did this:
in the grid's "afterrender" event:
var header = pnl.down("headercontainer");
if(header != null && header["getMenu"] != null)
{
var menu=header.getMenu();
menu.on('beforeshow',function(sender,eOpts){
var menu=sender;
if(!menu.items.containsKey("columnItem"))
{
return;
}
var columnsSubMenuItem=menu.items.getByKey("columnItem");
var columnsCheckboxes=columnsSubMenuItem.menu.items["items"];
// More code here...
// See the pseudo code
});
}
now i just looped through the columns and if checkbox.text == column.get_Title() && column.get_Hideable() == true then checkbox.Show() else checkbox.Hide();
(sorry for the pseudo code, i work with a Sharpkit that is a C# to javascript convertor, so if i'd copy pasted the code it'd be harder to explain.
Note: you can do the same with the grid's enableColumnHide event.
use following config to column
hidden: true,
hideable: false
'grid.headerCt.getGridColumns()'
use above method to get all grid column and use hide() and show() to show particular column
This will work on Ext js 4.1
You can configure columns property in initComponent method and insert only necessary columns into this.columns array
Reconfigure the grid for each scenario. Link to api hint
I use the setVisible(false | true) on the column.
doc
Iḿ trying to add more "columns" to a text area.
I have a form with
$f->addField('text','field');
$f->getElement('field')->setAttr('rows','8');
If I set 'rows' property I can add more rows to my textarea, but if i set the 'cols' property It doesn't display correct.
If I inspect the generated html, the textarea has correct set the property 'cols' but it doesn't expand it
Anyone as some help ?
thanks
The short answer is that CSS is affecting the textarea as #scrappedcola pointed out, but I'll give a bit more info on the matter.
Why is it 100%?
All the form fields take 100% of the width. If you need form to be more compact, you can place it into a grid column, which will limit it's width. You can also use horizontal form to conserve space or make it flow in multiple columns. Here is a demo: http://agiletoolkit.org/codepad/gui/formstyle
Where is it set?
If you open inspector for the textarea, you can find what the CSS properties are assigned to the textarea:
By clicking on the arrow under StyleRules (this is safari, but firefox's firebug addon is similar), you can see the following rules in atk-main.css file:
.atk-form fieldset .atk-form-row > .atk-form-field
input[type=text]:not([class*="span"]),
.atk-form fieldset .atk-form-row > .atk-form-field
input[type=password]:not([class*="span"]),
.atk-form fieldset .atk-form-row > .atk-form-field
textarea:not([class*="span"]),
.atk-form fieldset .atk-form-row > .atk-form-field select {
width: 100%;
}
The atk-main.css is generated from atk-main.less file:
fieldset .atk-form-row {
.clearafter();
margin-top:#margin/2;
&:first-child {margin-top:0;}
&.has-error>label {color:#error;}
&.has-error input {border-color:#error;}
>label {font-weight:bold;width:#label;margin-top:0.4em;float:left;}
>.atk-form-field {
margin-left:#label+#labelMargin;
input[type=text]:not([class*="span"]),
input[type=password]:not([class*="span"]),
textarea:not([class*="span"]),
select {width:100%;}
select {width:100%;margin-top:0.5em;}
textarea {display:block;margin-bottom:#margin/5;}
input+input {margin-left:0.4em;}
.atk-form-error {margin:#margin/5 0 0;color:#error;}
}
}
How to override?
You can create a local CSS file to set the width of YOUR textarea fields differently.
$this->api->jui->addStaticStylesheet('yourfile');
You can also set it manually:
$f->addField('text','field');
$f->getElement('field')->setAttr('style','width: 50%');
I am currently creating a web-based Mobile App using Phonegap 1.6.0 and Sencha Touch 1.1. The app consists of a number of panels through which the user can click.
Some of these panels have textfields or textareas in them. Upon entering the panel, we want these to automatically be focused. This seems to work with textfields but not with textareas.
I have a Panel with the following component:
xtype: 'textareafield',
cls: 'jasbackblock',
id: 'addreactiontextarea',
height: '100%',
grow: true,
listeners: {
afterrender: function(cmp) {
console.log('Component rendered.');
cmp.fieldEl.dom.focus();
}
Whenever I first open the panel, it automatically focuses, which is good. However, when I leave the panel and then return to it, I cannot think of a good way to do this with events.
I have previously tried the show listener in the panel:
listeners: {
show: function(cmp) {
Ext.get('addreactiontextarea').fieldEl.dom.focus();
}
}
This gives me the following error:
Uncaught TypeError: Cannot read property 'fieldEl' of null
It seems that I cannot access the element during the show event. Is there any other event that I could use which fires every time the panel is loaded and allows me to access the textarea?
If it is any help, this is the method we call to switch from one panel to another:
function switchScreen(from, to, newArgs) {
/* Save screen information. */
if (from != -1)
historyStack.push([from, screenArgs]);
if (currentPage > 2) {
if (to != 3)
main.getComponent(3).hide();
app.getComponent(currentPage - 3).hide();
}
else
main.getComponent(currentPage).hide();
screenArgs = newArgs;
if (to > 2) {
main.setActiveItem(3);
app.setActiveItem(to - 3);
/* setActiveItem does not fire a screen's show event if it has been
* shown before. Since we want the code in the screen's show listener to
* be executed every time we switch to the screen, we call show manually
* just to fire the event. */
main.getComponent(3).show();
app.getComponent(to - 3).show();
}
else {
main.setActiveItem(to);
main.getComponent(to).show();
}
if (to == 0 || to == 1)
adMode = to;
else
adMode = -1;
currentPage = to;
}
I solved the problem. The issue was that I was not quite aware of how DOM elements worked.
Ext.get('id') returns the DOM element of the Javascript Object with the id 'id'. It does not return the object itself.
Ext.getCmp('id') returns the Javascript object with the id 'id'. Therefore, Ext.getCmp('id').fieldEl returns the same object as Ext.get('id').
Because of a bug in Sencha Touch 1.1, we chose to use the DOM focus function rather than the Sencha focus function. One can access this function by either Ext.getCmp('id').fieldEl.dom.focus() or Ext.get('id').dom.focus(). As you can see in my question, I mixed these up. Because of my lack of experience with DOM elements, I became even more confused when I tried to use an Object function this way. (Ext.get('id').reset() is simply illogical.)
If you have any questions, feel free to message.