Sencha how to update viewport on click on tabpanel? - sencha-touch-2

I have an MVC multi item & paged image carousel in Sencha Touch 2, which works perfectly on it's own when added to the Viewport on init.
However, the problem I am having now is how to adapt it to my tab panel style app. I am a little unclear where I should put the code, at init or (I'm guessing) in the controller which fires on click of the specific tab. My tabpanel style app was downloaded from Github (Sencha touch 2 boilerplate template).
My working MVC carousel calls the following in the app.js:
controllers: ['Main'],
views: ['Carousel', 'Page'],
stores: ['Thumbnails'],
models: ['Thumbnail'],
launch: function () {
var carousel = Ext.create('Ext.Carousel');
Ext.Viewport.add(carousel);
Ext.getStore('Thumbnails').load(function (apps) {
var cols = 4, rows = 4; // todo: change for tablets
var page;
var btn;
var iPage = 0;
var iApp = 0;
var x = 1, y = 1, z = 0;
var row, grid, bottomrow;
var firstpage = 0;
etc....code cut for readbility.
Basically I want this carousel to appear on the second tab of the tabpanel, not initially on the viewport how it works now. Perhaps I should have the working launch code in a controller that fires when I'm on that tab of the tabpanel? I'm not sure of the best way to approach this.
Here is the launch function of my tabpanel app, with the
launch: function() {
Ext.create('TCApp.view.Viewport', {fullscreen: true});
// I have tried adding this working launch code after creating the Viewport, but maybe it should be in the controller? But I'm not sure how to go about it...
var carousel = Ext.create('Ext.Carousel');
Ext.Viewport.add(carousel);
Ext.getStore('Thumbnails').load(function (apps) {
var cols = 4, rows = 4; // todo: change for tablets
var page;
var btn;
var iPage = 0;
var iApp = 0;
var x = 1, y = 1, z = 0;
var row, grid, bottomrow;
var firstpage = 0;
Any help would be much appreciated!

You are adding your carousel to Ext.Viewport, which is the component that gets instantiated by default on application bootstrap. So, instead of using Ext.Viewport.add(carousel);, and adding it to the Viewport itself, try with
tabpanel.add(carousel);
Where tabpanel is the reference to your tab panel instance. This way you'll be adding the carousel to the first available card in Ext.tab.Panel

Thanks Grgur, it helped. I eventually solved it this way, making sure to have a title and iconCls otherwise I get an error in the console when adding the carousel item to the tabpanel:
var carousel = Ext.create('Ext.Carousel', {
title: 'Carousel',
iconCls: 'info'
});
var MyTabPanel = Ext.getCmp('mytabpanel');
MyTabPanel.add(carousel);

Related

A slider to separate 2 content divs

I want to create an "image comparison slider" for contents. Example:
Codepen Link
// Call & init
$(document).ready(function(){
$('.ba-slider').each(function(){
var cur = $(this);
// Adjust the slider
var width = cur.width()+'px';
cur.find('.resize img').css('width', width);
// Bind dragging events
drags(cur.find('.handle'), cur.find('.resize'), cur);
});
});
// Update sliders on resize.
// Because we all do this: i.imgur.com/YkbaV.gif
$(window).resize(function(){
$('.ba-slider').each(function(){
var cur = $(this);
var width = cur.width()+'px';
cur.find('.resize img').css('width', width);
});
});
function drags(dragElement, resizeElement, container) {
// Initialize the dragging event on mousedown.
dragElement.on('mousedown touchstart', function(e) {
dragElement.addClass('draggable');
resizeElement.addClass('resizable');
// Check if it's a mouse or touch event and pass along the correct value
var startX = (e.pageX) ? e.pageX : e.originalEvent.touches[0].pageX;
// Get the initial position
var dragWidth = dragElement.outerWidth(),
posX = dragElement.offset().left + dragWidth - startX,
containerOffset = container.offset().left,
containerWidth = container.outerWidth();
// Set limits
minLeft = containerOffset + 10;
maxLeft = containerOffset + containerWidth - dragWidth - 10;
// Calculate the dragging distance on mousemove.
dragElement.parents().on("mousemove touchmove", function(e) {
// Check if it's a mouse or touch event and pass along the correct value
var moveX = (e.pageX) ? e.pageX : e.originalEvent.touches[0].pageX;
leftValue = moveX + posX - dragWidth;
// Prevent going off limits
if ( leftValue < minLeft) {
leftValue = minLeft;
} else if (leftValue > maxLeft) {
leftValue = maxLeft;
}
// Translate the handle's left value to masked divs width.
widthValue = (leftValue + dragWidth/2 - containerOffset)*100/containerWidth+'%';
// Set the new values for the slider and the handle.
// Bind mouseup events to stop dragging.
$('.draggable').css('left', widthValue).on('mouseup touchend touchcancel', function () {
$(this).removeClass('draggable');
resizeElement.removeClass('resizable');
});
$('.resizable').css('width', widthValue);
}).on('mouseup touchend touchcancel', function(){
dragElement.removeClass('draggable');
resizeElement.removeClass('resizable');
});
e.preventDefault();
}).on('mouseup touchend touchcancel', function(e){
dragElement.removeClass('draggable');
resizeElement.removeClass('resizable');
});
}
Same as above, but instead of images, I want to create content divs with text, images, html. Like 2 pages with a slider to compare both.
Your comparison script utilizes a resizing a div, so there's no way (that I know of) to achieve this without some considerable trickery (or how to achieve the same effect without resizing).
The only way to prevent the text from automatically wrapping is by using ...
white-space: nowrap;
... but that would just result in one continuous line of text.
Breaks <br> could be inserted from there, but that would just look awful and negate any resizing.
Personally, my approach would be to render the text within a canvas element first (https://www.w3schools.com/graphics/canvas_text.asp).
Since a canvas is treated nearly identical to that of an image, it wouldn't require any changes to the existing comparison script.

In Extjs4 how to set scrollbar position to bottom of form panel

i am working in extjs4. i have form panel with autoscroll true. I have 20-25 fields with fileUpload field at bottom. When i am uploading file, form's scroll is going to top by default. i want to keep scroll of form as it is on where it was while uploading file. So how to set this scrollBar at bottom of or at upload field section in extjs4
You can try by adding the following method to your form declaration:
scrollToField: function(fieldId) {
var field = Ext.get(fieldId);
field.el.scrollIntoView(this.body.el);
}
Here you have a working sample
IMHO,it will be better, however, to group fields using tabs or something similar to avoid having a long a and hard to read / fill form
I have solve this problem into Ext js 4.2 for Ext.form.panel
See the following code. It will helpful to you.
onRender function call on render event
onRender: function () {
this.callParent(arguments);
if (!this.restoreScrollAfterLayout) {
this.mon(Ext.get(this.getEl().dom.lastElementChild), 'scroll', this.onScroll, this);
this.restoreScrollAfterLayout = true;
}
},
onScroll: function (e ,t, eOpts) {
this.scroll = Ext.get(this.getEl().dom.lastElementChild).getScroll();
},
afterLayout: function () {
this.callParent(arguments);
if (this.restoreScrollAfterLayout && this.scroll) {
var el = Ext.get(this.getEl().dom.lastElementChild),
scroll = this.scroll;
el.scrollTo('left', scroll.left);
el.scrollTo('top', scroll.top);
}
}

Unable to display button in tableViewRow in titanium

i am new to titanium development.i am developing ToDo application using Titanium for learning purpose.i able to display the data from database and generate tableViewRow successfully but i am stuck in one phase that i unable to display button in each row.i did R&D for it but i cant get solution.here is my code for display buttons in each row of tableViewRow it display all records from database in each row but not buttons.it shows [object TableViewRow] in each row instead of button. so please help me to solve the issue
![Titanium.UI.setBackgroundColor('black');
var win = Titanium.UI.createWindow
({
title:'Tab 1',
backgroundColor:'#fff'
});
var db = Titanium.Database.install('/mydata/ToDoDB', 'ToDoDB');
var rows = db.execute('SELECT * FROM task');
var data1=[];
while(rows.isValidRow())
{
var rowview=Titanium.UI.createTableViewRow();
var btn=Titanium.UI.createButton
({
right:'20dp',
width:'60dp',
height:'40dp',
title:'Show'
});
rowview.add(btn);
var tt=rows.fieldByName('title');
var cc=rows.fieldByName('content');
//data1.push({title:rows.fieldByName('title')},{title:rows.fieldByName('content')},{title:rowview});
data1.push({title:tt+cc+rowview});
rows.next();
//rowview.add(btn);
};
rows.close();
var yourTable = Ti.UI.createTableView
({
width : Ti.UI.FILL,
height : Ti.UI.FILL,
data: data1
});
db.close();
win.add(yourTable);
win.open();
Try the following
var rowview = Titanium.UI.createTableViewRow();
var tt=rows.fieldByName('title');
var cc=rows.fieldByName('content');
var btn=Titanium.UI.createButton({
right:'20dp',
width:'60dp',
height:'40dp',
title:'Show'
});
var labeltt=Titanium.UI.createLabel({
left:'20dp',
width:'60dp',
height:'40dp',
text:tt
});
var labelcc=Titanium.UI.createLabel({
left:'80dp',
width:'60dp',
height:'40dp',
text:cc
});
rowview.add(labeltt);
rowview.add(labelcc);
rowview.add(btn);
data1.push(rowview);
I didn't tried this code, so there should be some alignment issues. I hope this will help you
what you are looking for is a custom row once you start including buttons and such.
Here is a old but still informative example
http://cssgallery.info/custom-row-for-tableview-in-appcelerator-titanium/
Basic idea is that you create a view, place it in the row, and then add the additional row UI object into that view

How to use SettingsPane with MVVM Light in metro style app

I use MVVM Light Framework for a metro style app.
I want add a command in SettingsPane to show an about page. The about page should be displayed on the right (like preinstalled calendar app). For a test I have added following line in OnLaunched method in App.xaml.cs:
SettingsPane.GetForCurrentView().CommandsRequested += App_CommandsRequested;
and following event handler:
void App_CommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
{
// Add an About command
var about = new SettingsCommand("about", "About", (handler) =>
{
// show about page in flyout transition...
});
args.Request.ApplicationCommands.Add(about);
}
Is this the only way?
How can I flyout the about page? Any tips...?
Thanks for help!
Michael
to answer the first question:
as far as I know, This is the only way to do something like that.
To answer the second question:
To flyout the the about page you can do this:
// Add an About command
var about = new SettingsCommand("about", "About", (handler) =>
{
// show about page in flyout transition...
var currentPane = new AboutPane(); // the aboutpane is a page
var myPopup = new Popup();
myPopup.IsLightDismissEnabled = true;
myPopup.Width = _settingsWidth;
myPopup.Height = Window.Current.Bounds.Height;
myPopup.Width = 346;
myPopup.Height = Window.Current.Bounds.Height;
myPopup.Child = currentPane;
myPopup.SetValue(Canvas.LeftProperty, Window.Current.Bounds.Width - 346);
myPopup.SetValue(Canvas.TopProperty, 0);
myPopup.IsOpen = true;
});
args.Request.ApplicationCommands.Add(about);
I hope this will solve you're problem.
Michael, try using the SettingsFlyout control from the Callisto project on github
You will need something like:
using Callisto.Controls;
//... other code here
//in your callback for handling the settings command:
// show about page in flyout transition...
var settingsFlyout = new SettingsFlyout();
settingsFlyout.Content = new AboutControl(); //this would be your own user control that contains the about page content
settingsFlyout.IsOpen = true;

Sencha Touch - switching between views

i am trying to make the same app with the miamicode, i am at step 3
http://miamicoder.com/2012/how-to-create-a-sencha-touch-2-app-part-3/
i try to make the button that goes to new note (switch to a new screen and create a new note)
the code at the example is this:
onNewNoteCommand: function () {
console.log("onNewNoteCommand");
var now = new Date();
var noteId = (now.getTime()).toString() + (this.getRandomInt(0, 100)).toString();
var newNote = Ext.create("NotesApp.model.Note", {
id: noteId,
dateCreated: now,
title: "",
narrative: ""
});
this.activateNoteEditor(newNote);
}
the activateNotesList function is this :
activateNotesList: function () {
Ext.Viewport.animateActiveItem(this.getNotesListView(), this.slideRightTransition);
on my own example i try just to go the editview without passing data.
so i try this:
onNewNoteCommand:function()
{
var noteEditor = this.getNoteEditor();
// Ext.Viewport.add(noteEditor); also tried this.
Ext.Viewport.setActiveItem(noteEditor);
that code runs with no errors but the screen doesn't change.
any suggestion? whats the difference on add ?
how do i set the viewport (haven't created any custom viewport) to card? is this the problem that setactiveitem doesn't work? any other way to switch between views?
Are there some errors in google chrome browser's console? Ctrl+Shift+J to open.
Also you have to check if noteEditor equals Object or Number.
From sencha docs: setActiveItem( Object/Number activeItem )