Change event being called on click - javascript

I am making a chrome extension and the popup has a single input element to which I'm programmatically assigning an on-change event listener.
$(".search").change(function() {
console.log($(this).val());
});
Here is the html
<div class="title">extension</div>
<div class="animated-page-container">
<div class="stats">
<h1></h1>
</div>
<div class="website">
<div class="search-container">
<div class="search-box">
<div class="container">
<div class="search-icon"></div>
</div>
<input class="search" id="search" />
<div class="icon-container">
<div class="add"></div>
<h1 class="tooltip">Add to list</h1>
</div>
</div>
</div>
<div class="website-list-container">
<div class="website-list"></div>
</div>
</div>
</div>
I have a search icon with class search-icon next to it which has no event listeners attached to it.
The onchange event never gets fired when the input value changes. Instead when i click on the search icon it fires the onchange event. Chrome dev tools doesn't even show any listener being attached to the search icon. I have tried replacing the class of search with an id and attaching a listener to it, but in any case the behaviour remains the same.

The onchange event is always fired when the element loses focus, after the content has been changed. If you're looking for an event that fires immediately after each input, try the oninput event like so:
$(".search").on("input", function() {
console.log($(this).val());
});

Related

Angular click event inside another click event

I have the following setup in my page
When I click the main box for a division it becomes selected then the department and teams are updated in the tabs on the right. However I also want to click the edit icon to edit the name of the division.
Because the edit click event is inside the select division click event both events are being triggered when I click on edit.
What would be the solution to this? How do I click the edit button and only trigger that event without triggering the select division event? Do I have to move it outside the html then relative position it? Is there a better way?
<div class="divisionList">
<div *ngFor="let division of filteredDivisions" (click)="selectDivision(division)"
<form [formGroup]="formDivision" fxLayout="row" class="divisionForm">
<h4 *ngIf="!isDivisionNameBeingEdited(division)">{{division.name}}</h4>
<input matInput #editTitle (change)="submit()"
*ngIf="isDivisionNameBeingEdited(division)" class="mrmd titleInput"
id="title2" formControlName="division" />
<div fxFlex></div>
<mat-icon (click)="editDivisionName(division)">edit</mat-icon>
</form>
</div>
</div>
This the way click events are handled in JavaScript. They 'bubble' or propagate up through the parent elements. You'll need to handle the event and explicitly tell it to not propagate up the chain of elements.
<div class="divisionList">
<div *ngFor="let division of filteredDivisions" (click)="selectDivision(division)"
<form [formGroup]="formDivision" fxLayout="row" class="divisionForm">
<h4 *ngIf="!isDivisionNameBeingEdited(division)">{{division.name}}</h4>
<input matInput #editTitle (change)="submit()"
*ngIf="isDivisionNameBeingEdited(division)" class="mrmd titleInput"
id="title2" formControlName="division" />
<div fxFlex></div>
<mat-icon (click)="editDivisionName($event, division)">edit</mat-icon>
</form>
</div>
</div>
in .ts file
editDivisionName($event: MouseEvent, division) {
$event.stopPropagation();
}
StackBlitz demonstration

<autofocus> unable to get focus repeatedly until the page is refreshed

