Angular UI Bootstrap Dialog Width - angularjs

The Angular UI Bootstrap Dialog is easy to implement, but difficult to customise.
How on earth do you change the width? Or even max-width?
http://angular-ui.github.com/bootstrap/#/dialog
I've tried $dialog.dialog({width:600}) and other variations but no joy.

For version 0.8/0.9 the layout has changed so you do not specify the modal class, I fiddled a little around with it and found that I you can use a nested CCS definition like this:
.xx-dialog .modal-dialog {
width :90%;
min-width: 800px;
}
And the when you launch the modal dialog specify the windowsStyle like this:
modalInstance = $modal.open({
templateUrl: 'templates/editxxx.html',
controller: EditXXCtrl,
windowClass: 'xx-dialog',
resolve: {
xx_uuid: function () {
return xx_guid;
}
}
});
But be aware that the windowsstyle is for the WHOLE window including the backdrop .
Hope it helps

The default CSS class is modal, use the dialogClass option (or the options attribute if you are using the modal directive) to specify additional CSS classes, for example:
$dialog.dialog({dialogClass: 'modal modal-huge'});
For the modal directive:
<div modal="modalVisible" close="close()"
options="{dialogClass:'modal modal-huge'}">
<div class="modal-header"><h3>Hello</h3></div>
<div class="modal-body">Hello world!</div>
<div class="modal-footer">
<button ng-click="dialogs.escolherModelo=false"
class="cancel btn btn-warning">Cancel</button>
</div>
</div>
If you are messing with the dialog width, in order to have the dialog centered, the CSS rule needs a negative margin-left of half the width:
.modal-huge {
width: 80%;
margin-left: -40%;
}
#media (max-width: 600px) {
.modal-huge {
width: 580px;
margin-left: -290px;
}
}
[UPDATE]
it is now called windowClass and your css rule should be for inner .modal-dialog, so it's like - .modal-huge .modal-dialog – SET
Ouch, seems like nothing is ever settled in the javascript world. This is untested:
$dialog.dialog({windowClass: 'modal-huge'});
For the modal directive:
<div modal="modalVisible" close="close()"
options="{windowClass:'modal-huge'}">
<div class="modal-header"><h3>Hello</h3></div>
<div class="modal-body">Hello world!</div>
<div class="modal-footer">
<button ng-click="dialogs.chooseModel=false"
class="cancel btn btn-warning">Cancel</button>
</div>
</div>
If you are messing with the dialog width, in order to have the dialog centered, the CSS rule needs a negative margin-left of half the width:
.modal-dialog .modal-huge {
width: 80%;
margin-left: -40%;
}
#media (max-width: 600px) {
.modal-dialog .modal-huge {
width: 580px;
margin-left: -290px;
}
}

Inspect a dialog in browser console will see that width is set with css only. Options in docs allow for user defined class names on body and/or on dialog so you can adjust for various types within page
Docs reference: https://github.com/angular-ui/bootstrap/blob/master/src/modal/docs/readme.md

Here's how I add another class to the modal dialog in angular using the $dialog service:
var opts = {
backdrop: true,
keyboard: true,
backdropClick: true,
templateUrl: 'my-partial.html',
controller: 'MyPartiallController',
dialogClass: 'modal myWindow'
};
var d = $dialog.dialog(opts);
d.open();
The dialog will open with class="modal myWindow" - note you have to include 'modal' or the dialog contents will appear underneath the backdrop.
Then with this css you can change the width:
.modal.myWindow {
width:700px;
margin-left:-350px
}
You'll have to include the negative left margin of 1/2 the width or it will be off-center.

Related

AngularJS UI Grid and Popover alignment

