Commit a4ac7568a0487233202437722c682eef9a0e0016

Authored by Leonardo Merlin
1 parent 1fbebcd3

Fix #41 - Router em URL com HASH e HistoryAPI

index.html
... ... @@ -24,13 +24,17 @@
24 24 </header>
25 25  
26 26 <div id="content">
27   - {{{article.body}}}
  27 + <p>{{{article.body}}}</p>
28 28 </div>
29 29  
30 30 <nav>
31 31 <ul>
32   - <li id='nav-proposal-categories'><a href="#proposal-categories" class="active">Temas</a></li>
33   - <li id='nav-proposal-group'><a href="#proposal-group">Programas</a></li>
  32 + <li id='nav-proposal-categories'>
  33 + <a href="#/temas" class="active">Temas</a>
  34 + </li>
  35 + <li id='nav-proposal-group'>
  36 + <a href="#/programas">Programas</a>
  37 + </li>
34 38 </ul>
35 39 </nav>
36 40  
... ... @@ -38,12 +42,12 @@
38 42 <div id="proposal-categories-container">
39 43 {{#each article.categories}}
40 44 <li id='proposal-category-{{slug}}' class="proposal-category" data-category="{{slug}}">
41   - {{#link name id}}{{/link}}
  45 + <a href="#/temas/{{slug}}/{{id}}" class="proposal-link" data-target="proposal-item-{{id}}">{{name}}</a>
42 46 <div class="arrow-box" style="display: none"></div>
43 47 </li>
44 48 {{/each}}
45 49 {{#each article.categories}}
46   - <div id='proposal-item-{{id}}' class="proposal-category-items proposal-category-items-{{slug}} hide">
  50 + <div id='proposal-item-{{id}}' class="proposal-category-items proposal-category-items-{{slug}} hide" data-category="{{slug}}">
47 51 <div class="header">
48 52 <div class="name">{{name}}</div>
49 53 <div class="description"></div>
... ... @@ -77,7 +81,7 @@
77 81 <ul class="select">
78 82 {{#each categories}}
79 83 <li class='category proposal-category' data-category="{{slug}}">
80   - {{#link name id}}{{/link}}
  84 + <a href="#/temas/{{slug}}/{{id}}" class="proposal-link" data-target="proposal-item-{{id}}">{{name}}</a>
81 85 {{#select_proposal ../../article.children slug ../id}}{{/select_proposal}}
82 86 </li>
83 87 {{/each}}
... ... @@ -89,13 +93,18 @@
89 93 </div>
90 94 <div class='title'>{{title}}</div>
91 95 <div class='abstract'>{{{abstract}}}</div>
92   - <div class='show_body'><a href='#'><span>Conheça o Programa</span></a></div>
  96 + <div class='show_body'>
  97 + <a href='#/programas/{{id}}/sobre-o-programa'><span>Conheça o Programa</span></a>
  98 + </div>
93 99 </div>
94 100  
95 101 <div class='body proposal-detail-base hide'>
96 102 {{{body}}}
97   - <div class='go-to-proposal-button'><a href='#proposal-item-{{id}}'>
98   - <div class='fa fa-reply'> </div>Agora contribua para a melhoria desse programa</a>
  103 + <div class='go-to-proposal-button'>
  104 + <a href="#/programas/{{id}}" data-target='proposal-item-{{id}}'>
  105 + <span class='fa fa-reply'></span>
  106 + Agora contribua para a melhoria desse programa
  107 + </a>
99 108 </div>
100 109  
101 110 </div>
... ... @@ -173,7 +182,6 @@
173 182 </div>
174 183 </div>
175 184 </div>
176   - <div class="clearfix"></div>
177 185 </div>
178 186 {{/each}}
179 187 </script>
... ...
js/handlebars-helpers.js
... ... @@ -2,7 +2,8 @@ Handlebars.registerHelper(&#39;link&#39;, function(text, url) {
2 2 text = Handlebars.Utils.escapeExpression(text);
3 3 url = Handlebars.Utils.escapeExpression(url);
4 4  
5   - var result = '<a id="#' + url + '" href="#proposal-item-' + url + '" class="proposal-link">' + text + '</a>';
  5 + // Exemplo: <a href="#/programas/{{id}}" class="proposal-link" data-target="">{{name}}</a>
  6 + var result = '<a href="#/programas/' + url + '" data-target="proposal-item-' + url + '" class="proposal-link">' + text + '</a>';
6 7  
7 8 return new Handlebars.SafeString(result);
8 9 });
... ...
js/main.js
... ... @@ -40,52 +40,55 @@ $.getJSON(noosferoAPI)
40 40 $('.login-container').html(loginTemplate());
41 41 $('.countdown').maxlength({text: '%left caracteres restantes'});
42 42  
43   - url = $(location).attr('href').split('#').pop();
44   - if(url.match(/proposal-item-[0-9]+/)){
45   - display_proposal(url);
46   - }
  43 + navigateTo(window.location.hash);
  44 +
47 45 //Actions for links
48 46 $( '#nav-proposal-categories a' ).click(function(event){
49   - //Display the category tab
50   - $('#proposal-group').hide();
51   - $('#proposal-categories').show();
52   - $('#nav-proposal-categories a').addClass('active');
53   - $('#nav-proposal-group a').removeClass('active');
54   - $('.proposal-category-items').hide();
55   - $('.proposal-category .arrow-box').hide();
56   - $('.proposal-detail').hide();
57 47 event.preventDefault();
  48 +
  49 + var $link = $(this);
  50 +
  51 + // Update URL
  52 + updateHash($link.attr('href'));
  53 +
  54 + // Display the Category tab
  55 + display_category_tab();
58 56 });
  57 +
59 58 $( '#nav-proposal-group a' ).click(function(event){
60   - //Display the Topics or Discussions tab
61   - $('#proposal-categories').hide();
62   - $('#proposal-group').show();
63   - $('#nav-proposal-group a').addClass('active');
64   - $('#nav-proposal-categories a').removeClass('active');
65   - $(".proposal-item p").dotdotdot();
66 59 event.preventDefault();
  60 +
  61 + var $link = $(this);
  62 +
  63 + // Update URL
  64 + updateHash($link.attr('href'));
  65 +
  66 + //Display the Proposals tab
  67 + display_proposals_tab();
67 68 });
  69 +
68 70 $( '.proposal-item a' ).click(function(event){
69   - var item = this.href.split('#').pop();
  71 + var $link = $(this);
  72 + var item = $link.data('target');
  73 +
  74 + // Update URL
  75 + updateHash($link.attr('href'));
  76 +
70 77 display_proposal(item);
71 78 });
  79 +
72 80 $( '.proposal-category a' ).click(function(event){
73   - var item = this.href.split('#').pop();
74   - if($('#' + item).hasClass('proposal-category-items')){
75   - //Display Topics or Discussion by category
76   - $('nav').show();
77   - $('#content').show();
78   - $('#proposal-categories').show();
79   - $('.proposal-category-items').hide();
80   - $('.proposal-detail').hide();
81   - $('#' + item).show();
82   - $(".proposal-item p").dotdotdot();
83   - $('.proposal-category .arrow-box').hide();
84   - $(this).parent('.proposal-category').data('category');
85   - $('#proposal-category-'+$(this).parent('.proposal-category').data('category')).find('.arrow-box').show();
86   - }
87 81 event.preventDefault();
  82 +
  83 + var $link = $(this);
  84 + var item = $link.data('target');
  85 +
  86 + // Update URL
  87 + updateHash($link.attr('href'));
  88 +
  89 + display_proposal_by_category(item);
88 90 });
  91 +
89 92 $( '.send-button a' ).click(function(event){
90 93 //display form to send proposal (or login form for non-logged users)
91 94 loginButton = $(this).parents('.send-button');
... ... @@ -98,11 +101,25 @@ $.getJSON(noosferoAPI)
98 101 $('#proposal-result').toggleClass('contrast');
99 102 });
100 103 $( '.show_body a' ).click(function(event){
101   - display_proposal_detail();
  104 + event.preventDefault();
  105 +
  106 + var $link = $(this);
  107 + var item = $link.data('target');
  108 +
  109 + // Update URL
  110 + updateHash($link.attr('href'));
102 111 });
  112 +
103 113 $( '.go-to-proposal-button a' ).click(function(event){
104   - display_proposal(this.href.split('#').pop());
  114 + event.preventDefault();
  115 +
  116 + var $link = $(this);
  117 + var item = $link.data('target');
  118 +
  119 + // Update URL
  120 + updateHash($link.attr('href'));
105 121 });
  122 +
106 123 $( '.proposal-selection' ).change(function(event){
107 124 display_proposal('proposal-item-' + this.value);
108 125 });
... ... @@ -111,6 +128,7 @@ $.getJSON(noosferoAPI)
111 128 $('#proposal-group li a').each(function(){
112 129 availableTags.push({ label: $(this).text(), value: $(this).attr('href')});
113 130 });
  131 +
114 132 $( "#search-input" ).autocomplete({
115 133 source: availableTags,
116 134 select: function( event, ui ) { display_proposal(ui.item['value' ].replace('#','')); },
... ... @@ -143,7 +161,7 @@ $.getJSON(noosferoAPI)
143 161 .fail(function( jqxhr, textStatus, error ) {
144 162 var err = textStatus + ", " + error;
145 163 console.log( "Request Failed: " + err );
146   - });
  164 + });
147 165  
148 166 function loadRandomProposal(topic_id, private_token) {
149 167 $(".no-proposals").hide();
... ... @@ -160,7 +178,7 @@ function loadRandomProposal(topic_id, private_token) {
160 178  
161 179 var article = data.articles[0];
162 180 $('.random-proposal').html(supportProposalTemplate(article));
163   - $(".abstract").dotdotdot();
  181 + // $(".abstract").dotdotdot();
164 182 $(document.body).off('click', '.vote-actions .skip');
165 183 $(document.body).on('click', '.vote-actions .skip', function(e) {
166 184 loadRandomProposal(topic_id, private_token);
... ... @@ -181,10 +199,6 @@ function loadRandomProposal(topic_id, private_token) {
181 199 e.preventDefault();
182 200 });
183 201  
184   - $('.results-container').hide();
185   - $('.experience-proposal-container').show();
186   - $('.talk-proposal-container').show();
187   -
188 202 $(document.body).off('click', '.vote-result');
189 203 $(document.body).on('click', '.vote-result', function(e) {
190 204 $('.results-container').toggle();
... ... @@ -266,6 +280,24 @@ function guid() {
266 280 s4() + '-' + s4() + s4() + s4();
267 281 }
268 282  
  283 +function display_category_tab(){
  284 + $('#proposal-group').hide();
  285 + $('#proposal-categories').show();
  286 + $('#nav-proposal-categories a').addClass('active');
  287 + $('#nav-proposal-group a').removeClass('active');
  288 + $('.proposal-category-items').hide();
  289 + $('.proposal-category .arrow-box').hide();
  290 + $('.proposal-detail').hide();
  291 +}
  292 +
  293 +function display_proposals_tab(){
  294 + $('#proposal-categories').hide();
  295 + $('#proposal-group').show();
  296 + $('#nav-proposal-group a').addClass('active');
  297 + $('#nav-proposal-categories a').removeClass('active');
  298 + $(".proposal-item p").dotdotdot();
  299 +}
  300 +
269 301 function display_proposal(proposal_id){
270 302 $('#proposal-categories').hide();
271 303 $('#proposal-group').hide();
... ... @@ -302,6 +334,87 @@ function display_proposal_detail(){
302 334 $('.talk-proposal-container').hide();
303 335  
304 336 $('.body').show();
305   - event.preventDefault();
  337 +}
  338 +
  339 +function display_proposal_by_category(item){
  340 + var $item = $('#' + item);
  341 +
  342 + if($item.hasClass('proposal-category-items')){
  343 + //Display Topics or Discussion by category
  344 + $('nav').show();
  345 + $('#content').show();
  346 + $('#proposal-categories').show();
  347 + $('.proposal-category-items').hide();
  348 + $('.proposal-detail').hide();
  349 + $item.show();
  350 + $(".proposal-item p").dotdotdot();
  351 + $('.proposal-category .arrow-box').hide();
  352 + var categorySlug = $item.data('category');
  353 + $('#proposal-category-' + categorySlug).find('.arrow-box').show();
  354 + }
  355 +}
  356 +
  357 +function updateHash(hash){
  358 + var id = hash.replace(/^.*#/, '');
  359 + var elem = document.getElementById(id);
  360 +
  361 + if ( !elem ) {
  362 + window.location.hash = hash;
  363 + return;
  364 + }
  365 +
  366 + elem.id = id+'-tmp';
  367 + window.location.hash = hash;
  368 + elem.id = id;
  369 +}
  370 +
  371 +function locationHashChanged(){
  372 + var hash = location.hash;
  373 + navigateTo(hash);
  374 +}
  375 +
  376 +function navigateTo(hash){
  377 + var regexProposals = /#\/programas/;
  378 + var regexCategory = /#\/temas/;
  379 + var m;
  380 + var parts = hash.split('/');
306 381  
  382 + if( (m = regexProposals.exec(hash)) !== null ){
  383 + var proposalId = parts[2];
  384 + navigateToProposal(proposalId);
  385 + } else if( (m = regexCategory.exec(hash)) !== null ){
  386 + var categoryId = parts[3];
  387 + navigateToCategory(categoryId);
  388 + } else {
  389 + console.log('route not handled', hash);
  390 + }
307 391 }
  392 +
  393 +function navigateToProposal(proposalId){
  394 + if(proposalId === undefined){
  395 + display_proposals_tab();
  396 + }else{
  397 + display_proposal('proposal-item-' + proposalId);
  398 +
  399 + // show sub-page
  400 + var regexSubpages = /sobre-o-programa$/;
  401 + var m;
  402 + if((m = regexSubpages.exec(window.location.hash)) !== null ){
  403 + display_proposal_detail();
  404 + }
  405 + }
  406 +}
  407 +
  408 +function navigateToCategory(categoryId){
  409 + if(categoryId === undefined){
  410 + display_category_tab();
  411 + }else{
  412 + display_proposal_by_category('proposal-item-' + categoryId)
  413 + }
  414 +}
  415 +
  416 +if("onhashchange" in window){
  417 + window.onhashchange = locationHashChanged;
  418 +}else{
  419 + console.log('The browser not supports the hashchange event!');
  420 +}
308 421 \ No newline at end of file
... ...
sass/_proposal_group.scss
... ... @@ -11,8 +11,7 @@
11 11  
12 12 #search-input-container, label[for=search] {
13 13 width: 49%;
14   - display: inline-block;
15   - height: 80px;
  14 + height: 80px;
16 15 vertical-align: middle;
17 16 overflow: hidden;
18 17 }
... ...