Sencha grid: hidden column and combobox - extjs4

First a small portion of the code:
{ text: 'TipoVisitaID',
hidden: true,
dataIndex: 'TipoVisitaID',
itemId: 'TipoVisitaID'
}, {
text: 'TIPO VISITA',
flex: 1,
sortable: true,
align: 'right',
dataIndex: 'TipoVisita',
editor: {
xtype: 'combo',
allowBlank: true,
store: allTiposVisita,
valueField: 'Id',
name: 'TiposVisitaCombo',
itemId: 'TiposVisitaCombo',
tpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<div class="x-boundlist-item">{Designacao}</div>',
'</tpl>'),
displayTpl: Ext.create('Ext.XTemplate', '<tpl for=".">', '{Designacao}', '</tpl>')
}
},
What i would like to achivie is this.
When editing the row i would like that the selected value for the combo to be the value in the hidden field.
Is this even possible??
I've tried doing this: (on the combo)
value: Ext.ComponentQuery.query("#TipoVisitaID")[0] == null ? '' : Ext.ComponentQuery.query("#TipoVisitaID")[0].value
but it doesn't work...

Add a event listener to edit event on the grid and update data in your hidden field from there. This event will fire after edit is complete.
grid.on('edit', function (editor, e){
e.record.set('TipoVisitaID', e.value);
}

I've solved the problem.
{
text: 'TIPO VISITA',
flex: 1,
sortable: true,
align: 'right',
dataIndex: 'TipoVisitaID',
renderer: function (loader, response, active) {
return active.raw.TipoVisita;
},
editor: {
xtype: 'combo',
allowBlank: true,
store: allTiposVisita,
valueField: 'Id',
name: 'TiposVisitaCombo',
itemId: 'TiposVisitaCombo',
tpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<div class="x-boundlist-item">{Designacao}</div>',
'</tpl>'),
displayTpl: Ext.create('Ext.XTemplate', '<tpl for=".">', '{Designacao}', '</tpl>')
}
},
First i changed the dataIndex to the ID. But now the user would see the ID instead of the data, that's why i use the renderer so that the user sees the data and not the ID.
I then added the listener 'beforeedit' to the grid in which i did this:
Ext.ComponentQuery.query("#TiposVisitaCombo")[0].setValue(e.record.raw.TipoVisitaID);
Thus setting the value of the combo (making it the preselected one) with the ID.

Are you looking for something like this?
var theHidden = Ext.getCmp('TipoVisitaID');
var theCombo = Ext.getCmp('TiposVisitaCombo'); =
theCombo.on('change', function(combo, newValue, oldValue, e){
theHidden.setValue(newValue);
});

Related

Change text filed attribute in a specific row dojo dgrid in edit mode

