javascript - How do I dynamically populate a partial based on a link click? -
so have partial called _node.html.erb
. rendered in different views (and different controllers) throughout app. on 1 particular view, happens generate list of events
linkable (and unique).
what want happen is, whenever clicks 1 of links, shows partial , populates correct info. way trying via passing data-attributes
link js updating of partial. runs wall when reach node.comments
, partial should load of comments associated node
being rendered.
for example, here sample code of _node.html.erb
may like:
<!-- card meta --> <div class="card__meta"> <aside> <%= image_tag node.user.avatar.url, class: "card__author-avatar", alt: "" %> </aside> <section> <h6 class="card__author-name"><%= node.user.name %></h6> <time class="card__date"><%= node.created_at.strftime("%b %d, %y") %></time> <p class="card__description"><%= node.media.try(:description) %> <textarea class="card-form__description" name="" id="" cols="30" rows="10">aenean lacinia bibendum nulla sed consectetur.</textarea> </section> </div> <!-- end card meta --> <!-- card comments --> <div class="card-comments-container"> <h4 class="card-comments__title"><%= pluralize(node.comments_count, "comment") %></h4> <a class="card-comments__button"><i class="icon-arrow-down"></i></a> <div class="card-comments"> <%= render partial: "nodes/comment", collection: node.comments.includes(:user).order(created_at: :desc) %> </div> </div> <!-- end card comments -->
here sample of link user can press, or rather rails code generates link:
<div class="item-wrapper"> <div class="item_comment"> <h5 class="item_comment-title"><%= event.action %> on <%= link_to event.eventable.node.name, "#", data: {toggle_card: "", card_id: event.eventable.node.id, card_title: event.eventable.node.media.title, card_description: event.eventable.node.media.description, card_time: event.eventable.node.media.created_at, card_comments: event.eventable.node.comments_count, card_favorites: event.eventable.node.cached_votes_total } %></h5> <p class="item_comment-text"><%= event.eventable.message %></p> </div> </div>
this example of type of jquery using originally:
$(document).ready(function() { var overlay = $('.card-overlay'), $card = overlay.find('.card'), triggers = $('a[data-toggle-card]'); overlay.hide(); overlay.click(function(e) { if( e.target != ) { } else { overlay.hide(); } }); triggers.click(function() { var trigger = $(this); var tr = trigger; overlay.show(); var card = { id: tr.data('card-id'), title: tr.data('card-title'), description: tr.data('card-description'), time: tr.data('card-time'), comments: tr.data('card-comments'), favorites: tr.data('card-favorites'), }; $card.attr('id', 'card-' + card.id); $card.find('.card__content').attr('style', 'background-image: url(' + card.image + ')'); $card.find('.card__favorite-count').html('<i class="icon-heart"></i> ' + card.favorites); $card.find('.card__comment-count').html('<i class="icon-speech-bubble-1"></i> ' + card.comments); $card.find('.card__title').text(card.title); $card.find('.card__date').text(card.time); $card.find('.card__description').text(card.description); $card.find('textarea').attr('id', 'card-input-field-' + card.id); var player = videojs("example_video_" + card.id, {}, function() {}); player.src( { src: card.video.mp4, type: 'video/mp4' }, { src: card.video.webm, type: 'video/webm' }, { src: card.video.ogv, type: 'video/ogv' } ); player.load(); player.ready(function() { console.log("ready") }); return false; }); });
how do in more "railsy" way without relying on js/jquery?
edit 1
after attempting rich peck's suggestion, got error:
05:46:31 web.1 | unexpected error while processing request: js, accepted http methods options, get, head, post, put, delete, trace, connect, propfind, proppatch, mkcol, copy, move, lock, unlock, version-control, report, checkout, checkin, uncheckout, mkworkspace, update, label, merge, baseline-control, mkactivity, orderpatch, acl, search, , patch
to clear, did:
modified routes have this:
resources :events :node, action: :node end
then created action in eventscontroller
called node
this:
def node @node = current_user.nodes.find(params: [node_id]) respond_to |format| format.js end end
then created app/views/events/node.js.erb
, looks so:
$overlay = $('.card-overlay'); $node = $('<%= j render "nodes/node", locals: {node: @node} %>'); $overlay.append($node);
then modified link_to
tag so:
<%= link_to event.eventable.node.name, event_node_path(event.eventable.node), remote: true, method: :js %></h5>
okay there 2 problems here:
you're trying load & populate partial without data (ie
node.comments
)secondly, you're heavily relying on
jquery
update various attributes on page. although there nothing wrong in itself, does become issue if you're looking change page layouts etc.
a more "railsy" way remotely load node directly server, alex lynham
recommended:
#config/routes.rb resources :cards :node_id, action: :node #-> url.com/cards/:card_id/:node_id end #app/controllers/cards_controller.rb class cardscontroller < applicationcontroller def node @card = card.find params[:card_id] @node = @card.nodes.find params[:node_id] respond_to |format| format.js #-> app/views/cards/node.js.erb end end end #app/views/cards/node.js.erb $node = $("<%=j render "cards/node", locals: {node: @node} %>") $('body').append($node); #app/views/cards/index.html.erb <% @cards.each |card| %> <%= link_to card.name, card_node_path(@card), remote: true, format: :js %> <% end %>
this keep code clear , concise.
you can put options directly in _node.js.erb
partial. although still means there changes have make, give ability change partial & implementation without jquery specialization have now.
Comments
Post a Comment