ionic-modal and img directive don't play nice - angularjs

I am using ionic to build an app. I've written a global img directive that displays an alert box whenever an img is loaded. The problem I am facing is this directive is called for all views, but if I display an image inside an ionic-modal, the directive is not called.
My directive code is:
.directive('img', function () {
return {
restrict: 'E',
link: function (scope, element, attrs) {
console.log ("********** IMG DIRECTIVE ");
}
}
})
I've added a codepen here so you can see what is going on. It's a fork from a standard ionic modal example, so has some redundant code.
http://codepen.io/asker/pen/YXXyZj?editors=101
a) Click on the link at the bottom of the home page that says "CLICK ON IMAGE TO SEE DIRECTIVE" and you will see just before the image loads, the directive alert displays
b) Click on "Sign In" on home page and in the next page, click "Open Modal" button - and you will see the image show up but my directive not called
Thanks

I think it is because your img directive is called when you click "Sign In", the home tab loaded the modal.html in your HomeTabCtrl before you click "Open Modal".
You can make changes like following:
Changes to home.html: use ng-click="openModal()" instead of ng-click="modal.show()"
Changes to HomeTabCtrl:
$scope.openModal = function(){
$ionicModal.fromTemplateUrl('modal.html', function($ionicModal) {
$ionicModal.show();
}, {
// Use our scope for the scope of the modal to keep it simple
scope: $scope,
// The animation we want to use for the modal entrance
animation: 'slide-in-up'
}); }

Related

expand page element in a modal

