Div slider doesn't work - Javascript - javascript

I recently created a simple image slider here: http://americanbitcoinacademy.com/test2/
Which has basically a next and prev buttons and slides the image. You can check the codes of that here: https://jsfiddle.net/mmytscuz/
And now I am trying to apply these codes to my new element but this time instead of images I am trying to apply it using div elements.
You can check my current progress work here: https://jsfiddle.net/7808uLpv/
So basically when you click the next button it must slide up on the next list item element. For some reason it won't hide the other elements now also it doesn't slide either.
So far here's how I layout my elements:
<ul class="slider">
<li>
<div class="box center">
<h1>What is your name?</h1>
<input type="text" name="name" placeholder="Your Name.."/>
<div id="slider-nav">
<button data-dir="next" >Next »</button>
</div>
</div>
</li>
<li>
<div class="box center">
<h1>How much money do you have?</h1>
<input type="text" name="money" placeholder="Your Money.."/>
<div id="slider-nav">
<button data-dir="next" >Next »</button>
</div>
</div>
</li>
<li>
<div class="box center">
<h1>Your Birthday?</h1>
<input type="text" name="bday" placeholder="Your Birthday.."/>
<div id="slider-nav">
<button data-dir="next" >Next »</button>
</div>
</div>
</li>
</ul>
And here's my javascript:
(function() {
var container = $('div.slider').css('overflow', 'hidden').children('ul'),
slider = new Slider( container, $('#slider-nav') );
slider.nav.find('button').on('click', function() {
slider.setCurrent( $(this).data('dir') );
slider.transition();
});
})();
function Slider( container, nav ) {
this.container = container;
this.nav = nav.show();
this.imgs = this.container.find('img');
this.imgWidth = this.imgs[0].width; // 600
this.imgsLen = this.imgs.length;
this.current = 0;
}
Slider.prototype.transition = function( coords ) {
this.container.animate({
'margin-left': coords || -( this.current * this.imgWidth )
});
};
Slider.prototype.setCurrent = function( dir ) {
var pos = this.current;
pos += ( ~~( dir === 'next' ) || -1 );
this.current = ( pos < 0 ) ? this.imgsLen - 1 : pos % this.imgsLen;
return pos;
};
Any idea what am I doing wrong when I click the 'NEXT' button why the elements are not sliding as well why are they all showing up at once?

There's a lot wrong with your fiddle.
No jQuery loaded.
No div.slider that you refer to for plugin initialization.
You use id slider-nav like a class. Id must be unique.
In css li.slider needs to be .slider li
You're looking for images within js but there are none in the markup.
Consequently, your plugin is throwing errors, trying to detect width of these images that don't exist: this.imgs[0].width;
Imo, just start over, get a solid html and css base and only then try to write the js plugin.

Just add jQuery because without not working.See the Demo here
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>

Related

jQuery: Slider detect scrollDown or scrollUp

