I have been studying JavaScript from one book. Once I was playing with the codes concerning the client-server site communication, I wanted to do a POST request with the code below (which uses IE ActiveX object XMLHttpRequest):
<script type="text/javascript">
var oRequest = HTTPRequestUtil.getXmlHttp();
var sRequestType = "post";
var sURLofRequest = "MyPage.aspx";
var bAsnychronously = false;
oRequest.open(sRequestType, sURLofRequest, bAsnychronously);
oRequest.send(null);
alert ('Status is '+oRequest.status+' ('+oRequest.statusText+')');
alert ('Response text is '+oRequest.responseText);
</script>
I have breakpoint on the PAGE_load eventhandler of the MyPage.aspx" page. I was expecting the execution will stop at that place when this HttpRequest occurs above. (It is called on a html button click).
The thing is, the request is done, the responseText is obtained (which was the xml content of the page) and no stop at the Page_Load method where I have put a breakpoint.
So, now I cannot understand the difference between calling .send() function with POST request type and submit() function on the call.
I would appreciate if you can explain the main differences briefly.
thanks!
The difference is that using send will send the data back to the JavaScript calling routine without reloading the page, but calling submit on a form submits the form to the server and then reloads the results from the server as if the user had clicked on the submit button of the form.
The "send" is what is known as Ajax, and it is, for example, how the Stackoverflow voting buttons work to send the votes back to the server without reloading the entire page.
Related
I am making a post request to google app script with the code below
var url ="MY WEBAPP EXEC"
function submitForm() {
var postRequest = {}
postRequest.name = $("#inputName").val();
postRequest.email = $("#inputEmail1").val();
postRequest.message = $("#inputMessage").val();
alert(JSON.stringify(postRequest)); // this alert
$.post(url, postRequest, function(data,status){
alert('success')
});
}
I am very confused why the post is working with the alert but doesn't work without it. Thank you.
===
OK I guess my question was not clear enough sorry.
I have a form accessing GAS remotely. I assumed the url implied that I was accessing GAS remotely. At the moment I am working on my localhost and on my JS above it works if the alert statement is present and does not do anything if alert is not there.
I was watching the execution list on GSuite Developer Hub to see if the request failed or completed. I observed if the alert statement is in the script the execution status is completed but if the alert statement is not there nothing happens. I assume that my post script is not working if alert is not there. Any idea why?
You haven't shown exactly how that function is called, but it's likely to be because, if this is truly a "form submit" action, the result of submitting a form is to "load a new page" (which can be the same page you're on, and is so by default with no action attribute in the form tag
Since you want to perform AJAX on form submit, you need to "prevent" the "default" form submit action - this can be achieved as shown in the second and third lines below
var url ="MY WEBAPP EXEC"
function submitForm(e) { // if this function is called using an event handler, it gets an event as the first and only argument
e.preventDefault(); // prevent the "default" form submit action
var postRequest = {}
postRequest.name = $("#inputName").val();
postRequest.email = $("#inputEmail1").val();
postRequest.message = $("#inputMessage").val();
alert(JSON.stringify(postRequest)); // this alert
$.post(url, postRequest, function(data,status){
alert('success')
});
}
I'm working with basic HTML/CSS frontend, I currently have a landing page with a form on it that sends some data to a database. When the request is done, it is expecting some sort of response. In this case, I am re-rendering the page, however, I want to replace the form with some sort of a thank you message, something so the user knows that it has sent correctly. I have tried the solution of simply having a separate near identical page with the form removed and replaced, however, this kind of code cloning seems like an inefficient way to do it. Is there a way I could do some sort of front-end DOM manipulation from within my node app instead?
Generally, if you want to manipulate how the DOM looks server side you would need to render your entire page server side and then send it to the front end.
If you want to simply manipulate the DOM after a request is received on the front end, whic is a pretty regular practice for this type of stuff; regardless of the back end language(s) used, you can:
Submit form
Let user know form is submitting to server (Best practice for UX)
Once you receive your response, manipulate the DOM however you would like
For this use case, I've taken advantage of the async/await syntactical pattern which will allow you to wait for a response while not ending up in a nested callback pattern.
The attached snipped will fake a request to the server through a set timeout value, and echo what you put into the form back to the page. It's on a three second delay and uses AJAX to make the request.
*You can simplify this code by removing some logging and comments, but I've made it more verbose than necessary for learning purposes.
**I've purposely put the submit button outside of the form element so that it does not auto-post on submit. If you want to submit this way, you can use event.preventDefault() within the function, catch the event before it bubbles, and do this instead. Either way will work fine.
async function getDataAsync0(data) {
return new Promise(async (res) => {
setTimeout(()=>{
res(data);
},3000)
});
}
$(`#submitButton`).click(async () => {
// Create div to display what's going on
let statusAreaElement = $(`#statusArea`);
// Submit Event
statusAreaElement.html(`Submitted... Waiting for response...`);
// Cache input element
let inputElement = $(`#input01`);
// Cache form element
let formWrapperElement = $(`#formWrapper`);
// Cache success message div
let successMessageElement = $(`#successMessage`);
// Get value
let value = inputElement.val();
// Send value, await response;
let response = await getDataAsync0(value);
statusAreaElement.html(`Response returned -> ${response}`)
// Clear input element
inputElement.val(``);
// Hide form, show success message
formWrapperElement.hide();
successMessageElement.show();
})
#statusArea {
position: absolute;
left: 0;
bottom: 0;
}
#successMessage {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="formWrapper">
<form>
<label for="input01">Form Input</label>
<input id="input01" type="text">
</form>
<button id="submitButton">
Submit Form
</button>
</div>
<div id="successMessage">
Thanks for your submission!
</div>
<div id="statusArea">
</div>
JSFiddle offers an echo service so I've also written the same code into a fiddle so you can see it actually call the server and echo back the response.
Here is that link:
https://jsfiddle.net/stickmanray/ug3mvjq0/37/
This code pattern should be all you need for what you are trying to do. Again, this request is also over AJAX so the DOM does not need to completely reload; if you are actually going to be making a regular post (without AJAX) to the server and then reload the page afterwards, you can do the same thing - or simply construct the new page you wanted to send to them server side and then redirect them from there.
I hope this helps!
Can I do DOM manipulation within an Express POST request?
No. The server builds up a response (a big chunk of html), that gets sent to the client which parses it and builds up the DOM. You cannot directly work with that from the server.
However you can:
1) Modify the html the server sends (have a look at express.render)
2) Run a clientide script that opens a connection to the server (websockets, AJAX) and then mutate the DOM there when the server sends something.
I want the user to get redirected to a different page as soon as form is submitted. I don't care about what happens when the controller action httpost gets called. I just want the user to get redirected a page as soon as a button is clicked or form is submitted. below is what I have tried but its not working
cshtml file snippet
<script>
$(document).ready(function () {
$('#formSubmitButton').click(function () {
debugger;
// Neither works
window.location.href = "/Home/Index";
window.location.href = "https://www.google.com";
});
});
</script>
Home Controller
public ActionResult Index()
{
return View();
}
Actual httpost controller method that gets hit
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SavePayment(PaymentFormMV data)
{
return View ("Hello")
}
I can see the breakpoint gets hit in the JavaScript code. But no effect. Also the normal post call goes on as expected and SavePayment method gets called and hence the view hello accordingly. Why I am not able to redirect user on the button click to index page. I know the SavePayment will get called eventually but why not the redirection is working. Am I missing something?
Edit
Here is the whole story. Clients are making payment and some payments are getting timed out. The "Hello" redirection is perfectly fine when the timeout had not happened. So basically if time out happens in 2 minutes. then I will put a timer for may be 1.58 minutes before redirecting user to home page. If the post method returns success then the "Hello.cshtml" will get called.
But just in case if IIS server is about to throw time out exception which is after 2 minutes then my JavaScript code will time out (1.58 set in timer) before IIS kicks out and will redirect the user to home page. And I hope that the IIS time out error which eventually will occur will not override the home page that user has been safely redirected. Please guide me. Bottom line I don't want the IIS to kick out the user. I have not added the timeout interval code in JavaScript code snippet because the normal redirection itself is not working.
Because, when you click the submit button, the form is submitted and the HttpPost action method will handle the posted formdata and return a ViewResult (The html markup generated from the "Hello" view) back. Since the form is being submitted, it will not execute the JS code where you are setting the window.location.href value.
You should do your redirection in your action method after successfully doing your save, like the PRG pattern:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SavePayment(PaymentFormMV data)
{
//do something
return RedirectToAction("Index","Home");
}
If you absolutely want to do the redirection using client side script, but want the form to be submitted and processed (like a fire-forget fashion), you might consider doing an ajax form post.
$('#formSubmitButton').click(function (e) {
e.preventDefault(); // Prevent normal form submit
var _form=$(this).closest("form");
$.post(_form.attr("action"),_form.serialize(),function(res){
// If you want to check the response and then do redirection
// you should do it here. Make sure you return a json response from server then
});
window.location.href = "https://www.google.com";
});
Edit
As per the edit in question
Here is the whole story. Clients are making payment and some payments
are getting timed out. The "Hello" redirection is perfectly fine when
the timeout had not happened. So basically if time out happens in 2
minutes. then I will put a timer for may be 1.58 minutes before
redirecting user to home page. If the post method returns success then
the "Hello.cshtml" will get called. But just in case if IIS server is
about to throw time out exception which is after 2 minutes then my
JavaScript code will time out (1.58 set in timer) before IIS kicks out
and will redirect the user to home page. And I hope that the IIS time
out error which eventually will occur will not override the home page
that user has been safely redirected. Bottom line I
don't want the IIS to kick out the user. I have not added the timeout
interval code in JavaScript code snippet because the normal
redirection itself is not working
My initial response is, Do not do anything with takes 2 minutes on a user thread like this. That is not a good user experience. I am not sure where you are getting the 2 minute time out from! But I suggest you fix the code which takes this long time. You should offload this to may be an ajax call ( see above sample ajax code) and if you are not getting a 200 OK response (or your success callback), you may do something on client side (show a message to user so they can try again). This way you can eliminate the use of your local JavaScript timer.
Bottom line is: fix the code which takes 2+ minutes! There might be an alternate way to solve your problem/use cases.
I'm interfacing with a site that implements delaying a page-load with client-side JavaScript. Basically, a form is submitted on PageA.asp, and instead of the data going to PageB.asp, it goes to PageC.asp. PageC.asp consists of a 'please wait' message along with the following JavaScript:
function OnTimer() {
window.location.replace("PageB.asp");
return;
}
setTimeout('OnTimer()', 10000);
The interesting thing here is that when PageB.asp loads, it somehow has all the information submitted from PageA.asp. Yet whenever I've looked up whether you can pass POST data along with window.location.replace, the answer has been "no".
So how does PageB.asp have the data from PageA.asp even though it was loaded from PageC.asp? Does window.location.replace load the new page with the same POST data? How would I best re-implement this in mechanize: remember the POST data from PageA.asp and submit the form with the action being PageB.asp instead of PageC.asp?
Example URL: http://twitter.realgamingreview.com/index.php
Edit: forgot to mention: use the test sign in: test/test for username/password.
I am attempting to do a simple AJAX request to retrieve some data from a database. The target file, serverTime.php, seems to be working perfectly; it inserts the desired data and returns the desired responseText.
However, the request seems to be firing twice. This is clear when I step through the JavaScript using Firebug. This causes the page to 'reset' (not exactly sure), such that my cursor loses focus from its current textbox, which is a new problem. The URL also says, "localhost/twitter/index.php?message=", even if my message is not actually empty. I want to fix this fairly minor problem before something major comes of it.
The JavaScript is below. ajaxRequest is my XMLHTTPRequest object. Any help is appreciated!
//Create a function that will receive data sent form the server
ajaxRequest.onreadystatechange = function(){
if (ajaxRequest.readyState == 4){
document.getElementById('output').innerHTML = ajaxRequest.responseText;
}
}
// build query string
var message = document.myForm.message.value;
var queryString = "message=" + message;
//send AJAX request
ajaxRequest.open("GET", "serverTime.php" + "?" + queryString, true);
ajaxRequest.send(null);
Thanks,
Paragon
I've seen this many times, and for me it's always been firebug. Try TURNING OFF firebug and submit the request again. Use fiddler or some other means to verify the request only executed once.
When I write AJAX functions in Javascript, I usually keep around a state variable that prevents a new request from being dispatched while one is currently in progress. If you just want to ignore requests that are made before another one finishes, you can do something like this:
Initialize inProgress to false.
Set inProgress to true right before calling ajaxRequest.send(). Do not call ajaxRequest.send() unless inProgress is false.
ajaxRequest.onreadystatechange() sets inProgress to false when the state is 4.
In some cases, however, you'd like to queue the actions. If this is the case, then you can't just ignore the request to ajaxRequest.send() when inProgress is true. Here's what I recommend for these cases:
Initialize ajaxQueue to an empty global array.
Before calling ajaxRequest.send(), push the request onto ajaxQueue.
In ajaxRequest.onreadystatechange() when the state is 4, pop the array to remove the request just services. Then, if ajaxQueue is not empty (array.size > 0), pop again and call send() on the object returned.
My issue was completely unrelated to AJAX. Instead, it was a simple (but obscure) issue where with two textboxes in my form, I was able to hit enter and not have the page reload, but with only one, the page would reload for some reason.
I have since changed my event system such that I am not relying on something so unreliable (now using jQuery to listen for the Enter key being pressed for specific textboxes).
Thanks to those of you who took the time to answer my misinformed question.