Creating a custom component for alerts? - sencha-touch-2

I'm trying develop a custom component like that shown in my mockup. I found an example component on the web (might have been in Sencha's docs), and now I'm trying to adapt it for my purposes. I have two questions:
Is this the right approach?
How do I drive my data dynamically from my AlertStore. The example was hard-code with a data: [] value. This can't be bound to a Store?
What I need is like a scrollable list view but with a different type of view. Sort of like the balloons in Apple's iPhone Messages app.
Sample code that I found on the Internet and I'm in the middle of adapting:
Ext.define("Sencha.view.ComponentView", {
extend: 'Ext.Component',
xtype: 'custom-component',
config: {
xtype: 'container',
scrollable: true,
layout: {type: 'vbox', pack: 'start', align: 'stretch'},
cls: ['view1'],
data: {
items: [
{name: 'Congestion near tunnel', n: 100},
{name: 'Car fore near exit 10', n: 21},
{name: 'Broken down vehicle in tunnel', n: 24},
{name: 'Slow traffic next 20 miles', n: 24},
{name: 'Drive carefully', n: 26}
]
},
store: 'AlertStore',
tpl: new Ext.XTemplate(
'<tpl for="items">',
'{% if(xindex % this.getPerRow() == 1) {%}',
'<div class="view-container">',
'{% } %}',
'<div class="alert-row">',
'<div class="name">{[xindex]} - {name}</div>',
'</div>',
'{% if(xindex % this.getPerRow() == 0 || xindex == xcount){ %}',
'</div>',
'{% } %}',
'</tpl>',
{
getPerRow: function () {
return 2;
}
})
},
initialize: function () {
this.callParent(arguments);
}
});

You should just be able to use a list and a css class to add rounded corners to your list items.
Here is a basic fiddle: http://new.senchafiddle.com/#/vZ4fT/

I implemented this chat for this application with Sencha Touch 2:
This is a list with an XTemplate. As #kevhender suggested in his comment, you should let your component inherit from Ext.dataview.DataView (or Ext.dataview.List if you don't need listitems made by more than one component).
Of course you can drive your component with a store, checkout Sencha Docs section on stores. You can basically retrieve your data from a proxy attached to the store, or you can get it from any other source, for example with Ext.Ajax or Ext.data.JsonP, then use setData() on the store. Once you have configured correctly the store the list will automatically update itself when changing its contents.

Here's what I came up with from the provided answers.
Ext.define("SF.view.SampleDataView", {
extend: 'Ext.Container',
xtype: 'sample-view',
id: 'sample-view-id',
requires: [],
config: {
cls: ['class1', 'class2'],
items: [
{
xtype: 'dataview',
cls: 'myclass',
itemTpl: '{name}',
store: {
fields: ['name'],
data: [
{name: 'Congestion near tunnel'},
{name: 'Broken down vehicle in tunnel'},
{name: 'The conference is over. See you next year.'},
{name: 'Slow traffic next 20 miles'},
{name: 'Drive carefully'},
{name: 'Congestion near tunnel'},
{name: 'Broken down vehicle in tunnel'},
{name: 'The conference is over. See you next year.'},
{name: 'Slow traffic next 20 miles'},
{name: 'Drive carefully'}
]
}
}
]
},
initialize: function () {
this.callParent(arguments);
}
});
I also added some margin and padding to #bwags' css.
.customRound {
border:2px solid;
border-radius:25px;
margin: 30px;
padding: 10px;
}

Related

Vue-draggable, nesting, and groups

