angular material flex in ng-repeat element - angularjs

I am constructing a dynamic table using angular material row and column layouts. I am using ng-repeat to construct the columns based on pre defined columns in an array of objects called scope.tableLayout. Each object has a flex value. What I would like to do is set the table column width based on the flex value in the object. Is there a way to do this?
My JSfiddle of the table attached where I've tried to set the flex as flex="col.flex" with no luck. Any help is appreciated.
My Code in JSfiddle
<div ng-app="myApp" ng-controller="mainCtrl">
<script type="text/ng-template" id="/template">
<button ng-click="testFn()">Test</button>
<div layout="row">
<div flex='col.flex' ng-repeat="col in column"><span>HEADER{{$index}}</span>
<div layout="column">
<div flex style="border: 1px solid black;" ng-repeat="row in [1,2,3]">{{$index}}</div>
</div>
</div>
</div>
</script>
<form-table table-layout=tableLayout|filter:{table_id:1}></form-table>
</div>
var app = angular.module('myApp', ['ngMaterial']);
app.controller('mainCtrl', function($scope) {
$scope.tableLayout =[{"head_id":"GAP Assessment","table_id":"1","table_name":"GAP Table","element_id":"0","element_name":"Action Reference","sort_order":"0","is_multirow":"1","flex":"30","element_sort_order":"4","is_show":"0"},{"head_id":"GAP Assessment","table_id":"1","table_name":"GAP Table","element_id":"1","element_name":"Audit Criteria","sort_order":"0","is_multirow":"1","flex":"30","element_sort_order":"0","is_show":"1"},{"head_id":"GAP Assessment","table_id":"1","table_name":"GAP Table","element_id":"3","element_name":"Document Reference","sort_order":"0","is_multirow":"1","flex":"10","element_sort_order":"3","is_show":"1"}]
});
app.directive('formTable', function() {
return {
scope:{tableLayout:'&'},
link: function(scope,element,attrs){ // normal variables rather than actual $scope, that is the scope data is passed into scope
scope.column=scope.tableLayout();
scope.testFn=function(){
console.log(scope.tableLayout());
}
//function and scopes go here
},//return
transclude:true,
templateUrl: '/template',
restrict: 'E'
}
})

As soon as I posted this problem I found my issue - need to use handlebars!
flex = "{{col.flex}}"
It now works.
Working Fiddle

Related

AngularJS $scope not showing value

