Angular: Order html elements depending on scope varaible - html

I have two divs that I want to show on the page. The order of the two divs depends on the value of a variable on the scope.
The trivial way of doing this is by repeating the divs code twice in the page, each time in a different order:
<div class="option 1" ng-if="value">
<div class="div 1">
<p>"this is the content for div 1"</p>
</div>
<div class="div 2">
<p>"this is the content for div 2"</p>
</div>
</div>
<div class="option 2" ng-if="!value">
<div class="div 2">
<p>"this is the content for div 2"</p>
</div>
<div class="div 1">
<p>"this is the content for div 1"</p>
</div>
</div>
Is there another way to do this, without repeating the code?

If you do not support IE9 I guess you can use the flexbox order CSS property with a conditional class.
<div class="main">
<div ng-class="{after: !value}">this is the content for div 1</div>
<div class="fixed">this is the content for div 2</div>
</div>
And the CSS:
.main { display: flex; flex-direction: column; }
.fixed { order: 2; }
.after { order: 3; }
See the flexbox order in action: https://jsfiddle.net/a6eaov63/2/

UPDATE: You can move each <div> to external file and include it in proper order depending on value.
<ng-include src="value ? 'div1.html' : 'div2.html'"></ng-include>
<ng-include src="value ? 'div2.html' : 'div1.html'"></ng-include>

(function(angular) {
'use strict';
angular.module('orderDivs', [])
.controller('orderController', ['$scope', function($scope) {
//$scope.variable = true; //uncomment this line to reverse the div ..
$scope.divList = [{'div':'option 1','condition':'true', 'content':'THIS IS DIV 1111'},{'div':'option 2','condition':'false', 'content':'THIS IS DIV 2222'}]
if ($scope.variable){
$scope.divList = $scope.divList.reverse();
}
$scope.changeOrder = function(){
$scope.divList = $scope.divList.reverse();
}
}]);
})(window.angular);
<!-- in views -->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.1/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="orderDivs">
<div ng-controller="orderController">
<input type="checkbox" ng-click="changeOrder()" ng-model="variable"/>
<div ng-repeat="opt in divList">
<div class="option" ng-model="opt.div" ng-if="opt.condition">
<div>
{{opt.content}}
</div>
</div>
</div>
</div>
</body>
</html>

Related

JQuery for multiple div id's that are the same

I have multiple divs with id='title'.
When that div is hovered over I want a hidden div with id="source" to appear.
I am using the following code but only the first div with id='title' on the page works.
<!-- Show Source / Date on mouse hover -->
<script>
$(document).ready(function(){
$("#title").mouseenter(function(){
$("#source").fadeIn( 200 );
});
$("#title").mouseleave(function(){
$("#source").fadeOut( 200 );
});
});
</script>
HTML Example:
<div id="title" class="col-md-3">
<div id="source" style="display:none">Hidden Text</div>
</div>
<div id="title" class="col-md-3">
<div id="source" style="display:none">Hidden Text</div>
</div>
<div id="title" class="col-md-3">
<div id="source" style="display:none">Hidden Text</div>
</div>
Use classes instead of IDs
use .find() to search for descendants of an element
jQuery(function($) { // DOM ready and $ alias in scope
$(".title").on({
mouseenter() {
$(this).find(".source").fadeIn(200);
},
mouseleave() {
$(this).find(".source").fadeOut(200);
}
});
});
.title {
display: flex;
}
/* Utility classe */
.u-none {
display: none;
}
<div class="title col-md-3">
TITLE 1
<div class="source u-none">Visible Text</div>
</div>
<div class="title col-md-3">
TITLE 2
<div class="source u-none">Hidden Text</div>
</div>
<div class="title col-md-3">
TITLE 3
<div class="source u-none">Hidden Text</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
Hello Δce Let's start by modifying the source code to use classes for you to pick. This helps us describe the functionality and allow the ID's to serve their purpose.
we'll take your
<div class="col-md-3 show-source-on-hover">
<div class="source" style="display:none">Hidden Text</div>
</div>
<div class="col-md-3 show-source-on-hover">
<div class="source" style="display:none">Hidden Text</div>
</div>
<div class="col-md-3 show-source-on-hover">
<div class="source" style="display:none">Hidden Text</div>
</div>
and we can update the jQuery code
<script>
$(function() {
$(".show-source-on-hover")
.mouseenter(function() {
$(this).find('.source').fadeIn( 200 );
})
.mouseleave(function() {
$(this).find('.source').fadeOut( 200 );
});
});
</script>
You can see here there's the use of this wrapped in the $() jquery object function. and the new use of .find to get get the correct source class.
For a working demo please see the following link: https://codepen.io/jessycormier/pen/GRmaaEb
Note: your use of ID's should change and always try and be unique like others have suggested. MDN (Mozilla Developer Network) has some great documentation on the standards of HTML, CSS, and JavaScript which can help give you.
Also, in the demo I've given your column divs some default size otherwise there is nothing to trigger the mouse over events. Good luck and happy coding 🚀
IDs are IDENTIFIERS. What that means is that there can only be one per document. Classes are not unique, so you can use them.
✅ $(".title")
❌ $("#title")

