jQuery "Promise" resetting ol bullets to zero - javascript

I am having a problem with a jQuery plugin i am writing and was hoping for some guidance here.
The plugin is just a simple "Accordion". When you click on a heading, other already expanded sections collapse, and the clicked section expands. (i know there are many accordion plugins to download, but consider this an educational exercise for me as well)
Below is my full page code.
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
</head>
<body>
<section class="collapsibleGroup">
<div>
<h3>Heading 1</h3>
<div class="hiddenContent">
<ol>
<li>line 1</li>
<li>line 2</li>
</ol>
</div>
</div>
<div>
<h3>Heading 2</h3>
<div class="hiddenContent">
test
</div>
</div>
</section>
<script>
(function($) {
$.collapse = function( el, options ) {
var base = this;
base.$el = $(el);
base.init = function() {
base.$hideable = base.$el.find('.hiddenContent');
base.$trigger = base.$el.find('h3');
base.$hideable.hide();
}
base.init();
base.$trigger.on('click', function(e){
var $clicked = $(this);
var isVisible = ($clicked.next('div.hiddenContent').is(':visible')) ? true : false;
base.$hideable.slideUp(300);
base.$hideable.promise().done(function(){
if(!isVisible) {
$clicked.next('div.hiddenContent').slideDown(300)
}
})
})
};
$.fn.collapse = function(options) {
return this.each(function() {
(new $.collapse(this, options))
})
}
})(jQuery);
$('.collapsibleGroup').collapse();
</script>
</body>
</html>
My problem - which is only happening in Internet Explorer - is this. If you click "heading 1" you will see it expand, and 2 numbered bullets are shown. Then click "heading 2" and the first heading will collapse, and the second heading will expand, showing some text. Now, if you click "heading 1" again, section 2 collapses, section 1 expands, but the numbered bullets are both numbered 0 (zero).
I have no idea why this is happening, but I suspect it has to do with the "promise" function. If i take my slideDown command outside of a promise, this doesn't happen. In reality, my code is larger than this, and the promise is required, so if anyone can shed any light on this subject, I would be grateful.
Many thanks

Related

How do i make one button content close when i click another button's content in Javascript

My problem is that I have a website, using javascript I have made it when I click on the About Me it opens, but when I click on Education and Achievements the About me button's content remains open and the Education stuff overlaps it. I want to make it so that when I click on another button the first one closes (its content. The website name is dirieahmed.ml
My code HTML and JS will be linked below ill add CSS later if need be.
<div class="container">
<button id="one" class="click one">About Me</button>
<div class="list-1 sec">
<h1 class="content-header-one content">Dummy text header</h1>
<p class="content-paragraph-one">Dummy text</p>
</div>
<button class="click two">Education and Achivements</button>
<div class="list-2 sec">
<p class="content-paragraph2 content">Dummy text</p>
<ul class="content-list content">
<li>- Achivement #1</li>
<li>- Achivement #2</li>
<li>- Achivement #3</li>
</ul>
</div>
<button class="click three" >Other</button>
<div class="list-3 sec">
<h1 class="content-header-two content">Dummy text header</h1>
<p class="content-paragraph3 content">Dummy text</p>
</div>
<script async>
let one = document.querySelector('.one');
let two = document.querySelector('.two');
let three = document.querySelector('.three');
let list1 = document.querySelector('.list-1');
let list2 = document.querySelector('.list-2');
let list3 = document.querySelector('.list-3');
one.addEventListener("click", ()=>{
list1.classList.toggle('newlist');
});
two.addEventListener("click", ()=>{
list2.classList.toggle('newlist');
lis
})
three.addEventListener("click", ()=>{
list3.classList.toggle('newlist')
});
// please change above
</script>
</div>
To summarize you will need to hide all other ones when there is a click anywhere and then only show the ones based on the link that you clicked
Check the code below
https://codesandbox.io/s/keen-driscoll-igzlwb?file=/index.html:2333-3356
<script async>
// Instanciate List div's
let list1 = document.querySelector(".list-1");
let list2 = document.querySelector(".list-2");
let list3 = document.querySelector(".list-3");
// Reset's all views to the default without .newlist
const resetAllViews = () => {
list1.classList.remove("newlist");
list2.classList.remove("newlist");
list3.classList.remove("newlist");
};
// Checks to see what button is clicked and shows correct list based on input
document.addEventListener(
"click",
function (e) {
e = e || window.event;
var target = e.target;
if (target.classList.contains("one")) {
resetAllViews();
list1.classList.add("newlist");
}
if (target.classList.contains("two")) {
resetAllViews();
list2.classList.add("newlist");
}
if (target.classList.contains("three")) {
resetAllViews();
list3.classList.add("newlist");
}
}, false);
</script>
The document object should be given a click event listener.
Use the contains() function to determine with each click if the clicked element is outside the targeted element.
Hide the original element if the clicked element is outside.

