unwrap list items in jquery based on controller value - javascript

I have two side menus. Each menu has subitems as list items under unordered list, like
- FIRST MENU
- Link one
- Link two
- SECOND MENU
- Link three
- Link four
When page loads I want to open one menu and other menu list items should stayed unwrapped
like
- FIRST MENU
- Link one
- Link two
- SECOND MENU
I have working example with FIRST MENU unwrapped here but I do need example with unwrapped SECOND MENU so I can change it to dynamic value sent from my controller.
var unwrapped_menu = $data_sent_from_controller;
if data_sent_from_controller == "SECOND MENU"
then unwrapped second menu.
Changed this example here to hardcoded SECOND MENU unwrapped would be perfect. Nothing more.
If you need more info please ask.

If the dynamic value sent from the controller is the index (starting from 0) of the menu to be opened then:
JSFIDDLE
dynamic_value_from_controller = 1;
$(document).ready(function() {
$.easing.def = "easeOutBounce";
var menus = $( 'div.menu ul li.submenu' ),
current_submenu = null;
menus.next().hide();
menus.each( function(i){
var dropdown = $( this ).next(),
title = $( 'a.title', this );
title.click( function(e){
if ( current_submenu !== null && current_submenu != dropdown )
{
current_submenu.slideUp( 'slow' );
}
current_submenu = dropdown;
dropdown.stop(false, true).slideToggle('slow');
e.preventDefault();
} );
if ( i == dynamic_value_from_controller )
title.click();
});
});
If the dynamic value is the text of the title then:
JSFIDDLE
dynamic_value_from_controller = 'SECOND MENU';
$(document).ready(function() {
$.easing.def = "easeOutBounce";
var menus = $( 'div.menu ul li.submenu' ),
current_submenu = null;
menus.next().hide();
menus.each( function(i){
var dropdown = $( this ).next(),
title = $( 'a.title', this );
title.click( function(e){
if ( current_submenu !== null && current_submenu != dropdown )
{
current_submenu.slideUp( 'slow' );
}
current_submenu = dropdown;
dropdown.stop(false, true).slideToggle('slow');
e.preventDefault();
} );
if ( title.text() == dynamic_value_from_controller )
title.click();
});
});

Have your controller output something on the submenu that you want to open, e.g. a data attribute, or a class name. Then your JS can trigger the submenu that has said attribute or class name to open.
Your list item that you want to open should look something like this:
<li id="second_menu" class="submenu" data-open-on-load="true">
... then in your js, instead of if( i==0 ) you can do something like this:
if ( $(this).attr("data-open-on-load") )
title.click();
See example: http://jsfiddle.net/cWXm5/13/
Note that you'll need to have your controller output this on the first submenu when no others will be set to open, or none will open.

Related

JS Toggle Submenu within Mega Menu

