This is the view hello.html.erb using zurb foundation and tabulous:
<html>
<body>
<div class="contain-to-grid">
<nav class="top-bar" data-topbar>
<ul class="title-area">
<li class="name">
<h1>Hello World!</h1>
</li>
<li class="toggle-topbar menu-icon"><span>Menu</span>
</li>
</ul>
<ul class="center">
<li style="padding-top:55px;">
<%= form_tag("/salutation/hello", method: "post") do %>
<div class="large-6 columns" style="padding-left:250px;border:0px;
margin-right:0px;padding-right:0px;">
<%= text_field_tag(:find_stuff) %>
</div>
<div>
<%= submit_tag "Search", class: "large-1 small-3 columns",
style:"color:white;border:none;background-color:red;height:28px;margin:0px;"%>
</div>
<% end %>
Login|Register
</li>
</ul>
</nav>
<%= tabs %>
<%= subtabs %>
</div>
<div class="row">
<div class="six columns">
<div class="panel" style="min-height:800px">
<p><%= #test %></p>
<p><%= #test %></p>
</div>
</div>
</div>
</body>
</html>
This is the controller salutation.rb:
class SalutationController < ApplicationController
def new
#test = ''
end
def hello
#message = 'Hello, World!'
#test = params[:find_stuff]
end
end
This is very simple code for reading the text in the search box, and writing to the view. I have a
file tabulous.rb, which adds menu tabs to the screen. The code for tabulous.rb is:
tabulous.setup do
tabs do
news_tab do
text { 'News' }
link_path { news_index_path }
visible_when { true }
enabled_when { true }
active_when { in_action('any').of_controller('news') }
end
homes_tab do
text { 'Homes' }
link_path { homes_path }
visible_when { true }
enabled_when { true }
active_when { in_action('any').of_controller('homes') }
end
end
customize do
end
use_css_scaffolding do
background_color '#ccc'
text_color '#444'
active_tab_color '#fff'
hover_tab_color '#ddd'
inactive_tab_color '#aaa'
inactive_text_color '#888'
end
end
When I tried these tabs without the zurb foundation styling the form displays the menu tabs
fine, but when I embed this form in the view there is no display, and the form just displays the main top bar with the search box. Why this happens I can't figure out - is
this because of the styling by zurb foundation, that breaks it, or any other reason?
Why use tabulous.rb? Foundation already supports tabs out of the box. You can refer to the documentation for the markup required to create them. It'll be easier that way.
As an aside, I would really recommend against adding inline CSS in your markup. There should be a separation of concerns between your markup (for content), and your CSS (for style). Incidentally, this is the same reason that tabulous might not be a great choice for tabs. It's not Ruby's job to create structure and style.
Related
I have a navbar where I display the MainCategory (Men, Women, Neutral)
(MainCategory is a model that have only one attribute :gender.)
I've definied the different genders like so:
enum gender: [:men, :women, :neutral]in my model.
Expected:
When I hover the link "Men" I want that the sub menu of "Men" shows up , same for "Women" and "Neutral".
Category is another model which has attributes :gender and a :title
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mx-auto">
<% MainCategory.order('gender ASC').all.each do |main_cat| %>
<li class="nav-link gender"><%= main_cat.gender %>
<div id="categories">
<ul class="navbar-nav mx-auto">
<% Category.where(gender: main_cat.gender).order('title ASC').each do |cat| %>
<% if cat.product_with_stock %>
<li class="nav-link"><%= link_to "#{cat.title} ", clients_category_path(cat), class: "nav-link" %></li>
<% end %>
<% end %>
</ul>
</div>
<% end %>
</li>
</ul>
</div>
</nav>
This the js file that show and hide the #category div.
$(document).on('turbolinks:load', function() {
$(".gender").mouseenter(function(){
$("#categories").slideDown();
})
$("body").click(function() {
$("#categories").slideUp();
});
$("#categories").click(function(e) {
e.stopPropagation();
});
});
With this code, I see the same submenu if I hover men or women, or neutral...
How should I improve this to have what expected?
You'll need to specify the related gender for each div and open it from your JS:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mx-auto">
<% MainCategory.order('gender ASC').all.each do |main_cat| %>
<li class="nav-link gender" data-gender="<%= main_cat.gender %>"><%= main_cat.gender %>
<div class="categories" data-gender="<%= main_cat.gender %>">
<ul class="navbar-nav mx-auto">
<% Category.where(gender: main_cat.gender).order('title ASC').each do |cat| %>
<% if cat.product_with_stock %>
<li class="nav-link"><%= link_to "#{cat.title} ", clients_category_path(cat), class: "nav-link" %></li>
<% end %>
<% end %>
</ul>
</div>
<% end %>
</li>
</ul>
</div>
</nav>
JS:
$(document).on('turbolinks:load', function() {
$(".gender").mouseenter(function(){
var gender = $(this).data("gender")
$(".categories[data-gender=" + gender + "]").slideDown();
})
$("body").click(function() {
$(".categories").each(function() { $(this).slideUp() })
});
$(".categories").click(function(e) {
e.stopPropagation();
});
});
I can't test it, but this should work
I have an index page with different software in a table.
I want to display additional information (in a modal) when we click on a tr.
Everything works but I have the information of a single software that appears in my modal and is the same for each tr.
I would like to display the information of each software in the corresponding modals.
My script :
$(".clickable").click(function(e) {
if (!$(e.target).hasClass('no-click')) {
$('#exampleModal').modal('show');
}
});
My view :
<% #nonpremium.each do |software| %>
<table>
<tr class="clickable">
<td class="hey1">
<%= link_to software_path(software), class: "no-click" do %>
<%= image_tag software.logo.url(:medium), class:"no-click"%>
<% end %>
</td>
<td class="hey3">
<h6><%= software.slogan %></h6>
<p><%= software.largeslogan %></p>
</td>
</tr>
</table>
<div class="modal fade bd-example-modal-lg" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<%= link_to software.software_name, software_path(software), class:"no-click" %>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<% end %>
I tried something like this in my script, but it does not work ..
$(".clickable").click(function(e) {
if (!$(e.target).hasClass('no-click')) {
$('#exampleModal-<%= #software.id %>').modal('show');
}
});
Thx for you help
EDIT :
Controller/pages
class PagesController < ApplicationController
before_action :click, only: :index
def home
#softwares = Software.all.order(:cached_votes_up => :desc )
#premium = Software.includes(:user).where(users: { subscribed: true }).order("RANDOM()").limit(2)
#nonpremium = #softwares - #premium
end
def search
#softwares = Software.ransack(name_cont: params[:q]).result(distinct: true)
#categories = Category.ransack(name_cont: params[:q]).result(distinct: true)
respond_to do |format|
format.html {}
format.json {
#softwares = #softwares.limit(5)
#categories = #categories.limit(5)
}
end
end
end
EDIT 2 :
I have the desired result by putting in my table the information that I want to recover, then I put a "display: none".
<style>
td.test {
display:none;
}
</style>
<td class="test">
<span><%= software.software_description %></span>
<span><%= get_video_iframe(software.youtube_id) %></span>
</td>
Then I get the information from my table in my script:
$(".clickable").click(function(e) {
if (!$(e.target).hasClass('no-click')) {
var description = this.childNodes[3].innerHTML;
var name = this.childNodes[5].innerHTML;
document.getElementById("myModalName").innerHTML = name;
document.getElementById("myModalDesc").innerHTML = description;
$('#exampleModal').modal('show');
}
});
For then displayed in my modal:
...
<div class="modal-body" id="myModalName">
Name
</div>
<div class="modal-body" id="myModalDesc">
Description
</div>
...
There is probably better to do, but being a beginner is how I achieve the desired result.
However I would like to post videos in my modals.
Am I not going to overload my home page by hiding youtube videos with my display: none?
You won't be able to use erb in your script (unless this is in a script tag within your view, in which case your code should work) - better using a data attribute. For example, if you update your tr to the following:
<%= content_tag :tr, class: "clickable", data: { software_id: #software.id } do %>
# the rest of your code within the tr
<% end %>
# Equivalent of using:
# <tr class="clickable" data-software_id="<%= #software.id %>">
This attaches the relevant software_id to the tr in the DOM. You can then use the following in your script, accessing this new attribute:
$(".clickable").click(function(e) {
if (!$(e.target).hasClass('no-click')) {
$('#exampleModal-' + $(e.target).data('software_id')).modal('show');
}
});
And everything should work as desired.
Let me know how you get on or if you have any questions. Hope this helps!
Edit based on your comment:
That error you're seeing will come because #software is nil and you are, therefore, attempting to call id on nil.
It's a common error, and means to need to ensure #software is correctly set in your controller. If you post your controller code, I might be able to help with this.
Alternatively, you can 'safely' try the method, using #software&.id with newer versions of Ruby / Rails (or #software.try(:id) on older versions). However, that's not likely to be helpful here, more of a side note :)
Edit 2:
So, in your controller, you're not actually assigning the singular #software, rather the plural #softwares:
#softwares = Software.all.order(:cached_votes_up => :desc )
#premium = Software.includes(:user).where(users: { subscribed: true }).order("RANDOM()").limit(2)
#nonpremium = #softwares - #premium
Then, in your view, you're looping through #nonpremium using the local variable software. So, you can either:
assign #software in the controller if it should always use the same data in the modal
go back to the previous option, assigning a data attribute to the tr, which is what I'd recommend. Using that should work, although you'll need to alter the code to use software without the # to address the correct variable.
I.E.
<%= content_tag :tr, class: "clickable", data: { software_id: software.id } do %>
# the rest of your code within the tr
<% end %>
This ensures the script addresses the click based on the element clicked, and pulls the id directly from there, which is within the scope of your software loop.
That do it for ya?
I am new to rails and this is the first time I want to use a carousel in a web application. My carousel appears, but it does not auto-play.
This is what I have in my application.js :
//= require owl.carousel
$(function(){ $(document).foundation(); });
var owl = $('.owl-carousel');
owl.owlCarousel({
items:5,
loop:true,
margin:10,
autoplay:true,
autoplayTimeout:1000,
autoplayHoverPause:true
});
And this is from my view:
<div id="owl" class="owl-carousel">
<% #artists.each do |artist| %>
<div class="artist-card ">
<%= link_to artist, class: "poster" do %>
<%= image_tag artist.image.url(:thumb) %>
<% end %>
<div class="artist-info ell glassy-bg padmy padlx">
<div class="artist-card ">
<h6><%= artist.name %> <span>(<%= artist.instrument %>)</span></h6>
</div>
</div>
</div>
<% end %>
</div>
Is there also a way to display every artist from my database in the carousel? I've seen that the default number of items for the carousel is 5. Can I make it dynamic ?
I managed to solve the issue. Here is what I've done:
(function ($) {
$(document).ready(function() {
if ($('.carousel .owl-wrapper-outer').length === 0) {
var owl = $('.carousel').owlCarousel({
items:5,
loop:true,
margin:10,
autoPlay:1000,
autoplayHoverPause:true,
responsive: true,
responsiveRefreshRate : 200,
responsiveBaseWidth: window,
});
$('.carousel').hover(function() {
owl.trigger('owl.stop');
}, function(){
owl.trigger('owl.play', 1000);
});
}
I am working on a Hiragana flashcards app.
I spend nights and days to understand how don't refresh full page when I add a flashcard (hiragana) as a favorite.
Here is the favorite controller
class FavsController < ApplicationController
def index
#favs = Fav.where(user: current_user)
end
def create
#hiragana = Hiragana.find(params[:hiragana_id])
#fav = current_user.favs.new(hiragana: #hiragana)
if not #hiragana.favs.where(user: current_user).take
#fav.save
end
render json: #fav
end
def destroy
#fav = Fav.find(params[:id])
#fav.destroy
redirect_to :back
end
end
I render json in the create method and when I click on view I add only an hash
render view favorite
<% if current_user %>
<div class="hiragana-fav">
<% if hiragana.is_faved_by(current_user) %>
<%= link_to fav_path(hiragana.is_faved_by(current_user)), method: :delete do %>
<i class="fa fa-heart faved faved-on"></i>
<% end %>
<% else %>
<%= link_to hiragana_favs_path(hiragana), method: :post do %>
<i class="fa fa-heart faved faved-off"></i>
<% end %>
<% end %>
</div>
<% end %>
and it is located in hiragana render
<div class="row">
<ul class="list-inline text-center card-frame">
<li>
<div class="card">
<div class="front">
<% if current_user.try(:admin?) %>
<%= link_to hiragana_path(hiragana), class:'trash-hiragana', data: { confirm: 'Are you sure?' }, method: :delete do %>
<%= image_tag("delete-btn.png") %>
<% end %>
<% end %>
<span class="card-question img-popover" data-content="<h4 class='text-center letter-uppercase'><%= hiragana.bigletter.upcase %></h4><p class='text-center'><b><%= hiragana.midletter %></b> comme dans <b><%= hiragana.transcription %></b></p>">
<i class="fa fa-eye fa-lg"></i>
</span>
<div class="card-hiragana hiragana-<%=hiragana.bigletter.downcase.last%>">
<h1><b><%= hiragana.ideo1 %></b></h1>
</div>
<div class="card-katakana">
<p><%= hiragana.ideo2 %></p>
</div>
<%= render 'favs/favorites', hiragana: hiragana %>
</div>
<div class="back">
<div class="col-sm-3 col-xs-4 col-md-3 containerbackcards-<%=hiragana.bigletter.downcase.last%>">
<div class="backcard-hiragana">
<h1><b><%= hiragana.ideo1 %></b></h1>
</div>
<div class="card-bigletter">
<h4><%= hiragana.bigletter.upcase %></h4>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
When I add a card as favorite it gives me a hash like this :
{
id: 64,
user_id: 1,
hiragana_id: 4,
created_at: "2016-02-10T16:37:26.270Z",
updated_at: "2016-02-10T16:37:26.270Z"
}
I just want to have the heart grey to red as favorite, saved and not refresh the entire page. Your explainations are appreciated thank you.
In order to send the request to the controller without the page refreshing you need to use a combination of Ajax and JavaScript.
You use JavaScript to add a click listener to the .faved-on button and to trigger the Ajax request. You will also use JavaScript to prevent the default action occurring when you click the link ie. The Page Refresh
You then use Ajax to send the request to the controller and handle the response.
Your initial JavaScript code looks pretty correct, except you are missing the bit to stop the page from reloading.
See the e.preventDefault(); line below
$(document).ready(function() {
$('.faved-on').click(function(e) { //make sure to pass in the e (the event paramter)
e.preventDefault(); //this is the line you are missing
var fav = $('.faved-off')
//let your ajax handle the rest then
$.ajax({
type: "POST", url: "/hiraganas", dataType: "json",
success: function(data) {
console.log(data);
//change the color of your heart to red here
},
error: function(jqXHR) {
console.error(jqXHR.responseText);
}
});
})
})
I haven't tested your JavaScript but it looks pretty close to correct, I believe its the e.preventDefault(); bit you were missing
I have a problem with working my tab along with will_pagination. When i press Tab 2, it will show the correct content, but when i press on the pagination link, example page 2. It will bring me back to my Tab 1 view. After this, when i press back Tab 2, it will appear page 2 content of Tab 2. The problem here is why does it bring my back to my Tab 1 view when i press on the pagination link in Tab 2.
My View Code
<div>
<ul class="nav nav-tabs" id="TabLength">
<% #biscuit.each_index do |i| %>
<% if i == 0 %>
<li class="active"><a data-toggle="tab" href="#<%= #biscuit[i] %>"><%= #biscuit[i] %></a></li>
<% else %>
<li><a data-toggle="tab" href="#<%= #biscuit[i] %>"><%= #biscuit[i] %></a></li>
<% end %>
<% end %>
</ul>
<div class="tab-content">
<% #biscuit.each_index do |i| %>
<% if i == 0 %>
<div class="tab-pane fade in active" id="<%= #biscuit[i] %>">
<div class="row" id="PictureSetting">
<% #testpage.each do |i| %>
<div class="col-md-4" id="ProductPic">
<%= image_tag(i.name , class:"img-thumbnail", size:"180x180") %>
</div>
<% end %>
</div>
<%= will_paginate #testpage, :param_name => 'user_page' %>
</div>
<% elsif i == 1 %>
<div class="tab-pane fade" id="<%= #biscuit[i] %>">
<div class="row" id="PictureSetting">
<% #memberpage.each do |i| %>
<div class="col-md-4" id="ProductPic">
<%= image_tag(i.name , class:"img-thumbnail", size:"180x180") %>
</div>
<% end %>
</div>
<%= will_paginate #memberpage, :param_name => 'choco_page' %>
</div>
<% else %>
<div class="tab-pane fade" id="<%= #biscuit[i] %>">
<div class="row" id="PictureSetting">
<h1>hello</h1>
</div>
</div>
<% end %>
<% end %>
</div>
</div>
Thanks
Based on answer from here, you can design the following code for the problem:
<script>
// open tab on click
$('#TabLength a').click(function (e) {
e.preventDefault();
$(this).tab('show');
// getting tab id
var id = $(e.target).attr("href").substr(1);
// change hash value for all pages
$('ul.pagination > li > a').each(function(i, pageAnchor) {
pageAnchor.hash = id;
});
});
// assign tab id to location hash
$("ul.nav-tabs > li > a").on("shown.bs.tab", function (e) {
var id = $(e.target).attr("href").substr(1);
window.location.hash = id;
});
// open initial hash
var hash = window.location.hash;
$('#TabLength a[href="' + hash + '"]').tab('show');
// UPDATE
$('ul.pagination > li > a').each(function(i, pageAnchor) {
pageAnchor.hash = hash;
});
</script>
It saves currently selected tab into location.hash. and selects it when you navigate to a new page.