PageRenderTime 24ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/app/app.js

http://github.com/funkatron/WildGarlic-jqmobile
JavaScript | 201 lines | 146 code | 38 blank | 17 comment | 16 complexity | d43df202023399248e5662c5bc90c47d MD5 | raw file
  1. (function($) {
  2. $(document).ready( function() {
  3. /*
  4. a result model
  5. */
  6. var Result = Backbone.Model.extend({
  7. title:null,
  8. id:null
  9. });
  10. /*
  11. a results collection - a collection of result models
  12. much of this is based on https://gist.github.com/705733
  13. */
  14. var Results = Backbone.Collection.extend({
  15. initialize: function(models, options) {
  16. _.bindAll(this, 'parse', 'url', 'pageInfo', 'nextPage', 'previousPage');
  17. // when the collection contents have changed, trigger the view's addResult method
  18. this.bind("refresh", options.view.render);
  19. this.initSettings();
  20. },
  21. model:Result,
  22. page:1,
  23. last_search:null,
  24. url:function() {
  25. return 'http://www.urbandictionary.com/iphone/search/define?term='+
  26. encodeURIComponent(this.searchterm)+
  27. '&page='+encodeURIComponent(this.page);
  28. },
  29. initSettings:function() {
  30. this.searchterm = null;
  31. this.selected = null;
  32. this.page = 1;
  33. this.total = 0;
  34. this.total_pages = 0;
  35. this.result_type = null;
  36. this.has_related_words = null;
  37. },
  38. fetch:function(opts) {
  39. opts = opts || {};
  40. var that = this;
  41. var success = opts.success;
  42. this.trigger('fetching');
  43. // reset the search if we change the term
  44. if ((this.last_searchterm !== this.searchterm) || (opts.mode !== 'append')) {
  45. this.last_searchterm = this.searchterm;
  46. this.page = 1;
  47. }
  48. opts.success = function(resp) {
  49. if (success) {
  50. success(that, resp);
  51. }
  52. };
  53. // call the original fetch
  54. Backbone.Collection.prototype.fetch.call(this, opts);
  55. },
  56. parse:function(response) {
  57. var new_models = [];
  58. this.total = response.total;
  59. this.total_pages = response.pages;
  60. this.result_type = response.result_type;
  61. this.has_related_words = response.has_related_words;
  62. new_models = response.list;
  63. return new_models;
  64. },
  65. refresh:function(models, options) {
  66. models || (models = []);
  67. options || (options = {});
  68. if (this.page == 1) { // we redefined refres to support this
  69. this._reset(); // only _reset if page == 1
  70. }
  71. this.add(models, {silent: true});
  72. if (!options.silent) this.trigger('refresh', this, options);
  73. return this;
  74. },
  75. setSelected: function(cid) {
  76. var obj = this.getByCid(cid);
  77. this.selected = obj;
  78. },
  79. selected:null,
  80. searchterm:null
  81. });
  82. // we use doT.js templates
  83. Templates = {
  84. 'results':[
  85. '<ul data-role="listview" data-inset="true" id="results-list">',
  86. '{{ _.each(it, function(res) { }}',
  87. '<li data-id="{{=res.cid}}">',
  88. '<a href="#page-detail" data-cid={{=res.cid}}>{{=res.attributes.word}}</a>',
  89. '<span class="ui-li-count"><span class="thumbs_up">{{=res.attributes.thumbs_up}}</span> / <span class="thumbs_down">{{=res.attributes.thumbs_down}}</span></span>',
  90. '</li>',
  91. '{{ }); }}',
  92. '</ul>'
  93. ].join('')
  94. };
  95. /*
  96. compile all templates
  97. */
  98. for (var tplkey in Templates) {
  99. Templates[tplkey] = doT.template(Templates[tplkey]);
  100. }
  101. AppView = Backbone.View.extend({
  102. el:$('body'),
  103. initialize: function () {
  104. this.results = new Results( null, { view: this });
  105. },
  106. events: {
  107. 'click #search-button':'search',
  108. 'click #loadmore':'loadMore',
  109. 'click #results-list>li':'setSelected'
  110. },
  111. search: function() {
  112. this.results.searchterm = $('#search').val();
  113. if (!this.results.searchterm) { // skip out if it is empty
  114. return;
  115. }
  116. this.results.fetch();
  117. },
  118. loadMore: function() {
  119. if (this.results.page < this.results.total_pages) {
  120. this.results.page++;
  121. this.results.fetch({mode:'append'});
  122. }
  123. },
  124. render: function(collection) {
  125. $("#results").html( Templates.results(this.models) );
  126. if (collection.total_pages > collection.page) {
  127. $('#loadmore').show();
  128. } else {
  129. $('#loadmore').hide();
  130. }
  131. appview.reapplyStyles();
  132. return this;
  133. },
  134. reapplyStyles: function(el) {
  135. el = el || this.el;
  136. el.find('ul[data-role]').listview();
  137. el.find('div[data-role="fieldcontain"]').fieldcontain();
  138. el.find('button[data-role="button"]').button();
  139. el.find('input,textarea').textinput();
  140. return el.page();
  141. },
  142. setSelected: function(e) {
  143. var cid = $(e.target).attr('data-cid');
  144. this.results.setSelected(cid);
  145. this.renderSelected();
  146. },
  147. /**
  148. * doing this here just seems easier
  149. */
  150. renderSelected: function() {
  151. $('#header-detail>h1').text(this.results.selected.attributes.word);
  152. $('#definitions').html(this.nl2br(this.results.selected.attributes.definition));
  153. $('#examples').html(this.nl2br(this.results.selected.attributes.example));
  154. },
  155. nl2br:function(str, breaktag) {
  156. breaktag = breaktag || '<p></p>';
  157. str = str.replace(/(\r\n|\n\r|\r|\n)/g, breaktag+'$1');
  158. return str;
  159. }
  160. });
  161. var appview = new AppView();
  162. });
  163. })(jQuery);