jQuery UI Tab persistence (coffeescript) - jquery-ui

I have a Rails 3 app with some jQuery UI tabs to display published and unpublished stories. Here is the erb template:
<ul class="tabs">
<li><strong>Filter:</strong></li>
<li class="active"><%= link_to 'Published', '#published_stories' %></li>
<li><%= link_to 'Unpublished', '#unpublished_stories' %></li>
</ul>
<div id="published_stories">
<% #published_stories.each do |published_story| %>
<article class="story_article">
<h2><%= published_story.title %></h2>
<ul>
<li><%= link_to "Update", edit_story_path(published_story) %></li>
<li><%= link_to "Destroy", story_path(published_story), method: "delete", confirm: "Are you sure?" %></li>
</ul>
<%= time_tag published_story.published_at, pubdate: true %>
<%= markdown published_story.content.truncate(400, separator: " ") %>
</article>
<%= paginate #published_stories %>
<% end %>
</div>
<div id="unpublished_stories">
# As above to show unpublished stories
</div>
I'm listening to the click event on the li element to style the active tab. Now I would like to use jquery.cookie.js so that after a page refresh the previously selected tab persists. Here is what I have already:
jQuery ->
$(".tab_container").tabs(
active : ($.cookie('saved_tab') || 0),
activate : -> (event ui)
newIndex = ui.newTab.parent().children().index(ui.newTab)
$.cookie('saved_tab', newIndex, { expires: 1 })
)
$(".tabs li").click ->
$(this).addClass("active").siblings().removeClass("active")
The error message I get is that it can't find the variable ui. Any help is much appreciated.

I can see a few things that are off in your CoffeeScript.
First of all, functions are defined like:
(arg, arg, ...) -> function_body
in CoffeeScript so you want to say activate: (event, ui) -> .... Your -> (event ui) is interpreted as:
-> event(ui)
and that doesn't make much sense.
Secondly, you have to be very careful with your indentation in CoffeeScript, indentation is pretty much all you have for defining the structure of your code so you must be very careful with it. When you say this:
activate : -> (event ui)
newIndex = ui.newTab.parent().children().index(ui.newTab)
$.cookie('saved_tab', newIndex, { expires: 1 })
CoffeeScript doesn't see the newIndex assignment or $.cookie call as part of the activate method, CoffeeScript sees three separate and unrelated statements.
Applying the above gives us:
$(".tab_container").tabs(
active : ($.cookie('saved_tab') || 0),
activate : (event, ui) ->
newIndex = ui.newTab.parent().children().index(ui.newTab)
$.cookie('saved_tab', newIndex, { expires: 1 })
)

Related

Trouble with toggling visibility of a link_to in a tag

It's been a very long time since I've touched anything to do with Javascript or Coffeescript, still pretty new to RoR and I'm having some trouble getting an eventlistener to work.
Currently tags on my app are displayed with an 'x' that functions as a delete link. Here is what I'm trying to accomplish:
(in case my photo isn't loading) I want the displayed tag to show the name, and when hovered over, I'd like the x to be visible.
ERB:
<div class="desktop-only">
<% contact.tags.last(2).each do |t| %>
<span class="badge badge-color" id="tag-id-<%=t.id %>-<%=contact.id%>-d"
data-toggle="tooltip"
data-html="true"
data-placement="top"
title="<%= t.name%>">
<div class='truncate'><%= t.name %></div>
<%= link_to 'x', remove_tag_contact_path(contact, t), remote: true, class: 'tag-remove', id:'tag-remove', data: { confirm: 'Are you sure you want to delete the tag?' } %>
</span>
<% end %>
<% if contact.tags.count > 2 %>
<span class="badge badge-light" id="count-<%= contact.id %>-d">+<%= contact.tags.count-2 %></span>
<% end %>
</div>
.coffee:
toggle_tag = ->
tag_remove = document.getElementById('tag-remove')
display = ->
tag_remove.style.visibility = 'visible'
hide = ->
tag_remove.style.visibility = 'none'
tag_remove.addEventListener 'mouseover', display
tag_remove.addEventListener 'mouseout', hide
window.addEventListener 'turbolinks:load', toggle_tag
Currently the tags aren't changing on mouseover, and I cannot figure out why. Can anyone point me in the right direction?

How to run a specific AJAX call in Rails

I am using has_scope to filer to filter jobs in a show.html.erb page. Once the jobs are filtered or not, the user can click on a job title and have the detail displayed on the same page on a partial. I have two functions in show.js.erb working, except that when the user clicks on the job title, the system run both call again and re-initialize the jobs selection. Can I isolate the second call so it does not run both functions ?
I have the two lines working well.
show.js.erb
$("#job_indiv").html("<%= j render partial: 'jobs/show', :locals => {:job => #job} %>");
(The above function display the individual details of the job)
$('#job_menu_left').html('<%= escape_javascript(render('menu_left')) %>')
(The above function filters the jobs list)
The view:
<div class="job_intro_display">
<%= form_tag job_path, method: 'get', id: "jobs_search" do %>
<div>
<% #industries = Job.all.distinct.pluck(:industry) - ["", nil] %>
Industry:<br>
<% #industries.each do |industry| %>
<div class="btn-filter">
<%= check_box_tag "by_industries[]", industry %> <%= industry %>
</div>
<% end %>
</div>
</div>
<div id="job_menu_left">
<%= render 'menu_left' %>
</div>
<div id="job_indiv">
<%= render 'jobs/show' %>
</div>
<script type="text/javascript">
$(function () {
$('input[type=checkbox]').change(function () {
$.get($('#jobs_search').attr('action'),
$('#jobs_search').serialize(), null, 'script');
return false;
});
$('#jobs_search').submit(function () {
$.get(this.action, $(this).serialize(), null, 'script');
return false;
});
});
</script>
Each ajax should be able to run separately.

Starting owlCarousel in rails

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);
});
}

Add as favorite with no full page refresh

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

save position of draggable li jQuery Rails 3

I have page with a map on my web-site where administrator can drag and drop icons to the specific position. After reading some examples, icons can be draggable, but when i try to refresh the page all icons revert to their default positions. I can't figure out how to save the position of elements to the database. I'm using jQuery and Rails 3. Help me please!
Thank you!
Here's the code of my page:
<div class="map">
<ul class="departments-map" id="departments-map">
<%= render :partial => 'departments/departments_short_map', :collection => #departments %>
</ul>
</div>
Departments_short_map:
<% department ||= departments_short_map %>
<% if department.map_x.nil? or department.map_y.nil? %>
<li id="<%= department.id %>" class="department-short-map">
<%= department_for_collage(department) %>
</li>
<% else %>
<li id="<%= department.id %>" class="department-short-map" style="position:absolute; top:#{ department.map_y}px; left:#{ department.map_x}px;">
<%= department_for_collage(department) %>
</li>
<% end %>
And here is my jQuery code:
var Collage = {
init: function() {
$("#departments-map li").draggable({
scroll: false,
stop: function(event, ui) {
var img = {
"id": $(this).attr('id'),
"map_y": $(this).position().top.toString(),
"map_x": $(this).position().left.toString()
};
$.ajax({
type: "put",
url: "/departments/" + $(this).attr('id') + ".json",
data: JSON.stringify(img),
contentType: 'application/json',
dataType: 'json',
})
}
});
}
}
What am i doing wrong?

Resources