Hi I'm adding a popover to UI grid in AngularJS. The idea is when the user mouse-over a row a popover will show up, and the popover contains a directive. I've successfully implemented this part, but now the problem is that part of the popover is blocked by the ui grid table, like this:
I want to bring the popover to the front, and I've tried setting z-index for both the ui grid table and the popover. Related code is here:
JS part:
function rowTemplate() {
var template = [];
...
template.push('popover-template="\'popover.html\'" popover-placement="bottom" popover-trigger="click"></div>');
return template.join(' ' );
}
HTML:
<div class="gridStyle" ui-grid="vm.grid" ui-grid-resize-column ui-grid-selection style="margin-top:0px; height:200px; z-index: 4; position: relative">
</div>
<script type="text/ng-template" id="popover.html">
<div style="height: 150px; width: 600px; overflow-x: auto; overflow-y: hidden; z-index: 10; position: relative">
<directive-related part />
</div>
</script>
But after I set the z-index it's still not working. How can I resolve this?
Some of my references are here: popover: popover, z-index: z-index.
Thanks!
Note: I am making the assumption here that you are using ui-bootstrap.
I have found that usually you need to use the append-to-body attribute with ui-grid custom formats.
Try changing the template like so to add that attribute:
template.push('popover-template="\'popover.html\'" popover-append-to-body="true" popover-placement="bottom" popover-trigger="click"></div>')

angular js ngdialog scrollbar

I am using ng-dialog to display the popup. The problem i am facing with ng-dialog is there is no vertical scroll bar on the dialog box when the message is huge but scroll bar appearing for the entire html page.
Is there a way i can bring the scroll bar on the ng-dialog box.
I am using the ngdialog.js from https://github.com/likeastore/ngDialog
I googled my best but not getting any idea about how to bring the scrollbar. Please i am just bigger in the css.
below is the code which i am using to bring the popup.
ngDialog.open({ template: 'resources/views/popup.html', className: 'ngdialog-theme-default' , scope: $scope });
any suggestion much appreciated.
You should set overflow-y: scroll; on your content element within your dialog template.
HTML:
<div class="modal-content">
<ul class="list-group">
<li class="list-group-item" ng-repeat="item in items">{{::item.name}}</li>
</ul>
LESS:
.modal-content {
.choose-modal-content {
height: 100%;
width: 100%;
ul {
&.list-group {
overflow-y: scroll;
}
}
}
}
This way the ul will be scrollable when the content overflows.

Wrapping Formstone Wallpaper jquery plugin in an AngularJS directive

Trying hard to implement the Formstone Wallpaper JQuery plugin into my AngularJS application. I followed the instructions on the site just to learn that AngularJS and JQuery don't work well together. In many articles in the net it was mentioned that I had to wrap jquery plugins in AngularJS directives to use it the right way. I found this tutorial by David Boike on how to warp the Knob jquery plugin into an AngularJS directive.
I tried to follow along and achieve that for the Formstone Wallpaper plugin. This is my attempt:
'use strict';
angular.module('app').directive('formstoneWallpaper',[function() {
return {
restrict: 'E',
link: function (scope, elem, attrs) {
elem.wallpaper({
source: {
poster: attrs.poster,
mp4: attrs.mp4,
ogg: attrs.ogg,
webm: attrs.webm
}
});
}
};
}]);
Then my html markup changes to:
<div class="container-fluid">
<div class="row wall">
<formstone-wallpaper
poster="modules/launch/videos/ocean.jpg"
mp4="modules/launch/videos/ocean.mp4"
ogg="modules/launch/videos/ocean.ogv"
webm="modules/launch/videos/ocean.webm"
></formstone-wallpaper>
</div><!--row-->
</div><!--container-->
Yet this does not result in the desired full-width responsive video wallpaper. Instead the width and height is somehow set to 0px. I therefore do not see anything on my website. However, when I kill the wallpaper-container and wallpaper-media classes, the problem is partially resolved in that the video finally appears (however, it is not responsive and fittet to screen size-the reason why we are doing this exercise in the first place). Here is a screenshot from my chrome inspector.
Can someone help me to improve the code for the directive?
friends, it turned out the above directive is actually alright. The real problem that I had was my lack of understanding of nested relative positioning. I used this "resize" directive to dynamically set the height of my container to the height of the viewport.
This is the css that finally fixes the my issue:
formstone-wallpaper {
display: block;
position: relative;
width: auto;
height: auto;
padding: 100px 0;
min-height: 100%;
background: no-repeat center center;
background-attachment: scroll;
background-size: cover;
}
Set the "resize" attribute on your container like so:
<div class="container-fluid" data-ng-style="style()" resize>
<div class="row">
<formstone-wallpaper
poster="modules/launch/videos/ocean.jpg"
mp4="modules/launch/videos/ocean.mp4"
ogg="modules/launch/videos/ocean.ogv"
webm="modules/launch/videos/ocean.webm"
></formstone-wallpaper>
</div><!--row-->
</div><!--container-->

