I am trying to sort out back and forward browser buttons in my ajax page load setup.
This is my ajax code that calls page content:
jQuery(document).ready(function () {
$ = jQuery;
$("body").on("click", ".menuAjax a", function (e) {
//On click on body for ajax calls
e.preventDefault();
var pageID = $(this).data("id");
var catType = $(this).data("type");
var pageTitle = $(this).data("title");
var footerAdSwitch = $("#overFooter").data("footeradswitch");
var homePageSet = parseInt($("#homePageSet").val());
var $this = $(this);
//console.log($this);
var res;
var payload = JSON.stringify({
action: "router_loader",
pageid: pageID,
footeradswitch: footerAdSwitch,
homepage: homePageSet,
cattype: catType,
pagetitle: pageTitle,
});
XHR = $.ajax({
type: "get",
url: my_ajax_object.ajax_url + '/' + payload + '/view_' + (pageID || catType),
beforeSend: function () {
$("#ajaxPageLoader").show();
},
complete: function () {
$("#ajaxPageLoader").hide();
},
success: function (res) {
if (res != "") {
$("#ajaxpageLoad").html(res);
setTimeout(function () {
$("#ajaxPageLoader").hide();
}, 600);
$(".nav li.menu-item").removeClass(
"current-menu-item current_page_item"
);
$($this).parent().addClass("current-menu-item current_page_item");
const nextURL = $this[0].href;
history.pushState(res, pageTitle, nextURL);
document.title = pageTitle + " - company name";
$.getScript("/wp-content/themes/customTpl/js/functions.js");
var lazyLoadInstance = new LazyLoad({
threshold: 200,
});
$("html, body").animate({ scrollTop: 0 }, 0);
} else {
$("#ajaxPageLoader").hide();
}
},
error: function (req, status, error) {},
});
});
//Exclude expander btn from ajax call
$("body").on("click", ".btnNoBorder, .mobileMenueBtn, .closeBtn", function (e) {
e.stopPropagation();
});
window.addEventListener('popstate', function(e) {
$("#ajaxpageLoad").html(res);
updateContent(e.state);
});
});
Right now I ma stuck with popstate function, which I would like to pass urls of current position, so they are remembered once a users presses back button.
Can someone suggest me direction as to how to update history navigation with the browser buttons ?
Related
Good day, I am trying to manual ajax this
Add to cart
What this does is, It will add to the cart the one-time purchase option from the woocommerce subscription. I am trying to ajax it so it won't refresh the page when you click on it.
I found an idea how to manually ajax it by using these lines of codes. Reference here
(function($) {
$(document).on('click', '.testing', function(e) {
var $thisbutton = $(this);
try {
var href = $thisbutton.prop('href').split('?')[1];
if (href.indexOf('add-to-cart') === -1) return;
} catch (err) {
return;
}
e.preventDefault();
var product_id = href.split('=')[1];
var data = {
product_id: product_id
};
$(document.body).trigger('adding_to_cart', [$thisbutton, data]);
$.ajax({
type: 'post',
url: wc_add_to_cart_params.wc_ajax_url.replace(
'%%endpoint%%',
'add_to_cart'
),
data: data,
beforeSend: function(response) {
$thisbutton.removeClass('added').addClass('loading');
},
complete: function(response) {
$thisbutton.addClass('added').removeClass('loading');
},
success: function(response) {
if (response.error & response.product_url) {
window.location = response.product_url;
return;
} else {
$(document.body).trigger('added_to_cart', [
response.fragments,
response.cart_hash
]);
$('a[data-notification-link="cart-overview"]').click();
}
}
});
return false;
});
})(jQuery);
The codes above work and it does ajax however, it displays the monthly subscription, not the one-time purchase. It should display the one-time purchase because of the &convert_to_sub_55337=0 which means the one-time subscription option is selected.
Also, I am getting an error after clicking the button on the console log
Uncaught TypeError: $button is undefined
I am a newbie to handling ajax so I am unsure about the issue
Thank you in advance!!
you can try this code i hope it will helped.
(function($) {
$(document).on('click', '.testing', function(e) {
var $thisbutton = $(this);
try {
var href = $thisbutton.prop('href').split('?')[1];
if (href.indexOf('add-to-cart') === -1) return;
} catch (err) {
return;
}
e.preventDefault();
var product_id = href.split('=')[1];
var data = {
product_id: product_id
};
$(document.body).trigger('adding_to_cart', [$thisbutton, data]);
$.ajax({
type: 'post',
url: wc_add_to_cart_params.wc_ajax_url.replace(
'%%endpoint%%',
'add_to_cart'
),
data: data,
beforeSend: function(response) {
jQuery('.testing').removeClass('added').addClass('loading');
},
complete: function(response) {
jQuery('.testing').addClass('added').removeClass('loading');
},
success: function(response) {
if (response.error & response.product_url) {
window.location = response.product_url;
return;
} else {
$(document.body).trigger('added_to_cart', [
response.fragments,
response.cart_hash
]);
$('a[data-notification-link="cart-overview"]').click();
}
}
});
return false;
});
})(jQuery);
let formData2 = new FormData();
formData2.append('_token', vm.response._token);
formData2.append('file', vm.response.content[i].path);
formData2.append('type', vm.response.content[i].type);
$.ajax({
async: false,
url: "page/file/create/upload/"+vm.response.topic_id,
type: "POST",
data: formData2,
cache: false,
dataType: 'json', // what to expect back from the PHP script
contentType: false,
processData: false,
xhr: function() {
var xhr = new XMLHttpRequest();
console.log(xhr);
xhr.open('POST', this.url, false);
if (xhr.open) {
console.log("xhr port open");
}
if (xhr.upload) {
xhr.upload.addEventListener('progress', this.onProgress);
console.log("xhr.upload");
}
return xhr;
// console.log(xhr);
},
success: function (title) {
console.log(" file upload in controller recieves: "+title);
},
})
}
point : 1 > this is a function written in "methods" in a vue page (file uploading practice project with laravel v5.5 + vue 1.0)
point : 2 > from my controller file is uploaded smoothly , has no issue with that.
point :3 > now i want to impletement a progressbar which shows me the uploading %
have tried xhr:function but do not know to fetch the uploading %...
now my xhr function is look like this.. if i get the value of percentage. i will bind that with my progressbar value. but i can not get any upload %
xhr: function() {
var xhr = jQuery.ajaxSettings.xhr();
console.log(xhr);
xhr.open('POST', this.url, false);
if (xhr.open) {
console.log("xhr port open");
}
if (xhr.upload) {
var percentage = 0;
xhr.upload.addEventListener('progress', function(e) {
if(e.lengthComputable) {
percentage = e.loaded/e.total;
percentage = parseInt(percentage * 100);
// Do what ever you want after here
console.log("percentage:"+percentage);
}
}, false);
}
return xhr;
// console.log(xhr);
},
You can try this code below, it works in my side:
xhr : function() {
var xhr = jQuery.ajaxSettings.xhr();
if(xhr.upload) {
if(xhr instanceof window.XMLHttpRequest) {
var percentage = 0;
xhr.upload.addEventListener('progress', function(e) {
if(e.lengthComputable) {
percentage = e.loaded/e.total;
percentage = parseInt(percentage * 100);
// Do what ever you want after here
}
}, false);
}
}
return xhr;
}
Basically, I was using xhr = jQuery.ajaxSettings.xhr() and xhr.upload.addEventListener progress to compute its progress percentage.
Hope this works.
Finally it's working for me. happy me :)
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
percentComplete = parseInt(percentComplete * 100);
console.log("% :" + percentComplete );
$('.myprogress').text(percentComplete + '%');
$('.myprogress').css('width', percentComplete + '%');
}
}, false);
return xhr;
},
Looking at the Flux Documentation I can't figure out how the code to a ajax update, and a ajax fetch would fit into the dispatcher, store, component architecture.
Can anyone provide a simple, dummy example, of how an entity of data would be fetched from the server AFTER page load, and how this entity would be pushed to the server at a later date. How would the "complete" or "error" status of request be translated and treated by the views/components? How would a store wait for the ajax request to wait? :-?
Is this what you are looking for?
http://facebook.github.io/react/tips/initial-ajax.html
you can also implement a fetch in the store in order to manage the information.
Here is an example (it is a concept, not actually working code):
'use strict';
var React = require('react');
var Constants = require('constants');
var merge = require('react/lib/merge'); //This must be replaced for assign
var EventEmitter = require('events').EventEmitter;
var Dispatcher = require('dispatcher');
var CHANGE_EVENT = "change";
var data = {};
var message = "";
function _fetch () {
message = "Fetching data";
$.ajax({
type: 'GET',
url: 'Url',
contentType: 'application/json',
success: function(data){
message = "";
MyStore.emitChange();
},
error: function(error){
message = error;
MyStore.emitChange();
}
});
};
function _post (myData) {
//Make post
$.ajax({
type: 'POST',
url: 'Url',
// post payload:
data: JSON.stringify(myData),
contentType: 'application/json',
success: function(data){
message = "";
MyStore.emitChange();
},
error: function(error){
message = "update failed";
MyStore.emitChange();
}
});
};
var MyStore = merge(EventEmitter.prototype, {
emitChange: function () {
this.emit(CHANGE_EVENT);
},
addChangeListener: function (callback) {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function (callback) {
this.removeListener(CHANGE_EVENT, callback);
},
getData: function (){
if(!data){
_fetch();
}
return data;
},
getMessage: function (){
return message;
},
dispatcherIndex: Dispatcher.register( function(payload) {
var action = payload.action; // this is our action from handleViewAction
switch(action.actionType){
case Constants.UPDATE:
message = "updating...";
_post(payload.action.data);
break;
}
MyStore.emitChange();
return true;
})
});
module.exports = MyStore;
Then you need to subscribe your component to the store change events
var React = require('react');
var MyStore = require('my-store');
function getComments (){
return {
message: null,
data: MyStore.getData()
}
};
var AlbumComments = module.exports = React.createClass({
getInitialState: function() {
return getData();
},
componentWillMount: function(){
MyStore.addChangeListener(this._onChange);
},
componentWillUnmount: function(){
MyStore.removeChangeListener(this._onChange);
},
_onChange: function(){
var msg = MyStore.getMessage();
if (!message){
this.setState(getData());
} else {
this.setState({
message: msg,
data: null
});
}
},
render: function() {
console.log('render');
return (
<div>
{ this.state.message }
{this.state.data.map(function(item){
return <div>{ item }</div>
})}
</div>
);
}
});
I hope it is clear enough.
I'have page with a slide with some images. what I need now is to add a new image to the slide on carousel without a postback. the code I have is this
flex slider
$(window).load(function() {
$('.flexslider').flexslider({
animation: "slide",
controlsContainer: ".flex-container",
start: function(slider) {
$('.total-slides').text(slider.count);
},
after: function(slider) {
$('.current-slide').text(slider.currentSlide);
}
});
ajax code
$.ajax({
url: '#Url.Action("LoadCarrusel","picture",new { #id = #Model.Propertyid })',
type: 'GET',
dataType: 'json',
success: function (data) {
var flexslider = document.getElementById("flexslider");
// process the data coming back
$.each(data, function (index, item) {
var link = "../../Content/Uploaded-img/" + item;
var imag = document.createElement("img");
imag.setAttribute("src", link);
var newpicture = document.createElement("li");
var newpictureItem = document.createTextNode(imag);
newpicture.appendChild(imag);
flexslider.appendChild(newpicture);
});
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
and the controller which pass the data json is
public ActionResult LoadCarrusel(long id)
{
var routes = from s in db.Picture
where s.IdProp == id
select s.Location;
return Json(routes, JsonRequestBehavior.AllowGet);
}
I know this is a common problem. I've been looking at the various solutions proposed on this site and elsewhere but cannot hit upon something that works in my situation.
Here is my script:
$(function () {
$('a.editPersonLink').live("click", function (event) {
loadDialog(this, event, '#personList');
$.validator.unobtrusive.parse('#editPersonContainer');
});
$(".deleteButton").live("click", function(e) {
e.preventDefault();
var $btn = $(this);
var $msg = $(this).attr("title");
confirmDelete($msg,
function() {
deleteRow($btn, $target);
});
});
});
function loadDialog(tag, event, target) {
event.preventDefault();
var $loading = $('<img src="../../Content/images/ajaxLoading.gif" alt="loading" class="ui-loading-icon">');
var $url = $(tag).attr('href');
var $title = $(tag).attr('title');
var $dialog = $('<div></div>');
$dialog.empty();
$dialog
.append($loading)
.load($url)
.dialog({
autoOpen: false
,title: $title
,width: 800
,modal: true
,minHeight: 200
,show: 'slide'
,hide: 'clip'
});
$dialog.dialog( "option", "buttons", {
"Save": function () {
var dlg = $(this);
$.ajax({
url: $url,
type: 'POST',
data: $("#formData").serialize(),
success: function (response) {
$(target).html(response);
dlg.dialog('close');
dlg.empty();
$("#ajaxResult").hide().html('Record saved').fadeIn(300, function () {
var e = this;
setTimeout(function () { $(e).fadeOut(400); }, 2500);
});
},
error: function (xhr) {
if (xhr.status == 400)
dlg.html(xhr.responseText, xhr.status); /* display validation errors in edit dialog */
else
displayError(xhr.responseText, xhr.status); /* display other errors in separate dialog */
}
});
},
"Cancel": function() {
$(this).dialog("close");
$(this).empty();
}
});
$dialog.dialog('open');
};
Right up near the top I am trying to cause the form to recognise the validation from the partial view on the dialog via the statement:
$.validator.unobtrusive.parse('#editPersonContainer');
editPersonContainer is the name of the div containing the data in the partial view loaded into the dialog.
The bottom line is that the validation is not recognised. Am I making the call to validator.unobtrusive.parse in the wrong place, or am I missing something else here?
I ended up changing my script to use the techniques described here
Validation now works on my jQuery UI dialogs.
Hi I came up to your question as I was looking for the same.
I include this before the ajax call to validate on client side:
if (ModelState.IsValid) {}
I make an article with the full project on
Validation client/Server JqueryUI Dialog