Two jquery ui tabbed divs on one page. One works, the other doesn't

I have a page with two div panels, a left and a right. Both panels are tabbed using jquery-2.1.4.min.js and jquery-ui.js. One panel has three tabs, and it works.
The js in the head of my page looks like this:
$(function(){
// Doesn't matter if following two lines are reversed. Same output.
$( "#property-card" ).show().tabs(); // this one doesn't work
$( "#tabs" ).show().tabs(); // this one works
});
The html looks like this:
//This tabbed content works:
<div id="tabs">
<ul>
<li>Tasks</li>
<li>Notes</li>
<li>Photos</li>
</ul>
<div id="tabs-1">
<!-- Tasks -->
</div>
<div id="tabs-2">
<!-- Notes -->
</div>
<div id="tabs-3">
<!-- Other -->
</div>
The other div panel looks something like this:
//This one shows hyperlinked text within the content area, instead of showing tabs
<div id="property-card" class="eight columns light-manilla curved10 border-dark border-2 border-ridge padding-1-percent">
<ul>
<li>Property</li>
<li>Help</li>
<li>List Price</li>
<li>Taxes</li>
<li>HOA</li>
<li>Showing Instructions</li>
<li>BPO Values</li>
<li>Buyer Leads</li>
</ul>
<div id="property">
</div>
<div id="property-help">
</div>
<div id="property-list-price">
</div>
<div id="property-taxes">
</div>
<div id="property-hoa">
</div>
<div id="property-showing-instructions">
</div>
<div id="property-bpo-values">
</div>
<div id="property-buyer-leads">
</div>
</div>
(not sure if this is related) Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help http://xhr.spec.whatwg.org/jquery-2.1.4.min.js:4:14346
ReferenceError: data is not defined
(I think this one is related) jquery-2.1.4.min.js%20line%202%20%3E%20eval:35:1
See inline screen shot sample for example of what's going on.
Hate answering my own questions, but in another file at the bottom of my html, there is another javascript block, which "activated" the working tabbed div, but because I didn't add the new tabbed div (because I didn't realize that second javascript block was there) the second tabbed div didn't work. Here is what made it work:
$(function () {
$('#property-card').tabs({
activate: function (event, ui) {
var $activeTab1 = $('#property-card').tabs('option', 'active');
}
});
$('#tabs').tabs({
activate: function (event, ui) {
var $activeTab2 = $('#tabs').tabs('option', 'active');
if ($activeTab2 == 2) {
// HERE YOU CAN ADD CODE TO RUN WHEN THE SECOND TAB HAS BEEN CLICKED
$("#mls-images-carousel").css("display","block");
retrieveAssetImages('<?php echo $as_id; ?>');
}
else{
$("#mls-images-carousel").css("display","hidden");
}
}
});
});

Why jQuery selectable is not functioning properly?

