Titanium Mobile - Swipe TableView cell left/right to expose another row behind - ios

I've been searching around on how to do this, but I've been unsuccessful.
What I'm trying to accomplish is this: I have a TableView with, say, 5 rows. I want to be able to swipe a row left to expose information "behind" the row. Not sure if this would be done by adding an additional row to the TableView and placing it behind, or what?
At the end of the day, what would be even cooler, would be to be able to swipe the row left OR right, and depending on which direction you swipe, the row behind gets populated with different information.
Any ideas?

From your description, it sounds like you want something similar to what Twitter does when you swipe across a Tweet.
First, make sure the rows in the table don't have vertical/horizontal layouts.
Then create the left and right swipe views you want for each row, like so:
var leftSwipeView = Ti.UI.createView({
width: Ti.UI.FILL,
height: Ti.UI.FILL,
backgroundColor: '#ff0000', //just to make the effect apparent
visible: false
}
var rightSwipeView = Ti.UI.createView({
width: Ti.UI.FILL,
height: Ti.UI.FILL,
backgroundColor: '#00ff00', //just to make the effect apparent
visible: false,
}
row.add(leftSwipeView);
row.add(rightSwipeView);
row.addEventListener('swipe', function(e) {
if (e.direction == 'left'){
leftSwipeView.setVisible(true);
setTimeout(function(){leftSwipeView.setVisible(false);}, 2000);
}
if (e.direction == 'right'){
rightSwipeView.setVisible(true);
setTimeout(function(){rightSwipeView.setVisible(false);}, 2000);
}
});
The snippet I have up there will hide the views again after 2 seconds. Hope that helps.

Found the perfect solution on Github.
https://github.com/rborn/TiSwipeToReveal

Related

how to make text vertically center in fabric js TextBox

I am working on one fabric js editor, in which I need to implement TextBox as a Button look and feel,
For that, I Have implemented TextBox with Background, But Problem is that Height of TextBox.
I am trying this kind of code :
var text = new fabric.Textbox("this is text", {
top: 0,
left: 0,
width: 300,
height: 500,
fill: 'red'
})
canvas.add(text);
Now my Textbox is rendered of width: 300 but height is not rendered. how can I set Height to My TextBox
And another Thing, when I set Height to TextBox, I need to keep text in Center of height (vertical center)
what should I do, I can't understand, how to override default fabtic.Textbox class.
Please help me, If any one have Any suggestion.

Scroll To Top button that only appears when you reached the end of the page

I think this is rather easy achieved, but I couldn't find out how to- and couldn't find much documentary about it.
I hate those 'scroll to top' buttons that appear after you already scrolled just 300px. Like I'm that lazy to scroll to top on myself. Therefor I would like to have a scroll to top button that only appears when you reached the bottom of the page (minus 100vh (100% viewport height).
Let's take in account the button is called .scrollTopButton and it's CSS is opacity: 0 and it's position: fixed on default.
How would I make the button appear when you reached the bottom of the page, minus 100vh and scroll along?
I was thinking of comparing the body height minus 100vh with (window).scrollTop().
var vH = $(window).height(),
bodyMinus100vh = ($('body').height() - vH);
if (bodyMinus100VH < $(window).scrollTop) {
$('.scrollTopButton').toggle();
};
Fixed it myself. Quite easy, honestly.
$(window).scroll(function () {
var vH = $(window).height(),
bodyHeight = ($(document).height() - (vH * 2)),
// When you open a page, you already see the website as big
// as your own screen (viewport). Therefor you need to reduce
// the page by two times the viewport
scrolledPX = $(window).scrollTop();
if (scrolledPX > bodyHeight) {
$('.scrollTopButton').css('opacity', '1');
} else {
$('.scrollTopButton').css('opacity', '0')
};
});

Trigger resizable in jasmine [duplicate]

I have a div element which is made jquery Resizable. It has alsoResize option set, so other elements resize simultaneously.
What I want to do, is to set size of this Resizable div element programmatically in such way, that all Resizable logic is triggered (especially this alsoResize option is taken into account).
How can I achieve that?
Update: It looks like the internals of jQuery UI have changed dramatically since I answered this and firing the event no longer works.
There's no direct way to fire the event anymore because the resizable plugin has been fundamentally changed. It resizes as the mouse is dragged rather than syncing items up at the end. This happens by it listening for the internal resize propagation event for resizable plugins which is now fired by the _mouseDrag handler. But it depends on variables set along the way, so just firing that even internally won't help.
This means even overriding it is messy at best. I'd recommend just manually resizing the alsoResize elements directly, independent of the UI widget altogether if that's possible.
But for fun let's say it isn't. The problem is that the internals of the plugin set various properties relating to previous and current mouse position in order to know how much to resize by. We can abuse use that to add a method to the widget, like this:
$.widget("ui.resizable", $.ui.resizable, {
resizeTo: function(newSize) {
var start = new $.Event("mousedown", { pageX: 0, pageY: 0 });
this._mouseStart(start);
this.axis = 'se';
var end = new $.Event("mouseup", {
pageX: newSize.width - this.originalSize.width,
pageY: newSize.height - this.originalSize.height
});
this._mouseDrag(end);
this._mouseStop(end);
}
});
This is just creating the mouse events that the resizable widget is looking for and firing those. If you wanted to do something like resizeBy it'd be an even simpler end since all we care about is the delta:
var end = $.Event("mouseup", { pageX: newSize.width, pageY: newSize.height });
You'd call the $.widget() method after jQuery UI and before creating your .resizable() instances and they'll all have a resizeTo method. That part doesn't change, it's just:
$(".selector").resizable({ alsoResize: ".other-selector" });
Then to resize, you'd call that new resizeTo method like this:
$(".selector").resizable("resizeTo", { height: 100, width: 200 });
This would act as if you instantly dragged it to that size. There are of course a few gotchas here:
The "se" axis is assuming you want resize by the bottom right - I picked this because it's by far the most common scenario, but you could just make it a parameter.
We're hooking into the internal events a bit, but I'm intentionally using as few internal implementation details as possible, so that this is less likely to break in the future.
It could absolutely break in future versions of jQuery UI, I've only tried to minimize the chances of that.
You can play with it in action with a fiddle here and the resizeBy version here.
Original answer:
You can do this:
$(".selector").trigger("resize");
alsoResize internally rigs up a handler to the resize event, so you just need to invoke that :)
You can trigger the bars programmatically. For example, to trigger the east-west resize event:
var elem =... // Your ui-resizable element
var eastbar = elem.find(".ui-resizable-handle.ui-resizable-e").first();
var pageX = eastbar.offset().left;
var pageY = eastbar.offset().top;
(eastbar.trigger("mouseover")
.trigger({ type: "mousedown", which: 1, pageX: pageX, pageY: pageY })
.trigger({ type: "mousemove", which: 1, pageX: pageX - 1, pageY: pageY })
.trigger({ type: "mousemove", which: 1, pageX: pageX, pageY: pageY })
.trigger({ type: "mouseup", which: 1, pageX: pageX, pageY: pageY }));
I am doing a 1px left followed by 1px right movement on the east bar handle.
To perform a full size, you can target .ui-resizable-handle.ui-resizable-se if you have east and south resize bars.
I needed the same thing for tests. Similar questions have only one promising answer https://stackoverflow.com/a/17099382/1235394, but it requires additional setup, so I ended with my own solution.
I have an element with resizable right edge
$nameHeader.resizable({handles: 'e', ... });
and I needed to trigger all callbacks during the test in order to resize all elements properly. The key part of test code:
var $nameHeader = $list.find('.list-header .name'),
$nameCell = $list.find('.list-body .name');
ok($nameHeader.hasClass('ui-resizable'), 'Name header should be resizable');
equal($nameCell.outerWidth(), 300, 'Initial width of Name column');
// retrieve instance of resizable widget
var instance = $nameHeader.data('ui-resizable'),
position = $nameHeader.position(),
width = $nameHeader.outerWidth();
ok(instance, 'Instance of resizable widget should exist');
// mouseover initializes instance.axis to 'e'
instance._handles.trigger('mouseover');
// start dragging, fires `start` callback
instance._mouseStart({pageX: position.left + width, pageY: position.top});
// drag 50px to the right, fires `resize` callback
instance._mouseDrag({pageX: position.left + width + 50, pageY: position.top});
// stop dragging, fires `stop` callback
instance._mouseStop({pageX: position.left + width + 50, pageY: position.top});
// ensure width of linked element is changed after resizing
equal($nameCell.outerWidth(), 350, 'Name column width should change');
Of course this code is brittle and may break when widget implementation changes.
Hack Disclaimer (tested on jQuery 1.12.4):
This basically waits for the dialog to be opened and then increments by 1px (which forces the resize() event) and then decrements by 1px (to regain original size)
just say this in the dialog open event handler:
$(this)
.dialog("option","width",$(this).dialog("option","width")+1)
.dialog("option","width",$(this).dialog("option","width")-1);
note:
This may not work with show effects (like fadeIn,slideDown etc) as the "resizer" code executes before the dialog is fully rendered.
$(".yourWindow").each(function(e) {
$(this).height($(this).find(".yourContent").height());
});
And the same with the width.

TextField Not horizontal scrolling with text[Titanium]

I want the textarea to scroll horizontally once the test string has exceeded the width of the textarea. I tried the below code, but however, it does not work for some reason.
I also tried adding a wrapper view to scroll view and adding the textarea to the wrapper view; but that does not work either.
How can I fix this ?
var scroll = Ti.UI.createScrollView({
top:40,
left:230,
width:290,
height:50
});
win.add(scroll);
var textType = Ti.UI.createTextArea({
backgroundColor:'#E6E6E6',
borderColor:'blue',
borderRadius:10,
top:0,
left:0,
width:290,
height:50,
font:{fontSize:26, fontFamily:customFont},
editable:false,
enabled:false,
textAlign:'right',
scrollable:true
});
scroll.add(textType);
I know that this sound really simple but, for default the text area is vertical scrollable. and this is the only behavior i know of it. i have tried different properties like:
layout:"horizontal",
horizontalWrap:true,
scrollable:true,
But this has not resolve the issue.

Titanium Appcelerator: How do I target $(this) element?

I am designing a flashcard app using titanium appcelerator, the final aim is to use a scrollable view to display each card in the 'pack' and then on tapping a single card (i.e. the card in view) this should rotate about it's axis (i.e. flip over) to reveal the reverse.
You can see from the diagram below what I am hoping to achieve.
Unfortunately when tap one of the panels, instead of it's child view animating, instead the last child in the scrollableview animates.
I understand this is something to do with the fact that I am assigning variables in a loop but if someone can look at my code and tell me what I am doing wrong that would be great.
In JQuery it would look something like this
$(FrontView).click(function(){
$(this).parent().flip() //how do I access $(this) and $(this).parent() in Appcelerator?
});
Here is my appcelerator code:
while(rows.isValidRow()){
var FrontView = Ti.UI.createView({
backgroundImage: '/global/card_bg.png',
width: 295,
height:297
});
var BackView = Ti.UI.createView({
backgroundImage: '/global/card_bg.png',
width: 295,
height:297
});
var ControlView = Titanium.UI.createView({
backgroundColor:"#333",
bubbleParent : false,
width: 295,
height:297,
top : 100
});
FrontView.addEventListener('singletap', function() {
Ti.API.info('singletap');
ControlView.animate({view:BackView,transition:Ti.UI.iPhone.AnimationStyle.FLIP_FROM_RIGHT});
});
BackView.addEventListener('singletap', function() {
Ti.API.info('singletap');
ControlView.animate({view:FrontView,transition:Ti.UI.iPhone.AnimationStyle.FLIP_FROM_LEFT});
});
$.scrollable_view.addView(ControlView);
ControlView.add(BackView);
ControlView.add(FrontView);
rows.next();
} //endwhile
Can anybody help?
If you put a return variable in your event callbacks, you can get access to the source of the tap. Try this and see if it works:
FrontView.addEventListener('singletap', function(e) {
Ti.API.info('singletap');
e.source.animate({view:BackView,transition:Ti.UI.iPhone.AnimationStyle.FLIP_FROM_RIGHT});
});
BackView.addEventListener('singletap', function(e) {
Ti.API.info('singletap');
e.source.animate({view:FrontView,transition:Ti.UI.iPhone.AnimationStyle.FLIP_FROM_LEFT});
});
I found out that it works when you flip the card in the EventListener of your Scrollable View.
Check this out: https://gist.github.com/4683264

Resources