How to add labels to sliderfield Sencha Touch - slider

Ok, so I would like to have a slider that looks like this one.
Just can't figure out where we can at least have these delimiter separators? So if you see there are 7 delimiters and we have large labels on the first 4-th and the last delimeter.
How would you approach this task?

This is a rather old question but I was faced with the very same need today. Building on GenieWanted's answer, I came to this:
...
{
xtype: 'sliderfield',
maxValue: 5,
label: 'Some data',
html: '<table width="100%" align="left"><tr><td width="25%">Min</td><td width="50%" align="center">Med</td><td width="25%" align="right">Max</td></tr></table>'
}
...
which works very well for me, and avoids messing around to find the correct number of needed. Also, I suspect that results would vary from device to device using .

There is no way of adding a label inside sliderfield. However, you can indeed add HTML to acheive the required output. On the config panel, go to HTML property, and add something like this:
<div style="padding-left:1em">| | |<div>Low Average High </div></div>
The output I have got:
You just need to playaround with the alignment of your text in the HTML. That will do!
Good Luck!

You can create Custom Slider like this
Ext.ns('Ext.ux');
Ext.ux.CustomSlider = Ext.extend(Object, {
valueTextClass: 'x-slider-value-text',
showSliderBothEndValue: true,
sliderEndValueStyle: 'color: black',
constructor: function(config){
Ext.apply(this, config);
Ext.ux.CustomSlider.superclass.constructor.apply(this, arguments);
},
init: function(parent) {
var me = this;
parent.on({
painted: {
fn: function(component) {
if (me.showSliderBothEndValue) me.showSliderEndValue(this);
if (!this.valueTextEl) {
this.valueTextEl = component.element.createChild({
cls: me.valueTextClass
});
}
}
}
});
},
showSliderEndValue: function(slider) {
var sliderPosX = slider.getComponent().getThumb().element.getX();
var thumbHeight = slider.getComponent().getThumb().element.getHeight();
var sliderLength = slider.getComponent().element.getWidth();
var minValueEl = slider.getComponent().element.createChild();
minValueEl.setHtml(slider.getComponent().getMinValue());
minValueEl.applyStyles('overflow:hidden;position:absolute');
minValueEl.applyStyles(this.sliderEndValueStyle);
minValueEl.setLeft(14);
minValueEl.setTop(thumbHeight -7);
var maxValueEl = slider.getComponent().element.createChild();
maxValueEl.setHtml(slider.getComponent().getMaxValue());
maxValueEl.applyStyles('overflow:hidden;position:absolute');
maxValueEl.applyStyles(this.sliderEndValueStyle);
maxValueEl.setLeft(sliderLength-45);
maxValueEl.setTop(thumbHeight - 7);
}
});
And create slider like this
var slider = {
xtype: 'sliderfield',
flex : 6,
label: "Percentage",
name: "Percentage",
value : 50,
minValue : 0,
maxValue : 100,
labelWrap : true,
labelAlign : 'left',
increment : 10,
plugins: [new Ext.ux.CustomSlider({
showSliderBothEndValue: true
})],
listeners: {
painted: function (slider) {
var sliderPanelItems = this.parent.getInnerItems();
sliderPanelItems[1].setValue(this.getValue());
},
change: function (me,slider, thumb, newVal, oldVal, opts) {
var sliderPanelItems = this.parent.getInnerItems();
sliderPanelItems[1].setValue(newVal);
}
}
};
Result will be like this
I did this using this link

Related

FullCalendar and Flot Resize Conflict