I have an mvc project where I have implemented two jQuery selectable plugin like below:
The <HTML> code,
<div class="product-page-options">
<div class="pull-left">
<label class="control-label" style="font-weight:bolder">Size:</label>
<ol class="ui-selectable" style="width:auto" id="selectable">
#{
var size = Model.AvailableSizes.Split(',');
foreach (var item in size)
{
<li class="ui-selectable">#item</li>
}
}
</ol>
</div>
<div class="pull-left">
<label class="control-label">Color:</label>
<ol class="ui-selectable" style="width:auto" id="selectable1">
#{
var color = Model.AvailableColors.Split(',');
foreach (var clr in color)
{
<li class="ui-selectable">#clr</li>
}
}
</ol>
</div>
</div>
The static script for selectable jQuery plugin.
<script type="text/javascript">
$(document).ready(function () {
$("#selectable").selectable({
selected: function (event, ui) {
$(ui.selected).siblings().removeClass("ui-selected");
$("#selectedsize").val($("li.ui-selected").html());
}
});
});
</script>
<script type="text/javascript">
$(document).ready(function () {
$("#selectable1").selectable({
selected: function (event, ci) {
$(ci.selected).siblings().removeClass("ui-selected");
$("#selectedsize").val($("li.ui-selected").html());
}
});
});
</script>
The first selectable jQuery plugin works perfectly while the second is not functioning properly. I mean I cannot select any item from the second selectable list and also the appearance is not same as the first one. The picture below shows clearly the problem.
Anything i can do about it? any help would be appreciated. Thanks in advance.
There's 2 issues at play here. Firstly, you will need to have styles set up specifically for both of the selectables (if you have based your code on the examples on the jQuery UI site. Secondly, upon selecting in the selector for the items, you will need to identify the path to the selected li element as a child of the relevant selectable.
$("#selectedcolor").val($("#selectable1>li.ui-selected").html());
The following plunker will show you it working :
Link To My Plunker

Javascript Menu to Show 1 image and hide another

I have a simple menu bar for displaying a couple different menus. When I click the first one the image comes up, but when I click the 2nd I need the 1st one to disappear and the 2nd appear in its place.
What happens right now is I click "Main Menu" and it opens, but then I need to click it again to close it.
<div class='rmm' data-menu-style = "graphite" data-menu-title = "Menu">
<ul>
<li>Main Menu Show</li>
<li>Gluten Friendly</li>
<li>Kids Menu</li>
</ul>
</div>
<div id="main_menu" style="display:none;"><a href="http://xxxxxx"></div>
<div id="gluten_friendly" style="display:none;"><a href="http://xxxxx"></div>
<div id="kids_menu" style="display:none;"><a href="http://xxxxx"></div>
=====Javascript
<script type="text/javascript">
function hideshow(temp){
var menu = document.getElementById(temp);
if (menu.style.display=="block")
menu.style.display="none"
else
menu.style.display="block"
return false;
}
</script>
I've updated the code from Sid, which works a little better than what I had, but when I click "Main Menu" it opens and I still need to click it again to close, but also when I click "Kids Menu" that one opens right below the "Main Menu".
I know I'm getting close, haha, ughh.
This is part of my Company Website so I don't really want to post the link in public, but if someone can help me please shoot me an email and I will send you the live link so you can see what I'm dealing with. It would be greatly appreciated and I'll gladly make note of the help here on the forum.
seansugden#britishbeer.com
The following may not be the best solution but works OK for me.
HTML
<div class='rmm' data-menu-style = "graphite" data-menu-title = "Menu" >
<ul>
<li>Main Menu Show</li>
<li>Gluten Friendly</li>
<li>Kids Menu</li>
<li>Desserts</li>
</ul>
</div>
<div id="main_menu"><a href="http://xxxxxxx"><img src="http://xxxxxx" height="650" width="650"></div>
<div id="gluten_friendly"><a href="http://xxxxxxx"><img src="http://xxxxxx" height="650" width="650"></div>
<div id="kids_menu"><a href="http://xxxxxxx"><img src="http://xxxxxx" height="650" width="650"></div>
<div id="desserts"><a href="http://xxxxxxx"><img src="http://xxxxxx" height="650" width="650"></div>
JavaScript
function hideshow(temp){
var menu = temp.id;
if (menu == "main_menu") {
document.getElementById('main_menu').style.display="block";
}
else
{
document.getElementById('main_menu').style.display="none";
}
if (menu == "gluten_friendly") {
document.getElementById('gluten_friendly').style.display="block";
}
else
{
document.getElementById('gluten_friendly').style.display="none";
}
if (menu == "kids_menu") {
document.getElementById('kids_menu').style.display="block";
}
else
{
document.getElementById('kids_menu').style.display="none";
}
if (menu == "desserts") {
document.getElementById('desserts').style.display="block";
}
else
{
document.getElementById('desserts').style.display="none";
}
}
Demo
Try using underscores _ or dashes - instead of spaces for the id attributes. As Brett said in his comment, the ones with spaces are invalid.
As for hiding them all, you can give the divs a common class
<div class="image" id="main-menu"> ... </div>
and use document.getElementsByClassName('class-name') to retrieve an array to loop over and hide (before showing the selected one).
var divs = document.getElementsByClassName('image');
for(var i in divs){
div.style.display = 'none';
}
I do something similar on my website. You need to give them all a class and do the following when one is clicked:
$('#desserts').click(function(){
$('.menus').hide();
$('#desserts').show();
});
When you click desserts, first all menus are closed, then desserts is opened. I don't completely understand what you want to show and hide but I'm sure you'll be able to adapt it.

