How to fix items in div class="row" angular + bootstrap - javascript

Do anyone have idea how to fix elements in div with class="row" ?
How it should look like: Good view, Click: Live show(example without angular)
How it looks like: Bad view
Switch component is repeated in lights component
When i remove <div class="row"></div> elements looking good, but the are under themselves
<div class="row">
<app-switch *ngFor="let switch of switches" [switch]="switch"></app-switch>
</div>
Link to my repository: SmartPi-Client

It is because Bootstrap 4 is using Flexbox. app-switch selector is between .row and .col divs so the correct bootstrap style wasn't applied to them.
You can make the browser to ignore this app-switch selector using the following css code.
:host {
display: contents;
}
I added a working example here.
https://stackblitz.com/edit/angular-ho3q4q

Instead of adding .col-sm-12 .col-md-6 .col-xl-4 to child div of app-switch, add it to app-switch.
<div class="row">
<app-switch class="col-sm-12 col-md-6 col-xl-4" *ngFor="let switch of switches" [switch]="switch"></app-switch>
</div>

The thing is that the style for the columns is applied to the direct child/ren of the html element with the ‚row‘ class.
You could add that class to your app-switch component tag or use a wrapper around it to define the col design

Related

How to make 5 cards on each line?

Can someone help me please?
I'm writing in Angular and I want to display for example 5 cards on each row. Now I have horizontal scroll, and it looks like that:
Code:
<div class="content">
<div fxLayout="row wrap" fxLayout.xs="column" style="width: 35%; ">
<!-- Single "Responsive" Card-->
<div fxFlex [style.margin]="'20px'" style="display: flex;">
<mat-card *ngFor="let release of releases" [style.min-width]="'200px'">
<mat-card-header>
<mat-card-title>{{release.name}}</mat-card-title>
<mat-card-subtitle>New Release</mat-card-subtitle>
</mat-card-header>
<strong>Release Date: </strong>{{release.release_date}}<br />
<strong>Tracks: </strong>{{release.total_tracks}}<br /><br />
<a style="text-decoration:none" href="/artist">
<mat-card-content *ngFor="let rel of release.artists">
<mat-chip-list aria-label="Artist selection">
<mat-chip>{{rel.name}}</mat-chip>
</mat-chip-list>
</mat-card-content>
</a>
</mat-card>
</div>
How can I display 5 cards on each row for example? Thank you in advance.
Solution lies in using the right styles.
If you are looking to have few cards on each row, you might have to use max-width on the container containing the cards.
it because you wrap all with style: flex . to fix this you can add this style for child element in this case it mat-card
style = flex: 20%;
Your styles are a bit messy...
First: I recommend separating styling from html, use css files
Second: cards doesnt get wrapped because you specify fxLayout="row wrap" on mat-card's grandparent, but it cannot wrap anything because it only has one child, if you want to use flexbox then flex-flow: row wrap; must be declared on mat-card's direct parent div, and plus mat-card must have max-width: 20%.
But i would use grid, just remove every styling from html and add display: grid; grid-template-columns: repeat (5, 1fr); to the div that contains mat-cards
this will automatically devide each row in 5 containers of equal width and wrap the other ones to next row, you dont need to add anything else.
If you want it to be mobile frindly, you just add media query and change repeat(5,1fr) to repeat(1fr) and it will show one card in each row, when reproduced in mobile

How to display DIV to full width on a page that has a bootstrap class 'col-md-6'?

