ng-click fires multiple times inside ng-repeat ie9 - javascript

I have a weird quirk that appears to only be happening in ie9 with AngularJS.
I have a repeated button with ng-repeat and a function with ng-click. When the button is clicked the function appears to run multiple times and goes between the buttons. I've tried to remove as much conflicting code as possible and whittled it down to these parts.
I have come to the conclusion that it only happens on the add remove class if else statement, when this is removed it appears to work ok.
Here is my code:
<div class="row multiple-question">
<button
data-num="{{item.QuestionNo}}"
class="ansbtn" data-ans="{{ answer.AnswerValue }}"
ng-click="triggerNext(item.QuestionNo, answer.AnswerValue)"
ng-repeat="answer in item.Answers">
<span class="letter num{{ $index + 1 }}"></span>
<h3>
<span class="circle right">
<span class="icon-checkmark"></span>
</span>
</h3>
<p>{{ answer.Answer }}</p>
<span class="arrow-right-button"></span>
</button>
</div>
And the function code is here:
$scope.triggerNext = function(QuestionNo, AnswerValue) {
console.log('function run');
console.log(QuestionNo);
console.log(AnswerValue);
if($('.ansbtn[data-ans="'+AnswerValue+'"]').hasClass('active')) {
$('.ansbtn[data-ans="'+AnswerValue+'"]').removeClass('active');
} else {
$('.ansbtn[data-num="'+QuestionNo+'"]').removeClass('active');
$('.ansbtn[data-ans="'+AnswerValue+'"]').addClass('active');
}
};

One possible solution might be to enclose the button with a div or span element, and having that serve the ng-repeat, keeping your ng-click on each button.

Hey just posting my solution, although the issue still remained if I stuck to using ng-click, the issue went away if I binded the button click to the document, this is NOT the right way to do it as I understand. But it worked.

Related

#click event not triggering alongside element with #blur

