Creating multiple instance of a view - sencha-touch

Using Sencha Touch ver 2.3.1a
The carousel control in PassDownEntryView
{
xtype: "container",
itemId: "pageEntryItemsContainer",
layout: "fit",
items:
[
{
xtype: "carousel",
itemId: "carouselItems",
direction: "horizontal",
items:
[
]
}
]
}
I'm creating multiple instances of a view for a carousel
var data = JSON.parse(response.responseText);
var itemViewArray = [];
var index = 0;
Ext.Array.each(data.Data, function(item)
{
var itemView = Ext.create('MCConnect.view.PassDown.PassDownEntryItemView');
itemView.setItemId('EntryItemId' + index);
itemView.configureEntry(item);
itemViewArray.push(itemView);
index++;
});
if(itemViewArray.length > 0)
{
carouselControl.setItems(itemViewArray);
}
configureEntry sets the html in the PassDownEntryItemView
{
xtype: "label",
html: ""
}
Code that sets the label:
configureEntry: function(item)
{
var fieldLabel = Ext.ComponentQuery.query('label')[0];
fieldLabel.setHtml("<div style='text-align: center; padding-top: 5px; padding-bottom: 5px;'><span>" + item.item + "</span></div>");
}
It creates the right number of carousels but only the first instance has the label set. The rest of them are blannk. I did an output of configureEntry() and
it is properly passwing each item. Seems like im missing something when setting it. Any ideas?
Update: 6/21 - A
It seems like the problem is the instance of the view. Cause When I create a hard coded view:
var item1 =
{
item: "test1"
}
var itemView = new MCConnect.view.PassDown.PassDownEntryItemView();
itemView.configureEntry(item1);
var item2 =
{
item: "test2"
}
var itemView1 = new MCConnect.view.PassDown.PassDownEntryItemView();
itemView1.configureEntry(item2);
carouselControl.setItems([itemView, itemView1]);
I still get the result that only "Test2" shows even though there are two carousel panels showing up. Except the second one is blank
Update 6/22
Ive added my PassDownEntryItemView code below:
Ext.define('MCConnect.view.PassDown.PassDownEntryItemView',
{
extend: 'Ext.form.Panel',
xtype: 'passdownEntryItemView',
requires:
[
'Ext.data.Store',
"Ext.field.Text",
"MCConnect.view.Commons.AutoHeightTextArea"
],
config:
{
itemId: '',
isReadOnly: true,
passDownEntryItemId: 0,
layout: "vbox",
items:
[
{
xtype: 'fieldset',
style: 'padding: 0; margin: 1px;',
items:
[
{
xtype: "label",
html: ""
}
]
}
],
listeners:
[
]
},
initialize: function()
{
},
configureEntry: function(item)
{
this.setPassDownEntryItemId(item.passDownEntryId);
var fieldLabel = Ext.ComponentQuery.query('label')[0];
fieldLabel.setHtml("<div style='text-align: center; padding-top: 5px; padding-bottom: 5px;'><span>" + item.item + "</span></div>");
}
});
6/22
Thanks to Akatum suggestion. I figured it out. I labeled the itemId of the label as #labelDistrictItem-0 so in my configureEntry() i searched for it then set it and renamed the itemId:
var fieldLabel = Ext.ComponentQuery.query('passdownEntryItemView #labelDistrictItem-0')[0];
fieldLabel.setItemId('labelDistrictItem-' + item.id);
fieldLabel.setHtml("<div style='text-align: center; padding-top: 5px; padding-bottom: 5px;'><span>" + item.item + "</span></div>");
and it works now

Problem is in your configureEntry function. var fieldLabel = Ext.ComponentQuery.query('label')[0]; will always returns first label component in your whole application. So in your case it will always returns label which is in your first carousel panel.
Instead of using Ext.ComponentQuery.query('label')[0]; you should look for specific label in specific MCConnect.view.PassDown.PassDownEntryItemView by using up() or down() methods (depends on layout of your application).
Edit
You can get your label component by looking for it only in child components of your PassDownEntryItemView. For this you can use down() method. So your configureEntry method should look like this:
configureEntry: function(item) {
this.setPassDownEntryItemId(item.passDownEntryId);
var fieldLabel = this.down('label');
fieldLabel.setHtml("<div style='text-align: center; padding-top: 5px; padding-bottom: 5px;'><span>" + item.item + "</span></div>");
}
Fiddle with working example: https://fiddle.sencha.com/#fiddle/6t4

Related

dgrid onDemandGrid renders larger than the space it's in, therefore causing vertical scrolling

