AngularJS ui-sref on infoWindow not working - angularjs

The problem is that to click on the name of infoWindow redirection does not work with ui- sref or ng-click inside marker.content
index.html
<div ng-controller="MapCtrl">
<div id="mapPage" class="mapPageStyle left" >
<div id="mapPageContent" style="height:100%;background:#fff;">
<div id="mapContainer" ng-repeat="marker in markers">
</div>
</div>
</div>
</div>
controller_map.js (MapCtrl)
function createMarker(info) {
var marker = new google.maps.Marker({
map: $scope.map,
position: new google.maps.LatLng(info.lat, info.long),
title: info.name,
icon: info.markerImage
});
var myClass = [];
marker.content = '<div id="hook" class="hook" >' +
'<div class="nameInfoWindow" ui-sref="page_center/comercio({IdBusiness: info.id })">' + info.name + '</div>' +
'<div style="text-align: center;">' +
'<div class="ec-stars-wrapper">' +
'</div>' +
'</div>' +
'</div>';
google.maps.event.addListener($scope.map, 'click', function () {
infoWindow.close();
});
google.maps.event.addListener(marker, 'click', function () {
infoWindow.setContent(marker.content);
infoWindow.open($scope.map, marker);
});
$scope.markers.push(marker);
}

Your example doesn't work because you need to $compile the harcoded template. Here you have a thread talking about compiling html from controller, the second answer talks about "working outside angular scope and expects angular parse the scope", he creates an object wich compiles html&angular dynamic code
AngularHelper.Compile = function ($targetDom, htmlToCompile, applicationName)
Injecting html from controller directly is not a god practice due to performance issues.
It could be better an angular ready implementation like angular maps, with angular maps plugin you could implement something like:
<ui-gmap-google-map
center='map.center'
zoom='map.zoom'
options='options'
control='map.control'>
<ui-gmap-markers idKey="'bid'" models="map.markers" coords="'self'">
<ui-gmap-windows show="show">
<div ng-controller="MapClickCtrl">
<h5 ng-non-bindable>{{title}}</h5>
<button class="button" ng-click="goTo('page')">Detail</button>
</div>
</ui-gmap-windows>
</ui-gmap-markers>
</ui-gmap-google-map>
This is a working example, the method goto() is fired in MapClickCtrl.

Related

angular js opening modal after ajax call - not updaing html

