How to switch position of div in directive - javascript

I have a directive that renders the following structure
In Div1 I have some content and in Div2 some other content. There is a splitter in the middle. I need a function to swap the div positions Div1 in Div2 position and vice versa. What as some good ways to do this in Angular directive ?
One way i can think of is using ng-switch, but will have to do some reputable stuff... any other good ways ? Some animation during switching would be cool.
No jQuery allowed. Following is the demo fiddle - http://jsfiddle.net/gauravsoni/z9gz1wgy/
Sample code:
angular.module("KendoDemos", [ "kendo.directives" ])
.controller("MyCtrl", function($scope){
$scope.orientation = "horizontal";
$scope.hello = "Hello from Controller!";
})
.directive('myDirective',function(){
return{
template:'<div kendo-splitter><div>1st pane</div><div>2nd pane</div></div>'
}
})
UPDATE:
I am using the following code to do the switching,
<button ng-click='toggle = !toggle'>Switch View</button>
<div ng-if="toggle">
<div>
Left side
</div>
<div>
right side
</div>
</div>
<div ng-if="!toggle">
<div>
right side
</div>
<div>
left side
</div>
</div>
So based on the toggle value appropriate div gets activated , only drawback here is i have to write the view 2 times.
Any suggestions ?

You can use flexbox and define an order for the elements. Then use angular to toggle a class on the container. You could also use floats or some other CSS technique to mess around with the order, but the idea is to use CSS for this.
See demo below.
http://codepen.io/jessegavin/pen/ZbWeNV
Template
<div ng-app="demo">
<columns></columns>
<script type="text/ng-template" id="columns.html">
<div>
<div class="columns">
<div class="column column-one">Col 1</div>
<div class="column column-two">Col 2</div>
</div>
<button ng-click="swap()">Swap</button>
</div>
</script>
</div>
CSS
.columns {
display: flex;
}
.column-one { order: 1; }
.column-two { order: 2; }
.swapped {
.column-one { order: 2; }
.column-two { order: 1; }
}
.column {
width: 50%;
height: 200px;
border: solid 1px red;
}
Directive
angular.module("demo", [])
.directive("columns", function() {
return {
templateUrl: "columns.html",
link: function(scope, element, attrs) {
scope.swap = function() {
element.toggleClass("swapped");
}
}
}
})

You could use angular ui sortable on this. You can easily drag and sort them. You can place handlers so only portion of div is able to drag the divs.

There are multiple ways to do this, ones cleaner than others obviously.
If there are no other factors that can affect the method, that you use to resolve this problem and If the task is as simple as just switch positions, I guess you can define the container div (the one that contains both smaller divs) as flexbox with
display:flex
and
flex-flow: row nowrap,
and then on hover, or on scroll, or toggle, or whatever it is... change
flex-flow to flex-flow: row-reverse nowrap
If you need a bit of animation effect you can add transition: .5 to container div
Sorry if I'm not clear :(

Related

How to use css bootstrap list-group with affix to create a sticky menu in a column?