I'm trying to render the dgrid without the vertical scrollbar showing up, but for some reason, it always renders larger than the space it's in.
When the grid loads, it renders at 400x300 even though the space is only 300x200 which then causes vertical scrolling. How do I prevent that?
addGrid: function () {
this.grid = (declare([OnDemandGrid, Selection]))({
id: "tgrid" + this.reportId,
loadingMessage: 'Loading data...',
noDataMessage: 'No results found.',
allowTextSelection: true,
scroller: true,
collection: new Memory({
idProperty: "id"
}),
columns: {
trackName: "Name",
urn: {
label: "URN",
renderCell: function(object, value, cell) {
if(typeof value === 'undefined' ) {
cell.bgColor = "red";
} else {
cell.innerHTML = value;
}
}
},
location: "Location",
affiliation: "Affiliation",
eta: "ETA",
lta: "LTA"
}
}, this.gridId);
//next get the tracks using this call
this.getTracks();
}
.dgrid {
height: auto;
}
.dgrid-row {
padding: 3px 0 2px 9px;
}
.dgrid-scroller {
position: relative;
overflow: auto;
max-height: 95%;
}

Sencha Touch - Custom Component not functioning well on 'production' build

I have the following custom component build
Ext.define('TRA.view.MainMenuItemView', {
xtype: 'mainmenuitem',
extend: 'Ext.Container',
text: 'Menu text',
icon: './resources/icons/Icon.png',
tap: function(){
},
config: {
layout: {
type: 'vbox',
pack: 'center',
align: 'center'
},
items: [
{
width: '115px',
height: '115px',
style: 'border-radius: 50%; background-color: #e4e4e6',
items: [
{
xtype: 'image',
src: '',
width: '65px',
height: '65px',
centered: true
}
]
},
{
xtype: 'label',
html: '',
margin: '5px 0',
style: 'color: #455560; text-align: center; text-transform: uppercase; font-weight: bold;'
}
]
},
initialize: function() {
var me = this;
me.callParent(arguments);
//set icon
me.getAt(0).getAt(0).setSrc(me.icon);
//set text
me.getAt(1).setHtml(me.text);
//setup componet event
me.element.onAfter('tap', me.tap);
}
})
and I'm using it on other containers as this
{
xtype: 'mainmenuitem',
text: 'Signal Coverage',
icon: './resources/images/icon-signal-coverage.png',
tap: function() {
var nav = Ext.ComponentQuery.query('#mainnavigationview')[0];
nav.push({
title: 'Signal Coverage',
html: 'test Signal Coverage'
});
}
}
Quite strangely it all works all well normally except when I build the sencha app for native or for web build using sencha cmd
sencha app build production
the production version does not overwrite icon and text properties of my custom component. while it all works well on normal version. what could be issue?
first of all, some ideas to make your code easier readable for others:
1) the first item does neither have an xtype nor does a defaultType define it
2) width: '115px', height: '115px', just could be width:115,height115
3) instead of me.getAt().getAt() define an itemId for these and use me.down('#theItemId')
3a) or use Ext.Component to extend from and add a template with references. That way it's me.referenceElement
4) me.onAfter('tap',... not sure if this will work on an item that does not support the tap event. you might need to set a tap event to me.element and from there you can use a beforetap
5) instead of add me.getAt().getAt().setText(me.text) use the updateText: function(newValue) {this.getAt().getAt().setText(newValue)}
Same for the icon
then my personal opion
Personally I never expected this code to run anyways. But the fix might be to write me.config.icon and me.config.text
Solution
It's a matter of timing. While the constructor runs there are no icon or text defined inside the config.
This happends only on initialize. there you have them inside the config.
go and add icon: null, text: '' to the config of the component and it will word with getter and setter.

Rally 2.0 JavaScript API - Creating HTML tables and setting values dynamically

