Slick.Js asNavFor Resetting to First Slide Each Time - javascript

I'm using the Slick.JS plugin and have enountered an issue I'm hoping someone can help me with. I have two carousels, both have five slides, with the top carousel showing one slide at a time and the bottom showing all five at a time. The top is movable by arrows and on the bottom each individual slide image is clickable but there are no arrows or dots.
The intended behavior is I want a click on a slide in the carousel showing five at a time (bottom) to move the other carousel to the corresponding slide (a click on slide 3 in the bottom moves the top to slide 3, for example). Similarly, if someone rotates the one on the top, I want the "active" slide at the bottom to correspond to the number of the slide showing at the top.
Here is an example of how I want it to function: https://codepen.io/pjmtokyo/pen/JYyjew. "Slider syncing" here is another one but without the arrows on the bottom: http://kenwheeler.github.io/slick/.
Basically, when I click the arrows on the top nav, the bottom one updates appropriately (adding class "slick-active" to the appropriate slide). However, a click on the bottom nav always returns the top nav to the first slide. What am I doing wrong so clicks on the bottom don't update the top appropriately?
Here are my Slick Options (I'm using slick.1.4.1 with Jquery 3.2.1):
# HOMEPAGE WHO WE SERVE SLIDER
homepageWhoWeServeSlickOptions =
slidesToShow: 1,
slidesToScroll: 1,
arrows: true,
asNavFor: '.home-serve-icons',
homeServeIconsOptions =
slidesToShow: 5,
slidesToScroll: 1,
asNavFor: '.home-serve-scroll',
arrows: false,
focusOnSelect: true
$('.home-serve-scroll').slick(homepageWhoWeServeSlickOptions)
$('.home-serve-icons').slick(homeServeIconsOptions)
$('.home-serve-icons .slick-slide').removeClass 'slick-active'
$('.home-serve-icons .slick-slide').eq(0).addClass 'slick-active'
$('.home-serve-scroll').on 'beforeChange', (event, slick, currentSlide, nextSlide) ->
mySlideNumber = nextSlide
$('.home-serve-icons .slick-slide').removeClass 'slick-active'
$('.home-serve-icons .slick-slide').eq(mySlideNumber).addClass 'slick-active'
return
Here is the HTML that Slick is targeting (Twig code interwoven in there):
{% from '_macros/button' import button as m_button %}
{% set whoWeServe = craft.entries.section('homepageWhoWeServe').limit(5) %}
<section>
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="home-serve-scroll" style="padding: 0px 40px;">
{% for entry in whoWeServe.all() %}
<div id="serve-{{ loop.index }}">
<h2>{{ entry.title }}</h2>
{{ entry.whoWeServeDescription }}
{% set destination = entry.whoWeServeLandingPage.one.getUrl() %}
{% set text = entry.whoWeServeCtaText | default("Learn More") %}
{{ m_button(destination, text, {classes:'important-cta-button'}) }}
</div>
{% endfor %}
</div>
</div>
</div>
<div class="col-md-10 col-md-offset-1">
<div class="home-serve-icons">
{% for entry in whoWeServe.all() %}
<div id="serve-icon-{{ loop.index }}">
{{ entry.title }}
</div>
{% endfor %}
</div>
</div>
</div>
</section>

So I was able to get this issue resolved. Gouigouix's comment on this issue was the trick: https://github.com/kenwheeler/slick/issues/649
Basically, you have a proper HTML tag within your container div for it to work. I just had a div with some unwrapped text in it. So changing this:
<div class="col-md-10 col-md-offset-1">
<div class="home-serve-icons">
{% for entry in whoWeServe.all() %}
<div id="serve-icon-{{ loop.index }}">
{{ entry.title }}
</div>
{% endfor %}
</div>
</div>
to this:
<div class="col-md-10 col-md-offset-1">
<div class="home-serve-icons">
{% for entry in whoWeServe.all() %}
<div id="serve-icon-{{ loop.index }}">
<p>{{ entry.title }}</p>
</div>
{% endfor %}
</div>
</div>
Was the ticket. Hope that helps someone!

Related

Show and hide text of different posts

I have several posts each of them composed of three parts : a title, a username/date and a body. What I want to do is to show the body when I click on either the title or the username/date and hide it if I click on it again. What I've done so far works but not as expected because when I have two or more posts, it only shows the body of the last post even if I click on another post than the last one. So my goal is only to show the hidden text body corresponding to the post I'm clicking on. Here is my code:
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}Test page{% endblock %}</h1>
<a class="action" href="{{ url_for('main_page.create') }}">New</a>
{% endblock %}
{% block content %}
{% for post in posts %}
<article class="post">
<header>
<script language="JavaScript">
function showhide(newpost)
{var div = document.getElementById(newpost);
if (div.style.display !== "block")
{div.style.display = "block";}
else {div.style.display = "none";}}
</script>
<div onclick="showhide('newpost')">
<h1>{{ post['title'] }}</h1>
<div class="about">by {{ post['username'] }} on {{ post['created'].strftime('%d-%m-%Y') }}</div>
</div>
</header>
<div id="newpost">
<p class="body">{{ post['body'] }}</p>
</div>
</article>
{% if not loop.last %}
<hr>
{% endif %}
{% endfor %}
{% endblock %}
Of course I looked for a solution as much as I could but I'm kind of stuck plus I'm a complete beginner in HTML/JS/CSS. And one last thing, I'm currently using Python's framework Flask. Thank you by advance.
You need to give each of your posts a unique id for your approach to work.
Change your code to
<div id="{{post_id}}">
<p class="body">{{ post['body'] }}</p
</div>
where post_id is that post's unique id e.g. its id in the database you are using that you pass to the template in your view. Then, change the call to the onclick event handler to
<div onclick="showhide('{{post_id}}')">
If you don't have a unique id you can also use the for loop's index: replace all post_id instances above with loop.index. See Jinja's for loop docs for more information.

