Angular Modal ng-click does not work - javascript

I have made a modal in angular, it pops up great but the exit button doesnt fire to close the modal. It works if the button to open is reclicked but adding a new button inside the modal does not fire the function. Btw there is no bootstrap in this.
<section class="modal" ng-show="showMenu">
<div ng-click="setActive(album)">
<p class="exit" ng-click="modalFunc()"><i class="fa fa-times-circle fa-2x" aria-hidden="true"></i></p>
<h1>{{albumMod.artist}} - {{albumMod.title}}</h1>
<ul class="tracks">
<span><img src={{albumMod.img}}></span>
<li>Album: {{albumMod.album}}</li>
<li>Price: $1.29</li>
</ul>
<form style="display: inline" action="/#cart" method="get">
<button ng-click="setActive(album); cartFunc()" id="{{album.id}}"><a>Add</a></button>
</form>
</div>
</section>
$scope.closeMenu=true;
$scope.showMenu=false;
$scope.showItems=false;
$scope.modalFunc= function(){
$scope.showMenu = !$scope.showMenu;
console.log($scope.selected);
$scope.showItems = !$scope.showItems;
$scope.closeMenu=!$scope.closeMenu;
// console.log($scope.selected.attr("id"));
};

$scope.showMenu flag which you have used to hide popup is not used correctly. When $scope.modalFunc method is called then you negate the value of $scope.showMenu and assigned. So after assignment, $scope.showMenu value will be true.
Now you have used ng-show="showMenu" so your popup will not be hide.
Correct code will be:
1. Set $scope.showMenu = true in the callback which called when popup is opened.
2. $scope.modalFunc= function(){
$scope.showMenu = !$scope.showMenu;
...
}
3. Remove $scope.showMenu=false; since it is not needed.

Related

a function runs multiple times when showing a bootstrap modal. vanilla js

