Attempting to change pages without full reloading in django and javascript - javascript

I have tried to do something with Django and javascript. So for example, if I want to go to my "about" page from my "home" page, I only want to load the contents of the page. There are many similar elements in both pages (such as a header image and navbar) that does not need to be reloaded. I have already 80% achieved what I want, my code is below:
javascript
function loadcontent(url, classname) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// below changes the url to the new page
window.history.pushState(url, url, url);
var htmlres = document.createElement("div");
// get the html from the ajax response and then change the required parts.
htmlres.innerHTML = this.response;
document.querySelector(classname).innerHTML = htmlres.querySelector(
classname
).innerHTML;
}
};
xhttp.open("GET", url, true);
xhttp.send();
}
window.addEventListener("popstate", function(e) {
window.location.reload();
});
example link for about page
<a onclick = "loadcontent('{%url 'about_page'%}', '.content')" id = 'About'>About</a>
Django views.py about page
def about_page(request):
if request.is_ajax():
return HttpResponse('mainsite/about_page.html')
return render(request, 'mainsite/about_page.html')
First, of all I would appreciate feedback if this is actually a good idea or not. I have just started learning web programming and this is a mini-project of sorts.
Secondly, my issue is with pressing the back button on my browser. With the current code, I cause it to reload the url because if I press the back button and go back to my "Home" page without reloading, the webpage still displays the same thing on my "About" page.
Having to reload is not ideal since I went through the trouble of creating a way to only load certain parts of my webpage. Is there any way to store what has changed, so that when I "popstate()", it will revert the changes? One possible way is to call my loadcontent() function when popstate happens. However as shown in my function, I need to pass it the url to go to, and class name of the "div" that I want to swap. Is there a way to store the previous URL and which classname was changed?
Thirdly, as shown in my load content function, I don't really know what the "state" parameter sent to history.pushState() is for... I understand that it is a key-value dictionary-like object, however, when is it stored and when will I need to access it? Is it useful for my case where I just need to reload content without any user-selected items?
The only thing I can think of now is to do something like to use {wasloaded: True} as my state parameter, so that when I do "popstate()", it is able to identify if the current page was loaded through my loadcontent() or not, and handle it as required. (I guess this is because if someone came to my page from a totally different website, I would need to reload their page instead of trying to do loadcontent().)
Thank you for taking the time to read this!

Your approach is not good for this.
you have to follow following steps to achieve this;
the DOM which you want to update on JS event should have a unique ID or class.
make your ajax call which should return JSON response not HttpResponse and JSONResponse should have HTML field, rendered HTML of you template. You can use get_template and render methods for this.
On success, you have to update the HTML of the page by selecting the unique DOM container.

Related

Handling url targeted PHP page with custom jQuery loaded content

First I used include('pageName.php'); for every page I wanted to load.
Now I decided to rewrite everything and to load a page in a <div id="page_content"></div> with the jQuery function: $('#page_content').load(pageurl, {access:true});
I hope this is the best practice. Because I want to reduce load time on my web application by not refreshing the whole website with all CSS and JS files but just to refresh content when clicked on a new page.
Currently I am using the following function to load pages into the division and to pushState to history:
//Dynload pages
$("a[rel='dynload']").click(function(e) {
e.preventDefault();
var page = $(this).attr("page");
var pageurl = "pages/" + page + ".php";
$('#page_content').load(pageurl, {access:true});
if(pageurl!=window.location){
window.history.pushState({path:pageurl},'',page);
}
//stop refreshing to the page given in
return false;
});
This works perfectly.
I have this button that triggers this function and gives for attribute page="index_content" . The function will load this page to the division and the state is being pushed into the history.
However. We get an url something like this: https://mywebsite.com/index_content
The problem is, when I load this specific URL into my browser I get : "Page not found" ofcourse, because it is trying to search for the index_content folder which does not exist.
Is there a way to check the url by my PHP/jQuery script and to load the correct page into the division? If not, how can I solve this for a generic case.
When I add a new page, I want to spend no- to very less time on the pageswitcher function.
In that way I can also handle non-existing pages.
Thanks in advance!

How to use information from the URL to click on specific button?

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!

jQuery: Reload a DIV which was already loaded by AJAX (without url)?

