Append HTML Including ng-repeat directive - angularjs

I'm trying to append an alert class that includes the angular ng-repeat directive:
ng-repeat="m in orders.messages"
The html appends fine, but the angular does not bind. It simply displays one alert with {{m}} as the contents. When I check Google Developer tools, it includes the directive as well. Also, when I put the static html instead of appending it, it repeats as expected.
var validationErrors = '<div class="alert alert-warning alert-dismissible" role="alert" ng-repeat="m in order.messages"> <button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button><strong><span class="glyphicon glyphicon-warning-sign"></span> Warning!</strong> {{ m }} </div>';
$('#errorMessage').append(validationErrors);
Is there a way to append this so that the angular binds?

Related

Protractor Locating elements by by.repeater contained within a specific div

In protractor, I am trying to access the buttons repeated withina specific div with id 'CreateRFQID'. These buttons are defined a directive 'gps-button-bar'. I am trying to access them by.repeater. Because these buttons also appear else where in the page, I can not just access them through
element(by.repeater('aBtn in buttonBarController.config.buttonConfigs track by $index')).
But I am trying without success to get those buttons that are sub element of the div with id 'CreateRFQID'.
Protractor code I am trying:
var parent = element(by.css('#CreateRFQID'));
var first= parent.element(by.repeater('aBtn in buttonBarController.config.buttonConfigs track by $index')).row(0);
first.getText().then(function (text) {
console.log(text);
});
Any help how to get it?
Thanks.
View / html Fragment
<div ng-controller="CreateRFQController as createRFQCntrl" id="CreateRFQID" class="ng-scope">
<gps-button-bar config="createRFQCntrl.buttonBarConfig" class="ng-isolate-scope"><div class="container-fluid">
<div class="row row-buttonBar">
<label><h1 class="panel-title ng-binding">RFQ Create </h1></label>
<span class="pull-right">
<span ng-repeat="aBtn in buttonBarController.config.buttonConfigs track by $index" style="padding-right: 2px" class="ng-scope">
<button class="btn btn-default btn-xs ng-binding" id=""myButton"+$index" ng-click="buttonBarController.clickHandler($index);" data-toggle="tooltip" data-placement="top" title="Create" ng-show="buttonBarController.gpsShownButtons[$index]" ng-disabled="buttonBarController.gpsDisabledButtons[$index]">
<span class="fa fa-floppy-o"></span> Create
</button>
</span><!-- end ngRepeat: aBtn in buttonBarController.config.buttonConfigs track by $index -->
</span>
</div>
You have a problem in the selector, you don't do .row on the result of element but on the by
var parent = element(by.id('CreateRFQID'));
var first = parent.element(by.repeater('aBtn in buttonBarController.config.buttonConfigs track by $index').row(0));
first.getText().then(function (text) {
console.log(text);
});

angular bootstrap html popover not being displayed

I'm trying to use the uib-popover-html directive and it doesn't display. If I use the uib-popover or uib-popover-template directive it displays correctly. Am I missing something?
This works
$scope.dynamicPopover = {
content: 'Hello, World!',
templateUrl: 'app/login/popover.html',
title: 'Title'
};
<!-- popover.html -->
<div>
<b style="color: red">I can</b> have <div class="label label-success">HTML</div> content
</div>
<!-- /popover.html -->
<button uib-popover="I appeared on mouse enter!" popover-trigger="mouseenter" type="button" class="btn btn-default">Mouseenter</button>
<button uib-popover-template="dynamicPopover.templateUrl" popover-title="{{dynamicPopover.title}}" type="button" class="btn btn-default">Popover With Template</button>
This doesn't
<button uib-popover-html="htmlPopover" class="btn btn-default">HTML Popover</button>
Try using $sce (Strict Contextual Escaping) to show that the HTML is safe:
$htmlPopover = $sce.trustAsHtml('<div>Popover Content</div>');
This feature exists to avoid user's from inputting HTML that could be nefarious into a form, etc.
References: https://docs.angularjs.org/api/ng/service/$sce

Using href Within ng-repeat

