I am using this and have a datatable in my page.
I am receiving values from another site pages, and according to them I should redraw table.
I am receiving BookNo value, and when table is loaded, I should open page where this BookNo is placed. (If it is placed on page 2 or 3, I should open those page).
I found this and tried to use it:
var dtApi = new $.fn.dataTable.Api("#Book_grid");
dtApi.page.jumpToData(selectedBookNo, 1);
but, this has falled with TypeError: dtApi.page.jumpToData is not a function. What am I doing wrong?
EDIT:
Added:
jQuery.fn.dataTable.Api.register('page.jumpToData()', function (data, column) {
var pos = this.column(column, { order: 'current' }).data().indexOf(data);
if (pos >= 0) {
var page = Math.floor(pos / this.page.info().length);
this.page(page).draw(false);
}
return this;
});
This was missed. Now I don't have any exceptions, but this does't do a thing at all.
When script goes to setting var pos, I am receiving -1 no matter what, which means, I simply cant receive data? How can I deal with it?
Judging by the code example on the page you linked to, your code should be:
var dtApi = $("#Book_grid").DataTable();
dtApi.page.jumpToData(selectedBookNo, 1);
Related
I have a date input in my page, which I'm using Daterangepicker framework to populate it.
Here is the code of how I start my page!
$(function(){
startSelectors();
var variaveis = returnInputVars();
var rede = variaveis[0];
var codLoja = variaveis[1];
var period = variaveis[2];
console.log('1.'+rede+' 2.'+codLoja+' 3.'+period);
});
function returnInputVars(){
var rede = $("#dropdown-parceria").val();
var codLoja = $("#dropdown-loja").val();
var periodo = $("#datepicker-range").val();
return [rede, codLoja, periodo];
};
The function startSelectors() is set to start my datepicker and other fields, which is working perfectly. After it, I create a var called "variaveis" to fill
with the values of each field because I will use then later (this functions also works perfectly at other scripts of my page).
Running the page, my console returns this:
The funny thing is, if I type at the console this, the value is shown, just while starting the script is does not work!
Anybody experienced something like this?
***UPDATE
Adding this script to my start function:
console.log($("#datepicker-range"));
The value is shown, but the second console.log don't:
EDIT 1. FIDDLE (Suggested by #halleron)
To ensure things are loaded in the correct order, it is useful to apply a page sniffer code snippet that will scan the page continuously until a condition is met, or until a preset counter limit is reached (to prevent strain on browser memory). Below is an example of what I typically use that would fit your scenario.
I think because you are dealing with asynchronous loading, you can't have a global variable that holds the values in a global scope without an interval to detect when it can be used. Otherwise, it will attempt to read the variable when it is not yet ready.
You can invoke functions anywhere you like. But I would keep all of your variables contained within the page_sniffer_2017() because that is a controlled environment where you know that everything successfully loaded and you know that the variables are ready to be accessed without error.
That way, regardless of connection speed, your functions will only fire when ready and your code will flow, sequentially, in the right order.
Within the ajax success options, always add a class to the body of the document that you can search on to determine if it has finished loading.
$(document).ready(function() {
page_sniffer_2017();
});
function page_sniffer_2017() {
var counter = 0;
var imgScanner = setInterval(function() {
if ($("#datepicker-range").length > 0 && $("#datepicker-range").val().length && jQuery('body').hasClass('date-picker-successfully-generated')) {
var periodoDatepicker = $("#datepicker-range").val(); // ok
console.log(periodoDatepicker); // ok
var variaveis = returnInputVars(replaceDate(periodoDatepicker)); // ok
console.log(variaveis[0], variaveis[1], variaveis[2]);
//startNewSelectors(variaveis);
// start ajax call
generateData(variaveis[0], variaveis[1], variaveis[2]);
clearInterval(imgScanner);
} else {
//var doNothing = "";
counter++;
if (counter === 100) {
console.log(counter);
clearInterval(imgScanner);
}
}
}, 50);
}
i'm putting together a personal website as a portfolio and i'm having trouble getting a photo gallery to work. I found a free Javascript gallery (http://ettrics.com/lab/demo/material-photo-gallery/) that I decided to implement. When putting the page together locally, the javascript runs no problem, however when I upload the page to the site (which already has plenty of other javascript running) I get the following error when scrolling on the page, or when trying to 'fullscreen' one of the images by clicking on it:
TypeError: this._fullImgs is undefined
I tried to isolate the issue and found that a line of code was executing differently on the server, than locally, the excerpt is below:
Gallery.prototype._loadFullImgsDone = function() {
var imgLoad = imagesLoaded(this._fullBox);
imgLoad.on('done', function(instance) {
var imgArr = instance.images;
this._fullImgs = [];
this._fullImgDimensions = [];
this._fullImgsTransforms = [];
for (var i = 0, ii = imgArr.length; i < ii; i++) {
var rect = imgArr[i].img.getBoundingClientRect();
this._fullImgs.push(imgArr[i].img);
this._positionFullImgs.call(this, imgArr[i].img, i);
this._fullImgDimensions.push(rect);
}
this._fullImgsLoaded = true;
}.bind(this));
};
I have found that the images are being found from their source location, however
imgLoad.on('done', function(instance) {
...
executes differently. The site is located at http://http://samueller.tech/photo-best.html id anybody would like to see for themselves the error I am getting.
Thanks in advance, i'm at a complete loss of how to fix this.
I'm seeing (on that site) the resizeHandler is getting called before the images are loaded
Gallery.prototype._handleScroll = debounce(function() {
this._resetFullImg.call(this);
}, 25);
Gallery.prototype._handleResize = function() {
this._resetFullImg.call(this);
};
Then this._resetFullImg fails because there are no images loaded yet which is why this._fullImgs is empty. The code seems to have another variable called _fullImgsLoaded and probably the _resetFullImg method should do nothing if images haven't been loaded.
You could try adding that like this:
// in material-photo-gallery.js line 1379
Gallery.prototype._resetFullImg = function() {
if (!this._fullImagesLoaded) {
return
}
this._fullImgsTransforms = [];
for (var i = 0, ii = this._fullImgs.length; i < ii; i++) {
...
I don't know how this will affect the reset of the gallery code, but it might work. It makes some sense that on your production system, the page load time (with extra JS and stuff) is such that these events might get called before things are ready which is something you don't see locally.
good luck.
I am using DataTables.
What I am trying to do is: by using one of the columns values, get page number, where this value is located.
I have tried this: jumpToData()
BUT this didn't work out. The reason is that
var pos = this.column(column, { order: 'current' }).data().indexOf(data);
in jQuery.fn.dataTable.Api.register('page.jumpToData()' returns value >=0 ONLY if I was placed on page where value was.
For example, I want to detect page where needed value is, but I am staying on another page, so to detect value on... page 3, I need to go to this page and only then I can detect it, which makes no sence at all.
What I need to do, is: by staying on pirst page, using value from another pages, detect those pages numbers and then navigate to them:
$('#Grid_grid').DataTable().page(PageNumber).draw(false);
How can I accomplish that?
EDIT:
Got some idea (several changes in jumpToData()):
jQuery.fn.dataTable.Api.register('page.jumpToData()', function (data, column) {
for (var i = 0; i < this.page.info().pages; i++) {
var test = this.page(i).column(column, { order: 'current' }).data().indexOf(data);
if (test >= 0) {
this.page(i).draw(false);
return this;
}
}
return this;
});
(EDIT 2: idea didn't paid off, no difference)
BUT now I got second issue:
None methods of datatable works in .cshtml page.
For example I need to get overall page count. I doing this:
$('#Grid_grid').DataTable().page.info().pages;
and this return me 0;
Meanwhile, putting it in to console (Chrome F12) works fine (returns 5). Whats the matter?
EDIT 3:
Came up with this:
function LoadPage(value) {
var table = $('#Grid_grid').DataTable();
var pageNumber = table.search(value).page();
table.page(pageNumber).draw(false);
}
Looks promising BUT, I still cant validate it because in console DataTable methods are working, but in .cshtml no. (search() or page() returns nothing).
EDIT 4:
Moved issue to another question
CAUSE
Your new API method page.jumpToData() tries to query all pages data because second argument selector-modifier in column() API method has property page: 'all' by default. As written it will always stay on first page.
SOLUTION
There is original page.jumpToData() plug-in posted by Allan Jardine, creator of DataTables. It works as intended and can be used instead of your modification to avoid unnecessary iterations.
$.fn.dataTable.Api.register('page.jumpToData()', function (data, column) {
var pos = this.column(column, {
order: 'current'
}).data().indexOf(data);
if (pos >= 0) {
var page = Math.floor(pos / this.page.info().length);
this.page(page).draw(false);
}
return this;
});
DEMO
See this jsFiddle for code and demonstration.
NOTES
In the demo above I added console.log("Number of pages", table.page.info().pages); just to demonstrate that API method works. However they may work because I have HTML-sourced data.
If you have Ajax-sourced data, you need to query number of pages only when data has been loaded. Use initComplete option to define a callback function that will be called when your table has fully been initialised, data loaded and drawn.
Not on Chrome, but on Firefox the browser just get freeze every time I make an ajax request.
Here's the deal...
The ajax request receive a huge html, where the length is more than 75,000.
<div> ... <table> ... etc ... </table> ... </div>
So I start to use replace to get something better:
var html = data.replace(/\r?\n|\r/g, '').replace(/\s{2,}/g, ' ')
Than I got 55,000 that is not enough.
So I've been searching but until now I got nothing that can help.
Here's what I tried:
1.
asyncInnerHTML(html, function(fragment){
$(tab).get(0).appendChild(fragment); // myTarget should be an element node.
});
2.
var node = document.createTextNode(html);
$(tab).get(0).innerHTML = node;
3.
$(tab).get(0).innerHTML = html;
4.
$(tab).append(html);
5.
$(tab).html(html);
The only thing that was fast what the second one, where the javascript add the nodeContent, of course that was not what I want, because I need the HTML rendered and not the html in text/string form.
I hope that someone could help me.
Anyway, thanks.
Here's a piece of code that parses out the rows from your table HTML and then adds them one at a time to give the browser more time to breathe while parsing your HTML. This parsing logic is specific to your HTML and makes some assumptions about that HTML:
function addLargeHTML(parent, h) {
var d = document.createElement("div");
var pieces = extractRows(html);
d.innerHTML = pieces.core;
var tbody = $(d).find("tbody");
$(parent).append(d);
var cntr = 0;
function next() {
if (cntr < pieces.rows.length) {
tbody.append(pieces.rows[cntr]);
++cntr;
setTimeout(next, 1);
}
}
next();
}
function extractRows(h) {
var body;
var h = h.replace(/<tbody>(.*?)<\/tbody>/, function(match, p1) {
body = p1;
return "<tbody></tbody>";
});
var rows = body.match(/<tr.*?<\/tr>/g);
return {core: h, rows: rows};
}
You can see it working in this jsFiddle (select the "Add Row by Row" button): http://jsfiddle.net/jfriend00/z7jn4p12/.
Since I could not reproduce your original problem in Firefox, I can't really say whether this would fix what you saw or not. But, it does break the HTML up into smaller pieces so if that was really the problem, this should help.
The Skype Toolbar for Firefox is an extension that detects phone numbers in web pages, and re-renders them as a clickable button that can be used to dial the number using the Skype desktop application.
So, when the HTML is rendered, the skype extension try to find shit at my code making the browser stop work for a moment.
Thanks for all help.
I'm trying to use infinite-scroll to lazy load images. I'm getting the following error when it's called though:
TypeError: undefined is not a function
at handler (http://onfilm.us/ng-infinite-scroll.js:31:34)
Here's a very watered down look of what I have thus far.
function tagsController($scope) {
$scope.handleClick = function(tags) {
// Parse Tags
$scope.finished_tags = parsed_data;
};
$scope.$emit( 'handleEmit', { tags = $scope.finished_tags; });
};
function imagesController($scope,$http) {
var rows_per = 5;
$scope.$on('handleBroadcast', function(event, args) {
// Sort the images here, put them in matrix
// Example: matrix[row_number] = { picture1, picture2, picture3 }
$scope.data = matrix;
$scope.loadMore();
};
$scope.loadMore() = function() {
var last = $scope.images.length;
for ( var i = 0; i < rows_per; i++ ) {
$scope.images[last + i] = new Array();
$scope.images[last + i] = $scope.data[last + i].slice( 0 );
}
}
}
The rough idea is that the page loads the first time (w/ no tags) and get images from a PHP script. All of them. They are stored, and loadMore() is called which will populate $scope.images with 5 rows of images. It does, and they are loaded.
The line in that script is accessing $window.height and $window.scrollup. I'm still pretty green w/ Javascript, so feel free to lambast me if I'm doing something horribly wrong.
This is the broken version I'm testing with:
http://onfilm.us/test.html
Here is a version before the lazy loading was implemented, if seeing how the tags work will help. I don't think that's the issue here though.
http://onfilm.us/image_index.html
EDIT: I do think this is a problem w/ the ng-infinite-scroll.js script. The error is on line 31 (of version 1.0.0). It's telling me:
TypeError: undefined is not a function
It doesn't like $window apparently.
My JS Kung Fu is not really equipped to say why. YOu can see a literal copy/paste job from the simple demo here (with the error) onfilm.us/scroll2.html
By refering your site, It appears at first instance that your HTML-markup is not appropriate. You should move infinite-scroll to the parent of ng-repeat directive so that it will not make overlapping calls for each row generated. Please visit http://binarymuse.github.io/ngInfiniteScroll/demo_basic.html