I load a div by a simple
$('#thediv').load("theurl/param1/param2/param3");
The params differ - and I grab them from different points - depends on where the user clicks. (Different filter options..)
Now I'm searching for a simple way to reload this content with the url it was actually loaded - to avoid searching for the right filter params at this place. It is possible?
jQuery will not "save" the source of information on its own, but it is possible to specify it manually using the .data() method alongside the initial .ajax()
This means during the initial load, you can associate a URL with a div by saying something like .data("source-url","MY URL GOES HERE")
After that, you can look up that information the next time you want to reload it by using .data("source-url")
For Example:
function reloadDivs() {
// Look up all of the divs that we might want to reload
$("div.reloadable").each(function(i,el) {
// For each div, check to see if the source-url was set
// If it was set, re-run the ajax call
var $el = $(el);
if($el.data("source-url")
$el.load($el.data("source-url"));
});
}
$(function() {
// Set the initial source, change mypage.html to your actual source
$("#example-div").data("source-url","mypage.html");
$("#refreshbutton").click(reloadDivs);
});
Hope this helps!

remember most recent click

So I want to be able to have a different styling for a link after you go to the page it's clicked on. I have been using the following code:
$(document).ready(function(){
var url = document.URL;
function contains(search, find) {
return search.indexOf(find) !== -1;
};
$('#topbar a').each(function(){
var link = $(this).attr('href');
var answer = contains(link,url);
if(answer === true){
$(this).addClass('check');
}
else{
$(this).addClass('nocheck');
};
});
});
This goes through the links in my navigation bar and checks if it's on the same page as the link, and it works, but I can't use it in one specific case: Random.
I have a link that generates a random page from the pages I have, so it does not have a specified link as it links to a function to randomly generate the page (note: I cannot change the function or access information from it).
So how can I detect that the random link was clicked previously so i can give it the .check class
If i understand your question correctly, your function does not work for the randomlink because this has a href like http://mysite.com/random, but the server will actualy redirect you to a different page, like http://mysite.com/about-me, and therefore the url of the active page does not match the href of the random button, and it will not get the active state.
One could argue if you would want it to get the active state, cause clicking it again would not (likely) bring you to the same page, but that is besides the question.
I can see to ways to solve this.
server side:
In stead of redirecting to ie. http://mysite.com/about-me in the random function, you could also redirect to http://mysite.com/about-me?random. By adding this get variable, you should not change the behaviour of the link (unless you have some very strict controller, or that variable is actually used, but that is unlikely). You could then detect with javascript if that variable is present in the url, and then activate the random button.
Something like this:
$(document).ready(function(){
var url = document.URL;
// check for random
if (url.indexOf('?random') >= 0) {
$('#topbar a.random').addClass('check');
}
// check all other
$('#topbar a:not(.random)').each(function(){
if($(this).attr('href').indexOf(url) >= 0){
$(this).addClass('check');
}
else{
$(this).addClass('nocheck');
};
});
});
cookie:
If you do not have acces to the server side random controller, you could do it entirely with javascript, by the use of a cookie (the only way I know to make a variable persist trough page requests).
On click of the random button, you would first set a random cookie to true with javascript, before letting the actual link do it's thing. On entering the page, you could then do a similar check as in my previous option, but in stead of the url you check if the cookie is tre. If so, you change it to false (so on the next page request the random button will not be active again) and set the randombutton to active.
As I believe the first solution is to be preferred (cookies should only be used as a last resort, they are sent on every page request, which means extra data, and your user might have cookies disabled, or there might be laws against using cookies, so the function could not always work), I will not write the javascript yet. Feel free to ask if you prefer this solution and need further help however.

URL change ajax call in Facebook

In facebook, whenever you navigate to a different URL (in some situations), the URL changes but there is no feeling sensed as going to a different page.
For example: when we view pictures in facebook, and when we move to the next image the URL changes in the address bar
FROM >facebook.com/foo?bar=foobar&xxxx=
TO > >>facebook.com/foo?bar=boobar&xxxx=
and this is not hashed change also
like
FROM >facebook.com/xxxxx#xxx=xxxx
TO > >>facebook.com/xxxxx#xxx=yyyy
How is this possible seamlessly. I mean how is that only a container is modified on URL change. URL change is supposed to navigate to a different page which can contain cached information from previous page and THIS navigation by URL change can be seen obviously by browser's screen going blank for a moment.
If using an iFrame, how to implement this ?
I use somehting similar to this
try {
var stateObj = { foo: "bar" };
history.pushState(stateObj, "page", href);
loadPage(href);
}
catch(e) {
window.location.hash = "#!/"+href;
}
If it supports the HTML5 pushState them change URL, but if it doesn't then the fall back is the window hash.
wow. I just asked it few minutes ago ... use search next time ;)
Dynamic favicon when I'm proccessing ajax data
Modify the URL without reloading the page
There's a jQuery plugin called "address" that will watch for changes and call the function you give. I think it's just checking the URL every 100ms or so.
They issue an AJAX request for the data necessary to fulfil the "navigation", then tell the browser to "go to #xxx=yyy". Since such an anchor doesn't exist, the browser doesn't actually scroll down. However, it does record a new history entry, and also updates the URL so that if someone copy-pastes that URL, they will view the same object that the user is seeing, rather than just the original page.

Categories