I am using AngularFire and Firebase to store objects which contain a title and a url. I call the object list. I want to:
ng-repeat through my array of objects.
Use the list.url to download the URL's contents. All of the URL's are links to either a .js or a .css file.
Apply the download link/function to a button that is nested inside an input-group (Bootstrap 3.3.6).
All of this to be done within a routed view (ui-router)
What the buttons look like within the input-group
Here's my div. It's nested within a routed view. I am working on the first button within input-group-btn.
<div class="list-group">
<a class="list-group-item" ng-repeat="(id, link) in links | filter: search | orderBy: '-downloadCount' | limitTo: 5">
<h4 class="align-left list-group-item-heading">{{ link.name }}</h4>
<h4 class="align-right list-group-item-heading">{{ link.downloadCount }}</h4>
<br>
<br>
<div class="list-group-item-text">
<div class="input-group">
<input type="text" class="form-control" readonly value="{{ link.url }}" />
<div class="input-group-btn">
// *** IT'S THIS FIRST LINK THAT ISN'T WORKING ***
<button class="btn btn-default" ng-href="{{link.url}}"><i class="glyphicon glyphicon-download"></i></button>
<button class="btn btn-primary" ng-click="copyToClipboard(link)" tooltip-placement="bottom" uib-tooltip="Copy"><i class="glyphicon glyphicon-copy"></i></button>
</div>
</div>
</div>
</a>
</div>
When I use anchor tags instead of button tags, the ng-repeat goes crazy, the links get all kinds of messed up, formatting goes haywire, and there ends up being only one copy of the button that doesn't even work.
I'm not sure if I'm supposed to interpolate the link that ng-href is referring to, but I've tried it with and without and I still don't have anything.
Here's my JS to answer a comment.
var ref = new Firebase('https://myApp.firebaseio.com/links');
$scope.links = $firebaseArray(ref);
$scope.addLink = function () {
$scope.links.$add({
name: $scope.newLinkName,
url: $scope.newLinkUrl,
downloadCount: 1
});
$log.info($scope.newLinkName + ' added to database');
$scope.newLinkName = '';
$scope.newLinkUrl = '';
};
$scope.incrementDownloadCount = function (link) {
link.downloadCount += 1;
var tempCount = link.downloadCount;
var currentRef = new Firebase('http://myApp.firebaseio.com/links/' + link.$id);
// update the downloadCount
currentRef.update({ downloadCount: tempCount });
// update priority for sorting
currentRef.setPriority(tempCount);
$log.info(link.name + ' downloadCount changed to ' + link.downloadCount);
};
// Possibly relevant includes
ui.router
ui.bootstrap
firebase

Bootstrap and angular - pass object to modal

I create table using bootstrap and angular use object to display data. I want to open popup window to change object property by clicking row (and use angular binding in modal to work with object).
So my issue that i doesn't understand how to pass object from table to modal.
I found many examples with passing values and changing html on fly but in my case i want to use angular for binding and want to pass reference to object.
Sample of table:
<table class="table table-condensed table-bordered">
<thead>...</thead>
<tbody>
<tr ng-repeat="property in properties" data-toggle="modal" data-id="property" data-target="#editPropertyModal">
<td>{{property.name}}<td/>
<td>{{property.value}}<td/>
<td>...<td/>
</tr>
</tbody>
</table>
So by clicking this row i want to open modal and pass there property object and use controls like input, combobox to bind values via angular.
My sample of modal:
<div class="modal fade" id="editPropertyModal" tabindex="-1" role="dialog" aria-labelledby="editPropertyModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="editPropertyModalLabel">Property details</h4>
</div>
<div class="modal-body">
{{currentProperty.name}} - {{currentProperty.value}}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
My try to pass property via javascript:
$(document).on("click", ".open-editPropertyModal", function (e) {
e.preventDefault();
var _self = $(this);
var property = _self.data('id');
$("#currentProperty").val(property);
$(_self.attr('href')).modal('show');
});
Doesn't work.
You can use this to do that. It really helped me.
Default Bootstrap JavaScript is not working well with angular, because it makes changes in DOM model outside AngularJS. Please consider using native directives for bootstrap, like these http://mgcrea.github.io/angular-strap/
Also, for maximum simplicity, in many cases, you can use something like this plugin https://github.com/cgross/angular-prompt. It depends on bootstrap and gives you simple API based on promises.
prompt({
title: 'Give me a name',
message: 'What would you like to name it?',
input: true,
label: 'Name',
value: 'Current name',
}).then(function(name){
//name contains new value
});
Callback passed to then will be executed after clicking "OK" in popup.

