app:as_flexflow
  • Required Attributes (1)
  • Optional Attributes (5)
  • Examples (1)
  • Source code
Name Type Description Default value
property Identifier The name of the property in the passed in array that contains the list of photos Not specified
Back to menuExample: Using the FlexFlow

app:as_flexflow wraps Doug Mccune’s coverflow widget: http://dougmccune.com/blog/2007/11/19/flex-coverflow-performance-improvement-flex-carousel-component-and-vertical-coverflow/

This is a simple example that uses the <app:as_flexflow>.

$MQ('l:show.images.1', {photos: [ {'id': 1, 'label': 'Jeff', 'image': '../../widgets/app_as_flexflow/doc/jeff.jpg'}, {'id': 2, 'label': 'Nolan', 'image': '../../widgets/app_as_flexflow/doc/nolan.jpg'}, {'id': 3, 'label': 'Matt', 'image': '../../widgets/app_as_flexflow/doc/matt.jpg'}, {'id': 4, 'label': 'Joe', 'image': '../../widgets/app_as_flexflow/doc/joe.jpg'}]});
<app:as_flexflow id="FlexFlowTest1" on="l:show.images.1 then execute or l:select then select" property="photos" 
        img_height="200" img_width="200" click_message="l:clicked">
</app:as_flexflow>
<app:script on="l:app.compiled then execute after 500">
    $MQ('l:show.images.1', {photos: [
        {'id': 1, 'label': 'Jeff', 'image': '../../widgets/app_as_flexflow/doc/jeff.jpg'},
        {'id': 2, 'label': 'Nolan', 'image': '../../widgets/app_as_flexflow/doc/nolan.jpg'},
        {'id': 3, 'label': 'Matt', 'image': '../../widgets/app_as_flexflow/doc/matt.jpg'},
        {'id': 4, 'label': 'Joe', 'image': '../../widgets/app_as_flexflow/doc/joe.jpg'}]});
</app:script>

The property referenced by the ‘property’ attribute needs to be an array of objects. The widget will preserve any additional data passed in for subsequent click events.

You can select a specific cover like-so:

<button on="click then l:select[id=2]">Select Nolan</button>

Click on Jeff to see an alert:

if(this.data.label == "Jeff") { alert("Thanks for using Appcelerator!"); }
<app:script on="l:clicked then execute">
    if(this.data.label == "Jeff")
    {
        alert("Thanks for using Appcelerator!");
    }
</app:script>

