Trigger hashchange event on button clicked - javascript

I want to call the same action whenever the button is clicked, or the hash changed event occurred. Even if the hash changed event means just loading the page for the first time and redirecting to something like #something.
What I had so far, is basically duplicated code. The same code for a hashchange event, and for button clicked. I am looking for a solution not to have the code duplicated, but to call the hashchange event from a button clicked event. Here is my code so far.
main.js
$(window).bind('hashchange', function() {
// get User from the URL
var user = window.location.hash.substr(1);
// update the value in a text input with new ASIN
document.getElementById('asin_input').value = asin;
$.getJSON("/api/user/"+user, function (data) {
// ...
});
}).trigger('hashchange');
/*
* Whenever a button "Search!" is clicked, this function gets called.
*/
element.addEventListener('click', function () {
var user = $('#user_input').val();
$.getJSON("/api/user/"+user, function (data) {
// ...
});
});
Now the entire thing inside getJSON, and including the getJSON is duplicated, so I would want just the onClick calling/triggering the hashchange, which triggers getJSON. How to do this?

Related

JavaScript event handling code get's called multiple times

I need your help. I'm currently working with a modal lib in JavaScript to display a modal for my customers:
https://github.com/vodkabears/Remodal/tree/1.1.1
Unfortunately my event handling in case the user clicks a button don't works like expected. When you take a look into the manual, you can see under the point Events the following event handler:
$(document).on('cancellation', '.remodal', function () {
console.log('Cancel button is clicked');
});
This one get's triggered for example when the cancel button get's pressed. Because I'm using one popup for multiple things, I need to attach the event handler to the call directly. So first I've wrote a function that opens the popup:
function openRemodal( remodalId ) {
let remodal = $( `[data-remodal-id=${remodalId}]` );
remodal.remodal().open();
return remodal; // <- added to handle events
}
I can call this function that way:
openRemodal( 'information-remodal' );
To get an event handling done, I've now returned the remodal in the function and re-wrote my call:
openRemodal( 'information-remodal' ).on( 'cancellation', function () {
alert( 'Test' );
} );
This seems to work but somehow when I repeat the opening of the popup and pressing the button, the alert get's shown multiple times increased by any new opening.
I'm not sure why this happens and why. Can you please help me get this working? I just want to call any function in there once - any time.
JQuery has a .one method ... try using that in place of .on. The callback should run only once. https://api.jquery.com/one/
On each time when you open model you attach function to cancelation event. so add new function and you never remove it. after first time you have one, then you have two... etc.
just attach it once, or remove it after handling event.
const modal = openRemodal( 'information-remodal' )
const handler = () => {
alert( 'Test' );
modal.off('cancellation', handler);
}
modal.on( 'cancellation', handler);

jQuery click not working for a second time clicked