I'm using flask(version 1.0.2) and AngularJS (version 1.7.2) material (version 1.1.10).
Problem is the controller is attached to view and it working, but just not showing value in view.
The controller
$$.controller("bigLayoutToolbarController", function ($scope) {
$scope.title = "---"
console.log(">>", $scope.title)
})
Surprisingly the console logging is working.
>> ---
The view
<section layout="row" flex style="height: 100%" ng-controller="bigLayoutToolbarController">
<h2 flex md-truncate>{{ title }}</h2>
</section>
What am i wrong?
Try removing the md-truncate because it will will automatically clip text which is wider than the component.
DEMO
var app = angular.module('myApp',[]);
app.controller("bigLayoutToolbarController", function ($scope) {
$scope.title = "---"
console.log(">>", $scope.title)
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
<body ng-app="myApp">
<section layout="row" flex style="height: 100%" ng-controller="bigLayoutToolbarController">
<h2 flex md-truncate>{{ title }}</h2>
</section>
</body>

AngularJS: How can I plug a directive into a template?

I'm trying to write a generic confirmation screen. I'd like to reuse it across a variety of different entities. Each entity has a different directive used to render it to screen.
Is there a way to write a template with a "directive-shaped hole" (my-directive below) that I can fill in programmatically?
<div>
Are you sure you want to blah?
<directive-from-scope value-from-scope="theValue" params-from-scope="theParams" />
</div>
I solve it with built-in ng-include directive.
Assume you have some directive with getTemplateUrl() function. You can put any login into this function but it should basically return you a string with the template URL.
Then you can do next thing in your directive template.
<div ng-include="directiveCtrl.getTemplateUrl()"></div>
Tag that you use doesn't matter, it can be any HTML tag, just choose one that works better for you.
Now in each template you can have whatever you want: directive, HTML with some controller on it, etc.
You can create directive with transclude:
angular.module('app', []).directive('myDirective', function() {
return {
restrict: 'E',
transclude: true,
template: `
<div class='borders'>
Are you sure you want to blah?
<div ng-transclude></div>
</div>
`
};
}).controller('ctrl', function($scope){
$scope.log = console.log;
$scope.title = 'Simple title';
});
.borders {
border-style: solid;
border-width: 1px 1px 1px 1px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller='ctrl'>
<my-directive>
<ul>
<li>first</li>
<li>second</li>
</ul>
<input type='button' value='Log' ng-click="log(title)"/>
</my-directive>
<my-directive>
<h4>{{title}}</h4>
</my-directive>
</div>

Unable to get content AngularJs dynamic popover inside ngrepeat

I need to display a small popover which should open on click and goaway on clicking anywhere on the page.
I found a plunker (http://plnkr.co/edit/K7cYQSDEBS3cHvDfJNLI?p=preview) which matches this requirement however, unable to get it to work inside ng-repeat.
I saw several answers and Plunker examples but not able to get this to work.
Here is my html
<div ng-controller="TestController">
<div class="row" style="background-color: #ebebeb !Important; ">
<div style="text-align:center">
<table style="width:100% !important;">
<tr ng-repeat="member in TeamMembers" style="font-size:18px !important; height: 108px;">
<td style="display:block;margin-top:30px;text-align:left;"> {{member.FirstName}} {{member.LastName}} <i class="fa fa-info-circle" aria-hidden="true" ng-show="member.Description != null" popover-template="dynamicPopover.templateUrl" popover-placement="bottom" popover-elem descr="{{member.Description}}"></i></td>
</tr>
</table>
</div>
</div>
...
<script type="text/ng-template" id="descriptionModal.html">
<div class="adp-info-dialog">
<div class="modal-body">
<div class="row">
<div class="col-md-8 col-md-offset-1">
<div class="form-group">
<label class="fieldset-label">Test {{ dynamicPopover.descr }}</label>
</div>
</div>
</div>
</div>
</div>
</script>
Here is the JS
testApp.controller('TestController', function ($scope, $rootScope, $log, $modal, SiebelAccountTeamService, $filter, $element) {
$scope.dynamicPopover = {
templateUrl: 'descriptionModal.html',
descr: null
};
var result = TestService.GetTeamMembers();
result.then(function (data) {
$scope.TeamMembers = data.data;
}, function (e) {
console.log(e);
}).finally(function () {
$scope.CompleteLoading();
});
});
testApp.directive('popoverClose', function ($timeout) {
return {
scope: {
excludeClass: '#'
},
link: function (scope, element, attrs) {
var trigger = document.getElementsByClassName('trigger');
function closeTrigger(i) {
$timeout(function () {
angular.element(trigger[0]).triggerHandler('click').removeClass('trigger');
});
}
element.on('click', function (event) {
var etarget = angular.element(event.target);
var tlength = trigger.length;
if (!etarget.hasClass('trigger') && !etarget.hasClass(scope.excludeClass)) {
for (var i = 0; i < tlength; i++) {
closeTrigger(i)
}
}
});
}
};
});
testApp.directive('popoverElem', function () {
return {
scope: {
descr: '#'
},
link: function (scope, element, attrs) {
$scope.dynamicPopover.descr = scope.descr,
alert($scope.dynamicPopover.descr),
element.on('click', function () {
element.addClass('trigger');
});
}
};
});
Appreciate your help.
Update:
To show the data of the ng-repeat inside the popover content, we need to access the individual objects through the $index of the ng-repeat. Refer the below example.
Plunkr Demo
The problem here is that you are using ng-repeat which creates a new scope read more here.
Since replicating the issue with your code is tedious, I tried replicating the issue with the plunkr!
Solution:
Plunkr Demo
You can simply define a new controller inside the descriptionModal.html like so
HTML:
<script type="text/ng-template" id="myPopoverTemplate.html">
<div class="adp-info-dialog" ng-controller="tester">
<div class="modal-body">
<div class="row">
<div class="col-md-8 col-md-offset-1">
<div class="form-group">
<label class="fieldset-label">Test {{ $parent.$parent.dynamicPopover.content }}</label>
</div>
</div>
</div>
</div>
</div>
</script>
JS:
app.controller('tester', function ($rootScope, $scope) {
console.log($scope.$parent.$parent.dynamicPopover.title);
});
Then, we will be able to access the parent scope, using $parent, the html inside the above script uses the $parent to get the variable!
Please note: It took me two $parent to reach the required $scope to access the scope variable. In your scenario it will also require two, the way to check how many is needed is use console.log($scope), then open the console(F12), then traverse through the objects $parent property till you find the correct $scope. Then count the number of $parent traversed, that will be your required number of $parent to traverse!
P.S:
There is another method you can do this, since this method will require a significant rewrite of your code, I will provide the GIST, you can use the controller as syntax and access the correct scope.
Here is the SO Answer giving the method to do it
SO Answer
I hope this fixes you issue.

Angular - Directive - retain parent scope plus attribute value

So, I am looking to write a directive that displays a given structure. These structures can be embedded inside one another so the directive simply needs to read in the structure so that it can find all of its children and display them accordingly. If one of those children is another structure, then the directive is called again with the new structure.
This is pretty standard, however I want to do not want to create a new scope since I need to call functions from the main scope.
Can I retain the original scope and still pass in information through the attributes? Is there some other way of doing this?
What I have done is below:
Call the structureContent directive with the original structure.
The directive is a template that displays the properties of the structure depending on its type. It then gets its children and if one of those children is a structure then the directive is called again.
Like I said, this isn't the problem. The problem is that I need to retain the original scope as well since I need to call functions from there.
I cannot simply call the parent as there could be multiple levels of embedded structures.
Thanks
HTML
<div layout="row" flex="100" layout-align="center start" layout-fill>
<div flex="75" class="borderRight" layout-fill>
<div layout="column" layout="start center" class="fullWidth">
<structure-content struct="vm.currentItem"></structure-content>
</div>
</div>
</div>
</md-content>
Directive
(function ()
{
'use strict';
angular
.module('app.core')
.directive('structureContent', structureContent);
/** #ngInject **/
function structureContent($templateRequest, $compile)
{ return {
restrict : 'E',
controller : ["$scope", "$element", "$attrs",
function($scope, $element, $attrs) {
$scope.$watch($attrs.struct,
function(){
$scope.structObj = $attrs.struct;
}
);
}
],
link : function(scope, element, attrs){
$templateRequest("app/main/apps/document/worksheet/views/templates/multSpec/structureContentSection.html").then(function(html){
var template = angular.element(html);
element.html(template);
$compile(template)(scope);
});
}
}
};
})();
TEMPLATE CALLED
<div layout="column"
flex="100"
class="itemListSection" >
<div class="md-3-line"
ng-if="structObj.vartype=='6'"
ng-click="vm.currentStructure=scope.thisObj; vm.currentSubItem=scope.thisObj;"
layout="row">
<for-loop-list structObj="structObj" layout-fill></for-loop-list>
</div>
<div class="md-3-line"
ng-if="structObj.vartype=='7'"
ng-click="vm.currentStructure=scope.thisObj; vm.currentSubItem=scope.thisObj;"
layout="row">
<while-loop-list structObj="structObj" layout-fill></while-loop-list>
</div>
<div class="md-3-line"
ng-if="structObj.vartype=='8'"
ng-click="vm.currentStructure=scope.thisObj; vm.currentSubItem=scope.thisObj;"
layout="row">
<if-else-loop-list structObj="structObj" layout-fill></if-else-loop-list>
</div>
<div
ng-repeat="thisObj in vm.cadwolf_worksheet | orderBy:'location' track by thisObj.itemid"
ng-switch on="thisObj.vartype"
ng-if="thisObj.parentid==structObj.itemid"
class="subSection"
ng-click="vm.currentSubItem=thisObj; vm.currentStructure=thisObj" >
<div ng-switch-when="3"><equation-list equationobject="structObj"></equation-list></div>
<div ng-switch-when="6"><structure-content structObject="thisObj"></structure-content></div>
<div ng-switch-when="7"><structure-content structObject="thisObj"></structure-content></div>
<div ng-switch-when="8"><structure-content structObject="thisObj"></structure-content></div>
</div>

Angular 1.5 - Component() Method

I'm trying to get the component method working which is new for Angular 1.5. So far I acheived the following see my jsFiddle JSFIDDLE. For some reason I can not get the templateUrl working so that I can see the html template with the defined scope. Any help would be great.
JSFIDDLE
JS
var app = angular.module('myApp', []);
app.controller('mainCtrl', function($scope) {
$scope.name = "Tony Danza";
});
app.component("myBox", {
bindings: {},
controller: function($element) {
var myBox = this;
myBox.game = 'World Of warcraft';
},
controllerAs: 'myBox',
templateUrl: "/template",
transclude: true
})
HTML
<div ng-app="myApp" ng-controller="mainCtrl">
<script type="text/ng-template" id="/template">
<div style='width:40%;border:2px solid black;background-color:yellow'>
Your Favourite game is: {{myBox.game}}
</div>
</script>
Hi {{name}}
<div my-box>
</div my-box>
</div><!--end app-->
Angular components must be elements. Use <my-box> instead of <div my-box>.
The documentation on Components doesn't make this immediately clear, but it is documented.
when you want a directive that is triggered by an attribute or CSS class, rather than an element
The directive/component comparison table also explains that restrict is unavailable for components and they are always elements.

Resources