What would be the "best" approach to dealing with forms which have to work without and with JavaScript enabled?
Would it be better to create different routes for each, like
AJAX request: route "API/contact" and return res.send("message")
without JavaScript: route "contact"and return a redirect with a query param of "message"
Or in one route and detect xhr and render it depending on this?
Or is there a better way of dealing with the problem of taking the user to the res.send("") when the JavaScript isn't enabled to give the user feedback on the submit?
To clarify:
I have a site which is working with AJAX requests for its forms to avoid full page loads. It lacks the fallback when JavaScript is not enabled and thus when a user clicks submit on a form, he receives the data from the post back with res.send and it replaces the whole page, instead of the desired effect which would be to just update a label with the "success/fail" message. The question then remains as above which would be the neat way of dealing with this?
Probably the best thing to do would be to check the X-Requested-With header and check that it contains XMLHttpRequest (but this might get deprecated as the new fetch API will slowly come into browser.
Based on that value, you might want to return a JSON payload, or eventually trigger a server side rendering, therefore returning an HTML page ready-to-be-consumed.
As an alternative, you can return a redirect response with a particular query string value; once the page is loaded, you will check for that value (using qs for example, or deparam in jquery and manipulate the client side accordingly.
Your server routes have nothing to do with client-side javascript. You don't need javascript to receive a "res.send" message.
Related
I have a website and when a user follows an internal link I would like to pass some extra information to a new page, so JavaScript on the destination page could do some useful highlighting.
There is an option to pass that information via the link parameters (GET), but it will generate lots of virtually duplicate pages and break pretty URLs concept. Another way is to make a webapp using AJAX, but it will also bound content to a single URL.
How can I transparently pass some information to the new page during navigation w/o messing with site's URL structure?
You could store the data in local storage or session storage, and retrieve it again on the destination page.
So you have a few options.
Form Submission
First option post a form with the data. Add a hidden form, on the anchor click capture the click event, set the hidden fields with the values you want to send to the next page, and submit the form. On the next page, read the post parameters in the backend and update the page.
Local Storage
On click of the anchor, set localStorage to the values you want to appear on the next page. When the next page loads, read the localStorage values and update the page. Note: The server will not have access to the values
Ajax with pushState
Use Ajax to submit the form. When the Ajax call returns, use window.history.pushState to update the url with whatever url you want to be displayed to the user.
One of the options not mentioned is to create a dirty URL:
/destination/param1/value1/...
then strip additional parameters at server-side and redirect:
/destination
keeping additional values stored at server-side (e.g. via sessions). I still prefer using sessionStorage in a real application, but it worth mentioning anyway.
What do you mean it will "bind content to a single url"? AJAX request is the first thing that comes to my mind as the solution to this problem. You dont have to use the url of the page to make the ajax request, you can build the url inside your javascript based on whatever conditions exist in your application.
Besides AJAX and passing parameters in the URL, the only other thing I can think of is to use Cookies. That of course runs into problems if the user has cookies disabled. I think an Ajax call to your server is the most robust way of handling the problem.
The clearest example of this I could think of is the Reddit Upvote/downvote buttons how when you click the button, the value for upvotes is updated, the upvote button lights up, and the page DOES NOT reload, you just stay exactly where you are on the page.
I am trying to make a feature similar to this and I can totally figure out how to do it with reloading, but I want it to not reload so the user experience isn't disrupted.
Is it possible to do this with php? or would I need to use javascript or something?
The action I would need it to perform would be a basic update query in the database.
This would be done with an Ajax call to your php script. Ajax is designed for these asynchronous updates and/or reloads.
Another way you can do this is with HTML5 WebSockets. You could have the client send a trigger to the server when the user clicks the upvote, and then the server could update and push back the data. It would, however, be a bit overfill for this.
If what you want to do is to contact a server to either send it some state or to retrieve some state from the server (or both), then you would use AJAX with javascript in order to contact the server without reloading the page. You can then also use javascript to update the state of your page after the operation. That is generally what the Reddit page you refer to is doing.
Conceptually, you'd set up your page like this:
Put the link on the page.
With javascript install an event handler so you are notified of a click on the link.
When the link is clicked, your event handler will be called.
Prevent the default behavior of the link so the browser doesn't navigate to a new page.
Then, in the event handler, send your data to the server using AJAX. You will obviously need a URL on your server and server process that can accept and process the data for you and return a value if you need to.
If you need the response from the server, then set up a callback function for when the AJAX call completes (this will be some indeterminate time in the future).
Then, if you need to change the current page in any way (like show one more upvote), then you can modify the current page with javascript to show that new state.
Ajax is easier to use with a library (like jQuery) that contains some ajax support code, but you can certainly implement it in plain javascript too.
Here's one example of ajax with plain javscript. You can find many other examples with Google.
This MDN tutorial on AJAX seems pretty helpful too to show you how it works.
You could use JavaScript to do this. Here's a quick sample:
Vote Up
Simple solution in JavaScript:
var el = document.getElementById("upvoteBtn");
el.addEventListener("click", onVoteClick);
function onVoteClick(e) {
e.preventDefault();
// do something
}
Here's a fiddle.
NOTE: I see you'd be updating the database. In that case, you would have to use AJAX in the onVoteClick function (or use XMLHttpRequest) for this. JavaScript is a client-side programming language and will not be able to communicate to the server without the use of AJAX or XMLHttpRequest. Using the jQuery library, you should be able to write AJAX pretty easy.
It's called AJAX.
With AJAX you can send a request in the background.
The easiest way is to use the jquery libary for this.
You can also output some data as JSON back to the script if you want to take some other actions depending on the result from that query.
A good tutorial is this one.
It also explains how this requests (called: XMLHttpRequest) work.
You need to use Javascript's XMLHttpRequest
You can use AJAX...
It allows you to use JavaScript (client side) to call server side functions. Here's a good example.
So, I know that when I submit a form whose method is POST that the server receives the contents of that form and then processes them accordingly, and then returns a page with the desired content. What I am trying to learn is what exact query url is being passed to the server side script when I submit a form on a website that does not belong to me. The reason I want this query string is so that I can make use of the server side script programatically with my own data. There is no public API served by this website, but I would like to formulate my own.
So my question is, is there a way to intercept the POST as a query string URL? Perhaps by using a javascript console in browser?
I know I can look at the source code for the page and find the names/values of the form fields. However, there also happens to be a hidden field on this page whose properties are set by javascript during validation at submission time. How should I go about this?
You can use an extension for intercept the data : Tamper Data on FireFox
https://addons.mozilla.org/fr/firefox/addon/tamper-data/
You can intercept and modify all headers requests
This code toggles the color of an element whenever you click on it. But how can I send a GET request with query string ?toggle=True on the first toggle and ?toggle=False on the second one?
Ow, I can see it appearing in Firebug, but not in the url of the page. Any idea why?
Making a request and changing the URI in the address bar are two different things unless you cause the browser to load a completely new page.
If you want to do that, then you should forget about using client side JavaScript and move your logic server side and use a regular link.
In the server side logic, the value of the query string argument would be used to determine the class of the div (which is used to set the style) and the href of the link (i.e. if it has True or False in the query string).
If you want to avoid loading a new page, then you are looking at two separate steps.
The first one you already have (the changing of the style using JS).
The rest gets more complicated…
First you need server side logic so that True/False in the query string will set up the initial state of the page correctly. This will be the same as the logic described for the previous method.
Then you need to update the URI so that it matches the one that would load the page in the state you are altering the current page into. This is done using the History API (pushState and friends). There are more details on the subject on this question.
If you want to notify the server of the change, then you'll need to use jQuery.get, as well as updating the page and changing the URI in the address bar. To be efficient, you should probably add an additional query string argument (so you can tell if it from Ajax from that a normal page load) and have the server return a simple acknowledgement rather than the whole HTML document when it sees that argument.
Just use jQuery's get method to do so or do it yourself in your toggle functions.
A pragmatic yet pretty basic solution may be to use a local variable as a counter.. If the counter is even, send True, if odd, send False.
Increment counter on each click :)
How do I design a Django/Javascript application to provide for conditional Ajax responses to conventional HTTP requests?
On the server, I have a custom-built Form object. When the browser POSTS the form's data, the server checks the submitted data against existing data and rules (eg, if the form adds some entity to a database, does that entity already exist in the database?). If the data passes, the server saves, generates an ID number and adds it to the form's data, and passes the form and data back to the browser.
if request.method == 'POST':
formClass = form_code.getCustomForm()
thisForm = formClass(data=request.POST)
if thisForm.isvalid():
saveCheck = thisForm.saveData()
t = loader.get_template("CustomerForm.html")
c = Context({ 'expectedFormObj': thisForm })
(Note that my custom logic checking is in saveData() and is separate from the html validation done by isvalid().)
So far, standard Django (I hope). But if the data doesn't pass, I want to send a message to the browser. I suppose saveData() could put the message in an attribute of the form, and the template could check for that attribute, embed its data as javascript variable and include a javascript function to display the message. But passing all that form html back, just to add one message, seems inelegant (as does the standard Django form submission process, but never mind). In that case I'd like to just pass back the message.
Now I suppose I could tie a Javascript function to the html form's onsubmit event, and have that issue an XMLHttpRequest, and have the server respond to that based on the output of the saveData() call. But then the browser has two requests to the server outstanding (POST and XHR). Maybe a successful saveData() would rewrite the whole page and erase any potential for conflict. But I'd also have to get the server to sequence its response to the XHR to follow the response to the POST, and figure out how to communicate the saveData outcome to the response to the XHR. I suppose that is doable, even without the thread programming I don't know, but it seems messy.
I speculate that I might use javascript to make the browser's response conditional to something in the response to the POST request (either rewrite the whole page, or just display a message). But I suspect that the page's javascript hands control over the browser with the POST request, and that any response to the POST would just rewrite the page.
So can I design a process to pass back the whole form only if the server-side saveData() works, and a message that is displayed without rewriting the entire form if saveData() doesn't? If so, how?
Although you can arrange for your views to examine the request data to decide if the response should be an AJAXish or plain HTML, I don't really recommend it. Put AJAX request handlers in a separate URL structure, for instance all your regular html views have urls like /foo/bar and a corresponding api call for the same info would be /ajax/foo/bar.
Since most views will examine the request data, then do some processing, then create a python dictionary and pass that to the template engine, you can factor out the common parts to make this a little easier. the first few steps could be a generic sort of function that just returns the python dictionary, and then actual responses are composed by wrapping the handler functions in a template renderer or json encoder.
My usual workflow is to initially assume that the client has no javascript, (which is still a valid assumption; many mobile browsers have no JS) and implement the app as static GET and POST handlers. From there I start looking for the places where my app can benefit from a little client side scripting. For instance I'll usually redesign the forms to submit via AJAX type calls without reloading a page. These will not send their requests to the same URL/django view as the plain html form version would, since the response needs to be a simple success message in plain text or html fragment.
Similarly, getting data from the server is also redesigned to respond with a concise JSoN document to be processed into the page on the client. This also would be a separate URL/django view as the corresponding plain html for that resource.
When dealing with AJAX, I use this:
from django.utils import simplejson
...
status = simplejson.dumps({'status': "success"})
return HttpResponse(status, mimetype="application/json")
Then, AJAX (jQuery) can do what it wants based on the return value of 'status'.
I'm not sure exactly what you want with regards to forms. If you want an easier, and better form experience, I suggest checking out uni-form. Pinax has a good implementation of this in their voting app.
FYI, this isn't an answer...but it might help you think about it a different way
Here's the problem I'm running into...Google App Engine + jQuery Ajax = 405 Method Not Allowed.
So basically I get the thing to work using the outlined code, then I can't make the AJAX request :(.