bulma level inside box overflowing

I am having trouble trying to have a responsive grid of 3 boxes with some aligned content inside using the library Bulma. I would like to make it work still maintaining the level inside a box if possible.
Any help would be appreciated.
This is the result I expect:
But when decreasing the width, it breaks:
This is the code I am using:
<div className="columns sub">
{this.props.options.map(option => (
<div className="column is-one-third" key={option.id}>
<div
name={option.id}
className={
`box ` +
(this.props.optionToBeChosen === option.id
? "box-is-active"
: "")
}
onClick={() => this.props.onClick(option.id)}
>
<div className="level is-mobile">
<div className="level-item level-left">
<div>
<p className="box-text-title">{option.title}</p>
<p className="box-text-small">{option.description}</p>
<p className="box-text-small">{option.description2}</p>
</div>
</div>
<div className="level-item level-right has-text-right">
<div>
<p className="box-text-demo">{option.cta}</p>
</div>
</div>
</div>
</div>
</div>
))}
</div>
The Bulma levels are explicitly told not to shrink
.level-left, .level-right {
flex-basis: auto;
flex-grow: 0;
flex-shrink: 0;
}
You'll have to override that to get the levels to not break out of the .box elements.
Rather than overriding ALL level items, I suggest you add a custom class to those levels that you want to be able to shrink.
Something like
<div class="level is-mobile level-is-shrinkable">
Level items here...
</div>
<style>
.level-is-shrinkable .level-left,
.level-is-shrinkable .level-right {
flex-shrink: 1;
}
</style>
In my case, I had to add a third styling condition for centered level-item elements:
.level-is-shrinkable .level-left,
.level-is-shrinkable .level-item,
.level-is-shrinkable .level-right {
flex-shrink: 1;
}
Many thanks to just-a-web-designer for his|her answer.

Is there a way to dynamically wrap two elements into a div IF they exist?

