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 | 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('link', 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 | ... | ... |