I have defined the following script as part of implementing paging :-
var getPage = function () {
var $a = $(this);
var options = {
url: $a.attr("href"),
data: $("form").serialize(),
type: "get"
};
$.ajax(options).done(function (data) {
$(".loadingimage").show();
var target = $a.parents("div.pagedList").attr("data-tms-target");
$(target).replaceWith(data);
});
return false;
};
$(document).ready(function () {
$(".main-content").on("click", ".pagedList a", getPage);
})
And part of the mark-up is as follow:-
<div id="AuditTable">
<div class="pagedList" data-tms-target="#AuditTable">
#Html.PagedListPager(Model , page => Url.Action("Index",new { page }),
PagedListRenderOptions.ClassicPlusFirstAndLast)
</div> <img src="~/Content/Ajax-loader-bar.gif" class="loadingimage" id="progress2" />
<table class="table table-striped table-bordered bootstrap-datatable datatable">
<thead><tr>
The paging will work well , but the problem is that the
$(".loadingimage").show();
Will not show the hidden loading image during data retrieval, can anyone advice on this problem ?
Try these
You can load the image in your browser (e.g. http://yourdomain.com/Content/Ajax-loader-bar.gif) If you can, consider writing full url as image src.
Try id as selector (e.g. $("#progress2).show(); )
If those are not leading you to anywhere you can put the image into a div, remove its class (assume that you hide it with css), .show(); and .hide(); within getPage function.
HTML:
<div id="loadcontainer"><img src="Content/Ajax-loader-bar.gif" id="progress2" /></div>
Javascript:
var getPage = function () {
$("#loadcontainer").show();
var $a = $(this);
var options = {
url: $a.attr("href"),
data: $("form").serialize(),
type: "get"
};
$.ajax(options).done(function (data) {
$("#loadcontainer").hide();
var target = $a.parents("div.pagedList").attr("data-tms-target");
$(target).replaceWith(data);
});
return false;
};
Related
So, I am doing a laravel project where I am using Jquery sortables to sort some data and then using ajax to update the order in my database.
laravel blade code
<div id="gallery" style="width: 80%">
<div id="image-container">
<ul id="product-list" >
#foreach ($images as $key=>$image)
<li id="product_{{$key}}" class="inline-block" style="width: 20%">
<img id="li_product_{{$key}}" src="s3 source">
</li>
#endforeach
</ul>
</div>
</div>
JQuery Code :
<script>
$(document).ready(function () {
var dropIndex;
$("#product-list").sortable({
update: function(event, ui) {
dropIndex = ui.item.index();
var productIdsArray = [];
var i = 0;
$('#product-list li').each(function (index) {
var id = $(this).attr('id');
var split_id = id.split("_");
productIdsArray .push(parseInt(split_id[1]));
});
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: "/update",
type: 'post',
data: {
productIds: productIdsArray,
},
success: function (response) {
console.log(response);
}
});
}
});
});
</script>
It is working fine for the first time...updating data in the databse. and If I refresh the page and try again, it is fine. But If I keep changing order without refreshing, then it is not changing the dom...and the order is getting messed up. I need to know, how do I keep sorting the order without refreshing the page properly.
I would like to click on a previous or next button and update the ajax post request. The parameter I want to change is the variable called "page". The URL of the request takes this variable to show the right page. When I click on a previous or next button I want to change the "page" variable value. Thanks.
$(document).ready(()=>{
var pageSize = "pageSize=10";
//want to change the page number on click
var page = "page=1"
var requestIndex = $.ajax({
type: 'POST',
url: `url`,
beforeSend: function(){
$("#loading").show();
},
complete: function(){
$("#loading").hide();
}
});
// console.log(request)
requestIndex.done((data)=>{
var done = JSON.parse(data)
// console.log(done)
done.forEach((result, index)=>{
// res.push(result)
var firstName = result.FirstName;
var lastName = result.LastName;
var modelYear = result.ModelYear;
var make = result.Make;
var model = result.Model;
var dealership = result.Dealership;
$('#test>tbody').append(`
<tr>
<td>${firstName} ${lastName}</td>
<td>${modelYear}</td>
<td>${make}</td>
<td>${model}</td>
<td>${dealership}</td>
</tr>
`)
})
var tr = $('table').find("tr");
var resultQuant =[]
resultQuant.push(tr)
var pages = []
//loop over each result and create pagination
resultQuant.forEach(function(res, index){
console.log(res.length);
if(res.length > 9){
$('#prev_page').append(`
Prev Page
`)
$('#next_page').append(`
Next Page
`)
}
})
});
requestIndex.fail(function(jqXHR, textStatus) {
console.log('failed')
});
})
Here is a working snippet for what I think you're looking for. I had to make some changes, some for aesthetics, and some for functionality. Here's the functional changes/updates:
Your whole ajax/refresh table script needed to be outsourced to a function so it could be called multiple times.
The page and pageSize variables are better left as numbers rather than queryString strings
I created a delegated event listener on your buttons. It's one listener that will handle either button. The listener callback finds out if its the next or previous button that was clicked, then calls the goToPage() function with the incremented onPage variable
The table is now cleared before each new data batch is written to it, as you'd expect a paginated result to be
The buttons should disable/enable according to the pagination, so I put in a script to test if we're at the first page or the last page to disable/enable them
I changed all your vars to lets because that's the way we initialize block variables nowadays
let onPage, pageSize = 10;
$(document).ready(() => {
goToPage(1)
$('body').on('click', '#next_page, #prev_page', function() {
inc = 1;
if ($(this).attr('id') === 'prev_page') inc = -1;
goToPage(onPage + inc);
})
})
function goToPage(page) {
let requestIndex = $.ajax({
type: 'POST',
url: `url`,
beforeSend: function() {
$("#loading").show();
},
complete: function() {
$("#loading").hide();
}
});
requestIndex.done((data) => {
onPage = page;
$('#test>tbody').html('');
JSON.parse(data).forEach((result, index) => {
$('#test>tbody').append(`
<tr>
<td>${result.FirstName} ${result.LastName}</td>
<td>${result.ModelYear}</td>
<td>${result.Make}</td>
<td>${result.Model}</td>
<td>${result.Dealership}</td>
</tr>
`)
})
if (onPage > 1) $('#prev_page').removeAttr('disabled');
else $('#prev_page').attr('disabled', true)
if (JSON.parse(data).length === pageSize) $('#next_page').removeAttr('disabled');
else $('#next_page').attr('disabled', true)
});
requestIndex.fail(function(jqXHR, textStatus) {
console.log('failed')
});
}
#loading {
display: none'
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='loading'>Loading...</div>
<table id='test'>
<tbody></tbody>
</table>
<button id='prev_page'>Prev Page</button>
<button id='next_page'>Next Page</button>
So I'm using an AJAX request to load data from the database into a DIV. At the same time, I'm using the same data inside the DIV in a different script (Poptrox) witch does some design stuff.
Without the AJAX request, poptrox works, but if I'm using it together with poptrox it doesn't do the designing anymore.
Is there a way to reload the poptrox-script after the ajax request?
NOTE: the AJAX-Code and the Poptrox-code are placed inside the "main.js"!
Thanks in advance!
php:
<script src="assets/js/jquery.min.js"></script>
<section class="wrapper">
<form action="kochbuch.html" method="get" id="searchfilter">
<input type="text" class="searchBox" name="searchBox" id="searchBox" placeholder="Search..">
<button type="submit" id="searchBtn"><i class="fas fa-search"></i></button>
</form>
</section>
<section class="wrapper">
<div id="gerichte"></div>
</section>
<script src="assets/js/main.js"></script>
js-ajax:
var queryString = window.location.search;
var urlParams = new URLSearchParams(queryString);
if (urlParams.has('searchBox')){
var searchBox = urlParams.get('searchBox');
$.ajax({
type: "POST",
url: "kochbuch/fetchdata.php",
data: {
"search_post_btn": 1,
"searchBox": searchBox,
},
dataType: "json",
success: function (response) {
$("#gerichte").html(response);
}
});
};
js-poptrox:
// Gerichte.
var $gerichte = $('#gerichte');
// Thumbs.
$gerichte.children('.thumb').each(function() {
var $this = $(this),
$image = $this.find('.image'), $image_img = $image.children('img'),
x;
// No image? Bail.
if ($image.length == 0)
return;
// Image.
// This sets the background of the "image" <span> to the image pointed to by its child
// <img> (which is then hidden). Gives us way more flexibility.
// Set background.
$image.css('background-image', 'url(' + $image_img.attr('src') + ')');
// Set background position.
if (x = $image_img.data('position'))
$image.css('background-position', x);
// Hide original img.
$image_img.hide();
});
// Poptrox.
$gerichte.poptrox({
baseZIndex: 20000,
caption: function($a) {
var s = '';
$a.nextAll().each(function() {
s += this.outerHTML;
});
return s;
},
fadeSpeed: 300,
onPopupClose: function() { $body.removeClass('modal-active'); },
onPopupOpen: function() { $body.addClass('modal-active'); },
overlayOpacity: 0,
popupCloserText: '',
popupHeight: 150,
popupLoaderText: '',
popupSpeed: 300,
popupWidth: 150,
selector: '.thumb > a.image',
usePopupCaption: true,
usePopupCloser: true,
usePopupDefaultStyling: false,
usePopupForceClose: true,
usePopupLoader: true,
usePopupNav: true,
windowMargin: 50
});
// Hack: Set margins to 0 when 'xsmall' activates.
breakpoints.on('<=xsmall', function() {
$main[0]._poptrox.windowMargin = 0;
});
breakpoints.on('>xsmall', function() {
$main[0]._poptrox.windowMargin = 50;
});
alright, i found one possible solution, but know the preloaded data ist formated:
the whole poptrox code has to be wrapped by this function:
$(document).ajaxStop(function () {
// function after ajax
});
If you know any better solution, feel free to submit :)
EDIT:
alright, my solution was as follows:
if (urlParams.has('searchBox')){
var searchBox = urlParams.get('searchBox');
} else {
var searchBox = '';
}
$.ajax({ .....
I have several views that contain this same javascript.
<script type="text/javascript">
$(function () {
$("#addAnother").click(function () {
$.get('/QuestionGroup/QuestionEntryRow', function (template) {
$("#questionEditor").append(template);
});
});
});
</script>
I decided to move this logic to a javascript file. So here what I did.
On my view I added a data-attr.
<a method="get" action="#Url.Action("QuestionEntryRow", "QuestionGroup")" href="#">Add another</a>
In the javascript file I added the following code.
var insertRow = function () {
var $a = $(this);
var options = {
url: $a.attr("action"),
type: $a.attr("method")
};
$.ajax(options).done(function (data) {
var $target = $($a.attr("data-cban-target"));
$target.append(data);
});
return false
};
$("a[data-cban-a]").click(insertRow);
When the user click the link "Add another". The javascript is not getting executed.
Target
<ul data-cureurban-target="questionEditor" style="list-style-type: none">
</ul>
Here the controller logic
public ActionResult QuestionEntryRow()
{
ViewBag.QuestionID = new SelectList(db.Questions, "QuestionID", "QuestionDesc");
return PartialView("_QuestionEntryEditor");
}
Try the following for your .js file:
var insertRow = function () {
var $a = $(this);
var options = {
url: $a.attr("action"),
type: $a.attr("method")
};
$.ajax(options).done(function (data) {
var $target = $($a.attr("data-cban-target"));
$target.append(data);
});
return false
};
$(document).ready(){
$("a[data-cban-a]").click(insertRow);
}
Try adding javascript:void(0) in href of anchor tag.
<a method="get" action="#Url.Action("QuestionEntryRow", "QuestionGroup")" href="javascript:void(0)">Add another</a>
Refer this stackoverflow post for more details
Default event propogation for (a)anchor tag needs to be stopped.
<script type="text/javascript">
$(function () {
$("#addAnother").click(function (e) {
e.preventDefault();
$.get('/QuestionGroup/QuestionEntryRow', function (template) {
$("#questionEditor").append(template);
});
});
});
</script>
I'm trying to create a jQuery plugin, inside I need to do an AJAX call to load an xml.
jQuery.fn.imagetags = function(options) {
s = jQuery.extend({
height:null,
width:null,
url:false,
callback:null,
title:null,
}, options);
return this.each(function(){
obj = $(this);
//Initialising the placeholder
$holder = $('<div />')
.width(s.width).height(s.height)
.addClass('jimageholder')
.css({
position: 'relative',
});
obj.wrap($holder);
$.ajax({
type: "GET",
url: s.url,
dataType: "xml",
success:function(data){ initGrids(obj,data,s.callback,s.title); } ,
error: function(data) { alert("Error loading Grid data."); },
});
function initGrids(obj, data,callback,gridtitle){
if (!data) {
alert("Error loading Grid data");
}
$("gridlist gridset",data).each(function(){
var gridsetname = $(this).children("setname").text();
var gridsetcolor = "";
if ($(this).children("color").text() != "") {
gridsetcolor = $(this).children("color").text();
}
$(this).children("grid").each(function(){
var gridcolor = gridsetcolor;
//This colour will override colour set for the grid set
if ($(this).children("color").text() != "") {
gridcolor = $(this).children("color").text();
}
//addGrid(gridsetname,id,x,y,height,width)
addGrid(
obj,
gridsetname,
$(this).children("id").text(),
$(this).children("x").text(),
$(this).children("y").text(),
$(this).children("height").text(),
$(this).children("width").text(),
gridcolor,
gridtitle
);
});
});
}
function addGrid(obj,gridsetname,id,x,y,height,width,color,gridtitle){
//To compensate for the 2px border
height-=4;
width-=4;
$grid = $('<div />')
.addClass(gridsetname)
.attr("id",id)
.addClass('gridtag')
.imagetagsResetHighlight()
.css({
"bottom":y+"px",
"left":x+"px",
"height":height+"px",
"width":width+"px",
});
if(gridtitle != null){
$grid.attr("title",gridtitle);
}
if(color != ""){
$grid.css({
"border-color":color,
});
}
obj.after($grid);
}
});
}
The above plugin I bind with 2 DOM objects and loads two seperate XML files but the callback function is run only on the last DOM object using both loaded XML files.
How can I fix this, so that the callback is applied on the corresponding DOMs. Is the above ajax call is correct?
Sample usage:
<script type="text/javascript">
$(function(){
$(".romeo img").imagetags({
height:500,
width:497,
url: "sample-data.xml",
title: "Testing...",
callback:function(id){
console.log(id);
},
});
});
</script>
<div class="padding-10 min-item background-color-black">
<div class="romeo"><img src="images/samplecontent/test_500x497.gif" alt="Image"> </div>
</div>
<script type="text/javascript">
$(function(){
$(".romeo2 img").imagetags({
height:500,
width:497,
url: "sample-data2.xml",
title: "Testing...",
callback:function(id){
console.log(id);
},
});
});
</script>
<div class="padding-10 min-item background-color-black">
<div class="romeo2"><img src="images/samplecontent/test2_500x497.gif" alt="Image"> </div>
</div>
Here is the sample XML data:
<?xml version="1.0" encoding="utf-8"?>
<gridlist>
<gridset>
<setname>gridset4</setname>
<color>#00FF00</color>
<grid>
<color>#FF77FF</color>
<id>grid2-324</id>
<x>300</x>
<y>300</y>
<height>60</height>
<width>60</width>
</grid>
</gridset>
<gridset>
<setname>gridset3</setname>
<color>#00FF00</color>
<grid>
<color>#FF77FF</color>
<id>grid2-212</id>
<x>300</x>
<y>300</y>
<height>100</height>
<width>100</width>
</grid>
<grid>
<color>#FF77FF</color>
<id>grid2-1212</id>
<x>200</x>
<y>10</y>
<height>200</height>
<width>10</width>
</grid>
</gridset>
</gridlist>
You might be experiencing issues because your calling the ajax load on same url, thus the second call cancels the first call.
If you reading in the same url for each div, why don't you call the ajax once then loop the elements when it returns.
jQuery.fn.imagetags = function(options) {
s = jQuery.extend({
height:null,
width:null,
url:false,
callback:null,
title:null,
}, options);
var elems = $(this);
$.ajax({
type: "GET",
url: s.url,
dataType: "xml",
success:function(data){
elems.each(function() {
obj = $(this);
//Initialising the placeholder
$holder = $('<div />')
.width(s.width).height(s.height)
.addClass('jimageholder')
.css({
position: 'relative',
});
obj.wrap($holder);
initGrids(obj,data,s.callback,s.title);
});
},
error: function(data) { alert("Error loading Grid data."); }
});
return $(this);
}
Basically, what your doing here is calling the ajax function then instantly return the set. then, when the ajax callback gets fired, your looping the elements and appending the data.
This might be a scoping issue. You should use the 'var' statement when declaring variables inside functions. Otherwise, the variables go into the global scope.
var s = jQuery.extend({
height:null,
width:null,
url:false,
callback:null,
title:null,
}, options);
elems.each(function() {
var obj = $(this);
....
}
Since the variables are living in the global scope, they get overwritten by each iteration through the loop, and ultimately resulting in the the last DOM element.