I have an Angular application that renders spans based on whether they're needed or not (many ng-if's). I need to wrap these spans in a div based on their content/class names.
So, for example:
<div class="1"></div>
<div class="2"></div>
<div class="3"></div>
I don't want to do anything. But with
<div class="1"></div>
<div class="2"></div>
<div class="3"></div>
<div class="4"></div>
I DO want to wrap these 4 divs in a parent div <div class="parent"></div>, but only if the four appear one after the other. Is there a way to do this in CSS? Can I just use a combo of selectors to manipulate the four elements if they appear consecutively?
so you cant do this using just css and html, like the comments above, you need to use some form of javascript to manipulate the dom. heres an example using jQuery. hope it helps!
$(document).ready(function() {
$('.wrapme').each(function() {
var myElement = $(this);
var next1 = $(this).next();
var next2 = $(this).next().next();
var next3 = $(this).next().next().next();
if (next1.hasClass('wrapme') && next2.hasClass('wrapme') && next3.hasClass('wrapme')) {
var html = '<div class="parent"></div>';
next3.after(html);
var parent = next3.next('.parent')
parent.append(myElement);
parent.append(next1);
parent.append(next2);
parent.append(next3);
}
});
});
.parent {
background-color:lightgray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapme">1</div>
<div class="wrapme">2</div>
<div class="wrapme">3</div>
<span>BREAKKKKKK</span>
<div class="wrapme">1</div>
<div class="wrapme">2</div>
<div class="wrapme">3</div>
<div class="wrapme">4</div>
<span>BREAKKKKKK</span>
<div class="wrapme">1</div>
<div class="wrapme">2<div>
<span>BREAKKKKKK</span>
<div class="wrapme">1</div>
<div class="wrapme">2</div>
<div class="wrapme">3</div>
<div class="wrapme">4</div>
<span>BREAKKKKKK</span>
<span>BREAKKKKKK</span>
<div class="wrapme">1</div>
<div class="wrapme">2</div>
hey hey
<div class="wrapme">3</div>
<div class="wrapme">4</div>
<span>BREAKKKKKK</span>

showing different div tag for individual img links when clicked

I have 4 image links that when clicked need to show a specific DIV. Then when another of the remaining 3 images is clicked, its DIV shows whilst hiding the last DIV. I have tried several different ways and can't seem to get it going the way I need. The four DIVs occupy the same space on the page. Can anyone help?
Here is how I have set up the HTML so far:
<div id="content">
<div id="info">
<img src="../Images/yellowbutton.png" class="infolink" />
<img src="../Images/redbutton.png" class="infolink"/>
<img src="../Images/greenbutton.png" class="infolink" />
<img src="../Images/bluebutton.png" class="infolink"/>
<div id="level0">This is the home page for the levels</div>
<div id="level1">this is the information on level 1</div>
<div id="level2">this is the information on level 2</div>
<div id="level3">this is the information on level 3</div>
<div id="level4">this is the information on level 4</div>
</div>
</div>
You can change the visibility of the divs using css and javascript
The following code performs the desired behaviour, (if I understood it correctly :-)):
<html>
<head>
<script>
function selectItem(item) {
var availableItems = document.getElementsByClassName("itemToShow");
for (var i=0;i<availableItems.length;i++) {
if (availableItems[i].id == item) {
availableItems[i].style.display = "block";
} else {
availableItems[i].style.display = "none";
}
}
}
</script>
</head>
<body>
<div id="content">
<div id="info">
<img src="../Images/yellowbutton.png" class="infolink" />
<img src="../Images/redbutton.png" class="infolink"/>
<img src="../Images/greenbutton.png" class="infolink" />
<img src="../Images/bluebutton.png" class="infolink"/>
<div id="level0">This is the home page for the levels</div>
<div id="level1" class="itemToShow">this is the information on level 1</div>
<div id="level2" style="display:none;" class="itemToShow">this is the information on level 2</div>
<div id="level3" style="display:none;" class="itemToShow">this is the information on level 3</div>
<div id="level4" style="display:none;" class="itemToShow">this is the information on level 4</div>
</div>
</div>
</html>
The basic idea is call a javascript function when the anchor is clicked, passing the id of the DIV that must be shown.
Then, on the javascript funcion, select the DIVs by css class (itemToShow). For each DIV selected, set style="display:block" if its id is equal to the informed one or style="display:none" otherwise.

smooth scroll with mousewheel to next or previous div