I've successfully integrated both a Flot line graph and an instance of FullCalendar into my site. They are both on separate pages (although the pages are loaded into a div via AJAX).
I've added the Flot Resize plugin and that works perfectly, re-sizing the line graph as expected. However, it seems to cause an error when resizing the calendar.
Even if I load the calendar page first, when I resize the window I get this error in the console (also, the calendar does not resize correctly):
TypeError: 'undefined' is not an object (evaluating 'r.w=o!==c?o:q.width()')
I was struggling to work out where the error was coming from, so I removed the link to the Flot Resize JS and tried again. Of course the line graph does not resize, but when resizing the calendar, it works correctly.
The div containers for the two elements have different names and the resize function is called from within the function to draw the line graph (as required).
I have tried moving the link to the Flot Resize plugin into different places (i.e. above/below the fullCalendar JS, into the template which holds the graph), but all to no avail.
Does anyone have any idea where the conflict might be and how I might solve it??
Thanks very much!
EDIT: It seems that the error is also triggered when loading the line graph (flot) page AFTER the fullcalendar page even without resizing the window.... Now I am very confused!
EDIT 2: The code which draws the line graph. The function is called on pageload and recieves the data from JSON pulled off the server. When the graph is loaded, I still get the error about shutdown() being undefined.
function plotLineGraph(theData){
var myData = theData['data'];
var myEvents = theData['events'];
var myDates = theData['dates'];
var events = new Array();
for (var i=0; i<myEvents.length; i++) {
events.push(
{
min: myEvents[i][0],
max: myEvents[i][1],
eventType: "Calendar Entry",
title: myEvents[i][2],
description: myEvents[i][3]
}
);
}
function showTooltip(x, y, contents) {
$('<div id="tooltip">' + contents + '</div>').css( {
position: 'absolute',
display: 'none',
top: y + 5,
left: x + 5,
border: '1px solid #fdd',
padding: '2px',
'background-color': 'black',
opacity: 0.80
}).appendTo("body").fadeIn(200);
}
var previousPoint = null;
$("#placeholder").bind("plothover", function (event, pos, item) {
$("#x").text(pos.x.toFixed(2));
$("#y").text(pos.y.toFixed(2));
if ($("#enableTooltip:checked").length == 0) {
if (item) {
if (previousPoint != item.dataIndex) {
previousPoint = item.dataIndex;
$("#tooltip").remove();
var x = item.datapoint[0].toFixed(2),
y = item.datapoint[1].toFixed(2);
if(item.series.label != null){
showTooltip(item.pageX, item.pageY,
item.series.label + " of " + y);
}
}
}
else {
$("#tooltip").remove();
previousPoint = null;
}
}
});
var d1 = [
myData[0], myData[1], myData[2], myData[3], myData[4],
myData[5], myData[6], myData[7], myData[8], myData[9],
myData[10], myData[11], myData[12], myData[13], myData[14],
myData[15], myData[16], myData[17], myData[18], myData[19],
myData[20], myData[21], myData[22], myData[23], myData[24],
myData[25], myData[26], myData[27], myData[28], myData[29]
];
var markings = [
{ color: '#FFBDC1', yaxis: { from: 0, to: 2 } },
{ color: '#F2E2C7', yaxis: { from: 2, to: 3.5 } },
{ color: '#B6F2B7', yaxis: { from: 3.5, to: 5 } }
];
$.plot($("#placeholder"), [
{label: "Average Daily Rating", data: d1, color: "black"}
], {
events: {
data: events,
},
series: {
lines: { show: true },
points: { show: true }
},
legend: { show: true, container: '#legend-holder' },
xaxis: {
ticks:[
myDates[0], myDates[1], myDates[2], myDates[3], myDates[4],
myDates[5], myDates[6], myDates[7], myDates[8], myDates[9],
myDates[10], myDates[11], myDates[12], myDates[13], myDates[14],
myDates[15], myDates[16], myDates[17], myDates[18], myDates[19],
myDates[20], myDates[21], myDates[22], myDates[23], myDates[24],
myDates[25], myDates[26], myDates[27], myDates[28], myDates[29]
],
},
yaxis: {
ticks: 5,
min: 0,
max: 5
},
grid: {
backgroundColor: { colors: ["#fff", "#eee"] },
hoverable: true,
clickable: true,
markings: markings
},
selection: {
color: 'white',
mode: 'x'
},
});
$('#placeholder').resize();
$('#placeholder').shutdown();
}
EDIT 3:
The calendar is called like this:
function showCalendar() {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
$('#fullcalendar').fullCalendar({
header: {
left: 'prev',
center: 'title',
right: 'next'
},
clickable: true,
firstDay: 1,
eventSources: [
{
url: '/populate-calendar/{{theProductUuid}}/',
color: 'black',
data: {
text: 'text'
}
}
],
eventClick: function(calEvent, jsEvent, view) {
var startDate = $.fullCalendar.formatDate(calEvent.start, 'yyyy-MM-dd');
var endDate = $.fullCalendar.formatDate(calEvent.end, 'yyyy-MM-dd');
var eventId = calEvent.uuid;
$('#modal-event-title').text(calEvent.title);
$('#edit-event-name').val(calEvent.title);
$('#edit-start-date').val(startDate);
$('#edit-end-date').val(endDate);
$('#edit-event-text').val(calEvent.text);
$('#edit-event-btn').attr('data-uuid', eventId);
$('#modal-edit-event').on('click', '#delete-btn', function(){
deleteCalendarEvent(eventId);
});
$('#modal-edit-event').modal();
},
});
}
The AJAX to load the page containing the flot chart:
function loadDetailedReports(uuid){
$('#product-content').fadeOut('slow', function(){
$('#product-content').empty();
$('#whole-product-sub-nav .active').removeClass('active');
$('#detailed-reports-content').load('/detailed-reports/' + uuid + '/', function(){
$('#detailed-reports-btn').addClass('active');
$('#detailed-reports-content').fadeIn('slow', function(){
if (authorized){
setLocationHash('loadDetailedReports&' + uuid);
getChartData(uuid);
} else {
setLocationHash('');
}
});
});
});
}
And the AJAX to load the page containing the calendar:
function loadCalendar(uuid){
$('#detailed-reports-content').empty().hide();
$('#product-content').fadeOut('slow', function(){
$('#whole-product-sub-nav .active').removeClass('active');
$('#product-content').load('/calendar/' + uuid + '/', function(){
$('#calendar-btn').addClass('active');
$('#product-content').fadeIn('slow', function(){
if (authorized){
setLocationHash('loadCalendar&' + uuid);
} else {
setLocationHash('');
}
showCalendar();
});
});
});
}
The calls to .resize and .shutdown are there because I was under the impression that they are necessary to achieve the resizing function and in response to your earlier comment regarding shutdown...... They're quite possibly n00b errors........?!?!
It looks like this is triggering on line 198 of jquery-resize:
data.w = w !== undefined ? w : elem.width();
This sounds like a race-condition stemming from the way you load different content into the same div. Flot binds the resize event to the chart div, and only un-binds it if the plot is destroyed cleanly.
EDIT: Looking at your code, my first suggestion would be to get rid of the resize and shutdown calls at the end of plotLineGraph. The resize plugin doesn't require any setup; it hooks into Flot to attach automatically to any new plot. So your call to resize is actually to jQuery's resize event trigger, which may be what's causing the error.
EDIT #2: I'm still not clear on your structure, but to generalize: anywhere that you might be getting rid of #placeholder (via emptying its parent or anything like that) you should first call shutdown on the plot object. If you aren't keeping a reference to it, you can do it like this: $("#placeholder").data("plot").shutdown(); but then have to account for the fact that it's undefined prior to the creation of your first plot.
If that still doesn't work, I'd need to see a live (simplified) example to make any further suggestions.