I've got a problem when working with VueJS which is kinda getting on my nerfs since I know that it probably relies on something very small but still I'm here trying to get it running for hours.
I'm using a template which should represent a searchbar with the solutions under it. To show the solutions, I'm looping over an object (I'm not done including the filtering of the solutions to that point - wanted to finish this one first). The thing I was trying to do now was filling in the searchbar value with the value I select in the solutions (passing it with a click event). But somehow my click event doesn't trigger.
I've got the following code-snippet:
<template>
<div class="input-group">
<div class="input-group-prepend">
<div class="input-group-text">šŸ”</div>
</div>
<input
type="text"
class="form-control"
#focus="searchFocus = true"
#blur="searchFocus = false"
v-model="searchQuery"
placeholder="Search for vehicles..">
<div class="container p-0">
<div class="dropdown-menu search" v-show="searchFocus">
<a class="dropdown-item bus" href="#"
v-for="vehicle in vehicleObjects"
:key="vehicle.id.key"
v-on:click="setSelectedToQuery(vehicle)">
<span class="ml-4">Bus {{ vehicle.id.name }}
<span class="badge badge-secondary"> {{ vehicle.licenseNumber }}</span>
<span>
</a>
</div>
</div>
</div>
</template>
Am I missing something quite obvious? How can I get the click-event running/triggering?
Thanks in advance
Best Regards
There are few things "off" I'll list them by level of impact
#blur fires before click, essentially invalidating #click
anchors <a ...> need to prevent redirect. You can use #click.prevent="... to prevent event propagation, or use another element, since you don't have href defined anyway.
one of your span elements is not closed (<span> instead of </span at the end)
To handle #blur blocking #click, you could use #mousedown instead of #click, since it executes first.
Maybe it's the solution: close your last span
Click work for me: https://codesandbox.io/s/morning-browser-fgftf

Onclick my 'button' opens all buttons of the same type

So this is what I have right now
http://jsfiddle.net/Wpn94/1755/
The first part of the javascript is just calling in the jQuery lib. Since I don't have acces to the original files I use a custom css, js plugin (mind this all in done in wordpress).
In the fiddle if you click on one the the 'meer' it only opens the one you've clicked. If you press 'minder'it nicely closes the one you've clicked.
Now to the issue, on my testing area if I click one of these buttons the other 5 open as well, which ofcource is not the intended use.
Is there any solution which could fix this? I'mn not able to link to the testing enviroment since it's about a product which isn't released yet, so sadly I do not have permissions to do so.
Possibly the issue:
$('.wrapper').find('a[href="#"]').on('click', function (e) {
or
$(this).closest('.wrapper').find('.small, .big').toggleClass('small big');
I think the issue is in one of those two. Since I look for the wrapper class which all the 'buttons'have in common.
Any help would be greatly appreciated.
(structure of the element on the test area)
<div class="column withimage ">
<div class="column-inner">
<div class="image" style="background-image: url(http://eperium.com.testbyte.nl/wp-content/uploads/2016/08/Icoon_orientatie_v02.png)"></div>
<div class="txtwrap"><h4><center>ORIƋNTATIE</center></h4>
<div class="wrapper">
<div class="small">
<p style="text-align: center;">
<span style="color: #000000; font-size: 16pt;">title</span><br>
<span style="color: #000000; font-size: 12pt;">text<br>more text week. </span></p>
</div>
<p style="text-align: center;"><a class="btn" href="#">Meer informatie</a></p>
</div>
What are you doing inside this function ?
$('.wrapper').find('a[href="#"]').on('click', function (e) {
You need to toogle your class on $(this) element, not to select all element with jquery again.
As closest doesn't seem to be reliable (maybe only in your test area) it is worth a try to navigate to the desired element with .parent()
$(this).parent().parent().find('.small, .big').toggleClass('small big');
If anyone is interested in the differences:
Difference between jQuery parent(), parents() and closest() functions.
According to this, closest should actually work but parent seems to be the saver way.
You can use Jquery's findByClass.
$('.className')
This will find all the elements use className.

AngularJS - ngShow/ngSwitch/ngIf - Two elements flicker

So I have a two elements that are rendered inside an ng-repeat, when I click a button that does a toggle, for a brief second both elements get shown.
I have tried various things, ngIf, ngShow, ngSwitch and ngCloak and nothing seems to work.
Here is a code sample:
<div data-ng-repeat="item in view.myModel.items">
<div class="row">
<a ng-hide="item.link" class="btn ng-cloak"
ng-click="view.getLink($index)">Get Link</a>
<a ng-show="item.link" class="btn ng-cloak"
data-ng-href="{{item.link}}" download>Download</a>
</div>
</div>
So here is the problem, on load I only see the 'Get Link' button which is fine.
As soon as I click it, it makes a http call and sets the 'items.link' value, which is where the problem happens. At that moment both buttons are shown together.
Then correctly just the download button shows.
Here is the http call if your interested:
/**
* Get a link
*/
function getLink(idx) {
Linker
.getLink(idx)
.then(onGotLink);
function onGotLink(link) {
myModel.items[idx].link = link.url;
}
}
Any ideas?
So credit to user1620220 who pointed it out. The issue is ng-animate is running that is causing the ng-hide-animate to trigger causing that slight flicker.
You can turn off ng-animate, or use CSS to turn of 'transition' if you only want to partially disable it is.

How to avoid firing an onclick() event fired when clicking a link in AngularJS

First of all, I want to say that I have seen some topics already with similar question. I have tried withe the responses of these topics, but I have not been able to find a solution for my problem. Maybe the difference is that I am using AngularJS
(HTML)
<li class="article-list_item" ng-repeat="noticia in news" >
<article class="article_news" id="newsBlock{{noticia.id}}" >
<header>
<h1 class="article_newsTitle">
<a href="http://www.google.es" rel="tooltip" title="{{noticia.title}}"
data-toggle="modal" ng-bind-html-unsafe="noticia.shortTitle"></a>
</h1>
</header>
</article>
(JS)
$(document).ready(function () {
$(".article_news").click(function (event) {
$(this).addClass("approved");
});
});
What I am trying to do is to add the class "Approved" to the object I am clicking.
But when I click the link inside the <article> , I dont want to add the Class. Instead, I want the browser to open the URL.
How can I do this? Must I use stopPropagation(), preventDefault() or similar? How should I use them?
Thanks in advance
Well, Angular automatic filter link action if you implement it in angular way. For implementing it in angular way you should create directive to bind click event which handles your issue. Still you can solve it like this.
ng-click="$event.stopPropagation()"
Your HTML
<article class="article_news" id="newsBlock{{noticia.id}}" >
<header>
<h1 class="article_newsTitle">
<a ng-click="$event.stopPropagation()" href="http://www.google.es" rel="tooltip" title="{{noticia.title}}"
data-toggle="modal" ng-bind-html-unsafe="noticia.shortTitle"></a>
</h1>
</header>
</article>

javascript does not want to parse text more than twice

So i have this function in my Js that gets called on a link onclick() event.
here is the HTML:
<li class="collapsed">
<span>
Directions
</span>
<p>ajajgajajys agajgjgtajgtdja ajdtajtjate ajgdjagjd ajt</p>
</li>
And here is the Javascript:
function expand(myElem)
{
if (myElem.parentNode.parentNode.style.height<100)
myElem.parentNode.parentNode.style.height="100px";
else
myElem.parentNode.parentNode.style.height="45px";
}
Obviosuly, the code expands the li parent tags that the links are in. Originally, the li tags are set as height:45px; in CSS. Then they change to 100px and back.
The problem im having is that the javascript only works twice.
I cna click on the links oncde and expand the li's. Then i can click on them and collapse the li's. Then it doesn't want to work again.
I was looking at my browsers errors and i found this:
"Error parsing value for 'height'. Declaration dropped.
After much trolling thru the interwebs I thought it might be because i'm not including the unit declarations in my js. But I am!
myElem.parentNode.parentNode.style.height="45px"; ---- as you can see.
****NOTES: MY SOLUTION*****
For future referance for whoever stumbles on this thread, here's my solution:
HTML --> I ened up doing somethin glike:
<span class="heading">
Link1
<span>
<span class="information">
Info about Link1
</span>
<span class="heading">
Link2
<span>
<span class="information">
Info about Link2
</span>
And the Jquery was super simple:
$(document).ready(function() {
$(".information").hide();
$(".heading").click(function(){
var item = $(this);
item.next().slideToggle(500);
});
});
...super simple, works like a charm
Try to use replace and parseInt functions like,
function expand(myElem)
{
if (parseInt(myElem.parentNode.parentNode.style.height.replace('px','')) < 100)
myElem.parentNode.parentNode.style.height="100px";
else
myElem.parentNode.parentNode.style.height="45px";
}
You can use Jquery for simplifying it like,
HTML
<li class="collapsed">
<span>
Directions
</span>
<p>ajajgajajys agajgjgtajgtdja ajdtajtjate ajgdjagjd ajt</p>
</li>
SCRIPT
$(function(){
$('.direction').on('click',function(e){
var ht= $('.collapsed').height()==100 ? 45 : 100;
$('.collapsed').height(ht);
});
});
Try
if (parseInt(myElem.parentNode.parentNode.style.height)<100)
Thank you everyone for your help.
I was able to figure out that, for some reason, after the height was set the second time around to 45px, it wasn't registering as a int anymore. idk y tho. Why would it accept a declaration of 100px the first time and register it as int but not the second time? wierd.
Anyway, i tried parseInt and it worked like a charm.
But I really like the jQuery solution that Jason P provided. the transition sold me. I'm gonna go with that.
So thanks again guys.

Categories