How can I assing a navigation link to multiple sections in fullpage.js - fullpage.js

I'm using a multi-sectioned website in fullpage.js. Some of the sections should be available only through scrolling, but not through a navigation link. For example, in the first section, you should get to a second part of that section by scrolling (once), but the navigation will still show the first element as active. If you click on the second link in the navigation, you get to the second real section, which would be the third, if you consider the first two seperate. When I assign two sections the same anchor in the initialization, scrolling between the two stops working. If I try to assign multiple values for data-menuanchor in the navigation, it doesn't work either.

The best way to do it would be to create your own navigation element and not the one provided by fullpage.js.
This way you'll have total control over it.
By using the fullpage.js method moveTo you can activate or desactivate elements in your menu by adding or removing a class and you can do that using a callback such as afterLoad or onLeave.
Demo online
Having the following HTML menu:
<div id="myMenu">
<span id="element1">Section 1</span>
<span id="element2">Section 2</span>
<span id="element3">Section 3</span>
</div>
You can use this:
$('#fullpage').fullpage({
sectionsColor: ['yellow', 'orange', '#C0C0C0', '#ADD8E6'],
afterLoad: function(anchorLink, index){
var activeElement;
if(index === 1){
activeElement = $('#element1');
}
else if(index === 2 || index ===3){
activeElement = $('#element2');
}else if( index === 4){
activeElement = $('#element3');
}
activeElement.addClass('active').siblings().removeClass('active');
}
});

Related

On sorting a jsp <select> element items vanishes

I have two listbox in a .jsp page with Add(+) and Remove(-) buttons in between. Two list boxes are 'Available Items' (left) and 'Selected Items'(right). 'Available Items' list box displays all the available items on page load fetching from DB, and 'Selected Items' listbox displays blank. User can add one item from left to right in 'Selected Items' listbox.
I have written code to move the items from both sides and vice versa. But the problem is when I am clicking 'Add' button to move the item from left to right, the item is moved properly to right listbox but the left list ('Available Items') items are getting vanished and reappears only after doing a click event the listbox which is weird from UI devlpment perspective. The same is happening for Remove button click. I hope there is some refresh issue underline. I am posting the codes below.
N.B : I have written a sort method to sort the items in the listbox. I troubleshooted that if I close calling the method sortItemsList() then everything is working fine.
Code for the listbox :
<tr>
<td>
<select id="leftItemList" size="8" multiple="multiple" style="height:auto"></select>
<input type="button" name="moveItemsToLeft" id="buttonAddItems" class="selectBoxAddButton checkboxDependent" value="Add >>" />
<input type="button" id="buttonRemoveItems" class="selectBoxRemoveButton checkboxDependent" value="<< Remove" />
<select id="rightItemList" size="8" multiple="multiple" style="height:auto"></select>
</td>
</tr>
Corresponding code for sort in javascript that is causing the issue :
Code for adding and removing items:
$('#buttonAddItems').click(function(){ //Moving items from left to right
var elementFrom = document.getElementById('leftItemList');
var element = document.getElementById('rightItemList');
var len = element.options.length;
var elementFromLength = elementFrom.length;
for ( var i = (elementFromLength - 1); i >= 0; i--) {
if ((elementFrom.options[i] != null) && (elementFrom.options[i].selected == true)) {
var selectedItemLength = $("#leftItemList :selected").length;
element.options[len] = new Option(
elementFrom.options[i].text,
elementFrom.options[i].value);
len++;
elementFrom.options[i] = null;
}
}
sortItemsList(); //Commenting this call fixes the problem
});
$('#buttonRemoveItems').click(function(){ //Moving items from right to left
var element = document.getElementById('rightItemList');
var elementTo = document.getElementById('leftItemList');
var len = element.options.length;
var elementFromLength = elementTo.length;
for ( var i = (len - 1); i >= 0; i--) {
if ((element.options[i] != null) && (element.options[i].selected == true)) {
elementTo.options[elementFromLength] = new Option(
element.options[i].text,
element.options[i].value);
elementFromLength++;
element.options[i] = null;
}
}
sortItemsList(); //Commenting this call fixes the problem
});
function sortItemsList(){
var options = $("#leftItemList option"); // Collect options
options.detach().sort(function(a,b) { // Detach from select, then Sort
var at = $(a).text();
var bt = $(b).text();
return (at > bt)?1:((at < bt)?-1:0); // Tell the sort function how to order
});
options.appendTo("#leftItemList");
}
N.B : The code for sorting that I used is taken from reference whose URL is below. Have tried both Approaches. None of them is working. I do have same '3.4.1/jquery.min.js' as in reference -
https://www.geeksforgeeks.org/how-to-sort-option-elements-alphabetically-using-jquery/
#Swati I am having the same problem running your code in jsfiddle (which you are running successfully). So the problem is with Chrome version. My chrome version is 'Version 81.0.4044.113 (Official Build) (64-bit)'. I guess yours is 'Chrome version 80.0.3987.122' one version older than me with which it is working fine. Finally the observations are as below.
Observations
In the higher chrome version, the code is working fine till sorting. But when the code is trying to append the sorted itemList into existing itemList object, there was some issues with DOM manipulation with latest chrome version against appendTo() method, which means appendTo() method is adding sorted itemList into existing DOM element but refresh or reload is not happening with that DOM element. That's why the vanished itemList drop down is getting all the values after a mouse click event on the drop down manually.
In order to fix this issue, we need to do manual refresh. We can do the refresh or reload by two different ways as mentioned below.
Approach 1 :
Adding the below line after itemList append.
$("#leftItemList").html($("#leftItemList").html());
Approach 2 :
We can set the focus on leftItemList element after append. If we follow this approach, when we click Add button it will add the item list to right side but the focus will be there is the leftItemList drop down.
$("#leftItemList").focus();
So Approach 1 is the preferable solution.

