I am looking for a better way or improved way of handling my Ajax call, currently my Gallery Objects (images) are being duplicated when making a request for them via .load()
I call the content of my Show action from my index page
<div id="project">
<div class="col-md-6">
<div class="project-media">
<div class="project-slider">
<ul class="slides">
<% @gallery.gallery_images.each do |image| %>
<li><%= image_tag(image.photo.url(:gallery_flexslider)) %>
<p class="flex-caption"><%= image.image_status %></p>
</li>
<% end %>
</ul>
</div>
</div>
</div>
<div class="col-md-6">
<div class="project-info">
<h1><%= @gallery.title %></h1>
</div>
<div class="project-category">
<span class="border"></span>
<span><%= @gallery.category.name %></span>
<span class="border"></span>
</div>
<p class="center"><%= @gallery.overview %></p>
</div>
</div><!--/#project -->
Index
<!-- Portfolio Section -->
<section id="portfolio" class="section">
<div class="container">
<div class="title col-md-8 col-sm-10 col-xs-12">
<h1>Our <strong>Portfolio</strong></h1>
<hr>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
<!-- Portfolio Filters -->
<ul id="filters">
<li class="filter" data-filter="all">All</li>
<% @categories.each do |c| %>
<li class="filter" data-filter="<%= c.name %>"><%= c.name %></li>
<% end %>
</ul>
<!-- End Portfolio Filters -->
</div>
<div class="portfolio-top"></div>
<!-- Portfolio Grid -->
<ul id="portfolio-grid">
<% @galleries.each do |g| %>
<li class="mix <%= g.category.name %> mix_all">
<% g.gallery_images.take(1).each do |i| %>
<%= image_tag(i.photo.url(:gallery_portfolio_home), class: 'open-project') %>
<a href='/galleries/<%= g.id %>' class="open-project">
<% end %>
<div class="project-overlay">
<i class="fa fa-plus-circle fa-3x"></i>
<span class="project-name"><%= g.title %></span>
<span><%= g.category.name %></span>
</div>
</a>
</li>
<% end %>
</ul>
<!-- End Portfolio Grid -->
<!-- Ajax Loaded Portfolio -->
<div id="project-extended">
<div class="container">
<ul id="project-controls">
<li>
<a href="#" id="close-project">
<i class="fa fa-times fa-2x"></i>
</a>
</li>
</ul>
<div id="project-content"></div>
</div>
</div>
<!-- End Ajax Loaded Portfolio -->
<div class="portfolio-bottom"></div>
The show action gets appended to #project-content.
JS
$(document).ready(function() {
//Portfolio filters
$('#portfolio-grid').mixitup({
effects: ['fade','scale'],
easing: 'snap'
});
//Portfolio project slider
function initProjectSlider() {
$('.project-slider').flexslider({
prevText: "",
nextText: "",
useCSS: false,
animation: "slide"
});
};
//Portfolio Project Loading
$('.open-project').click(function(){
var projectUrl = $(this).attr("href");
$('#project-content').animate({opacity:0}, 400,function(){
$("#project-content").load(projectUrl);
$('#project-content').delay(400).animate({opacity:1}, 400);
});
//Project Page Open
$('#project-extended').slideUp(600, function(){
$('#project-extended').addClass('open');
$('html, body').animate({ scrollTop: $(".portfolio-bottom").offset().top }, 900);
}).delay(500).slideDown(600,function(){
$('#project-content').fadeIn('slow',function(){
if ($('.project-slider').length > 0) {
initProjectSlider();
}
});
});
return false;
});
//Project Page Close
$('#close-project').click(function(event) {
$('#project-content').animate({opacity:0}, 400,function(){
$('#project-extended').delay(400).slideUp(400).removeClass('open');
$('html, body').animate({ scrollTop: $(".portfolio-top").offset().top -60}, 900);
});
return false;
});
});
Apologies for the size of this but this is the output when rendering the show action, all my images are being duplicated
EDIT
refactored js, not throwing any errors but not loading the content within show action]
$(document).ready(function() {
//Portfolio filters
$('#portfolio-grid').mixitup({
effects: ['fade','scale'],
easing: 'snap'
});
//Portfolio project slider
function initProjectSlider() {
$('.project-slider').flexslider({
prevText: "",
nextText: "",
useCSS: false,
animation: "slide"
});
};
//Portfolio Project Loading
var connect = function(link, success, fail) {
$.ajax({
url: link,
success: function(data) { success(data) },
error: function(data) { error(data) }
});
};
var animate = function(){
$('#project-extended').slideUp(600, function(){
$('#project-extended').addClass('open');
$('html, body').animate({ scrollTop: $(".portfolio-bottom").offset().top }, 900);
}).delay(500).slideDown(600,function(){
$('#project-content').fadeIn('slow',function(){
if ($('.project-slider').length > 0) {
initProjectSlider();
}
});
});
};
$(document).on("click", ".open-project",function(e){
e.preventDefault();
var url = $(this).attr("href");
$("#project_content").fadeOut(400, function() {
connect(url, function(data){
$("#project_content").html(data).fadeIn(400);
}, function(data){
$("#project_content").fadeIn(400);
});
});
animate();
});
//Project Page Close
$('#close-project').click(function(event) {
$('#project-content').animate({opacity:0}, 400,function(){
$('#project-extended').delay(400).slideUp(400).removeClass('open');
$('html, body').animate({ scrollTop: $(".portfolio-top").offset().top -60}, 900);
});
return false;
});
});
Here's a refactor for you:
//Portfolio Project Loading
var connect = function(link, success, fail) {
$.ajax({
url: link,
success: function(data) { success(data) },
error: function(data) { error(data) }
});
};
var animate = function(){
$('#project-extended').slideUp(600, function(){
$('#project-extended').addClass('open');
$('html, body').animate({ scrollTop: $(".portfolio-bottom").offset().top }, 900);
}).delay(500).slideDown(600,function(){
$('#project-content').fadeIn('slow',function(){
if ($('.project-slider').length > 0) {
initProjectSlider();
}
});
});
};
$(document).on("click", ".open-project",function(e){
e.preventDefault();
var url = $(this).attr("href");
$("#project_content").fadeOut(400, function() {
connect(url, function(data){
$("#project_content").html(data).fadeIn(400);
}, function(data){
$("#project_content").fadeIn(400);
});
});
animate();
});
This should make the ajax call the data asynchronously, but act synchronously (uses callbacks). This means you'll be able to get the data properly (once). I think this will help you a lot, but may need some more fixes to prevent the duplication you're experiencing