Angular-strap: html element is rendering as text, why? - angularjs

I've just got angular-strap installed and I'm trying out some of the features. I've got a modal functioning however the content doesn't render the <br /> element, it is rendering it as text. I don't see why and the docs show that it is working correctly. As far as I can tell I'm doing everything correctly.
Can anyone spot any issue with my code? I've stripped it as bare as possible. I did previously have ngAnimate and ngSanitize included.
var app = angular.module('app', ['mgcrea.ngStrap'])
.controller('myCtrl', function($scope) {
$scope.modal = {
"title": "Title",
"content": "Hello Modal <br/> This is a multiline message!"
};
});
<html ng-app="app">
<head>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-strap/dist/angular-strap.min.js"></script>
<script src="bower_components/angular-strap/dist/angular-strap.tpl.min.js"></script>
<script src="//cdn.jsdelivr.net/angularjs/1.4.2/angular-animate.min.js" data-semver="1.4.2"></script>
<script src="//cdn.jsdelivr.net/angularjs/1.4.2/angular-sanitize.min.js" data-semver="1.4.2"></script>
<script src="app.js"></script>
</head>
<body>
Angular Strap
<div ng-controller="myCtrl">
<!-- Button to trigger a default modal with a scope as an object {title:'', content:'', etc.} -->
<button type="button" class="btn btn-lg btn-primary" data-animation="am-fade-and-scale" data-placement="center" bs-modal="modal">Click to toggle modal
<br>
<small>(using an object)</small>
</button>
</div>
</body>
</html>

Your problem may be related to the fact that Angular does not interpret HTML code when displaying any variable obtained programatically.
You should take a look at this directive: https://docs.angularjs.org/api/ng/directive/ngBindHtml, it may solve your problem!

I've got it working now.
According to the docs:
replace ng-bind with ng-bind-html, requires ngSanitize to be loaded
I set an option as per the plunkr on the docs and my code now looks like this:
var app = angular.module('app', ['ngAnimate','ngSanitize', 'mgcrea.ngStrap'])
.config(function($modalProvider) {
angular.extend($modalProvider.defaults, {
html: true
});
})
.controller('myCtrl', function($scope) {
$scope.modal = {
"title": "Title",
"content": "Hello Modal <br/> This is a multiline message!"
};
});

Related

Does angular-spinner work?

I'm trying to use angular-spinner with Angular JS 1.5.x in Chrome and every thing I try, every Plunker I find (even the one linked to the project page) fails with one error or another.
One discussion I found said I shouldn't load spin.js myself in a <script> tag but if I don't, how is it supposed to be loaded? When I don't I get an error that Spinner (or i in the minimized code) isn't a constructor. I feel like I must be missing something obvious but I've been searching and testing for hours and I don't feel any closer to a solution.
I actually don't care if I use this package, I just want a spinner so if angular-spinner is deprecated and there is a working alternative, I'm happy for the pointer. Thanks.
Use version 2 of spin.js:
<script type="text/javascript" src="//unpkg.com/angular/angular.js"></script>
<script type="text/javascript" src="//unpkg.com/spin.js#2"></script>
<script type="text/javascript" src="//unpkg.com/angular-spinner"></script>
The DEMO
var app = angular.module('myapp', ['angularSpinner']);
app.controller('MyController', ['$scope', 'usSpinnerService', '$rootScope',
function($scope, usSpinnerService, $rootScope) {
$scope.startcounter = 0;
$scope.startSpin = function() {
if (!$scope.spinneractive) {
usSpinnerService.spin('spinner-1');
$scope.startcounter++;
}
};
$scope.stopSpin = function() {
if ($scope.spinneractive) {
usSpinnerService.stop('spinner-1');
}
};
$scope.spinneractive = false;
$rootScope.$on('us-spinner:spin', function(event, key) {
$scope.spinneractive = true;
});
$rootScope.$on('us-spinner:stop', function(event, key) {
$scope.spinneractive = false;
});
}
]);
<script type="text/javascript" src="//unpkg.com/angular/angular.js"></script>
<script type="text/javascript" src="//unpkg.com/spin.js#2"></script>
<script type="text/javascript" src="//unpkg.com/angular-spinner"></script>
<body ng-app="myapp" ng-controller="MyController">
<h1>Hello Spinner!</h1>
<input type="button" ng-click="startSpin()" value="Start spinner" />
<input type="button" ng-click="stopSpin()" value="Stop spinner" />
<br />Spinner active: {{spinneractive}}<br />Started: {{startcounter}} times<br />
<span us-spinner="{radius:30, width:8, length: 16}" spinner-key="spinner-1"></span>
</body>
There's a bug: https://github.com/urish/angular-spinner/issues/26 spinner keys won't work as intended.
What worked for me was registering every spinner in an array: when you call .spin(spinnerName) just add {spinnerName: true} to some controller's array, when you call stop(spinnerName) change it to {spinnerName: false}. Then show/hide the spinner with ng-if based on an expression like ng-if="mySpinners['spinnerName'] == true"

