I'm trying to use the answer to this question to implement exactly what that user wants to do.
I am basically making a popover that appears when you click on a link, and when you click anywhere except the popover it will close, and if you click the link that opened it, it will also close it.
The problem I'm having is that nothing happens when I click on the link, when I remove all the stopPropagation stuff it opens but doesn't close.
Here is my JavaScript:
function close_popovers(){
$('.new_tooltip').remove();
}
function toggle_popover(user_id){
$('.new_tooltip').show();
var position = $('#link_' + user_id).position();
var top_position = (position.top - $('.new_tooltip').outerHeight()) - 10;
var left_position = (position.left - ($('.new_tooltip').outerWidth() / 2) + ($('#link_' + user_id).outerWidth() / 2));
$('.new_tooltip').css ({
top: top_position + "px",
left: left_position + "px"
});
return false;
}
$(document).click(function() {
close_popovers();
});
$(".new_tooltip, .stoppropagation").click(function(e) {
e.stopPropagation();
return false;
});
Here is the html link that opens the popover:
Adam Tester
And finally the html of my popover:
<div class="new_tooltip" id="popover_34" style="display:none; top:0px; left:0px; position:absolute; z-index:1000;">
<div class="top">
<div class="picture">
<div class="userphotomedium">
<img class="actual_photo" src="image url" width="31" height="31" />
</div>
</div>
<div class="infomation">
<div class="name main_text_colour">Name</div>
<div class="role">Department of Science and Research - Subdivision 3</div>
</div>
<div class="buttons">
<div class="closebtn_con">
<div class="crossbtn" style="float:none;"></div>
</div>
<div class="viewbtn_con">
<div>View Bio</div>
</div>
</div>
<div class="floatfix"></div>
</div>
<div class="bottom">
<dl>
<dt>Department</dt>
<dd class="main_text_colour">Medical, Business Unit Head</dd>
<dt>Country</dt>
<dd class="main_text_colour">United Kingdom</dd>
<dt>Email</dt>
<dd class="main_text_colour">adam.tester#edge.co.uk</dd>
<dt>Contact Number</dt>
<dd class="main_text_colour">01832 300097</dd>
<dt>Mobile Number</dt>
<dd class="main_text_colour">07710 664 689</dd>
</dl>
<div class="bio" id="bio_34" style="background-color:#FFFFFF; position:relative; z-index:100;">
<div class="main_text_colour" style="font-weight:bold;">Biography</div>
<div id="bio_width_34" style="white-space:pre-wrap; overflow-y:scroll; height:100px; width:100px;">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>
</div>
</div>
</div>
Check some of the mistakes in your code:
Use $(".new_tooltip, .stoppropagation") instead of $(".new_tooltip .stoppropagation").
$('.new_tooltip').remove(); will remove the popup and you cannot display it again. Try $('.new_tooltip').hide(); instead.
In your code, you always show the popup when clicking on the link. Try $('.new_tooltip').toggle(); or check for the current state and show, hide accordingly.
Related
hello I'm getting a blank space in the page and that's what I get when I want to inspect the page bindings={
"ng-reflect-ng-if": "false"
} and I found out that I'm getting a a blank cards
here is an image for it :
`<section class="play-n-win-section">
<h1 class="play-n-win-paragraph">play N Win</h1>
<div class="card-container">
<div *ngFor="let item of games; index as i">
<mat-card class="cards" *ngIf="i <= 11">
<mat-card-header>
<mat-card-title>{{item.game_name}}</mat-card-title>
<mat-card-subtitle>{{item.game_description}}</mat-card-subtitle>
</mat-card-header>
<div class="game-cover-container">
<img class="game-cover" mat-card-image src="{{item.game_cover_url}}" alt="{{item.game_name}}">
</div>
<mat-card-content>
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,was
popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages
</p>
</mat-card-content>
</mat-card>
</div>
</div>
<a mat-button routerLink="playandwin ">Link</a>
</section>`
The ngfor is creating those extra elements because they are in the array (games) that you are ngFor-ing
The solution is to instead ngFor over a smaller array, or use a pipe
In your class
get first12Games(){
return this.games ? this.games.slice(0,12) : [];
}
Then in the html
*ngFor="let item of first12Games;
And then you won't have to use *ngIf="i<=11"
Technically it's best practice to use pipes https://angular.io/guide/pipes for this, but an optimization like that isn't a concern in a smaller project.
In my application there are a lot of buttons inside a div.
Initially I am showing three buttons in div width 400 px. Overflow:hidden will hide the remaining elements. I have added below css for div, having right arrow button in my application.
Can anybody body tell how I, if user clicks arrow button, can show next button elements occupying the same width in jquery? If user clicks again I need to show remaining elements up to last element
My html structure is below
.parentdiv {
display: inline-flex width:400px;
overflow: hidden;
}
<div class="parentdiv">
<div class="childdiv">
<span> Text1
<button>button1 </button>
</span>
</div>
<div class="childdiv">
<span> Text2 lorem ipsum
<button>button2 </button>
</span>
</div>
<div class="childdiv">
<span> Text3 lorem ipsum
<button>button3 </button>
</span>
</div>
<div class="childdiv">
<span> Text4 lorem ipsum
<button>button4 </button>
</span>
</div>
<div class="childdiv">
<span> Text5 lorem ipsum
<button>button5 </button>
</span>
</div>
<div class="childdiv">
<span> Text6 lorem ipsum
<button>button6 </button>
</span>
</div>
What you want to do is.... a LOT more complicated than you think it is, and will require a lot of javascript.
It's usually not worth it to try to reinvent the wheel by hand. The correct solution to accomplish what you want is to use a "carousel" plugin. (Many, many different people have created plugins like this. You can simply google for it.)
If you are using Wordpress, then you should search for a Wordpress plugin.
If you simply want a plug-and-play solution that will work with any website, Slick is the best carousel plugin that I know of, and it works great with jQuery.
Using jQuery you can achieve that.
jQuery library is required
clicked = 1;
divSW = document.getElementByClassName('parentdiv').scrollWidth;
$('button#nxtBtn').click(function(){
divSL = $('div.parentdiv').scrollLeft();
if(divSW > divSL){
clicked++;
divW = $('div.parentdiv').width();
moveW = divW * clicked;
$('div.parentdiv').animate({
scrollLeft : moveW
})
}
})
But you need to add a next button in your HTML code with an id attribute of nxtBtn
<button id="nxtBtn">next</button>
If you need to see the previous buttons in the div you will add another button to your HTML code with an id of prvBtn.
<button id="prvBtn">previous</button>
Then you also add this code below
$('button#prvBtn').click(function(){
divSL = $('div.parentdiv').scrollLeft();
if(divSL > 0){
clicked--;
divW = $('div.parentdiv').width();
moveW = divW * clicked;
$('div.parentdiv').animate({
scrollLeft : moveW
})
}
})
$("#after").on("click", function() {
for (var i = 0; i < 3; i++)
$(".childdiv:not(.show)").eq(0).addClass("show");
});
#after {
background: lightgrey;
display: block;
width: 250px;
text-align: center;
padding: 2px 0;
cursor: pointer;
border-radius: 5px;
margin-top: 5px;
}
#after:hover {
text-decoration: underline;
}
.childdiv {
display: none;
}
.show {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parentdiv">
<div class="childdiv show">
<span> Text1
<button>button1 </button>
</span>
</div>
<div class="childdiv show">
<span> Text2 lorem ipsum
<button>button2 </button>
</span>
</div>
<div class="childdiv show">
<span> Text3 lorem ipsum
<button>button3 </button>
</span>
</div>
<div class="childdiv">
<span> Text4 lorem ipsum
<button>button4 </button>
</span>
</div>
<div class="childdiv">
<span> Text5 lorem ipsum
<button>button5 </button>
</span>
</div>
<div class="childdiv">
<span> Text6 lorem ipsum
<button>button6 </button>
</span>
</div>
<a id="after">after \/</a>
</div>
I want my show more and hide button to work for multiple text contents, now it's only working for one of them. I have 12 different texts that I want to be able to show and hide with 12 different buttons, like the one in my code. How do I do this?
var content = document.getElementById("content");
var button = document.getElementById("show-more");
button.onclick = function() {
if (content.className == "open") {
//shrink the box
content.className = "";
button.innerHTML = "Läs mer";
} else {
//expand the box
content.className = "open";
button.innerHTML = "Dölj";
}
};
<div id="content">
Test
</div>
<a id="show-more">Läs mer</a>
Hej Linnéa!
IDs should be unique, and if you want multiple occurrences of something, you should use class names.
What I would do is to wrap the links inside of the container divs;
<div class="content">
Content
<a class="toggle" href="#">Läs mer</a>
</div>
<div class="content">
Content
<a class="toggle" href="#">Läs mer</a>
</div>
Then, instead of attaching your event listener to each anchor element, take advantage of event propagation, and add a listener to each content wrapper instead;
document.querySelectorAll('.content').forEach(function(contentDiv) {
contentDiv.onclick = function(e) {
if(e.target.classList.contains('toggle')) {
e.target.innerHTML = e.currentTarget.classList.contains('open') ? 'Dölj' : 'Läs mer';
e.currentTarget.classList.toggle('open');
}
}
});
It is better to use class than id. I have implemented simple snippet where you can design using just class names.
var content = document.getElementById("content");
$(".showHide").on("click", function() {
$(this).parent().find(".more").toggle();
if ($(this).parent().find(".more").is(":visible")) {
$(this).text("Show less");
} else {
$(this).text("Show more");
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content">
<div class="text">
First text1
<div style="display:none;" class="more">Other text 1</div>
<a class="showHide" href="#">Show more</a>
</div>
<hr />
<div class="text">
First text2
<div style="display:none;" class="more">Other text 2</div>
<a class="showHide" href="#">Show more</a>
</div>
</div>
Use document querySelectorAll
var content = Array.from(document.querySelectorAll(".container"));
content.forEach(function(el){
//var content= el.querySelector(".content");
var button = el.querySelector(".show-more");
button.addEventListener("click", function () {
el.classList.toggle("open");
el.classList.contains("open") ? (button.innerHTML = "Dölj") : (button.innerHTML = "Läs mer");
}, false)
});
.container .content{display: none}
.container.open .content{display: block}
<section>
<article class="container">
<p>Lorem Ipsum is simply dummy</p>
<p class="content">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
<a class="show-more">Läs mer</a>
</article>
<article class="container">
<p>Lorem Ipsum is simply dummy</p>
<p class="content">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
<a class="show-more">Läs mer</a>
</article>
<article class="container">
<p>Lorem Ipsum is simply dummy</p>
<p class="content">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
<a class="show-more">Läs mer</a>
</article>
<article class="container">
<p>Lorem Ipsum is simply dummy</p>
<p class="content">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
<a class="show-more">Läs mer</a>
</article>
</section>
You can make it work for multiple paragraphs if you use classes for all elements, and then process it from there as element pairs (div + corresponding button).
I deliberately kept everything as much as possible the same as your original code, so it would be easy to understand the changes. And I added some 'hidden' content so you really see something happening.
var contentDivs = document.getElementsByClassName("content");
var buttons = document.getElementsByClassName("show-more");
for (var i = 0; i < contentDivs.length; i++) {
// "let" creates locally scoped variables for use in the function.
let div = contentDivs[i];
let button = buttons[i];
button.onclick = function() {
if (div.className == "open") {
//shrink the box
div.className = "content";
button.innerHTML = "Read more";
} else {
//expand the box
div.className = "open";
button.innerHTML = "Close";
}
};
}
div, a { font-size: 14px; }
.content { overflow: hidden; max-height: 18px }
<div class="content">
Div 1<br />.....<br />.....<br />.....
</div>
<a class="show-more">Read more</a>
<hr size="1">
<div class="content">
Div 2<br />.....<br />.....<br />.....
</div>
<a class="show-more">Read more</a>
<hr size="1">
I am trying to toggle the specific paragraph only but not both at the same time.
.popuplink is the same class for both the ul in the html code.
IDs are dynamically generated and it starts from 0 (in the end).
Example: If I click the id promo_popup_cta_0 then promo_popup_wrapper_0 should toggle.
When this id promo_popup_cta_0 is with 0 in the end then this id will be promo_popup_wrapper_0 is with 0 in the end. Below won't work if there are 100 of div with different numbers. I don't want to write separate code for separate clicks.
$("#promo_popup_cta_0").on("click", function() {
$("#promo_popup_wrapper_0").slideToggle();
});
$(".popupLink").on("click", function() {
$(".popupContentWrapper").slideToggle();
});
$(".popupCloseBtn").on("click", function() {
$(".popupContentWrapper").slideToggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="header-top-info">
<div class="promo-row">
<p>
FREE SHIPPING ON U.S. ORDERS OF $100 +
<u class="popupLink" id="promo_popup_cta_0">Details</u>
</p>
<p></p>
<div class="popupContentWrapper" id="promo_popup_wrapper_0">
<div class="text-right">
<div class="popupCloseBtn">Close X</div>
</div>
<div class="popupContent">
<p>Nothing says thank you, and I love you, quite like snacks, especially when they come packaged in a FEED 10 Bag. Curated with our friends at Mouth, this bundle features a delightful mix of salty and sweet</p>
</div>
</div>
</div>
<div class="promo-row">
<p>
Navy blue bag day <u class="popupLink" id="promo_popup_cta_1">For More</u>
</p>
<p></p>
<div class="popupContentWrapper" id="promo_popup_wrapper_1">
<div class="text-right">
<div class="popupCloseBtn">Close X</div>
</div>
<div class="popupContent">
<p style="margin: 0px 0px 15px; padding: 0px; text-align: justify;"><strong style="margin: 0px; padding: 0px;">Lorem Ipsum</strong> is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley
of type and scrambled it to make a type </p>
</div>
</div>
</div>
</div>
You need to use this to refer to the element being clicked on, otherwise (as you discovered) you will refer to all matching elements. Use .closest() to traverse up the DOM and when needed, .find() to traverse down:
$(".popupLink").on("click", function() {
$(this).closest('.promo-row').find(".popupContentWrapper").slideToggle();
});
$(".popupCloseBtn").on("click", function() {
$(this).closest(".popupContentWrapper").slideToggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="header-top-info">
<div class="promo-row">
<p>
FREE SHIPPING ON U.S. ORDERS OF $100 +
<u class="popupLink" id="promo_popup_cta_0">Details</u>
</p>
<p></p>
<div class="popupContentWrapper" id="promo_popup_wrapper_0">
<div class="text-right">
<div class="popupCloseBtn">Close X</div>
</div>
<div class="popupContent">
<p>Nothing says thank you, and I love you, quite like snacks, especially when they come packaged in a FEED 10 Bag. Curated with our friends at Mouth, this bundle features a delightful mix of salty and sweet</p>
</div>
</div>
</div>
<div class="promo-row">
<p>
Navy blue bag day <u class="popupLink" id="promo_popup_cta_1">For More</u>
</p>
<p></p>
<div class="popupContentWrapper" id="promo_popup_wrapper_1">
<div class="text-right">
<div class="popupCloseBtn">Close X</div>
</div>
<div class="popupContent">
<p style="margin: 0px 0px 15px; padding: 0px; text-align: justify;"><strong style="margin: 0px; padding: 0px;">Lorem Ipsum</strong> is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley
of type and scrambled it to make a type </p>
</div>
</div>
</div>
</div>
If you stay consistent and the Id's are all the same besides for the number at the end you can take the number after the last _ and use it like this
$(".popupLink").on("click", function(e) {
var id = e.target.id;
var n = id.lastIndexOf('_');
var result = id.substring(n + 1);
$("#promo_popup_wrapper_" + result).slideToggle();
});
Hope this helps
I have a 3 DIVs ('event') each with a child DIV ('event-details'). I want to be able to save the height original of 'event-details' (it varies depending on the 'event'), and then set height of 'event-details' to 126px. Then after clicking on a button ('more') I want 'event-details' to return to the original height.
What I have so far saves the 'event-details' heigh, changes it to 126px but after clicking on 'more' it changes the height of 'event-details' to 222px, regardless of the original height it has.
Any help?
JS
$(function() {
$('.event').each(function() {
var eventHeight = $(this).find('.event-details').height();
console.log( eventHeight );
$('.more').on('click', function (e) {
e.preventDefault();
$(this).parent('.event').toggleClass('show');
$('.show > .event-details').css( 'height', eventHeight);
});
});
$('.event-details').css( 'height', '126' );
});
HTML
<div class="event event-1925">
<div class="event-details">
<div class="year">1925</div>
<div class="title">Home Away</div>
<div class="copy">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
</div>
MORE
</div>
<div class="event event-1925">
<div class="event-details">
<div class="year">1925</div>
<div class="title">Home Away</div>
<div class="copy">Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</div>
</div>
MORE
</div>
<div class="event event-1925">
<div class="event-details">
<div class="year">1925</div>
<div class="title">Home Away</div>
<div class="copy">It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</div>
</div>
MORE
</div>
Thanks.
The problem you have is that the variable event height will be reset in the first each loop with the height of the next event div, so essentially you will be left with the height of the final div. You need to store the height of each div in an array or object and then retrieve it.
HTML
Use a unique identifier in the html e.g. an id
<div class="event event-1925">
<div id="event-1" class="event-details">
.....
</div>
</div>
Javascript
$(function() {
//create array to store all the event div heights
var eventHeights = [];
$('.event').each(function() {
var eventHeight = $(this).find('.event-details').height();
console.log( eventHeight );
//get the id of the event div
var id = $(this).find('.event-details').attr('id');
//store the height with reference to the div id
eventHeights[id] = eventHeight;
$('.more').on('click', function (e) {
e.preventDefault();
$(this).parent('.event').toggleClass('show');
//get the id of the event div
var id = $(this).parent('.event').find('.event-details').attr('id');
//use id to get the event div's height from array
$('.show > .event-details').css( 'height', eventHeights[id]);
});
});
$('.event-details').css( 'height', '126' );
});
I have not tested this and it could do with being optimised but hopefully it gives you the idea.
Looks like you are trying to build the expandable field set view. Basically in less View you want to show the title or summary and on expand you show more details. The above answer will work fine. Below is another way you can do it with small animations. To see a working example take a look at this link
your HTML markup for 2 events will be
<div class=" event event-1925">
Event Summary <a class="toogleButton">LESS</a>
</div>
<div class="event-details">
<div class="year">1925</div>
<div class="title">Home Away</div>
<div class="copy">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
</div>
<div class=" event event-1925">
Event Summary <a class="toogleButton">LESS</a>
</div>
<div class="event-details">
<div class="year">1925</div>
<div class="title">Home Away</div>
<div class="copy">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
</div>
The script
$(".event").click(function () {
$header = $(this);
$content = $header.next();
$toogleBut = $header.children().first()
$content.slideToggle(500, function () {
$toogleBut.text(function () {
return $content.is(":visible") ? "LESS" : "MORE";
});
});
});
Finally a simple CSS to set initial styles like your required height
.event{
height:126px;
}