app:search
| Widget Name | appcelerator search |
| Element | <app:search> |
| Author | Hamed Hashemi |
| Homepage | http://www.appcelerator.org |
| Description | search widget |
- Required Attributes (3)
- Optional Attributes (15)
- Examples (1)
- Source code
| Name | Type | Description | Default value |
|---|---|---|---|
| request | Appcelerator Message Send | Request message being sent to search | Not specified |
| response | Appcelerator Message Send | Response message for search results | Not specified |
| selected | Appcelerator Message Send | Message sent when the user has selected an option | Not specified |
| Name | Type | Description | Default value |
|---|---|---|---|
| key | Identifier | Parameter name used in the request for the query | key |
| property | Identifier | Property in the response used for the results | result |
| resultId | Identifier | Property to use from the result to send selected message when using complex results | id |
| inputWidth | CSS Dimension | Width of the input field | 200 |
| resultWidth | CSS Dimension | Width of the results | 220 |
| delay | Time value | Delay before firing request message | 200 |
| indicator | Element Id | Indicator id to show or hide | Not specified |
| activeClass | CSS Class name | Active class for selecting search results | search_result_active |
| inactiveClass | CSS Class name | Inactive class for selecting search results | search_result_inactive |
| fieldset | Fieldset | Fieldset applied to the input element | Not specified |
| class | CSS Class name | Class applied to the input element | Not specified |
| name | Identifier | Name applied to the input element | Not specified |
| value | Unknown | Value attribute applied to the input element | Not specified |
| on | On Expression | On attribute applied to the input element | Not specified |
| safariSearch | Boolean | Whether or not to use type search for Safari | true |
Back to menuExample: Simple Example
$MQ('l:search.response', {result: ['item 1','item 2','item 3']});
#{name}
#{city}, #{job}
$MQ('l:search2.response', {result: [{id: 1, name: 'John', city: 'Atlanta', job: 'Engineer'}, {id: 2, name: 'Bob', city: 'New York', job: 'Mayor'}, {id: 3, name: 'Bill', city: 'Seattle', job: 'Plumber'}]});
This is a simple example that uses the <app:search>.
Here is a real simple example
<app:search request="l:search.request" response="l:search.response" selected="l:search.selected" key="search" property="result"> </app:search> <app:script on="l:search.request then execute"> $MQ('l:search.response', {result: ['item 1','item 2','item 3']}); </app:script>
Here’s another example with a complex search result.
You've selected an item with id .
<app:search request="l:search2.request" response="l:search2.response" selected="l:search2.selected" key="search" property="result"> <html:div> #{name} </html:div> <html:div> #{city}, #{job} </html:div> </app:search> <app:script on="l:search2.request then execute"> $MQ('l:search2.response', {result: [{id: 1, name: 'John', city: 'Atlanta', job: 'Engineer'}, {id: 2, name: 'Bob', city: 'New York', job: 'Mayor'}, {id: 3, name: 'Bill', city: 'Seattle', job: 'Plumber'}]}); </app:script> <div style="border:1px solid #ccc;background-color:#f6f6f6;padding:10px;margin-top:10px;display:none" on="l:search2.selected then effect[appear] or l:search2.request then effect[fade]"> You've selected an item with id <span on="l:search2.selected then value[value]"></span>. </div>
1 /* 2 * This file is part of Appcelerator. 3 * 4 * Copyright (C) 2006-2008 by Appcelerator, Inc. All Rights Reserved. 5 * For more information, please visit http://www.appcelerator.org 6 * 7 * Appcelerator is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * 20 */ 21 22 Appcelerator.Widget.Search = 23 { 24 getName: function() 25 { 26 return 'appcelerator search'; 27 }, 28 getDescription: function() 29 { 30 return 'search widget'; 31 }, 32 getVersion: function() 33 { 34 return '1.0.1'; 35 }, 36 getSpecVersion: function() 37 { 38 return 1.0; 39 }, 40 getAuthor: function() 41 { 42 return 'Hamed Hashemi'; 43 }, 44 getModuleURL: function () 45 { 46 return 'http://www.appcelerator.org'; 47 }, 48 isWidget: function () 49 { 50 return true; 51 }, 52 getWidgetName: function() 53 { 54 return 'app:search'; 55 }, 56 getAttributes: function() 57 { 58 var T = Appcelerator.Types; 59 return [{ 60 name: 'request', 61 optional: false, 62 type: T.messageSend, 63 description: "Request message being sent to search" 64 }, { 65 name: 'response', 66 optional: false, 67 type: T.messageSend, 68 description: "Response message for search results" 69 }, { 70 name: 'selected', 71 optional: false, 72 type: T.messageSend, 73 description: "Message sent when the user has selected an option" 74 }, { 75 name: 'key', 76 optional: true, 77 defaultValue: 'key', 78 type: T.identifier, 79 description: "Parameter name used in the request for the query" 80 }, { 81 name: 'property', 82 optional: true, 83 defaultValue: 'result', 84 type: T.identifier, 85 description: "Property in the response used for the results" 86 }, { 87 name: 'resultId', 88 optional: true, 89 defaultValue: 'id', 90 type: T.identifier, 91 description: "Property to use from the result to send selected message when using complex results" 92 }, { 93 name: 'inputWidth', 94 optional: true, 95 defaultValue: '200', 96 type: T.cssDimension, 97 description: "Width of the input field" 98 }, { 99 name: 'resultWidth', 100 optional: true, 101 defaultValue: '220', 102 type: T.cssDimension, 103 description: "Width of the results" 104 }, { 105 name: 'delay', 106 optional: true, 107 defaultValue: 200, 108 type: T.time, 109 description: "Delay before firing request message" 110 }, { 111 name: 'indicator', 112 optional: true, 113 type: T.elementId, 114 description: "Indicator id to show or hide" 115 }, { 116 name: 'activeClass', 117 optional: true, 118 defaultValue: 'search_result_active', 119 type: T.cssClass, 120 description: "Active class for selecting search results" 121 }, { 122 name: 'inactiveClass', 123 optional: true, 124 defaultValue: 'search_result_inactive', 125 type: T.cssClass, 126 description: "Inactive class for selecting search results" 127 }, { 128 name: 'fieldset', 129 optional: true, 130 type: T.fieldset, 131 description: "Fieldset applied to the input element" 132 }, { 133 name: 'class', 134 optional: true, 135 type: T.cssClass, 136 description: "Class applied to the input element" 137 }, { 138 name: 'name', 139 optional: true, 140 type: T.identifier, 141 description: "Name applied to the input element" 142 }, { 143 name: 'value', 144 optional: true, 145 description: "Value attribute applied to the input element" 146 }, { 147 name: 'on', 148 optional: true, 149 type: T.onExpr, 150 description: "On attribute applied to the input element" 151 }, { 152 name: 'safariSearch', 153 defaultValue: true, 154 optional: true, 155 type: T.bool, 156 description: "Whether or not to use type search for Safari" 157 }]; 158 }, 159 ignoreFieldset: function() 160 { 161 return true; 162 }, 163 compileWidget: function(params) 164 { 165 var id = params['id']; 166 var input = $(id); 167 var request = params['request']; 168 var response = params['response']; 169 var selected = params['selected']; 170 var elementScope = params['scope']; 171 var key = params['key']; 172 var property = params['property']; 173 var activeClass = params['activeClass']; 174 var inactiveClass = params['inactiveClass']; 175 var select = $(id+'_select'); 176 var resultId = params['resultId']; 177 var delay = params['delay']; 178 var indicator = params['indicator']; 179 var hideResults = params['hideResults']; 180 var compiled = null; 181 182 if (params['template']) 183 { 184 compiled = eval(params['template'] + '; init_'+id); 185 } 186 187 $MQL(response, 188 function(t, data, datatype, direction) 189 { 190 if (indicator) 191 { 192 Element.hide(indicator); 193 } 194 var value = property ? Object.getNestedProperty(data, property) : data; 195 196 Appcelerator.Compiler.destroy(select); 197 198 while (select.hasChildNodes()) 199 { 200 select.removeChild(select.firstChild); 201 } 202 203 var selectableData = []; 204 205 for (var i = 0; i < value.length; i++) 206 { 207 (function(){ 208 var optionId = Appcelerator.Compiler.generateId(); 209 var optionValue = value[i]; 210 var optionCode = '<div id="'+optionId+'" style="width: 100%" class="search_result_inactive">'; 211 if (compiled) 212 { 213 for (idx in optionValue) 214 { 215 if (typeof optionValue[idx] == 'string') 216 { 217 optionValue[idx] = optionValue[idx].replace(/'/,'\u2019'); 218 } 219 } 220 optionCode += compiled(optionValue); 221 } 222 else 223 { 224 optionCode += optionValue; 225 } 226 optionCode += '</div>'; 227 new Insertion.Bottom(select, optionCode); 228 var option = $(optionId); 229 option.onclick = function(event) 230 { 231 if (compiled) 232 { 233 $MQ(selected, {value: optionValue[resultId]}); 234 } 235 else 236 { 237 $MQ(selected, {value: optionValue}); 238 input.value = optionValue; 239 } 240 } 241 option.onmouseover = function() 242 { 243 for (var i = 0; i < select.selectableData.length; i++) 244 { 245 Element.addClassName($(select.selectableData[i].id), inactiveClass); 246 Element.removeClassName($(select.selectableData[i].id), activeClass); 247 } 248 Element.removeClassName(this, inactiveClass); 249 Element.addClassName(this, activeClass); 250 }; 251 option.onmouseout = function() 252 { 253 Element.addClassName(this, inactiveClass); 254 Element.removeClassName(this, activeClass); 255 }; 256 selectableData.push({id: optionId, value: optionValue}); 257 })(); 258 } 259 260 select.selectedIndex = -1; 261 select.selectableData = selectableData; 262 263 Appcelerator.Compiler.dynamicCompile(select); 264 265 if (select.selectableData.length > 0) 266 { 267 Effect.Appear(id+'_results', {duration: 0.5}); 268 } 269 else 270 { 271 Element.hide(id+'_results'); 272 } 273 }, 274 elementScope); 275 276 var selectFunction = function() 277 { 278 (function(){ 279 if (select.selectedIndex >= 0) 280 { 281 var selected = select.selectableData[select.selectedIndex]; 282 if (selected) 283 { 284 if (!compiled) 285 { 286 input.value = selected.value; 287 } 288 289 for (var i = 0; i < select.selectableData.length; i++) 290 { 291 Element.addClassName($(select.selectableData[i].id), inactiveClass); 292 Element.removeClassName($(select.selectableData[i].id), activeClass); 293 } 294 Element.removeClassName($(selected.id), inactiveClass); 295 Element.addClassName($(selected.id), activeClass); 296 } 297 } 298 else 299 { 300 for (var i = 0; i < select.selectableData.length; i++) 301 { 302 Element.addClassName($(select.selectableData[i].id), inactiveClass); 303 Element.removeClassName($(select.selectableData[i].id), activeClass); 304 } 305 } 306 })(); 307 }; 308 309 var timer = null; 310 var keystrokeCount = 0; 311 var timerFunc = function() 312 { 313 if (indicator) 314 { 315 Element.show(indicator); 316 } 317 318 keystrokeCount = 0; 319 var payload = {}; 320 payload[key] = input.value; 321 $MQ(request, payload); 322 }; 323 324 input.onkeydown = function (event) 325 { 326 (function(){ 327 event = event || window.event; 328 329 switch(event.keyCode) 330 { 331 case Event.KEY_TAB: 332 case Event.KEY_LEFT: 333 case Event.KEY_RIGHT: 334 case Event.KEY_ESC: 335 { 336 Effect.Fade(id+'_results', {duration: 0.5}); 337 Event.stop(event); 338 return; 339 } 340 case Event.KEY_RETURN: 341 { 342 Effect.Fade(id+'_results', {duration: 0.5}); 343 if (select.selectableData && select.selectedIndex >= 0) 344 { 345 if (compiled) 346 { 347 $MQ(selected, {value: select.selectableData[select.selectedIndex].value[resultId]}); 348 } 349 else 350 { 351 $MQ(selected, {value: select.selectableData[select.selectedIndex].value}); 352 } 353 } 354 Event.stop(event); 355 return; 356 } 357 case Event.KEY_UP: 358 { 359 if (select.selectableData && select.selectableData.length > 0) 360 { 361 Effect.Appear(id+'_results', {duration: 0.5}); 362 select.selectedIndex--; 363 if (select.selectedIndex < 0) 364 { 365 select.selectedIndex = select.selectableData.length-1; 366 } 367 selectFunction(); 368 } 369 Event.stop(event); 370 return; 371 } 372 case Event.KEY_DOWN: 373 { 374 if (select.selectableData && select.selectableData.length > 0) 375 { 376 Effect.Appear(id+'_results', {duration: 0.5}); 377 select.selectedIndex++; 378 if (select.selectedIndex > select.selectableData.length-1) 379 { 380 select.selectedIndex = 0; 381 } 382 selectFunction(); 383 } 384 Event.stop(event); 385 return; 386 } 387 } 388 389 if (timer) 390 { 391 clearTimeout(timer); 392 timer = null; 393 } 394 395 if (keystrokeCount++ < 10) 396 { 397 timer = setTimeout(timerFunc, delay); 398 } 399 else 400 { 401 timerFunc(); 402 } 403 })(); 404 }; 405 406 input.onblur = function (event) 407 { 408 setTimeout(function() 409 { 410 Effect.Fade(id+'_results', {duration: 0.5}); 411 },100); 412 } 413 414 input.onfocus = function (event) 415 { 416 if (input.value.length > 0 && select.selectableData && select.selectableData.length > 0) 417 { 418 Effect.Appear(id+'_results', {duration: 0.5}); 419 } 420 } 421 }, 422 buildWidget: function(element,parameters) 423 { 424 parameters['scope'] = element.scope; 425 426 if (element.innerHTML.strip().length > 0) 427 { 428 parameters['template'] = Appcelerator.Compiler.compileTemplate(Appcelerator.Compiler.getHtml(element),true,'init_'+element.id); 429 } 430 431 var inputType = (Appcelerator.Browser.isSafari && (parameters['safariSearch'] != "false")) ? 'search' : 'text'; 432 433 var html = '<div style="position: relative">'; 434 html += '<table style="padding: 0; margin: 0" cellpadding="0" cellspacing="0"><tr><td><input autocomplete="off" type="'+inputType+'" id="'+element.id+'" style="width: '+parameters['inputWidth']+'px" '; 435 if (parameters['fieldset']) 436 { 437 html += ' fieldset="'+parameters['fieldset']+'" '; 438 } 439 if (parameters['class']) 440 { 441 html += ' class="'+parameters['class']+'" '; 442 } 443 if (parameters['name']) 444 { 445 html += ' name="'+parameters['name']+'" '; 446 } 447 html += '/></td></tr></table>'; 448 html += '<div style="display:none;z-index:2;position:absolute; left: 0px" id="'+element.id+'_results" on="'+parameters['selected']+' then hide">'; 449 html += '<div id="'+element.id+'_select" style="width: '+parameters['resultWidth']+'px; border: 1px #000 solid; cursor: pointer;"></div></div>'; 450 html += '</div>'; 451 452 return { 453 'position' : Appcelerator.Compiler.POSITION_REPLACE, 454 'presentation' : html, 455 'wire' : true, 456 'compile' : true 457 }; 458 } 459 }; 460 461 Appcelerator.Core.loadModuleCSS('app:search','search.css'); 462 Appcelerator.Widget.register('app:search',Appcelerator.Widget.Search); 463
Chapters
- Web Expressions (Interaction)
- Web Expressions (Visual)
- Web Expression Macros
-
Widget Reference
- app:as_flexflow
- app:box
- app:button
- app:calendar
- app:chart
- app:content
- app:datacache
- app:datatable
- app:download
- app:editinplace
- app:ext_grid
- app:ext_paging_grid
- app:ext_tree
- app:field
- app:folder
- app:graphical_music_player
- app:http
- app:if
- app:imagetransition
- app:iterator
- app:message
- app:modalbox
- app:modaldialog
- app:mp3player
- app:music_player
- app:pagination
- app:panel
- app:progressbar
- app:script
- » app:search
- app:security
- app:shadowbox
- app:simple_panel
- app:statemachine
- app:stopwatch
- app:tabpanel
- app:template
- app:tooltip
- app:upload
- app:validation
- app:widget
- app:yui_map
- CSS Helper Classes
- Advanced Configuration
- Debugging
- Forms
- Localization