You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

897 lines
28 KiB

10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. /*
  2. * # Semantic - Search
  3. * http://github.com/semantic-org/semantic-ui/
  4. *
  5. *
  6. * Copyright 2014 Contributor
  7. * Released under the MIT license
  8. * http://opensource.org/licenses/MIT
  9. *
  10. */
  11. ;(function ($, window, document, undefined) {
  12. "use strict";
  13. $.fn.search = function(parameters) {
  14. var
  15. $allModules = $(this),
  16. moduleSelector = $allModules.selector || '',
  17. time = new Date().getTime(),
  18. performance = [],
  19. query = arguments[0],
  20. methodInvoked = (typeof query == 'string'),
  21. queryArguments = [].slice.call(arguments, 1),
  22. returnedValue
  23. ;
  24. $(this)
  25. .each(function() {
  26. var
  27. settings = $.extend(true, {}, $.fn.search.settings, parameters),
  28. className = settings.className,
  29. selector = settings.selector,
  30. error = settings.error,
  31. namespace = settings.namespace,
  32. eventNamespace = '.' + namespace,
  33. moduleNamespace = namespace + '-module',
  34. $module = $(this),
  35. $prompt = $module.find(selector.prompt),
  36. $searchButton = $module.find(selector.searchButton),
  37. $results = $module.find(selector.results),
  38. $result = $module.find(selector.result),
  39. $category = $module.find(selector.category),
  40. element = this,
  41. instance = $module.data(moduleNamespace),
  42. module
  43. ;
  44. module = {
  45. initialize: function() {
  46. module.verbose('Initializing module');
  47. var
  48. prompt = $prompt[0],
  49. inputEvent = (prompt !== undefined && prompt.oninput !== undefined)
  50. ? 'input'
  51. : (prompt !== undefined && prompt.onpropertychange !== undefined)
  52. ? 'propertychange'
  53. : 'keyup'
  54. ;
  55. if(settings.automatic) {
  56. $prompt
  57. .on(inputEvent + eventNamespace, module.throttle)
  58. ;
  59. }
  60. $prompt
  61. .on('focus' + eventNamespace, module.event.focus)
  62. .on('blur' + eventNamespace, module.event.blur)
  63. .on('keydown' + eventNamespace, module.handleKeyboard)
  64. ;
  65. $searchButton
  66. .on('click' + eventNamespace, module.query)
  67. ;
  68. $results
  69. .on('mousedown' + eventNamespace, module.event.result.mousedown)
  70. .on('mouseup' + eventNamespace, module.event.result.mouseup)
  71. .on('click' + eventNamespace, selector.result, module.event.result.click)
  72. ;
  73. module.instantiate();
  74. },
  75. instantiate: function() {
  76. module.verbose('Storing instance of module', module);
  77. instance = module;
  78. $module
  79. .data(moduleNamespace, module)
  80. ;
  81. },
  82. destroy: function() {
  83. module.verbose('Destroying instance');
  84. $module
  85. .removeData(moduleNamespace)
  86. ;
  87. $prompt
  88. .off(eventNamespace)
  89. ;
  90. $searchButton
  91. .off(eventNamespace)
  92. ;
  93. $results
  94. .off(eventNamespace)
  95. ;
  96. },
  97. event: {
  98. focus: function() {
  99. $module
  100. .addClass(className.focus)
  101. ;
  102. clearTimeout(module.timer);
  103. module.throttle();
  104. if( module.has.minimumCharacters() ) {
  105. module.showResults();
  106. }
  107. },
  108. blur: function(event) {
  109. module.cancel();
  110. $module
  111. .removeClass(className.focus)
  112. ;
  113. if(!module.resultsClicked) {
  114. module.timer = setTimeout(module.hideResults, settings.hideDelay);
  115. }
  116. },
  117. result: {
  118. mousedown: function() {
  119. module.resultsClicked = true;
  120. },
  121. mouseup: function() {
  122. module.resultsClicked = false;
  123. },
  124. click: function(event) {
  125. module.debug('Search result selected');
  126. var
  127. $result = $(this),
  128. $title = $result.find('.title'),
  129. title = $title.html()
  130. ;
  131. if(settings.onSelect == 'default' || settings.onSelect.call(this, event) == 'default') {
  132. var
  133. $link = $result.find('a[href]').eq(0),
  134. $title = $result.find(selector.title).eq(0),
  135. href = $link.attr('href') || false,
  136. target = $link.attr('target') || false,
  137. name = ($title.length > 0)
  138. ? $title.text()
  139. : false
  140. ;
  141. module.hideResults();
  142. if(name) {
  143. $prompt.val(name);
  144. }
  145. if(href) {
  146. if(target == '_blank' || event.ctrlKey) {
  147. window.open(href);
  148. }
  149. else {
  150. window.location.href = (href);
  151. }
  152. }
  153. }
  154. }
  155. }
  156. },
  157. handleKeyboard: function(event) {
  158. var
  159. // force latest jq dom
  160. $result = $module.find(selector.result),
  161. $category = $module.find(selector.category),
  162. keyCode = event.which,
  163. keys = {
  164. backspace : 8,
  165. enter : 13,
  166. escape : 27,
  167. upArrow : 38,
  168. downArrow : 40
  169. },
  170. activeClass = className.active,
  171. currentIndex = $result.index( $result.filter('.' + activeClass) ),
  172. resultSize = $result.length,
  173. newIndex
  174. ;
  175. // search shortcuts
  176. if(keyCode == keys.escape) {
  177. module.verbose('Escape key pressed, blurring search field');
  178. $prompt
  179. .trigger('blur')
  180. ;
  181. }
  182. // result shortcuts
  183. if($results.filter(':visible').length > 0) {
  184. if(keyCode == keys.enter) {
  185. module.verbose('Enter key pressed, selecting active result');
  186. if( $result.filter('.' + activeClass).length > 0 ) {
  187. module.event.result.click.call($result.filter('.' + activeClass), event);
  188. event.preventDefault();
  189. return false;
  190. }
  191. }
  192. else if(keyCode == keys.upArrow) {
  193. module.verbose('Up key pressed, changing active result');
  194. newIndex = (currentIndex - 1 < 0)
  195. ? currentIndex
  196. : currentIndex - 1
  197. ;
  198. $category
  199. .removeClass(activeClass)
  200. ;
  201. $result
  202. .removeClass(activeClass)
  203. .eq(newIndex)
  204. .addClass(activeClass)
  205. .closest($category)
  206. .addClass(activeClass)
  207. ;
  208. event.preventDefault();
  209. }
  210. else if(keyCode == keys.downArrow) {
  211. module.verbose('Down key pressed, changing active result');
  212. newIndex = (currentIndex + 1 >= resultSize)
  213. ? currentIndex
  214. : currentIndex + 1
  215. ;
  216. $category
  217. .removeClass(activeClass)
  218. ;
  219. $result
  220. .removeClass(activeClass)
  221. .eq(newIndex)
  222. .addClass(activeClass)
  223. .closest($category)
  224. .addClass(activeClass)
  225. ;
  226. event.preventDefault();
  227. }
  228. }
  229. else {
  230. // query shortcuts
  231. if(keyCode == keys.enter) {
  232. module.verbose('Enter key pressed, executing query');
  233. module.query();
  234. $searchButton
  235. .addClass(className.down)
  236. ;
  237. $prompt
  238. .one('keyup', function(){
  239. $searchButton
  240. .removeClass(className.down)
  241. ;
  242. })
  243. ;
  244. }
  245. }
  246. },
  247. query: function() {
  248. var
  249. searchTerm = $prompt.val(),
  250. cachedHTML = module.read.cache(searchTerm)
  251. ;
  252. if(cachedHTML) {
  253. module.debug('Reading result for ' + searchTerm + ' from cache');
  254. module.addResults(cachedHTML);
  255. }
  256. else {
  257. module.debug('Querying for ' + searchTerm);
  258. if($.isPlainObject(settings.source) || $.isArray(settings.source)) {
  259. module.search.local(searchTerm);
  260. }
  261. else if(settings.apiSettings) {
  262. module.search.remote(searchTerm);
  263. }
  264. else if($.fn.api !== undefined && $.api.settings.api.search !== undefined) {
  265. module.debug('Searching with default search API endpoint');
  266. settings.apiSettings = {
  267. action: 'search'
  268. };
  269. module.search.remote(searchTerm);
  270. }
  271. else {
  272. module.error(error.source);
  273. }
  274. settings.onSearchQuery.call(element, searchTerm);
  275. }
  276. },
  277. search: {
  278. local: function(searchTerm) {
  279. var
  280. results = [],
  281. fullTextResults = [],
  282. searchFields = $.isArray(settings.searchFields)
  283. ? settings.searchFields
  284. : [settings.searchFields],
  285. searchRegExp = new RegExp('(?:\s|^)' + searchTerm, 'i'),
  286. fullTextRegExp = new RegExp(searchTerm, 'i'),
  287. searchHTML
  288. ;
  289. $module
  290. .addClass(className.loading)
  291. ;
  292. // iterate through search fields in array order
  293. $.each(searchFields, function(index, field) {
  294. $.each(settings.source, function(label, content) {
  295. var
  296. fieldExists = (typeof content[field] == 'string'),
  297. notAlreadyResult = ($.inArray(content, results) == -1 && $.inArray(content, fullTextResults) == -1)
  298. ;
  299. if(fieldExists && notAlreadyResult) {
  300. if( content[field].match(searchRegExp) ) {
  301. results.push(content);
  302. }
  303. else if( settings.searchFullText && content[field].match(fullTextRegExp) ) {
  304. fullTextResults.push(content);
  305. }
  306. }
  307. });
  308. });
  309. searchHTML = module.generateResults({
  310. results: $.merge(results, fullTextResults)
  311. });
  312. $module
  313. .removeClass(className.loading)
  314. ;
  315. module.write.cache(searchTerm, searchHTML);
  316. module.addResults(searchHTML);
  317. },
  318. remote: function(searchTerm) {
  319. var
  320. apiSettings = {
  321. stateContext : $module,
  322. urlData : {
  323. query: searchTerm
  324. },
  325. onSuccess : function(response) {
  326. searchHTML = module.generateResults(response);
  327. module.write.cache(searchTerm, searchHTML);
  328. module.addResults(searchHTML);
  329. },
  330. onFailure : module.error
  331. },
  332. searchHTML
  333. ;
  334. module.cancel();
  335. module.debug('Executing search');
  336. $.extend(true, apiSettings, settings.apiSettings);
  337. $.api(apiSettings);
  338. }
  339. },
  340. throttle: function() {
  341. clearTimeout(module.timer);
  342. if(module.has.minimumCharacters()) {
  343. module.timer = setTimeout(module.query, settings.searchDelay);
  344. }
  345. else {
  346. module.hideResults();
  347. }
  348. },
  349. cancel: function() {
  350. var
  351. xhr = $module.data('xhr') || false
  352. ;
  353. if( xhr && xhr.state() != 'resolved') {
  354. module.debug('Cancelling last search');
  355. xhr.abort();
  356. }
  357. },
  358. has: {
  359. minimumCharacters: function() {
  360. var
  361. searchTerm = $prompt.val(),
  362. numCharacters = searchTerm.length
  363. ;
  364. return (numCharacters >= settings.minCharacters);
  365. }
  366. },
  367. read: {
  368. cache: function(name) {
  369. var
  370. cache = $module.data('cache')
  371. ;
  372. return (settings.cache && (typeof cache == 'object') && (cache[name] !== undefined) )
  373. ? cache[name]
  374. : false
  375. ;
  376. }
  377. },
  378. write: {
  379. cache: function(name, value) {
  380. var
  381. cache = ($module.data('cache') !== undefined)
  382. ? $module.data('cache')
  383. : {}
  384. ;
  385. cache[name] = value;
  386. $module
  387. .data('cache', cache)
  388. ;
  389. }
  390. },
  391. addResults: function(html) {
  392. if(settings.onResultsAdd == 'default' || settings.onResultsAdd.call($results, html) == 'default') {
  393. $results
  394. .html(html)
  395. ;
  396. }
  397. module.showResults();
  398. },
  399. showResults: function() {
  400. if( ($results.filter(':visible').length === 0) && ($prompt.filter(':focus').length > 0) && $results.html() !== '') {
  401. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported') && !$results.transition('is inward')) {
  402. module.debug('Showing results with css animations');
  403. $results
  404. .transition({
  405. animation : settings.transition + ' in',
  406. duration : settings.duration,
  407. queue : true
  408. })
  409. ;
  410. }
  411. else {
  412. module.debug('Showing results with javascript');
  413. $results
  414. .stop()
  415. .fadeIn(settings.duration, settings.easing)
  416. ;
  417. }
  418. settings.onResultsOpen.call($results);
  419. }
  420. },
  421. hideResults: function() {
  422. if($results.filter(':visible').length > 0) {
  423. if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported') && !$results.transition('is outward')) {
  424. module.debug('Hiding results with css animations');
  425. $results
  426. .transition({
  427. animation : settings.transition + ' out',
  428. duration : settings.duration,
  429. queue : true
  430. })
  431. ;
  432. }
  433. else {
  434. module.debug('Hiding results with javascript');
  435. $results
  436. .stop()
  437. .fadeIn(settings.duration, settings.easing)
  438. ;
  439. }
  440. settings.onResultsClose.call($results);
  441. }
  442. },
  443. generateResults: function(response) {
  444. module.debug('Generating html from response', response);
  445. var
  446. template = settings.templates[settings.type],
  447. html = ''
  448. ;
  449. if(($.isPlainObject(response.results) && !$.isEmptyObject(response.results)) || ($.isArray(response.results) && response.results.length > 0) ) {
  450. if(settings.maxResults > 0) {
  451. response.results = $.isArray(response.results)
  452. ? response.results.slice(0, settings.maxResults)
  453. : response.results
  454. ;
  455. }
  456. if($.isFunction(template)) {
  457. html = template(response);
  458. }
  459. else {
  460. module.error(error.noTemplate, false);
  461. }
  462. }
  463. else {
  464. html = module.displayMessage(error.noResults, 'empty');
  465. }
  466. settings.onResults.call(element, response);
  467. return html;
  468. },
  469. displayMessage: function(text, type) {
  470. type = type || 'standard';
  471. module.debug('Displaying message', text, type);
  472. module.addResults( settings.templates.message(text, type) );
  473. return settings.templates.message(text, type);
  474. },
  475. setting: function(name, value) {
  476. if( $.isPlainObject(name) ) {
  477. $.extend(true, settings, name);
  478. }
  479. else if(value !== undefined) {
  480. settings[name] = value;
  481. }
  482. else {
  483. return settings[name];
  484. }
  485. },
  486. internal: function(name, value) {
  487. if( $.isPlainObject(name) ) {
  488. $.extend(true, module, name);
  489. }
  490. else if(value !== undefined) {
  491. module[name] = value;
  492. }
  493. else {
  494. return module[name];
  495. }
  496. },
  497. debug: function() {
  498. if(settings.debug) {
  499. if(settings.performance) {
  500. module.performance.log(arguments);
  501. }
  502. else {
  503. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  504. module.debug.apply(console, arguments);
  505. }
  506. }
  507. },
  508. verbose: function() {
  509. if(settings.verbose && settings.debug) {
  510. if(settings.performance) {
  511. module.performance.log(arguments);
  512. }
  513. else {
  514. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  515. module.verbose.apply(console, arguments);
  516. }
  517. }
  518. },
  519. error: function() {
  520. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  521. module.error.apply(console, arguments);
  522. },
  523. performance: {
  524. log: function(message) {
  525. var
  526. currentTime,
  527. executionTime,
  528. previousTime
  529. ;
  530. if(settings.performance) {
  531. currentTime = new Date().getTime();
  532. previousTime = time || currentTime;
  533. executionTime = currentTime - previousTime;
  534. time = currentTime;
  535. performance.push({
  536. 'Name' : message[0],
  537. 'Arguments' : [].slice.call(message, 1) || '',
  538. 'Element' : element,
  539. 'Execution Time' : executionTime
  540. });
  541. }
  542. clearTimeout(module.performance.timer);
  543. module.performance.timer = setTimeout(module.performance.display, 100);
  544. },
  545. display: function() {
  546. var
  547. title = settings.name + ':',
  548. totalTime = 0
  549. ;
  550. time = false;
  551. clearTimeout(module.performance.timer);
  552. $.each(performance, function(index, data) {
  553. totalTime += data['Execution Time'];
  554. });
  555. title += ' ' + totalTime + 'ms';
  556. if(moduleSelector) {
  557. title += ' \'' + moduleSelector + '\'';
  558. }
  559. if($allModules.length > 1) {
  560. title += ' ' + '(' + $allModules.length + ')';
  561. }
  562. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  563. console.groupCollapsed(title);
  564. if(console.table) {
  565. console.table(performance);
  566. }
  567. else {
  568. $.each(performance, function(index, data) {
  569. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  570. });
  571. }
  572. console.groupEnd();
  573. }
  574. performance = [];
  575. }
  576. },
  577. invoke: function(query, passedArguments, context) {
  578. var
  579. object = instance,
  580. maxDepth,
  581. found,
  582. response
  583. ;
  584. passedArguments = passedArguments || queryArguments;
  585. context = element || context;
  586. if(typeof query == 'string' && object !== undefined) {
  587. query = query.split(/[\. ]/);
  588. maxDepth = query.length - 1;
  589. $.each(query, function(depth, value) {
  590. var camelCaseValue = (depth != maxDepth)
  591. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  592. : query
  593. ;
  594. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  595. object = object[camelCaseValue];
  596. }
  597. else if( object[camelCaseValue] !== undefined ) {
  598. found = object[camelCaseValue];
  599. return false;
  600. }
  601. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  602. object = object[value];
  603. }
  604. else if( object[value] !== undefined ) {
  605. found = object[value];
  606. return false;
  607. }
  608. else {
  609. return false;
  610. }
  611. });
  612. }
  613. if ( $.isFunction( found ) ) {
  614. response = found.apply(context, passedArguments);
  615. }
  616. else if(found !== undefined) {
  617. response = found;
  618. }
  619. if($.isArray(returnedValue)) {
  620. returnedValue.push(response);
  621. }
  622. else if(returnedValue !== undefined) {
  623. returnedValue = [returnedValue, response];
  624. }
  625. else if(response !== undefined) {
  626. returnedValue = response;
  627. }
  628. return found;
  629. }
  630. };
  631. if(methodInvoked) {
  632. if(instance === undefined) {
  633. module.initialize();
  634. }
  635. module.invoke(query);
  636. }
  637. else {
  638. if(instance !== undefined) {
  639. module.destroy();
  640. }
  641. module.initialize();
  642. }
  643. })
  644. ;
  645. return (returnedValue !== undefined)
  646. ? returnedValue
  647. : this
  648. ;
  649. };
  650. $.fn.search.settings = {
  651. name : 'Search Module',
  652. namespace : 'search',
  653. debug : false,
  654. verbose : true,
  655. performance : true,
  656. // api config
  657. apiSettings : false,
  658. type : 'standard',
  659. minCharacters : 1,
  660. source : false,
  661. searchFields : [
  662. 'title',
  663. 'description'
  664. ],
  665. searchFullText : true,
  666. automatic : 'true',
  667. hideDelay : 0,
  668. searchDelay : 300,
  669. maxResults : 7,
  670. cache : true,
  671. transition : 'scale',
  672. duration : 300,
  673. easing : 'easeOutExpo',
  674. // onSelect default action is defined in module
  675. onSelect : 'default',
  676. onResultsAdd : 'default',
  677. onSearchQuery : function(){},
  678. onResults : function(response){},
  679. onResultsOpen : function(){},
  680. onResultsClose : function(){},
  681. className: {
  682. active : 'active',
  683. down : 'down',
  684. focus : 'focus',
  685. empty : 'empty',
  686. loading : 'loading'
  687. },
  688. error : {
  689. source : 'Cannot search. No source used, and Semantic API module was not included',
  690. noResults : 'Your search returned no results',
  691. logging : 'Error in debug logging, exiting.',
  692. noTemplate : 'A valid template name was not specified.',
  693. serverError : 'There was an issue with querying the server.',
  694. method : 'The method you called is not defined.'
  695. },
  696. selector : {
  697. prompt : '.prompt',
  698. searchButton : '.search.button',
  699. results : '.results',
  700. category : '.category',
  701. result : '.result',
  702. title : '.title, .name'
  703. },
  704. templates: {
  705. escape: function(string) {
  706. var
  707. badChars = /[&<>"'`]/g,
  708. shouldEscape = /[&<>"'`]/,
  709. escape = {
  710. "&": "&amp;",
  711. "<": "&lt;",
  712. ">": "&gt;",
  713. '"': "&quot;",
  714. "'": "&#x27;",
  715. "`": "&#x60;"
  716. },
  717. escapedChar = function(chr) {
  718. return escape[chr];
  719. }
  720. ;
  721. if(shouldEscape.test(string)) {
  722. return string.replace(badChars, escapedChar);
  723. }
  724. return string;
  725. },
  726. message: function(message, type) {
  727. var
  728. html = ''
  729. ;
  730. if(message !== undefined && type !== undefined) {
  731. html += ''
  732. + '<div class="message ' + type + '">'
  733. ;
  734. // message type
  735. if(type == 'empty') {
  736. html += ''
  737. + '<div class="header">No Results</div class="header">'
  738. + '<div class="description">' + message + '</div class="description">'
  739. ;
  740. }
  741. else {
  742. html += ' <div class="description">' + message + '</div>';
  743. }
  744. html += '</div>';
  745. }
  746. return html;
  747. },
  748. category: function(response) {
  749. var
  750. html = '',
  751. escape = $.fn.search.settings.templates.escape
  752. ;
  753. if(response.results !== undefined) {
  754. // each category
  755. $.each(response.results, function(index, category) {
  756. if(category.results !== undefined && category.results.length > 0) {
  757. html += ''
  758. + '<div class="category">'
  759. + '<div class="name">' + category.name + '</div>'
  760. ;
  761. // each item inside category
  762. $.each(category.results, function(index, result) {
  763. html += '<div class="result">';
  764. if(result.url) {
  765. html += '<a href="' + result.url + '"></a>';
  766. }
  767. if(result.image !== undefined) {
  768. result.image = escape(result.image);
  769. html += ''
  770. + '<div class="image">'
  771. + ' <img src="' + result.image + '" alt="">'
  772. + '</div>'
  773. ;
  774. }
  775. html += '<div class="content">';
  776. if(result.price !== undefined) {
  777. result.price = escape(result.price);
  778. html += '<div class="price">' + result.price + '</div>';
  779. }
  780. if(result.title !== undefined) {
  781. result.title = escape(result.title);
  782. html += '<div class="title">' + result.title + '</div>';
  783. }
  784. if(result.description !== undefined) {
  785. html += '<div class="description">' + result.description + '</div>';
  786. }
  787. html += ''
  788. + '</div>'
  789. + '</div>'
  790. ;
  791. });
  792. html += ''
  793. + '</div>'
  794. ;
  795. }
  796. });
  797. if(response.action) {
  798. html += ''
  799. + '<a href="' + response.action.url + '" class="action">'
  800. + response.action.text
  801. + '</a>';
  802. }
  803. return html;
  804. }
  805. return false;
  806. },
  807. standard: function(response) {
  808. var
  809. html = ''
  810. ;
  811. if(response.results !== undefined) {
  812. // each result
  813. $.each(response.results, function(index, result) {
  814. if(result.url) {
  815. html += '<a class="result" href="' + result.url + '">';
  816. }
  817. else {
  818. html += '<a class="result">';
  819. }
  820. if(result.image !== undefined) {
  821. html += ''
  822. + '<div class="image">'
  823. + ' <img src="' + result.image + '">'
  824. + '</div>'
  825. ;
  826. }
  827. html += '<div class="content">';
  828. if(result.price !== undefined) {
  829. html += '<div class="price">' + result.price + '</div>';
  830. }
  831. if(result.title !== undefined) {
  832. html += '<div class="title">' + result.title + '</div>';
  833. }
  834. if(result.description !== undefined) {
  835. html += '<div class="description">' + result.description + '</div>';
  836. }
  837. html += ''
  838. + '</div>'
  839. ;
  840. html += '</a>';
  841. });
  842. if(response.action) {
  843. html += ''
  844. + '<a href="' + response.action.url + '" class="action">'
  845. + response.action.text
  846. + '</a>';
  847. }
  848. return html;
  849. }
  850. return false;
  851. }
  852. }
  853. };
  854. })( jQuery, window , document );