In Extjs4 how to set scrollbar position to bottom of form panel - extjs4

i am working in extjs4. i have form panel with autoscroll true. I have 20-25 fields with fileUpload field at bottom. When i am uploading file, form's scroll is going to top by default. i want to keep scroll of form as it is on where it was while uploading file. So how to set this scrollBar at bottom of or at upload field section in extjs4

You can try by adding the following method to your form declaration:
scrollToField: function(fieldId) {
var field = Ext.get(fieldId);
field.el.scrollIntoView(this.body.el);
}
Here you have a working sample
IMHO,it will be better, however, to group fields using tabs or something similar to avoid having a long a and hard to read / fill form

I have solve this problem into Ext js 4.2 for Ext.form.panel
See the following code. It will helpful to you.
onRender function call on render event
onRender: function () {
this.callParent(arguments);
if (!this.restoreScrollAfterLayout) {
this.mon(Ext.get(this.getEl().dom.lastElementChild), 'scroll', this.onScroll, this);
this.restoreScrollAfterLayout = true;
}
},
onScroll: function (e ,t, eOpts) {
this.scroll = Ext.get(this.getEl().dom.lastElementChild).getScroll();
},
afterLayout: function () {
this.callParent(arguments);
if (this.restoreScrollAfterLayout && this.scroll) {
var el = Ext.get(this.getEl().dom.lastElementChild),
scroll = this.scroll;
el.scrollTo('left', scroll.left);
el.scrollTo('top', scroll.top);
}
}

Related

Create custom command to expand client detail template in Kendo UI Grid (MVC)

