Is there any way to apply a template to the selected value of a ComboBox? I'm using a template to display the drop down values of the ComboBox, but as soon as i select one, the plain value from the datastore is shown.
{
id: 'requestStatusCombo',
hiddenName: 'requestStatus',
tpl: '<tpl for="."><div class="x-combo-list-item">{statusCode:requestStatus}</div></tpl>',
fieldLabel: 'Status',
xtype: 'combo',
mode: 'local',
triggerAction: 'all',
store: new Ext.data.ArrayStore({
fields: ['statusCode'],
data: [['unassigned'],['assigned'],['closed']]
}),
valueField: 'statusCode',
displayField: 'statusCode'
}
I want to use my format function requestStatus to translate the statusCodes into locale spesific status names, and this works well for the drop down list, but as soon as I select something, the statusCode is shown.
So is it possible to assign a template to the displayField, or perhaps do some simple batch modification on the datastore? By processing the input through a reader maybe? Is there another <tpl for="?"> keyword that will make this happen?
I'm looking for some simple method utilizing the Ext library. If the only solution is to pre process the data, I'm capable of doing that myself.
I found a solution!
I changed my datastore, and added a reader to pre-process the status using a convert function:
{
id: 'requestStatusCombo',
hiddenName: 'requestStatus',
fieldLabel: 'Status',
xtype: 'combo',
mode: 'local',
triggerAction: 'all',
store: new Ext.data.Store({
data: [['unassigned'],['assigned'],['closed']],
reader: new Ext.data.ArrayReader({},[
{name: 'statusCode', mapping: 0},
{name: 'displayname', mapping: 0, convert: function(statusCode) {
return Ext.util.Format.requestStatus(statusCode);
}}
])
}),
valueField: 'statusCode',
displayField: 'displayname'
}
Examinig generated DOM you will notice that while list elements are DIVs, the field itself is html INPUT element. You can't have HTML within INPUT element... so no... no xtemplate here.
This does not mean it can't be done by extending Ext.form.ComboBox (or Ext.Component maybe)
Related
Looking in the Docs for Sencha Touch there seems to be an option on the List widget that allows for setting "infinite" which enables infinite scroll.
Docs: https://docs.sencha.com/touch/2.3.1/#!/api/Ext.dataview.List-cfg-infinite
I am hoping this will resolve some issues that I have with performance with very large lists on portable devices.
Important Note: This is for an offline mobile app. As in the fiddle. The store already contains all of the data.
I tried enabling it on a large list but all it does is hide the data.
{
xtype: 'list',
store: 'contactStore',
flex: 1,
itemTpl: '<table><tr><td class="contact"><strong>{firstname}</strong> {lastname}</td></tr><tr><td>{companyname}</td></tr><tr><td>{address}, {city}, {province}, {postal}</td></tr><tr><td>{phone1}, {phone2}, {email}</td></tr><tr><td>{web}</td></tr></table>',
infinite: true /* Setting this to true hides the list */
}
What am I missing? I have included a jsFiddle.
http://jsfiddle.net/AnthonyV/bba58zfr/
The issue here isn't anything about the data being loaded like the other answers. You have said the data is being loaded into the store just fine as when you don't have infinite set to true you can see the data.
First, let's discuss what the infinite config does. As Anand Gupta explained, the infinite config will only render the number of list items that can fit on the screen (plus some as a buffer for scrolling). If you don't have it set to true then the list will render all items and not manage a visible range. With all items rendered, the list can support auto sizing. However, when infinite is set to true, the list needs to know what size it has in order to calculate the number of visible rows it can render.
This is where the issue happens, the list doesn't have a full size set to it. You have the list nested in a container and that container uses vbox layout:
config: {
title: 'Big List Issue',
fullscreen: true,
items: [{
xtype: 'container',
layout: 'vbox',
title: 'Big List',
items: [{
xtype: 'list',
store: 'contactStore',
id: 'simpleList',
flex: 1,
itemTpl: '<table><tr><td class="contact"><strong>{firstname}</strong> {lastname}</td></tr><tr><td>{companyname}</td></tr><tr><td>{address}, {city}, {province}, {postal}</td></tr><tr><td>{phone1}, {phone2}, {email}</td></tr><tr><td>{web}</td></tr></table>',
striped: true,
infinite: false
}]
}]
}
This is technically overnesting. Overnesting is when you have nested a component within a container that doesn't need to be nested within the container. This is an unnested version of your code that should work as you want:
config: {
title: 'Big List Issue',
fullscreen: true,
items: [{
xtype: 'list',
title: 'Big List',
store: 'contactStore',
id: 'simpleList',
itemTpl: '<table><tr><td class="contact"><strong>{firstname}</strong> {lastname}</td></tr><tr><td>{companyname}</td></tr><tr><td>{address}, {city}, {province}, {postal}</td></tr><tr><td>{phone1}, {phone2}, {email}</td></tr><tr><td>{web}</td></tr></table>',
striped: true,
infinite: true,
variableHeights: true
}]
}
What I did here is remove the container and had the list as a direct child of your MyApp.view.MyIssue navigation view. The navigation view uses card layout which will give each direct child 100% height and width and therefore allowing the list to calculate the number of rows it can render with infinite set to true. Here is a Sencha Fiddle to show this unnested list in action: https://fiddle.sencha.com/#fiddle/11v1
The other way, if you REALLY wanted the list to be nested in that container (the more you nest, the bigger the DOM since you have more components created and the bigger the DOM, the slower your app may respond) then you can give the container's vbox layout the align config:
config: {
title: 'Big List Issue',
fullscreen: true,
items: [{
xtype: 'container',
layout: {
type: 'vbox',
align: 'stretch'
},
title: 'Big List',
items: [{
xtype: 'list',
store: 'contactStore',
id: 'simpleList',
flex: 1,
itemTpl: '<table><tr><td class="contact"><strong>{firstname}</strong> {lastname}</td></tr><tr><td>{companyname}</td></tr><tr><td>{address}, {city}, {province}, {postal}</td></tr><tr><td>{phone1}, {phone2}, {email}</td></tr><tr><td>{web}</td></tr></table>',
striped: true,
infinite: true
}]
}]
}
In the unnested list example, I also use the variableHeights config on the list. This allows the list items to be properly heighted. Run the fiddle with it commented out to see the difference it makes.
You can go with this. Add this plugin, It handles automatically infinite scrolling.
http://docs.sencha.com/touch/2.4/2.4.0-apidocs/#!/api/Ext.plugin.ListPaging
For offline
You can implement an idea. Create 2 store one is fully loaded and second will load only with some page size suppose 10. You will use second store in your grid and implement list paging plugin, also pass here second store.
You can take help with this fiddle example. (this example is in Ext jS 5 but logic will be same)
https://fiddle.sencha.com/#fiddle/pim
Please try this one and let us know.
First you need to understand that infinite: true helps in improving list performance. It helps rendering only that chunk of list data which is the current page, rest are not rendered. So,
For pagination, you backend should support that like it should have parameter like limit, start, pageSize etc.
For implementing pagination, your store should have these configs like pageSize, buffered etc.
Hence if your backend support and you have implemented pagination. Then you can enjoy the benefit of infinite: true and get extreme sencha touch list performance.
I am accessing model data using the .find method but how to get records in JSON format from the model? I am getting output from .find() as: (Console log view)
Class {type: function, store: Class, isLoaded: true, isUpdating: true, toString: function…}
ember1375269653627: "ember313" __ember1375269653627_meta: Meta _super: undefined get content: function () { isLoaded: true isUpdating: false set content: function (value) { store: Class toString: function () { return ret; } type: Grid.ModalModel __proto: Object
I am new user of this community, so unable to upload image.
If you're using Ember Model, you do model.toJSON(). If you are trying to get values from the model you should use the getter model.get('name').
In javascript to create a JSON out of javascript object you may want to use:
JSON.stringify({name: "John"}); // => "{"name":"John"}"
It works pretty good for plain Ember.Objects. But you may not want to stringify all properties of given object. In such case you should use getProperties method of EmberObject. For example:
var john = Ember.Object.create({firstName: "John", lastName: "Doe", title: "CEO"});
JSON.stringify(john); // => "{"firstName":"John","lastName":"Doe", "title": "CEO"}"
var namesOnly = john.getProperties("firstName","lastName");
JSON.stringify(namesOnly); // => "{"firstName":"John","lastName":"Doe"}"
I've been trying to create an object to use in a jtable as the options (for a select list).
I don't seem to have the format correct. The jtable.org website says it will take an array:
From the jtable.org website:
http://jtable.org/ApiReference#fopt-options
PhoneType: {
title: 'Phone type',
options: [{ Value: '1', DisplayText: 'Home phone' }, { Value: '2', DisplayText: 'Office phone' }, { Value: '2', DisplayText: 'Cell phone' }]
}
However, when I create an object like that:
var optionsObject = [];
optionsObject.push({Value: i, DisplayText: 'Hello' + i});
and then use it as a variable for the options in my jtable:
key: true,
options: optionsObject,
I don't get the items in the select list drop down. I do get something in the select list, but that looks like '[object Object]' instead of the actual items.
I'm not really sure what I'm doing wrong.
If I send an object that looks like this:
object.push('hello' + i);
I will get an item in the select list that looks like this 'hello0', as expected, but then the display text is also used as the value. I need to have an object with separate display texts and values.
Has anybody had any success with doing this?
After much trial and error, and debugger stops in the jtable scripting files, I learned that in order to use an object for the 'options' property of a field in jtable, the object must be in the following format
var optionsObject = new Object();
optionsObject[Value] = DisplayText;
I'm creating an app with some custom gauges using Rally SDK 2.0. This requires some custom HTML. I took a rake-compiled app.html file from the examples as a starting point. Using JustGage for my gauges. Here is my launch function.
launch: function () {
var info = this.getStoriesForProject(); //Gets some aggregate info
$('#header label').html(info.Title);
var g = new JustGage({
id: "devgauge",
value: info.DevPercent,
levelColors: ['#f80404', '#f8f804', '#50ed0e'],
min: 0,
max: 100,
title: "Dev %"
});
this.add('foo');
},
Then I added some custom HTML in app.html.
Now, if i run this without the code "this.add('foo')", the app adds a new div in the body with class="x-container" and puts my custom HTML outside that div effectively hiding it.
If i use the "this.add('foo') it does NOT create the div class=x-container and it shows my widget just fine.
What is the PROPER way to accomplish what I'm attempting using the 2.0 sdk? I realize the add method is for adding Ext components, but somehow calling this is causing my HTML to render ok. Looking at some apps we developed in the old SDK, using the custom HTML worked just fine in those.
Ext likes to know what is going on layout-wise and often gets confused if you're manually manipulating the dom beneath it without its knowledge. Usually if we have some known set of initial layout we add those via the items collection on the app:
Ext.define('My.App', {
extend: 'Rally.app.App',
items: [
{
xtype: 'container',
itemId: 'header'
},
{
xtype: 'container',
itemId: 'devguage'
}
]
});
Then inside of launch you can add content to those like so:
this.down('#devguage').add({
//some other component
});
You can always just drop all the way down to the element level though as well:
this.down('#header').getEl().dom //the raw html element
By default apps use an auto layout, so any items should flow as you would expect with normal html.
Or, instead of using itemId, you can set the id of the container's element using its id property:
Ext.define('My.App', {
extend: 'Rally.app.App',
items: [
{
xtype: 'container',
id: 'header'
},
{
xtype: 'container',
id: 'devguage'
}
]
});
The resulting html elements will use those ids, which allows you to target them directly with your own custom rendering.
I'm a newbie to all the Sencha Touch stuff, but until now I'm very enthousiastic about it's capabilities. There is one problem, i somehow can't solve.
I would like to use a Tpl (XTemplate) for a calender view. The idea is to create a div element for every appointment, which i can place within containers to layout them. Somehow i can't get the dataview to work.
I've stripped down my code to the bare minimum: a panel containing a DataView. When i use the itemTpl, everything works fine. But when I use the tpl (with or without the XTemplate) i don't see anything. I checked if it was just a display malfunction (searched for the XXX from the template), but that's not the case.
This is my code:
Ext.define('InfoApp.view.CalendarDay', {
extend: 'Ext.Panel',
xtype: 'calendarday',
requires: [ 'InfoApp.store.sAppointments'],
config: {
title: 'Dag',
layout: 'fit',
items: [
{
xtype: 'dataview',
store: 'appointmentStore',
//itemTpl: [ 'XXX {day} {course}' ] --> Works
tpl: new Ext.XTemplate('<tpl for=".">XXX {day} {course}</tpl>')--> Doesn't Work...
}
]
}
});
Thanks in advance for any suggestions or improvements!
Assuming ST2 and not ST1
From http://docs.sencha.com/touch/2-0/#!/api/Ext.Component-cfg-tpl and the comments on the tpl: config in the docs, it appears there's a bug when using a remote store. Even if your store has data it. tpl: apparently only works right now if your data is hardcoded in data:[]
you can use itemTpl: new XTemplate(), or itemTpl: XTemplate.from('someid') or you can defer specifying until afterwards, grab your dataview and go dv.setItemTpl(new XTemplate()), etc.
Tanks #brink for your answer.
It took me a couple of days, but this worked for me:
// Load the store
var store = Ext.getStore('appointmentStore');
// Get the current range of the store
var data = store.getRange();
// Create a custom template
var tpl = new Ext.XTemplate(<tpl for=".">{day} {course}</tpl>);
// Loop through the data array
var showData = array();
for(var i=0;i<data.length;i++){
showData.push(data[i].data);
}
// Get the panel by ID and push the html template
var panel = Ext.getCmp('appointmentspanel');
panel.updateHtml(tpl.applyTemplate(showData));