The issue I'm having is, creating a submenu inside another menu.
Demo: LIVE DEMO (Important, cause CSS is needed as well
$(function () {
// Desktop Menu
var categoriesMenu = $(".list-ausbildung-categories li");
var triggerMenu = $(".dropdown-submenuSide");
var highlightsList = $(".list-ausbildung-highlights");
var submenuList = $(".list-ausbildung-submenu");
$('.list-ausbildung-categories').on('click', 'li', function () {
if( $(this).hasClass('active') ){
triggerMenu.removeClass('asg-gray-bg-200');
$(".dropdown-submenuSide .list-ausbildung-submenu ul").html('');
} else {
highlightsList.hide();
submenuList.show();
triggerMenu.addClass('asg-gray-bg-200');
$('li.active').removeClass('active');
$(this).addClass('active');
var subMenu = $(this).find(".dropdown-submenu").html();
$(".dropdown-submenuSide .list-ausbildung-submenu ul").html(subMenu);
}
});
$('.asg-megamenu div[class^="col"]:first-child').on('click', function () {
categoriesMenu.removeClass('active');
triggerMenu.removeClass('asg-gray-bg-200');
submenuList.hide();
highlightsList.show();
});
});
I'm having this Bootstrap Mega Menu, which also contains a submenu (Column 2). On click, it should hide Column 3, and show the submenu items. (it does its job)
Currently, I'm grabbing the submenu content with jquery html() and then placing it on the third column (probably not the cleanest method).
The problem: whenever I close a submenu and click again, it won't open back.
It looks like currently, the active class isn't removed on the second click. Instead, it just clears out the HTML of column three. We could fix that by adding a line to remove the active class when we hide the submenu.
if( $(this).hasClass('active') ){
$(this).removeClass('active'); // add in this line here so it will trigger properly on the next click
triggerMenu.removeClass('asg-gray-bg-200');
$(".dropdown-submenuSide .list-ausbildung-submenu ul").html('');
}

Hide inactive or disabled elements in the list

I am struggling with the following issue.
On my wordpress website I have a dropdown filter lists
1. VEHICLE TYPE (convertible, coupe etc.)
2. MAKE (Mercedes, BMW etc.)
3. MODEL (CLK, X5 etc.)
so, when selecting the VEHICLE TYPE from the FIRST list,
appears the corresponding MAKES in the SECOND one for the selected item,
and in the THIRD list appears then the model coresponding the MAKE (Mercedes-CLK, BMW-X5).
Now the thing is, that the Makes or Models that are disabled or inactive won't show on DESKTOP but on MOBILE they appear although still inactive.
1ST question: How can I hide the disabled elements from the list on MOBILE?
2ND question: Can I disable the MAKES and MODELS unless chosen VEHICLE TYPE?
Here below you can see the backend code for the list.
var car_dealer = {};
(function ($) {
/*
* Cleans the form URL from empty parameters on submit
*/
$('.vehicle-search-form').submit( function() {
$(this).find( "input[type='number']" ).filter(function(){
return ($(this).attr( 'min' ) == $(this).attr( 'value' ) || $(this).attr( 'max' ) == $(this).attr( 'value' ));
}).attr( 'disabled', 'disabled' );
$(this).find( "input[type='search']" ).filter(function(){
return ! $(this).val();
}).attr( 'disabled', 'disabled' );
$(this).find( "select" ).filter(function(){
return ! ( $(this).val() && $(this).val() != '-1');
}).attr( 'disabled', 'disabled' );
})
/*
* Disables all models that do not fit the selected make
*/
$('#car_dealer_field_vehicle_type').on('change',function(){
var makeName = $(this).find( 'option:selected' ).attr( 'data-type' );
$('#car_dealer_field_make option')
// first, disable all options
.attr( 'disabled', 'disabled' )
// activate the corresponding models
.filter( '[data-type="' + $.trim( makeName ) + '"], [value="-1"]' ).removeAttr( 'disabled' )
// remove previous value
.parent().val( -1 );
});
$('#car_dealer_field_make').on('change',function(){
var makeName = $(this).find( 'option:selected' ).attr( 'data-make' );
$('#car_dealer_field_model option')
// first, disable all options
.attr( 'disabled', 'disabled' )
// activate the corresponding models
.filter( '[data-make="' + $.trim( makeName ) + '"], [value="-1"]' ).removeAttr( 'disabled' )
// remove previous value
.parent().val( -1 );
});
}(jQuery));
I am grateful and looking forward to hear from you soon !
I know this is old but here we go.
Here is the event handler - reworked a slight bit to only have one selection event handler.
Now as far as the hiding and showing, simply do that to the appropriate list of options filtered as you indicate to hide the disabled ones.
Use prop("disabled",true) to disable, not an attribute.
I left out how to re-enable and show when that is needed but that is a simple
.find('option').prop('disabled",false).show();
(function($) {
/* * Cleans the form URL from empty parameters on submit */
$('.vehicle-search-form').on('submit', function(e) {
// might want to prevent the submit?
e.preventDefault();
$(this).find("input[type='number']")
.filter(function() {
return ($(this).attr('min') == $(this).attr('value') ||
$(this).attr('max') == $(this).attr('value'));
}).prop('disabled', true);
$(this).find("input[type='search']")
.filter(function() {
return !$(this).val();
}).prop('disabled', true);
$(this).find("select").filter(function() {
return !($(this).val() && $(this).val() != '-1');
}).prop('disabled', true);
});
// here we can create one custom event handler to do the disable
$('#car_dealer_field_make')
.on('change', function() {
var makeName = $(this).find('option:selected').data('make');
$(this).trigger("custom-set-me", [makeName, "fun"]);
});
$('#car_dealer_field_vehicle_type')
.on('change', function() {
let makeName = $(this).find('option:selected').data('type');
$(this).trigger("custom-set-me", [makeName, "fun"]);
})
// add the other one to the handler
.add("#car_dealer_field_make")
/*
* Disables all that do not fit the selected
*/
.on('custom-set-me', function(event, compareTo, param2) {) {
let iamMe = $(this);
let options = iamMe.find('option');
options
.prop('disabled', true)
// activate the corresponding models
.filter(function() {
return $(this).data('type') == $.trim(compareTo);
}).val(-1).prop('disabled', false);
// remove previous value
iamMe.val(-1);
options.filter(':diabled').hide();
});
}(jQuery));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

jquery.mobile swipe page navigation restrict to div element

I am working with this jquery.mobile example to use swipe to navigate pages.
jquery.mobile swipe-page example
Now I don´t want to have the swipe on the whole page. I want to bind it only to an div element.
I have a div element on my page
<div id="divSWIPE"></div>
I have looked at the source code of the example and I think I found the part that handles the swipe event.
// The same for the navigating to the previous page
$( document ).on( "swiperight", ".ui-page", function( event ) {
var prev = $( this ).jqmData( "prev" );
if ( prev && ( event.target === $( this )[ 0 ] ) ) {
navprev( prev );
}
});
I have tried to modify this but I can´t get this working only on the div element.
I have tried this
$( "#divSWIPE" ).on( "swiperight", ".ui-page", function( event ) {
and this
$( document ).on( "swiperight", "divSWIPE", function( event ) {
But this doesn´t work.
How can I bind this to my div element?
Attack swipe listeners on pagecreate. The below code will check if there is a page in DOM before the current page. Or retrieve value from custom attribute in page div data-prev.
$(document).on("pagecreate", function (e) {
var page = e.target;
$("#divSwipe", page).on("swiperight", function () {
var prev = $(this).closest(".ui-page").prev("[data-role=page]");
/* or read custom attribute */
var prev = $(this).closest(".ui-page").data("prev");
if ( prev.length > 0 || typeof prev != "undefined" ) {
/* navigate or do something else */
$.mobile.pageContainer.pagecontainer("change", prev);
}
});
});

Focus selection in layout

Here is my JS fiddle that I am using to create expanding boxes for products:
http://jsfiddle.net/wpneily/vsnag7ja/
using this code:
var $container = $('#iso-container'),
$items = $('.item');
$container.isotope({
itemSelector: '.item',
masonry: {
columnWidth: 60
},
getSortData : {
selected : function( $item ){
// sort by selected first, then by original order
return ($item.hasClass('selected') ? -500 : 0 ) + $item.index();
}
},
sortBy : 'selected'
})
$items.click(function(){
console.log('ee')
var $this = $(this);
// don't proceed if already selected
var $previousSelected = $('.selected');
if ( !$this.hasClass('selected') ) {
$this.addClass('selected');
}
$previousSelected.removeClass('selected');
// update sortData for new items size
$container
.isotope( 'updateSortData', $this )
.isotope( 'updateSortData', $previousSelected )
.isotope();
});
$('.noclick').click(function(e){
console.log('dd')
e.stopPropagation();
});
This works great except, if a user scrolls down and picks one of the boxes below the current "open" selection, the new selection open out of view up above. In other words the new selected product box in not in focus. I want a selected box to not only open but also scroll the page to the top of the container, in this case, id="iso-container". Can anyone please help.
Try adding following code at end of your $item.click handler:
$('html,body').animate({scrollTop: $("#iso-container").offset().top}, 'slow');
Updated your fiddle

jQuery fadeOut callback function not being called

I am trying to swap divs by fading them in and out when another div is clicked. The only problem is: first the callback function wouldn't get called, so I took it out completely and the divs are acting funny now. Meaning when I click one of the divs the corresponding div that should fadeIn doesn't and the div that should have fadedOut did not.
HTML:
<ul id="tour">
<li id="pitch_link" class="selected">
<h1>Pitch</h1>
<p>Pitch a ball.</p>
</li>
<li id="publish_link">
<h1>Publish</h1>
<p>Publish the spin.</p>
</li>
<div id="pitch">
<ul>
<li><h2>pitch Stuff</h2></li>
<li><h2>Graphics</h2></li>
</ul>
</div>
<div id="publish">
<ul>
<li><h2>publish Stuff</h2></li>
<li><h2>Graphics</h2></li>
</ul>
</div>
jQuery w/out callback:
$("#tour li").click( function(event) {
if( !$(this).is( ".selected" ) ) {
// find the link that was previously selected and fade it out
var prevSelectedLink = $(".selected").attr( 'id' );
prevSelectedID = "#" + prevSelectedLink.substr( 0, prevSelectedLink.length-5 );
// fade the previously selected div out
$(prevSelectedID).fadeOut( "fast" );
// Deselect the previously selected link (remove selected class)
$(prevSelectedLink).removeClass( "selected" );
// Select the new Link
$(this).addClass("selected");
// Fade the new div content in
var linkID = $(this).attr( 'id' ); // linkID = pitch_link
contentID = "#" + linkID.substr( 0, linkID.length-5 ); // contentID = #pitch
$(contentID).fadeIn( "slow" );
}
});
jQuery w/ callback:
if( !$(this).is( ".selected" ) ) {
// find the link that was previously selected and fade it out
var prevSelectedLink = $(".selected").attr( 'id' );
prevSelectedID = "#" + prevSelectedLink.substr( 0, prevSelectedLink.length-5 );
// fade the previously selected div out
$(prevSelectedID).fadeOut( "fast" , function() {
// Deselect the previously selected link (remove selected class)
$(prevSelectedLink).removeClass( "selected" );
// Select the new Link
$(this).addClass("selected");
// Fade the new div content in
var linkID = $(this).attr( 'id' ); // linkID = pitch_link
contentID = "#" + linkID.substr( 0, linkID.length-5 ); // contentID = #pitch
$(contentID).fadeIn( "slow" );
});
}
});
Without the CSS, I can't really tell what the problem is but the code can be cleaned up like so:
$('#tour li').click(function(){
if( !$(this).hasClass('selected') ){
//Get the ID of the DIV you want to show
var div_id = $(this).attr( 'id' ).replace('_link','');
$('#tour li').removeClass('selected');
$(this).addClass('selected');
$('div').fadeOut("fast", function(){
$('#'+div_id).fadeIn("fast");
});
}else{
return false;
}
});
I haven't tested this but what it does is if the link is not selected, it gets the ID of the div using the link ID, removes the 'selected' class from all other links and adds the 'selected' class to the li clicked. All div's are then faded out and finally the required div is faded In.
You can also use the .not() operator to prevent the fadeOut() for the div with 'div_id'.
This is the code I ended up with that worked thanks a lot to Sagar.
$("#tour li").click( function(event) {
// make sure we are not already selected
if( !$(this).hasClass( "selected" ) ) {
// find the tab link that was previously selected and the corresponding div content
var prevTab = '#' + $(".selected").attr( 'id' ); // prevTab = #pitch_link
prevTabCont = prevTab.replace( '_link', '' ); // prevTabCont = #pitch
// Deselect the previously selected tab link (remove selected class)
$(prevTab).removeClass( "selected" );
// Find the currently selected tab and its corresponding div content
var selectedTab = '#' + $(this).attr( 'id' ); // selectedTab = #publish_link
selectedTabCont = selectedTab.replace( '_link', '' ); // selectedTabCont = #publish
// Make the tab link selected
$(this).addClass("selected"); // this -> #publish_link
// fade the previously selected div out
$(prevTabCont).fadeOut( "slow", function() {
$(selectedTabCont).fadeIn( "slow" );
});
}
});

Categories