How to respond to an event after loading a hyperlink page? - javascript

I wonder is it possible to respond to an event after the client click the hyperlink and the hyperlink is loaded? Which that event can use properties in the hyperlink(i.e. id, class...etc)?
For example, page_A have a hyperlink
link
But since some_func need to use some properties in page_B, let say page_B have this line
<p id="a">hello world</p>
and some_func want to do something with it(e.g. document.getElementById("a")), how can I first load the hyperlink(page_B) then run some_func?

You could use the localStorage to save the name of the function that you want to execute on the second page, and call it once it loads.
The code would be like this:
JS
// a sample function to be called
function myFunc() {
alert("Called from previous page!");
}
// save the name of the function in the local storage
function saveForLater(func) {
localStorage.setItem("func", func);
}
// if the function exists
if (localStorage.func) {
// call it (not using the evil eval)
window[localStorage.func]();
// remove it from the storage so the next page doesn't execute it
localStorage.removeItem("func");
}
HTML (just for testing)
Go to Page 2<br/>
Go to Page 2 (not saving function)
Notice: as this code runs on the client's side, it is subject to be changed by the user, so you must be careful on how to proceed and execute the "saved" function, or you may find yourself with a security problem.

Related

Cannot unset a GET parameter unless location.reload is called

I have two php files named student_profile.php and viewQuizAnswers.php.
In student_profile.php I have <a> tag that calls the modal in viewQuizAnswers.php and the value from student_profile.php jumps to viewQuizAnswers.php
Imagine that the code below is repeated 10 times with different values of qzid and stid:
View
In viewQuizAnswers.php
$studid = $_GET['stid'];
$qzid = $_GET['qzid'];
After I got the value and the query succeeded I unset the _GET at the end of a query
unset($_GET["stid"]);
unset($_GET["qzid"]);
?>
But when I click a different tag, the previous values are still there and I cannot get the new values I need.
I cannot unsetthe _GET['qzid'] and _GET['stid'] unless I use location.reload(); and if I used location.reload I do not need to UNSET anymore
$('#myModal').on('hidden.bs.modal', function () {
location.reload();
})
//this code is in viewQuizAnswers.php
But I do not want to use location reload because there is a lot of data and it takes too much time to load.

addClass only if cookie exists else hide

I'm trying to make a voting system that will check when user has voted and then change the html item css from "Vote" to "Thank you" and the background color to "green".
Now this works great, but I need to make the option when user refreshes the page to check if cookie exists (the cookie is already set = variable is voteCookie('id')) and then apply the class="exists". If it doesn't exist hide that class. That class would say "Thanks for voting", nothing else.
jQuery:
$(window).ready(function() {
var voteId = $('.gallery-item a');
$(voteId).on('click', function() {
$(this).text('Thank you!');
$(this).css('background-color', 'green');
});
});
You can do that (it's made easier with the jQuery cookie plugin), but it's not the correct use case for cookies. Cookies get sent from the client to the server with every HTTP request; if you're not using that information on every HTTP request, that's just completely unnecessary data transfer.
Consider local storage instead, which is supported by virtually all browsers, even IE8:
$(document).ready(function() {
var voteLink = $('.gallery-item a');
if (localStorage.getItem("voted")) {
voteLink.text('Thank you for voting').addClass('voted');
} else {
voteLink.one('click', function() {
localStorage.setItem("voted", "yes");
$(this).text('Thank you!');
voteLink.addClass('voted');
// If you wanted to do something with *just* the elements that weren't
// clicked, you could do:
// voteLink.not(this).addClass('unused-vote');
// ...or similar
});
}
});
...but if you want to use cookies, with the jQuery cookie plugin, you just change the getItem line to if ($.cookie('voted')) and the setItem line to $.cookie('voted', 'yes');
I made a few other changes above as well:
I used document rather than window with ready - the documentation only talks about document, not window. (That said, I generally prefer not to use ready at all; instead, I just ensure scripts are at the end of the HTML, just before the closing </body> tag.)
I called the variable voteLink rather than voteId since it's a jQuery object containing an a element, not an ID.
I changed $(voteId) to voteLink because the object is already a jQuery object, no need to pass it through $() again.
I changed the direct style manipulation to a class you add, for better separation of logic and styling.
I added that same class when they've already voted.
I used one rather than on so that we remove the click handler on the first click.
Obviously, this just has the client code. I assume there's a server piece that validates votes and such (since you can't trust anything the client sends or stores for you).

Basic questions about javascript

