I have a simple grid with two(add and remove) buttons as docked item in sencha cmd application. I want to delete the selected row.
I have grid defined in my view as
xtype:'app-main',
viewModel: {
type: 'main'
},
layout: 'absolute',
autoScroll : true,
resizable:true,
items: [
{
xtype: 'gridpanel',
x: 10,
y: 10,
autoScroll : true,
renderTo: document.body,
//height: 300,
width: 300,
title: 'Grid Panel',
store: 'peopleStore',
columns: [
{
xtype: 'gridcolumn',
dataIndex: 'id',
text: 'Id'
},
{
xtype: 'gridcolumn',
dataIndex: 'title',
text: 'Title'
},
{
xtype: 'gridcolumn',
dataIndex: 'body',
text: 'Body'
}
],
dockedItems: [{
xtype: 'toolbar',
items:[
{
xtype: 'button',
x: 330,
y: 10,
scale: 'medium',
text: 'Add New Record',
handler: function() {
var UserStore = Ext.getStore('peopleStore');
UserStore.add({title: 'asd', body:'asdasd'});
UserStore.sync();
UserStore.load();
}
},
{
xtype: 'button',
scale: 'medium',
text: 'Reset Records',
handler: function() {
//delete code will go here
}
}]
}]}]
With this stackoverflow question extjs how to get a grid
I know code will be some thing like
grid.getView().getSelectionModel().getSelection()[0];
if (selection) {
UserStore.remove(selection);
}
But can someone tell me how to get reference to "grid" ?
Grabs the first parent (relative to the button) that is a grid:
xtype: 'button',
...
handler: function(button) {
var grid = button.up('gridpanel');
console.log("my grid", grid);
}
Grabs the first parent (relative to the button) that is a grid and has itemId "myGrid" (to prevent ambiguity):
xtype: 'gridpanel',
itemId: 'myGrid',
...
xtype: 'button',
...
handler: function(button) {
var grid = button.up('gridpanel #myGrid');
console.log("myGrid", grid);
}
I would heavily suggest looking up selectors in ExtJS (for ExtJS <= 5) and references in ViewControllers (for ExtJS 5). There are pros/cons to both so I would recommend reading about both of them (though both do very similar things). My solution uses selectors.
Here are some resources:
http://docs.sencha.com/extjs/5.0/application_architecture/view_controllers.html
http://training.figleaf.com/tutorials/senchacomplete/chapter2/lesson5/2.cfm
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.dom.Query (complete selector syntax list)
Related
so I have a view where I display a combobox and a grid that share a 'Roles' store. If you pick an option on the combobox, the grid will be filtered accordingly.
I am looking for a way to add an "All" option to the combobox that is selectable (so placeholder or value attributes don't work for me). I want to do this because I cannot add that option to the store without affecting the grid as well.
This is my code:
Ext.define("MODIFE.view.administration.Roles",{
extend: "Ext.panel.Panel",
xtype: "app-administration-roles",
controller: "administration-roles",
viewModel: {
type: "administration-users"
},
title: "Roles",
items:[
{
title: 'Búsqueda de Roles',
frame: true,
resizable: true,
xtype: 'form',
layout: 'column',
defaults: {
layout: 'form',
xtype: 'container',
defaultType: 'textfield',
style: 'width: 50%'
},
items: [{
items: [{
fieldLabel: 'Rol',
xtype: 'combobox',
store: 'Roles',
displayField: 'Description',
valueField: 'RoleId',
}]
}, {
items: [
{ fieldLabel: 'Estatus', xtype: 'combobox' },
]
}],
buttons: [
{ text: 'Nuevo' },
{ text: 'Buscar' }
]
},
{
layout: 'fit',
items: [{
xtype: 'grid',
id: 'rolesGrid',
title: 'Listado de Roles',
store: 'Roles',
columns: [
{ text: 'Rol', dataIndex: 'Description', flex: 2},
{ text: 'Estatus', dataIndex: 'Status', flex: 2},
]
}]
}]
});
Thanks in advance!
You could clone the store, then any alterations wont be reflected in the original store. (but it's messy, and may have problems with syncing if you have this enabled)
//clone store
var records = [],
me = this;
me.store.each(function(r){
records.push(r.copy());
});
var store2 = new Ext.data.Store({
recordType: me.store.recordType,
model: me.store.model
});
store2.add(records);
//add record
store2.add({ID:"-1", NAME: "-Please select-"});
I have my ExtJS 4.2.1 MVC Application.
Inside my app, I have a grid with a toolbar. The toolbar has 2 buttons, "Add New" and "Edit Record".
Inside my Controller.js I listen for my toolbar buttons click events.
this.control({
'toolbar #newRecord': {
click: this.addRecord
},
'toolbar #editRecord': {
click: this.editRecord
},
'[xtype=editshiftcode] button[action=commit]': {
click: this.saveRecord // here I have to add or edit
}
}
Then I have Window that I want to use for editing and adding records:
Ext.define('App.view.EditShiftCode', {
extend: 'Ext.window.Window',
alias: 'widget.editshiftcode',
height: 250,
width: 550,
title: 'Add / Edit Shift',
modal: true,
resizable: false,
layout: 'fit',
glyph: Glyphs.PENCIL,
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [{
xtype: 'container',
//height: 175,
layout: {
type: 'hbox',
align: 'strech'
},
items: [{
xtype: 'form',
bodyPadding: 10,
autoScroll: false,
itemId: 'editForm',
defaults: { // defaults are applied to items, not the container
allowBlank: false,
allowOnlyWhitespace: false,
msgTarget: 'side',
xtype: 'textfield'
},
items: [
{
xtype: 'textfield',
name: 'ShiftCode',
fieldLabel: 'Code'
},
{
xtype: 'textfield',
name: 'Description',
fieldLabel: 'Description'
},
{
xtype: 'hiddenfield',
name: 'ShiftType'
},
{
xtype: 'hiddenfield',
name: 'ShiftTypeId'
},
{
xtype: 'textfield',
name: 'Hours',
fieldLabel: 'Hours per Day'
},
{
xtype: 'colorcombo',
name: 'ColorHex',
fieldLabel: 'Color'
},
{
xtype: 'checkbox',
fieldLabel: 'Active',
name: 'IsActive',
}
],
}]
}],
buttons: [
{
text: 'OK',
action: 'commit',
glyph: Glyphs.SAVE
},
{
text: 'Cancel',
action: 'reject',
glyph: Glyphs.CANCEL
}]
});
me.callParent(arguments);
},
});
My editRecord function is:
editRecord: function (button, e, options) {
var me = this;
var window = Ext.create('App.view.EditShiftCode');
window.show();
},
My addRecord function is:
addRecord: function (button, e, options) {
var me = this;
var window = Ext.create('App.view.EditShiftCode');
window.show();
},
My saveRecord function is:
saveRecord: function (button, e, options) {
// here i need to know what operation im going to perform.
// if Im going to edit then I have to update my form record to my store record
// if im going to add then I need to add a new item to my store.
}
Is this correct? To use the same function to perform 2 different actions? And if so, how can I know what action am I going to perform and how to do it?
Thanks
This way always worked for me:
User selects a record in the grid
User clicks "Edit record"
I use loadRecord to load the selected record in the form
When he clicks OK I call updateRecord
If user clicks "Add record" I create a new blank record and go to step 3
If he clicks OK after adding record, I just add the new record to the grid - you can easily know if the record is new or existing by checking phantom flag. So if record.phantom === true then it is new.
I'd like to achieve this behavior:
If a field (combo, text, date ...) in a form panel has a custom property set true
{
xtype: 'textfield',
fieldLabel: 'Name',
name: 'Name',
customProp: true
},
then add a button or other components behind the actual component. Writen in json it would look like this:
{
xtype: 'container',
margin: '0 0 8 0',
layout: 'hbox',
items: [
{
xtype: 'textfield',
fieldLabel: 'Name',
name: 'Name',
},
{
xtype: 'button',
text: 'xxx',
tooltip: 'I\'m a custom tooltip'
}
]
}
I'm wondering how i could achieve this. Is this even possible ?
It is.
Ext.require('*');
Ext.onReady(function() {
var form = new Ext.form.Panel({
renderTo: document.body,
width: 400,
height: 100,
items: {
xtype: 'textfield',
fieldLabel: 'Foo'
}
});
setTimeout(function() {
var field = form.down('textfield');
// We have a reference to the field, let's go!
var owner = field.ownerCt;
owner.remove(field, false);
owner.add({
xtype: 'container',
layout: 'hbox',
items: [field, {
xtype: 'button',
text: 'Foo'
}]
});
}, 1000);
});
Where container is a reference to the container with the hbox layout.
I have a tabpanel. In the tab, i have a panel which includes a toolbar and 3 items: [ fieldset, a gridpanel, and another fieldset (or some buttons)]. I cannot get the gridpanel to show scroll bar. It only works if i set the maxheight/minheight of the gridpanel.
I also tried wrapping gridpanel inside a container. No luck.
In the example, i use fit layout. I tried "anchor" layout, and assigned anchor:'100% 50%' to gridpanel, hoping that it would resize when i resize browser. No luck.
Alternatively, if gridpanel is the ONLY item in the tab, autoscroll would work. So it appears when it's inside another panel, autoscroll/ resizing does not work.
Did I miss something here ?
Ext.application({
name: 'MyApp',
launch: function () {
// create the data store
var d = ['company', 100];
var myData = [];
for (var i = 0; i < 50; i++) {
myData[i] = d;
}
var store = Ext.create('Ext.data.ArrayStore', {
fields: [{
name: 'company'
}, {
name: 'price',
type: 'float'
}],
data: myData
});
Ext.create("Ext.container.Viewport", {
layout: {
type: 'border'
},
items: [{
xtype: 'toolbar',
id: 'headerbar',
region: 'north',
height: 30
}, {
xtype: 'toolbar',
id: 'menubar',
region: 'north',
height: 30
}, {
xtype: 'tabpanel',
itemId: 'maintabpanel',
activeTab: 0,
region: 'center',
plain: true,
margins: '5 5 5 5',
layout: 'fit',
items: [{
closable: false,
title: 'Tab',
margins: '0 0 0 0',
items: [{
xtype: 'panel',
title: 'Panel',
layout: 'fit',
tools: [{
type: 'help',
tooltip: 'Help'
}, {
type: 'close',
tooltip: 'Close'
}],
items: [{
xtype: 'fieldset',
title: 'Field Set',
layout: 'hbox',
items: [{
xtype: 'textfield',
fieldLabel: 'Input'
}]
}, {
xtype: 'gridpanel',
autoScroll: true,
store: store,
columns: [{
text: 'Company',
flex: 1,
sortable: true,
dataIndex: 'company'
}, {
text: 'Price',
flex: 1,
sortable: true,
dataIndex: 'price'
}],
viewConfig: {
autoFit: true
}
}, {
xtype: 'fieldset',
title: 'Field Set 2',
layout: 'hbox',
items: [{
xtype: 'textfield',
fieldLabel: 'Output'
}]
}]
}]
}]
}, {
xtype: 'box',
id: 'footer',
region: 'south',
html: '<h1> Copyright 2012</h1>',
height: 30
}]
});
}
});
Note that the parent panel of the gridpanel has fit layout, yet it has more than 1 item (the fieldset, the gridpanel, and another fieldset). A fit layout can only have 1 child.
Also, the parent of that fit panel (the one with closable : false - the tab) has no layout definition.
Here's a JsFiddle modified version of your code that works.
When I'm adding items to the grid's store and grid is not visible at that moment then grid is not populated with items. Is there any fix or workaround for this?
Here is the code (switch to "tab1", click button, switch back to "tab2" — grid is empty):
var tbar = {
items: [{
text: 'add some lines',
handler: function() {
Ext.getCmp('grid-panel').store.loadData([[1, 'aaaaa'], [2, 'bbbbb']]);
}
}]
};
Ext.onReady(function() {
var p = new Ext.TabPanel({
renderTo: 'panel-div',
width: 500,
height: 350,
title: '123123',
activeItem: 1,
items: [{
title: 'tab1',
tbar: tbar
},{
title: 'tab2',
layout: 'fit',
tbar: tbar,
items: {
xtype: 'grid',
hideHeaders: true,
id: 'grid-panel',
autoExpandColumn: 'text',
columns: [{id: 'text', header: 'Category', width: 1, dataIndex: 'text'}],
store: new Ext.data.ArrayStore({
fields: ['id', 'text']
})
}
}]
});
});
grid.getView().refresh() should reload the grid.