Prevent scrolling from section, but allow anchor navigation in Fullpage.js

My first fullpage.js section is scrollable (scrollOverflow: true), and I don't want a jump to the second section when reaching the bottom of the first section.
As such, I set up the following callback:
onLeave: function(origin, destination, direction) {
if (origin.index === 0) {
return false;
}
}
The problem is, this also prevents regular anchor links (such as <a href="#section2">) to work: navigation is also blocked by the callback.
This is annoying as my first page has links to the other sections.
Is there a way to prevent onLeave only when it is due to a scroll, but still allow anchor navigation?
The callback parameters do not seem to have a way to distinguish a scroll from an anchor click.
Is there a way to prevent onLeave only when it is due to a scroll, but still allow anchor navigation?
Sure!
You can use the method fullpage_api.setAllowScrolling(false) when reaching that section with scrollOverflow.
Then set it back to true in any other section:
new fullpage('#fullpage', {
sectionsColor: ['yellow', 'green', 'purple', 'orange'],
navigation: true,
onLeave: function(origin, destination, direction) {
//assuming section 2 is the one with scrollOverflow
fullpage_api.setAllowScrolling(destination.index !== 1);
}
});
Reproduction online:
https://jsfiddle.net/alvarotrigo/zx05cfr9/1/

full page scrolling issue on touch device after autoscrolling set to false

I've total four 4 sections and a footer.
Section one, two , three are normal sections.
On section four I need normal scrolling as its height is more than window height.
Below code works fine with keyboard scrolling and mouse scrolling.
But On mobile I've issue while scrolling upward.
Please open the link on a touch device too see the issue.
Js fiddle here
<div id="fullpage">
<div class="section">One</div>
<div class="section">Two</div>
<div id="three" class="section">Three</div>
<div id="four" class="section fp-normal-height fp-normal-scroll">
<div style="height:1000px;">Four</div>
</div>
</div>
<footer style="height:300px;">Site footer</footer>
$('#fullpage').fullpage({
sectionsColor: ['yellow', 'orange', '#C0C0C0', '#ADD8E6'],
hybrid:true,
fitToSection: false,
afterLoad: function(anchorLink, index){
var loadedSection = $(this);
if(loadedSection.attr("id") == "four") {
$.fn.fullpage.setAutoScrolling(false);
}
if(loadedSection.attr("id") == "three") {
$.fn.fullpage.setAutoScrolling(true);
}
},
});
when we swipe upward from section 4 (as at this point Autoscrolling has been set to false) the swipe takes user directly to first section.
I think The reason Its happening because, when user swipes, the page gets scrolled to the top as normal scrolling has been triggered. If I do console log I can see autoscrolling is being set back to true when it passes section 3 but still page scrolls till top as swipe has triggered the scrolling when auto scrolling was false .
if you open below link on mobile you will see the issue above described. Works fine for keyboard.
Expect issues.
The hybrid option is not documented which means is might not work as expected in all possible scenarios.

How to load a div after the line break on click event?

I'm creating under Wordpress a single page portfolio. Each gallery thumbnail is a list item.
When you click an item, it loads a sliding drawer (#DrawerContainer) pulling the content from the post with ajax.
I want this drawer to appear on the line after the clicked item.
Since it's a fluid layout, I don't know if the browser is displaying 1,2,3,4 or 5 items in a row.
I tried to append my drawer to every <li> but I'm afraid if I click a thumbnail,
the slider will open and make the other thumbnails jump to the next line.
So I thought the best way to prevent layout problems is to call the drawer only after a line break.
How can I target the last li item in the row, and load a div after the line break of this row?
If I'm not clear, here is the code I'd like to see rendered
EDIT: I just added the code to jsfiddle if you want to put your hands on it. http://jsfiddle.net/F6MvZ/10/
<ul id="portfolio-list">
<li>item1</li>
<li>item2</li>
<li>item3</li> //end of first row (br/)
<li>item4</li> //if I click this item
<li>item5</li>
<li>item6</li> //end of second row (br/)
<div id="DrawerContainer"></div> // the content of item4 appears here
<li>item7</li> //end of third row
</ul>
and here is the code I'm struggling with
$(document).ready(function(){
$.ajaxSetup({cache:false});
$(".ProjectWrap,.mosaic-overlay,.mosaic-backdrop").click(function(){
var post_link = $(this).attr("href");
//$('#DrawerContainer').slideToggle(500);
$("#DrawerContainer").html("loading...");
$("#DrawerContainer").load(post_link + " #container > * ");
return false;
});
//Here is the part I'm stuck with now
$(#portfolio-list).click(function(){
$("<br/>").append('<section id="DrawerContainer"></section>');
});
//I assume the #DrawerContainer will generate a br/
});
Looking for something like this?
http://jsfiddle.net/RF6df/1/
Its an extension of what I originally wrote. Hope this helps.

