angular same height directive not working - angularjs

I have created a directive so that the columns in a bootstrap row are of same height.
Here is the code - http://jsbin.com/waxoboloqo/edit
But it is not working. Can you please fix it ?
Html code:
<h1>Height: {{ hei }}</h1>
<div class="row">
<div class="col-lg-6 col-1">
<h1 ng-repeat="x in y" match-height>{{x}}</h1>
</div>
<div class="col-lg-6 col-2">
</div>
</div>
CSS:
.col-lg-6 {
border: 1px solid;
min-height: 50px;
}
Js:
angular.module('myApp', [])
.controller('myController', function($scope){
$scope.y = [1,2,3];
$scope.hei = "initial"
})
.directive('matchHeight', function(){
return function(scope, element) {
if(scope.$last){
scope.hei = $(element).height();
$(element).closest(".row").find(
".col-2").height(scope.hei);
}
}
});

you can try this.
app.directive('getHeight',function () {
return {
restrict: 'AE',
link: function (scope, element, attrs) {
scope.$watch(function(){
scope.style = {
height:element[0].offsetHeight+'px',
// width:element[0].offsetWidth+'px'
};
});
}
};
});
<div class="col-lg-6 col-1" get-height>
<h1 ng-repeat="x in y">{{x}}</h1>
</div>
<div class="col-lg-6 col-2" ng-style="style">
</div>

Related

losing scope of ng-model when using ng-include (AngularJS)

I am creating android app using ionic and angularjs. In app i used ng-include for include html content in my page.
checkbox.html:
<ul>
<li ng-repeat="opt in $parent.checkboxOptions">
<h4>
<label><input type="checkbox" name="checkbox" ng-model="$parent.checkboxAnswer" value="{{opt.option_value}}">{{opt.option_value}}</label>
</h4>
</li>
</ul>
surveyCtrl.js
$scope.checkboxOptions = params.QuestAnswers;
$scope.next = function(){
console.log($scope.checkboxAnswer);
}
its showing undefined and another thing when i am click on one checkbox its selecting all checkbox's also.
surveyCtrls.js
.directive('question', function ($compile) {
return {
restrict: 'A',
replace: true,
link: function (scope, ele, attrs) {
scope.$watch(attrs.question, function(QuesHtml) {
ele.html(QuesHtml);
$compile(ele.contents())(scope);
});
}
};
})
.directive('description', function ($compile) {
return {
restrict: 'A',
replace: true,
link: function (scope, ele, attrs) {
scope.$watch(attrs.description, function(DescHtml) {
ele.html(DescHtml);
$compile(ele.contents())(scope);
});
}
};
})
.directive('answers', function ($compile) {
return {
restrict: 'A',
replace: true,
link: function (scope, ele, attrs) {
scope.$watch(attrs.answers, function(AnswerHtml) {
ele.html(AnswerHtml);
$compile(ele.contents())(scope);
});
}
};
})
.controller('surveyLoad', function($scope){
var QuestType = SurveyData[QuestionIndex].question_type;
var DrawHTML = {
'QuestionText': 'Some Text',
'QuestionDesc': 'Some Desc',
'QuestAnswers': [{
option_value: 'Red',
}, {
option_value: 'Blue',
}];,
'scope' : $scope
};
checkbox(DrawHTML);
}
})
.controller('nextQuest', function($scope){
$scope.QuestNext = function(){
console.log($scope);
}
});
function checkbox(params){
var $scope = params.scope;
$scope.QuesHtml = "<p>"+params.QuestionText+"</p>";
$scope.DescHtml = "<p>"+params.QuestionDesc+"</p>";
$scope.checkboxOptions = params.QuestAnswers;
$scope.AnswerHtml = "<div ng-include src=\"'surveyTemplate/checkbox.html'\"></div>";
}
survey.html
<div class="row">
<div class="col question_div">
<div class="qus_head">
<p>Question: 1/10</p>
</div>
<h4 class="para"><span question="QuesHtml"></span> </h4>
<div class="qus_footer">
<p>Maxime quis.</p>
</div>
</div>
</div>
<div answers="AnswerHtml">
</div>
<div class="row">
<div class="col button_div">
<ul>
<li><img src="../img/next.png" style="width:70px;float:right" alt="next" ng-controller="nextQuest" ng-click="QuestNext()"></li>
<!-- <center><li><button style="align:center">Stop</button></li></center> -->
<li><img src="../img/pre.png" style="width:70px;float:left" alt="previous" ></li>
</ul>
</div>
</div>
is there any way to get the value of checked checkboxes and prevent to check all other checkboxe's ?
Using ng-includes create it's own scope.
By using the controller as syntax you can overcome this issue.
https://docs.angularjs.org/api/ng/directive/ngController
<div id="ctrl-as-exmpl" ng-controller="Controller as ctrl">
...
<li ng-repeat="opt in ctrl.checkboxOptions">
<h4>
<label><input type="checkbox" name="checkbox" ng-model="ctrl.checkboxAnswer" value="{{opt.option_value}}">{{opt.option_value}}</label>
</h4>
</li>
...
</div>
and in your controller :
$scope.checkboxOptions = params.QuestAnswers;
becomes
this.checkboxOptions = params.QuestAnswers;
and so on.
AngularJS plunker about this syntax :
https://plnkr.co/edit/DB1CpoWLUxQ9U8y558m1?p=preview
Regards,
Eric
You need some correction in the html.
<label><input type="checkbox" name="checkbox" ng-model="opt.option_value">{{opt.option_value}}</label>
With ng-model="$parent.checkboxAnswer" ,all checkbox will share common model.
So,it will get updated at the same time.
So,when you check/uncheck,it will check/uncheck everyone.
And ,you don;t need to use value,angular is used ng-model property for its value evaluation and not value
Yupii...i found the solution..
here is solution:
<ul>
<label ng-repeat="opt in $parent.checkboxOptions">
<li>
<h4>
<label><input type="checkbox" name="checkbox" ng-model="$parent.$parent.selected[opt.option_value]" >{{opt.option_value}}</label>
</h4>
</li>
</label>
</ul>
(function(angular) {
'use strict';
angular.module('MyApp', [])
.controller('AppCtrl', SettingsController1);
function SettingsController1($scope) {
$scope.options = {
'checkboxAnswer': ''
};
$scope.checkboxOptions= [{
type: 'phone',
value: '917xxxxxxxx'
}, {
type: 'email',
value: 'sajankumarv#example.org'
}];
}
})(window.angular);
radio box template file #radiobox.html
<ul>
<li ng-repeat="opt in checkboxOptions">
<h4>
<label><input type="checkbox" ng-model="options.checkboxAnswer" ng-true-value="'{{opt.value}}'" ng-false-value="''">{{opt.type}}</label>
</h4>
</li>
<h1>{{options.checkboxAnswer}}</h1>
</ul>
//in main index.html you simply include this radiobox.html using ng-include directive
<body ng-app="MyApp">
<div ng-controller="AppCtrl">
<div ng-include='"radiobox.html"'></div>
</div>
</body>
I think you are not in isolate scope so you don't have to use $parent for your case.I made a simple working demo for you to understand kindly refer the below link.
https://plnkr.co/edit/aQMZBln5t0Fipwn1qloN?p=preview

