I'm new to Sencha Touch...
I've been searching and asking people for hours, but cannot figure out why my detail view does not get the data (using setRecord).
I have not been able to find an example that uses Ext.NavigationView to push a view that uses the data from setRecord, so I suspect I'm doing something wrong there.
I have a tabbed view. First tab shows a list of items. Click an item disclosure to see details for that item. The detail view appears, but with no any data.
The tabs are setup in the launch function of ViewPortController.
The main view in the first tab is the PeopleListView. All the people appear in the list.
The PeopleListView is added to an Ext.NavigationView. A reference to the Ext.NavigationView is added to the PeopleListView so it can be used later
PeopleListViewController has a function, showDetailView, that is successfully called when a disclosure button is tapped.
The controller's showDetailView function
sets the record (which contains the correct data) on the personDetailView,
retrieves the instance of the Ext.NavigationView and pushes the PersonDetailView.
The record value passed to showDetailView has the correct data.
When personDetailView appears, the fields have no data.
ViewPortController:
launch: function() {
// var personDetailView = {
// xtype: 'persondetailview'
// }
var pplView = Ext.create('PeopleApp.view.PeopleListView');
var pplNavView = Ext.create('Ext.NavigationView', {
title: 'People',
iconCls: 'home',
useTitleForBackButtonText: true,
});
pplView.setNavigationView(pplNavView);
pplNavView.add(pplView);
. . .
var mainViewPort = getMainViewPort();
mainViewPort.setItems([pplNavView, . . .]);
},
PersonModel:
Ext.define('PeopleApp.model.PersonModel', {
extend: 'Ext.data.Model',
requires: ['Ext.data.proxy.Rest'],
config: {
idProperty: 'id',
fields: [
{ name: 'id', type: 'auto' },
{ name: 'name', type: 'string' },
{ name: 'address', type: 'string' },
{ name: 'email', type: 'string' },
{ name: 'age', type: 'int' },
{ name: 'gender', type: 'string' },
{ name: 'note', type: 'string' }
],
proxy: {
type: 'rest',
url: '/app/data/people.json',
reader: {
type: 'json',
rootProperty: 'people'
}
},
}
});
PeopleListViewController:
Ext.define('PeopleApp.controller.PeopleListViewController', {
extend: 'Ext.app.Controller',
xtype: 'peoplelistviewcontroller',
config: {
refs: {
peopleListView: 'peoplelistview',
personDetailView: 'persondetailview',
peopleView: 'peopleview',
},
control: {
peopleListView: {
discloseDetail: 'showDetailView'
}
}
},
showDetailView: function(view, record) {
console.log("record.data.name=" + record.data.name);
var detailView = Ext.create('PeopleApp.view.PersonDetailView');
//var detailView = this.getPersonDetailView();
detailView.setRecord(record);
var navView = view.getNavigationView();
navView.push(detailView);
},
launch: function() { this.callParent(arguments); },
init: function() { this.callParent(arguments); },
});
PersonDetailView:
Ext.define('PeopleApp.view.PersonDetailView', {
extend: 'PeopleApp.view.BaseView',
xtype: 'persondetailview',
requires: [
'Ext.form.FieldSet',
'Ext.form.Text',
'Ext.form.TextArea'
],
config: {
title: "Person Details",
scrollable: true,
items: [{
xtype: 'fieldset',
items: [{
xtype: 'textfield',
name: 'name',
label: 'Name: ',
required: true
}, {
xtype: 'textfield',
name: 'age',
label: 'Age: ',
required: false
}, // etc.
]}
]}
});
Can you tell me why detailView.setRecord(record) does not get the data set in the fields of DetailViewController, and what I need to do differently?
I am not sure but you should use below code in your Person detail view:
items: [
{
xtype:'formpanel',
id:'personDetailViewForm',
items:[{
xtype: 'fieldset',
items: [{
xtype: 'textfield',
name: 'name',
label: 'Name: ',
required: true
}, {
xtype: 'textfield',
name: 'age',
label: 'Age: ',
required: false
}, // etc.
]
}]
}]
and in the personListViewController you can set that form's values instead of setting records to the view like:
var detailView = Ext.create('PeopleApp.view.PersonDetailView');
var personDetailViewForm = detailView.down('#personDetailViewForm ');
personDetailViewForm .setValues(records);
Note that records object property names and form fields names must match and if records doesn't work try with records.data.
Related
Is there a way to dynamically populate a combobox with the attributes a certain property of an artifact can take on?
e.g.
I have a custom field set up on User Stories. I want to be able to populate a combobox with all the possible values for this custom field without hard-coding it in.
In the code below the combobox is automatically populated with the allowed values of the custom field of dropdown type:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
items: [
{
xtype: 'container',
itemId: 'kbFilter'
},
{
xtype: 'container',
itemId: 'grid',
width: 800
}
],
launch: function() {
this.down('#kbFilter').add({
xtype: 'checkbox',
cls: 'filter',
boxLabel: 'Filter table by custom field',
id: 'kbCheckbox',
scope: this,
handler: this._onSettingsChange
});
this.down('#kbFilter').add({
xtype: 'rallyattributecombobox',
cls: 'filter',
model: 'Defect',
field: 'MyKB',
listeners: {
ready: this._onKBComboBoxLoad,
select: this._onKBComboBoxSelect,
scope: this
}
});
},
_onKBComboBoxLoad: function(comboBox) {
this.kbComboBox = comboBox;
Rally.data.ModelFactory.getModel({
type: 'Defect',
success: this._onModelRetrieved,
scope: this
});
},
_getFilter: function() {
var filter = [];
if (Ext.getCmp('kbCheckbox').getValue()) {
filter.push({
property: 'MyKB',
operator: '=',
value: this.kbComboBox.getValue()
});
}
return filter;
},
_onKBComboBoxSelect: function() {
if (Ext.getCmp('kbCheckbox').getValue()) {
this._onSettingsChange();
}
},
_onSettingsChange: function() {
this.grid.filter(this._getFilter(), true, true);
},
_onModelRetrieved: function(model) {
this.grid = this.down('#grid').add({
xtype: 'rallygrid',
model: model,
columnCfgs: [
'FormattedID',
'Name',
'MyKB'
],
storeConfig: {
context: this.context.getDataContext(),
filters: this._getFilter()
},
showPagingToolbar: false
});
}
});
In this example I have a dropdown field with Name: myKB and Display Name: My KB.
In the WS API the name shows with prepended c_, as in c_myKB.
However, if I use c_myKB this error comes up:
Uncaught Rally.ui.combobox.FieldValueComboBox._populateStore(): field config must be specified when creating a Rally.ui.combobox.FieldValueComboBox
Use the display name of the field, without spaces.
Here is a screenshot showing this app in action:
I'm learning Sencha Touch. I created this app with a form before and it worked fine.
Now i'm working on a new little test app i copy the code from the other app and it only passes empty variables to the webservice.
the View:
<!-- language: lang-js -->
Ext.define('Gasoline.view.InsertTankTrip', {
requires: [
'Ext.form.FieldSet'
],
extend: 'Ext.form.Panel',
xtype: 'inserttankpanel',
id: 'insertTankForm',
config: {
title: 'Insert Tank Trip',
iconCls: 'add',
url: 'contact.php',
items:[
{
xtype: 'fieldset',
title: 'Insert Tank Trip',
instructions: '(Make sure the info is correct!)',
items:[
{
xtype: 'datepickerfield',
label: 'Date',
name: 'date',
value: new Date()
},
{
xtype: 'textfield',
label: 'Amount',
name: 'amount',
minValue:-9007199254740992,
maxValue: 9007199254740992
}
]
},{
xtype: 'button',
text: 'Send',
ui: 'confirm',
action: 'insertTankSubmit'
}
]
}
});
And in the controller :
launch: function() {
// Destroy the #appLoadingIndicator element
Ext.fly('appLoadingIndicator').destroy();
// Initialize the main view
Ext.Viewport.add(Ext.create('Gasoline.view.Main'));
this.control({
'button[action=insertTankSubmit]' : {
tap: 'insertTankForm'
}/*,
'list[itemId=kingsLeagueList]' : {
itemtap: 'onListTap'
},
'list[itemId=tournamentsList]' : {
disclose: 'showDetail'
}*/
});
},
insertTankForm : function(){
console.log('test');
var form = this.getInsertTankForm();
form.submit({
url:'contact.php'
});
},
This sends the following to the webservice (which currently doesn't exist i just check with developer tools)
date:2012-07-26T17:02:16
amount:
so the date does get sent , the number doesnt
If i fill in a standard value for the number ... that gets sent but if you type something in , it still doesn't send that
Use
xtype: 'numberfield'
instead of
xtype: 'textfield'
I had tried numerous solutions...none of them worked.
Lastly i deleted everything ... coded everything the exact same way and it started working ...
I am creating my first app with sencha touch.
I have a problem with form validation.
This is the form:
var form = new Ext.form.FormPanel({
title: 'Activity',
items: [{
xtype: 'fieldset',
items: [{
xtype: 'textfield',
name : 'sector',
label: 'Sector',
required: true
},
{
xtype: 'selectfield',
name : 'city',
label: 'City',
options: [
{
text: '*',
value: '*'
},
{
text: 'First Option',
value: 'first'
},
{
text: 'Second Option',
value: 'second'
},
{
text: 'Third Option',
value: 'third'
}]
},
{
xtype: 'textfield',
name : 'nation',
label: 'Nation',
required: true
},
{
xtype: 'toolbar',
docked: 'bottom',
layout: {
pack: 'center'
},
items: [{
xtype: 'button',
text: 'Cerca',
handler: function() {
formSettori.submit({
url: 'book.php',
method: 'GET',
success: function() {
Ext.Msg.alert('OK');
},
failure: function() {
Ext.Msg.alert('NO');
}
});
}
},
{
xtype: 'button',
text: 'Reset',
handler: function() {
form.reset();
}
}]
}]
}]
});
the form has only three fields:
-activities
-city
-nation
all fields are required.
activities and the nation must not be empty, while the city should not be equal to *
how do I control the fields?
thank you!
There is not built in way to do form validation. You must do it yourself.
The easiest way is to use the private Ext.form.Panel method getFields to loop through each of the fields and ensure they are not empty.
var fields = form.getFields(),
field, name, isEmpty;
for (name in fields) {
field = fields[name];
isEmpty = (!field.getValue() || field.getValue() == "");
if (isEmpty) {
field.addCls('x-invalid');
} else {
field.removeCls('x-invalid');
}
}
If the field is empty, then we add the x-invalid class (so you can style it).
I'm a new sencha learner , what i want to do is adding an image to the nested list text.
I tried to modify kithcensink exapmle code,This is my nestedlist
Ext.require('Ext.data.TreeStore', function() {
Ext.define('Kitchensink.view.NestedList', {
requires: ['Kitchensink.view.EditorPanel', 'Kitchensink.model.Kategori'],
extend: 'Ext.Container',
config: {
layout: 'fit',
items: [{
xtype: 'nestedlist',
store: {
type: 'tree',
id: 'NestedListStore',
model: 'Kitchensink.model.Kategori',
root: {},
proxy: {
type: 'ajax',
url: 'altkategoriler.json'
}
},
displayField: 'text',
listeners: {
leafitemtap: function(me, list, index, item) {
var editorPanel = Ext.getCmp('editorPanel') || new Kitchensink.view.EditorPanel();
editorPanel.setRecord(list.getStore().getAt(index));
if (!editorPanel.getParent()) {
Ext.Viewport.add(editorPanel);
}
editorPanel.show();
}
}
}]
}
});
});
I modified the store file
var root = {
id: 'root',
text: 'Lezzet Dünyası',
items: [
{
text: 'Ana Menü',
id: 'ui',
cls: 'launchscreen',
items: [
{
text: 'Et Yemekleri',
leaf: true,
view:'NestedList3',
id: 'nestedlist3'
},
{
text: 'Makarnalar',
leaf: true,
view: 'NestedList2',
id: 'nestedlist2'
},
{
text: 'Tatlılar',
leaf: true,
view: 'NestedList4',
id: 'nestedlist4'
},
{
text: 'Çorbalar',
view: 'NestedList',
leaf: true,
id: 'nestedlist'
}
]
}
]
};
How should I edit the code to add image near the nested list text ?
For example , in this site you can see a nested list example , I need an images near Blues,Jazz,Pop,Rock.
Generally, you can do more than what you need by customizing your getItemTextTpl (place it into your Ext.NestedList definition, for example:
getItemTextTpl: function(node) {
return '<span><img src="image_url" alt="alternative_text">{text}</span>';
}
Define whatever template you like through that returning string.
The controller function
startpage:function(a){
var model1 = this.store.getAt(a.index);
App.views.start.load(model1);
App.views.viewport.reveal('start');
},
how to get the loaded model1 values in the start page
how can i able to pass parameter from controller to a page
App.views.start = Ext.extend(Ext.form.FormPanel, {
initComponent: function(){}
}
As your extending the FormPanel, I believe Sencha will pre-populate your fields.
Your code will looking something similar to this:
App.views.start = Ext.extend(Ext.form.FormPanel, {
initComponent: function(){
var fields = {
xtype: 'fieldset',
id: 'a-form',
title: 'A Form',
instructions: 'Some instructions',
defaults: {
xtype: 'textfield',
labelAlign: 'left',
labelWidth: '40%'
},
items: [
{
name : 'title',
label: 'title',
xtype: 'textfield'
},
{
name: 'email',
label: 'email',
xtype: 'emailfield'
}
]
};
Ext.apply(this, {
scroll: 'vertical',
items: [ fields ]
});
App.views.start.superclass.initComponent.call(this);
}
}
Ext.reg('App.views.start', App.views.start);
Note that you will have to substitute in your actual fields and you'll probably need to customise the form somewhat.