How to show Django page with VenoBox?

Portfolio page, each post have its detailed page that is accessible by clicking on it
Need the content of the detailed post page in the grey container but it's displayed over it
That's how I link it from each portfolio post
The detailed page code extended with template.html, where venobox css,js and jquery linked.
{% extends "template.html" %}
{% block content %}
<main id="main">
<!-- ======= Portfolio Details ======= -->
<div id="portfolio-details" class="portfolio-details">
<div class="container">
<div class="row">
<div class="col-lg-8 ">
<h2 class="portfolio-title">{{work.title}}</h2>
<div class="owl-carousel portfolio-details-carousel">
{% for image in work.images %}
<img src="{{image}}" class="img-fluid" alt="">
{% endfor %}
</div>
</div>
<div class="col-lg-4 portfolio-info">
<ul>
<li><strong>Category</strong>: {{work.work_type}}</li>
<li><strong>Project tools</strong>: {{work.tools}}</li>
<li><strong>Project date</strong>: {{work.created}}</li>
<li><strong>Project URL</strong>: {{work.link}}</li>
</ul>
<p>
{{work.description}}
</p>
</div>
</div>
</div>
</div><!-- End Portfolio Details -->
</main><!-- End #main -->
{% endblock content %}`
Pls, help :)
If your problem is simply concerning the fact that the content is displayed over it instead of within then you can alter the values of the venoBox.
Custom settings, See here for more configurable options.
$('.venobox_custom').venobox({
framewidth : '400px', // default: ''
frameheight: '300px', // default: ''
border : '10px', // default: '0'
bgcolor : '#5dff5e', // default: '#fff'
titleattr : 'data-title', // default: 'title'
numeratio : true, // default: false
infinigall : true, // default: false
share : ['facebook', 'twitter', 'download'] // default: []
});
You can also use CSS to set the badly positioned content to wherever you want on the page.

How to set position of a block at top-right with freewall.js?

I am facing a problem with freewall.js.
I want to set the position of a specific element at top-right, but the only options i found in the docs are for top-left positioning.
<div class="freewall">
<div class="freewall-item js-frontpage-teaser-slider frontpage-teaser-slider">
{{ render_esi(controller( "sf.fnma.controller.frontpage:renderAdBanner")) }}
</div>
<div class="freewall-item mx-auto sidebar-banner" data-fixPos="top-right">
{% include 'teaser/frontpage.html.twig' %}
</div>
{{ render_esi(controller( "sf.fnma.controller.frontpage:renderEvents")) }}
{{ render_esi(controller("sf.fnma.controller.frontpage:renderNews")) }}
</div>
</div>
I have tried the fixPos() method and the data attributes data-positon and data-fixPos, but i'm not able to achieve the result i want.

How to fix this bug on Glide.js? The width of the active slide is always smaller than the others

I'm using Glide.js for a carousel, but the active item always has the width smaller than that of the others, and this is set by glide.js.
And that height being smaller, makes it inconsistent and ugly, as you can see in this video: https://vimeo.com/323290507
I already tried to add a 'DOMContentLoaded' event listener to get the node of the active item and node of the clones (which contains the correct height) and change the width of the active slide to the same width as the other, this worked only the first time, because glide always changes the width every time you change the current slide.
I also tried using MutationObserver but I'm not really sure how it works and I did not get it.
Here is my code:
<div class="glide">
<div data-glide-el="track" class="glide__track">
<ul class="glide__slides">
{% for article in articles %}
{% with article.specific as article %}
<li class="glide__slide">
{% image article.main_image fill-1300x500 as img %}
<img src="{{img.url}}" width="100%">
</li>
{% endwith %}
{% endfor %}
</ul>
</div>
<div class="glide__arrows" data-glide-el="controls">
<i class="myglide__arrow myglide__arrow--left fas fa-angle-left" data-glide-dir="<"></i>
<i class="myglide__arrow myglide__arrow--right fas fa-angle-right" data-glide-dir=">"></i>
</div>
<div class="glide__bullets" data-glide-el="controls[nav]">
<button class="glide__bullet" data-glide-dir="=0"></button>
<button class="glide__bullet" data-glide-dir="=1"></button>
<button class="glide__bullet" data-glide-dir="=2"></button>
</div>
</div>
<script>
const glide = new Glide('.glide', {
type: 'carousel',
startAt: 0,
perView: 1,
autoplay: 3000,
hoverpause: true,
keyboard: true,
duration: 1000,
arrows: true,
animationTimingFunc: 'ease-in-out',
});
glide.mount();
</script>

How to close Bootstrap modal window after set interval of time using Jquery?

I have a script which makes AJAX calls to update a page every 5 seconds. I want to display a alert/popup every time a change is observed i.e. for the first time when the page loads, I want to display a popup that says "Everything setup!" and on the subsequent page loads via AJAX, I'll display a popup IF there is any change. The popup stays on the page for 2 seconds and then disappears.
I am able to make the AJAX calls successfully. However, the popup window does not work as expected.
Observed behavior :- The popup window shows up on page load as expected, but it does not close after 2 seconds. However, the page refreshes after 5 seconds due to AJAX call. The popup remains in its place unless I manually close it.
I think I have figured out where the problem may be arising. The AJAX calls are being made through the setInterval() function of JS. I had removed that statement and tried calling the popup function and it worked as expected i.e. the page loaded and then the popup appeared. After 2 seconds the popup closed automatically. This method however is not helpful as I will not be able to perform the page reloads in the background after every 5 seconds.
The issue seems to arise from the AJAX calls.
HTML - dashboard.html
{% extends "base.html" %}
{% block content %}
<div id='modal-disp' class="modal fade bs-example-modal-sm" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
No new images!
</div>
</div>
</div>
<div class="image-area">
<div class="container dash-container main-body" >
<hr>
<div class="row">
<br>
<hr >
<br>
<div class="col-md-12">
<div class="jumbotron ">
<h1 id="hdr">DASHBOARD</h1>
</div>
</div>
</div>
{% if folders %}
<div class="row">
<div class="col-md-12 folder-list" id="info">
Please select the Date to view their corresponding test results.<br><br>
{% set ns = namespace(counter=0) %}
<table class="table table-hover ">
{% for row in range(rows) %}
<tr class="row-hover">
{% for data in range(3) %}
{% if ns.counter < folders|length %}
<td>
<a class="folder-link" href="{{ url_for('image',im=folders[ns.counter]) }}">{{ folders[ns.counter] }}</a>
<br>
{% set ns.counter = ns.counter + 1 %}
</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</table>
</div>
</div>
{% endif %}
{% if images %}
<div class="row" id="info">
<span class="glyphicon glyphicon-backward" aria-hidden="true"></span>
</div>
<br><br>
<div class="row">
<div class="col-md-12" id="info">
{% set ns = namespace(counter=0) %}
<table class="table table-hover table-condensed table-bordered images-table" cellspacing="5" cellpadding="5">
{% for row in range(rows) %}
<tr class="image-hover">
{% for data in range(3) %}
{% if ns.counter < images|length %}
<td style="width:10%;">
<img src="{{ url_for('static',filename=images[ns.counter]) }}" alt="User Image" width="200" height="180">
<br>
{% set ns.counter = ns.counter + 1 %}
</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</table>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock %}
Javascript file -
<script type="text/javascript">
var first_time = 0;
var current_count = 0;
var total_count = 0;
function update(){
$('#modal-disp').modal('show');
setTimeout(function() { $("#modal-disp").modal('hide'); }, 2000);
if (first_time === 0){
current_count = $('td').length;
total_count = current_count;
first_time = 1;
//var txt = $("<p class='notify'></p>").text("No new images");
$('body').append("<div class='row'><div class='col-md-12'><p class='notify'><br>Up to date !</p></div></div>");
$('.notify').css({'color':'#06661f','font-size':'30px','font-family': "'Saira',sans-serif",'font-style':'bold','text-align': 'center'});
$('html, body').animate({scrollTop:$(document).height()}, 'slow');
//$('#myModal').modal('hide');
setTimeout(function() { $(".notify").text(""); }, 5000);
}
else {
total_count = $('td').length;
if (total_count>current_count){
$('.notify').text(total_count-current_count + " new image added !");
$('.notify').css({'color':'#bc0041','font-size':'30px','font-family': "'Saira',sans-serif",'font-style':'bold','text-align': 'center' });
$('html, body').animate({scrollTop:$(document).height()}, 'slow');
//alert(total_count-current_count + ' images added !');
current_count = total_count;
setTimeout(function() { $(".notify").text(""); }, 5000);
}
}
}
//setInterval(function(){ $('.image-area').load("{{ url_for('image',im=image_date) }}"); update(); }, 2000);
setInterval(function(){$('.image-area').load("{{ url_for('image',im=image_date) }}", function() {update();}); }, 5000);
</script>
Here, Flask is used in the back end. So I am calling the /image route every 5 seconds. For the sake of keeping the code simple, I am just displaying a static popup for now. The popup is defined at the top of the HTML file. My best guess is the AJAX calls are interfering with the DOM and as a result the modal ID tag is getting masked.
Please help.
EDIT 1:
Notice in Image 1, there is the popup and also the message - "Up to date!" at the extreme bottom of the page. This works as it should because the page is loaded for the first time.
Here, in image 2 you can see that the message -"Up to date" is not there anymore. This behavior is also expected because according to code logic, the message is displayed on initial page load only. It will not be displayed on subsequent AJAX page reloads. Check the function update() for clarity.
At the same time, you can see that the alert box has remained in its place. More than 10 seconds have passed and the alert box has not closed at all.
EDIT 2:
I have noticed that if I place the HTML for the modal inside the div tag with class="image-area", the popup closes after 2 seconds but its backdrop (i.e the grayed out background ) does not disappear. Also, because of this, the entire website becomes unresponsive. Clicking anywhere, on the screen has no effect and everything appears grayed out due to the presence of the backdrop.
The div with class area="image-area" defined at the top encloses all the HTML that is refreshed every 5 seconds. This part of the HTML is fetched from the back end.
Python - routes.py
#app.route('/image/<im>')
#login_required
def image(im):
image_src=[im+'/'+i for i in os.listdir(os.path.join(app.static_folder,im))]
rows=math.ceil(len(image_src)/3)
print(image_src)
return render_template('dashboard.html',title='Welcome',images=image_src,rows=rows,image_date=im)
The above behavior is observed when I move the modal HTML inside the topmost div tag as follows:
{% extends "base.html" %}
{% block content %}
<div class="image-area">
<div id='modal-disp' class="modal fade bs-example-modal-sm" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
No new images!
</div>
</div>
</div>
<div class="container dash-container main-body" >
<hr>
The following image shows the web page after the popup disappears. Note, clicking anywhere in the web page does not yield any response.

Categories

Resources