I am using the following code to send the ajax, but the problem is when user clicks for a second time on the button it does not post to backend or do not submit data, for it to work again the user needs to reload the page again. Anyone has an idea why?
$(document).ready(function () {
$('#btn_follow').click(function (e) {
e.preventDefault();
//e.stopPropagation();
//$('#divId :input').serialize();
var follow_and_unfollow = $("#user_page_follow :input").serialize();
$.post(
"backend/ajax/follow_and_unfollow.php",
follow_and_unfollow
).done(function (data) {
//$("#testimonials").load(location.href+" #testimonials>*","");
$("#follow").html(data);
$("#user_followers").load(location.href + " #user_followers>*", "");
}).fail(function () {
//alert("Error submitting forms!");
});
});
});
on second click on #btn_follow it's not submitting, the user needs to reload the page for it to work
As we've confirmed in the comments, you're overwriting your original button with new content returned via AJAX. As such, the button element that you'd bound the click even too is gone, replaced with a new bit of HTML from the server.
I'd suggest you do the following. Replace:
$('#btn_follow').click(function (e) {
With:
$('#follow').on('click', '#btn_follow', function (e) {
This essentially binds the handler to the #follow element, but only runs it if the element clicked matches the filter expression. It's called event delegation and it's an important concept. Read about it here.

Update Variable On Hashchange

I am trying to have a variable that always matches the hash of the URL on a single page site.
$(window).on('hashchange', function() {
var hashTag = window.location.hash;
$('#btn').click(function(){
console.log(hashTag)
});
});
Using the code above creates a list of all the past changes rather than the current hash.
hashTag.last();
This didn't work
That is because you are attaching button click event listener again and again. Please move your button event listener outside hashchange event, like below
var hashTag = "";
$(window).on('hashchange', function() {
hashTag = window.location.hash;
});
$('#btn').click(function(){
console.log(hashTag)
});
Now, there is permanent event listener attached to button which display value of hashTag variable. And on hashchange value of hashTag variable is updated.

Detect If Changes Have Been Made To Input Form

I have a input form with Jquery & PHP what I am trying to archive is if a user makes any changes to the form and they try to navigate away from the page A popup message comes up saying if they want to exit and discard changes or stay and save the changes first?
How could I archive this thought I did it but all my current one is doing is checking if the fields have data in them but i'm making use of the value='' feature in HTML to get the current settings in the database.
Only run this function if submit has not been pressed yet.
1 Create a flag that specifies whether something was changed:
var changes = false;
2 Bind an event listener to every single input and textarea that sets changes to true:
$('textarea,input').on('keypress change input', function() {
changes = true;
});
3 Bind an event listener to onsubmit that sets changes to false:
$('form').on('submit', function () {
changes = false;
});
4 Bind an event listener to onbeforeunload that returns the question if there are changes:
$(window).on('beforeunload', function () {
if (changes) return "Do you really want to leave?";
});
Demo on JSFiddle: http://jsfiddle.net/TimWolla/VYKeu/

How to make event click event fire only once when element is clicked multiple times

I have a link that the user clicks on to delete a record (class="delMail"). When they click this link, a new div shows up with 2 more links [Y and N]. clicking on Y will delete their email, clicking on N will cancel the request.
The problem is that if the user clicks 10 times on the delMail link prior to clicking on either Y/N, the code will try to delete the email 10 times also?
I've updated my code to my working version, here it is:
$(function(){ //delete Message
$("a.delMail").click(function(e) {
e.preventDefault();
//get divs to show and hide
var $confirmDelDiv = $(this).parents("tr").next().find(".confirmDelete");
var $replyDiv = $(this).parents("tr").next().next().find(".replyDiv");
$replyDiv.fadeOut(); //hide reply div
$confirmDelDiv.fadeIn("slow"); //show confirm message
//get id
var $id = $(this).attr("href"); //get id value of email
var dataString = "id="+$id;
$("a.delLinkYes").click(function(y){//if user confirms delete, send id to php page
y.preventDefault(); $(this).unbind("click");
$.ajax({
type: "POST",
url: "process.php",
action: "deleteEmail",
data: dataString,
dataType: "JSON",
cache: false,
success: function(data){
if(data == "true"){//if email was successfully deleted
$confirmDelDiv.delay(60).append("Email deleted!");
$confirmDelDiv.fadeOut("slow");
}else{$confirmDelDiv.delay(60).append("Error deleting this email. Please try again!"); return false;}
}
});
return false;
});
$("a.delLinkNo").click(function(n){//if user cancels request, stop.
$(this).unbind("click");alert("cancel"); return false;
//$confirmDelDiv.fadeOut("slow"); return false;
});
});
});
Is this ok? I mean efficiency wise?
I would look into using jQuery.fn.one() rather than jQuery.fn.click() for this. From the documentation it shows that you can:
Attach a handler to an
event for the elements. The handler is
executed at most once per element.
So it should be as simple as replacing:
$("a.delMail").click(function(e) ...
With:
$("a.delMail").one('click', function(e) ...
That's how jQuery functions. You should unbind and rebind the click event handler to stop users from spamming the results. Here is the basic structure:
$(function() {
var delHandler=function(e) {
e.preventDefault();
//Ignore additional clicks until otherwise stated
$('a.delMail').unbind('click');
//Do your stuff
$.ajax({
//...
success:function(data) {
//...
//Start listening to user clicks again
$('a.delMail').bind(delHandler);
}
});
$("a.delLinkNo").click(function(n){
alert("cancel");
//Start listening to user clicks again
$('a.delMail').bind(delHandler);
return false;
});
}
});
I hope the code example makes sense to you. I omitted several parts to try to make it more clear of what I added. Basically, you stop jQuery from caring if the user clicks the button up until it is done processing the second Y/N box.
As Kranu noted this is just how click handling works in jQuery - though it's not specific to jQuery, but the JavaScript onclick event that fires.
There's several possible workarounds. Use unbind (scroll down to the section "Using the Event Object") to remove the click handler when the delete button is pressed for that element. You will need to re-bind the click handler whenever the user selects 'no'.
Another option would be to keep a global lookup object such as window.pendingDeletes = {} (keyed by message_id) to track when a delete has been triggered, but not confirmed, and have the click handler return false whenever an message has a pending yes/no decision about a delete.

Categories