I am trying to create a sticky menu using CSS Bootstrap affix and list-group menu.
I manage to get most of it to work except for when the user scrolls down.
When the user scrolls down, the menu seems to take the entire with of the page.
I tried to set it up via data attributes
using something like this
<div class="container">
<div class="row">
<div class="col-md-3" id="leftCol">
<div data-spy="affix">
<div class="list-group list-group-root well">
<a class="list-group-item" href="#introduction">Introduction</a>
<a class="list-group-item" href="#features">Features</a>
<a class="list-group-item" href="#dependencies">Dependencies</a>
</div>
</div>
</div>
<div class="col-md-9" id="mainCol">
Some long text for the body along with some tables.
</div>
</div>
</div>
But the data attribute did not make the menu stick! it just kept it on the top.
So I tried to use JS to get the job done like this
$(function(){
$('#leftCol').affix({
offset: {
top: 100,
bottom: function () {
return (this.bottom = $('.footer').outerHeight(true))
}
}
});
});
I created jsFiddle to show you the current behavior.
How can I fix this affix so when the user scrolls down the menu maintain the same shape?
First of all, you should use either data-attributes or JS.
I updated your jsFiddle. The position of id="leftCol" was changed:
<div class="col-md-3" >
<div id="leftCol">
...
</div>
</div>
and style was added:
#leftCol {
width: 220px;
}
Also, you should add media queries to remove affix from mobile view.
As an "unacceptable" workaround, I set a max width of the menu to 250px like so
.list-group.list-group-root {
padding: 0;
max-width: 250px;
}
I am not sure how to get it to work without adding a max-with the max with should be defined by the parent. In this case class="col-md-3"
UPDATED
javascript to the rescue!
I added the following JS code to solve this problem once an for all.
It basically resize the menu everytime affix.bs.affix event is fired
$(document).on('affix.bs.affix', '#docs-menu', function() {
$(this).width($(this).width());
});
From the docs
affix.bs.affix => This event fires immediately before the element has
been affixed.
Ok I believe I got most of the code working like you want it to. The main changes I made were adding this CSS:
#leftCol {
display: block;
height: auto;
padding: 0;
width: 100%;
}
.navbar-fixed-top-again {
position: static;
top: 60px;
z-index:1031;
}
.navbar-inner {
background: red;
padding: 5px;
}
.affix {
position: fixed !important;
}
and I changed up some of the structure on your HTML:
<div class="container body-content">
<div>made up content to allow the navigation to scroll more before it becomes sticky. This height will need to be set in the data-offset-top which is in the leftCol DIV just below this content. The same will apply if you need to set it for a footer offset.</div>
<!-- new nav section -->
<div class="col-md-3 navbar-fixed-top-again" id="leftCol" data-spy="affix" data-offset-top="80">
<div class="navbar-inner">
<div class="list-group list-group-root well">
*the rest of your code*
</div>
</div>
</div>
</div>
The main problem now is having a sticky navigation menu with variable height. If you notice when you scroll your reading content underneath jumps up and gets hidden. It seems that it is possible to fix this using JavaScript (link to SO question).
Heres the link to your updated Fiddle. Hope that helps.

How hide div inside div when inner div mode left by jquery animate:left function?

I have html:
<div style='width:300px; height:40px; float:left;' class='outerDiv'>
<div style='width:200px; height:40px; float:right;' class='innerDiv'>
Some text
</div>
</div>
I try to make small move div.innerDiv by:
$('.innerDiv').animate({ left: '+=200px' });
Basic idea - when div.innerDiv move to border of div.outerDiv, div.outerDiv should hide part of div.innerDiv. I stuck on css styles on div's.
see here : jsfiddle
you need to set a position ( relative,absolute,fixed ) so the css left:200px can work.
css :
.outerDiv {
overflow:hidden;
}
.innerDiv {
position:relative;
}
jq :
$('.innerDiv').animate({ left: '+=200px' });
let me know if this was what you were looking for.
If i understand you correctly, you want to hide the outer div but show the inner div.
You should not hide parent div, because if you hide parent div, child will be hidden.
You can change the background color of the outer div.
js fiddle link
$('.innerDiv').animate({left:'200px'}, {
complete: function () {
$('.outerDiv').addClass('hide');
}
}
);

Last created DIV to be above other DIVs

I'm creating DIVs dynamically and appending them to a particular DIV.
My question is how do I always make the last created DIV to be above other DIVs within the appended (its parent) DIV?
So basically I want the last created DIV to be on the top level of the other.
DIV 4 - [created at 4:32pm]
DIV 3 - [created at 4:29pm]
DIV 2 - [created at 4:27pm]
DIV 1 - [created at 4:26pm]
the dynamic DIV css:
.dynamicDIV{
width:100%;
position: relative;
}
the append DIV css:
.parentDiv{
width: 100%;
margin-top: 5px;
}
I'm not referring to the z-index. I want to position it above the others.
var parentElement;
var newFirstElement;
parentElement.insertBefore(newFirstElement, parentElement.firstChild);
As I pointed out in my comment, .prepend() can be used here:
$('.parentDiv').prepend('<div class="dynamicDIV">New Div</div>');
but there is a second possibilty:
$('<div />').addClass('dynamicDIV').text('New Div').prependTo('.parentDiv');
This solution is a bit more maintainable.
Demo
Reference
.prepend()
.prependTo()
Use .prepend() on whatever element you want to be preceeded with the new one:
http://api.jquery.com/prepend/
When a DIV is at position: absolute, the last sibling in the DOM is over the others. This doesn't depend on the time you inserted it.
But you can override this behavior by using z-index: 1.
Look at this HTML code:
<style>
div.container > div {position: absolute; z-index: 0}
div#C {z:index: 7}
</style>
<div class="container">
<div id="A">A</div>
<div id="B">B</div>
<div id="C">C</div>
<div id="D">D</div>
</div>
This code will display C hidding D, hidding B, hidding A.
CSS with display:flex and flex-direction:column-reverse; can help you:
body {/* parent container of div to shw in a reverse flow*/
display:flex;
flex-direction:column-reverse; /* row-reverse if on line*/
}
div {
width:50%;
border:solid;
margin:auto;
}
div:last-of-type:after {
content:'last in document !';
color:red;
}
<div> 1 </div>
<div> 2 </div>
<div> 3 </div>
<div> 4 </div>
anyway, in the DOM or for CSS selector, last will be last. reverse order only shows at screen.