Hey guys I need some assistance with vue draggable used in a nested context with groups. Some back story; I'm building a landing page creator, that said my layout follows standard bootstrap layout
section
container
row
col
col
That said I have a toolbox with 2 types of modules: Component modules and Layout Modules.
Layout modules look like the following:
layoutToolbox: [
{
name: "2 column layout",
icon: "font",
tagName: "div",
attributes: {
id: Math.random().toString(36).substring(7),
class: "row",
style: {},
},
textNode: null,
children: [
{
tagName: "div",
attributes: {
id: Math.random().toString(36).substring(7),
class: "col",
style: {},
},
textNode: null,
children: [],
},
{
tagName: "div",
attributes: {
id: Math.random().toString(36).substring(7),
class: "col",
style: {},
},
textNode: null,
children: [],
},
],
},
],
And then component modules:
toolbox: [
{
name: "paragraph",
icon: "font",
tagName: "div",
attributes: {
id: "toolbox-p",
class: "p",
style: {},
},
textNode: "This is my paragraph from the toolbox",
children: [],
},
]
That said I need layout to only be draggable to the top parent level, and then components I need draggable inside the column drag groups only!
Using just groups I can't get this behavior to work, my top level in recursion has the group of section:
<draggable
v-model="elements"
:group="{ name: 'section', put: true }"
handle=".editor-ui-drag-handle"
>
Then all my children inside of this are rendered using the group row:
<draggable
v-bind="dragOptions"
:list="list"
:value="value"
tag="div"
:group="{ name: 'row', put: !child }"
handle=".editor-ui-drag-handle"
#input="emitter"
#change="onChange"
>
That said I have what I think is a solution but I want to know why groups aren't working. When I have a group set to section on 2 draggable groups(toolbar, and parent) why can I drag it into its children? And why can I drag components with the group of row into the parent with the group of section?
My idea to solve this right now is using the drag start call backs and set the store to a variable that says if its a parent type or child type and then enable / disable put in the sections accordingly but I want to know if there's a better way.
Thanks!

Bootstrap tabs and Echarts

am having an issue with displaying my Echarts on the second tab. The chart is only displayed on the first tab but on navigation to the second tab it doesn't display
<ul class="nav nav-tabs" style="margin-bottom: 15px;">
<li class="active">
Campaigns
</li>
<li>
Subscribers
</li>
</ul>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="campaign">
<div id="pieChart" style="height:500px;border:1px solid #ccc;padding:10px;"></div>
</div>
<div class="tab-pane fade" id="subscribers">
<div id="barChart" style="height:500px;border:1px solid #ccc;padding:10px;"></div>
</div>
</div>
then hereis the js that displays the chart
var myChart = echarts.init(document.getElementById('pieChart'));
myChart.setTheme({color:['#6CC66C','#418BCA','#ff6600']});
pieChartOption = option = {
title : {
text: 'Campaign Analysis',
subtext: 'Jackpot',
x:'center'
},
tooltip : {
trigger: 'item',
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
legend: {
orient : 'vertical',
x : 'left',
data:['Sent','Pending','Not Delivered']
},
toolbox: {
show : true,
feature : {
mark : {show: true},
dataView : {show: true, readOnly: false},
magicType : {
show: true,
type: ['pie', 'funnel'],
option: {
funnel: {
x: '25%',
width: '50%',
funnelAlign: 'left',
max: 1548
}
}
},
restore : {show: true},
saveAsImage : {show: true}
}
},
calculable : true,
series : [
{
name:'Access Source',
type:'pie',
radius : '55%',
center: ['50%', '60%'],
data:[
{value:{{ $no}}, name:'Sent'},
{value:135, name:'Pending'},
{value:155, name:'Not Delivered'}
]
}
]
};
myChart.setOption(pieChartOption);
/*######################### BARCHART ##################################*/
var myBarChart = echarts.init(document.getElementById('barChart'));
var barChartOption = {
title: {
text: '某地区蒸发量和降水量',
subtext: '纯属虚构'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['2014', '2015']
},
toolbox: {
show: true,
feature: {
mark: {
show: true
},
dataView: {
show: true,
readOnly: false
},
magicType: {
show: true,
type: ['line', 'bar']
},
restore: {
show: true
},
saveAsImage: {
show: true
}
}
},
calculable: true,
xAxis: [{
type: 'category',
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
}],
yAxis: [{
type: 'value'
}],
series: [{
name: '2014',
type: 'bar',
data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3],
}, {
name: '2015',
type: 'bar',
data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],
}]
};
myBarChart.setOption(barChartOption);
/*######################### BARCHART ##################################*/
$(function() {
$( "#tabs" ).tabs({
select: function(event, ui) {
console.log('Calling chart.invalidateSize()');
chart.invalidateSize();
}
});
What cud be the solution to this?
});
ECharts documentation has mentioned
Sometimes charts may be placed in multiple tabs. Those in hidden labels may fail to initialize due to the ignorance of container width and height. So resize should be called manually to get the correct width and height when switching to the corresponding tabs, or specify width/heigth in opts explicitly.
So every time you switch to a new tab, just call the resize function on the chart instance:
chartInstance.resize()
The answer is a little late and I am not sure if you found a solution, but the resolution to this would be a combination of echarts setOption and Bootstrap's Tab event.
Like-
$('#myTabItem').on('shown.bs.tab', function (e) {
myChart.setOption(options);
})
The above code will reload the chart mychart using echarts setOption callback as soon as the Bootstrap Tab is shown. More info on Bootstrap Tab events can be found here.