How to show div when link is clicked with ng-show angular js

first off, i have links from a json and display it using ng-repeat and i want to know if its best practise to load all object property (in a div) corresponding to its link and hide it so when you click a link, the corresponding div shows.
I'm thinking about the worst case scenario, were we have about a 100 links and the load all corresponding divs and hide it o_O
So this is my html:
<a href="">
<div ng-model="showModal" class="contentItem" ng-repeat='meal in recipes | filter:searchText' ng-style="{'background-image':'url({{ meal.url }})'}">
<span id="contentItemHeader">{{ meal.title }}</span>
<span id="contentItemLevel">{{ meal.level }}</span>
</div>
</a>
This is the div (modal) i want to display in full screen:
<div ng-show="showModal" ng-repeat='meal in recipes'>
<span>{{ meal.url }}</span>
<span>{{ meal.method }}</span>
<span>{{ meal.ingredients }}</span>
</div>
Use case is:
-all links loads
-click a link
-corresponding div shows
Thats it ! just like when you see a list of videos on youtube, you click one, then the video page opens but as a modal (same page)
Thanks alot,
regards
You can utilize $modal service from the UI Bootstrap, define template for meal's modal and attach ng-click handler on each individual meal in ng-repeat. In click handle you can open modal and pass meal instance to modal's scope:
View:
<div ng-repeat='meal in recipes' ng-click='selectMeal(meal)'>
{{meal.title}}
</div>
Conrtoller:
$scope.selectMeal = function(meal) {
var dialogScope = $scope.$new(true);
dialogScope.meal = meal;
var modalInstannce = $modal.open({
templateUrl: 'meal-dialog.html',
scope: dialogScope
});
};
Modal template:
<div class="modal-header">
<h3 class="modal-title">{{ meal.title }}</h3>
</div>
<div class="modal-body">
<div>{{ meal.url }}</div>
<div>{{ meal.method }}</div>
<hr />
<h4>Ingridients</h4>
<ul >
<li ng-repeat='ingridient in meal.ingridients' >{{ingridient.name}} : {{ingridient.amount}}</li>
</ul>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="$close()">Close</button>
</div>
Plunker here
To show div in question, when meal selected, introduce new selectedMeal property in $scope and use it in modal template, remove ng-repeat from modal div and set selectedMeal and showModal in selectMeal function:
$scope.selectMeal = function(meal) {
$scope.selectedMeal = meal;
$scope.showModal = true;
};
<div ng-show="showModal" >
<span>{{ selectedMeal.url }}</span>
<span>{{ selectedMeal.method }}</span>
<span>{{ selectedMeal.ingredients }}</span>
</div>
if your worried about performance of having all the divs exist, but hidden, consider using ng-if instead of ng-show. ng-if does not create the dom element if the expression is false.
<div ng-if="expression">
//element exists if 'expression' is true
</div>
if you are ok to ahead with angular-ui then i think the accordian fits the requirement perfectly... [here's the link for angular-ui's the accordian] directive 1
angular-ui is the pure angularjs implementation of all twitter bootstrap components.
<accordion close-others="oneAtATime">
<accordion-group heading="Static Header, initially expanded" is-open="status.isFirstOpen" is-disabled="status.isFirstDisabled">
This content is straight in the template.
</accordion-group>
<accordion-group heading="{{group.title}}" ng-repeat="group in groups">
{{group.content}}
</accordion-group>
</accordian>
you can have either one or all user selected link detail section open at a time...

Resources