htmlajaxpyramidchameleon

Send AJAX Request and response with new URL


at first I want to say, that I'm new to web development and missing some specific scientific terms.

I'm using Pyramids for the backend and Chameleon in the front end. Now I've a main page, where I send a few ajax request. After the response is received, I've got a callback for DOM manipulation. AFAIK dom manipulation are not saved by the browser, so the user can't hit the back button. But how is the mechanism called - or how can i get the ajax response AND a unique url? The url can be something out of the current one + the params or a sha1 of the params.

Do I need to implement a specific handler on the server side or can this be done by the client?

With the help of google I only could find, that I cannot preserve the states of dom manipulation in the browser. So every request needs a unique url -> Therefore I think this has to be done on the server side but as said, I'm new.

Thanks :)

Edit: The site - I'm programming - can be imagined like 'who wants to be a millionaire'. We have several rounds and in each round the user can choose between several answers, where every round depends on the last round. It is hard to add code for this, because it is part of my doctoral degree and quite huge :\


Solution

  • (Firstly, Chameleon does not run "on the front end" - it's a Python templating library which takes a string (your template) and a python dict (template parameters) as input and returns another string as its output. When sent to the client, that output is interpreted by the browser as a HTML page, possibly with embedded <script> tags. The JavaScript in those tags is then executed by the browser - that's what runs on the client.)

    Now, on to your question :) You can change the URL displayed in the browser's address string from JavaScript, which will insert a new entry into the browser's history. You'll also need to somehow ensure that your application can restore its state based on the information in that new URL, otherwise things will break if somebody bookmarks the URL, opens it in a new tab or simply reloads the application.

    One, historically older, way of manipulating browser's history is by modifying the hash part of the URL via window.location.hash. Here's a minimal example:

    <html>
    
    <body>
        <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    
        <input id="name-input" type="text" />
    
        <script>
            // restore the "application state" on page load -
            // if there's a hash in the url we set the text in the input
            if (window.location.hash) {
                $('#name-input').val(window.location.hash.substring(1));
            }
    
            // whenever the hash changes (user clicked the Back button)
            // we also need to modify the application state
            $(window).on('hashchange', function () {
                $('#name-input').val(window.location.hash.substring(1));
            });             
    
            // type some text in the input and press Enter. 
            // Observe the URL changing. Try using the Back button.
            $('#name-input').on('change', function () {
                window.location.hash = $(this).val();
            });
        </script>
    </body>
    
    </html>
    

    Another, more modern, way of modifying the history is via history.pushState(), which is more powerful but might require some server-side support (your server will need to be able to serve a correct page from the new URL your application transitioned to - if your URLs look like mysite.com/page1, mysite.com/page2, and you use pushState to transition from /page1 to /page2 - the server needs to be able to handle both URLs).

    You also need to be aware that there's a whole world of client-side frameworks built specifically to deal with this kind of situations (retrieving JSON data, rendering a page, modifying the URL), so maybe you'll find that using a client-side framework instead of doing things manually simplifies things. I'd start by looking at Backbone.js as it's pretty minimal and does not require you to do things in the "one and only true way" as some other frameworks.