Executing a function via HTML in a view when tapped

I have a view that generates some HTML. I want part of this HTMl to be clickable and execute a function when it is tapped.I can get this to work using a Sencha Touch button item but is it possible to reference and use an HTML element instead?
Here is my code.
View
Ext.define('myApp.view.ScheduleDetails', {
extend: 'Ext.Panel',
xtype: 'ScheduleDetails',
config: {
title: '<span class="logo"></span>',
styleHtmlContent: true,
scrollable: 'vertical',
tpl: [
'<img src="{image}" width="100%" class="mh"/>',
'<div class="dark-overlay">',
'<h1>{title}</h1>',
'<h3>{description}</h3>',
'<h1>{time}</h1>',
'</div>',
'<div class="actions">',
'<div class="actions-left check-in" id="checkin">',
'Check-in',
'</div>',
'<div class="actions-right map">',
'Map',
'</div>',
'</div>',
'<div class="schedule-details">',
'<p>{longdesc}</p>',
'</div>'
].join("")
}
});
Controller
Ext.define('myApp.controller.ScheduleDetails', {
extend: 'Ext.app.Controller',
config: {
refs: {
main: 'ScheduleDetails',
'checkinbutton': '.actions #check-in'
},
control: {
'.x-button #checkin': {
tap: 'showPage'
},
'checkinbutton': {
tap: 'showPage'
}
}
},
showPage: function(){
console.log('Callback');
}
});
Any help would be great, Thanks.
The proper way of doing this is to subscribe to events for particular element from the DOM. But the trick is where to do this - you can't just specify reference to such elements in controller. Because at the time this file is executed your element is not yet rendered.
You need to wait for your panel to be rendered and then find particular DOM element and subscribe to its events.
Yes, this is possible. You can use itemTap, this example can come in handy: http://www.mysamplecode.com/2012/05/sencha-touch-list-button-example.html
look at the controller that they use.

Give input to a Sencha 2 template

How can I pass arguments to a Sencha 2 template? Below is my small template, have tried different things like defining "field variables" on the template and using the config, and so fourth, but Im definitly doing something wrong. Lets say I want to give arguments "title" and "usageTime", how can I do it
Ext.define('Sencha.templates.AppDetailsUsageTemplate' ,{
extend: 'Ext.XTemplate',
constructor: function (config) {
var html = [
'<div id="{id}" class="limitsList {cls}">',
' <div class="reportsSummaryLeft"> {title} </div>',
' <div class="reportsSummaryRight"> {usageTime} </div>',
' <div style="clear:both"></div>',
'</div>'];
this.callParent(html);
}
});
In my view I wanna do something ala this (pseudo code below):
xtype: 'container',
tpl: Ext.create('Sencha.templates.AppDetailsUsageTemplate',{
title: 'test tittle',
usageTime: 100384
})
I figured it out, give parameters through data:
Examples:
{
id: 'appDetailsMonth',
xtype: 'component',
tpl: Ext.create('Sencha.templates.AppDetailsUsageTemplate')
},{
id: 'appDetailsLifeDuration',
xtype: 'component',
tpl: Ext.create('Sencha.templates.AppDetailsUsageTemplate')
}
And then in applyItems
applyItems:function(newItems, oldItems) {
var i = 0,
iNum = newItems.length,
data = this.getData();
var yesterdayItem = newItems[2];
yesterdayItem.data = {
title: 'Yesterday',
usage: data.dayDuration
};
....
}