jQuery .on() event doesn't work for dynamically added element

I'm making a project where a whole div with buttons is being inserted dynamically when user click a button, and inside that div there's a button, which when the user click on it, it does something else, like alerting something for example.
The problem is when i press on that button in the dynamically added div, nothing happens. The event doesn't fire at all.
I tried to add that div inside the HTML and try again, the event worked. So i guess it's because the div is dynamically added.
The added div has a class mainTaskWrapper, and the button has a class checkButton.
The event is attached using .on() at the end of script.js file below.
Here's my code :
helper_main_task.js : (that's the object that adds the div, you don't have to read it, as i think it's all about that div being dynamically added, but i'll put it in case you needed to)
var MainUtil = {
tasksArr : [],
catArr : ["all"],
add : function(){
var MTLabel = $("#mainTaskInput").val(), //task label
MTCategory = $("#mainCatInput").val(), //task category
MTPriority = $("#prioritySlider").slider("value"), //task priority
MTContents = $('<div class="wholeTask">\
<div class="mainTaskWrapper clearfix">\
<div class="mainMarker"></div>\
<label class="mainTaskLabel"></label>\
<div class="holder"></div>\
<div class="subTrigger"></div>\
<div class="checkButton"></div>\
<div class="optTrigger"></div>\
<div class="addSubButton"></div>\
<div class="mainOptions">\
<ul>\
<li id="mainInfo">Details</li>\
<li id="mainEdit">Edit</li>\
<li id="mainDelete">Delete</li>\
</ul>\
</div>\
</div>\
</div>');
this.tasksArr.push(MTLabel);
//setting label
MTContents.find(".mainTaskLabel").text(MTLabel);
//setting category
if(MTCategory == ""){
MTCategory = "uncategorized";
}
MTContents.attr('data-cat', MTCategory);
if(this.catArr.indexOf(MTCategory) == -1){
this.catArr.push(MTCategory);
$("#categories ul").append("<li>" + MTCategory +"</li>");
}
$("#mainCatInput").autocomplete("option", "source",this.catArr);
//setting priority marker color
if(MTPriority == 2){
MTContents.find(".mainMarker").css("background-color", "red");
} else if(MTPriority == 1){
MTContents.find(".mainMarker").css("background-color", "black");
} else if(MTPriority == 0){
MTContents.find(".mainMarker").css("background-color", "blue");
}
MTContents.hide();
$("#tasksWrapper").prepend(MTContents);
MTContents.slideDown(100);
$("#tasksWrapper").sortable({
axis: "y",
scroll: "true",
scrollSpeed : 10,
scrollSensitivity: 10,
handle: $(".holder")
});
}
};
script.js : (the file where the .on() function resides at the bottom)
$(function(){
$("#addMain, #mainCatInput").on('click keypress', function(evt){
if(evt.type == "click" || evt.type =="keypress"){
if((evt.type =="click" && evt.target.id == "addMain") ||
(evt.which == 13 && evt.target.id=="mainCatInput")){
MainUtil.add();
}
}
});
//Here's the event i'm talking about :
$("div.mainTaskWrapper").on('click', '.checkButton' , function(){
alert("test text");
});
});
It does not look like div.mainTaskWrapper exist.
From the documentation (yes, it is actually bold):
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page.
[...]
By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers.
You might want to bind it to #tasksWrapper instead:
$("#tasksWrapper").on('click', '.checkButton' , function(){
alert("test text");
});
You need to specify a selector with on (as a parameter) to make it behave like the old delegate method. If you don't do that, the event will only be linked to the elements that currenly match div.mainTaskWrapper (which do not exists yet). You need to either re-assign the event after you added the new elements, or add the event to an element that already exists, like #tasksWrapper or the document itself.
See 'Direct and delegate events' on this page.
I know this is an old post but might be useful for anyone else who comes across...
You could try:
jQuery('body')on.('DOMNodeInserted', '#yourdynamicallyaddeddiv', function () {
//Your button click event
});
Here's a quick example - https://jsfiddle.net/8b0e2auu/

Resources