I have a script which will make a simple slider with buttons to navigate.
Now I need to make this slider controllable with scrolling.
When user scroll down will be moved to the next slider also reverse.
Buttons will be available too. So there will be 2 options on how to control it. With buttons next and back also with scrolling down or up.
Is there any option of how to do it in the easiest way?
var lottieone = document.getElementById('lottieone');
var lottietwo = document.getElementById('lottietwo');
var lottiethree = document.getElementById('lottiethree');
var lottiefour = document.getElementById('lottiefour');
$('#lottieone').show();
$('#lottietwo').hide();
$('#lottiethree').hide();
$('#lottiefour').hide();
function missionsSlide() {
$('#lottieone').hide();
$('#lottietwo').show();
$('#lottiethree').hide();
$('#lottiefour').hide();
}
function missionsSlideBacc() {
$('#lottieone').hide();
$('#lottietwo').show();
$('#lottiethree').hide();
$('#lottiefour').hide();
}
function researchSlide() {
$('#lottieone').hide();
$('#lottietwo').hide();
$('#lottiethree').show();
$('#lottiefour').hide();
}
function educationSlide() {
$('#lottieone').hide();
$('#lottietwo').hide();
$('#lottiethree').hide();
$('#lottiefour').show();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="slider">
<div id="lottieone" class="lottieSlide">
<div class="content">
<button onclick="missionsSlide()">HOME</button>
</div>
</div>
<div id="lottietwo" class="lottieSlide mainSliders">
<div class="content">
<h1>MISSIONS</h1>
<button onclick="researchSlide()">Next</button>
</div>
</div>
<div id="lottiethree" class="lottieSlide mainSliders">
<div class="content">
<h1>RESEARCH</h1>
<button onclick="missionsSlideBacc()">Back</button>
<button onclick="educationSlide()">Next</button>
</div>
</div>
<div id="lottiefour" class="lottieSlide mainSliders">
<div class="content">
<h1>EDUCATION</h1>
<button onclick="researchSlide()">Back</button>
</div>
</div>
</section>
Try using this snippet.
$(document).on('mousewheel', '.slider', function (e) {
var delta = e.originalEvent.wheelDelta;
if (delta > 0) alert("scrolled Up");
if (delta < 0) alert("scrolled Down");
e.preventDefault();
});
This is highly repeated question, so you might find multiple solution for it as well

Angular 4 scroll a div a certain amount

I have a div whose height is given and it has overflow-y: auto, so when necessary it has a scrollbar.
Now I want to be able to scroll that div a certain amount on an event. So far I've been able to scrollIntoView(false) which just scrolls it to the bottom. I want to scroll it almost, but not quite to the bottom. I do not want to scroll the window, as this div is position: fixed relative to the window.
From what I've seen this is technically possible, but people keep referring to various plugins. Right now a plugin is not an option (maybe for some future release, but not now).
<form novalidate #searchFilterForm [formGroup]="filterForm" role="application">
<section id="searchFilters" role="form">
<div class="search-filter-tab" #searchFilterTab>
..
</div>
<div #searchFormContainer class="search-filter-container" >
<div class="search-filter-header">
...
</div>
<fieldset class="search-filter-checkboxes search-mobile-small" >
...
</fieldset>
<fieldset class="search-filter-sliders search-mobile-small" >
...
</div>
</fieldset>
<fieldset class="search-filter-dropdowns search-mobile-small" >
...
</fieldset>
<fieldset >
<span #scrollToHere></span>
<div class="search-filter-text-input-container search-mobile-small" *ngFor="let textItem of searchBoxList; trackBy: trackByFunc; let i = index;">
<app-auto-complete
#autoCompleteBoxes
...
(showToggled)="scrollToEndOfFilter($event)"
>
<input
type="text"
autocomplete="off"
[attr.name]="textItem.apiName"
[placeholder]="textItem.label"
[attr.aria-label]="textItem.label"
class="search-filter-text-input"
>
</app-auto-complete>
</div>
</fieldset>
</div>
</section>
</form>
Typescript:
scrollToEndOfFilter(ev){ //ev == {shown: true/false, ref: ElementRef}
if (ev == null || (ev.shown == true && ev.ref)){
this.searchFormContainer.nativeElement.scrollTop = 950;
}
}
How about standard approach:
Fist you assign a reference to your div like this:
<div #divToScroll></div>
then, you get a reference to your div:
#ViewChild('divToScroll') divToScroll: ElementRef;
and finally when you need to scroll you just call:
divToScroll.nativeElement.scrollTop = 30;
It becomes tedious when we need to scroll elements( let say a particular div inside *ngFor)
best way is to get the current position and height of element using :
dynamically assign id to each div [attr.id]=" 'section' + data.id"
<div id="parentDiv" #parentDiv>
<div *ngFor="let data of content" [attr.id]=" 'section' + data.id">
<p>section {{data.id}}</p>
<botton (click)="scrollMyDiv(data)"></button>
</div>
</div>
and in .ts
scrollMyDiv(item) {
let section = 'section' + item.id);
window.scroll(0, 0); // reset window to top
const elem = document.querySelector('#' + section);
let offsetTop = elem.getBoundingClientRect().top` - x;
window.scroll(0, offsetTop);
}`
getBoundingClientRect().top will give height from top. x is any constant value like the height of your header section.
its mostly used to provide scrollspy like feature.

Using datepicker with jquery, dialog box associated with div onselect

Not sure if this is possible, I'm just starting to learn javascript and jQuery. If the way that I would like is not possible, I am very open to hearing of different ways I may be able to achieve this.
I want to display a datepicker, the user will click on dates and when they do a dialog box appears which has specific predefined data in it. They can select a different date, and it will open another dialog box with different predefined data in it, and I want to keep track of the dates that they click on.
<div id="tabs">
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
<div id="tabs-1">
<p>I'm going to have different data applying to only this day</p>
</div>
<div id="tabs-2">
<p>I'm going to have different data applying to only this day</p>
</div>
<div id="tabs-3">
<p>I'm going to have different data applying to only this day</p>
</div>
</div>
Open jQuery dialog box upon selecting a date from jQuery datepicker inline
That link was useful because a user has a jsfiddle posted: http://jsfiddle.net/qqabC/ which is a start to what I am trying to do, I am just not sure of how or if it is even possible to incorporate divs into the dialog boxes like so. I keep messing around with it but I have been getting nowhere. Each date that is selected will have different dialog box content in it.
If this is not possible, what would be the best way to achieve this? Thank you.
--Edit:
I still need to implement the divs that I have defined above with div id "tabs". Tabs = workout days. So tabs-1 to tabs-5 would be 5 total days. tabs-1 is going to be their first click which is day 1 form content, tabs-2 will be their second click which is day 2 form content, and so on. I believe I should use a for loop, because which each click the div is being incremented onto the next one. I was trying to do something like:
var divs = $('#tabs > div[id]');
var links = $('#tabs li');
divs.hide();
for (i=0;i<=max_workouts;i++) {
$('#tabs li').on('click', function(e){
var clickedID = $(this).attr('href').clone().appendTo(#workout-modal);
}
Something like that, to iterate through the div's with each click, but it's not working, I have been trying to find examples of placing existing div content in modals but there is nothing on iterating through divs in this way, do you have any suggestions?
Here is an example of how you could achieve this functionality using Bootstrap. Of course you'll need to change the functionality and design as needed but this should be a fair start
The workflow is as follows:
User clicks a date
Modal is displayed with various inputs
Inputs are cleared when modal opens
User enters info in the inputs
User clicks add workout
A span label is added to the display showing the workout number and the date selected
This span has data attributes set to store the date, title, and each of the values from the modal inputs
If user clicks the "X" on the right end of the span, it is removed
If user clicks the span label anywhere else it reopens the modal and populates the inputs with the data stored as attributes on the span
If the user clicks add workout after loading an existing one, the new span replaces the old one instead of adding to the end of the div
Here is a jsFiddle also
$(function(){
var max_workouts = 5;
$('#workout-datepicker').datepicker({
startDate: "today"
}).on('changeDate', function(e) {
var cur = $('.workout-label').length;
if (cur < max_workouts) {
var workoutDate = e.format('mm/dd/yyyy');
var title = 'Workout ' + (cur + 1) + ' - ' + workoutDate;
openModal(title, workoutDate);
}
else{
var $tooMany=$('#too-many');
$tooMany.show();
setTimeout(function(){ $tooMany.hide() }, 2000);
}
});
var $workoutLabelsContainer = $('#workout-labels-container');
$('#add-workout').click(function() {
var $workoutModal = $('#workout-modal');
var workoutDate = $workoutModal.data('workout-date');
var title = $workoutModal.data('workout-title');
var vaule1 = $('#modal-workout-value-1').val();
var vaule2 = $('#modal-workout-value-2').val();
var $workout = $('<span class="label label-primary workout-label col-sm-12">' + title + '<span class="glyphicon glyphicon-remove pull-right remove-workout" aria-hidden="true"></span></span>');
var clickedLabelIndex = $workoutModal.data('crurent-label-index');
$workout.data('workout-title', title).data('workout-date', workoutDate).data('value-1', vaule1).data('value-2', vaule2);
if (clickedLabelIndex == -1) $workoutLabelsContainer.append($workout);
else($('.workout-label').eq(clickedLabelIndex).replaceWith($workout))
$workoutModal.modal('hide');
});
$workoutLabelsContainer.on('click', '.remove-workout', function(e) {
e.stopPropagation();
$(this).closest('.workout-label').remove();
})
$workoutLabelsContainer.on('click', '.workout-label', function() {
var $workoutLabel = $(this);
var workoutDate = $workoutLabel.data('workout-date');
var title = $workoutLabel.data('workout-title');
var value1 = $workoutLabel.data('value-1');
var value2 = $workoutLabel.data('value-2');
var labelIndex = $('.workout-label').index($workoutLabel);
openModal(title, workoutDate, value1, value2, labelIndex);
});
function openModal(title, workoutDate, value1, value2, labelIndex) {
var $workoutModal = $('#workout-modal');
var $value1 = $('#modal-workout-value-1').val('');
var $value2 = $('#modal-workout-value-2').val('');
$workoutModal.data('workout-title', title).data('workout-date', workoutDate);
$('#workout-modal-title').html(title);
if (value1) $value1.val(value1);
if (value2) $value2.val(value2);
if (labelIndex !== 'undefined' && labelIndex > -1) $workoutModal.data('crurent-label-index', labelIndex);
else $workoutModal.data('crurent-label-index', -1);
$workoutModal.modal({
show: true
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.5.1/js/bootstrap-datepicker.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.5.1/css/bootstrap-datepicker.min.css" rel="stylesheet"/>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<style>
.workout-label {
padding: 6px;
font-size: 16px;
width: 100%;
display: block;
margin-bottom: 5px;
cursor: pointer;
}
.remove-workout {
cursor: pointer;
}
#too-many{
display:none;
}
</style>
<br>
<br>
<div class="container well" id="workout-container">
<div class="row">
<div class="col-xs-6">
<div id="workout-datepicker"></div>
</div>
<div class="col-xs-6" id="workout-labels-container">
</div>
</div>
<div class="alert alert-danger" id="too-many" role="alert">Maximun reached</div>
</div>
<div id="workout-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="workout-modal-title"></h3>
</div>
<div class="modal-body">
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="firstname" class="col-sm-4 control-label">Some short text:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="modal-workout-value-1" placeholder="">
</div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-4 control-label">Some longer text:</label>
<div class="col-sm-8">
<textarea class="form-control" id="modal-workout-value-2" name="textarea"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
<button type="button" class="btn btn-primary" id="add-workout">Add workout</button>
</div>
</form>
</div>
</div>
</div>

Convert values in form box

I'm a bit confused on how this works. I am trying to have the seconds value convereted to a "hh:mm:ss" in the input box when the slider is active.
Here the div displays the start time and end time in seconds. And adjusts as they slide
<div class='slider-example col-xs-12 col-sm-6 col-lg-5 center-block'>
<div class="well">
<input id="ex2" type="text" class="span2" value="[{{ start_length }},{{ end_length }}]" data-slider-min="{{ start_length }}" data-slider-max="{{ end_length }}" data-slider-step="1" data-slider-value="[{{ start_length }},{{ end_length }}]" data-slider-selection="after" data-slider-tooltip="hide"/>
</div> <!-- /well -->
</div> <!-- /slider example -->
<div class = "container col-xs-12 col-sm-6 col-lg-5 center-block">
<form class="form-inline">
<div class = "container col-xs-4">
<div class="form-group">
<label for="bar">Start:</label>
<input type="text" class="form-control" id="bar">
</div>
</div>
<div class = "container col-xs-4 pull-right">
<div class="form-group">
<label for="bar1">End: </label>
<input type="text" class="form-control" id="bar1">
</div>
</div>
</form>
</div>
Here is my javascript
<script type='text/javascript' src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script type='text/javascript' src="{{url_for('static', filename='js/bootstrap-slider.js')}}"></script>
<script type='text/javascript'>
function secondsTimeSpanToHMS(s) {
var h = Math.floor(s/3600);
s -= h*3600;
var m = Math.floor(s/60);
s -= m*60;
return h+":"+(m < 10 ? '0'+m : m)+":"+(s < 10 ? '0'+s : s);
}
$(document).ready(function(){
/* Example 2 */
$("#ex2").slider({});
$("#ex2").on('slide', function (ev) {
$('#bar').val(ev.value.slice(",")[0]);
$('#bar1').val(ev.value.slice(",")[1]);
document.getElementById('#bar').innerHTML = secondsTimeSpanToHMS('#bar');
document.getElementById('#bar1').innerHTML = secondsTimeSpanToHMS('#bar1');
});
});
</script>
I doubt it's doing what you intended, but here's what it's trying to do
$("#ex2").on('slide', function (ev) {
The slide event triggers when you slide the range handles and returns a 2 element array with the value of each handle
$('#bar').val(ev.value.slice(",")[0]);
$('#bar1').val(ev.value.slice(",")[1]);
This is an attempt to set the value of the element with id bar and bar1 to the range handle values - this will work if bar and bar1 are form elements (like a textbox, textarea...)
document.getElementById('#bar').innerHTML = ...
document.getElementById('#bar1').innerHTML = ...
This attempts to set the innerHTML of elements with id #bar and #bar1 - however since you are using document.getElementById, you should be using bar and bar1 instead of prefixing it with # (like you'd do for jQuery).
... = secondsTimeSpanToHMS('#bar');
... = secondsTimeSpanToHMS('#bar1');
I'd assume the above is an attempt to run the function using the range handle values, but the code is wrongly passing in jQuery selectors to these function - the function expects a value in seconds.
Finally, the secondsTimeSpanToHMS takes a seconds value and converts it to hour:minute:seconds
The below may be a bit closer to what you are looking for
$(document).ready(function () {
/* Example 2 */
$("#ex2").slider({});
$("#ex2").on('slide', function (ev) {
$('#bar').val(secondsTimeSpanToHMS(ev.value.slice(",")[0]));
$('#bar1').val(secondsTimeSpanToHMS(ev.value.slice(",")[1]));
});
});
Or alternatively, you could set another 2 element's innerHTML to the output of secondsTimeSpanToHMS and retain the .val() lines from the original function.

The slideshow and the zoom function is not working anymore of fetching content

I have an images slideshow which each images can bee zoomed in the slideshow. And all the codes I used was working fine before I added some change there.
Here is the working code:
<div id="leftBigWraper"><!-- Example -->
<div id="bigPicture">
<div class="easyzoom easyzoom--overlay">
<p></p>
<img src="colour/big/Evan-Picone-Turtleneck-Sweater-Dress__01688224_balired_1.jpg" alt="" width="100%"/></div>
<div class="easyzoom easyzoom--overlay">
<p></p>
<img src="colour/big/Evan-Picone-Turtleneck-Sweater-Dress__01688224_balired_2.jpg" alt="" width="100%"/></div>
</div>
<div id="smallPicture">
<img src="colour/thumnail/Evan-Picone-Turtleneck-Sweater-Dress__01688224_balired_1.jpg" width="100%">
<img src="colour/thumnail/Evan-Picone-Turtleneck-Sweater-Dress__01688224_balired_2.jpg" width="100%">
</div>
</div><!-- End of Example -->
<!--End of Wraper in the Left Side (Product Images)-->
In the working code, all the content in the #bigPicture div is set maually, and the slideshow is run by this script:
var $el = $('#leftBigWraper'),
// SETUP ////////
F = 600 , // Fade Time
P = 5000 , // Pause Time
C = 0 , // Counter / Start Slide# (0 based)
///////////////////
$sl = $('#bigPicture > div'),
$th = $('#smallPicture > img'),
N = $sl.length,
T = 10000;
$sl.hide().eq(C).show();
$th.eq(C).addClass('on');
// ANIMATION
function anim() {
$sl.eq(C%N).stop(1).fadeTo(F,1).siblings().fadeTo(F,0);
$th.removeClass('on').eq(C%N).addClass('on');
}
// AUTO ANIMATE
function autoAnim() {
T = setTimeout(function() {
C++;
anim(); // Animate
autoAnim(); // Prepare another iteration
}, P+F);
}
autoAnim(); // Start loop
// HOVER PAUSE
$el.hover(function(e) {
return e.type==='mouseenter'? clearTimeout( T ) : autoAnim();
});
// HOVER THUMBNAILS
$th.on('mouseenter', function() {
C = $th.index( this );
anim();
});
THE WORKING FIDDLE
However, when all the contents in the #bigPicture div are set by calling it from hidden div and with Jquery, the slideshow and the zooming function is not working anymore.
The Jquery that I used to fill the blank div from the hidden div is here:
$(document).ready(function(){
$('#bigPicture').html($('#pilihWarna li #bigHidden:first').html());
$('#smallPicture').html($('#pilihWarna li #smallHidden:first').html());
$('#pilihWarna li').click(function(event) {
$('#bigPicture').html($(this).find('#bigHidden').html());
$('#smallPicture').html($(this).find('#smallHidden').html());
});
});
As follows:
First, I left the div of #bigPicture to be blank or without any content in there.
<!--Wraper in the Left Side (Product Images)-->
<div id="leftBigWraper"><!-- Example -->
<div id="bigPicture"></div>
<div id="smallPicture"></div>
</div><!-- End of Example -->
<!--End of Wraper in the Left Side (Product Images)-->
Then, I create some hidden div that will transfer all the contents insede the div to the #bigPicture div.
<ul id="pilihWarna" style="">
<li><img src="colour/thumnail/Evan-Picone-Turtleneck-Sweater-Dress__01688224_balired_1_7.jpg" width="10%">
<div id="bigHidden">
<div class="easyzoom easyzoom--overlay">
<p></p>
<img src="colour/big/Evan-Picone-Turtleneck-Sweater-Dress__01688224_balired_1.jpg"></div>
<div class="easyzoom easyzoom--overlay">
<p></p>
<img src="colour/big/Evan-Picone-Turtleneck-Sweater-Dress__01688224_balired_2.jpg"></div>
</div>
<div id="smallHidden">
<img src="colour/thumnail/Evan-Picone-Turtleneck-Sweater-Dress__01688224_balired_1.jpg">
<img src="colour/thumnail/Evan-Picone-Turtleneck-Sweater-Dress__01688224_balired_2.jpg">
</div>
</li>
The ul which its id is #pilihanWarna has at least 5 li, which I used as clickable menus that I have been discussing here
That's when the slidshow and the zooming images functions are not working anymore.
You're using the same IDs multiple times, IDs should be unique. Given multiple elements with the same ID:
<div id="foo">One</div>
<div id="foo">Two</div>
<div id="foo">Three</div>
Searching the DOM for the elements will only ever return the first instance:
document.getElementById('foo'); // returns <div id="foo">One</div>
Start by removing the duplicated IDs and using a different selector (a class probably, but you could just use an element selector too) and then you might be getting somewhere.

Categories