I'm trying to get a javascript on my site so when a person scrolls on the website, it automatically scrolls to the next or previous Div with a certain class. I'm working with smoothscroll and scrollto. I also found two codes that I'm trying to combine. But I don't seem to understand the whole scripts...
The first script is from http://webdesignerwall.com/tutorials/scrollto-posts-with-jquery. This script makes it possible to navigate between DIV's (with a certain class) by pressing next or previous.
The second script is from How to enforce a "smooth scrolling" rule for mousewheel, jQuery? (last post) and makes it possible to make the website scroll (smooth) down or up for a certain amount of pixels when scrolling.
I wanted to combine these two but it's not really straight forward for me :/
It would be nice if someone could point me how to do this. Thanks
Best regards,
Billy Beach
Dear lalibi,
Thanks for your answer. I tried your code, but don't seem to get it work. Here is the code I used:
<head>
<script type="text/javascript" src="Box/jquery.js"></script>
<SCRIPT src="Box/jquery.min.js"></SCRIPT>
<SCRIPT src="Box/jquery.scrollTo-1.4.2-min.js"></SCRIPT>
<SCRIPT src="Box/jquery.localscroll-1.2.7-min.js"></SCRIPT>
<script type="text/javascript" src="Box/jquery.mousewheel.min.js"></script>
<style type="text/css">
<!--
div {
border: 1px solid black;
height: 50px;
}
div.current {
background-color: orange;
}
-->
</style>
<script type="text/javascript">
var current
$(function() {
$('body').mousewheel(function(event, delta) {
var $current = $('div.current');
console.log(delta);
console.log($current);
if (delta > 0) {
$prev = $current.prev();
if ($prev.length) {
$('body').scrollTo($prev, 100);
$current.removeClass('current');
$prev.addClass('current');
}
} else {
$next = $current.next();
if ($next.length) {
$('body').scrollTo($next, 100);
$current.removeClass('current');
$next.addClass('current');
}
}
event.preventDefault();
});
});
</script>
</head>
<body>
<div class="current" id="div">1</div>
<div id="div">2</div>
<div id="div">3</div>
<div id="div">4</div>
<div id="div">5</div>
<div id="div">6</div>
<div id="div">7</div>
<div id="div">8</div>
<div id="div">9</div>
<div id="div">10</div>
<div id="div">11</div>
<div id="div">12</div>
<div id="div">13</div>
<div id="div">14</div>
<div id="div">15</div>
<div id="div">16</div>
<div id="div">17</div>
<div id="div">18</div>
<div id="div">19</div>
<div id="div">20</div>
<div id="div">21</div>
<div id="div">22</div>
<div id="div">23</div>
<div id="div">24</div>
<div id="div">25</div>
<div id="div">26</div>
<div class="current" id="div">27</div>
<div id="div">28</div>
<div id="div">29</div>
<div id="div">30</div>
<div id="div">31</div>
<div id="div">32</div>
<div id="div">33</div>
<div id="div">34</div>
<div id="div">35</div>
<div id="div">36</div>
<div id="div">37</div>
<div id="div">38</div>
<div id="div">39</div>
<div id="div">40</div>
<div id="div">41</div>
<div id="div">42</div>
<div id="div">43</div>
<div id="div">44</div>
<div id="div">45</div>
<div id="div">46</div>
<div id="div">47</div>
<div id="div">48</div>
<div id="div">49</div>
<div id="div">50</div>
<div id="div">51</div>
<div id="div">52</div>
<div id="div">53</div>
<div id="div">54</div>
<div id="div">55</div>
<div id="div">56</div>
<div class="current" id="div">57</div>
</body>
</html>
EDIT: I tweaked the fiddle a little bit. One of the two external scripts was using http: and since the link (before the edit) used https:, Chrome blocked it unless you pressed the little shield icon. I also updated to latest version.
This seems to work fine: http://jsfiddle.net/9Amdx/1707/
var current;
$(function() {
$('body').mousewheel(function(event, delta) {
var $current = $('div.current');
console.log(delta);
console.log($current);
if (delta > 0) {
$prev = $current.prev();
if ($prev.length) {
$('body').scrollTo($prev, 100);
$current.removeClass('current');
$prev.addClass('current');
}
} else {
$next = $current.next();
if ($next.length) {
$('body').scrollTo($next, 100);
$current.removeClass('current');
$next.addClass('current');
}
}
event.preventDefault();
});
});