AngularJS - JQuery event handler on a directive - javascript

There is the following situation:
I've implemented a chat module with a directive and controller in my AngularJS application. This is used in the lobby and for the game itself.
Somewhere in the link() function of the directive I am using the following code to accept the enter keystroke as an input trigger.
$('#msgInput').keypress((e) => {
if( e.keyCode == 13 ) // Enter
{
var chatMsg = {
message : $('#msgInput').val()
};
$('#msgInput').val('');
scope.chatModel.sendMessage(chatMsg);
}
e.stopPropagation();
});
Initially when the page loads for the first time everything works fine - I navigate to the lobby, the event handler gets registered and for every input the callback gets executed.
This continues to work until I decide to navigate to the game menu.
Once again the directive's link function gets triggered and registers the same event handler as before.
From this point any keypress() to the input box isn't handled by the event handler anymore.
As soon as I reload the page (f5) either in the lobby or game - everything goes back to normal and works fine and stops once again when I navigate back to the other menu (lobby or menu).
Edit: When I navigate back to the menu where I came from, the keypress() also stopped working for this menu (now for the lobby & game). Only a reload helps.
What am I missing? The event handler apparently gets registered but just doesn't trigger after an initial navigation in either menu.

Related

Possible bug in fullcalendar's eventClick?

Here is the code snippet in question:
eventClick: function(calEvent) {
if(user != calEvent.modified_by && calEvent.modified_by != 0){
$('.antoconfirm').css("display", "inline-block");
}
$('#fc_edit').click();
$('#title2').val(calEvent.title);
//-----------Submit button click-------------------
$(".antosubmit2").on("click", function(e) {
e.preventDefault();
e.stopImmediatePropagation();
calEvent.title = $("#title2").val();
calEvent.confirm = 0;
calEvent.backgroundColor = '#ddbd39';
dbTitle = calEvent.title;
//ajax goes here, works fine
calendar.fullCalendar('updateEvent', calEvent);
$(".antosubmit2").off("click");
$('.antoclose2').click();
});
//---------------------------------------------------
//-----------Close button click-------------------
$(".antoclose2").on("click", function() {
console.log(calEvent.title);
$(".antoclose2").off("click");
});
//---------------------------------------------------
return false;
},
$('#fc_edit').click(); calls the modal in which the editing is done. There are two buttons with the classes "antosubmit2" and "antoclose2". You click on an event, the modal comes up, you change the title, click submit, the modal goes away and voila, the title is changed(from "new1" to "new3" in this example):Test events, title change
When ONLY the submit button is used, everything works fine, you can change one event after the other without incident. On the other hand, when you use the close button on one event and try to change the title on another, the first event will be changed:Test events, title change after close
Now at the "ajax goes here, works fine" part is an ajax POST, that sends the correct data despite what the calendar shows and after a page reload everything is edited the way it should be.
Is this a bug with fullcalendar's event rendering or does my code fail somewhere?
I think you need to run .off against all your button click handlers whenever any of your buttons is used. At the moment you only remove the handler for the button that was actually clicked. If you don't remove them, those handlers will remain and get used again if the other button is clicked in future. This is exactly the scenario you have run into.
In the case you described, I suspect because when you closed the first event, you didn't remove the "click" handler related to the "submit" button that went with that event. Then, when you changed the title of the second event, it ran the "click" handler for both events, because you never removed the first handler. Hence why the title for the first event gets changed when it shouldn't.

$location.path takes time to work after bootstrap modal hide (hide.bs.modal) event is fired

