Skip to content

Instantly share code, notes, and snippets.

@moduscreate
Created April 26, 2013 18:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save moduscreate/5469322 to your computer and use it in GitHub Desktop.
Save moduscreate/5469322 to your computer and use it in GitHub Desktop.
Ext.ux.ActionList and Ext.ux.ActionListItem classes for Sencha Touch 2.2 in Action
/** CSS
.flexbox {
display : -webkit-box;
height : 47px;
background-color : rgb(231, 231, 231);
-webkit-box-shadow : inset 0 5px 5px #888;
}
.opaque-list-item {
background-color : rgba(247, 247, 247, 1);
z-index : 99;
position : absolute;
top : 0;
}
.list-icon {
margin : -5px 5px 0;
background-position : center center;
background-repeat : no-repeat;
width : 32px;
height : 32px;
margin-top : 7px;
}
**/
/**** ACTION LIST ITEM CLASS ****/
Ext.define('Ext.ux.ActionListItem', {
extend : 'Ext.dataview.component.ListItem',
xtype : 'actionlistitem',
config : {
actionsEl : null,
actionsTpl : [
'<div class="flexbox">',
'<tpl for=".">',
'<div class="list-action list-icon {.}" action="{.}"> </div>',
'</tpl>',
'<span class="target-dismiss list-icon remove_2" action="dismiss"> </span>',
'</div>'
].join('')
},
applyActionsTpl : function(cfg) {
if (typeof cfg == 'string') {
return Ext.create('Ext.XTemplate', cfg);
}
},
initialize : function() {
var me = this,
myElement = me.element;
me.callParent();
myElement.on({
scope : me,
tap : 'onActionTap'
});
myElement.on({
scope : me,
drag : 'onDrag',
dragend : 'onDragEnd',
delegate : '.x-list-item-inner'
});
},
onActionTap : function(eventObj) {
var me = this,
action = eventObj.target.getAttribute('action');
if (action) {
if (action != 'dismiss') {
me.fireEvent('actiontap', me, action, me.getRecord());
}
me.hideActions();
}
if (me.getActionsEl()) {
eventObj.stopEvent();
}
},
onDrag : function(event) {
if (this.isAnimating || this.isShowingActions) {
return;
}
var me = this,
currXY = event.getXY(),
currX = currXY[0],
currY = currXY[1],
prevX = me.prevX || currX,
prevY = me.prevY || currY,
deltaX = currX - prevX,
deltaY = currY - prevY,
initX = me.initialDragX,
moveToX;
me.prevX = currX;
me.prevY = currY;
// Vertical Dragging
if (Math.abs(deltaY) >= 1) {
me.isDraggingVertical = true;
}
// Horizontal Dragging
else if (Math.abs(deltaX) >= 5) {
me.isDraggingHorizontal = true;
if (! initX) {
me.initialDragX = currX;
}
if (currX < initX) {
me.dragDirection = 'left';
moveToX = currX - initX;
}
else if (currX > initX) {
me.dragDirection = 'right';
moveToX = Math.abs(currX - initX);
}
me.fireEvent('horizontaldrag', me, moveToX);
}
},
showActions : function(actions, moveToX) {
var me = this,
itemDockBody = me.element.down('.x-dock-body'),
itemTextElCt = itemDockBody.down('.x-list-item-inner'),
itemTextElCtStyle = itemTextElCt.dom.style,
itemActionsEl = me.getActionsEl(),
actionsTpl = me.getActionsTpl();
itemTextElCt.addCls('opaque-list-item');
if (! itemActionsEl) {
itemActionsEl = actionsTpl.append(itemDockBody, actions);
itemActionsEl = Ext.get(itemActionsEl);
me.setActionsEl(itemActionsEl);
itemTextElCtStyle.webkitTransitionTimingFunction = 'ease-out';
itemTextElCtStyle.webkitTransitionProperty = 'translate3d';
itemTextElCtStyle.webkitTransitionDuration = '.15s';
}
itemActionsEl.setWidth(itemTextElCt.getWidth());
itemTextElCtStyle.webkitTransform = 'translate3d(' + moveToX + 'px, 0, 0)';
},
onDragEnd : function() {
if (! this.dragDirection) {
return;
}
var me = this,
itemDockBody = me.element.down('.x-dock-body'),
dockBodyWidth = itemDockBody.getWidth(),
itemTextElCt = itemDockBody.down('.x-list-item-inner'),
itemTextElStyle = itemTextElCt.dom.style,
moveToX = dockBodyWidth,
transitionEndFn = function() {
itemTextElCt.dom.removeEventListener('webkitTransitionEnd', transitionEndFn);
delete me.isAnimating;
};
me.isShowingActions = true;
me.isAnimating = true;
if (me.isDraggingHorizontal) {
me.fireEvent('horizontaldragend', me);
}
if (me.dragDirection === 'left') {
moveToX *= -1;
}
itemTextElCt.dom.addEventListener('webkitTransitionEnd', transitionEndFn);
itemTextElStyle.webkitTransitionDuration = '.20s';
itemTextElStyle.webkitTransform = 'translate3d(' + moveToX + 'px, 0, 0)';
delete me.prevX;
delete me.prevY;
delete me.isDraggingHorizontal;
delete me.initialDragX;
delete me.dragDirection;
},
hideActions : function() {
if (! this.getActionsEl()) {
return;
}
var me = this,
itemDockBody = me.element.down('.x-dock-body'),
itemTextElCt = itemDockBody.down('.x-list-item-inner'),
itemTextElCtDom = itemTextElCt.dom,
itemTextElCtStyle = itemTextElCtDom.style,
transitionListener = function() {
itemTextElCtDom.removeEventListener('webkitTransitionEnd', transitionListener);
itemTextElCtStyle.webkitTransitionDuration = '0s';
itemTextElCtStyle.webkitTransform = 'translate3d(0,0,0)';
itemTextElCt.removeCls('opaque-list-item');
me.clearActionsEl();
};
itemTextElCtDom.addEventListener('webkitTransitionEnd', transitionListener);
itemTextElCtStyle.webkitTransform = 'translate3d(0,0,0)';
},
clearActionsEl : function() {
var me = this;
me.element.down('.x-list-item-inner');
Ext.destroy(me.getActionsEl());
me.setActionsEl(null) ;
delete me.isShowingActions;
}
});
/**** ACTION LIST CLASS ****/
Ext.define('Ext.ux.ActionList', {
extend : 'Ext.dataview.List',
xtype : 'actionlist',
requires : [ 'Ext.ux.ActionListItem' ],
config : {
defaultType : 'actionlistitem',
actions : null,
currentActionsItem : null,
control : {
'container > actionlistitem' : {
actiontap : 'onActionItemTap',
// Custom events fired by ActionListItem
horizontaldrag : 'onItemHorizontalDrag',
horizontaldragend : 'onItemHorizontalDragEnd'
}
}
},
initialize : function() {
var me = this;
me.callParent();
me.getScrollable().getScroller().on({
scope : me,
scroll : 'onScrollClearActionsEl'
});
me.on({
scope : me,
select : 'onItemSelectClearActionsEl'
});
},
onItemHorizontalDrag : function(item, moveToX) {
var me = this,
scrollable = me.getScrollable(),
scroller = scrollable.getScroller(),
currActions = me.getCurrentActionsItem();
scroller.setDisabled(true);
scrollable.hideIndicators();
item.showActions(this.getActions(), moveToX);
if (currActions != item) {
me.onScrollClearActionsEl();
}
me.deselectAll();
me.setCurrentActionsItem(item);
},
onItemHorizontalDragEnd : function(item, direction) {
var scrollable = this.getScrollable(),
scroller = scrollable.getScroller();
scroller.setDisabled(false);
},
onScrollClearActionsEl : function() {
var me = this,
actionItem = me.getCurrentActionsItem();
if (actionItem) {
actionItem.hideActions();
me.setCurrentActionsItem(null);
}
},
onItemSelectClearActionsEl : function() {
this.onScrollClearActionsEl();
},
onActionItemTap : function(listItem, action, record) {
var me = this;
me.setCurrentActionsItem(null);
me.deselectAll();
me.fireEvent('actiontap', me, listItem, action, record);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment