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.
Related
I have some unwanted tags inside contenteditable divs and need to remove them.
Those are and span
Tried with jquery unwrap function but but the result is undefined because it removes parent's tags and not the tags itself.
Any help? In the example below the expected console is:
lorem ipsum lorem ipsum lorem ipsum
$('button').on('click', function(){
$('span').unwrap();
console.log($('#story').html());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='story' id='story'>
loem ipsum <span style="font-size: 1.3em;">lorem ipsum</span> lorem ipsum
</div>
<br>
<button>CLICK</button>
you have to use like
$("#story").find("span").contents().unwrap();
$('button').on('click', function(){
$("#story").find("span").contents().unwrap();
console.log($('#story').html().replace(/ /g, ''));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='story' id='story'>
loem ipsum <span style="font-size: 1.3em;">lorem ipsum</span> lorem ipsum
</div>
<br>
<button>CLICK</button>
You can change outerHTML to innerHTML for <span> and use replace to remove
$('button').on('click', function(){
$('span').each(function(){
this.outerHTML = this.innerHTML;
})
let html = $('#story').html();
$('#story').html(html.replace(/ /g,""))
console.log($('#story').html());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='story' id='story'>
loem ipsum <span style="font-size: 1.3em;">lorem ipsum</span> lorem ipsum
</div>
<br>
<button>CLICK</button>
You need to unwrap the text nodes, so use contents() method to get all child nodes. And replace using String#replace method where html() method with a callback(the second argument in the callback is old HTML content) can be used for updating the content.
$('button').on('click', function() {
// get span tags child nodes and unwrap
$('#story span').contents().unwrap();
// remove from html content
$('#story').html((_, html) => html.replace(/ /g, ''))
console.log($('#story').html());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='story' id='story'>
loem ipsum <span style="font-size: 1.3em;">lorem ipsum</span> lorem ipsum
</div>
<br>
<button>CLICK</button>
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 working on a laravel project. I have to iterate over a resource using the #foreach blade directive like so:
#foreach($users as $user)
<p #click="toggleClick">{{ $user->name }}</p>
<p v-if="clicked">Lorem ipsum</p>
#endforeach
You may have already noticed the problem with this approach. The problem is if there are five users, the toggleClick listener will be attached to each of the paragraphs. So if I click on "one" user, the hidden Lorem ipsum paragraphs will be immediately shown for "all" paragraphs. Here is an example:
John Doe
Lorem ipsum
Jane Doe (Clicked)
Lorem ipsum
Jimmy Doe
Lorem ipsum
But what I want is this:
John Doe
Jane Doe (Clicked)
Lorem ipsum
Jimmy Doe
How can I achieve that?
If you want each paragraph to behave independently, then you must have independent listeners.
For example, you could add an index in your loop and toggleClick(event, i) where i is the paragraph number.
In your HTML simply show visible paragraph using a Boolean field ;)
Just wrap it in some div or smg like it.
#foreach($users as $user)
<div>
<p #click="toggleClick">{{ $user->name }}</p>
<p v-if="clicked">Lorem ipsum</p>
<div>
#endforeach
JS in jQ
q = f() ->
$(this).parent().find('[v-if="clicked"]')
// ...
If you're not against using some classes and Javascript, I suggest you this approach:
var names = document.getElementsByClassName("toggleClick");
for (var i = 0; i < names.length; i++) {
names[i].addEventListener("click", function(index, value) {
this.nextElementSibling.classList.toggle("hiddenText");
})
}
.hiddenText {
display: none;
}
<p class="toggleClick">John Doe</p>
<p class="hiddenText">Lorem ipsum 1</p>
<p class="toggleClick">Jane Doe</p>
<p class="hiddenText">Lorem ipsum 2</p>
<p class="toggleClick">Jimmy Doe</p>
<p class="hiddenText">Lorem ipsum 3</p>
Hope it 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;
}
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.