I've got a nested grid within my grid, and it works perfectly, but the client doesn't like to use the arrow on the left and asked for a button to be added in order to show the child grid.
The example on the Kendo website shows how to automatically open the first row, I just want a way to expand the grid from a custom control in the same way that the left selector does it.
I've got the custom command working, and it executes the sample code, but I just need some help with the javascript required to make it work for the current row.
columns.Command(command =>
{
command.Edit().Text("Edit").UpdateText("Save");
command.Destroy().Text("Del");
command.Custom("Manage Brands").Click("showBrandsForAgency");
And the js with the standard example of opening the first row:
function showBrandsForAgency(e) {
this.expandRow(this.tbody.find("tr.k-master-row").first());
}
Please help by giving me the js required to expand the row clicked and not the first row?
* EDIT *
Modified the solution provided by Atanas Korchev in order to get it to work on only the button and not the whole row.
I'd prefer a solution that uses the function showBrandsForAgency instead of a custom funciton but this does the job:
$(document).ready(function () {
$("#grid").on("click", "a", function (e) {
var grid = $("#grid").data("kendoGrid");
var row = $(this).parent().parent();
if (row.find(".k-icon").hasClass("k-minus")) {
grid.collapseRow(row);
} else {
grid.expandRow(row);
}
});
});
You can try something like this:
$("#grid").on("click", "tr", function(e) {
var grid = $("#grid").data("kendoGrid");
if ($(this).find(".k-icon").hasClass("k-minus")) {
grid.collapseRow(this);
} else {
grid.expandRow(this);
}
});
When using jQuery on the function context (available via the this keyword) is the DOM element which fired the event. In this case this is the clicked table row.
Here is a live demo: http://jsbin.com/emufax/1/edit
Same results just Simpler, faster, and more efficient:
$("#grid").on("click", "tr", function () {
$(this).find("td.k-hierarchy-cell .k-icon").click();
});

Dojo1.8: I am not able to update label of each Button instance while creating instances from Button

I am not able to update label of each Button instance while creating instances from button.
How do I work around it? Or can I not code it as follows?
registry.byId(new Obj_Button({
id:'star'+ i,
label:'Button '+ i, //it will not work, so how to solve it???
}).placeAt(dom.byId('new1')));
Also please see my jsfiddle - http://jsfiddle.net/clementyap/sTxbh/42/
regards
Clement
Your widget needs to be coded to handle label
declare("Obj_Button", [_WidgetBase], {
postMixInProperties: function() {
if(!this.label)
this.label = 'New Button Instance';
},
buildRendering: function () {
// create the DOM for this widget
this.domNode = domConstruct.create("button", {
innerHTML: this.label
});
}
});
Also, you can just instantiate the widget, the registry.byId call is not needed.

making Ext.Action's text property dependent on another field's value

I have a grid within a window. The grid has 3 Actions: Edit, Delete and Disable.I was wondering if it is possible to make the text of the Disable Action (which is currently 'Disable/Enable') to be dependent on the Current Status of the record selected. So say the user selects a record whose Current Status is Enabled, then the action's text should be 'Disable'. If, however, the user selects a record whose status is Disabled, then the action's text should be 'Enable'. Is it possible to do this when using Action? Or do I need to use a button instead of Action?
I am assuming your action button is in a toolbar that is docked to the top of your grid panel. The only tricky thing is getting a reference to the grid (without hardcoding it). The grid's 'select' event only gives you a reference to the rowmodel used.
/* Set a action attribute on the Ext.Action so we can find it */
var action = new Ext.Action({
text: 'Do something',
handler: function(){
Ext.Msg.alert('Click', 'You did something.');
},
iconCls: 'do-something',
itemId: 'myAction',
action: 'myAction' // I don't like itemId's personally :)
});
/* In the Controller */
init: function() {
this.control({
'mygrid': {
select: this.onRecordSelect
}
});
},
onRecordSelect: function(rowModel, record) {
var grid = rowModel.views[0].ownerCt);
var action = grid.getDockedItems('toolbar[dock="top"]')[0].down('button[action="myAction"]');
var enabled = (record.get('CurrentStatus') == "Enabled");
action.setText(enabled ? 'Disable' : 'Enable');
action.setIconCls(enabled ? 'myDisableCls' : 'myEnableCls');
}
/* in SASS */
.myDisableCls{
background-image:url(#{$icon_path}/checkbox.png) !important;
}
.myEnableCls {
background-image:url(#{$icon_path}/checkbox_ticked.png) !important;
}
Good luck!
I solved the problem in another way. This is my code:
grid.getSelectionModel().on({
selectionchange: function(sm, selections) {
if (selections.length > 0) {
Edit.enable();
Delete.enable();
if(selections[0].data.CurrentStatus == "Disabled"){
Disable.setText("Enable");
Disable.enable();
}else{
Disable.setText("Disable");
Disable.enable();
}
} else {
Edit.disable();
Delete.disable();
Disable.disable();
}
}
});

Dojo/Dijit TitlePane

How do you make a titlePane's height dynamic so that if content is added to the pane after the page has loaded the TitlePane will expand?
It looks like the rich content editor being an iframe that is loaded asynchronously confuses the initial layout.
As #missingno mentioned, the resize function is what you want to look at.
If you execute the following function on your page, you can see that it does correctly resize everything:
//iterate through all widgets
dijit.registry.forEach(function(widget){
//if widget has a resize function, call it
if(widget.resize){
widget.resize()
}
});
The above function iterates through all widgets and resizes all of them. This is probably unneccessary. I think you would only need to call it on each of your layout-related widgets, after the dijit.Editor is initialized.
The easiest way to do this on the actual page would probably to add it to your addOnLoad function. For exampe:
dojo.addOnLoad(function() {
dijit.byId("ContentLetterTemplate").set("href","index2.html");
//perform resize on widgets after they are created and parsed.
dijit.registry.forEach(function(widget){
//if widget has a resize function, call it
if(widget.resize){
widget.resize()
}
});
});
EDIT: Another possible fix to the problem is setting the doLayout property on your Content Panes to false. By default all ContentPane's (including subclasses such as TitlePane and dojox.layout.ContentPane) have this property set to true. This means that the size of the ContentPane is predetermined and static. By setting the doLayout property to false, the size of the ContentPanes will grow organically as the content becomes larger or smaller.
Layout widgets have a .resize() method that you can call to trigger a recalculation. Most of the time you don't need to call it yourself (as shown in the examples in the comments) but in some situations you have no choice.
I've made an example how to load data after the pane is open and build content of pane.
What bothers me is after creating grid, I have to first put it into DOM, and after that into title pane, otherwise title pane won't get proper height. There should be cleaner way to do this.
Check it out: http://jsfiddle.net/keemor/T46tt/2/
dojo.require("dijit.TitlePane");
dojo.require("dojo.store.Memory");
dojo.require("dojo.data.ObjectStore");
dojo.require("dojox.grid.DataGrid");
dojo.ready(function() {
var pane = new dijit.TitlePane({
title: 'Dynamic title pane',
open: false,
toggle: function() {
var self = this;
self.inherited('toggle', arguments);
self._setContent(self.onDownloadStart(), true);
if (!self.open) {
return;
}
var xhr = dojo.xhrGet({
url: '/echo/json/',
load: function(r) {
var someData = [{
id: 1,
name: "One"},
{
id: 2,
name: "Two"}];
var store = dojo.data.ObjectStore({
objectStore: new dojo.store.Memory({
data: someData
})
});
var grid = new dojox.grid.DataGrid({
store: store,
structure: [{
name: "Name",
field: "name",
width: "200px"}],
autoHeight: true
});
//After inserting grid anywhere on page it gets height
//Without this line title pane doesn't resize after inserting grid
dojo.place(grid.domNode, dojo.body());
grid.startup();
self.set('content', grid.domNode);
}
});
}
});
dojo.place(pane.domNode, dojo.body());
pane.toggle();
});​
My solution is to move innerWidget.startup() into the after advice to "toggle".
titlePane.aspect = aspect.after(titlePane, 'toggle', function () {
if (titlePane.open) {
titlePane.grid.startup();
titlePane.aspect.remove();
}
});
See the dojo/aspect reference documentation for more information.

create a window chrome with an exception in back

I'd just like to create a new window from the background page and put it in back. I tried focused:false but it doesn't seem to make the trick. I tried to save the previous windowId and tabId and update it after having creating the new window but it doesn't solve the problem neither.
Do you know how we can do that?
Here is my code:
function saveTabId() {
// Get the current tab
chrome.tabs.getSelected(null,function(tab){
if (tab != 'undefined') {
if (tab.windowId != windowId) {
currentTabId = tab.id;
currentWindowId = tab.windowId;
}
chrome.windows.create({url:"http://www.google.com", width:100, height:100, top:0, left:0, focused:false}, function() {
chrome.tabs.get(currentTabId, function(tab) {
chrome.windows.update(tab.windowId, {}, function(w) {
chrome.tabs.update(tab.id, {selected:true});
});
});
});
}
});
}
I launched this code at the beginning of background.html and when I refresh the extension, the window is on top of the extensions tab.
P.S: something more strange the window is on top of the extensions tab and when I change tab in this window, the new window stays on top of the other one even if I click and type text in the other one...
I got it kind of working, but popup window is still showing up for a moment before going underneath the current window:
chrome.windows.create({url:"http://www.google.com", width:100, height:100, top:0, left:0, focused:false}, function() {
chrome.windows.update(currentWindowId, {focused:true});
});
Thanks, here is the code I'm using now. The problem in the code of the question was the focus to the other window before updating it. It is strange, when you focus on a window, it doesn't show it on top of the others.
function focusTab(tabId) {
chrome.tabs.get(tabId, function(tab) {
chrome.windows.update(tab.windowId, {}, function(w) {
chrome.tabs.update(tab.id, {selected:true});
});
});
}