Prevent parent div from resizing when child div resizes

What I want to accomplish is after calling jQuery $().hide(), the animation to hide a child div on a current page and then show a new div in its place.
When I call the .hide(), the parent div resizes and I do not want that.
The parent has two divs in it, a text filled div, and the div in question so when I call the hide, only the text-only div remains. I want the height to remain the same because the new content is going to be the same height.
Here is what I have:
<div class="adminContent"> //Wrapper div, this should not change in height of 668px
<div class="adminTitle"> // Text only div, remains after .hide is called
Admin > Manage Class Roster
</div>
<div class="resetBody" id="manageClassBody1"> // Div that is being hidden/replaced
... // div contents
</div>
CSS
.adminContent {
background: #F7F7F7;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
min-height: 668px;
}
How should I have it so that its height is static after I hide the child div? Thanks!
EDIT: I want to do an in place swap of the two divs with an animation to switch between the two. I looked at the replaceWith() provided by jQuery but I'm not sure how to use it for my needs.
I would suggest using the animation features of JQuery to accomplish your task.
I created a sample JSBin for you.
Example:
$(document).on("click", "#togglebtn", function() {
var divs = $('.resetBody, .resetBody2');
var hiddenDiv = divs.filter(":not(:visible)");
var visibleDiv = divs.filter(":visible");
visibleDiv.fadeToggle({
complete: function() {
hiddenDiv.fadeToggle();
}
});
});
.adminContent {
background-color: lightgreen;
padding: 10px;
}
.resetBody {
background-color: #880000
}
.resetBody2 {
background-color: lightblue
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="adminContent">//Wrapper div, this should not change in height of 668px
<div class="adminTitle">much text wow! much text wow! much text wow! much text wow! much text wow!
Admin > Manage Class Roster
</div>
<div class="resetBody">Div 1
<br/>Div 1
<br/>Div 1
<br/>Div 1
<br/>Div 1
<br/>Div 1
<br/>
</div>
<div class="resetBody2" style="display:none">Div 2 is taller
<br/>Div 2
<br/>Div 2
<br/>Div 2
<br/>Div 2
<br/>Div 2
<br/>Div 2
<br/>
</div>
</div>
<div style="margin-top:10px;">
<button id="togglebtn">Toggle</button>
</div>

Horizontal centering of a div without knowing the div width, possible?

I'm currently building a popup box script using css/jquery and i can't seem to get the div centered on the screen on all cases. It it possible to center it without knowing the div width?
Instead of posting all the code here i put up a live example at http://goo.gl/N45cp
Any kind of help is much appreciated!
Best Regards
John
<div id="wrapper">
<div id="child"></div>
</div>
If the position of the #child is not absolute, you can set left and right margins to auto:
#child {
margin: 0 auto;
}
Or if the position is absolute you can try the following:
$("#child").css("left", function(){
return ($("#wrapper").width() - $(this).width()) / 2;
});
You can achieve this with pure CSS if you have a containing div:
HTML
​<div id="outer">
<div id="inner">some content here</div>
</div>
CSS
​body, html, div#outer { height:100%; }
div#outer { text-align:center; }
div#inner { display:inline-block; }
http://jsfiddle.net/NjZbW/
​​​​​​​​​​​​​​

Categories

Resources