Making an ajax call after a button click and updating the html inside the modal via angular js. Sometime html inside modal is not updating. Tried $scope.$apply(); function but still its not updating sometimes. Provided the angular js and bootstrap code below . editfilterrules function is called after clicking on a button,
$scope.editfilterrules=function(filterid,initid){
console.log('edit filter rules filterid:' + filterid + ' initid:' + initiativeid );
$http({
method : "GET",
url : 'testoptions.php?filterid=' + filterid + '&initid=' + iniid
}).then(function mySucces(response) {
// console.log(response.data);
$scope.filterrulesDivCon=$sce.trustAsHtml(response.data);
// $('#filterrulesDiv').html(response.data);
// $scope.$apply();
$('#editfilterrulesModal').modal();
}, function myError(response) {
});
}
<div class="modal fade" id="editfilterrulesModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Edit Filter Rules</h4>
</div>
<div class="modal-body">
<div id="filterrulesDiv" ng-bind-html="filterrulesDivCon" ng-cloak> </div>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
As pointed out by #llp you are opening your modal out of angular scope,instead you can use Bootstrap UI modal which is lot flexible.
you can also use $apply() and do something like this if you are not thinking to use bootsrap.
$scope.editfilterrules=function(filterid,initid){
console.log('edit filter rules filterid:' + filterid + ' initid:' + initiativeid );
$http({
method : "GET",
url : 'testoptions.php?filterid=' + filterid + '&initid=' + iniid
}).then(function mySucces(response) {
$scope.filterrulesDivCon=$sce.trustAsHtml(response.data);
$scope.$apply(function() {
$('#editfilterrulesModal').modal();
});
}, function myError(response) {
});
}
with Bootstrap UI
Below I've added a sample code snippet on how to achieve the same.Here is a plunker for demo
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);//add bootstrap dependency
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($uibModal, $log, $document) {
var $ctrl = this;
$ctrl.items = ['item1', 'item2', 'item3'];
$ctrl.animationsEnabled = true;
$ctrl.open = function (size, parentSelector) {
var parentElem = parentSelector ?
angular.element($document[0].querySelector('.modal-demo ' + parentSelector)) : undefined;
//this opens the modal and an instance is created and assigned to variable..
var modalInstance = $uibModal.open({
animation: true,
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
templateUrl: 'myModalContent.html',//HTML content
controller: 'ModalInstanceCtrl',//specific controller for modal
controllerAs: '$ctrl',
size: size,
appendTo: parentElem,
resolve: {
items: function () {
return $ctrl.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$ctrl.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
});
It seems that the way you called the modal is out of the scope of angular.
Actually, it doesn't recommended using jQuery and Angular at the same time.
If you want to use the Bootstrap style, I suggest you to use UI-Bootstrap.It contains a set of native AngularJS directives based on Bootstrap's markup and CSS.
And the Modal directive.
Hope this will help you.

Unable to make angular-formly work within a ng-template of an angular-ui-bootstrap modal

I am using angular-formly to build a form inside an angular-ui-bootstrap modal, the following code works when the form is placed outside the modal template but it doesn't when placed inside the ng-template, it just doesn't print the fields at all.
I believe this should work but I don't know how the life-cycle of angular-formly runs, so I am unable to identify how to make the fields show up inside my bootstrap modal template.
The issue is clearly related to the ng-template, it appears not to render the form even if the fields array is passed correctly.
var app = angular.module("demo", ['dndLists', 'ui.bootstrap', 'formly', 'formlyBootstrap']);
app.controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, items, User) {
var vm = this;
vm.loadingData = User.getUserData().then(function(result) {
vm.model = result[0];
vm.fields = result[1];
vm.originalFields = angular.copy(vm.fields);
console.log(vm);
});
});
app.controller("AdvancedDemoController", function($scope, $uibModal){
$scope.modalOpen = function(event, index, item){
var modalInstance = $uibModal.open({
animation: true,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: 'md',
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
});
In my view:
<!-- Template for a modal -->
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h3 class="modal-title">I'm a modal!</h3>
</div>
<div class="modal-body">
<div ng-if="vm.loadingData.$$state.status === 0" style="margin:20px 0;font-size:2em">
<strong>Loading...</strong>
</div>
<div ng-if="vm.loadingData.$$status.state !== 0">
<form ng-submit="vm.onSubmit()" novalidate>
<formly-form model="vm.model" fields="vm.fields" form="vm.form">
<button type="submit" class="btn btn-primary submit-button">Submit</button>
</formly-form>
</form>
</div>
<ul>
<li ng-repeat="item in items">
{{ item }}
</li>
</ul>
Selected: <b>{{ selected.item }}</b>
</div>
</script>
Any ideas?
When calling $uibModal.open you need to specify controllerAs: 'vm' (that's what you're template assumes the controller is defined as).

How to Show Dynamic Content on Ionic Custom POPUP

http(req).success(function(r){
var test = {};
test.a = res.a;
test.b = res.b;
var array-list = res.z;
var details = popup.show({
template : '<div class="row"><div class="row">' +
'<div class="col col-40"><span>{{test.a}}</span></div>' +
'<div class="col col-40"><span>{{test.b}}</span></div>' +
'</div></div><ul class="list"><li class="item" ng-repeat="list in array-list">{{list.a}}</li></ul></div>',
title :'Some Text',
scope:$scope,
buttons:[{
test:'Close',
onTap:function(e){
e.preventDefault();
details.close();
}
}]
});
Can any one correct me where i caught wrong in implementing Ionic Pop-up with custome template and with ajax response dynamic content.
You have a typo. In Success function. You are getting "r" and you are using "res". Otherwise the code has one more thing missing. Where is your
details.then(function(result){
//do something here with result
})
Without this the popup wont show up. I GUESS.
try this...
var details = $ionicPopup.show({
template : '<div class="row"><div class="row">' +
'<div class="col col-40"><span>{{test.a}}</span></div>' +
'<div class="col col-40"><span>{{test.b}}</span></div>' +
'</div></div><ul class="list"><li class="item" ng-repeat="list in array-list">{{list.a}}</li></ul></div>',
title :'Some Text',
scope:$scope,
buttons:[{
test:'Close',
onTap:function(e){
e.preventDefault();
details.close();
}

How to add a line break in an Angular Foundation Popover content?

This seems like it should be a simple problem but it's turning out to be a lot more involved that I initially thought.
I have a couple of items inside my Angular Foundation Popover directive that i would like to separate with a line break.
.div{ 'popover' => "Name: {{ user.name }} /br Age: {{ user.age }}", 'popover-trigger' => 'click' }
What is the solution to adding a line break where the /br is in this line of html?
This is quite tricky. If you are using angular-foundation (and I realy recommand to use it), you can modify the official popover template to be HTML unsafe - than you can use HTML in popovers:
JS
"use strict";
// app definition - don't forget to include angular-foundation module
angular.module("app", ["mm.foundation"]);
// just o controller, nothing special
angular
.module("app")
.controller("MainController", MainController);
function MainController() {
var vm = this;
vm.name = "John Doe"
vm.email = "john.doe#example.com"
}
// unsafe filter - this is used in the template below
angular
.module("app")
.filter("unsafe", unsafe)
function unsafe($sce) {
return function (val) {
return $sce.trustAsHtml(val);
};
};
// oficial popover template modification
angular
.module("template/popover/popover.html", [])
.run(["$templateCache", function($templateCache) {
$templateCache.put("template/popover/popover.html",
"<div class=\"joyride-tip-guide\" ng-class=\"{ in: isOpen(), fade: animation() }\">\n" +
" <span class=\"joyride-nub\" ng-class=\"{\n" +
" bottom: placement === 'top',\n" +
" left: placement === 'right',\n" +
" right: placement === 'left',\n" +
" top: placement === 'bottom'\n" +
" }\"></span>\n" +
" <div class=\"joyride-content-wrapper\">\n" +
" <h4 ng-bind-html=\"title | unsafe\" ng-show=\"title\"></h4>\n" +
" <p ng-bind-html=\"content | unsafe\"></p>\n" +
" </div>\n" +
"</div>\n" +
"");
}]);
HTML
<main ng-app="app" ng-controller="MainController as vm">
<div class="row">
<div class="small-12 column">
<div popover="{{vm.name + '<br />' + vm.email}}" popover-trigger="mouseenter">
<h1>Hover me!</h1>
</div>
</div>
</div>
</main>
Here you are working CodePen example.
You can also make your own directive to have both HTML safe popovers and HTML unsafe popovers - or you can use tooltip insetead which has support for HTML unsafe by default (directive tooltip-html-unsafe).

Angular Directive parent template?

Let's say I have something like:
<body>
<section id="page_content">
<div myDirective></div>
</section>
</body>
And I want my AngularJS directive to return:
<body>
<div id="newDivFromDirective">
...with some stuff inside!
</div>
<section id="page_content">
<div myDirective></div>
</section>
</body>
I currently have:
myAngularApp.directive('myDirective', function() {
return {
template: '<div id="newDivFromDirective" style="display: none">' +
'...with some stuff inside!' +
'</div>'
}
});
But that doesn't return the result I need. I looked into using link - but unsure how I can use template with link too and then get element.parent I guess?
You can use the Node.insertBefore() function to move the element to somewhere else in the link function. Based on the structure above, you want it to be before the parent element so you need to basically do grandParentNode.insertBefore(directiveElemNode,parentNode).
Here is a simplified directive code that you can use:
app.directive('myDirective', function() {
return {
template: "<div>... some text</div>",
link: function(scope,elem,attrs) {
var myParent = elem.parent();
var newParent = myParent.parent();
newParent[0].insertBefore(elem[0],myParent[0]);
}
};
});
If as you said you don't mind it being after the <section> element then you can also do myParent.after(elem)
Node.insertBefore() - https://developer.mozilla.org/en-US/docs/Web/API/Node.insertBefore
Sample plunker - http://plnkr.co/edit/FD08cP4aj0InJwf8okeC?p=preview

Resources