Sencha Touch 2 Get Current Location on Button Click

I have a toolbar button which when clicked should update my map to my current location. I am unable to find a working example of this functionality and hoping someone can advise me. Please see below for sample code - thanks for your help
Map:
Ext.define('MyApp.view.Myap', {
extend: 'Ext.Map',
alias: 'widget.mymap',
config: {
useCurrentLocation: false,
mapOptions:{
zoom: 9,
center: new google.maps.LatLng(42.2, -72.5),
mapTypeId: google.maps.MapTypeId.ROADMAP
},
listeners: {
maprender : function(comp, map){
google.maps.event.addListenerOnce(map, "idle", function () {
var host = window.location.origin ? window.location.origin : window.location.protocol + "/" + window.location.host;
var kmlOptions = {preserveViewport: false}
var now = +new Date();
var layer = new google.maps.KmlLayer(host + '/path/to.kml?timestamp=' + now, kmlOptions);
layer.setMap(map);
return layer;
});
},
}
},
})
Toolbar Button:
Ext.define('MyApp.view.btnLocateMe', {
extend: 'Ext.Button',
alias: 'widget.btnlocateme',
config: {
ui: 'normal',
iconCls: 'locate',
iconMask: true,
text: 'Locate Me',
listeners: [
{
fn: 'onButtonTap',
event: 'tap'
}
]
},
onButtonTap: function(button, e, options) {
//Produces error: cannot call method of undefined
currentLocation: new google.maps.LatLng(this._geo.getLatitude(), this._geo.getLongitude());
MyApp.view.MyMap.map.setCenter(currentLocation);
}
});
my two cents contribution, try this
1) in MyApp.view.Myap substitute
useCurrentLocation: false,
by
useCurrentLocation : {
autoUpdate : false
},
Also you should declare currentLocation as a variable (I presume)
var currentLocation = ...
This should works. I've use a similar logic as yours in onButtonTap but inside a controller with no problems
Best regards
I have one suggestion.
Try changing current location to
new google.maps.LatLng( this.geo.getLatitude(),this.geo.getLongitude() ) ;
I think you can gather more info from this question in here.
The simplest way - switch to the another map view with option useCurrentLocation: true set in the config