// show mymodal
// register an event to route to a different page once modal is closed
$('#myModal').on('hide.bs.modal', function() {
if ($location.path() == '/') {
$location.path('/ser/mynewpath');
alert("fired"); // just to check the event was fired
}
});
// open the modal
$('#myModal').modal('show');
I'm calling the bootstrap modal #myModal using JavaScript. Once I close the modal I want to direct the page to a different path. The problem is it takes 30sec - 1 min to direct the page after closing the modal. I added an alert to check if the event is getting late to fire, but I get the alert the moment I close the modal, but the page is only directed after a long wait.
Sometimes when I click somewhere else it will get fired. But this is not happening always - at times the long wait is inevitable.
My initial guess was since I'm using the bootstrap modal and using the $location, angular might not detect it the moment modal gets closed. But now it seems like a dumb guess. I also tried changing the event trigger to 'hidden.bs.modal' but got the same result.
I will try adding angular $modal and see if this solves, will post the updates. But meanwhile I'm thrilled to understand the cause behind this delay in this setup.
Thank you.
Since it is jquery event angular will not be aware of this event immediately. It will have to wait till the next digest cycle and that is causing the delay. You try using $scope.$apply
$scope.$apply(function() {
if ($location.path() == '/') {
$location.path('/ser/mynewpath');
alert("fired"); // just to check the event was fired
}
}

WinJS Stop javascript in memory

I'm learning using the Win.JS navigation and I am able to navigate between pages now. But I'm having errors when I leave a page and trigger a event from the first page.
So the problem is. I have some javascript running on Page1.html | .js
If I press the Arrow up button on my keyboard for example a javascript runs (onclick). This works okay, but then I click on a button and navigate to Page2.html also with a ( .js) and if I then also click on the Arrow up button I get an error. It tries to start the function that is called within the onclick, and that isn't there anymore in my Page2.
So the question is, how can I unload these javascript triggers from Page1 if i'm notttt on that page anymore?
In your WinJS Page definition you can define unload method that is always invoked when the user leaves the page. Unregister all event handlers there.
WinJS.UI.Pages.define("/page.html", {
ready: function (element, options) {
// add onclick handler
},
unload: function() {
// remove here all event handlers
}
});

Trigger an event on back button in browser/android with javascript

My angular app's content creation flow is being broken by androids and browsers physical buttons which take the user to where they came from instead of previous step in the process. I tried fixing it with locationChangeStart as well as few other similar events, but they all get triggered both by my "Continue" buttons as well as physical "back" buttons.
Is there a way to trigger an event only when user presses browsers/android's back button, or alternatively to know if locationChangeStart was triggered by the back button vs app's button? If possible, I would like avoid adding jQuery as we are not currently using it.
I gave up on trying to detect the user pressing back button and act on it. Instead, make it the default action and change the way our buttons behave. I detect when user is pressing one of our buttons and set a variable based on it.
var navigating = false;
$scope.$on('$locationChangeStart', function(event) {
if($scope.global.application="new-ad" && !navigating){
event.preventDefault();
$scope.areYouSure = true;
}
});
$scope.nextStep = function() {
navigating = true;
$location.url('/step-two');
}
Basically, we first set our variable to false, and if the user presses physical back, it will display the prompt alerting user they will lose their work. However, if the user instead uses our "continue" button, also triggering the locationChange, it will set variable to true, letting the app know what the locationChange is triggered from within the app and allowing it to continue.

Long time between do event and handle it using jquerymobile/phonegap

I develop an app using phonegap and jquerymobile/jquery.
During development I only had a virtual iOS device and now since I'm testing the app on a real device I see, that time between click on an element and handle this event is very long.
E.g if i Click on an icon a loader icon is shown but this icon first come in the moment the next page is final loaded (a very short time the loader is shown).
I develop with Javascript since a long time and always have focus on performant execution but this is very strange.
The App has got about 10 views in one HTML file. And on click on an element only show the next part of these file.
Does anyone know about solutions to solve "Bugs" like these?
Thanks in advance.
The click delay on iPhones is a feature used to distinguish between clicks and scrolls. When you bind to the click event iOS waits approximately 300ms to decide whether you were clicking an object or trying to scroll the page.
You can use jQuery Mobile's vclick event which fires much faster however you will probably run into situations where the vclick event is fired off twice in a row which can result in multiple elements being clicked. Here is some sample code of how to use vclick events and only capture the event triggered first:
$(function () {
//setup a function to check if a vclick event has fired within the last 500ms
function check_vclick () {
//if a vclick event has fired in the last 500ms then return false
if (do_vclick == false) return false;
//otherwise set a flag to disallow vclicks for 500ms
do_vclick = false;
//setup a timeout to allow vclicks in 500ms
setTimeout(function () {
do_vclick = true;
}, 500);
//return true so the event handler knows it's ok to run its code
return true;
}
//setup a flag to allow/disallow vclick events from firing
var do_vclick = true;
//bind an event handler to the vclick event for an element
$('#link_id').bind('vclick', function () {
if (check_vclick()) {
//run the code associated with the element, if it's a link referencing a pseudo-page on the same HTML document, you can do something like this
$.mobile.changePage($(this.href));
}
});
});
Here's a link to the documentation for $.mobile.changePage(): http://jquerymobile.com/demos/1.0rc2/docs/api/methods.html
Here's a link to the documentation for vclick (notice the notes under the virtual mouse event section): http://jquerymobile.com/demos/1.0rc2/docs/api/events.html

Categories