I want to change a text field attribute in a specific row.
I have an editable dGrid with 5 fields, 2 of them are disabled and their values change when a select filed value is changed, now I want when the value of the select is changing to specific value, the two disabled filed are enabled for edit only for this row, and then be disabled again when choosing other values in the select, here's a screenshot of the grid
And here's the creation of the grid
this.productStore = new Memory({idProperty: 'id', data: []});
this.productObjStore = new ObjectStore({objectStore:
this.productStore});
var productColumn = {
field: 'productServiceId',
label: dojoConfig.i18n.productOrService,
className: 'hand',
editor: Select,
autoSave: true,
editorArgs: {
searchAttr: 'name',
labelAttr: "name",
style: 'width: 95%',
store: this.productObjStore,
required: true,
},
renderCell: function(object, data, td, options){
if(data != ''&& data != dojoConfig.i18n.addNewProduct){
td.innerHTML = this.editorArgs.store.get(data).label;
}
}
};
var quantityColumn = {
field: 'quantity',
label: dojoConfig.i18n.quantity,
className: 'hand',
editor: TextBox,
autoSave: true,
editorArgs: {
placeHolder: '#####',
regExp: dojoConfig.regExps.intExp,
trim: true,
style: 'width: 100%',
invalidMessage: dojoConfig.i18n.error_quantityIsZero,
validator: function(){
if( this.value > 0)
return true;
return false;
}
}
};
var me=this
var rateColumn = {
field: 'rate',
label: dojoConfig.i18n.rate,
className: 'hand',
editor: TextBox,
autoSave: true,
editorArgs: {
disabled: true,
placeHolder: '#####.##',
regExp: dojoConfig.regExps.floatExp,
trim: true,
style: 'width: 100%',
}
};
var amountColumn = {
field: 'amount',
label: dojoConfig.i18n.amount,
className: 'hand',
editor: TextBox,
editorArgs: {
disabled: true,
placeHolder: '#####.##',
regExp: dojoConfig.regExps.floatExp,
trim: true,
style: 'width: 100%',
}
};
this.discountStore = new Memory({idProperty: 'id', data: []});
var discountColumn = {
field: 'discount',
label: dojoConfig.i18n.lineDiscount,
className: 'hand',
editor: Select,
autoSave: true,
editorArgs: {
searchAttr: 'name',
labelAttr: "name",
style: 'width: 99%',
store: this.discountStore,
required: false,
value:null
},
renderCell: function(object, data, td, options){
if(data != '')
td.innerHTML = this.editorArgs.store.get(data).label;
}
};
this._grid = new Grid({
autoHeight: true,
showToolbar: true,
//label: dojoConfig.i18n.invoiceLines,
style: 'width: 100%; max-height: 200px; margin-top: 1px;',
columns : [
{field: 'id', label: 'ID', hidden: true, unhidable: true},
productColumn,
{field: 'description' ,label: dojoConfig.i18n.description, dismissOnEnter: false, editor: 'textarea', autoSave: true, renderCell: function(object, data, td, options){
td.innerHTML = data;
}},
quantityColumn,
rateColumn,
// discountColumn,
amountColumn,
{field: 'taxable', style:'width:50%', label: dojoConfig.i18n.taxable, editor: CheckBox, hidden: true, unhidable: true}
],
contextMenuInfo: [
{label: dojoConfig.i18n.new_, iconClass: 'newIcon', onClick: this.addProduct},
{label: dojoConfig.i18n.remove, iconClass: 'deleteIcon', onClick: this.deleteProduct, needSelection: true}
],
contextHandler: this,
selectionMode : 'single', // for Selection; only select a single row at a time
cellNavigation : false,
colspan: 5
});
this._grid.set('store', new Observable(new Memory({idProperty: 'id', data: []})));
Thanks

Creating user story popover