I'm using Custom HTML Rally Grid to develop a table that must return some statistics. My JavaScript is being called at the head of my HTML and i'm creating a table in the body tag. So, my JavaScript is setting values in the table using the fields ids. The problem is: the table is being loaded but when the Rally.launchApp method runs, the table disappears. Curiously, if i check the font-code, the table still there.
<!DOCTYPE html>
<html>
<head>
<title>Grid With Freeform Data Example</title>
<script type="text/javascript" src="/apps/2.0rc1/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function() {
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
var firstMetricResult;
var secondMetricResult;
var firstMetricName = "% of user stories assigned story points";
var secondMetricName = "Average story points per user story ";
var currentProjectName = Rally.environment.getContext().getProject().Name;
var currentProjectNameID = document.getElementById("currentProjectNameID");
currentProjectNameID.value = currentProjectName;
var benchmark = 20;
var storiesQuery = Ext.create('Rally.data.WsapiDataStore', {
model: 'UserStory',
fetch: ['PlanEstimate', 'LastUpdateDate'],
filters: [
{property: 'ScheduleState',
operator: '=',
value: 'Accepted'},
{property: 'DirectChildrenCount',
operator: '=',
value: '0'},
{property: 'AcceptedDate',
operator: '<',
value: 'LastMonth'},
{property: "Iteration.Name",
operator: "!contains",
value: "hardening"},
{property: "Iteration.Name",
operator: "!contains",
value: "regression"},
{property: "Iteration.Name",
operator: "!contains",
value: "stabilization"}
]
});
storiesQuery.load({
callback: function(records, operation) {
if(operation.wasSuccessful()) {
var estimatedStoriesCount = 0;
Ext.Array.each(records, function(record){
if (record.get('PlanEstimate') != null){
estimatedStoriesCount++;
}
});
var storiesCount = records.length;
firstMetricResult = (estimatedStoriesCount*100)/storiesCount;
alert(firstMetricResult);
}
}
});
var estimatedStoriesQuery = Ext.create('Rally.data.WsapiDataStore', {
model: 'UserStory',
fetch: ['PlanEstimate', 'LastUpdateDate'],
filters: [
{property: 'PlanEstimate',
operator: '!=',
value: 'null'},
{property: 'ScheduleState',
operator: '=',
value: 'Accepted'},
{property: 'DirectChildrenCount',
operator: '=',
value: '0'},
{property: 'AcceptedDate',
operator: '<',
value: 'LastMonth'}
]
});
estimatedStoriesQuery.load({
callback: function(records, operation) {
if(operation.wasSuccessful()) {
var astoriesCount = records.length;
var storiesPointsSum = 0;
Ext.Array.each(records, function(record){
storiesPointsSum += record.get('PlanEstimate');
});
secondMetricResult = storiesPointsSum/astoriesCount;
alert(secondMetricResult);
}
}
});
}
});
Rally.launchApp('CustomApp', {
name: 'Grid With Freeform Data Example'
});
});
</script>
<style type="text/css">
table.gridtable {
font-family: verdana,arial,sans-serif;
font-size:11px;
color:#333333;
border-width: 1px;
border-color: #666666;
border-collapse: collapse;
}
table.gridtable th {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #dedede;
}
table.gridtable td {
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #666666;
background-color: #ffffff;
}
</style>
</head>
<body>
<table border=1 class='gridtable' id="tab1">
<tr>
<th> Team </th>
<td><b>All prior periods</b></td>
<td><b>All prior periods</b></td>
</tr>
<tr>
<td id="currentProjectNameID">
</td>
</tr></table>
</body>
</html>
I decided to use this simple HTML table because i want to have the power to edit the CSS.
Thanks.
The above answer is correct. Generally when working with apps (and ExtJS) most content is created through javascript rather than literally declared dom.
Check out this guide for a little more info on working with content in apps: https://developer.help.rallydev.com/apps/2.0rc1/doc/#!/guide/add_content
Something like this should work though if you're still sold on the manual dom manipulation:
launch: function() {
this.add({
xtype: 'component',
html: [
'<table border=1 class="gridtable" id="tab1">',
'<tr>',
'<th> Team </th>',
'<td><b>All prior periods</b></td>',
'<td><b>All prior periods</b></td>',
'</tr>',
'<tr>',
'<td id="currentProjectNameID"></td>',
'</tr>',
'</table>'
].join('')
});
},
afterRender: function() {
this.callParent(arguments);
//the rest of your code that used to be in launch here
}
Then you should be able to look up the elements by id and manipulate them as you'd like.
You would still be able to modify the CSS if you used an Ext grid or a rallygrid - besides using normal CSS selectors to style the grid, you also have access to certain properties when creating the grid - the renderer function for a column takes meta as its second parameter, which has an attribute called tdCls which you can use to style cells in that column. For example:
.green > .x-grid-cell-inner {
border : 1px solid #afd3b6;
background : #c6efce;
background : -moz-linear-gradient(top, #c6efce 0%, #afd3b6 100%);
background : -webkit-gradient(linear, left top, left bottom, color-stop(0%,#c6efce), color-stop(100%,#afd3b6));
background : -webkit-linear-gradient(top, #c6efce 0%,#afd3b6 100%);
background : -o-linear-gradient(top, #c6efce 0%,#afd3b6 100%);
background : -ms-linear-gradient(top, #c6efce 0%,#afd3b6 100%);
background : linear-gradient(to bottom, #c6efce 0%,#afd3b6 100%);
filter : progid:DXImageTransform.Microsoft.gradient( startColorstr='#c6efce', endColorstr='#afd3b6',GradientType=0 );
}
{
text : 'State',
dataIndex : 'c_WINListState',
editor : 'stateeditor',
renderer : function(value, meta, record) {
if (value === 'At Risk') {
meta.tdCls = 'yellow';
} else if (value === 'Off Track') {
meta.tdCls = 'red';
} else if (value === 'On Track') {
meta.tdCls = 'green';
} else if (value === 'Complete') {
meta.tdCls = 'grey';
}
return value;
}
},
I would recommend using the built in functionality.
That being said, I think this is the reason for the built in functionality - if you look at the SDK, the launch app function states:
Create and execute the specified app. Ensures all required components have been loaded and the DOM is ready before app code begins executing. As soon as all required dependencies have been loaded the launch method will be called.

SenchaTouch onItemDisclosure 2 icons

I have a list and I want have two icons per line using onItemDisclosure. How can I do that?
I don't know how to implement onItemDisclousre() on two icons but probably this will help you.
In the following example i have put an image on every itemlist and functionality is provided on itemtap event. This will serve the purpose of doing multiple tasks with single itemlist.
//demo.js
Ext.define("Stackoverflow.view.demo", {
extend: "Ext.Container",
requires:"Ext.dataview.List",
alias: "widget.demo",
config: {
layout: {
type: 'fit'
},
items: [
{
xtype: "list",
store: "store",
itemId:"samplelist",
loadingText: "Loading Notes...",
emptyText: "<div class=\"notes-list-empty-text\">No notes found.</div>",
onItemDisclosure: true,
itemTpl:"<div class='x-button related-btn' btnType='related' style='border: none; background: url(\"a.png\") no-repeat;'></div>"+
"<div class=\"list-item-title\">{title}</div>"
grouped: true
}
],
listeners:
[
{
delegate: "#samplelist",
event: "disclose",
fn: "onDiscloseTap"
}
]
},
onDiscloseTap: function (list, record, target, index, evt, options) {
this.fireEvent('ondisclosuretap', this, record);
}
});
// Democontrol.js
Ext.define("Stackoverflow.controller.Democontrol", {
extend: "Ext.app.Controller",
config: {
refs: {
// We're going to lookup our views by xtype.
Demo: "demo",
Demo1: "demo list",
},
control: {
Demo: {
ondisclosuretap: "Disclosure",
},
Demo1: {
itemtap:"imagetap"
}
}
},
Disclosure: function (list, record,target,index,e,obj) {
Ext.Msg.alert('','Disclosure Tap');
},
imagetap: function (dataview,index,list,record, tar, obj) {
tappedItem = tar.getTarget('div.x-button');
btntype = tappedItem.getAttribute('btnType');
if(btntype == 'related')
{
Ext.Msg.alert('','Image/Icon Tap');
}
},
// Base Class functions.
launch: function () {
this.callParent(arguments);
},
init: function () {
this.callParent(arguments);
}
});
//app.css
.related-btn
{
width: 100px;
height: 100px;
position: absolute;
bottom: 0.85em;
right: 2.50em;
-webkit-box-shadow: none;
}
Hope this will help you.
bye.
You can do this by manually adding a disclosure icon inside of itemTpl on your list items. Add this inside of your view:
{
xtype: 'list',
onItemDisclosure: true,
cls: 'my-list-cls',
itemTpl: [
'<div class="x-list x-list-disclosure check-mark" style="right: 48px"></div>'
]
}
Notice that the div inside of itemTpl has the CSS class "x-list x-list-disclosure check-mark". I set style="right: 48px" because I want this icon to appear on the left side of the regular disclosure icon (the one with the right arrow) and this rule leaves enough room on the right to show the arrow icon.
Then, in your app.scss, add:
.my-list-cls {
.x-list.check-mark.x-list-disclosure:before {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
content: '3';
font-family: 'Pictos';
color: #fff;
text-align: center;
text-shadow: 0 0 0;
}
}
This controls the styling for your new disclosure icon.
By setting content: '3';, you are changing the icon from the default right arrow to a checkmark. (See all of the available icons here: Pictos fonts).
The result:
It is possible but not easy. In short you have to extend class Ext.dataview.List and/or Ext.dataview.element.List.

dojox.Grid row background color

I have a Grid and I would like to change the background color, do you know how to do it ?
Thanks for your help, have a nice day.
Here is my code :
var jsonStore = new dojo.data.ItemFileReadStore({url: "..." ?>"});
var model = new dojox.grid.data.DojoData(null,jsonStore,{jsId: 'model', rowsPerPage: 20, query: { date: '*' }});
var view1 = {
cells: [[
{name: 'x', width: "80px", field: "date"},
{name: 'y', width: "50px", field: "weight"},
{name: 'z', width: "100px", field: "nurse"}
]]
};
var layout = [ view1 ];
<div id="gridWeight" dojoType="dojox.Grid" model="model" structure="layout" autoWidth="true" style="height: 150px"></div>
You can either use the onStyleRow event or adapt the CSS directly - in your case:
.tundra #gridWeight .dojoxGridRow,
.tundra #gridWeight .dojoxGridRowOdd {
background: red;
}