Note this widget will not work if accessed via a file URL and must be accessed through a web server.
Note #2 this widget only works when there is one per page

  1 Appcelerator.Widget.AppAsFlexflow =
  2 {
  3     flows: {}, 
  4     
  5 	/**
  6 	 * The name of the widget
  7 	 */
  8 	getName: function()
  9 	{
 10 		return 'app:as_flexflow';
 11 	},
 12 	/**
 13 	 * A description of what the widget does
 14 	 */
 15 	getDescription: function()
 16 	{
 17 		return 'app:as_flexflow uses the flex ajax bridge to show an iTunes like photo view';
 18 	},
 19 	/**
 20 	 * The version of the widget. This will automatically be corrected when you
 21 	 * publish the widget.
 22 	 */
 23 	getVersion: function()
 24 	{
 25 		return "1.0.2";
 26 	},
 27 	/**
 28 	 * The widget spec version.  This is used to maintain backwards compatability as the
 29 	 * Widget API needs to change.
 30 	 */
 31 	getSpecVersion: function()
 32 	{
 33 		return 1.0;
 34 	},
 35 	/**
 36 	 * The widget author's full name (that's you)
 37 	 */
 38 	getAuthor: function()
 39 	{
 40 		//TODO
 41 		return 'Tejus Parikh';
 42 	},
 43 	/**
 44 	 * The URL for more information about the widget or the author.
 45 	 */
 46 	getModuleURL: function ()
 47 	{
 48 		//TODO
 49 		return 'http://www.appcelerator.org';
 50 	},
 51 	/**
 52 	 * This should always return true for widgets.
 53 	 */
 54 	isWidget: function ()
 55 	{
 56 		return true;
 57 	},
 58 	/**
 59 	 * The widget's tag name
 60 	 */
 61 	getWidgetName: function()
 62 	{
 63 		return 'app:as_flexflow';
 64 	},
 65 	/**
 66 	 * The attributes supported by the widget as attributes of the tag.  This metadata is 
 67 	 * important so that your widget can automatically be type checked, documented, 
 68 	 * so the IDE can auto-sense the widgets metadata for autocomplete, etc.
 69 	 */
 70 	getAttributes: function()
 71 	{
 72 		var T = Appcelerator.Types;
 73 		return [{
 74             name: 'on',
 75             optional: true,
 76 			type: Appcelerator.Types.onExpr,
 77             description: "May be used to execute the script's content."
 78         }, {
 79             name: 'property',
 80             optional: false,
 81 			type: T.identifier,
 82             description: "The name of the property in the passed in array that contains the list of photos"
 83         }, {
 84             name: 'click_message',
 85             optional: true,
 86 			type: Appcelerator.Types.messageSend,
 87             description: "Then name of the message sent when the flex flow is clicked"
 88         }, {
 89             name: 'img_height',
 90             optional: true,
 91 			type: Appcelerator.Types.naturalNumber,
 92 			defaultValue: 300,
 93             description: "Then name of the message sent when the flex flow is clicked"
 94         }, {
 95              name: 'img_width',
 96             optional: true,
 97 			type: Appcelerator.Types.naturalNumber,
 98 			defaultValue: 300,
 99             description: "Then name of the message sent when the flex flow is clicked"
100         }, {
101             name: 'label_position',
102             optional: true,
103             defaultValue: 'top',
104             description: "Where the label goes"
105         }];
106 	},
107 	/**
108 	 * return an array of function names for the actions the widget supports in the widget's 
109 	 * on expression.
110 	 */
111 	getActions: function()
112 	{
113 		return ['execute', 'select'];
114 	},
115 	execute: function(id,parameters,data,scope,version)
116 	{
117         var bridge_name = id + "_bridge";
118         var photos = data[parameters["property"]];
119         Appcelerator.Widget.AppAsFlexflow.flows[id] = photos;
120         var images = [];
121         for(var i = 0, length = photos.length; i < length; i++) 
122         {
123             images.push(photos[i]["image"]);
124         }
125         
126 	    var interval = setInterval( function()
127 	    {
128 	        if(typeof FABridge[bridge_name] != "undefined") {
129         	    var bridge = FABridge[bridge_name].root();
130         	    bridge.setDataProvider(images);
131                 var data = Appcelerator.Widget.AppAsFlexflow.flows[id][0];
132                 data.index = 0;
133                 
134 				$(id + "_label").innerHTML = data.label;
135         	    clearInterval(interval);
136     	    }
137     	    
138         }, 500);
139 	},	
140 	select: function(id,parameters,data,scope,version)
141 	{
142 	    var bridge_name = id + "_bridge";
143 	    var bridge = FABridge[bridge_name].root();
144 	    
145 	    var covers = Appcelerator.Widget.AppAsFlexflow.flows[id];
146 	    for(var i = 0, length = covers.length; i < length; i++) 
147 	    {
148 	        var selected = -1;
149 	        if(data['id'] == covers[i].id || data['image'] == covers[i].image || data['label'] == covers[i].label) 
150 	        {
151 	            selected = i;
152 	        } 
153 	        
154 	        if(selected != -1) {
155 	            bridge.getCfc().setSelectedIndex(i);
156 	            var data = covers[i];
157                 data.index = i;
158                 $MQ(id + "_select", data);
159 	            break;
160 	        }
161 	    }
162 	},
163 	/**
164 	 * this method will be called after the widget has been built, the content replaced and available
165 	 * in the DOM and when it is ready to be compiled.
166 	 *
167 	 * @param {object} parameters
168 	 */
169 	compileWidget: function(parameters)
170 	{
171 	    var id = parameters['id'];
172 	    var bridge_name = id + "_bridge";
173 		FABridge.addInitializationCallback(bridge_name, function() {
174             var bridge = FABridge[bridge_name].root();
175             bridge.setReflectionEnable(true);
176             bridge.setBgColor(0x000000);
177             bridge.setMaxImageWidth(parameters['img_width']);
178             bridge.setMaxImageHeight(parameters['img_height']); 
179             
180             bridge.getCfc().addEventListener("click", function() {
181                 var index = bridge.getCfc().getSelectedIndex();
182                 var data = Appcelerator.Widget.AppAsFlexflow.flows[id][index];
183                 data.index = index;
184 				$(id + "_label").innerHTML = data.label;
185                 setTimeout( function() {
186 					$MQ(parameters['click_message'], data);
187 				}, 1100);
188             }); 
189         });
190 	},
191 	/**
192 	 * this method will be called each time a <app:as_flexflow> is encountered in a page. the return object gives
193 	 * instructions to the compiler about how to process the widget.
194 	 *
195 	 * @param {element} dom element for the <app:as_flexflow> encountered in the page
196 	 * @param {object} parameters object for the attributes that <app:as_flexflow> supports
197 	 */
198 	buildWidget: function(element,parameters)
199 	{
200 	    var id = element.id;
201 	    var bridge_name = element.id + "_bridge";
202 	    if(typeof parameters['click_message'] == "undefined") {
203 	        parameters['click_message'] = "l:" + id + "_click";
204 	    }
205 	    
206 	    var box_height = parseInt(parameters['img_height']) + 100;
207 		var html = [];
208 		html.push('<div style="position:relative; background-color: black;" id="' + id + '">');
209 		
210 		if("top" == parameters['label_position']) {    
211     		html.push('<div style="background-color: black; color:white;padding-top:7px; position:absolute; top: -11px; text-align:center;width:100%"><span id="' + element.id + '_label" ');
212     		html.push('on="' + parameters['click_message'] + ' then hide and value[label] and show if expr[this.data.label] or l:' 
213     		        + element.id + '_select then hide and value[label] and show"');
214     		html.push('></span></div>');
215 		}
216 		
217 		html.push('<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"');
218         html.push('id="flow_object_' + element.id + '" width="100%" height="' + box_height + '"');
219         html.push('codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">');
220         html.push('  <param name="movie" value="' + Appcelerator.WidgetPath + 'app_as_flexflow/swf/FlexFlow.swf" />');
221         html.push('  <param name="flashvars" value="bridgeName=' + bridge_name + '"/>');
222         html.push('  <param name="quality" value="high" />');
223         html.push('  <param name="allowScriptAccess" value="sameDomain" />');
224         html.push('  <param name="wmode" value="transparent" />');
225         html.push('  <embed src="' + Appcelerator.WidgetPath + 'app_as_flexflow/swf/FlexFlow.swf" quality="high"');
226         html.push('    width="100%" height="' + box_height + '" name="' + bridge_name + '" ');
227         html.push('    align="middle"');
228         html.push('    play="true"');
229         html.push('    wmode="transparent"');
230         html.push('    loop="false"');
231         html.push('    quality="high"');
232         html.push('    allowScriptAccess="sameDomain"');
233         html.push('    type="application/x-shockwave-flash"');
234         html.push('    pluginspage="http://www.adobe.com/go/getflashplayer" ');
235         html.push('    flashvars="bridgeName=' + bridge_name + '">');
236         html.push('  </embed>');
237         html.push('</object>');
238         
239         if("bottom" == parameters['label_position']) {    
240     		html.push('<div style="color:white;position:relative;bottom:56px;text-align:center;width:100%"><span id="' + element.id + '_label" ');
241     		html.push('on="' + parameters['click_message'] + ' then hide and value[label] and show if expr[this.data.label] or l:' 
242     		        + element.id + '_select then hide and value[label] and show"');
243     		html.push('></span></div>');
244 		}
245 		
246 		
247         html.push('</div>');
248 		return {
249 			'presentation' : html.join(' '),   // this is the HTML to replace for the contents <app:as_flexflow>
250 			'position' : Appcelerator.Compiler.POSITION_REPLACE,  // usually the default, could be POSITION_REMOVE to remove <app:as_flexflow> entirely
251 			'wire' : true,  // true to compile the contents of the presentation contents replaced above
252 			'compile' : true,  // true to call compileWidget once the HTML has been replaced and available in the DOM
253 			'parameters': parameters  // parameters object to pass to compileWidget
254 		};		
255 	}
256 };
257 
258 /*
259 To load a custom widget CSS file - create a css file under the widget's css directory and 
260 reference it here. For example:
261   
262     Appcelerator.Widget.loadWidgetCSS('app:as_flexflow','mystyles.css');
263 
264 To load a widget that has widget JS dependencies, place your JS files under the widget's js
265 directory and use registerWidgetWithJS. For example:
266 
267     Appcelerator.Widget.registerWidgetWithJS('app:as_flexflow',Appcelerator.Widget.AppAsFlexflow,['a.js', 'b.js']);
268 
269 You can require a common JS file (loaded under widgets/common/js) and load your widget once it's loaded.
270 For example:
271 
272 	Appcelerator.Widget.requireCommonJS('scriptaculous/builder.js',function()
273 	{
274 	    Appcelerator.Widget.registerWidgetWithJS('app:as_flexflow',Appcelerator.Widget.AppAsFlexflow,['a.js']);
275 	});
276 
277 */
278 // Appcelerator.Widget.register('app:as_flexflow',Appcelerator.Widget.AppAsFlexflow);
279 Appcelerator.Widget.registerWidgetWithJS('app:as_flexflow',Appcelerator.Widget.AppAsFlexflow,['AC_OETags.js', 'FABridge.js']);
280 
281 
282 
283