ng-submit, removing a form, and "Form submission canceled because the form is not connected"

I'm using angular 1, and trying to set a variable when a form is submitted using ng-click or ng-submit. That variable then cascades and removes the form from the DOM using an ng-if. However, I run into the chrome error message "Form submission canceled because the form is not connected", and the form is not posted.
Here's a complete MWE:
<html>
<head>
<title>Something</title>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-if="status.value=='ok'">
<form action="url" method="post" target="_blank">
<button type="submit" ng-click="status.value='newwindow'">Open in new window</button>
</form>
</div>
<div>{{status}}</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
var ctrl = app.controller('myCtrl', ['$scope', function($scope) {
$scope.status = {'value':'ok'};
}]);
</script>
</body>
</html>
Whenever I completely remove the ng-* attributes, the form submits normally, but then the variable isn't updated.
Any suggestions on how to keep the form around just long enough to post it?
The problem in your code here is the ng-if statement. When you click the button, the status.value is updated immediately, causing a $digest cycle. The $digest cycle causes the ng-if to be false, which removes the entire div (including the form) from the DOM.
One possible fix would be to use ng-show instead of ng-if, which just hides the element, but does not remove it from the DOM.
Another possibility would be to attach the ng-click to a function which handles all the form submission logic, and perhaps even suppresses the default submission with event.preventDefault().
<html>
<head>
<title>Something</title>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-if="status.value=='ok'">
<form action="url" method="post" ng-submit="formSubmit()" target="_blank">
<button type="submit" ng-click="status.value='newwindow'">Open in new window</button>
</form>
</div>
<div>{{status}}</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
var ctrl = app.controller('myCtrl', ['$scope', function($scope) {
$scope.status = {'value':'ok'};
$scope.formSubmit=function(){
//here you can write you business logic here
};
}]);
</script>
</body>
</html>
or you can also write:
<form action="url" method="post" target="_blank">
<button type="submit" ng-click="postData()">Open in new window</button>
</form>
in your controller:
$scope.postData=function(){
//logic will be here:
}

Input value doesn't show inside bootstrap popover

I have a directive to display a bootstrap's popover where user can update some value. The problem is that my value is not visible as an input's value (it's bind, I can edit it). Same value is visible inside the popover just next to the input.
HTML
<div custom-popover popover-html="<div><span>{{costPrice}}</span><input type='text' ng-model='costPrice' /></div>"></div>
JS
$(elem).popover({
trigger: 'manual',
html: true,
content: () => {
var content = $compile(attr.popoverHtml)(scope);
return content;
},
placement: 'bottom'
});
Demo
It's of course some piece of whole project only, but it shows the issue. Any idea of how to make this value visible inside the input?
I think I finally figured out what's the issue.
You are using jquery for pop-over as it's not a good practice to use the jquery code with angular
Here in your case you are using angular and what ng-model does is it continuously watch on the element value and if it's change it calls the digest cycle to update all the values as per the model and vice versa.
So, as you have given the angular code to jquery content function it can cause the angular to stop watching for costPrice which you can see in popover if you implement it by ui-bootstrap popover or any other angular third party popovers then you can see the effects. Here is the code for that,
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="PopoverDemoCtrl">
<button style="margin:70px;" uib-popover-template="dynamicPopover.templateUrl" popover-placement="bottom-right" popover-title="{{dynamicPopover.title}}"
type="button" class="btn btn-default">Popover With Template</button>
<script type="text/ng-template" id="myPopoverTemplate.html">
<div>{{dynamicPopover.content}}</div>
<div class="form-group">
<label>Popup Title:</label>
<input type="text" ng-model="dynamicPopover.content" class="form-control">
</div>
</script>
<script>
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('PopoverDemoCtrl', function ($scope, $sce) {
$scope.dynamicPopover = {
content: 'Hello, World!',
templateUrl: 'myPopoverTemplate.html',
title: 'Title'
};
});
</script>
</div>
</body>
</html>
So as I said you gave the html with angular code to jquery to handle it and jquery cant handle the angular code so you get the error.
Hopefully this will help :)