Directive is Not Called when the ng-repeat is finished

I want to call the directive when my ng-repeat is finished. I use two controllers with same name. My problem is that when I call the function of controller the function changes the value of the list. And base on that list ng-repeat is work. When ng-repeat is end directive is called that called the END function. But ng-repeat not work as well as directive also not called.
my HTML code is here
> <body ng-app="modules" >
<div class="container" >
<div class="row" ng-controller="mainctl">
<div class="col-sm-1">
<a href="#" ng-click="divide(1)" ><h3>1*1</h3></a>
</div>
<div class="col-sm-1">
<h3>2*2</h3>
</div>
<div class="col-sm-1">
<h3>3*3</h3>
</div>
<div class="col-sm-1">
<h3>4*4</h3>
</div>
<div/>
<div ng-controller="mainctl">
<div ng-repeat="rows in cells" > <!-- repeat fot rows -->
<div class="row">
<div ng-repeat="cols in cells" repeat-end="onEnd()"> <!-- repeat for colums -->
<div id="Div_{{rows}}{{cols}}" class="col-sm-2 rcorners2">
<center><h1>{{rows}}{{cols}}</h1></center>
<div id="divPictureBoxPlayback{{rows}}{{cols}}" class="pictureboxPlayback'"
ad-drop="true"
ad-drop-end="onDrop($data, $dragElement, $dropElement, $event);" >
<div id="divHeaderPictureBoxPlayback{{rows}}{{cols}}" class="panel panel-default margin-b-0 text-center pictureboxHeader row"
ng-hide="StartPlayerPlayback{{rows}}{{cols}}" >
<div class="">
<span class="col-lg-3 col-xs-3 col-md-3 text-left">{{cameraNamePlayback00}}</span>
<span class="col-lg-9 col-xs-9 col-md-9 text-right pad-0">
<button class="margin-r-10 btn btn-xs" ng-click="StopStreaming('{{rows}}{{cols}}')"><i class="fa fa-close"></i></button>
</span>
</div>
</div>
<div id="divStreamingAreaPlayback{{rows}}{{cols}}" class="video-cointainer text-center row" ng-hide="StartPlayerPlayback{{rows}}{{cols}}"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
here is my controller
app.controller('mainctl', function ($scope,$timeout) {
$scope.cells =["0"];
//Scopes.store('mainctl', $scope);
$scope.divide = function (ar)
{
$scope.value = ar;
$scope.cells = [];
for (var i = 0; i < ar; i++)
{
$scope.cells.push(i + "");
}
}
$scope.divide1=function()
{
for(var i=0;i<$scope.value;i++)
{
for(var j=0;j<$scope.value ;j++)
{
$scope.index=""+i+j;
$("#divPictureBoxPlayback" + $scope.index).attr('class', 'picturebox pictureboxPlayback' + i + j);
$("#divPictureBoxPlayback" + index).show();
}
}
}
$scope.onEnd = function(){
$timeout(function(){
alert('all done');
$scope.divide1();
}, 1);
}
});
here is my directive
app.directive("repeatEnd", function($timeout){
return {
restrict: "A",
link: function (scope, element, attrs) {
if (scope.$last) {
alert("last element ");
scope.$eval(attrs.repeatEnd);
}
}
};
})
It seems you are missing timeout. You will need timeout in your code in directive:
app.directive("repeatEnd", function ($timeout) {
return {
restrict: "A",
link: function (scope, element, attrs) {
if (scope.$last) {
$timeout(function () {
alert("last element ");
scope.$eval(attrs.repeatEnd);
});
}
}
};
})
$timeout will ensure it is executed only when ng-repeat finishes its rendering. The reason for using $timeout over setTimeout is because it will call $apply internally.