Could someone help me create a popover that appears on mouse hover to display user story name and project it belongs to. I've created a custom app in rally that displays parent and child stories in a grid. I would like to create a popover when user hover on child story ID to view Name and project information. How can this functionality be added?
this.grid = this.down('#gridCnt').add({
xtype: 'rallygrid',
id: 'dataGrid',
showPagingToolbar: true,
flex: 1,
store: myCustomStore,
plugins: ['rallyboardformattedidhoverable'],
enableBlockedReasonPopover: false,
columnCfgs: [{
xtype: 'templatecolumn',
text: 'ID',
dataIndex: 'FormattedID',
width: 80,
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
}, {
text: 'Name',
dataIndex: 'Name',
},
{
text: 'Child stories',
dataIndex: 'Children',
flex: 1,
renderer: function(value) {
var html = [];
Ext.Array.each(value, function(child) {
html.push('' + child.FormattedID + '' + ' - ' + child.Project);
});
return html.join('</br>');
}
},
There is a plugin that should do exactly what you are looking for. Just add the plugin to your grid config:
plugins: ['rallyboardformattedidhoverable'],
getRecord: function(x) {
return this.view.getRecord(x);
},

Sencha Touch 2 Navigation View responding very slowly

I am a newbie to Sencha Touch 2 . I am building an PhoneGap + Sencha Touch 2 application for Android 2.3.4 . I completed developing my application . While testing the app , i found out that the navigation view i used is responding very slow on tap of disclosure item.
I am using a list container view , list view and editor view . The code for them is given below .
The below piece of code works fine but on the tap of disclosure item the incident editor view is shown after 10 secs and i sometimes even don't know whether it was clicked or not .
So i need help in two things :
1.) When i click on disclosure item i should show masking to know that i clicked it atleast
2.) Or speed up the show of incident editor view
ListContainer View :
Ext.define('Sample.view.ListContainer', {
extend: 'Ext.NavigationView',
xtype:'listContainer',
id: 'idListContainer',
config: {
id:'idIncidentListContainer',
items:[
{
xtype:"incidentsList",
cls: "clsHeader"
}
]
}
});
List View:
Ext.define("Sample.view.IncidentsList", {
extend: "Ext.Panel",
xtype: 'incidentsList',
id: 'idIncidentList',
requires:[
'Ext.dataview.List',
'Ext.data.proxy.Memory',
'Ext.data.Store',
],
alias:'widget.incidentslist',
config: {
id: 'idIncidentList',
layout:'fit',
items: [
{
xtype: "toolbar",
docked: "top",
ui:'light',
id:"idHeaderTwo",
cls:"clsHeaderTwo" ,
items: [
{ xtype: 'title' ,
cls: 'clsLeftTitle',
title: "My Incidents",
},
{ xtype: 'spacer'},
{ xtype: 'title' ,
cls: 'clsRightTitle',
id: 'idIncidentsListTitle',
title:"Welcome",
},
]
},
{
xtype: "list",
store: "IncidentStore",
itemId:"incidentsList",
id:"inclist",
loadingText: "Loading Incidents...",
emptyText: "<div class=\"empty-text\">No incidents found.</div>",
onItemDisclosure: true,
itemTpl: Ext.create('Ext.XTemplate',
'<tpl if="TKT_STATUS_NAME == \'CLOSED\'">',
'<div class="vm_statusRed">',
'</tpl>',
'<tpl if="TKT_STATUS_NAME == \'OPENED\'">',
'<div class="vm_statusYellow">',
'</tpl>',
'<tpl if="TKT_STATUS_NAME == \'ASSIGNED\'">',
'<div class="vm_statusOrange">',
'</tpl>',
'<tpl if="TKT_STATUS_NAME == \'PENDING\'">',
'<div class="vm_statusRed">',
'</tpl>',
'<tpl if="TKT_STATUS_NAME == \'RESOLVED\'">',
'<div class="vm_statusOrange">',
'</tpl>',
'<tpl if="TKT_STATUS_NAME == \'REOPEN\'">',
'<div class="vm_statusYellow">',
'</tpl>',
'<div class="vm_dvList"><h4 class="vm_txtName"><span class="vm_listHeader"><label>Inci.#{TKT_ID} by </label><label class="vm_txtFirstName"><i>{FIRST_NAME:ellipsis(15, true)}</i></label></span><div class="date vm_clsDate">{CREATED_ON:date("d-M-y H:i")}</div></h4>',
'<div class="vm_title">{TKT_SUBJECT}</div>',
'<div class="vm_subDesc">{TKT_DESC}</div></div></div>'
)
}],
listeners: [
{
delegate: "#incidentsList",
event: "disclose",
fn: "onIncidentsListDisclose",
loadingText: "Loading ...",
},
]
},
initialize: function() {
this.callParent(arguments);
var getLoginData = localStorage.getItem('userData');
var parseData = JSON.parse(getLoginData);
var fname = parseData[0].FIRST_NAME;
var getIncidentData = localStorage.getItem('userIncidentData');
var parseIncidentData = JSON.parse(getIncidentData);
Ext.getCmp("idIncidentsListTitle").setTitle("Welcome, " + fname);
Ext.getStore("IncidentStore").setData(localStorage.userIncidentData).load();
},
onIncidentsListDisclose: function (list, record, target, index, evt, options) {
console.log("editIncidentCommand");
/*var list = Ext.getCmp('idIncidentList');
list.setMasked({
xtype:'loadmask',
message:'Loading...'
});*/
this.fireEvent('editIncidentCommand', this, record);
}
});
Editor View :
Ext.define("Sample.view.IncidentEditor", {
extend: 'Ext.form.Panel',
xtype: 'incidentsEditor',
id:'incidentsEditorView',
alias: "widget.incidenteditorview",
config: {
scrollable: 'vertical',
id:'idIncidentEditor',
layout:'vbox',
items: [
{
xtype: "toolbar",
docked: "top",
ui:'light',
id:"idHeaderTwo",
cls:"clsHeaderTwo",
items: [
{ xtype: 'title' ,
cls: 'clsLeftTitle',
title: "Incident Details",
},
{xtype: 'spacer'},
{ xtype: 'title' ,
cls: 'clsRightTitle',
id: 'idIncidentEditorTitle',
title:"Welcome",
},
]
},
{ xtype: "fieldset",
items: [
{
xtype: 'textfield',
name: 'TKT_SUBJECT',
label: 'Subject',
labelAlign: 'top',
cls:'vm_fieldFont',
clearIcon:false,
disabled:true
},
{
xtype: 'textareafield',
name: 'TKT_DESC',
label: 'Description',
labelAlign: 'top',
cls:'vm_fieldFont',
clearIcon:false,
disabled:true
},
{
xtype: 'textfield',
name: 'SEV_DESC',
label: 'Impact',
labelWidth:'45%',
cls:'vm_fieldFont',
clearIcon:false,
disabled:true
},
{
xtype: 'textfield',
name: 'SERVICE_NAME',
id:'displayIncident',
cls:'vm_fieldFont',
label: 'IncidentType',
disabled: true,
labelWidth:'45%',
},
{
xtype: 'textfield',
label: 'Category',
name: 'CATEGORY_NAME',
cls:'vm_fieldFont',
id:'getCategory',
labelWidth:'45%',
disabled: true,
},
]
},
],
},
initialize: function() {
var getLoginData = localStorage.getItem('userData');
var parseData = JSON.parse(getLoginData);
var fname = parseData[0].FIRST_NAME;
Ext.getCmp("idIncidentEditorTitle").setTitle("Welcome, " + fname);
//var list = Ext.getCmp('idIncidentList');
//list.unmask();
},
onIncidentsListDisclose: function (list, record, target, index, evt, options) {
console.log("editIncidentCommand");
this.fireEvent('editIncidentCommand', this, record);
}
});
Controller:
Ext.define("Sample.controller.Incidents", {
extend: "Ext.app.Controller",
config: {
refs: {
//lookup for views by xtype
incidentsListView:'incidentslist',
incidentEditorView: 'incidenteditorview',
incidentsList: 'incidentsList',
listContainer:'listContainer'
},
control: {
incidentsListView: {
//commands fired by the Incidents list container.
editIncidentCommand: "onEditIncidentCommand",
},
}
},
//Transitions
slideLeftTransition: { type: 'slide', direction: 'left' },
slideRightTransition: { type: 'slide', direction: 'right' },
//Helper function(generates random integer)
getRandomInt: function (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
},
//Function to get incident details and set them to incidentview
activateIncidentEditor: function (record) {
var incidentContainer = this.getListContainer();
var incidentEditorView = Ext.create("Sample.view.IncidentEditor");
incidentEditorView.setRecord(record); // load() is deprecated.
incidentContainer.push(incidentEditorView);
},
//on edit incident command
onEditIncidentCommand: function (list, record) {
this.activateIncidentEditor(record);
}
});
Please help me guys ... Thanks in Advance ...!!!
I experience the same problems. Coding Sencha Touch 2 in MVC format makes the app's respond super-slow on "old" hardware. Especially Android. It's the drawback of HTML5 vs Native. However they claim the performance would increase when manually building the lib, I experienced almost no improvement.
On Android most performance based issues are related to Animations though. Try setting the show/hide animations to none and see if it improves.
You can also try setting the onBackButtonTap and other events on the controller though. That should improve the page rendering allot.
I had a similar problem, in my case the solution was this:
http://www.sencha.com/forum/showthread.php?184341-Best-practice-to-prevent-App-peformance-from-Slowly-degrading-after-drilling-around&p=900511&posted=1#post900511

Grid for Update Entries

I did the following code to list the searched items in the grid.
Ext.onReady(function(){
var rowEditing = Ext.create('Ext.grid.plugin.RowEditing');
var searchUsers = new Ext.FormPanel({
renderTo: "searchUsers",
frame: true,
title: 'Search Users',
bodyStyle: 'padding:5px',
width: 500,
items:[{
xtype:'textfield',
fieldLabel: 'Username',
name: 'userName'
}],
buttons:[
{
text:'Search',
formBind: true,
listeners: {
click: function(){
Ext.Ajax.request({
method:'GET',
url : url+'/lochweb/loch/users/getUser',
params : searchUsers.getForm().getValues(),
success : function(response){
console.log(response); //<--- the server response
Ext.define('userList', {
extend: 'Ext.data.Model',
fields: [{ name: 'id', mapping: 'id' },
{ name: 'name', mapping: 'name' },
{ name: 'firstName' ,mapping:'personalInfo.firstName'},
{ name: 'lastName' ,mapping:'personalInfo.lastName'}
]
});
var store = Ext.create('Ext.data.Store', {
model: 'userList',
autoLoad: true,
proxy: {
type: 'ajax',
url : url+'/lochweb/loch/users/getUser',
reader: {
type: 'json',
root: 'Users'
}
}
});
var grid = Ext.create('Ext.grid.Panel', {
renderTo: "searchUsers",
plugins: [rowEditing],
width: 900,
height: 300,
frame: true,
title: 'Users',
store: store,
iconCls: 'icon-user',
columns: [{
text: 'ID',
width: 40,
sortable: true,
dataIndex: 'id'
},
{
text: 'Name',
flex: 1,
sortable: true,
dataIndex: 'name',
field: {
xtype: 'textfield'
}
},
{
text: 'FirstName',
flex: 1,
sortable: true,
dataIndex: 'firstName',
field: {
xtype: 'textfield'
}
},
{
text: 'LastName',
flex: 1,
sortable: true,
dataIndex: 'lastName',
field: {
xtype: 'textfield'
}
}]
});
}
});
}
}
}
]
});
var win = new Ext.Window({
layout:'fit',
closable: false,
resizable: true,
plain: true,
border: false,
items: [searchUsers]
});
win.show();
});
How to Fit the grid inside the Search User window
Add an icon in the grid,so that by clicking on that icon the values from the
grid must be populated to entry form for update.
Here with your code, I've found something:
Use renderTo: "searchUsers" for both FormPanel and the Grid: You add the FormPanel to the window, so this config should not exist (Please refer to renderTo document). So remove them.
Use frame: true for both FormPanel and the Grid: There you have the window as container, so the Form and Grid have been framed inside. So remove them.
You dynamically add the Grid on searching: I recommend you create the result Grid as a separate component (not inside success's result) and specify both Form and Grid as items' components of window. You still can config the Grid with hidden. When Ajax is successful, you can fill the Grid with data returned and show it.
"add an icon in the grid": You can specify a new column in columns of the Grid and use renderer config of grid panel to show the button. For example:
renderer: function(v) {
return "<input type='button'.../>";
}
Finally, you can catch the itemclick event of the grid to know if the column of the clicked cell is the cell which contains the button, the entry will be populated to somewhere you want. Don't forget to specify the grid's Selection model as cellmodel

Adding a form to the timeline object in sencha touch

I have taken the form example from Sencha Touch API
var form = new Ext.form.FormPanel({
items: [
{
xtype: 'textfield',
name : 'first',
label: 'First name'
},
{
xtype: 'textfield',
name : 'last',
label: 'Last name'
},
{
xtype: 'numberfield',
name : 'age',
label: 'Age'
},
{
xtype: 'urlfield',
name : 'url',
label: 'Website'
}
]
});
and I have created a timeline object using
timeline = new Ext.Component({
title: 'Loan Details',
cls: 'timeline',
scroll: 'vertical',
tpl: ['<div></div>']
});
and then added the timeline to the panel as:
panel = new Ext.TabPanel({
fullscreen: true,
cardSwitchAnimation: 'slide',
ui: 'light',
items: [timeline]
});
How can I add the form object to the timeline? Like how I can show that on it? Where I should add it?
Thanks for the response in advance.
I'm not sure what you are trying to do. Are you trying to have some kind of continuous carousel where you will put the FormPanel?
If so you should extend the Ext.Panel to make that timeline object and then as item use the xtype:'fieldset' and have the form items there.
For example:
App.views.Timeline = Ext.extend(Ext.Panel, {
initComponent: function() {
Ext.apply(this, {
title: 'Loan Details',
cls: 'timeline',
scroll: 'vertical',
items:[
{
xtype: 'fieldset',
defaults: {
labelAlign: 'left',
labelWidth: 'auto',
}
items: [
{
xtype: 'textfield',
name : 'first',
label: 'First name'
},
{
xtype: 'textfield',
name : 'last',
label: 'Last name'
},
{
xtype: 'numberfield',
name : 'age',
label: 'Age'
},
{
xtype: 'urlfield',
name : 'url',
label: 'Website'
}
]
}
]
});
}});
the Ext.Component is for showing data through the data property. The data is display according to the template you provide i.e. the tpl property but you need to specify the property of the objects you want to show. For example tpl:<div>{text}</div> and data:[{text:'Example'}]