AngularJS UI Bootstrap popover outsideclick trigger closes popover when item removed from ng-repeat

I am using the AngularJS UI Bootstrap popover with outside click trigger and a popover template. It all works as expected, except inside my template I have an ng-repeat with an option to remove one of the items in the repeat. While this all works, as soon as the item is removed, the popover closes - it is as though it thinks I have clicked outside the popover. Here is a plunk to demonstrate: http://plnkr.co/edit/vAk3y779eEmLSmIg9kb4?p=preview
JS:
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('PopoverDemoCtrl', function ($scope, $sce) {
$scope.dynamicPopover = {
templateUrl: 'myPopoverTemplate.html',
};
$scope.checklistitems = [
{check: false, text: "item 1"},
{check: false, text: "item 2"},
{check: false, text: "item 3"}
];
$scope.delete = function (item) {
var index;
index = $scope.checklistitems.indexOf(item);
$scope.checklistitems.splice(index, 1);
console.log("yo delete: " + item.text)
}
});
html:
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.2.5.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="PopoverDemoCtrl">
<span>some text to pad</span>
<button uib-popover-template="dynamicPopover.templateUrl"
type="button" class="btn btn-default"
popover-placement="bottom"
popover-trigger="outsideClick"
>Popover With Template</button>
<script type="text/ng-template" id="myPopoverTemplate.html">
<div ng-repeat="item in checklistitems">
{{item.text}}
<button ng-click="delete(item)">delete</button>
</div>
</script>
</div>
</body>
</html>
I had the same problem, I just found out it is a problem when the HTML in the popover changes!
I changed my ng-ifs to ng-show and the popover didn't close when clicking on a button.
Your solution could be to tag the deleted items and hide them, and make the real 'delete' when the popover closes!
Like this: http://plnkr.co/edit/2NifZtWtUuqh8CCBTALf?p=preview
Working Plnkr
Remove popover-trigger="outsideClick", it should work.

Firefox addon using AngularJS - "ng-src" not working

I am working on a Firefox add-on that uses AngularJS.
The issue is with 'ng-src'. It does not load the referenced image.
When I switch to 'src' the image loads fine.
Example.html and 'icon-32.png' are within same folder.
Appreciate your help in making sense of this issue.
Below are the code snippets.
Example.html
<html ng-app="MyAddon" ng-csp>
<head>
</head>
<body ng-controller="MainCtrl" dir="{{dirr}}">
<div border="0">
<img ng-src="{{logo}}" width="32" align="center">
<input id="textbox" type="text"> </input>
<button id="textboxbutton" type="button"> {{ButtonText}}</button>
</div>
<script src="lib/angular.min.js"></script>
<script src="scripts/app.js"></script>
</body>
</html>
app.js:
function MainController($scope) {
$scope.ButtonText= 'Hit me!';
$scope.dirr = 'rtl';
$scope.logo= 'icon-32.png';
};
var MyModule = angular.module('MyAddon', [])
.controller('MainCtrl', MainController)
It is because angular keeps adding unsafe: to your image url. I think this is the solution, please try: Angular changes urls to "unsafe:" in extension page
and whitelist the resource:// urls. without unsafe: it works.
I saw this from using DOM Inspector:

Resources