Template-expanding directives not rendering on the DOM

I've created a JSFiddle demonstration of a problem I've been facing, where my template-expanding directives are not functioning correctly.
In the JSFiddle, there are three buttons, where each toggles a different colored box.
redBox {
height: 50px;
width: 50px;
background-color: red;
border: 2px solid black;
}
// etc, etc.
Clicking a button toggles the display of one of the colored boxes.
<body ng-app="boxApp">
<div ng-controller="NavCtrl">
<nav>
<button ng-click="shownSection = 'red'">Show red box</button>
<button ng-click="shownSection = 'blue'">Show blue box</button>
<button ng-click="shownSection = 'green'">Show green box</button>
</nav>
<article>
<redBox ng-show="shownSection == 'red'"></redBox>
<blueBox ng-show="shownSection == 'blue'"></blueBox>
<greenBox ng-show="shownSection == 'green'"></greenBox>
</article>
</div>
</body>
Lastly, each fooBox element corresponds to an AngularJS directive that I would like to create a new DOM element based on a simple template.
var app = angular.module("boxApp", []);
app.controller("NavCtrl", function ($scope) {
$scope.shownSection = "";
});
app.directive('redBox', function() {
return {
restrict: "E",
template: '<div>red box</div>',
}
});
app.directive('greenBox', function() {
return {
// etc.
}
});
It doesn't work. In fact, the application behaves the same way regardless of whether or not I define the directives in the first place: it toggles each DOM element as intended, but displays the element as empty - ignoring the height and width properties but not the border property.
I assumed that the fooBox elements would render on the page because AngularJS would recognize these directives when it initially traverses the DOM, but it doesn't seem to do anything, and I don't get any console errors.
What am I doing incorrectly?
A few things.
You named your directives redBox / blueBox / greenBox the camel-case means a - goes between the letters.
So in the html it needs to look like this:
<red-box />
<blue-box />
<green-box />
Your CSS also needs to change to red-box { }.
Also put display:block; within your CSS for the blocks. That's why the height & width are being ignored.
jsFiddle updated*

How to implement a flip over effect using AngularJS animations?