I am designing a footnote at the bottom of an article to annotate following up status;
<article class="col-md-12">
</article>
<div class="col-md-12 footnote">
add a footnote
</div>
When the "add a footnote" link is hidden after being clicked and prompt the "footnote form" which I set autofocus which textarea. The "autofucus" works properly.
$('.footnote-link a').on('click', function (e) {
e.preventDefault();
...
var $footnoteForm = $(`
<form class="article-footnote-form footnote-form" style="margin-top:10px" >
<div class="form-group row">
<div class="col-md-9">
<textarea class="form-control" name="footnote" rows="3" autofocus></textarea>
</div>
<div class="col-md-3">
<button class="btn btn-primary" type="submit" id="articleFootnoteBtn">Add Annotation</button>
</div>
</div>
</form>`);
$articleFootnoteLink.parent().hide();
$articleFootnoteLink.parent().after($footnoteForm);
The form is submitted to server using Ajax then I cleared the forms by
$footnotesTop.find(".footnote-form").html(""). Now the page displays the article and the newly added footnote.
However, if I click the "add footnote" again, it unable to get focus automatically as it does at first time until I refresh the page to click.
How could I get the form focus during the second click event.
You need to use a delegated eventHandler. The js code $('.footnote-link a').on('click', function (e) { is only applied to the elements jQuery finds using that selector when the page is loaded.
Try $( document ).on('click', '.footnote-link a', function (e) {. You can use a tighter selector rather than document - it seems like .footnote would work based on what I see.
jQuery delegated events tutorial

How do I change a variable in a child element that has ng-click in the parent element.

Consider this code:
<section class="page-section about-us" scroll-bookmark="about-us" ng-click="activeSection=true" ng-init="activeSection=false">
<div class="page-content sub-content active-section">{{activeSection}}
<div class="page-border">
<a href="#" class="close-section"><img src="public/images/go-back-icon.png" />
<div class="back-button" ng-click="activeSection=false">CLOSE</div>
</a>
</div>
</div>
</section>
I have an ng-click in the that element which changes the value of 'activeSection' to true. Inside of it, I have another button that can switch this back to it's initial value (false).
In the actual app, it would show or hide this child button based on a class added to the element,just to give you a little background what I'm trying to achieve.
When I click on the element, it does as I expect it to be: switch the value to 'true'. But when I click on the .back-button element with the other ng-click, it fails to register the changed value.
Why is that?
They're both inside the same controller, btw. If there's a solution that doesn't involve creating a new controller, it would be better.
If you click on your back button, activeSection will be false but then your event will be propagated to its parent so the ng-click of Section will be executed too and activeSection will be true again.
In order to make your code work, you should stop the propagation of the ng-click event after changing the value of your variable in your back-button.
Your code would look like this:
<section class="page-section about-us" scroll-bookmark="about-us" ng-click="activeSection=true" ng-init="activeSection=false">
<div class="page-content sub-content active-section">{{activeSection}}
<div class="page-border">
<a href="#" class="close-section"><img src="public/images/go-back-icon.png" />
<div class="back-button" ng-click="activeSection=false; $event.stopPropagation();">CLOSE</div>
</a>
</div>
</div>
</section>
What you are doing wrong is that you are putting the close button inside the element which have already ng-click, that's why when you are clicking the close button, it executes the parent ng-click and stop propagation for all other click events happening simultaneously.
So, the possible solution is making another super parent of the elements and taking the close button out of the element which is making it visible when clicked and adding a ng-show directive to the close button.
Checkout the following snippet
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<section class="page-section about-us" scroll-bookmark="about-us" ng-init="activeSection=false">
<div ng-click="activeSection=true" class="page-content sub-content active-section">{{activeSection}}
<div class="page-border">
<a href="#" class="close-section"><img src="public/images/go-back-icon.png" />
</a>
</div>
</div>
<div ng-show="activeSection" class="back-button" ng-click="activeSection=false">CLOSE</div>
</section>
</div>

Swipe event propagation with nested div doesn't work

Hi I've the following html structure:
<div class="container">
<div class="scroller">
<div id ="goldenPage" class="page active">
<div class="block text">
<div class="rich-text"></div>
</div>
<div class="block">
<div class="form"></div>
</div>
<div class="block">
<ul class="menu"></ul>
</div>
</div>
<div id ="cachePage" class="page"></div>
</div>
</div>
If I bind a swipe event on div with class container using code
var myElement = $(".container")[0];
var hammertime = new Hammer(myElement);
hammertime.on("swiperight",function(){
console.debug(" manage swiperight event.");
});
and if I swipe nothing happen (except if I swipe on the bottom of my page because the internal div with scroller class is fewer height than parent div). If I bind the swipe on div with class scroller the swipe is correctly binded. The scroller div is binded with jquery scrollpane plugin.
Any ideas?!
DEMO — Make sure your JavaScript/jQuery is fired after the document.ready event.
If the JavaScript fires before the element is available in the DOM, your JavaScript will not find the element, and thus be unable to bind the (swiperight) event to the element.
Using jQuery, this can be achieved by wrapping your JavaScript code in:
$(function() {
// Your code here.
console.log("Ready!");
});

jQuery click function exclude children except for one

I have this piece of HTML:
<div class="pop-up rooster-toevoegen">
<div class="pop-up-container">
<div class="pop-up-header clearfix">
<div class="pop-up-title">
Rooster toevoegen
</div>
<div class="sprite close"></div>
</div>
<div class="pop-up-content clearfix">
<form id="rooster-toevoegen-form" class="form rooster-toevoegen-form">
<div class="afdeling-container">
</div>
<div class="date-container">
</div>
<div class="button-container clearfix">
<button value="" name="rooster-toevoegen-button" class="rooster-toevoegen-button button-green">Toevoegen</button>
</div>
</form>
</div>
</div>
</div>
Now I want a click function on .rooster-toevoegen and exclude all children from this click function EXCEPT the button. Also the button has already a function(submitting the form), this must stay the buttons event handler.
CONTEXT:
This is a pop-up with a form inside. When the user clicks next to the pop-up the pop-up has to close. Not when clicking on the pop-up which happens when I don't exclude the children from the click event. BUT when the user clicks on the button the form has to submit. So the button should not be excluded from the click and perform his own action.
How do I do this?
You can prevent from bubbling to all elements using e.preventDefault(), and manually trigger click on button.
Better way is to bind one more click event only to button.

Categories