I am trying to display divs side by side on a page. However, if there is only one col-xs-12 col-md-6 div class on the page, then I am trying to display it full width(100%) rather than 50%. Currently it's using only 50% even if there is only one col-xs-12 col-md-6. The HTML is coming from MVC, so this HTML is fixed. Is there a way to do this using CSS or JavaScript/jQuery? I was thinking the following javascript(below) will do the trick but it doesn't.
Here is the my HTML and CSS:
<div class="col-xs-12 col-md-6 textcontent">
</div>
<div class="col-xs-12 col-md-6 service">
</div>
<div class="col-xs-12 col-md-6 textcontent">
</div>
CSS
.col-md-6{
width50%;
}
JavaScript
if ($('.col-xs-12.col-md-6').length == 1) {
$('.col-xs-12.col-md-6').toggleClass(".col-xs-12.col-md-12")
}
The Bootstrap grid system is based in a 12 column model. You can just use col-12 to say a column fill all container width.
Try this:
<div class="col-12 textcontent">
</div>
<div class="col-12 service">
</div>
<div class="col-12 textcontent">
</div>
Here the documentation about grid system with bootstrap and breakpoints if you want to apply different column configuration depending of the device screen width.
Sorry that you're locked into Bootstrap. This could easily be done with Flexbox. Addressing your specific question and code you posted, there's just a small error with your class toggle.
if ($('.col-xs-12.col-md-6').length == 1) {
$('.col-xs-12.col-md-6').toggleClass("col-xs-12 col-md-12");
}
When adding the class names, you don't want to add the "." and you want the class names separated just like they appear in the HTML. What you were doing was trying to add class=".col-xs-12.col-md-12" instead of class="col-xs-12 col-md-12".
I presume since you're using Bootstrap, you also won't need that css definition for .col-md-6 since Bootstrap should already have that defined for you.
What you actually need to do in JavaScript is remove the class "col-md-6".
if ($('.col-xs-12.col-md-6').length == 1) {
$('.col-xs-12.col-md-6').removeClass("col-md-6")
}
The .col-xs-12 applies to every screen size from xs up, and is overrode by .col-md-6 for screen size md and up. So you just stop the override from happening by removing the class.

How can I wrap to child by parent? (not component) Vue.js

When using Vue I am faced with something different than usual and cannot be overcome. The HTML code and JSFiddle links:
<div class="box align" id="app" onmouseover="fuchsia(id)" onmouseout='notFuchsia(id)'>
<div class="line align">
<div class="y-line align">
<p>get ur pointer yellow line</p>
</div>
</div>
</div>
<!--JS and CSS in JSFiddle links. Please look at -->
Case 1 (Pure JS + HTML + CSS):
https://jsfiddle.net/mcezgsa7/32/
Case 2 (Vue.js + HTML + CSS):
https://jsfiddle.net/pa2xmyju/12/
I want my code to work like the case 1, but I'm using Vue.js. So, I think I can explain the problem.
Well, I did a little bit of rewriting of your code. Notice that I removed your methods, added property hover to data object and added a css class active, which is added to the element when mouse is hovered over it.
https://jsfiddle.net/v0komLf9/

using document.querySelector with complex CSS selectors

In JavaScript I want to use document.querySelector to "grab" the last div (<div class="widget-footer">) in below HTML. However after many tries, I still can't figure out the correct CSS selector syntax to use.
The following code does not work:
document.querySelector (".skin-grid-widgets.ui-sortable.gridWidgetTemplatePositie.AgendaStandaard.disablesorting.hoogte-1-knoppen-0.breedte-1.widget-footer")
Here is the HTML I am working with
<div class="skin-grid enkeleKolom" id="Infobalk">
<div class="skin-grid-widgets ui-sortable">
<div class="gridWidgetTemplatePositie AgendaStandaard disablesorting hoogte-1-knoppen-0 breedte-1">
<div class="widget-header">
here comes the header text
</div>
<div class="widget-body">
some body text
</div>
<div class="widget-footer">
here comes the footer text
</div>
</div>
</div>
</div>
I've surfed everywhere to find example of complex CSS selectors used with querySelector, but to no avail. Any help would be really appreciated.
Your issue is you need a space in between each child element you are trying to select. If you do not have spaces in between your class selectors, by CSS specification, it will look for both classes on the same element.
Change your selector to look like the following:
var footer = document.querySelector(".skin-grid-widgets.ui-sortable .gridWidgetTemplatePositie.AgendaStandaard.disablesorting.hoogte-1-knoppen-0.breedte-1 .widget-footer");
footer.classList.add("highlight");
.highlight {
background-color: yellow;
}
<div class="skin-grid enkeleKolom" id="Infobalk">
<div class="skin-grid-widgets ui-sortable">
<div class="gridWidgetTemplatePositie AgendaStandaard disablesorting hoogte-1-knoppen-0 breedte-1">
<div class="widget-header">
here comes the header text
</div>
<div class="widget-body">
some body text
</div>
<div class="widget-footer">
here comes the footer text
</div>
</div>
</div>
</div>
try this:
<script>
document.querySelector (".skin-grid-widgets .gridWidgetTemplatePositie .widget-footer");
</script>
You don't need to add adjacent classes like "skin-grid-widgets ui-sortable" in querySelector, if you do so then query selector assumes that "skin-grid-widgets" is parent of "ui-sortable". Use just one of the classes at one DOM level.
The selector ain't complex, your thoughts are.
Listen to yourself, to the description you provide of what you want to select:
"grab" the last div in below HTML
Not grab the node with the class widget-footer inside of a node that has all these classes: gridWidgetTemplatePositie AgendaStandaard disablesorting hoogte-1-knoppen-0 breedte-1, inside a node ...
//a utility, because DRY.
//and because it's nicer to work with Arrays than with NodeLists or HTMLCollections.
function $$(selector, ctx=document){
return Array.from(ctx.querySelectorAll(selector));
}
//and the last div in this document:
var target = $$('div').pop();
or
"grab" <div class="widget-footer"> in below HTML
var target = document.querySelector("div.widget-footer");
or the combination: grab the last div.widget-footer in the HTML
var target = $$('div.widget-footer').pop();