NumberSpinner constraints not working in DataGrid

I am using inline editing of enhancedgrid cells and have a NumberSpinner element. The constraints of this numberspinner don't work when editing inline. The required property works fine though.
My code:
{field: 'msorder', width: '10%', name: 'Milestone Order',editable: true, type: dojox.grid.cells._Widget, widgetClass: dijit.form.NumberSpinner, widgetProps: {required:true,smallDelta:1, editorParams:{constraints:{ min:-1000, max:1000, places:0 }} }}
I have also tried:
{field: 'msorder', width: '10%', name: 'Milestone Order',editable: true, type: dojox.grid.cells._Widget, widgetClass: dijit.form.NumberSpinner, widgetProps: {required:true,smallDelta:1, constraints:{ min:-1000, max:1000, places:0 } }}
There is an easier solution, guys:
constraint:{min:0,max:24}
{field: "hours", name: "Stunden",type: dojox.grid.cells._Widget, widgetClass: dijit.form.NumberSpinner, constraint:{min:0,max:24}, widgetProps: {smallDelta:0.25, intermediateChanges:true,}},
It has to be outside of widgetProps and in singular...
I don't know what version of Dojo you use, but there is known bug in 1.6 that constraints are ignored in grid widgets. However, I solve that problem doing a little overwriting standard NumberSpinner.
dojo.require("dijit.form.NumberSpinner");
dojo.addOnLoad(function() {
dojo.declare("mySpinner", [ dijit.form.NumberSpinner], {
validator: function(v, c){
var MIN= -1000;
var MAX = 1000;
c.min= MIN;
c.max = MAX ;
return ((v < MAX ) && (v > MIN));
},
});
var dateBox = new mySpinner({}).placeAt('foo');
dateBox.set("value", 1000);
});
(Now, in your grid structure you should use mySpinner of course, and it should do the trick).
Demo: http://jsfiddle.net/tvUaK/135/
I used another way to solve that problem. I define the type of cell as Widget and then I create the widget on get method.
{
field: 'msorder',
width: '10%',
name: 'Milestone Order',
editable: true,
type: dojox.grid.cells._Widget,
get: function(rowIndex, item) {
var store = this.grid.store,
value = store.getValue(item, 'value');
this.widget = new dijit.form.NumberSpinner({ value:0,
constraints:{ min:-1000, max:1000 }
});
return value;
}
}
With this implementation I was able to set different constraints for each cell on the grid.

How to save the notes in local storage in sencha touch?