I have a button that shows a bootstrap modal, it has an onclick attribute set to a function,
The button:
<span style="color:blue;margin-left: 2rem;" data-id="{{student.id}}" id="{{student.id}}"
type="button" data-bs-toggle="modal" data-bs-target="#grade-modal"
onClick="getEnrolledSubjects(this.getAttribute('data-id'))">
<i class="fas fa-plus"></i>
</span>
My javascript function:
function getEnrolledSubjects(id){
var modal = document.getElementById('grade-modal')
modal.addEventListener('shown.bs.modal', function(){
console.log(id)
}
}
at first, it looks fine because it will only log the id once, but when I close the modal and open it again, it will log 2 times, then 3 times, and so on... it goes incrementally. how can i fix this?
as Bootstrap Modal documentation
You can Use event.relatedTarget:
<span style="color:blue;margin-left: 2rem;" data-id="{{student.id}}" id="{{student.id}}" type="button" data-bs-toggle="modal" data-bs-target="#grade-modal">
<i class="fas fa-plus"></i>
</span>
without onClick event
const modal = document.getElementById('grade-modal')
modal.addEventListener('shown.bs.modal', function(event){
const button = event.relatedTarget
const id = button.getAttribute('data-id');
console.log(id)
})

How to handle event delegation with priorities?

I have this look-a-like code in my app :
let item;
$('.parent').on('click', function () {
item = $(this).attr('item') || 0;
});
$('.parent').on('click', '.children', this, function () {
doSomething();
});
<div class="parent" item="50">
<div class="children">
</div>
</div>
<div class="parent" item="51">
<div class="children">
</div>
</div>
<div class="parent" item="52">
<div class="children">
</div>
</div>
I have a parent element with several children in it. Clicking anywhere on the parent element will give me an item information, so I will be able to load functions according to this item variable on click on children.
My problem is : I have to delegate the onClick event on children to parent element otherwise the events will trigger in this order :
Click on any child
Click on parent, which is too late because I need item variable first
I have a functionality that replaces the parent element if activated, since it was dynamically inserted into the DOM, I have to delegate the onClick event as well, like this :
$('.grandParent').on('click', '.parent', function () {
item = $(this).attr('item') || 0;
});
Now my problem is that the events are triggering in the wrong order again :
Click on any child
Click on parent
How can I manage to set click event on parent as top priority?
Edit :
I will be more specific. I have a messages list on my page, each .message element contains the message content but also some functionnalities like edit, delete, set as favorite, like, etc.
Like this :
<div class="message" data-item="1">
<a class="edit">E</a>
<a class="delete">X</a>
<a class="favorite">Fav</a>
<a class="like">Like</a>
<div class="content">
Hello world !
</div>
</div>
<div class="message" data-item="2">
<a class="edit">E</a>
<a class="delete">X</a>
<a class="favorite">Fav</a>
<a class="like">Like</a>
<div class="content">
Hello world !
</div>
</div>
Each one of those functionnalities will trigger different functions when clicked : edit(), delete(), like(), etc.
All of them will make AJAX requests which will then send the item variable to my server in order to know what item has to be impacted by this click.
To avoid repetition in my events handlers, I am trying to get the data-item attribute's value with one event bound to click on .message element, relying on the bubbling of children elements.
Get the item where you actually want it and get rid of the handler on parent:
$('.parent').on('click', '.children', function () {
item = $(this).closest('.parent').attr('item');
doSomething();
});
EDIT:
Then get the item when you click on the grandparent:
$('.grandParent').on('click', '.children', function () {
item = $(this).closest('.parent').attr('item');
});
EDIT #2:
Based on the OPs updated requirements, do it like this:
<div class="message" data-item="1">
<a class="action edit" data-type="edit">E</a>
<a class="action delete" data-type="delete">X</a>
<a class="action favorite" data-type="favorite">Fav</a>
<a class="like">Like</a>
<div class="content">
Hello world !
</div>
</div>
<div class="message" data-item="2">
<a class="action edit" data-type="edit">E</a>
<a class="action delete" data-type="delete">X</a>
<a class="action favorite" data-type="favorite">Fav</a>
<a class="like">Like</a>
<div class="content">
Hello world !
</div>
</div>
$(document).on('click','.message .action',function(e) {
const item = $(this).closest('message').attr('item');
switch($(this).data('type')) {
case 'edit': doEdit(item); break;
case 'delete': doDelete(item); break;
case 'favorite': doFavorite(item); break;
}
});
See, one event handler?
It's a very common pattern to do what you're doing. In the absence of a more robust framework (e.g. React), then using plain jQuery this is how it should be done.

Why an ionic modal freezes the UI when it is closed or submitted?

I have a popover which two options -Add Favorite and Add Comment-, the first options is working correctly: it does not freeze the user interface; but the second one once the form is omitted or submitted freezes the interface. This is what is happening:
Note how when I close the form the interface does not respond.
This is the code I have used to create the popover and and modal:
$ionicPopover.fromTemplateUrl('templates/dish-detail-popover.html',{
scope: $scope})
.then(function(popover){
$scope.popover = popover;
});
$scope.openPopover = function($event){
$scope.popover.show($event);
}
$scope.closePopover = function() {
$scope.popover.hide();
};
$ionicModal.fromTemplateUrl('templates/dish-comment.html', {
scope: $scope
}).then(function(modal) {
$scope.commentModal = modal;
});
// Triggered in the reserve modal to close it
$scope.closeAddComment = function() {
$scope.commentModal.hide();
};
// Open the reserve modal
$scope.showCommentModal = function($event) {
$scope.closePopover();
$scope.commentModal.show($event);
};
The template for dish-detail-popover.html:
<ion-popover-view>
<ion-content>
<div class="list">
<a class="item" ng-click="addFavorite(dish.id)">
Add to favorites
</a>
<a class="item" ng-click="showCommentModal()">
Add Comment
</a>
</div>
</ion-content>
</ion-popover-view>
and the template for dish-comment.html:
<ion-modal-view>
<ion-header-bar>
<h1 class="title">Submit Comment on Dish</h1>
<div class="buttons">
<button class="button button-clear" ng-click="closeAddComment()">Close</button>
</div>
</ion-header-bar>
<ion-content>
<form id="comentDishForm" name="comentDishForm" ng-submit="doComment()">
<div class="list">
<label class="item item-input item-select">
<span class="input-label">Rating</span>
<select ng-model="comment.rating">
<option ng-repeat="n in [1,2,3,4,5]" value="{{n}}">{{n}}</option>
</select>
</label>
<label class="item item-input">
<span class="input-label">Your Name</span>
<input type="text" ng-model="comment.author">
</label>
<label class="item item-input">
<span class="input-label">Your Comment</span>
<input type="text" ng-model="comment.comment">
</label>
<label class="item">
<button class="button button-block button-positive" type="submit">Submit</button>
</label>
</div>
</form>
</ion-content>
</ion-modal-view>
NOTE: When the form is called from the Add Comment button (the green one), it works correctly. The failure is related when it called from the popover.
Some suggestions, or ideas,... to solve this?
The screen gets freezed because despite closing the popover before opening the modal, the body tag remains dirty with the class 'popover-open'. A quick solution, but not the neatest, is to close the popover again when closing the modal. This way, ionic framework will remove the class 'popover-open' from the body tag. Example:
$scope.$on('modal.hidden', function() {
$scope.closePopover();
});
Hope it helps.
I also ran into the same issue and had no idea why this was happening. Reading the Ionic docs about ionicPopover, I found that the .hide() method is actually returning a promise which will resolve once the popover is animated out. So, what you can actually do is setup your closePopover() method as follows:
$scope.closePopover = function () {
return $scope.popover.hide();
};
As for the method to be executed when someone clicks the "Add Comment" option, you can implement that as follows:
$scope.addComment = function addComment() {
$scope.closePopover()
.then(function() {
$scope.openAddCommentModal();
});
};
This will ensure that the modal is only shown once the popover is completely animated out and those classes are removed from the body tag. This will clear the dirty states and make the app respond.

Execute javascript again with load function

I want to create a "next" button which display different profiles. For that, I want to reload the div. I have successfull create the function, but when It's reload 1 time, javascript is not load after, so my button click function doesn't work.
My code :
<div class="col-md-6">
<div class="my" id="profile_rd">
<div class="ibox-content text-center" id="ok">
<h1>Profile example</h1>
<a class="btn btn-xs btn-prim-red" id="please_next"><i class="fa fa-chevron-right"></i> Next</a> <!-- Here, we can click and execute the function one time , after, click doesn't work -->
</div>
</div>
</div>
<script>
$('#please_next').click(function(){
$('#profile_rd').load(document.URL + ' #ok');
return false;
});
</script>
Try changing
$('#please_next').click(function(){
$('#profile_rd').load(document.URL + ' #ok');
return false;
});
to
$(document).on( 'click', '#please_next', function(){
$('#profile_rd').load(document.URL + ' #ok');
return false;
});
You're reloading the document so after the first click on the button, the DOM can't find the element that you're trying to attach the event to. You need to use event delegation.

ng-hide show on-click event in AngularJS

I have in my index.html a div which initially must be hidden:
<div class="autocomplete" ng-show="div_show" ng-controller="SearchController">
And I need when I click on my Menu on the search link,the div to be shown,basically
ng-show="true"
So on my link I defined something like that:
<a class="list-group-item" ng-click="show()"><i class="fa fa-search fa-fw"></i> Search</a>
And in my controller the function :
$scope.div_show = false;
$scope.show =function(){
$scope.div_show = true;
console.log($scope.div_show);
alert($scope.div_show);
}
When I click on the link I have the alert value set to 'true'but the div is still hidden,
Any suggestions? Thank you!!!
To toggle the ng-show element, just assign the following directive on the Menu button:
ng-click="div_show = !div_show"
All this does is toggles the value of div_show between true and false.
Here's a plunker for a full demo.
Try something like this :
<a href="#" class="list-group-item" ng-click="div_show = true">
<i class="fa fa-search fa-fw"></i> Search
</a>
This will make sure the page is not getting loaded again and i will set the div_show to be true, only if it is in the scope.

Categories

Resources