Rails and React, how to use helpers and methods? - ruby-on-rails

How to use rails helpers in rails-react? For example, _post.haml partial looks like this
%ul#comments-list.comments-list{:data => { post: post.id }}
%li
.comment-main-level
.comment-avatar
= post_avatar(post)
.comment-box
.comment-head
%h6.comment-name.by-author
= link_to full_name(post.user), post.user
%span="#{post.created_at.strftime("%D:%H:%M:%S")}"
- if user_signed_in?
%i= post_options(post, current_user)
%i=votes(post, current_user, post)
.comment-content
.pop
= check_string(post.content)
= div_for(post.reviews.includes(:user)) do |review|
= render review
= render 'welcome/modal'
I try to put it into react component:
{ div, h2, a, p, input, ul, li, span, h6, img, span } = React.DOM
#Post = React.createClass
render: ->
div {},
ul
className: 'comments-list'
id: 'comments-list'
li null,
div className: 'comment-main-level',
div className: 'comment-avatar',
img
className: 'group-post-img media-object'
src: #props.user.img_url
div className: 'comment-box',
div className: 'comment-head',
h6 className: 'comment-name by-author',
a
href: #props.user.first_name
#props.user.first_name + ' ' +#props.user.last_name
span null, #props.post.created_at
How to realize this part?
- if user_signed_in?
%i= post_options(post, current_user)
%i=votes(post, current_user, post)
This is devise helper, and my own helpers, that contains links (with if else conditions.) I have no idea how to implement this in React. Can anybody tell me how to solve problems like this?

Pass the result of your helper methods as props to your component:
= react_component('Post', {
post: #post,
userSignedIn: user_signed_in?,
postOptions: post_options(post, current_user),
votes: votes(post, current_user, post)
})
In your component use a condition before returning the DOM:
var Post = React.createClass({
render: function() {
var postDetails;
if(this.props.userSignedIn) {
postDetails =
<div className="shown-when-logged-in">
<i>{this.props.postOptions}</i>
<i>{this.props.votes}</i>
</div>
}
return (
<div>
<div className="always-shown">
{this.props.post.content}
</div>
{postDetails}
</div>
);
}
});

Related

How to save using the Mercury editor