Please take a peek at the following code, which is in _form.html.erb:
<script>
function typeCatch(){
$.post("<%= update_readers_link_essay_path(#essay) %>");
$(this).off("keypress", typeCatch);//remove handler
}
$(function(){
("form#new_revision").on("keypress", typeCatch);
});
</script>
When the user starts typing in a form, the ajax request should be fired and update the readers list. However, the post request is not fired when I start typing in the form and I am trying to debug this problem.
Since I am not that familiar with javacsript yet, I would appreciate if you helped me clarify a few things.
a. For the second part, can I just do
$("form#new_revision").on("keypress", typeCatch);
without wrapping it with $(function() {} ?
b. Is there anything that I'm doing wrong? Since ajax call isn't fired, I must have made a mistake in the second part?
Additional Question
my_personal_chat.js (in app/assets/javascripts pipeline)
$(function() {
var pusher = new Pusher('app_key');
var channel = pusher.subscribe('presence-my-chat');
channel.bind('pusher:subscription_succeeded', function(members) {
$('#online_users').empty();
members.each(function(member){
addMember(member);
});
... other functions ...
});
This is how I implemented my chat feature, using Pusher. Since the channel is private, everytime I call var channel, an ajax call to POST /pusher/auth is invoked.
I found that every time I navigate to a different page, even when it's not where the chat feature is, POST /pusher/auth is called. Basically, every time my_personal_chat.js is loaded, the ajax call will be unnecessarily invoked.
Question: How do I prevent this from happening? my_personal_chat.js should only be loaded when I go to myapp.com/chat. Should I just pull out everything from the javascript file and put it inside chat.html.erb? Is that the conventional way of doing it?
to answer my own question: I moved the code from my_personal_chat.js to chat.js.coffee and deleted my_personal_chat.js. Now the javascript only gets loaded when users go to the chat page.
a. There are alternatives, but wrapping the code in $(function() {}) is one of the best ways to ensure that the code isn't executed until all the elements are loaded into the DOM. It's a jQuery feature.
b. ("form#new_revision").on("keypress", typeCatch); should be $("form#new_revision").on("keypress", typeCatch);. You're missing the $ at the beginning.

Iframe onload does not execute after file download?

I show a waiting dialog and then i create an iframe with the url of the file and append it to the document.
Neptune.ShowWaitingDialog();
iFrame.src = "ExportReportAllMediaDetailsCsv/?" + $.param(object);
iFrame.style.display = "none";
iFrame.onload = function () {
parent.Neptune.CloseWaitingDialog();
};
document.body.appendChild(iFrame);
If there is an error on the server side the iFrame.onload function executes accordingly and the waiting dialog is closed, however if a file is returned the onload function doesnt get executed and the waiting dialog stays open.
my question is, if a file is returned doesnt the iframe get refreshed and hence cause the onload event to execute?
if no then is there a way to detect if a file has been returned?
The way I do that, taken from T.J. Crowder's answer to this old question of mine, is this:
Add a hidden form field or GET parameter called "nonce" (or whatever you want). Fill it with a unique number or random string, either at page creation time or with JavaScript.
On the server, look for the "nonce" parameter and add a cookie called "FILE_READY" (or whatever you want), and set its value to the nonce value. Return the file as you normally would.
On the client, when the form posts or the iframe "src" is set — in other words, when you initiate the file download — start up a JavaScript interval timer to check the current value of the "FILE_READY" cookie. Check like every 100 milliseconds or so; it doesn't have to be super-frequently.
As soon as the "FILE_READY" cookie has the value sent in the "nonce" parameter, then you know that the HTTP response has come back from the server.
Works like a charm.

How to override variable parameter loaded from another script

I have a script that loads the code dynamically. It is kind of a search engine. When I press a search button, the action gets triggered and a new page opens with many parameters.
I want to override one of the parameters generated with the script in the new URL. JS code is quite big and hard to read, but I have found the important part in the Firebug DOM editor.
This is the pattern of the URL generated when you perform the search:
http://www.example.com/...?ParameterOne=123&ParameterTwo=Two&ThisParameter=Sth&ParameterFour=Four...
What I want to edit is "ThisParameter" and change its value. This is the part edited in the DOM that does what I want:
Foobar = {
_options: [],
...
var options = {"ParameterOne":123,"ParameterTwo":"Two","ThisParameter":"ABC","ParameterFour":Four,...}
...
And this is the output of "ThisParameter" when you choose "Copy path" in Firebug's DOM tab:
_options[0].ThisParameter
I am wondering it this is possible at all. What makes me think that it is, is the fact that I can change this parameter in Firebug and it works perfectly. So, if Firebug can edit it, there should be a way to influence it with another script.
Looking forward to any suggestions, thank you in advance!
Since you cannot edit the dynamic script you have the following options:
You have to try to give the script the correct input and hope it uses your value.
Add a script to the results page which will read the url and arguments, change it and redirect, as we discussed here. (If you put everything in functions it should not conflict with the dynamic script if the functions are uniquely named.)
You could try adding something like this jQuery code to the page with the search button:
$('input[name=search_button_name]').click(function(e) {
e.preventDefault();
var form_search = $('#search_form_id');
$('<input>').attr({
type: 'hidden',
name: 'ThisParameter',
value: 'SomethingElse'
}).appendTo(form_search);
f.submit();
});
You can override any js function and method, or wrap you code around it. The easiest thing would be to look at the code you get and once it gets loaded, you re-declare a method with your own functionality.
I you are trying to replace a parameter in a specific jquery request, you can even wrap around the jquerys ajax method:
var jquery_ajax = $.ajax
$.ajax = function(options){
// parse only a specific occurence
if(options.url.indexOf("example.com") > -1) {
// change the url/params object - depending on where the parameter is
options.params.ThisParameter = "My Custom value"
}
// call the original jquery ajax function
jquery_ajax(options);
}
But it would be a lot cleaner to override the method that builds the ajax request rather than the ajax request itself.
I would investigate further on the scope of the variable options (var options), is it global? i.e. if you type 'options' in the Firebug console, does it display its properties?
If so, you could then access it via your own script and change is value, e.g.
options.ThisParameter = 'my-own-value';
You might hook your script to the click event of the search button.
I hope this helps, it could be more specific maybe if you have some sample code somewhere.

Categories

Resources