I have a widget in the page that shows google chart for some data with couple of filters to filter the chart data and with a print icon to print it.
I want to add a button to open this same widget with the chart, filters and print functionality working in a modal with a larger screen view. because the widget is small in the page.
I have tried to add a button, and added a function for this button in the link function to open element.html() in a modal, the html worked but the issue is that the filters and the print are not functional .
What's wrong with element.html() ? I have tired to use $compile but it got me into many errors. what can I use?
app.directive("widget", function ($rootScope) {
return {
restrict: "EA",
scope: {
title: '=',
options: '='
},
transclude: true,
templateUrl: "widget.html",
link: function(scope, element, attrs, ctrl, transclude) {
scope.print = function() {....}
scope.filterChart = function() {....}
scope.expand = function() {
$rootScope.openModal("expand Modal", element.html(), {});
}
}
}
note that $rootScope.openModal is just a wrapper service that uses the $modal service, takes a title and a body
I think we have some issue with design.
To sort things out:
You have some logic (in your case "widget with the chart, filters and print functionality")
This logic should be implemented in directive or component (1.5+).
So directive name is widget like you did.
This directive you can implement in main page (what you did so far) or as part of modal. The modal is wrapper only for your widget. So create new emplty modal, put inside <widget title="xx" options=someOptions></widget> on you are fine
Since you have isolate scope directive I don't see any problem to make it work.

Angular: ng-bind-html removing ng directives from HTML data fetched from Firebase

I am saving data in firebase from WYSIWYG editor using angularJS. This data will be in HTML format.
I am fetching HTML data from firebase and with the help of angular directive ng-bind-html this HTML content is sanitized and text saved on the editor will be shown to the user. This text could contain text, images, links.
<div ng-bind-html="newHTML" ng-model="cleanText1"></div>
The HTML coming for data with link is in the below format:
<p>This is text editor link<br></p>
Now if I click this link on the page it will redirect to the URL specified.But I want this link to open the page in a div which is to the right hand side of the page.
To prevent this behavior I replaced href with ng-href using code below:
$scope.newHtml=$scope.htmlcontent1.replace("href","ng-href");
$scope.newHTML=$sce.trustAsHTML($scope.newHtml);
Doing this ng-bind-html removed ng-href
<p>This is text editor <a>link</a><br></p> Which made it unclickable.
Also I have tried to add directive for a tag so that once user clicks this link I can give my own functionality instead of redirecting the user.
Directive looks like this:
app.directive('a', function ($compile) {
return {
restrict: 'AE',
link: function (scope, elem, attrs) {
var href = elem.children('a').attr('href');
console.log("href"+href);
elem.children('a').attr('href', null);
elem.children('a').attr('ng-click', 'open()');
$compile(elem.contents())(scope);
console.log("elem"+elem.children('a').attr('href'));
scope.open = function () {
alert('1');
}
}
}
})
But directive is being called once the user clicks and is redirected to the new page.
Any ideas how to make this link open in right hand side of the page?
Appreciate your help.
Let's make some tweaks in your code to get it in action.
Try this instead.
Make your own directive for sanitizing HTML in place of using ng-bind-html.
Replace
<div ng-bind-html="newHTML" ng-model="cleanText1"></div>
To
<div cleanHtml="newHTML" ng-model="cleanText1"></div>
cleanHTML will be a customized directive.
Make below directive in app.js to render HTML content.
app.directive('cleanHTML',['$compile',function ($compile) {
return function(scope, element, attrs) {
scope.$watch(
function(scope) {
return scope.$eval(attrs.compile);
},
function(value) {
console.log(value)
// Here you can see your HTML is going to get sanitized below
element.html(value);
$compile(element.contents())(scope); // After this HTML will be sanitized.
}
)};
}])
Next is to suppress the behavior of href and apply a click function on the link so as to define your own functionality for the link.
Now replace this:
$scope.newHtml=$scope.htmlcontent1.replace("href","ng-href");
$scope.newHTML=$sce.trustAsHTML($scope.newHtml)
To
$scope.newHtml=$scope.htmlcontent1.replace
("<a ","<a ng-click=\"$event.preventDefault();open()\"");
$scope.open = function()
{
alert("Whoa! It worked :)");
//Write your code here
}
This replacement will add ng-click to Link.
For e.g. if your HTML is like this
link
It will become like this
<a ng-click="$event.preventDefault();open()" href="http://someLink">link</a>
$event.preventDefault() has been added to override href functionality so that ng-click functionality takes priority.
Now once you are able to make your link working after that comes the display part which is now a piece of cake.
You want that on click of that link content appears to the right hand side of the page.
You can fetch the content of the link and add in scope variable like this:
$scope.newHtml=$scope.htmlcontent1.replace("<a ","<a ng-click=\"$event.preventDefault();open()\"");
$scope.open = function()
{
alert("Whoa! It worked :)");
//Write your code here
//fetch the content in var content
$scope.linkContent= content;
}
use linkContent and add it to the right hand side of the DIV of HTML page where you want to display and it's done :)
<div>{{linkContent}}</div>
Hope it works.
Happy Coding !!!

How to hide a ionic modal that shows a list after selecting a value?

I have a ion-view that shows a list of items in a modal. I want to dismiss the modal once I select an item. I have associated the modal template with a controller using an ng-controller attribute.
How do I dismiss the modal form inside the controller where I will be getting click events ?
try like this
$scope.modal.hide();
If you are using multiple modals, give different names to scope variables..
$ionicModal.
fromTemplateUrl('example.html', {
scope: $scope,
animation: 'slide-in-up' }).
then(function(modal) {
$scope.exmapleModal = modal;
$scope.exmapleModal.show();
$scope.closeExample = function() {
$scope.exmapleModal.hide();
$scope.exmapleModal.remove();
};
});
Close the modal the same name as
$scope.closeExample();

How can I remove :active from bootstrap button

I have a website, where I have multiple buttons. Once a button is pressed I populate a list, though my problem is that the last pressed button keeps to be looking pressed (has the :active class). I thought about using angular's $timeout to reset the button, though the removeClass function doesn't do the trick.
My view looks like this:
div(ng-controller='productButtonController')
div(ng-repeat='product in products')
div.col-md-4
button.btn.btn-block.sell-button(id='{{product._id}}' ng-click='sell()'){{product.name}}
and my controller:
app.controller('productButtonController', ['$scope', '$timeout', 'productServices', 'flash',
function($scope, $timeout, productServices, flash) {
productServices.getProducts()
.success(function(result) {
$scope.products = result.data
})
.error(showErrorMessage(flash))
$scope.sell = function() {
console.log(this.product)
that = this
$('#' + that.product._id).removeClass('active')
}
}
])
Add the angular $window service to your dependencies for the
controller
Call the blur method on the document's active element, which will be
your button.
$window.document.activeElement.blur();
See How do you clear the focus in javascript?.
This code from Justin Poehnelt's handy GIST solves this elegantly.
app.directive('blur', [function () {
return {
restrict: 'A',
link: function (scope, element) {
element.on('click', function () {
element.blur();
});
}
};
}]);
Add the blur attribute to a button/element you need blurred after click. Eg.
<button type="button" blur>Click me</button>
If you simply want to override the focus status of the bootstrap buttons you could do it with:
.btn:focus{
outline: none;
}
Then your buttons should look like:
<button class="btn btn-default">My button 1</button>
It's also important that the stylesheet which overrides the button status is loaded after the bootstrap stylesheet.
EDIT:
Sorry, but the previous step only removes the outline. The background-color of the button still remains the same.
Since bootstrap doesn't append any active classes to the clicked element as far as i know you need to change the :focus status of the button:
$('#' + that.product._id).blur();
Let me know if this works for you.

Click event gets executed even after window.confirm returns false in angular confirmation dialog

Based on the example given here I have written a directive to display a confirmation dialog in Angular when a button is clicked. The problem is even after the user clicks on the cancel button on the confirmation dialog, the ng-click action gets triggered.
This is the directive:
app.directive('ngConfirmClick',function(){
return {
link: function(scope, element, attr) {
var msg = attr.ngConfirmClick;
var clickAction = attr.ngClick;
attr.ngClick = "";
element.bind('click', function(event) {
if(window.confirm(msg)){
scope.$eval(clickAction);
}
});
}
}
});
This is the section of my index.html that has the ng-confirm-click directives:
<input class="delete" type="button" value="" ng-click="delete(item._id)"
ng-confirm-click="Are you sure you want to delete?">
I tried setting a priority of -1 for the ng-confirm-click directive and that did not help either.
When I was debugging the code on firebug, I found that window.confirm DOES return false when the user clicks on Cancel, so I am not sure why the ng-click (clickAction in the directive code above) is getting executed.
Is there a way to stop propagating the click action if window.confirm returns false?
Any help would be appreciated.

Resources