I want to get the save function in the Mercury editor working but to no avail.
I have a model to save the page, title and content.
mercury.js:
$(window).bind('mercury:ready', function() {
var link = $('#mercury_iframe').contents().find('#edit_link');
Mercury.saveURL = link.data('save-url');
link.hide();
});
$(window).bind('mercury:saved', function() {
window.location = window.location.href.replace(/\/editor\//i, '/');
});
static_pages_controller.rb:
def update
#static_page = StaticPage.find(params[:id])
#static_page.page = params[:page]
#static_page.title = params[:content][:aboutContainer][:value][:about_title][:value]
#static_page.content = params[:content][:aboutContainer][:value][:about_content][:value]
#static_page.save!
render plain: ''
end
about.html.erb:
<% provide(:title, 'About') %>
<div class="container" id="aboutContainer" data-mercury="full">
<h1 id="about_title"><%= raw #static_page.title %></h1>
<div class="col-sm-12">
<p id="description about_content"><%= raw #static_page.content %></p>
</div>
<p><%= link_to "Edit Page", "/editor" + request.path, id: "edit_link",
data: {save_url: static_page_update_path(#static_page)} %></p>
</div>
Ok, so i basically realised that I needed a show action so I can grab records from the model and save to the #static_page object
I was following this guide: http://railscasts.com/episodes/296-mercury-editor?autoplay=true
Please note I had to change my routes to using those in the link (or similar routes to them) and had to place them before the default mercury routes and had to change:
#static_page.title = params[:content][:aboutContainer][:value][:about_title][:value]
#static_page.content = params[:content][:aboutContainer][:value][:about_content][:value]
to:
#static_page.title = params[:content][:about_title][:value]
#static_page.content = params[:content][:about_content][:value]
I then removed the class 'container' div in about.html.erb and moved all the code to show.html.erb not needing about.html.erb.

How can I use jTable in Ruby on Rails?

I would like to use jTable jQuery plugin in Ruby on Rails 4. What is the best way to do it? Turbolink compatibility is important for me.
I installed jTable js and css into the vendor directory (jQuery UI is needed, I used jquery-ui-rails gem)
I created a controller (called tables_controller), and used a little bit tricky way to make it easy to use and rails friendly.
See the following example. I used a special naming convention to make the process easier: the name of the fields contains the name of the table and the name of the column separated with ‘__’ - for example visitors__id. You will see how it helps to handle automatic ordering.
app/controllers/tables_controller.erb:
class TablesController < ApplicationController
def demo
respond_to do |format|
format.json {
page_size = params[:jtPageSize].to_i
start_index = params[:jtStartIndex].to_i
start_page = start_index / page_size + 1
sort_by = params[:jtSorting].gsub('__', '.')
filter = params[:filter]
if filter
#visitors_count = Visitor.joins(:city).
where('visitors.name like ? OR cities.name like ?', "%#{filter}%", "%#{filter}%").size()
#visitors = Visitor.joins(:city ).
where('visitors.name like ? OR cities.name like ?', "%#{filter}%", "%#{filter}%").order(sort_by).
paginate(:page => start_page, :per_page => page_size)
else
#visitors_count = Visitor.all.size()
#visitors = Visitor.joins(:city).order(sort_by).
paginate(:page => start_page, :per_page => page_size)
end
}
format.html {}
format.js {}
end
end
def demo_delete
#visitor = Visitor.find(params[:visitors__id])
if #visitor
if #visitor.destroy
render js: '{"Result":"OK"}'
end
end
end
end
app/views/tables/demo.json.jbuilder:
json.Result "OK"
json.TotalRecordCount #visitors_count
json.Records do
json.array!(#visitors) do |visitor|
json.visitors__id visitor.id
json.visitors__name visitor.name
json.visitors__age visitor.age
json.cities__name visitor.city.name
end
end
app/views/tables/demo.html.erb:
<div class="jtable-filter">
<form class="jtable-filter">
<input type="text" name="filter" id="filter"/>
<button type="submit" data-jtable-filter="demo">Filter</button>
</form>
</div>
<div id="demo" data-jtable-config="/demo">
</div>
app/views/tables/demo.js.erb:
var jtable_config = {
title: '',
paging: true, //Enable paging
pageSize: 10, //Set page size (default: 10)
sorting: true, //Enable sorting
defaultSorting: 'visitors__name ASC', //Set default sorting
defaultDateFormat: 'yy-mm-dd',
gotoPageArea: 'combobox',
actions: {
listAction: '/demo',
deleteAction: '/demo/delete'
},
fields: {
visitors__id: {
key: true,
list: false
},
visitors__name: {
title: 'Name',
width: '30%'
},
visitors__age: {
title: 'Age',
width: '20%'
},
cities__name: {
title: 'City',
width: '20%'
}
}
};
application.js:
(function ($) {
jQuery.fn.jtable_ou = function () {
return this.each(function () {
var $this = $(this);
var config_url=$this.attr("data-jtable-config");
$.getScript( config_url, function( data, textStatus, jqxhr ) {
$this.jtable(jtable_config);
$this.jtable('load');
});
});
};
})(jQuery);
$(document).on("page:change", function() {
$('[data-jtable-config]').jtable_ou();
$('button[data-jtable-filter]').click(function (e) {
e.preventDefault();
var target=this.getAttribute("data-jtable-filter");
$('#'+target).jtable('load', {
filter: $('#filter').val()
});
});
});
Gemfile:
match '/demo', to: 'tables#demo', via: [:get, :post]
match '/demo/delete', to: 'tables#demo_delete', via: [:post]
It is turbolink friendly and uses unobtrusive JavaScript.
You can find detailed description in this post.

Rails: passing an instance variable to different controller through a partial

In Category view I have:
<ul>
<% #category.subcategories.each do |subcategory| %>
<li>
<h6>
<%if subcategory.has_topic_headings? %>
<%= link_to subcategory.name, { controller: 'subcategories',
action: 'show_topic_headings',
category_id: subcategory.category_id,
id: subcategory.id
}, data: 'topic_heading_link',
remote: true %>
<% else %>
<%= link_to subcategory.name, subcategory %>
<% end %>
</h6>
<hr>
</li>
<% end %>
</ul>
In application.js:
/* slides in the subcategory menu or the content */
$('.category-menu a').on(
'click',
function(e) {
if ($(this).attr('data')) {
/* make submenu visible */
$('.stretched.nav.row > .slider').animate({left:'-62.5em'});
e.preventDefault();
}
else {
/* make content visible */
$('.stretched.main.row > .slider').animate({left:'-62.5em'});
e.preventDefault();
}
}
);
In subcategories_controller.rb
def show_topic_headings
respond_to :js
#subcategory = Subcategory.find(params[:id])
end
And in subcategories/show_topic_heading I have:
$('.subcategory-menu').html( "<%= escape_javascript( render( partial: "layouts/topic_headings", locals: { subcategory: #subcategory} ) ) %>" );
Clicking on the active link, .subcategory-menu should be populated with the correct content and the div containing should slide in. But the content only appears if it's static (for example, if I put a string instead of a reference to #subcategory). Please note that the view in which I am inserting the subcategory partial is a category view.
The problem lies in the subcategories_controller:
respond_to, not the function itself, generates the partial. Therefore the instance variable needs to be declared before calling respond_to
def show_topic_headings
#subcategory = Subcategory.find(params[:id])
respond_to :js
end

Gmaps4rails: map does not show through ajax with erb data feeding but does when hard coded

I would like to use the gmaps4rails gem to display a map of items in a fancybox.
I followed carefully the remarks on the wiki concerning ajax call, i.e. scripts have to be included manually in the application layout, maps have to be loaded in a javascript (see gem wiki).
But I still not succeed completely to make the map displayed in the box.
On the other hand as I hard code coordinates in the javascript it works fine, the map is displayed in the fancybox and the markers appear.
Let me recap.
In my index view, I have a ajax call to the items index action:
<%= link_to "Show Map", items_path(:format => :js, :show_map => true), :remote => true, :class => 'fancybox' %>
In the controller, I populate the map data:
def index
#items=Item.all
if params[:show_map]
#map= #items.to_gmaps4rails
end
end
in the index.js.erb file, I put
<% if params[:show_map] %>
var content = "<%= escape_javascript( gmaps({:last_map => false})) %>";
$.fancybox({
'content': content,
'padding' : 20
});
Gmaps.map = new Gmaps4RailsGoogle();
Gmaps.load_map = function() {
Gmaps.map.initialize();
Gmaps.map.markers = <%= #map %>;
Gmaps.map.create_markers();
Gmaps.map.adjustMapToBounds();
Gmaps.map.callback();
};
Gmaps.loadMaps();
<% else %>
// blablabla
<% end %>
Where the markers are provided in the map object.
This does not work and instead of my map I got in the fancybox the code itself appearing.
Something like:
var content = "\n
\n
<\/div>\n<\/div>\n"; $.fancybox({ 'content': content, 'padding' : 20 }); Gmaps.map = new Gmaps4RailsGoogle(); Gmaps.load_map = function() {Gmaps.map.initialize();
//Gmaps.map.markers = [{"lat":50.294,"lng":5.857},{"lat":50.294,"lng":5.857},{"lat":50.548,"lng":4.918},{"lat":50.384,"lng":3.649},{"lat":50.384,"lng":3.649},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.054,"lng":5.195}];
Gmaps.map.markers = [{"lat":50.8483059,"lng":4.351783999999999},{"lat":50.496,"lng":5.066},{"lat":50.11,"lng":5.003},{"lat":50.11,"lng":5.003},{"lat":50.162,"lng":5.871},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.08,"lng":4.5760000000000005}];
Gmaps.map.create_markers(); Gmaps.map.adjustMapToBounds(); Gmaps.map.callback(); }; Gmaps.loadMaps();
When instead of the erb <%= #map %>, I hard code the markers, for instance:
Gmaps.map.markers = [{"lat":50.294,"lng":5.857},"lat":50.294,"lng":5.857},{"lat":50.548,"lng":4.918}];
It works!
Seems like I'm missing something in the json data type conversion. But I'm not expert to find what is going wrong.
Thanks for your help!
Just successfully tried:
Open
<div id="test" style="display:none;width:300px;">
<%= gmaps markers: { data: #json } , last_map: false %>
</div>
<script type="text/javascript">
$(".fancybox").fancybox({
openEffect : 'none',
closeEffect : 'none',
afterLoad : function() { Gmaps.loadMaps(); }
});
</script>
Ok, I've got what was not going well. Thanks to the following answer https://stackoverflow.com/a/12219016/1100674.
As I use the following syntax:
Gmaps.map.markers = <%= #map %>;
I get the json rendered as this:
Gmaps.map.markers = [{"lat":50.8483059,"lng":4.351783999999999},{"lat":50.11,"lng":5.003},{"lat":50.11,"lng":5.003},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.413,"lng":4.371}];
Whereas I use the raw() method,
Gmaps.map.markers = <%= raw(#map) %>;
I get the correct format.
Gmaps.map.markers = [{"lat":50.8483059,"lng":4.351783999999999},{"lat":50.11,"lng":5.003},{"lat":50.11,"lng":5.003},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.08,"lng":4.5760000000000005},{"lat":50.413,"lng":4.371}];

How to add link to marker using gmaps4rails gem

I would like to add a marker with link in marker, so, when i click that marker, i will redirect to another page
Is anybody know to do it?
Thanks
I already added my code like this :
In controller:
#json = #businesses.results.to_gmaps4rails do |object|
"\"link\": \"#{root_url}\""
end
In view :
<%= gmaps4rails(#json) %>
<% content_for :scripts do %>
<script type="text/javascript">
function redirect_to(url) {
window.location = url;
};
Gmaps4Rails.callback = function() {
function say_yo(arg) { return function(){alert('yo '+ arg + '!' );};};
for (var i = 0; i < Gmaps4Rails.markers.length; ++i) {
google.maps.event.addListener(Gmaps4Rails.markers[i].google_object, 'click', redirect_to(Gmaps4Rails.markers[i].link));
}
}
</script>
<% end %>
Is it any wrong? because there just an info window that show after i clicked the marker(Not redirect to any page)
First include the link inside the json:
Model.all.to_gmaps4rails do |object|
"\"link\": \"your link as string\""
end
Then add the extra listeners in your view (beware to include this AFTER your call to the gmaps method):
<%= gmaps(whatever you need here) %>
<% content_for :scripts do %>
<script type="text/javascript">
function redirect_to(url) {
window.location = url;
};
Gmaps4Rails.callback = function() {
function say_yo(arg) { return function(){alert('yo '+ arg + '!' );};};
for (var i = 0; i < Gmaps4Rails.markers.length; ++i) {
google.maps.event.addListener(Gmaps4Rails.markers[i].google_object, 'click', redirect_to(Gmaps4Rails.markers[i].link));
}
}
</script>
<% end %>

Resources