I have followed the tutorial : http://miamicoder.com/2011/writing-a-sencha-touch-application-part-3/
to add and save notes. But save note is not working for me. What is the issue??
My code to save :
NotesApp.views.noteEditorTopToolbar = new Ext.Toolbar({
title: 'Edit Note',
items: [
{ xtype: 'spacer' },
{
text: 'Save',
ui: 'action',
handler: function () {
// TODO: Save current note.
var noteEditor = NotesApp.views.noteEditor;
var currentNote = noteEditor.getRecord();
// Update the note with the values in the form fields.
noteEditor.updateRecord(currentNote);
//var errors = currentNote.validate();
/*if (!errors.isValid()) {
currentNote.reject();
Ext.Msg.alert('Wait!', errors.getByField('title')[0].message, Ext.emptyFn);
return;
}*/
var notesList = NotesApp.views.notesList;
var notesStore = notesList.getStore();
if (notesStore.findRecord('id', currentNote.data.id) === null) {
alert('fjghjkh');
notesStore.add(currentNote);
} else {
alert('fjghjkh');
currentNote.setDirty();
}
notesStore.sync();
notesStore.sort([{ property: 'date', direction: 'DESC'}]);
notesList.refresh();
NotesApp.views.viewport.setActiveItem('notesListContainer', { type: 'slide', direction: 'right' });
}
thanks
Sneha
I had the same problem. In my case, the solutaion was to add the config 'autoLoad: true' to my defined store.
Perhaps this answer helps other, who find this question by googling a similar problem.
Regards,
Andreas

How to display data in Label from data store in Sencha Touch

I want to display data that i receive from a data store. One way that i have tried, is to take a text field make it disabled and then set its value with store data.
But i don't think it is the correct solution so i am trying to use label instead and I am not getting how it can be done. Can you guys can point me to correct way of doing it.? Any help appreciated .
Thanks,
Mehul Makwana.
This post is a little old but I was research the for same topic and ended up using a different approach.
I'm using Sencha Touch v2.0. I create the label and place it inside the form.Panel as one would normally do. I then configured the label tpl in designer to include the model fields. When applying the values to the formpanel, I also invoke the apply() method on the label tpl. The following working sample illustrate it.
app.js:
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
views: [
'MyFormPanel'
],
name: 'MyApp',
launch: function() {
Ext.create('MyApp.view.MyFormPanel', {fullscreen: true});
}
});
view.MyFormPanel.js
Ext.define('MyApp.view.MyFormPanel', {
extend: 'Ext.form.Panel',
alias: 'widget.myformpanel',
config: {
items: [
{
xtype: 'label',
itemId: 'myLabel',
tpl: [
'Hello, {firstName} {lastName}, please change your email below:',
''
]
},
{
xtype: 'textfield',
label: 'Email:'
}
],
listeners: [
{
fn: 'onFormpanelInitialize',
event: 'initialize'
}
]
},
onFormpanelInitialize: function(component, options) {
var person = Ext.decode("{firstName: 'John',lastName: 'Dow',email: 'jd#somewhere.com'}");
// apply value to the form
this.setValues(person);
// get the updated text for the label
var label = this.down('#myLabel');
var html = label.getTpl().apply(person);
label.setHtml(html);
}
});
So the idea is save the label template in the label.tpl field, then get the runtime label value using apply() method of Template, then set the label text to it.
I recently tried to solve this problem by creating a 'label' form component. I posted about it in a blog article I wrote on Sencha/PhoneGap. Here is the code:
Ext.form.LabelField = function(config){
Ext.form.LabelField.superclass.constructor.call(this, config);
};
Ext.extend(Ext.form.LabelField, Ext.form.Field, {
isField: true,
value: '',
renderSelectors: {fieldEl: '.x-form-labelfield'},
renderTpl: [
'<tpl if="label">',
'<div class="x-form-label"><span>{label}</span></div>',
'</tpl>',
'<div class="x-form-label x-form-labelfield" style="width:70%; text-align:right"><span>{value}</span></div>',
],
setValue:function(val) {
this.value = val;
if(this.rendered){
this.fieldEl.update('<span>' + val + '</span>');
}
return this;
},
});
Ext.reg('labelfield', Ext.form.LabelField);
Let me know if this does the trick.
Thank you mistagrooves. That was exactly what I was looking for. I reccomand removing x-form-label class and using these styles:
.x-form-labelfield {
-webkit-box-flex: 1;
box-flex: 1;
width: 100%;
position: relative;
-webkit-border-radius: 0;
border-radius: 0;
padding: .4em;
border: 0;
min-height: 2.5em;
display: block;
background: white none;
-webkit-appearance: none;
}