Commit a4ac7568a0487233202437722c682eef9a0e0016
1 parent
1fbebcd3
Exists in
master
and in
10 other branches
Fix #41 - Router em URL com HASH e HistoryAPI
Showing
4 changed files
with
176 additions
and
55 deletions
Show diff stats
index.html
@@ -24,13 +24,17 @@ | @@ -24,13 +24,17 @@ | ||
24 | </header> | 24 | </header> |
25 | 25 | ||
26 | <div id="content"> | 26 | <div id="content"> |
27 | - {{{article.body}}} | 27 | + <p>{{{article.body}}}</p> |
28 | </div> | 28 | </div> |
29 | 29 | ||
30 | <nav> | 30 | <nav> |
31 | <ul> | 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 | </ul> | 38 | </ul> |
35 | </nav> | 39 | </nav> |
36 | 40 | ||
@@ -38,12 +42,12 @@ | @@ -38,12 +42,12 @@ | ||
38 | <div id="proposal-categories-container"> | 42 | <div id="proposal-categories-container"> |
39 | {{#each article.categories}} | 43 | {{#each article.categories}} |
40 | <li id='proposal-category-{{slug}}' class="proposal-category" data-category="{{slug}}"> | 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 | <div class="arrow-box" style="display: none"></div> | 46 | <div class="arrow-box" style="display: none"></div> |
43 | </li> | 47 | </li> |
44 | {{/each}} | 48 | {{/each}} |
45 | {{#each article.categories}} | 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 | <div class="header"> | 51 | <div class="header"> |
48 | <div class="name">{{name}}</div> | 52 | <div class="name">{{name}}</div> |
49 | <div class="description"></div> | 53 | <div class="description"></div> |
@@ -77,7 +81,7 @@ | @@ -77,7 +81,7 @@ | ||
77 | <ul class="select"> | 81 | <ul class="select"> |
78 | {{#each categories}} | 82 | {{#each categories}} |
79 | <li class='category proposal-category' data-category="{{slug}}"> | 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 | {{#select_proposal ../../article.children slug ../id}}{{/select_proposal}} | 85 | {{#select_proposal ../../article.children slug ../id}}{{/select_proposal}} |
82 | </li> | 86 | </li> |
83 | {{/each}} | 87 | {{/each}} |
@@ -89,13 +93,18 @@ | @@ -89,13 +93,18 @@ | ||
89 | </div> | 93 | </div> |
90 | <div class='title'>{{title}}</div> | 94 | <div class='title'>{{title}}</div> |
91 | <div class='abstract'>{{{abstract}}}</div> | 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 | </div> | 99 | </div> |
94 | 100 | ||
95 | <div class='body proposal-detail-base hide'> | 101 | <div class='body proposal-detail-base hide'> |
96 | {{{body}}} | 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 | </div> | 108 | </div> |
100 | 109 | ||
101 | </div> | 110 | </div> |
@@ -173,7 +182,6 @@ | @@ -173,7 +182,6 @@ | ||
173 | </div> | 182 | </div> |
174 | </div> | 183 | </div> |
175 | </div> | 184 | </div> |
176 | - <div class="clearfix"></div> | ||
177 | </div> | 185 | </div> |
178 | {{/each}} | 186 | {{/each}} |
179 | </script> | 187 | </script> |
js/handlebars-helpers.js
@@ -2,7 +2,8 @@ Handlebars.registerHelper('link', function(text, url) { | @@ -2,7 +2,8 @@ Handlebars.registerHelper('link', function(text, url) { | ||
2 | text = Handlebars.Utils.escapeExpression(text); | 2 | text = Handlebars.Utils.escapeExpression(text); |
3 | url = Handlebars.Utils.escapeExpression(url); | 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 | return new Handlebars.SafeString(result); | 8 | return new Handlebars.SafeString(result); |
8 | }); | 9 | }); |
js/main.js
@@ -40,52 +40,55 @@ $.getJSON(noosferoAPI) | @@ -40,52 +40,55 @@ $.getJSON(noosferoAPI) | ||
40 | $('.login-container').html(loginTemplate()); | 40 | $('.login-container').html(loginTemplate()); |
41 | $('.countdown').maxlength({text: '%left caracteres restantes'}); | 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 | //Actions for links | 45 | //Actions for links |
48 | $( '#nav-proposal-categories a' ).click(function(event){ | 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 | event.preventDefault(); | 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 | $( '#nav-proposal-group a' ).click(function(event){ | 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 | event.preventDefault(); | 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 | $( '.proposal-item a' ).click(function(event){ | 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 | display_proposal(item); | 77 | display_proposal(item); |
71 | }); | 78 | }); |
79 | + | ||
72 | $( '.proposal-category a' ).click(function(event){ | 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 | event.preventDefault(); | 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 | $( '.send-button a' ).click(function(event){ | 92 | $( '.send-button a' ).click(function(event){ |
90 | //display form to send proposal (or login form for non-logged users) | 93 | //display form to send proposal (or login form for non-logged users) |
91 | loginButton = $(this).parents('.send-button'); | 94 | loginButton = $(this).parents('.send-button'); |
@@ -98,11 +101,25 @@ $.getJSON(noosferoAPI) | @@ -98,11 +101,25 @@ $.getJSON(noosferoAPI) | ||
98 | $('#proposal-result').toggleClass('contrast'); | 101 | $('#proposal-result').toggleClass('contrast'); |
99 | }); | 102 | }); |
100 | $( '.show_body a' ).click(function(event){ | 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 | $( '.go-to-proposal-button a' ).click(function(event){ | 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 | $( '.proposal-selection' ).change(function(event){ | 123 | $( '.proposal-selection' ).change(function(event){ |
107 | display_proposal('proposal-item-' + this.value); | 124 | display_proposal('proposal-item-' + this.value); |
108 | }); | 125 | }); |
@@ -111,6 +128,7 @@ $.getJSON(noosferoAPI) | @@ -111,6 +128,7 @@ $.getJSON(noosferoAPI) | ||
111 | $('#proposal-group li a').each(function(){ | 128 | $('#proposal-group li a').each(function(){ |
112 | availableTags.push({ label: $(this).text(), value: $(this).attr('href')}); | 129 | availableTags.push({ label: $(this).text(), value: $(this).attr('href')}); |
113 | }); | 130 | }); |
131 | + | ||
114 | $( "#search-input" ).autocomplete({ | 132 | $( "#search-input" ).autocomplete({ |
115 | source: availableTags, | 133 | source: availableTags, |
116 | select: function( event, ui ) { display_proposal(ui.item['value' ].replace('#','')); }, | 134 | select: function( event, ui ) { display_proposal(ui.item['value' ].replace('#','')); }, |
@@ -143,7 +161,7 @@ $.getJSON(noosferoAPI) | @@ -143,7 +161,7 @@ $.getJSON(noosferoAPI) | ||
143 | .fail(function( jqxhr, textStatus, error ) { | 161 | .fail(function( jqxhr, textStatus, error ) { |
144 | var err = textStatus + ", " + error; | 162 | var err = textStatus + ", " + error; |
145 | console.log( "Request Failed: " + err ); | 163 | console.log( "Request Failed: " + err ); |
146 | - }); | 164 | + }); |
147 | 165 | ||
148 | function loadRandomProposal(topic_id, private_token) { | 166 | function loadRandomProposal(topic_id, private_token) { |
149 | $(".no-proposals").hide(); | 167 | $(".no-proposals").hide(); |
@@ -160,7 +178,7 @@ function loadRandomProposal(topic_id, private_token) { | @@ -160,7 +178,7 @@ function loadRandomProposal(topic_id, private_token) { | ||
160 | 178 | ||
161 | var article = data.articles[0]; | 179 | var article = data.articles[0]; |
162 | $('.random-proposal').html(supportProposalTemplate(article)); | 180 | $('.random-proposal').html(supportProposalTemplate(article)); |
163 | - $(".abstract").dotdotdot(); | 181 | + // $(".abstract").dotdotdot(); |
164 | $(document.body).off('click', '.vote-actions .skip'); | 182 | $(document.body).off('click', '.vote-actions .skip'); |
165 | $(document.body).on('click', '.vote-actions .skip', function(e) { | 183 | $(document.body).on('click', '.vote-actions .skip', function(e) { |
166 | loadRandomProposal(topic_id, private_token); | 184 | loadRandomProposal(topic_id, private_token); |
@@ -181,10 +199,6 @@ function loadRandomProposal(topic_id, private_token) { | @@ -181,10 +199,6 @@ function loadRandomProposal(topic_id, private_token) { | ||
181 | e.preventDefault(); | 199 | e.preventDefault(); |
182 | }); | 200 | }); |
183 | 201 | ||
184 | - $('.results-container').hide(); | ||
185 | - $('.experience-proposal-container').show(); | ||
186 | - $('.talk-proposal-container').show(); | ||
187 | - | ||
188 | $(document.body).off('click', '.vote-result'); | 202 | $(document.body).off('click', '.vote-result'); |
189 | $(document.body).on('click', '.vote-result', function(e) { | 203 | $(document.body).on('click', '.vote-result', function(e) { |
190 | $('.results-container').toggle(); | 204 | $('.results-container').toggle(); |
@@ -266,6 +280,24 @@ function guid() { | @@ -266,6 +280,24 @@ function guid() { | ||
266 | s4() + '-' + s4() + s4() + s4(); | 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 | function display_proposal(proposal_id){ | 301 | function display_proposal(proposal_id){ |
270 | $('#proposal-categories').hide(); | 302 | $('#proposal-categories').hide(); |
271 | $('#proposal-group').hide(); | 303 | $('#proposal-group').hide(); |
@@ -302,6 +334,87 @@ function display_proposal_detail(){ | @@ -302,6 +334,87 @@ function display_proposal_detail(){ | ||
302 | $('.talk-proposal-container').hide(); | 334 | $('.talk-proposal-container').hide(); |
303 | 335 | ||
304 | $('.body').show(); | 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 | \ No newline at end of file | 421 | \ No newline at end of file |
sass/_proposal_group.scss
@@ -11,8 +11,7 @@ | @@ -11,8 +11,7 @@ | ||
11 | 11 | ||
12 | #search-input-container, label[for=search] { | 12 | #search-input-container, label[for=search] { |
13 | width: 49%; | 13 | width: 49%; |
14 | - display: inline-block; | ||
15 | - height: 80px; | 14 | + height: 80px; |
16 | vertical-align: middle; | 15 | vertical-align: middle; |
17 | overflow: hidden; | 16 | overflow: hidden; |
18 | } | 17 | } |