how can I remove the subnavigation overlap?

I am trying to create a sub navigation. Right now I have two subnav. When i hover over the first item on the main menu the corresponding submenu appears. But when I hover over the second item the second sub nav appears OVER the first one. How can I write the code so that this does not happen?
url: http://arabic001.com
$(document).ready(function() {
$('#arbNavText01').mouseover(function() {
$('#subNav01').show('slow');
});
$('#subNav01').mouseleave(function() {
$('#subNav01').hide('slow');
});
$('#arbNavText02').mouseover(function() {
$('#subNav02').show('slow');
});
$('#subNav02').mouseleave(function() {
$('#subNav02').hide('slow');
});
})
I just tried the below suggestion from Scott and I am not able to show and hide the submenu on hover. Any ideas of how to solve this problem? Here are my new codes:
html
<div id="menu01" class="menu_item">
<div id="engNavText01">Alphabet</div>
<div id="arbNavText01">الأحرف</div>
<div id="subNav01" style="display:none;">
<a href="colors" class="subNav">
<span style="font-size:26px; cursor:pointer;">قراءة</span</a>
<br>reading<br><br>
</div>
</div>
<div id="menu02" class="menu_item">
<div id="engNavText02">Numbers</div>
<div id="arbNavText02">الأحرف</div>
<div id="subNav02" style="display: none; ">
<a href="colors" class="subNav">
<span style="font-size:26px; cursor:pointer;">قراءة</span</a>
<br>reading<br><br>
</div>
</div>
and the JS
$(document).ready(function() {
$('.menu_item').children().hover(
function(){
$subNav = $(this).parents('menu_item').children("div[id^='subNav'");
if ($subNav.css('display', 'none')){
$subNav.show('slow');
}
},
function(){
$(this).parents('menu_item').children("div[id^='subNav'").hide('slow');
});
})
You've created a mouseleave event, but you've only attached it to the submenu. So in order to make a menu disappear, the user will have to hover over the submenu and then move out. You could achieve what you want by hiding other submenus before opening a new one. So keeping your mouseleave events as you have them, you could modify your 2 mouseover events to this:
$('#arbNavText01').mouseover(function() {
$('#subNav02').hide('slow');
$('#subNav01').show('slow');
});
$('#arbNavText02').mouseover(function() {
$('#subNav01').hide('slow');
$('#subNav02').show('slow');
});
Edit for comment:
I was thinking about that when I went and looked at your page originally. I think if you used a slightly different structure in your html this could be done. Right now your menu divs aren't clearly structurally related to each other so maybe add a div that can contain the 3 elements associated with each menu item.
I'm going to spit ball an idea, it may not even work let alone be the best way.
<div id="menu01" class="menu_item">
<div id="engNavText01">Alphabet</div>
<div id="arbNavText01">الأحرف</div>
<div id="subNav01" style="display: none; ">
<span style="font-size:26px; cursor:pointer;">قراءة</span
<br>reading<br><br>
</div>
</div>
<div id="menu02" class="menu_item">...
Edited JS, I think now it could work
$('.menu_item').hover(
function(){
$subNav = $(this).children("div[id^='subNav']");
if ($subNav.css('display', 'none')){
$subNav.show('slow');
}
},
function(){
$(this).children("div[id^='subNav']").hide('slow');
}
);
Was trying it out with a JSFiddle, seems alright there. Might need some modification for your uses.

Categories