So I'm running a data collection project by injecting a html form into a third party website, via a chrome extension, which instructs users to describe the data they see and submit it to my server.
For some bizarre reason, however, whenever the user clicks the "submit" button to send the form contents to the background page (and from thence to the server), the underlying page reloads, and, not only that, but it reloads with the contents of the form I injected showing up in the url after reload. Which is kind of bizarre behavior.
I don't know if this is something in my code, or even if it's something in the underlying web page's code (maybe it redefines chrome.runtime.sendMessage or something as some kind of anti-extension technique?!!?). I'd really like to stop this behavior if possible... does anyone have any ideas?
The relevant parts of my code, stripped down a little:
var cururl = window.location.href
var codestring= "[A HTML FORM TO INJECT]"
var raformvalues = {};
function codeValues() {
$.each($('#mainCoding').serializeArray(), function(i, field) {
raformvalues[field.name] = field.value;
});
}
function sendValues() {
let pageinfo = {"page": document.documentElement.outerHTML,
"url": cururl,
"title": document.title,
"timestamp": String(Date.now())};
let tosend = $.extend({"type": "doctype"}, pageinfo, raformvalues);
chrome.runtime.sendMessage(tosend);
chrome.storage.local.set({'lasturl': pageinfo.url});
$("#pgcodediv").empty();
location.href = cururl; // note: I added this line to try to stop the reloading and url/changing behavior. behavior is the same with and without it.
}
function appendCodingInfo() {
$("#headerID").append(codestring);
$( ":checkbox, :radio" ).click( codeValues );
$( ":text" ).change( codeValues );
$( "#codingsubmit" ).click(sendValues);
}
appendCodingInfo()
when the user hits the submit button (#codingsubmit, of course), the message gets passed and the background page handles it correctly, but the page refreshes unbidden, and the contents of raformvalues show up in the URL of the refreshed page (i.e., when I call window.location.href from the console the contents of that object show up as parameters to a get request, i.e., http://url?prop=value&prop2=value2 -- no clue why.
If you click a button with type="submit" in a form, by default browser will reload the page after the form is submitted.
To prevent the page reloaded, either replace type="submit" with type="button" or call e.preventDefault() inside sendValues handler.
Appendix:
According to MDN, the default value for button is submit.
type
The type of the button. Possible values are:
submit: The button submits the form data to the server. This is the default if the attribute is not specified, or if the attribute is dynamically changed to an empty or invalid value.
reset: The button resets all the controls to their initial values.
button: The button has no default behavior. It can have client-side scripts associated with the element's events, which are triggered when the events occur.
menu: The button opens a popup menu defined via its designated element.
Related
I'm working on a group project for a class, and we have a webpage that is split into different tabs, so it is only one webpage, but appears to be different pages using Jquery so the page doesn't have to reload when switching between tabs. The problem I am having is that one of the tabs has a form to get information from the user, then after the user clicks the submit button, the info is sent to the database using php, causing the page to reload. Then depending on if the information was successfully sent to the database, there will be either "success" or "invalid" appended to the end of the URL. If the user submits this form, we want them to automatically come back to this tab on the reload, and I have tried doing this by using a script like this:
<script>
document.getElementById("baseTab").click();
window.onload = function() {
var theurl = document.location.href;
if (theurl.includes("success") || theurl.includes("invalid") {
document.getElementById("infoTab").click();
}
};
</script>
The baseTab is the tab we want to load whenever someone first loads the webpage, unless they have just submitted the form on the infoTab page. This code structure works on a simple test webpage I run on my computer, but when I try to push it to our project repository, it will only do the "baseTab".click, and not click the "infoTab" button even if theurl includes "success" or "invalid". I tried doing it without the window.onload(), but that doesn't work either. Also, if I do
if (theurl.includes("success") || theurl.includes("invalid") {
document.getElementById("infoTab").click();
}
else {
document.getElementById("baseTab").click();
}
then neither of the buttons get clicked. If their is an easier way to do this or you see where I am going wrong, any help would be appreciated. Thanks!
Firefox version is 37.0.2
I have an MVC application where I submit forms in order to carry out CRUD functions. I POST to a hidden iframe, then refresh the page after the POST so that the user can see the new data after the database has been updated. Here is the javascript function that takes care of adding a new user:
$('#submitNewUser').click(function () {
document.getElementById("newUser").submit();
$('#newUser').remove();
location.reload();
}
submitNewUser is the button for submitting the form (id and name). newUser is the name and id of the modal form that is submitted. So on click of the submitNewUser button, the newUser form is submitted, then the newUser modal window is removed, then the page is reloaded.
This function works as intended (or at least, as I intended it to) in Chrome and IE. In Firefox, the page reloads without submitting the form. There are no errors in the console, it just looks like a page refresh occurs. When I comment out the line: location.reload();, the form submits but I then have to manually refresh the page in order to see the data changes.
I've searched for similar issues but thus far have been unable to fix the problem. Things I've tried:
changing the name parameter of the iframe to NAME
removing any capital letters from the name and id parameters of the iframe
using window.location = window.location instead of location.reload()
I changed the input type from button to submit and modified the javascript function to be an onSubmit of the form, but the behavior is identical to my original reported issue
I removed the target parameter from the form, and then removed the location.reload() line from the javascript. The behavior is then identical across all browsers: the form gets submitted and the page is redirected to my "Success!" page. This tells me that there is something going on with the location.reload() and how it interacts with the iframe in Firefox. Here is my iframe code:
<iframe id="new_user_hidden_frame" name="new_user_hidden_frame" class="hide"></iframe>
And here is where I set the target for my POST method:
<form id="newUser" method="POST" action='<c:url value="/createUser.htm" />' target="new_user_hidden_frame">
EDIT:
As per the accepted answer, Firefox was actually the only browser that was technically handing this correctly! I was refreshing the page before receiving a response, so the behavior was 100% appropriate. I added the following to my function so the page won't refresh until a response has been received:
$.ajax({
success: function() {
window.location.reload(true);
}
});
As your code says you are trying to reload page before getting the response, so request is not completed till, for this you have to delay the reload or better way submit form using ajax and reload page in the callback function.
PRE EDIT: It turned out that it was not about the disability of the button, but making some other actions after save. I debugged the page and found out that after making changes on a saved form, then page loses the javascript functionality in the (document).ready part. I've added the solution as an answer.
I have an entry page which has two buttons save and approve. The mechanism is something like, you can fill the form and save, then approve. You can also reach a saved page by refreshing the page or from the list of your saved pages.
The approve button is disabled if the form is not saved. I enable it from code behind after saving. Approve button also has a confirm button extender which takes its confirm text from javascript. I load it in (document).ready and its code is:
$(document).ready(function () {
$("#ASPxSplitter1_ContentPlaceHolder1_uctActivityEntry1_tbActivity_tbHistory_btnApproveActivity_btnApprove").click(function () {
$("#ASPxSplitter1_ContentPlaceHolder1_uctActivityEntry1_tbActivity_tbHistory_btnApproveActivity_lblMessage").text(GetConfirmTextForApprove());
});
});
,where GetConfirmTextForApproval() makes some calculations and returns the confirm text.
Now, my problem is, as the button is disabled when you open the form, the code above is not rendered at the first page load. This leads to the problem that, when I start to fill a form and save it, then approve it, I don't get any confirm text, because it does not run the function. But after refreshing the page or after I go to a saved form's page from another page, I get the proper confirm text.
So, how can I solve this problem? How can I get the proper confirm text even though the button is disabled at the first page load?
Note: I have to add that after saving, the url of the page is changed. The query string is added. That might also cause the problem.
You can use
// Disable #x
$( "#x" ).prop( "disabled", true );
// Enable #x
$( "#x" ).prop( "disabled", false );
But not when document ready, you need enable button when you want. Then you need create a event listener
$("#button").click(function(){
//Your code
if(GetConfirmTextForApproval()){
//You active the button and the text that you want show.
}
});
Solved my own problem:
As it was said in the pre edit of the question, the problem was caused because of making changes after the save. I've changed my function as:
$(document).ready(function () {
SetConfirmMessageForApproval();
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
});
function EndRequestHandler(sender, args) {
SetConfirmMessageForApproval();
}
function SetConfirmMessageForApproval() {
$("#ASPxSplitter1_ContentPlaceHolder1_uctActivityEntry1_tbActivity_tbHistory_btnApproveActivity_btnApprove").click(function () {
$("#ASPxSplitter1_ContentPlaceHolder1_uctActivityEntry1_tbActivity_tbHistory_btnApproveActivity_lblMessage").text(GetConfirmTextForApprove());
});
}
This helps, if anyone else needs it.
I have a javascript code that, whenever a checkbox is checked, will reload my current page and then is supposed to grey out some input fields.
However, it is only doing the reload when the page is reloaded the input fields are never greyed out.
$(document).ready(function(){
$("#storePickUp").on("click", function () {
if ($(this).is(":checked")) {
document.getElementById("shippingForm").submit();
document.getElementById("shippingAdress").disabled = true;
document.getElementById("shippingState").disabled = true;
document.getElementById("shippingCity").disabled = true;
document.getElementById("shippingZip").disabled = true;
document.getElementById("shippingZipCode").disabled = true;
document.getElementById("shippingButton").disabled = true;
}
});
});
So in your code on the 4th line where you call .submit()... unless you have some extra magic on the page that you are not showing, this line will proceed to post/get your form to whatever url you have configured in that form.
What this means is that the lines underneath that do not matter at all, since they will not be executed on the forms target page.
To get around this if you truly need the form post in the middle, you would need to post to a specific url and use that url as a trigger on page load to disable those elements. Not directly after the click, but rather on the newly loaded page that is the target of the form... make sense?
I think that's because it's only disabling them when you click on #storePickUp but if your page is reloaded it will reset.
Method submit is executed, page reloads, code after submit is never executed. Even if that code would be executed, page refresh nullifies any changes.
You should probably do submitting with ajax, not with submit method. If you are using jQuery, it will make it easy for you:
http://api.jquery.com/category/ajax/
I have an html/php webpage (the file is called searchresults.php) that imports jquery mobile. When you enter the page, the url is usually something like
www.domain.com/searchresults.php?&sort="off"&max="5"
In this example sorting is off and only 5 items are displayed. On that page is a button that opens a popup where I want the user to be able to change these settings. I use the built-in jquery mobile popup. On that popup you can toggle "sort" on/off and you can enter a new maximum. On the popup is an "ok" button to confirm your new settings. It looks like this:
OK
The sortAgain(); function in javascript looks like this:
function sortAgain();
{
//some code to get the necessary variables//
...
//change the href of the button so you reload the page
document.getElementById("okbutton").href = "searchresults.php" + "?keyword=" + var1 + "&sort=" + var2 + "&max=" + var3
}
So, basically, right before the "ok" button navigates to another page, I set its href of the page where it should navigate too.
This scheme works, and the searchresults.php file is fetched again from the server and re-interpreted (with the new variables in the url).
However, if i try to change the settings again after changing it once, the popup just does nothing! In other words, the href of the ok button on the popup stays empty and the javascript function sortAgain() is not called. I don't understand why it calls the onclick method perfectly fine the first time, but then refuses to call it again?
I assume it has something to do with the fact that the popup html code is an integral part of searchresult.php file, and that hrefing to the same page gives problems? The popup is pure html, no php is involved in the popup code. and again, it works fine the first time.
You should check out how to attach events via JavaScript. See here: javascript attaching events
You need to use the "pageinit" event when setting up click handlers in JQM: http://api.jquerymobile.com/category/events/
Here is an example of how to bind click handlers when the page is first loaded.
$( document ).on( "pageinit", "#that-page", function() {
$('#okbutton').on( "click", "#that-page", function( e ) {
$(this).attr("href", "searchreslts.php");
});
});