ws-ui-parts.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. "use strict";
  2. (function($) {
  3. $(document).ready(function() {
  4. var eventBinders = {
  5. menuExample: function() {
  6. console.log('eventBinder for menuExample', this);
  7. this.$elem.find('a').click(function(e) {
  8. e.preventDefault();
  9. var $link = $(this);
  10. console.log('menu item clicked', $link.prop('href'));
  11. var originalColor = $link.css('backgroundColor');
  12. // self.toggleMenu();
  13. $link.animate({
  14. backgroundColor: '#aaa',
  15. }, 70);
  16. $link.animate({
  17. backgroundColor: originalColor,
  18. }, 70);
  19. _ws.navigator.navigateTo($link.prop('href'));
  20. });
  21. }
  22. }
  23. /**
  24. * Render an UI part
  25. */
  26. function renderPart(partName, data) {
  27. var part = _ws.ui[partName];
  28. part.$elem.html( Mustache.render( part.tmpl, data ) );
  29. }
  30. _ws.makeView = function(elemId, props) {
  31. var v = {};
  32. v.props = props || {};
  33. v.$elem = $('#' + elemId);
  34. v.partName = _.camelCase(elemId);
  35. _ws.ui[v.partName] = v;
  36. // Assign a default render function if none given
  37. if(! v.props.render) {
  38. var $tmplEl = $('script[data-tmpl-for="' + elemId + '"]');
  39. v.tmpl = $tmplEl.html();
  40. v.render = (function(data) {
  41. if(! data) {
  42. console.log('WARNING! You should provide data for #' + elemId + "'s render()");
  43. }
  44. // var eventBinder = eventBinders[v.partName];
  45. this.$elem.html( Mustache.render( this.tmpl, data ) );
  46. // if(eventBinder) {
  47. // eventBinder = eventBinder.bind(this);
  48. // console.log('bind events for', v.partName);
  49. // eventBinder();
  50. // }
  51. console.log('rebind events after render', this);
  52. this.bindEvents();
  53. }).bind(v);
  54. }
  55. // Otherwise bind the provided one
  56. else {
  57. v.render = props.render.bind(v);
  58. }
  59. // Set event handlers
  60. if(v.props.events) {
  61. v.bindEvents = (function() {
  62. var events = this.props.events;
  63. for(var descriptor in events) {
  64. var handler = events[descriptor];
  65. var bits = descriptor.split(' ');
  66. var evtName = bits.shift();
  67. var selector = bits.join(' ');
  68. console.log('#### bind', descriptor, 'e:' + evtName, 's:' + selector, handler.toString())
  69. v.$elem.find(selector).on(evtName, handler);
  70. }
  71. }).bind(v);
  72. v.bindEvents();
  73. }
  74. else {
  75. v.bindEvents = function() {};
  76. }
  77. }
  78. /**
  79. * Initialize an empty object to be populated as follows:
  80. * - key is an UI element's id
  81. * - value associated is an obj containing: tmpl (the template) and $elem (jQueried target element)
  82. */
  83. _ws.ui = {};
  84. // Iterate over the template script elements
  85. var $templateElems = $('script[data-tmpl-for]');
  86. $templateElems.each(function(idx, el) {
  87. return;
  88. // Get the script element content and target element id
  89. var $script = $(el);
  90. var tmpl = $script.html();
  91. var elemId = $script.data('tmpl-for');
  92. var $elem = $('#' + elemId);
  93. var partName = _.camelCase(elemId);
  94. // Populate the uiParts object
  95. _ws.ui[partName] = {
  96. tmpl: tmpl,
  97. $elem: $elem,
  98. render: (function(_name) {
  99. return function(data) {
  100. var eventBinder = eventBinders[_name];
  101. renderPart(_name, data);
  102. if(eventBinder) {
  103. eventBinder = eventBinder.bind(this);
  104. console.log('bind events for', _name);
  105. eventBinder();
  106. }
  107. };
  108. })(partName)
  109. };
  110. });
  111. // console.log(_.map(_ws.uiParts, p => (p.render.toString())));
  112. });
  113. })(jQuery);