AngularJS: Update DOM after hidden panel is shown? - javascript

I'm using the AngularJS range slider directive from prajwalkman. The slider works fine while it is visible, but when it is embedded in a hidden options screen using ng-show, the DOM manipulation bits dont work due to the use of "offsetWidth". I am using these sliders in a panel that is by default hidden at screen launch, but still want to initialize the sliders so the pointers are at the correct positions and the colored selection bar is visible when the user toggles the panel.
wholeBar = element.children()[0].offsetWidth;
When the element is hidden offsetWidth is 0 and the calculations dont work correctly. I think what I need to do is show the panel, then run the DOM update code but I havent been able to figure out how to schedule it to run after the current apply/digest cycle completes.
I created a fiddle that is vastly simplified to show what I mean - when the DIV is shown the code works because offsetWidth is not 0, but when it is hidden the selection bar doesn't expand to 50%.

As comments mentioned, a simple solution would be to use a class to just move the slider out of view, effectively 'hiding' it.
Updated fiddle
I accomplished this by making the hide/show button toggle a var
<button ng-init="move=false" ng-click="move=!move">Show/Hide DIV</button>
creating a class to move the element off the screen
.move {
transform: translate(-9999px, 0);
}
and using ng-class to apply the class when we toggle the button
<div ng-class="{move: move}" my-component>
<h3>This is my hidden DIV</h3>
<div style="height:20px; width:100%; background-color:red; zindex=0; ">
<div style="height:35px; width:15px; background-color:blue; zindex=1; position:absolute"></div>
</div>
</div>

Related

How to smoothly move the background when toggle between multiple options in Vanilla JS

I have a navigation option. One of the option will always be active by default and will have a background color like this:
When I click on any other option, the background color should animate smoothly and move from previous option to the newly clicked option. I tried to search it but couldn't figure out the correct name of this effect. It should act like a switch but I want to build it for custom use with text written on the handlebar, which isn't possible in switch.
How do I achieve it using Vanilla JS.
Here is my JS fiddle link for what I have done: https://jsfiddle.net/1ex3y94g/1/
Code I use to toggle the background color:
function change(id1,id2) {
document.getElementById(id2).style.background="lightgreen";
document.getElementById(id1).style.background="red";
}
<div class="wrapper">
<div class="bar1" id="bar1" onclick="change('bar1','bar2')">
Option1
</div>
<div class="bar2" id="bar2" onclick="change('bar2','bar1')">
Option2
</div>
</div>
Like this: https://jsfiddle.net/72c5k4ub/19/
The two options are not animated at all. Create a "handle" div which translates from left to right depending on which side has been pressed. This handle just has the background color and no content. It lays behind the actual options (which do not have a background color). The handle does not impact layout (since it is display absolute). For the animation use transforms (for best performance. Not margin) with css animations (transform: translateX(100%)). 100% referes to the width of this element.

slimScroll hidden on page load

I'm developing an application that uses the slimScroll jQuery plugin (http://rocha.la/jQuery-slimScroll) to essentially add a nice overflow to div containers.
Everything works apart from a small, almost insignificant annoyance: when the page is loaded for the first time, the plugin is initiated on the div and automatically displays the scrollbar. After hovering in then out of the container, the scrollbar is hidden.
Is there any way to make the scrollbar start in a hidden state on page load?
The developer was asked this a number of times but I can't find a solution on the website.
Any help would be much appreciated.
This code work for multiple elements that have same classes.
JS:
$(document).ready(function() {
$('.inner').slimScroll({
//your options
opacity: 0
}).mouseover(function() {
$(this).next('.slimScrollBar').css('opacity', 0.4);
});
});
for such HTML code like this.
<div id='box'>
<div class='inner'>
some paragraph
</div>
</div>
The result show here: https://jsfiddle.net/ATR616/4Lnr3fju/2/

Button resizable jquery magic margin

I have created a button using the <button></button> tags. I applied .resizable() jQuery and it looks fine. But when I inspect element the button, it occupies the whole div with its margin-right though the margin-right is set to 0px. I've looked in the css and overrode some parts to fix it but I didn't succeed. What's causing it?
It is very similar to this: http://jsfiddle.net/nagwW/13/
If you inspect element the button, it occupies the whole row but how could I just limit the width with respect to its real width?
If you are using jQuery UI resizable function then you have to place the button element inside the element being resized, because jQuery UI's default functionality adds a div with class name "ui-resizable-handle". The clickable resize handle that you see.
<div id="resizable" class="ui-widget-content">
<button>Resizable</button>
</div>
See this JS Fiddle that I changed from jQuery UI:
http://jsfiddle.net/truthreveller/mX7Ej/3/