Accessing controller from a directive

I have an angular app:
HTML
<body ng-controller="DashboardController as vm">
<div ng-controller="OneController as vm">
Number inside the controler: {{vm.number}}
</div>
<div ng-controller="TwoController as vm">
<me-dir></me-dir>
</div>
</body>
ANGULAR
angular.module('plunker', [])
angular.module('plunker').controller 'DashboardController', ()->
vm = #
angular.module('plunker').controller 'OneController', ()->
vm = #
vm.number = 7
angular.module('plunker').controller 'TwoController', ()->
vm = #
angular.module('plunker').directive 'meDir', ()->
return {
#scope: {} ???
#require ???
#link ???
template: "<strong>Got it!{{number}}</strong>"
}
How can I access the value vm.number from OneController and assign it to the scope inside of the directive?
Is it possible to do it using require and link field from directive?
Can you reference existing controller using require?
At the moment OneController isn't the parent of directive so require: '^ctrlName' doesn't work. I haven't found a lot of documentation about controller/require field. I know how to do it if I would have to pass it in using attributes and stuff. The question is strictly about require link controller directive fields.
Plunker link
Use a service to share data across components
Very simple service upgrade to your code with data shared between controller and directive through the service
angular.module('plunker').service 'SharedService', ()->
vm = #
vm.number=7
angular.module('plunker').controller 'OneController', (SharedService)->
vm = #
vm.number = SharedService.number
angular.module('plunker').directive 'meDir', (SharedService)->
return {
scope:{}
controllerAs:'dir'
controller: ()->
vm = #
vm.number = SharedService.number
template: "<strong>Got it!{{dir.number}}</strong>"
}
DEMO
EDIT 2
var app = angular.module("test", []);
app.controller("Ctrl1", function($scope) {
$scope.name = "Harry Potter";
});
app.controller("Ctrl2", function($scope) {
$scope.any = "Any"
});
app.directive("myDirective", function($compile) {
return {
restrict: "EA",
scope: true,
link : function(scope, element, attr) {
var scopeCtrlOne = angular.element('[ng-controller="Ctrl1"]').scope();
angular.element(element).append($compile(
"<div>Your name is : {{name}}</div>" +
"Change your name : <input type='text' ng-model='name' />")(scopeCtrlOne)
);
}
};
});
h2 {
cursor: pointer;
}
.directive {
border: 5px solid #F5BF6E;
;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
<div ng-controller="Ctrl1">
<h2 ng-click="reverseName()"> {{name}}, CTRL ONE</h2>
<div ng-controller="Ctrl2">
<h2 ng-click="reverseName()"> {{any}}, CTRL TWO</h2>
<div my-directive class='directive'></div>
</div>
</div>
</div>
EDIT 1
Look this. For details: http://www.undefinednull.com/2014/02/11/mastering-the-scope-of-a-directive-in-angularjs/
var app = angular.module("test",[]);
app.controller("Ctrl1",function($scope){
$scope.name = "Harry";
$scope.reverseName = function(){
$scope.name = $scope.name.split('').reverse().join('');
};
});
app.directive("myDirective", function(){
return {
restrict: "EA",
scope: true,
template: "<div>Your name is : {{name}}</div>"+
"Change your name : <input type='text' ng-model='name' />"
};
});
h2 {
cursor: pointer;
}
.directive {
border: 5px solid #F5BF6E;;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
<div ng-controller="Ctrl1">
<h2 ng-click="reverseName()">Hey {{name}}, Click me to reverse your name</h2>
<div my-directive class='directive'></div>
</div>
</div>

Angularjs: get parent element width

html"
<div id="parent">
<input type=button ng-click="getWidth()">
</div>
js:
function Ctrl($scope) {
$scope.getWidth = function(){
// How to get div[id=parent] width here?
}
}
So my question is how to get parent div in getWidth method?
like hansmaad's answer, you better use directive for handling DOM stuffs.
app.directive('getWidth', ['$timeout', '$location', function($timeout, $location) {
return {
scope: {
callbackFn: "&"
},
link: function(scope, elem, attrs) {
scope.callbackFn({width: elem[0].clientWidth});
}
}
}]);
in html
<body ng-controller="MainCtrl" >
<div get-width callback-fn="returnWidth(width)" style="height:100%; width: 100%;">
<p >Hello {{name}}!</p>
</div>
</body>
working example here
use $event.target to get the element click and then use jquery to find width
function SimpleController($scope) {
$scope.width = 0;
$scope.getWidth = function($event) {
// How to get div[id=parent] width here?
$scope.width = $($event.target).parent().outerWidth();
}
}
#parent{
background-color : red;
width : 200px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script>
<div class="container" ng-app="" ng-controller="SimpleController">
<div id="parent">
parent width : {{width}}
<button type=button ng-click="getWidth($event)"> find width </button>
</div>
</div>

Toggling a Twitter Bootstrap (3.x) Modal using AngularJS

I've been trying to get a Bootstrap Model to be hidden on load, and then show it after clicking a button, but have been unsuccessful so far. I am pretty new to AngularJS so bear with me if I'm not doing this correctly. Here's what I've got so far:
Modal Angular Directive (modal.js):
angular.module('my.modal', ['modal.html'])
.directive('myModal', function () {
return {
restrict: 'E',
transclude: true,
replace: false,
templateUrl: 'modal.html',
link: function(scope, element, attrs) {
element.modal('hide')
scope.toggleModal = function() {
if (attrs.showModal === true) {
element.modal('hide')
attrs.showModal = false
} else {
element.modal('show')
attrs.showModal = true
}
}
}
};
});
Modal Template (modal.html):
<div id="{{id}}" showModal="false" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<div class="content" ng-transclude></div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="showModal = false">Cancel</button>
</div>
</div>
</div>
</div>
And finally, the button to toggle the modal (index.html):
...
<my-modal>
<p>Some content</p>
</my-modal>
<button class="btn btn-default" type="button" ng-click="toggleModal()">Toggle me!</button>
...
All this does is show the modal on page load (between my header and all the other content, so it's not floating above anything) and the toggle button does not work.
I've managed to get it working by using the Bootstrap 3 Modal properties and dynamically changing styling and classes of the modal directive based on it's show or hide state, though there are no animations:
Modal Angular Directive (modal.js):
angular.module('my.modal', ['modal.html'])
.directive('myModal', [function () {
return {
restrict: 'E',
transclude: true,
replace: false,
templateUrl: 'modal.html',
controller: 'ModalCtrl',
link: function(scope, element, attrs) {
if (attrs.title === undefined) {
scope.title = 'Modal Title Placeholder';
} else {
scope.title = attrs.title;
}
scope.$watch('showModal', function (value) {
if (value) {
scope.displayStyle = 'block';
scope.modalFadeIn = 'in';
} else {
scope.displayStyle = 'none';
scope.modalFadeIn = '';
}
});
}
};
}).controller('ModalCtrl', ['$scope', function ($scope) {
$scope.toggleModal = function() {
$scope.showModal = !$scope.showModal;
};
$scope.$open = function() {
$scope.showModal = true;
};
$scope.$close = function() {
$scope.showModal = false;
};
});
Modal Template (modal.html):
<div role="dialog" tabindex="-1" class="modal fade" ng-init="showModal = false" ng-show="showModal" ng-style="{display: displayStyle}" ng-class="modalFadeIn">
<div class="modal-backdrop fade in" style="height: 100%"> </div>
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">{{title}}</h3>
</div>
<div class="modal-body">
<div class="content" ng-transclude></div>
</div>
</div>
</div>
</div>
The call to open the modal can be done using the open or toggleModal function. A custom button needs to be placed in the modal to close the modal.

Resources