What would be the best way to achieve a flip over effect using AngularJS animations?
I would like the flip over effect to occur on click. Every time it's clicked, it should flip over to the other side.
Ideally, I guess, I'm looking for a directive implementation that uses Angular animations.
PLNKR - here is a seed of a configurable angular directive that provides 3d flipping functionality. I do not see any good reason why to use ngAnimate for it.
basic usage
<flip flip-width="200px" flip-height="100px">
<flip-panel>
content-front
</flip-panel>
<flip-panel>
content-back
</flip-panel>
</flip>
Comments
It appends css-styles on its own, to be fully independent.
In a proper, generic directive all names should be configurable.
flip-width and flip-height sets style of flip and both flip-panels.
Directive makes some basic check, if both front and back are set.
First flip-panel is front and the second is back.
Due to usage of transclusion content of the flip-panel may be arbitrary html. (you are right Misha no transclusion needed)
It only works in -webkit. (update to make it work in Firefox, just duplicate all pieces with -webkit with no prefix - you do not need -moz)
UPDATE
PLNKR - here is an updated and extended version. It shows what I meant by making the directive configurable. In more details:
Introduced flipConfig via provider, that allows to set in app.config:
default dimensions
css class names
speed of the transition
if the flip action is triggered by a click on the panel
Introduced flip-show attribute that specifies which side to show.
Changing flip-show we can trigger the flip action from outside of the directive.
It works in Firefox and [almost:-)] in IE11.
(btw: it is just a seed and it may be improved in a lot of ways. E.g: specifying axis, specifying origin of the transform, specifying radius and margin of the panels, allowing flip on hover, defaults colors, margins and so on)
I had the same usecase just recently for an angular memory game.
My implementation is the same by the idea of the other answers. I also released the flipping code along with a DEMO.
Github: https://github.com/zwacky/angular-flippy
P.s.: Looks i'm late to the party ;)
You can use ng-click and ng-class to add a class when the flip container is clicked.
<div class="flip-container" ng-click="flip = !flip" ng-class="{'flip': flip}">
<div class="flipper">
<div class="front" style="background: lightblue;">
front
</div>
<div class="back" style="background: lightgreen;">
back
</div>
</div>
</div>
This is essentially the angular way of doing what Walsh suggested in his article:
Adding the flip class to the container element will flip the card using JavaScript -- no user hover required. A JavaScript comment like document.querySelector("#myCard").classList.toggle("flip") will do the flip!
The only change to David Walsh's css was removing the :hover selector - the html structure is unchanged. It works nicely in chrome and firefox.. but the flip isn't as pretty in IE.
Here is a working demo: http://plnkr.co/edit/0dn775vpuoOeh2PS1T6k?p=preview
Update
I created a simple directive to encapsulate this basic technique. It allows you to flip over a black card, to reveal a picture on the other side.
app.directive("flipReveal", function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'template.html',
scope: {
url: '=',
flip: '='
}
}
})
Here is a link to a new demo: http://plnkr.co/X4pSav
Disclaimer Based on #artur's answer https://stackoverflow.com/a/23139242/1319998 , but hopefully both simplified and made more flexible.
A custom directive is the way to go, one that can be used as:
<flip flip-side="{{side}}">
<flip-front>
Front side contents
</flip-front>
<flip-back>
Rear contents
</flip-back>
</flip>
I think it should have certain properties:
Programatically controlled by an attribute. In this case, a string that is equal to 'front' or 'back'
<flip flip-side="{{side}}">....</flip>
this would allow programmatic access via the surrounding scope.
Integrated with ngAnimate/$animate. Specifically, if ngAnimate is removed or disabled, the animation should not occur, but the reveal of the other side happen immediately. Using $animate.addClass/$animate.removeClass would achieve this, adding/removing a flip-visible class together with display:block and display:none styles to make sure the right side is visible/hidden when the animations are disabled.
flip > flip-front, flip > flip-back {
display: none;
}
flip > .flip-visible {
display: block;
}
Controlled by CSS, with defaults. So if you want to change the duration of the flip, it's a CSS, and not a Javascript, addition.
So it will have a style sheet to add styles required for the various stages of $animate.addClass / $animate.removeClass CSS animations explained at Year of Moo and $animate docs . The class will be flip-visible, so the extra classes will be .flip-visible-add, .flip-visible-add-active, .flip-visible-remove, and .flip-visible-remove-active classes.
The full set of styles can be seen at http://plnkr.co/edit/bbYbMhiURnm6FqC9patp?p=preview, but the main construction is of the form:
.flip-visible-add {
// Initial setup: time and initial, pre-animation, transform
}
.flip-visible-add.flip-visible-add-active {
// Target transform
}
Putting all this together, the directive is quite short:
app.directive("flip", function($animate) {
return {
restrict : "E",
controller: function($scope, $element, $attrs) {
var elements = {
'front': $element.find('flip-front'),
'back': $element.find('flip-back')
};
$attrs.$observe('flipSide', function(visibleSide) {
visibleSide = visibleSide || 'front';
var otherSide = visibleSide == 'front' ? 'back' : 'front';
$animate.removeClass(elements[otherSide], 'flip-visible');
$animate.addClass(elements[visibleSide], 'flip-visible');
});
}
}
});
This can all be seen in an example, together with the stylesheets to make it all work, at http://plnkr.co/edit/bbYbMhiURnm6FqC9patp?p=preview
I realise there is a benefit to not integrating with the $animate service, and having a purely class-based solution.
If you use $animate with addClass and removeClass, but interrupt the animation (say, by clicking quickly and repeatedly on the element), the animation will 'jerk' to its end/starting point, and then animate from that position, at least on Chrome. Using a pure CSS solutions avoids this issue, and always animates from the exact current point, giving a smoother effect.
An added benefit is the solution is also simpler, and you don't need a custom directive.
For example, the HTML can be as follows:
<flip class="{{side === 'front' ? 'flip-front' : 'flip-back'}}">
<flip-front>
Front side contents
</flip-front>
<flip-back>
Rear contents
</flip-back>
</flip>
I use custom elements, but they don't need to have any directives attached: they are just for CSS to hook into:
flip > flip-front, flip > flip-back {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
/* Time can be overriden */
transition: -webkit-transform 0.5s;
transition: transform 0.5s;
}
/* Front visible */
flip > flip-front {
-webkit-transform: perspective(800px) rotateY(0);
transform: perspective(800px) rotateY(0);
}
flip > flip-back {
-webkit-transform: perspective(800px) rotateY(180deg);
transform: perspective(800px) rotateY(180deg);
}
/* Back visible */
flip.flip-back > flip-front {
-webkit-transform: perspective(800px) rotateY(-180deg);
transform: perspective(800px) rotateY(-180deg);
}
flip.flip-back > flip-back {
-webkit-transform: perspective(800px) rotateY(0);
transform: perspective(800px) rotateY(0);
}
This can be seen in a demo at http://plnkr.co/edit/A7IeGa1JEsZishmTDTaK?p=preview
I would simply add / remove a class on click.
If you want to hook into the angular animation system then take a look at the $animate service, in particular add/remove/setClass(). The service is usually used in directives. You might want to create a directive that reacts on a click event and triggers the animation. You even get informed when the animation has completed.
Chances are that it's not worth it ;)
You are going to want to create 3 divs.
<div class="wrapper">
<div class="front"></div>
<div class="back"></div>
</div>
You then position back behind front using z-index, and flip it upside down using rotateX (-180deg or so). Set a transition on wrapper as well.
Then, on click of wrapper, rotateX(+180deg). This will pretty much infinitely flip it over.
** Update: For angular, bind to click and use setClass to toggle between two classes on wrapper, one at rotateX(0deg) , the other at rotateX(180deg)
Here is a slightly modified version of artur's answer:
DEMO
angular.module('FlipDemo', []).directive("flip", function() {
return {
restrict : "A",
scope: true,
link: function(scope, element) {
var $panels = element.css({ position: 'relative' }).children().addClass("flip-panel");
var frontPanel = $panels.eq(0);
var backPanel = $panels.eq(1);
scope.showFrontPanel = function() {
frontPanel.removeClass("flip-hide-front-panel");
backPanel.addClass("flip-hide-back-panel");
};
scope.showBackPanel = function() {
backPanel.removeClass("flip-hide-back-panel");
frontPanel.addClass("flip-hide-front-panel");
};
scope.showFrontPanel();
}
}
});
.flip-panel {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-webkit-transition: -webkit-transform .4s;
-moz-transition: -moz-transform .4s;
-webkit-transform: perspective(800px) rotateY(0deg);
-moz-transform: perspective(800px) rotateY(0deg);
}
.flip-hide-back-panel {
-webkit-transform: perspective(800px) rotateY(180deg);
-moz-transform: perspective(800px) rotateY(180deg);
}
.flip-hide-front-panel {
-webkit-transform: perspective(800px) rotateY(-180deg);
-moz-transform: perspective(800px) rotateY(-180deg);
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.1/angular.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body ng-app="FlipDemo">
<div style="width: 100px; height: 150px">
<div flip style="width: 100%; height: 100%">
<div style="background-color: green">
<div>Front</div>
<button ng-click="showBackPanel()">Show Back</button>
</div>
<div style="background-color: blue">
<div>Back</div>
<button ng-click="showFrontPanel()">Show Front</button>
</div>
</div>
</div>
<br>
<div style="width: 150px; height: 100px">
<div flip style="width: 100%; height: 100%">
<div style="background-color: green">
<div>Front</div>
<button ng-click="showBackPanel()">Show Back</button>
</div>
<div style="background-color: blue">
<div>Back</div>
<button ng-click="showFrontPanel()">Show Front</button>
</div>
</div>
</div>
</body>
</html>
Main differences:
Works in Chrome and Firefox.
More flexibility with when the flip happens.
Just one directive rather than two. Less code.
I took the CSS outside of the directive for clarity sake.

Resources