Trying to traverse the DOM so unique video will play when certain div is clicked

So, I have a requirement for dynamically generated content blocks on a page. These blocks have a thumbnail and when it is clicked, it should open a modal, and display an unique overlay window, as well as as the unique associated video.
I am trying to write some generic JavaScript that will traverse the DOM tree properly, so that when any particular thumbnail is clicked, a modal, the associated overlay, and the associated video will open.
Here is an example of what I have now (there are many of these, dynamically added):
<div class="block">
<div class="thumbnail">
//Thumbnail image
</div>
<p>Video Description</p>
<div class="window hide">
<div class="video hide">
//Video content
</div>
</div>
</div>
<div id="modal" class="hide"></div>
and after attempting to do a bunch of different things, I ended up trying to do something like this for the JavaScript, which doesn't work:
$(".thumbnail").on("click",function(){
$("#modal").removeClass("hide").addClass("show");
$(this).closest(".window").removeClass("hide").addClass("show");
$(this).closest(".video").removeClass("hide").addClass("show");
});
CSS is very basic:
.hide { display: none; }
.show { display: block; }
Trying to make the click function generic as possible so it would work on any .thumbnail that was clicked. I've also interchanged find(".window") and children(".window") but nothing happens. Any ideas on what I'm doing wrong? Thanks!
Depending on what you actually want your classes to be, I'd use this code:
$(".thumbnail").on("click", function () {
var $block = $(this).closest(".block");
$block.find(".window, .video").add("#modal").removeClass("hide").addClass("show");
});
DEMO: http://jsfiddle.net/gLMSF/ (using different, yet similar code)
It actually finds the right elements, based on the clicked .thumbnail. It finds its containing .block element, then looks at its descendants to find the .window and .video elements.
If you actually want to include . in your attributes, you need to escape them for jQuery selection.
As for styling, you should probably just have the styling be display: block; by default, and then toggle the hide class. It's less work, and makes more sense logically.
You have a huge issue with your class names in HTML:
<div class=".block">
it should be
<div class="block">
Your modal is the only one that has the class properly named. Your DOM traversals will not work because they are looking for "block" but it's called ".block"
So fix it all to this and you should find more success:
<div class="block">
<div class="thumbnail">
//Thumbnail image
</div>
<p>Video Description</p>
<div class="window hide">
<div class="video hide">
//Video content
</div>
</div>
</div>
<div id="modal" class="hide"></div>
Your code won't work because your selectors have periods (.) in your classes if that's actually what you want, you should try it like this:
$(".\\.thumbnail").on("click",function(){
$("#modal").removeClass("hide").addClass("show");
$(this).closest("\\.window").removeClass("hide").addClass("show");
$(this).closest("\\.video").removeClass("hide").addClass("show");
});
Otherwise just try removing the periods from the classes...
Also, you're using .closest() incorrectly, as it looks up through ancestors in the DOM tree...
You should change your code to:
$(".\\.thumbnail").on("click",function(){
$(this).next("\\.window").children(".video")
.addBack().add("#modal").removeClass("hide").addClass("show");
});

Categories