abort a window.location.hash - javascript

I have a url say www.abc.com which display all data of a table
I have search box in the page which calls a function search() on keyup
//search function
function search(){
window.location.hash = "?query="+$("#search).val(); /* goes to the page and get data*/
}
When I type any key say a, it will send a the request www.abc.com?query=a and get all data starting with a
When I type any key say aa, it will send the request www.abc.com?query=aa and get all data starting with aa
I want to know a way to abort the request www.abc.com?query=a when
www.abc.com?query=aa is send because it takes a lot of time

Whatever "goes to the page and get data" is, it should return a handle. For instance, if you're using the Vanilla JS XMLHttpRequest, then you can return that object.
Then, before loading a new search, call its abort method to cancel the old one.
Note that this may not actually cancel it on the server side, so be careful.

Related

Can I do DOM manipulation within an Express POST request?

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.

Javascript: Append a string to search query after clicking submit/search button

In this case, Let's take Google as example:
The code is JScript .NET, which is basically a .NET version of Javascript. Regardless of language, Anyone with appending type of skill can answer my question.
This code is used in Fiddler(It's a Man-in-the-middle proxy)
if (oSession.uriContains("&q=")) // oSession is a Fiddler object session // uriContains() function, checks for case-insensitive string from the URI
{
var str = oSession.fullUrl;
var sAppend = "test1+test2+test3";
if (!oSession.uriContains(sAppend))
{
oSession.fullUrl = str.replace( "&q=","&q="+sAppend);
}
}
For those who are confused, It says, If &q= is present in the URI, replace/append &q= with &q=test1+test2+test3
Problem: It appends test1+test2+test3 instantly, when it sees &q= in the URL.
Basically, how do I make it wait until I click the submit/search button
Thank you.
Identifying your problem
I'm assuming:
you want to use Fiddler for your solution (since you're already using it)
you've figured out how to alter the request URI (as shown in your example), and your problem is that you want to target only those requests where the "search" button was clicked, not auto-submitted searches
Isolating those requests that stem from the search button being pressed on google is not straightforward, but I came up with a hack that seems to work. Basically, the oq (original query) get parameter is only added when the user explicitly hits button/enter key, so we test for its presence in order to identify such requests.
Solution
In your OnBeforeRequest method in Fiddler Handlers class (where you're already putting your code), we'll:
Check that request is to www.google.com and contains q parameter
If true, log (in the fiddler log) that a query was submitted to google.com &
highlight request in pink
Check that request contains oq parameter (original query)
If true, log alert that submit button was pressed & highlight request in Light Forest Green
Code
if(oSession.HostnameIs('www.google.com') && oSession.uriContains("&q=")){
FiddlerApplication.Log.LogString('query submitted to google.com...');
oSession['ui-backcolor'] = 'pink'; //highlight this request
//test for original query
if(oSession.uriContains('&oq=')){
FiddlerApplication.Log.LogString('SUBMIT BUTTON OR ENTER CLICKED (probably)');
oSession['ui-backcolor'] = '#369369'; //highlight in Light Forest Green
//whatever sort of request manipulation you want to do here...
}
}
Other notes:
I'm assuming you want to prepend your query string to the existing q value, i.e. q=Hello will become q=test1+test2+test3Hello. If you want to replace it you need More Regex.
Depending on your needs, Naomi or Ahmed's request may be better (it's in-browser, not in fiddler).
Modifying a request or response in Fiddler
Understanding Fiddlerscript
Well in Javascript you can bind actions to events. In your case the event is the submit of the form For example:
function addEventsToHTML(){
var form1 = document.getElementById('form1');
form1.onsubmit = submitHandler;
function submitHandler(){
alert("You just submit: "+this.email.value);
}
}
If you want to bind it on click you can do:
object.onclick=function(){myScript};
Or
object.addEventListener("click", myScript);
Note: The addEventListener() method is not supported in Internet Explorer 8 and earlier versions.

ajax sending request twice

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.

How to add parameters to a #Url.Action() call from JavaScript on click

I have a link that when clicked needs to call a controller action with certain data which must be retrieved via JavaScript. The action will be returning a FileStreamResult.
I looked at #Url.Action but I couldn't figure out how (or even if) I could pass value dictionary stuff which had to be retrieved via JS.
So then I went with a $.post from a click handler. The problem I'm having is that I'm not sure what to do in my success: function() to return the file stream result to the user. Or even if I can.
So any help on how you would do something like this would be great..
So then I went with a $.post from a click handler. The problem I'm having is that I'm not sure what to do in my success: function() to return the file stream result to the user. Or even if I can.
Exactly. You can't do much with a received byte in javascritpt: obviously you cannot save it on the client computer nor pass it to some external program on the client. So don't call actions that are supposed to return files using AJAX. For those actions you should use normal links:
#Html.ActionLink("download file", "download", new { id = 123 })
and let the user decide what to do with the file. You could play with the Content-Disposition header and set it to either inline or attachment depending on whether you want the file to be opened with the default associated program inside the browser or prompt the user with a Save File dialog.
UPDATE:
It seems that I have misunderstood the question. If you want to append parameters to an existing link you could subscribe for the click event in javascript and modify the href by appending the necessary parameters to the query string:
$(function() {
$('#mylink').click(function() {
var someValue = 'value of parameter';
$(this).attr('href', this.href + '?paramName=' + encodeURIComponent(someValue));
return true;
});
});
Instead of going with a post, I'd go with associate a JQuery on click handler of the link which would call the controller action. This is assuming that the action method returns a FileStreamResult and sets the correct content type so that the browser interprets the result and renders it accordingly.
With your approach you'd have to interpret in the onSuccessHandler of the post on how to render the generated stream.

Sending a JSON string as a parameter to an action

I have a button on my Ruby on Rails view file.
Firstly when the button is clicked an Ajax call is made which in response gives a JSON string. So far I have accomplished this task.
Here is where I am stuck: The button also redirects me to another action of the same controller. Now I want to send the JSON string received by JavaScript as a parameter to that action.
Is there any way around this?
Your ajax call should look something like this:
... doing stuff before ...
$.ajax(
url:'url-to-script',
success: function(data) {
var json = JSON.parse(data);
$('#hidden-field').val(json); // set a hidden field in your form
$('#from-id').submit();
}
);
$('#submit-button').attr('disabled', 'true'); // disable the button
// set some spinny animation to notify the user that you are waiting.
// time out after a while if you don't get a response
... doing stuff after ...
Basically we fire off the ajax event, disable the button and notify the user you are waiting. When the call returns, your callback method submits the form to rails. You can also set a time out for the ajax call and let the user resubmit if necessary. You can handle the error case however you like.

Categories