Does anyone else have trouble with angular and range sliders? - angularjs

Seems to be an impossible task to find a range slider that works well with ng-repeat and can be displayed vertically. Anyone have ideas about what to try next?
I'm trying to make a took where you can manually control the brightness of a sign at each hour of the day. The current idea is to stack 24 vertical range sliders next to each other where each one controls the brightness for that hour and a 25th slider that is a master control that adjusts all 24 other sliders simultaneously.
The closest I came was with angular-rangeslider but it turned out to be incredibly buggy when used with ng-repeat. I suppose I could manually write out all 25 of them but I'd rather not.
The other idea is to use jqPlot because you can drag the datapoints. (It seems to be the only chart library where you can drag the datapoints too (please correct me if I'm wrong))

How about an HTML5 range input?
HTML:
<input type="range"
orient="vertical"
ng-repeat="slider in sliders"
ng-model="slider.val" />
CSS (necessary to make it vertical in some browsers):
input[type=range][orient=vertical] {
writing-mode: bt-lr; /* IE */
-webkit-appearance: slider-vertical; /* Webkit */
width: 20px;
height: 200px;
}
Works fine with Angular bindings. Here's a Plunker.
Supported browsers look to be IE10+ and most others.

I made an exemple in plunker of how i would use this
I create an array of empty object.
$scope.sliders = [];
for(var i=0; i<5; i++){
$scope.sliders.push({});
}
I display it using a ng-repeat using HTML range inputs
<span ng-repeat="slider in sliders track by $index">
<input ng-init="slider.value = 0" type="range" ng-model="slider.value">
{{slider.value}}
</span>
Maybe not elegant but i just use the rotation from CSS to make it vertical.
Note that you'll have to define a better css selector than "input"
input {
-ms-transform: rotate(-90deg); /* IE 9 */
-webkit-transform: rotate(-90deg); /* Chrome, Safari, Opera */
transform: rotate(-90deg);
width:70px;
height:100px;
}
Hope it helped

Related

Prevent column-count breaking inner elements

I am trying to create a responsive image wrap gallery. Each image will have a header. I distribute them using column-count of webkit.
The problem is this: I've specified a container to be "relative". Inside that container, I have an "absolute" header followed by an image. What seems to be happening in some values of column-count is that the header is going to another column and the image in the next. I need them both to be together at all times and I'm surprised why the absolute within relative container is not doing that.
A codepen for reference: http://codepen.io/pliablepixels/full/YwWLzy/
The core image gallery code is:(SO insists I include a code fragment when posting a codepen link, so here goes)
<div style="-webkit-column-count:{{ cols }};-webkit-column-gap:0px;line-height:0px;">
<span ng-repeat="image in images">
<div style="position:relative">
<div class="my_header">Header</div>
<img class="scaled_image" src={{ image.src }} />
</div>
</span>
</div>
Please change the column values and note the header behavior.
How does one solve this? (Note I must use an img tag - can't use background-image)
thanks
Columns
To protect elements from breaking and keep them entirely in a column you can add these properties:
.element {
-webkit-column-break-inside: avoid; /* Chrome, Safari, Opera */
page-break-inside: avoid; /* Firefox */
break-inside: avoid; /* IE 10+ */
}
Your fixed example http://codepen.io/anon/pen/rxMWxa
Header
Such behaviour occurs because you've added line-height:0px to your container div. So you can just return header's line-height value to normal. Fixed that in codepen.
Using line-height sometimes can make headache. Try to use padding like below:
.my_header {
background-color: red;
padding: 2px 4px;
line-height: normal;
}

Creating an animated 1-3 column layout using Angular

Here's the situation:
I'm building a page for an application which consists of a navbar, a footer and a 3 column body.
Initially, only one column should be shown. This first column will be filled with clickable divs (let's call them cards). When one of these cards is clicked, the second column should slide open from the side, revealing more information about the clicked card.
The same workflow applies to the second column: the details displayed in the second column contains its own cards, which - when clicked - open up the third column with more details about the card in the second column.
The second and third column can also be closed, while the first can not.
I'm loading the column information using Angular, and so far I've had no real struggle implementing the 1-3 column layout.
But when I try to make this work smooth - e.g. using animations - things get weird. I don't really know how I can animate the (dis)appearance of one of each columns.
Here's what I have so far: Codepen example
<div class="container" ng-controller="Controller as ctrl">
<div class="column" ng-repeat="column in ctrl.columns" ng-class="[column.mode, column.color]" ng-show="column.open">
<button ng-click="ctrl.close(this)" ng-show="column.id != 0">Close</button>
<p ng-click="ctrl.open(this)">Name: {{column.name}}</p>
<p>Open: {{column.open}}</p>
<p>Mode: {{column.mode}}</p>
<p>Color: {{column.color}}</p>
</div>
</div>
CSS:
.container {
height: calc(100% - 50px);
display: flex;
}
.column {
padding: 10px 0 0 10px;
overflow-y: auto;
}
.column-narrow {
flex: 33;
}
.column-wide {
flex: 66;
}
.column-full {
flex: 100;
}
The second and third column can be triggered by clicking the name paragraph.
Don't worry about the colors, they're definitely not final and are used only for a clear visual difference between containers etc.
Can any one of you offer me a CSS(3) solution to this? If my code can be optimised please do, as I'm currently learning Angular.
There is not a lot of code needed to get some basic animations working.
The ng-show and ng-hide directives already provide support for animations out of the box. That means that AngularJS will add animation hooks in the form of additional classes ng-hide-add, ng-hide-add-active, ng-hide-remove, ng-hide-remove-active.
So these classes get added to your CSS column.
I literally only had to add these CSS lines to make animations work in your Codepen.
.column.ng-hide-add.ng-hide-add-active,
.column.ng-hide-remove.ng-hide-remove-active {
-webkit-transition: all linear 0.5s;
transition: all linear 0.5s;
}
Here is the updated codepen:
http://codepen.io/anon/pen/XbVLxO

ngAnimate not adding classes to image gallery using ngRepeat

Demo: http://plnkr.co/edit/gehNa1s62ipRcny5Uzkj?p=preview
I'm attempting to make my image gallery animate when you hit the left/right arrows. Ideally, they would work like they do here.
I tried doing this:
.gallery-image {
opacity: 1;
&.ng-enter {
transition: transform 0.5s;
opacity: 0;
}
&.ng-enter-active {
opacity: 0.5;
}
}
But it just seems like ngAnimate doesn't want to add any classes to my elements on the DOM. My repeater is declared like this:
<img class="gallery-image"
ng-repeat="image in images | limitTo:3:currentIndex-1"
ng-show="$index+currentIndex-1 >= 0 && $index+currentIndex-1 < images.length"
ng-src="{{images[$index+currentIndex-1].url}}" />
So what I do is just change the current index I'm looking at, and that adjusts what images are visible.
The weird thing is, if you resize the plunk (sm to md, md to lg) you can see the images very clearly animating.
Why isn't ngAnimate adding any classes to my DOM?
It seems that ngAnimate will not do anything unless you actually modify the underlying array. The solution here is to keep a list of "visible" items, and modify that, instead of basing everything off of the currently visible index.

inline-block elements not showing in IE7

So, this is an odd one...
I've got basic pagination code:
<div class="pagination">
< 1 <a class="current">2</a> 3 >
</div>
And I want it all centred, so I'm using inline-block on the anchor tags. Simple enough, stripped down CSS code:
.pagination{text-align:center; margin-bottom:20px;}
.pagination > a{display:inline-block; vertical-align:middle; margin:0 2px 0 1px;}
.ie7 .pagination > a{zoom:1;}
.pagination .next,
.pagination .prev{width:26px; height:38px; text-indent:-9999px; overflow:hidden;
background:url(../images/page-arrows.png) no-repeat;}
.pagination a{width:37px; height:31px; line-height:32px; font-size:15px; font-weight:bold; color:#7e7e7e;
background:url(../images/page-numbers.png) left top no-repeat;}
Problem is that, NOTHING is displaying in IE7 (at least IE7-mode of IE9). I'm well aware of the display-inline bugs that IE7 has, but those only apply to elements that aren't inline by default. I've added in a zoom:1 anyway though for good measure.
If I put a background colour on the .pagination wrapper, that wrapper does indeed show up with the background colour, but the elements inside just aren't showing!
I've tried the usual IE 'fixes' ...position:relative, zoom:1, height:1% on any and every element, but not luck.
What am I missing?!
After some experimenting in JSFiddle I've managed to discover that the problem relates to this particular rule
.pagination .prev {text-indent:-9999px; }
Disabling this fixes the issue but is not ideal as you would then have the text charecter appear on top of your background images.
Interestingly enough your .next does not cause the same issue. with that in mind added an to either side of your paging control (so your center alignment dosnt get skewed) and it seems to of fixed the problem.
<div class="pagination">
< 1 <a class="current">2</a> 3 >
</div>
JSFiddle available here (background images replaced with solid colors for obvious reasons)

Fluid like box?

I'm making a responsive site and need to include a Facebook Like-Box for the client's Facebook fanpage. The developer page for the like-box has a widget for customization, but it doesn't allow you to set a width in percentages.
I've searched around and the closest I've got was this page from 2010, which refers to a fb:fan widget that allows you to link custom CSS. I tried to get this tutorial to work but it fails with this error:
<fb:fan> requires one of the "id" or "name" attributes.
So, to recap, I need a Facebook Like Box that I can either set up to be fluid, or which allows me to pass custom CSS to the iFrame it generates. Anyone able to point me in the right direction?
I found this Gist today and it works perfectly: https://gist.github.com/2571173
/* Make the Facebook Like box responsive (fluid width)
https://developers.facebook.com/docs/reference/plugins/like-box/ */
/* This element holds injected scripts inside iframes that in
some cases may stretch layouts. So, we're just hiding it. */
#fb-root {
display: none;
}
/* To fill the container and nothing else */
.fb_iframe_widget, .fb_iframe_widget span, .fb_iframe_widget span iframe[style] {
width: 100% !important;
}
You thought it couldn't be done? AHA! Have at you, Facebook and your wicked fixed-width ways: I wrote a JQuery script to undo all your evil!
$(document).ready(function(){
var fbWidth;
function attachFluidLikeBox(){
// the FBML markup: WIDTH is a placeholder where we'll insert our calculated width
var fbml = '<fb:like-box href="http://www.facebook.com/YOURFANPAGEORWHATEVS" width="WIDTH" show_faces="false" stream="true"></fb:like-box>';//$('#likeBoxTemplate').text().toString();
// the containing element in which the Likebox resides
var container = $('#likebox');
// we should only redraw if the width of the container has changed
if(fbWidth != container.width()){
container.empty(); // we remove any previously generated markup
fbWidth = container.width(); // store the width for later comparison
fbml = fbml.split('WIDTH').join(fbWidth.toString()); // insert correct width in pixels
container.html(fbml); // insert the FBML inside the container
try{
FB.XFBML.parse(); // parses all FBML in the DOM.
}catch(err){
// should Facebook's API crap out - wouldn't be the first time
}
}
}
var resizeTimeout;
// Resize event handler
function onResize(){
if(resizeTimeout){
clearTimeout(resizeTimeout);
}
resizeTimeout = setTimeout(attachFluidLikeBox, 200); // performance: we don't want to redraw/recalculate as the user is dragging the window
}
// Resize listener
$(window).resize(onResize);
// first time we trigger the event manually
onResize();
});
What is does is it adds a listener to the window's resize event. When it resizes, we check the width of the Likebox' containing element, generates new XFBML code with the correct width, replaces the containing element's children with said XFBML and then trigger the Facebook API to parse the XFBML again. I added some timeouts and checks to make sure it doesn't do anything stupid and only runs when it needs to.
Much has changed since the OP.
By simply choosing iFrame and setting your width to 100%, your FB Like Box should be responsive.
Basically FB adds this to the iFrame:
style="border:none; overflow:hidden; width:100%; height:300px;".
Been struggling with the exact same problem. A quick & simple solution is to use the iframe based Facebook Like box.
<iframe class="fb-like-box" src="//www.facebook.com/plugins/likebox.php?href=http%3A%2F%2Fwww.facebook.com%2Fplatform&width=292&height=500&colorscheme=light&show_faces=true&border_color&stream=true&header=true" scrolling="no" frameborder="0" allowTransparency="true"></iframe>
Note the assigned 'fb-like-box' class and all the removed inline styles. The class for the iframe could look something like this:
.fb-like-box {
width: 100% !important;
height:500px;
border:none;
overflow:hidden;
}
Looks like it doesn't matter what the height and width are that are defined in the iframe's src tag. Just place the iframe into some fluid element like a cell in a CSS grid layout.
(includes ideas from: http://updateox.com/web-design/make-facebook-comment-and-like-box-fluid-width/)
I used the HTML5 version of Facebook Like Box and here is what worked for me:
.fb-like-box,
.fb_iframe_widget span,
.fb_iframe_widget iframe {
width:100% !important;
}
You cannot set the like-box to anything other than a pixel width. My suggestion is to place it in a DIV or SPAN that is fluid with overflow set to hidden. Sure, it's going to crop off part of the like-box, but by having the requirement of fluid, this is your best bet.
Here's a small work around that appends the HTML5 Facebook LikeBox Plugin into the DOM with a response height or width.
$(document).ready(function(){
var height = $(window).height();
var width = $(window).width();
var widget_height = parseInt((height)*0.9);
var widget_width = parseInt((height)*0.3);
var page_url = "http://www.facebook.com/Facebook";
$(".fb-plugin").append("<div class='fb-like-box'
data-href='"+page_url+"'
data-width='"+widget_width+"'
data-height='"+widget_height+"'
data-colorscheme='dark'
data-show-faces='true'
data-border-color='#222'
data-stream='true'
data-header='true'>
</div></div>");
});
The comment above from Ed and Matthias about using 100% for the iframe worked great for me. Here is my iframe code
ORIGINAL WITHOUT FIX:
<iframe src="//www.facebook.com/plugins/likebox.php?
href=https%3A%2F%2Fwww.facebook.com%2FXXXXXXXXXX&
width&height=290&colorscheme=dark&
show_faces=true&header=true&stream=false&
show_border=true&appId=XXXXXXXXXX"
scrolling="no" frameborder="0"
style="border:none; overflow:hidden; height:290px;"
allowTransparency="true"></iframe>
UPDATED WITH 100% FIX:
<iframe src="//www.facebook.com/plugins/likebox.php?
href=https%3A%2F%2Fwww.facebook.com%2FXXXXXXXXXX&
width&height=290&colorscheme=dark&
show_faces=true&header=true&stream=false&
show_border=true&appId=XXXXXXXXXX"
scrolling="no" frameborder="0"
style="border:none; overflow:hidden; height:290px;width:100%"
allowTransparency="true"></iframe>
The only change is adding "width:100%" to the style attribute of the iframe
note that the code above has "XXXXXXXXXX" in place of the unique references

Resources