pushState on Ajax call? - javascript

My client is tormenting me to be able to go back to a 'previous page' using the browser back button. The thing is that this 'pages' are being called via Ajax to a modal window that displays the content. I'm doing an ajax call and I found that pushState will be my solution, but I really don't get it. I found stuff where there's not even a bit of ajax, it's all javascript.. So, what should I do to add pushState to an ajax call? Is that even possible? Or should I just a find a way to make it work with Ajax?
I found this thing called Pjax but I really don't get it. My ajax call looks something like this;
$(function() {
$('.w-container .w-nav-menu a').click(function() {
var $linkClicked = $(this).attr('href');
var $pageRoot = $linkClicked.replace('#', '');
if (!$(this).hasClass("active")) {
$(".w-container .w-nav-menu a").removeClass("active");
$(this).addClass("active");
$.ajax({
type: "POST",
url: "./PATH/load.php",
data: 'page='+$pageRoot,
dataType: "html",
beforeSend: function(){
$('#canvasloader-container.wrapper').show();
},
complete: function(){
$('#canvasloader-container.wrapper').hide();
},
success: function(msg){
if((msg))
{
$('.content').html(msg);
$('.content').hide().fadeIn();
}
}
});
}
event.preventDefault();
});
I'm sorry if someone else already created something like this, but I didn't find anything useful

You can do a pushState at any stage you'd like in the code you provided, depending on when do you want the history to be manipulated.
You can just do history.pushState([data], [title], [url]); (with appropriate values as parameters) just after a successful ajax form return and before replacing the html content like this:
success: function(msg){
if((msg))
{
history.pushState([data], [title], [url]); // replace with appropriate values as parameters
$('.content').html(msg);
$('.content').hide().fadeIn();
}
}
There might be an issue depending on the UX you've set up, if a user is accessing pages continuously by ajax calls and there are no URLs to reflect the previous page or 'state' in that case, then this solution probably won't work for you.
History manipulation functions like pushState only change the browser history, they don't control what happen when someone clicks the 'back' button.
If there are no pages being loaded with URLs in your setup then you might need to control what happens when a user clicks the 'back' button, by doing another ajax call and loading the previous content (you got to keep track of the changes in content). If that is your scenario, this might help you getting started: https://stackoverflow.com/a/25806609/4283725

The best solution is I think use a javascript component that handles this for you. I use for example Barba.js. Thats a component that used PJAX.

Related

How to display a newly randomly generated quote from a specific API when clicking a button?

Problem- I have an API that displays a random quote once the page loads. My button(div) called "newQuote" doesn't generate a new quote, instead, it displays the exact same quote, making my button useless.
My code can be found on GitHub here
SO-
I have a javascript function, called getNewQuote() that runs when my page loads. This function grabs a quote and author from an API (https://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1), and appends it to my div with the class quoteTitle and quoteDisplay.
function getNewQuote() {
$.ajax({
url: 'https://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1',
jsonp: 'jsonp',
cache: 'false',
success: function(data) {
var post = data.shift();
$("#quoteTitle").empty();
$("#quoteDisplay").empty();
$("#quoteTitle").append(post.title);
$("#quoteDisplay").append(post.content);
}
});
}
getNewQuote();
Then, I set another div called newQuote which, when clicked, would display a new quote.
$('#newQuote').on('click', function(e) {
e.preventDefault();
getNewQuote();
Now, to me, it seems that the problem is caching. The reason that I think it is a cache problem is because if I go to the site on my phone using the app Firefox Focus, which (pretty sure) doesn't store any cache, the site will run as wanted, and will change my quote whenever I click on my #newQuote. You can try it for yourself at 'rqg.ronlaniado.me', where it is hosted.
Since my problem is cache, I did use some methods and plans to avoid this.
cache: 'false',
I set cache-ing to false in my .ajax request.
<script src="qg_js.js?v=42"></script>
I put "?v-42 which, according to Google, shouldn't keep cache stored.
If anyone can look through my code and assist me in solving my issue, that'd be great. Also, this is my first time posting here, so sorry if I am a bit messy with everything.
The error was here:
cache: 'false';
The correct usage is:
cache: false;
These quotes caused cache to be kept, meaning that the quotes didn't change.

How do I run my own userscript function after the host site completes an ajax request? [duplicate]

This question already has answers here:
Fire Greasemonkey script on AJAX request
(2 answers)
Closed 3 years ago.
I'm using greasemonkey with Firefox to alter what content is displayed when I visit a particular domain. One of the pages contains a dropdown with two elements, let's call them element0 and element1. Whenever it detects a switch from one to the other, it performs an ajax query that alters the page content depending on which one you've selected. So it looks something like this:
$(".dropdown").change(function(){
if($(this).val()=='element0'){
$.ajax({
// fetch some html
});
}
else{
$.ajax({
// fetch some other html entirely
});
I'm happy with what is displayed when element0 is selected - it's element1's associated content I want to alter. So I need a way to trigger my own userscript function only in the second case. I also somehow need it to execute only after the ajax query is complete of course. How do I do this?
I have some basic experience with programming, but know absolutely nothing about jquery, ajax, json etc etc. A friend helped me locate the above ajax for that page so that I could even post a meaningful question. Please bear my level of experience in mind, because I'd really really like to move forward with whatever knowledge/wisdom you guys can offer, but will only be able to do so if I understand it.
Many thanks!
EDIT: The above is javascript that the host is running. I accessed it by saving the page and looking around manually. I am writing userscripts on the client side to alter what my browser displays. So I want to write my own function that responds to their js in the way I described.
AJAX
In ajax you have a tow useful method,
success & compleate
success: with execute if ajax request are work truth
complete: are work when finished ajax function, so you can use this method
example:
complete: function(){
// call another ajax, hide somthing, do any somthing
},
another example:
var all_data = {'user':txtuser,'pass':txtpass};
$.ajax ({
url:"ajax.php",
type:"post",
data:all_data,
beforeSend:function(){
// do somting before send a data
},
statusCode:{
404:function(){
$("#ma").html("Page not found");
},
401:function(){
$("#ma").html(".....");
}
},
success:function (data) {
$("#ma").html(data);// if sucsess
},
complete:function(){ // when complete
$("#user").hide(2000);
$("#pass").hide(2000);
$(".q").hide(2000);
}
});

Codeigniter with AJAX dropdown menus not working after form_validation fails and redirects/re-loads view

Once the validation runs, fails, and proceeds to redirect to the same controller index.
if (!$this->form_validation->run())
{
$this->index();
}
The form is a simple, two dropdowns, one dependent on the other, once the view is reloaded though, the second dependent dropdown stops working.
Here is the JS
$(document).ready(function()
{
$('#manufacturer_dropdown').change(function()
{
$("#sw_names > option").remove();
var id = $('#manufacturer_dropdown').val();
$.ajax({
type: "POST",
url: "software/get_software_names/"+id,
datatype : "JSON",
success: function(sw_names)
{
$.each(sw_names,function(id,software_name)
{
var opt = $('<option />');
opt.val(software_name);
opt.text(software_name);
$('#sw_names').append(opt);
});
}
});
});
});
If I manually refresh the page, the dropdowns work again. Not sure what is happening, maybe the document ready function stops checking or something. I'm no JS expert...
I can post more of the code if needed.
Edit: My JS URL was missing a /
Works now
If you are making an ajax request, you must give an ajax response
You cannot redirect the page in the middle of a request like that.
I've written something up going through all of this type of problem, as it's such a common one. Hopefully this will steer you along: http://codebyjeff.com/blog/2013/04/how-do-i-use-ajax-with-framework-x

ASP.NET MVC 3 - After ajax call, redirect to new page or generate page refresh

Scenario:
I have written an MVC wizard that automatically uses ajax if javascript is enabled in the browser. Each step of the wizard is a PartialView (I'm using ASP.NET MVC 3).
All works fine.
The problem is refreshing the page if, for example, the user's status changes as a result of how she fills in the wizard. EG, if the wizard logs the user in, or registers them. As the wizard 'moves' from step to step by getting Partial Views via AJAX, the page doesn't get refreshed to reflect the change in the user's status (eg, an anonymous user is now registered).
What I want to do:
Essentially, when I need a full page refresh, I need to AUTOMATICALLY run the following on the client AFTER delivering the Partial View corresponding to the current step of the wizard via AJAX:
location.reload();
The Problem:
As the DOM has been modified via AJAX, I don't know how to make my javascript (location.reload();) run WITHOUT user intervention (eg, clicking a button).
Any suggestions? I have been off work for a while and am struggling to get back up to speed.
For now, I have solved my problem using the code in the following article:
Redirecting after AJAX call, when using ASP.NET MVC
I like the approach discussed in the article because it results in reusable code, in a very MVC way - I already have a base controller (AjaxController.cs) where I encapsulate all my AJAX aware code and this is a nice addition to it.
However, there are two issues with this approach:
I have to redirect away from my wizard, so it only works for the final step of the wizard. If the user's status changes half way through the wizard, I am still jiggered.
I would still like to know how to refresh my page after an AJAX call, rather than just redirecting like this.
So if anyone has the answer, I will gladly give them the biscuit.
I am not quite sure how your ajax calls are structured, but if you are using the MVC Ajax helper you can just call location.reload(); in the OnComplete method, like so:
#using (Ajax.BeginForm(new AjaxOptions{OnComplete = "javascriptfunction"}))
{
//Data and submit button
}
<script>
function javascriptfunction(){
location.reload();
}
</script>
// C# code
public ActionResult Foo(Bar bar)
{
// code here
return Json(new
{
Success = true,
Value = this.RenderPartialViewToString("PartialViewName", bar),
Callback = "window.location.href = 'http://yourdomainurl.com/';"
});
}
// jQuery Ajax
$.ajax({
type: "POST",
url: "/urlWhereToPost",
data: ("form#id").serialize(),
dataType: 'json',
async: false,
beforeSend: function() {
// some instruction
},
error: function(e) {
alert(e.responseText);
},
success: function(data) {
if (data.Success) {
if (data.Callback != null) {
if (data.Callback.length > 0) {
jQuery.globalEval(data.Callback);
}
}
}
else {
// do something
}
}
});

how to use JSON for an error class

Hey all. I was fortunate enough to have Paolo help me with a piece of jquery code that would show the end user an error message if data was saved or not saved to a database. I am looking at the code and my imagination is running wild because I am wondering if I could use just that one piece of code and import the selector type into it and then include that whole json script into my document. This would save me from having to include the json script into 10 different documents. Hope I'm making sense here.
$('#add_customer_form').submit(function() { // handle form submit
The "add_customer_form" id is what I would like to change on a per page basis. If I could successfully do this, then I could make a class of some sort that would just use the rest of this json script and include it where I needed it. I'm sure someone has already thought of this so I was wondering if someone could give me some pointers.
Thanks!
Well, I hit a wall so to speak. The code below is the code that is already in my form. It is using a datastring datatype but I need json. What should I do? I want to replace the stupid alert box with the nice 100% wide green div where my server says all is ok.
$.ajax({
type: "POST",
url: "body.php?action=admCustomer",
data: dataString,
success: function(){
$('#contact input[type=text]').val('');
alert( "Success! Data Saved");
}
});
Here is the code I used in the last question, minus the comments:
$(function() {
$('#add_customer_form').submit(function() {
var data = $(this).serialize();
var url = $(this).attr('action');
var method = $(this).attr('method');
$.ajax({
url: url,
type: method,
data: data,
dataType: 'json',
success: function(data) {
var $div = $('<div>').attr('id', 'message').html(data.message);
if(data.success == 0) {
$div.addClass('error');
} else {
$div.addClass('success');
}
$('body').append($div);
}
});
return false;
});
});
If I am right, what you are essentially asking is how you can make this piece of code work for multiple forms without having to edit the selector. This is very easy. As long as you have the above code included in every page with a form, you can change the $('#add_customer_form') part to something like $('form.json_response'). With this selector we are basically telling jQuery "any form with a class of json_response should be handled through this submit function" - The specific class I'm using is not relevant here, the point is you use a class and give it to all the forms that should have the functionality. Remember, jQuery works on sets of objects. The way I originally had it the set happened to be 1 element, but every jQuery function is meant to act upon as many elements as it matches. This way, whenever you create a form you want to handle through AJAX (and you know the server will return a JSON response with a success indicator), you can simply add whatever class you choose and the jQuery code will take over and handle it for you.
There is also a cleaner plugin that sort of does this, but the above is fine too.
Based on your question, I think what you want is a jQuery selector that will select the right form on each of your pages. If you gave them all a consistent class you could use the same code on each page:
HTML
<form id="some_form_name" class="AJAX_form"> ... </form>
Selector:
$('form.AJAX_form")

Categories