Divs too wide when hiding/showing

I have two divs that contain two other divs each. One containing DIV's display is set to none. I have a button that toggles the containing DIVs so I can alternately hide/show the containing div and thus the two divs inside. The inside DIVs are set the 49% width, floated left/right. Problem I have is the fist time the visible DIV is hidden and the hidden one displayed the inside two divs are way too wide. If I resize the width of the browser just a tiny bit with my mouse they are the desired size and any time I toggle the visibility from here on out all is fine. If I reload the page it is wrong on the first toggle. Works the same in IE 10 and Chrome so don't think a browser issue.
The inner two divs both contain high charts that are generated and rendered to the inner divs I want them to be side by side and almost (99%) the width of my page.
Here is snipped of my DIVs to be hidden and shown that contain the inner DIVs with highcharts
<div id="highChartsNG" style="width:99%;display:none;">
<div id="FillRateHigh" style="border:2px solid black;width:49%;float:left;"></div>
<div id="WaitTimeHigh"style="border:2px solid black;width:49%;float:right;"></div>
</div>
<div id="LowChartsPEAK" style="width:99%">
<div id="FillRateLow" style="border:2px solid black;width:49%;float:left;"></div>
<div id="WaitTimeLow"style="border:2px solid black;width:49%;float:right;" ></div>
</div>
This is a snippet of the javascript function I call on a button click to toggle on/off on the display of two containing DIVs
document.getElementById("highChartsNG").style.display = "none";
document.getElementById("LowChartsPEAK").style.display = "block";
Fiddle showing problem, see comment of mine below on how to reproduce http://jsfiddle.net/rplace/UTTz4/1/
Okay, after hours of searching I finally found the problem (I think). I was determined to find the solution =).
The problem is multiple-fold.
The first problem was the display:none; property on the second chartcontainer. For some reason the widths calculated for the charts and their containers were incorrect for the hidden div. So I removed the property from the HTML, and instead hid it dynamically with document.getElementById("LowChartsPEAK").style.display = "none"; in the JS right after the chart rendering functions. If you do this, your SVG's will fit your containers already, although the last one has a slight shift.
Apparently HighChart doesn't like percentage-based parent containers. When you go to your updated fiddle , run the fiddle with both:
<div id="wrapper" style="width: 800px;">
<div id="wrapper" style="width: 100%;">
Open the console and check the results (container name - SVG width - container width). When the wrapper is given a pixel width, all container widths are equal (as it should be). Now check the wrapper with percentage width: your last SVG will be about 6 to 20 pixels smaller. The only solution I have found for eliminating that small shift in the last container, is that somewhere a top container must have a pixel-width.
EDIT: pt's and em's also work. It's only % that causes problems
If you are hiding DIV, you should be aware that browser won't calculate %-based widths with display:none. Then if browser won;t calculate DIV, then also Highcharts are not able to do it ;)
Check this FAQ - when showing chart update his size or call reflow().

Hide child <div>s as parent div shrinks?

I am trying to write a zoom in/out feature on a web app I am making using the jqueryUI slider.
I am having difficulty handling when my parent div shrinks too much, and cramps its child containers.
<div class="puck originator inline-block" style="width: 310.5px; left: 0px;">
<div class="conflicted inline-block originator">
<div class="right-number">I should stay</div>
<div class="left-number">I should stay</div>
<div class="middle-number">I Should disapper</div>
</div>
</div>
Here is the relevant section of code I have
http://jsfiddle.net/aQKwE/
Basically I have the parent div (class 'puck') that is being shrunk using a jquery slider. For this code I just used a text box, but same idea.
When I shrink that div, the containing divs stick around and are very garbled.
I want to be able to remove the middle child div when it becomes to cramped, leaving the left and right child divs to occupy all the space
Furthermore, if it becomes to cramped yet after that, I want to remove the right div, leaving only the left.
Finally I want to be able to remove all contents so that nothing more than the background of the parent shows.
Is there a way to do this easily, preferably through CSS? I don't want to write more javascript code to set 'display:none' on each child div, since it seems like some CSS rules should handle this.
Any ideas?
There's not really any logic built into CSS to handle something like this. You can set rules based on viewport size, but that won't help in this case.
I updated your jsfiddle with this code so you can test it and see what you think, but essentially I just added some checks in your javascript function to hide based on the width submitted.
var newwidth = $('#text').val();
$(".middle-number").show();
$(".right-number").show();
if (newwidth < 280) {
$(".middle-number").hide();
}
if (newwidth < 180) {
$(".right-number").hide();
}
$('.puck').css('width',newwidth);

Categories