For the life of me I'm unable to get my dataview to fire an itemtaphold event no matter how I attach the event handler. The itemtap event fires just fine. The closest i've been able to come is to use the longpress on the dom elements but that doesn't give me a reference to my control, just the dom element. Is the itemtaphold event broken for dataview on sencha touch 2 commercial?
BrowserGrid.js:
Ext.define('MyApp.view.BrowserGrid', {
extend: 'Ext.dataview.DataView',
xtype: 'browsergrid',
requires: [
'MyApp.view.BrowserGridItem',
'Ext.dataview.*',
'Ext.plugin.*'
],
config: {
useComponents: true,
cls: 'browser-grid',
defaultType: 'browsergriditem',
scrollable:{
direction: 'vertical',
directionLock: true
},
plugins :[{xclass:'Ext.plugin.ListPaging',autoPaging: true}],
listeners:
{
itemtaphold: function() { console.log('tapped'); }
}
}
});
BrowserGridItem.js
Ext.define('MyApp.view.BrowserGridItem', {
extend: 'Ext.dataview.component.DataItem',
xtype : 'browsergriditem',
config: {
cls: 'browser-grid-item',
dataMap: {
getName: {
setHtml: 'FILE_NAME'
},
getImage: {
setSrc: 'IMG_URL'
}
},
name: {
cls: 'x-name'
},
image: {
height:150,
width: 150,
flex:1
},
layout: {
type: 'vbox',
align: 'center'
}
},
applyImage: function(config) {
return Ext.factory(config, Ext.Img, this.getImage());
},
updateImage: function(newImage, oldImage) {
if (newImage) {
this.add(newImage);
}
if (oldImage) {
this.remove(oldImage);
}
},
applyName: function(config) {
return Ext.factory(config, Ext.Component, this.getName());
},
updateName: function(newName, oldName) {
if (newName) {
this.add(newName);
}
if (oldName) {
this.remove(oldName);
}
}
});
Related
I've read a lot of comments about it, but I didn't resolve my problem.
So my navigation code looks like this
export function pushScreens() {
Navigation.setRoot({
root: {
sideMenu: {
id: 'sideMenu',
left: {
visible: true,
component: {
id: 'Drawer',
name: SIDE_DRAWER,
},
},
center: {
bottomTabs: {
children: [{
stack: {
children: [{
component: {
name: HOME_SCREEN,
passProps: {
text: 'Home'
},
}
}],
options: {
bottomTab: {
text: 'Home',
icon: HomeIcon,
testID: 'FIRST_TAB_BAR_BUTTON'
},
}
}
},
{
component: {
name: PROFILE_SCREEN,
passProps: {
text: 'Profile'
},
options: {
bottomTab: {
text: 'Profile',
icon: HomeIcon,
testID: 'SECOND_TAB_BAR_BUTTON'
},
}
}
},
{
component: {
name: POSTS_SCREEN,
passProps: {
text: 'Posts'
},
options: {
bottomTab: {
text: 'Posts',
icon: HomeIcon,
testID: 'SECOND_TAB_BAR_BUTTON'
}
}
}
}]
}
}
}
}
});
}
I can pull the drawer from the left side of the screen by default, but how I could add the icon for that?
On the view that you wish to have the hamburger button, add:
static get options() {
topBar: {
leftButtons: [
{
color: colors.white,
id: TOOLBAR_HUMBERGER_BUTTON_ID,
icon: require("../resources/hamburger_topBar_button.png")
}
]
};
return topBar;
}
and then handle it like every other button of topBar:
navigationButtonPressed({ buttonId }) {
if (buttonId == TOOLBAR_HUMBERGER_BUTTON_ID) {
Navigation.mergeOptions(SIDEMENU_ID, {
sideMenu: {
left: {
visible: true
}
}
});
}
}
I am using a rallymilestonecombobox to display milestones.
I am selecting the milestone and getting the correct value when I output to console.log.
When I select the new milestone I update the filter.
The filter isn't loading or updating in the store.
Initially I tried filters: myFilters but that didn't work in the artifact.Store.
It worked when I used
"filters:
[{
property : 'Milestones',
operator : 'contains',
value : myFilters.value
}],"
But I am not successful in updating the filter on the update ".load".
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
myStore: undefined,
storyGrid: undefined,
storyStore: undefined,
// Intital Layout
width: 1600,
height: 1200,
items: [{
xtype: 'container',
itemId: 'pulldown-container',
padding: '25,5,5,25',
layout: {
type: 'hbox',
}
},
{
xtype: 'container',
itemId: 'group-container',
layout: {
type: 'hbox',
},
items: [{
title: 'Stories',
xtype: 'container',
itemId: 'story-grid-container',
padding: '20,5,5,25',
layout: {
type: 'vbox',
}
},
{
title: 'Story info',
xtype: 'tabpanel',
itemId: 'story-info-container',
padding: '5,5,5,25', //top, right, bottom, left).
autoScroll: true,
layout: {
type: 'vbox',
},
}
]
}
],
launch: function() {
// Load Releases in ComboBox
// this._loadReleases();
this._loadMilestones();
},
_loadMilestones: function() {
// Create Milestone ComboBox
var milestoneComboBox = {
xtype: 'rallymilestonecombobox',
itemId: 'milestone-combo-box',
fieldLabel: 'Milestones',
labelAlign: 'right',
width: 300,
listeners: {
ready: this._loadData,
select: this._loadData,
scope: this
}
};
this.down('#pulldown-container').add(milestoneComboBox);
},
//construct filters for given milestone
_getMilestoneFilters: function(milestoneValue) {
var milestoneFilter = Ext.create('Rally.data.wsapi.Filter', {
property: 'Milestone',
operation: '=',
value: milestoneValue
});
return milestoneFilter;
},
//Get data from rally
_loadData: function() {
var selectedMilestoneRef = this.down('#milestone-combo-box').getRecord().get('_ref');
var myFilters = this._getMilestoneFilters(selectedMilestoneRef);
console.log(myFilters);
//if store exists, load new data
if (this.myStore) {
this.myStore.setFilter(myFilters);
this.myStore.load();
} else {
//create store
this.myStore = Ext.create('Rally.data.wsapi.artifact.Store', {
models: ['User Story', 'Defect'],
autoLoad: true,
filters: [{
property: 'Milestones',
operator: 'contains',
value: myFilters.value
}],
listeners: {
load: function() {
this._onStoriesForMilestoneLoad();
},
scope: this
},
fetch: ['FormattedID', 'Name']
});
}
},
_onStoriesForMilestoneLoad: function() {
if (!this.down('#my-grid')) {
var gridListeners = {
itemclick: {
fn: function(record, item) {
this._createStoryInfo(record, item);
this._createRevisionInfo(record, item);
}
},
scope: this
};
var columnCfgs = ['FormattedID', 'Name'];
this._createGrid('my-grid', this.myStore, gridListeners, '#story-grid-container', columnCfgs, 600, 775, null);
}
},
_createGrid: function(id, theStore, theListeners, container, theColumnCfgs, gridwidth, gridheight, tabTitle) {
var storyGrid = {
title: tabTitle,
xtype: 'rallygrid',
itemId: id,
store: theStore,
listeners: theListeners,
context: this.getContext(),
columnCfgs: theColumnCfgs,
enableEditing: false,
showRowActionsColumn: false,
enableScheduleStateClickable: false,
verticalScroller: false,
showPagingToolbar: false,
width: gridwidth,
height: gridheight,
forceFit: true,
};
this.down(container).add(storyGrid);
},
});
I'd check out this example:
https://help.rallydev.com/apps/2.1/doc/#!/example/filterable-grid
It's a little different than your use case, but the mechanics are still the same.
The important bit is this:
var myFilters = this._getMilestoneFilters(selectedMilestoneRef);
if (this.myStore) {
this.myStore.clearFilter(true);
this.myStore.filter([myFilters]); //notice, it's an array
}
There's also an app baseclass to make it easy to work with timebox scoping since it is such a common use case:
https://help.rallydev.com/apps/2.1/doc/#!/guide/timebox_filtering
You could extend Rally.app.TimeboxScopedApp, set scopeType to milestone and go from there. It will handle creating the milestone combo for you. And it will also automatically support working on milestone scoped custom pages in Rally.
I think you're probably really close to working code in your existing implementation, but worth a consideration to look into TimeboxScopedApp...
I had to update the Filter value specifically and it worked.
I should have known since I had to do this when creating the store.
//if store exists, load new data
if(this.myStore)
{
this.myStore.clearFilter(true);
this.myStore.filter([
{
property : 'Milestones',
operator : 'contains',
value : myFilters.value
}]);
this.myStore.load();
}
else
{
//create store
this.myStore = Ext.create('Rally.data.wsapi.artifact.Store',
{
I'm using Durandal and Kendo UI. My current problem is the edit popup event on my grid. I cannot seem to set the selected value on my dropdown.
I can debug and inspect, and I indeed do see the correct value of e.model.InstrumentName nicely populated.
How can I set the value/text of those dropdowns in edit mode ?
Here's my grid init:
positGrid = $("#positGrid").kendoGrid({
dataSource: datasource,
columnMenu: false,
{
field: "portfolioName", title: "Portfolio Name",
editor: portfolioDropDownEditor, template: "#=portfolioName#"
},
{
field: "InstrumentName",
width: "220px",
editor: instrumentsDropDownEditor, template: "#=InstrumentName#",
},
edit: function (e) {
var instrDropDown = $('#InstrumentName').data("kendoDropDownList");
var portfDropDown = $('#portfolioName').data("kendoDropDownList");
instrDropDown.list.width(350); // let's widen the INSTRUMENT dropdown list
if (!e.model.isNew()) { // set to current valuet
//instrDropDown.text(e.model.InstrumentName); // not working...
instrDropDown.select(1);
//portfDropDown.text();
}
},
filterable: true,
sortable: true,
pageable: true,
editable: "popup",
});
Here's my Editor Template for the dropdown:
function instrumentsDropDownEditor(container, options) {
// INIT INSTRUMENT DROPDOWN !
var dropDown = $('<input id="InstrumentName" name="InstrumentName">');
dropDown.appendTo(container);
dropDown.kendoDropDownList({
dataTextField: "name",
dataValueField: "id",
dataSource: {
type: "json",
transport: {
read: "/api/breeze/GetInstruments"
},
},
pageSize: 6,
select: onSelect,
change: function () { },
optionLabel: "Choose an instrument"
}).appendTo(container);
}
thanks a lot
Bob
Your editor configuration is bit unlucky for grid, anyway i have updated my ans on provided code avoiding manual selections:
Assumptions: Instrument dropdown editor only (leaving other fields as strings), Dummy data for grid
<div id="positGrid"></div>
<script>
$(document).ready(function () {
$("#positGrid").kendoGrid({
dataSource: {
data: [
{ PositionId: 1, Portfolio: "Jane Doe", Instrument: { IID: 3, IName: "Auth2" }, NumOfContracts: 30, BuySell: "sfsf" },
{ PositionId: 2, Portfolio: "John Doe", Instrument: { IID: 2, IName: "Auth1" }, NumOfContracts: 33, BuySell: "sfsf" }
],
schema: {
model: {
id: "PositionId",
fields: {
"PositionId": { type: "number" },
Portfolio: { validation: { required: true } },
Instrument: { validation: { required: true } },
NumOfContracts: { type: "number", validation: { required: true, min: 1 } },
BuySell: { validation: { required: true } }
}
}
}
},
toolbar: [
{ name: "create", text: "Add Position" }
],
columns: [
{ field: "PositionId" },
{ field: "Portfolio" },
{ field: "Instrument", width: "220px",
editor: instrumentsDropDownEditor, template: "#=Instrument.IName#" },
{ field: "NumOfContracts" },
{ field: "BuySell" },
{ command: [ "edit", "destroy" ]
},
],
edit: function (e) {
var instrDropDown = $('#InstrumentName').data("kendoDropDownList");
instrDropDown.list.width(400); // let's widen the INSTRUMENT dropdown list
},
//sortable: true,
editable: "popup",
});
});
function instrumentsDropDownEditor(container, options) {
$('<input id="InstrumentName" required data-text-field="IName" data-value-field="IID" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
dataSource: {
type: "json",
transport: {
read: "../Home/GetMl"
}
},
optionLabel:"Choose an instrument"
});
}
</script>
Action fetching json for dropddown in Home controller:
public JsonResult GetMl()
{
return Json(new[] { new { IName = "Auth", IID = 1 }, new { IName = "Auth1", IID = 2 }, new { IName = "Auth2", IID = 3 } },
JsonRequestBehavior.AllowGet);
}
I am using a carousel and would like to lock the carousel until a button is clicked. Is there an easy way to do this? Thanks!
My code so far:
Ext.define('BabyBen.view.MainCarousel', {
extend: 'Ext.carousel.Carousel',
xtype: 'maincarousel',
config: {
fullscreen: true,
activeItem: 1,
indicator: false,
scrollable: {
direction: 'vertical',
directionLock: true
},
items: [{
xtype: 'whatscreen'
}, {
xtype: 'startscreen'
}, {
xtype: 'whenscreen'
}]
}
});
You need to write a custom view for lockable carousel:
Ext.define("myApp.view.LockableCarousel",{
extend: 'Ext.Carousel',
initialize: function () {
this.onDragOrig = this.onDrag;
this.onDrag = function (e) { if(!this.locked){this.onDragOrig(e);} }
},
locked: false,
lock: function () { this.locked = true; },
unlock: function () { this.locked = false; }
});
Then you can extend this custom carousel anywhere using extend as well as you need to apply custom lock and unlock function for your desired lockable carousel through button handler:
Ext.define("myApp.view.CustomCarousel",{
xtype: 'CustomCarousel',
extend: 'myApp.view.LockableCarousel',
config: {
id: 'LockableCarousel',
title: 'Example4',
iconCls: 'cloud',
indicator: false,
items: [
{
html : 'Item 1',
style: 'background-color: #5E99CC'
},
{
items: [
{
xtype : 'button',
text: 'Lock',
handler:function() {
Ext.getCmp('LockableCarousel').lock();
}
},
{
xtype : 'button',
text: 'Unlock',
handler:function() {
Ext.getCmp('LockableCarousel').unlock();
}
}
]
}
]
}
});
Working Demo
I'm working on my very first Sencha Touch 2 project, so I'm not very familiar with it yet. I'm using the Sencha documentation and have been Googling and Stackoverflowing a lot, but can't seem to find the answer to this problem.
I'm working in MVC and want to add some eventlisteners (in the controller) to controls in my view. Whatever I try, they don't seem to work, although they work when I add them in the view itself. Ofcourse that's not best practice at all, so I'm wondering what I'm doing wrong?
This is how my controller looks:
Ext.define("workingTime.controller.MainController", {
extend: "Ext.app.Controller",
views: ['Main'],
refs: [
{
sl_break: '#sl_break'
},
{
sl_work: '#sl_work'
}
],
init: function() {
this.control({
'sl_break': {
change: 'setBreakTime'
}
});
},
setBreakTime: function(newValue) {
console.log('set');
}
});
And this is how my view looks (with the listener still added):
Ext.define("workingTime.view.Main", {
extend: 'Ext.form.Panel',
controllers: ['MainController'],
requires: [
'Ext.field.Slider'
],
config: {
fullscreen: true,
items: [
{
xtype: 'label',
html: '<p class="label_field">Take a <span>five</span> minute break<p>'
},
{
xtype: 'sliderfield',
name: 'sl_break',
value: 5,
minValue: 1,
maxValue: 30,
style: {
'background-color' : '#FFecc0'
},
listeners: {
change: function() {
alert('changed');
}
}
},
{
]
}
});
Tell me if you need more info.
I would try: (without init function)
config: {
refs: {
sl_break: '#sl_break',
sl_work: '#sl_work'
},
control: {
sl_break: {
change: 'setBreakTime'
}
}
},
in your controller add sl_break: 'main sliderfield[itemId=sl_break]' in refs
Ext.define("workingTime.controller.MainController", {
extend: "Ext.app.Controller",
views: ['Main'],
refs: [
{
sl_break: 'main sliderfield[itemId=sl_break]'
}
],
init: function() {
this.control({
'sl_break': {
change: 'setBreakTime'
}
});
},
setBreakTime: function(newValue) {
console.log('set');
}
});
in view add alias to main and itemId to sliderfield
Ext.define("workingTime.view.Main", {
extend: 'Ext.form.Panel',
controllers: ['MainController'],
alias: 'widget.main',
requires: [
'Ext.field.Slider'
],
config: {
fullscreen: true,
items: [
{
xtype: 'label',
html: '<p class="label_field">Take a <span>five</span> minute break<p>'
},
{
xtype: 'sliderfield',
name: 'sl_break',
itemId:'sl_break',
value: 5,
minValue: 1,
maxValue: 30,
style: {
'background-color' : '#FFecc0'
},
listeners: {
change: function() {
alert('changed');
}
}
},
{
]
}
});
i hope it will work