Linking Images to different views in Sencha Touch 2

After 2 days of searching and trying all sorts of code snippets and explanations, i need to ask for some help here!
Demo:
http://kachipun.se/sandbox/touch/
Problem:
On the landing page of the app i have 8 instances of the same image (Planning to dress them up as buttons later on). I want to link these individual images to the 8 different views i have listed up in a menu up to the left.
As i've understood it, i need to use setActiveItem(), but however i try i cant get it to work ;/
Resources:
For this particular project i've used wozznik's Slider Menu as a base for the menu, and im building on that.
It contains a store with the data of the different views.
Ext.define('SliderMenu.store.MenuOptions', { extend: 'Ext.data.Store',
requires: [,
],
config: {
model: 'SliderMenu.model.MenuOption',
storeId: 'MenuOptionsStore',
//Customize your menu options
data: [
{id: 1, view: 'SliderMenuDemo.view.Start', iconCls: 'basic', iconMask:true, text:'Start'},
{id: 2, view: 'SliderMenuDemo.view.MC', iconCls: 'basic', iconMask:true, text:'Machining Center'},
{id: 3, view: 'SliderMenuDemo.view.TC', iconCls: 'basic', iconMask:true, text:'Turning Center'},
{id: 4, view: 'SliderMenuDemo.view.ST', iconCls: 'basic', iconMask:true, text:'Silent Tools'},
{id: 5, view: 'SliderMenuDemo.view.HC', iconCls: 'basic', iconMask:true, text:'Heavy Cuts'},
{id: 6, view: 'SliderMenuDemo.view.MT', iconCls: 'basic', iconMask:true, text:'Multi Task'},
{id: 7, view: 'SliderMenuDemo.view.SH', iconCls: 'basic', iconMask:true, text:'Sliding Head'},
{id: 8, view: 'SliderMenuDemo.view.VTL', iconCls: 'basic', iconMask:true, text:'VTL'},
{id: 9, view: 'SliderMenuDemo.view.Web', iconCls: 'basic', iconMask:true, text:'Web'},
]
}
});
And on the landing view (Start.js) i have the images setup like this with listeners listening for taps on the different images (check console log):
items: [{
html: '<div class="gridwrapper">'+
'<img class="test1 normal" src="http://static.flickr.com/43/102997171_f9263d8797_o.jpg" width="23%" />'+
'<img class="test2 normal" src="http://static.flickr.com/43/102997171_f9263d8797_o.jpg" width="23%" />'+
'<img class="test3 normal" src="http://static.flickr.com/43/102997171_f9263d8797_o.jpg" width="23%" />'+
'<img class="test4 normal" src="http://static.flickr.com/43/102997171_f9263d8797_o.jpg" width="23%" />'+
'<img class="test5 normal" src="http://static.flickr.com/43/102997171_f9263d8797_o.jpg" width="23%" />'+
'<img class="test6 normal" src="http://static.flickr.com/43/102997171_f9263d8797_o.jpg" width="23%" />'+
'<img class="test7 normal" src="http://static.flickr.com/43/102997171_f9263d8797_o.jpg" width="23%" />'+
'<img class="test8 normal" src="http://static.flickr.com/43/102997171_f9263d8797_o.jpg" width="23%" />'+
'</div>',
},
{
}],
listeners: [{
element: 'element',
delegate: 'img.test1',
event: 'tap',
fn: function() {
console.log('One!');
}
},{
element: 'element',
delegate: 'img.test2',
event: 'tap',
fn: function() {
console.log('Two!');
}
}
I really hope that you guys can help me make sense of this!
Best Regards
Please try:
listeners: [{
element: 'element',
delegate: 'img.test1',
event: 'tap',
fn: function() {
Ext.getCmp("maincard").changeViewTo(Ext.create("SliderMenuDemo.view.SH"));
// alternative: Ext.getCmp("SliderMenu.view.Main").changeViewTo(Ext.create("SliderMenuDemo.view.SH"));
}
}