Since changing to a new theme I have some probs including DataTables. jQuery is only called once and it is placed at the correct position, so basically everything correct.
I receive messages like
TypeError: $(...).DataTable is not a function
or
TypeError: $ is undefined
Beneath the DataTables I have a different JS with load() and with a similar problem. There I could fix it while putting this:
jQuery(document).ready(function($){
before this:
$("#tmp").load("tmp.htm")
I've read on some boards, that there could be an issue with the place-holder $. Anyway, the part above solves my problem. But back to the DataTables. I think it's the same problem, but I'm unable to understand the problem.
My Table starts with:
$(document).ready(function() {
var tabelle = $('#mytable').DataTable(
But with this before..
jQuery(document).ready(function($){
I do only get errors. Could somebody please help me?
++++++++ UPDATE ++++++++
<script type="text/javascript" language="javascript" class="init">
$.fn.dataTable.pipeline = function ( opts ) {
// Configuration options
var conf = $.extend( {
pages: 5, // number of pages to cache
url: '', // script url
data: null, // function or object with parameters to send to the server
// matching how `ajax.data` works in DataTables
method: 'GET' // Ajax HTTP method
}, opts );
// Private variables for storing the cache
var cacheLower = -1;
var cacheUpper = null;
var cacheLastRequest = null;
var cacheLastJson = null;
return function ( request, drawCallback, settings ) {
var ajax = false;
var requestStart = request.start;
var requestLength = request.length;
var requestEnd = requestStart + requestLength;
if ( settings.clearCache ) {
// API requested that the cache be cleared
ajax = true;
settings.clearCache = false;
}
else if ( cacheLower < 0 || requestStart < cacheLower || requestEnd > cacheUpper ) {
// outside cached data - need to make a request
ajax = true;
}
else if ( JSON.stringify( request.order ) !== JSON.stringify( cacheLastRequest.order ) ||
JSON.stringify( request.columns ) !== JSON.stringify( cacheLastRequest.columns ) ||
JSON.stringify( request.search ) !== JSON.stringify( cacheLastRequest.search )
) {
// properties changed (ordering, columns, searching)
ajax = true;
}
// Store the request for checking next time around
cacheLastRequest = $.extend( true, {}, request );
if ( ajax ) {
// Need data from the server
if ( requestStart < cacheLower ) {
requestStart = requestStart - (requestLength*(conf.pages-1));
if ( requestStart < 0 ) {
requestStart = 0;
}
}
cacheLower = requestStart;
cacheUpper = requestStart + (requestLength * conf.pages);
request.start = requestStart;
request.length = requestLength*conf.pages;
// Provide the same `data` options as DataTables.
if ( $.isFunction ( conf.data ) ) {
// As a function it is executed with the data object as an arg
// for manipulation. If an object is returned, it is used as the
// data object to submit
var d = conf.data( request );
if ( d ) {
$.extend( request, d );
}
}
else if ( $.isPlainObject( conf.data ) ) {
// As an object, the data given extends the default
$.extend( request, conf.data );
}
settings.jqXHR = $.ajax( {
"type": conf.method,
"url": conf.url,
"data": request,
"dataType": "json",
"cache": false,
"success": function ( json ) {
cacheLastJson = $.extend(true, {}, json);
if ( cacheLower != requestStart ) {
json.data.splice( 0, requestStart-cacheLower );
}
json.data.splice( requestLength, json.data.length );
drawCallback( json );
}
} );
}
else {
json = $.extend( true, {}, cacheLastJson );
json.draw = request.draw; // Update the echo for each response
json.data.splice( 0, requestStart-cacheLower );
json.data.splice( requestLength, json.data.length );
drawCallback(json);
}
}
};
$.fn.dataTable.Api.register( 'clearPipeline()', function () {
return this.iterator( 'table', function ( settings ) {
settings.clearCache = true;
} );
} );
$(document).ready(function() {
var tabelle = $('#mytable').DataTable(
{
"processing": true,
"serverSide": true,
"ajax": $.fn.dataTable.pipeline(
{
url: 'source.htm',
pages: 1
}
),
.....
}
);
} );
</script>
I had same problem and the code below solves the issue
jQuery(document).ready(function($){
This solves the problem. Adding the line below the initiating body-tag:
<script> $ = jQuery; </script>
Related
I am not sure so I decide to ask here. I have a plugin which uses jquery animate function and then it call complete callback. It works pretty much with dom. After few cycles script starts to be slow. I cant find any issue only local lambda variables. But I dont know why this local variables should remain in memory. It does not make sense. Here is the code:
cEl.el.animate( { left: offset.left - state.cEl.mL, top: offset.top - state.cEl.mT }, 250,
function() // complete callback
{
tidyCurrEl( cEl );
targetEl.after( cEl.el[0] );
targetEl[0].style.display = 'none';
hintStyle.display = 'none';
hintNode.remove();
......
if ( isHintTarget )
{
// This seems to be a problem.
var paretnLi = state.placeholderNode.parent().closest( 'li' )
......
}
else
{
......
}
} );
Am I right the local variables in anonymous function is the problem? Thanks.
Here is full code example
function endDrag( e )
{
var cEl = state.cEl,
hintNode = $( '#s-l-hint', state.rootEl.el ),
hintStyle = hint[0].style,
targetEl = null, // hintNode/placeholderNode
isHintTarget = false, // if cEl will be placed to the hintNode
hintWrapperNode = $( '#s-l-hint-wrapper' );
if ( hintStyle.display == 'block' && hintNode.length && state.isAllowed )
{
targetEl = hintNode;
isHintTarget = true;
}
else
{
targetEl = state.placeholderNode;
isHintTarget = false;
}
offset = targetEl.offset();
cEl.el.animate( { left: offset.left - state.cEl.mL, top: offset.top - state.cEl.mT }, 250,
function() // complete callback
{
tidyCurrEl( cEl );
targetEl.after( cEl.el[0] );
targetEl[0].style.display = 'none';
hintStyle.display = 'none';
// This has to be document node, not hint as a part of documentFragment.
hintNode.remove();
hintWrapperNode
.removeAttr( 'id' )
.removeClass( setting.hintWrapperClass );
if ( hintWrapperNode.length )
{
hintWrapperNode.prev( 'div' ).append( opener.clone( true ) );
}
var placeholderNode = state.placeholderNode;
// Directly removed placeholder looks bad. It jumps up if the hint is below.
if ( isHintTarget )
{
placeholderNode.slideUp( 150, function()
{
var placeholderParent = placeholderNode.parent();
var placeholderParentLi = ( ! placeholderParent.is( state.rootEl.el ) ) ? placeholderParent.closest( 'li' ) : null;
placeholderNode.remove();
tidyEmptyLists();
setting.onChange( cEl.el );
setting.complete( cEl.el ); // Have to be here cause is necessary to remove placeholder before complete call.
state.isDragged = false;
if( setting.maxLevels !== false ) // Has to be after placeholder remove.
{
recountLevels( cEl.el );
if( placeholderParentLi ) recountLevels( placeholderParentLi );
}
});
}
else
{
state.placeholderNode.remove();
tidyEmptyLists();
setting.complete( cEl.el );
state.isDragged = false;
}
} );
scrollStop( state );
state.doc
.unbind( "mousemove", dragging )
.unbind( "mouseup", endDrag );
}
NOTE:: I have replaced some code with comments to make it much shorter and more readable
I am working with Javascript (Ajax) and PHP (Laravel). I have run into a predicament! When calling an ajax function I have two listener to show a loading symbol while the ajax is processing, and then hide it again once it's done.
$( document ).ajaxStart( function() {
$( '#loading' ).css( 'display', 'block' );
} );
$( document ).ajaxStop( function() {
$( '#loading' ).css( 'display', '' );
} );
When you click on the submit button, the HTML onclick says to go to this function which is working just fine:
function submit( button ) {
var table = $( button ).closest( '.popup' ).find( 'table:first' );
var verified = verifyTable( table );
if ( verified == -1 ) {
return -1;
}
if ( table.hasClass( 'campaigns' ) ) {
campaign = table.find( '.campaign:first' );
submitNewCampaign( campaign );
} else if ( table.hasClass( 'groups' ) ) {
groups = table.find( 'tr.group' );
for ( var i = 0; i < groups.length; ++i ) {
submitNewGroup( groups.eq( i ) );
}
} else if ( table.hasClass( 'keywords' ) ) {
keywords = table.find( 'tr.keyword' );
for ( var i = 0; i < keywords.length; ++i ) {
submitNewKeyword( keywords.eq( i ) );
}
}
closePopup();
}
If from there you are sent to submitNewCampaign(), everything works just fine.
function submitNewCampaign( campaign ) {
// Set campaign variables
$.ajax({
url : '/ajax/addCampaign',
type : 'POST',
data : { // set campaign data },
success : function( result ) {
// get all groups in campaigns and loop through
for ( var i = 0; i < groups.length; ++i ) {
// set group variables
$.ajax({
url : '/ajax/addGroup',
type : 'POST',
async : false,
data : { // set group data },
success : function( result ) {
// get all keywords in group and loop
for ( var i = 0; i < keywords.length; i++ ) {
// set keyword variables
$.ajax({
url : '/ajax/addKeyword',
type : 'POST',
async : false,
data : { // set keyword data },
success : function( result ) { // done },
error : function( result ) {
alert( "error adding new keyword (name - " + keyword_name + ")");
console.log( result );
}
);
}
},
error : function( result ) {
alert( "error adding new group (name - " + group_name + ")" );
console.log( result );
}
});
}
},
error : function( result ) {
alert( "error adding new campaign (name - " + campaign_name + "): " + JSON.parse( xhr.responseText ) );
}
});
}
However if you are send to either submitNewGroup() or submitNewKeyword(), the loading image does not appear.
function submitNewGroup ( group ) {
// set group variables
$.ajax({
url : '/ajax/addGroup',
type : 'POST',
async : false,
data : { // set group data },
success : function( result ) {
// get all keywords in group and loop
for ( var i = 0; i < keywords.length; ++i ) {
// set all keyword variables
$.ajax({
url : '/ajax/addKeyword',
type : 'POST',
async : false,
data : { // set all keyword data },
success : function( result ) { // done },
error : function( result ) {
console.log( result );
}
});
}
},
error : function( result ) {
console.log( result );
}
});
}
function submitNewKeyword( keyword ) {
// set keyword variables
$.ajax({
url : '/ajax/addKeyword',
type : 'POST',
async : false,
data : { // set keyword data },
success : function( result ) { //done },
error : function( result ) {
console.log( result );
}
});
}
IMPORTANT: No errors appear in the log when any of the three functions are called. All three complete their assigned tasks with no issues.
I tried a few things and the one that made it work was: I removed async from the outer most ajax call for both group and keyword
When signupUser gets executed I am calling showSuccessMessage if signup is successful or showErrorMessage if signup fails. Now I do not know how to represent this in the parameter of signupUser. The way I am naming it now as showMessage it only executes showSuccessMessage even if my signup fails.
I am confused about general / concrete naming of parameters.
// GLOBAL ARRAY for storing any DATA from the SERVER
var ajDataFromServer = [];
// Main ajax function using callback for posting data to the server
function postAjax( sUrl , frmData, callback ){
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var ajDataFromServer = JSON.parse(this.responseText);
callback( ajDataFromServer, showMessage );
}
}
ajax.open( "POST", sUrl , true );
var jFrm = new FormData( frmData );
ajax.send( jFrm )
}
/************************************************************************/
/************************************************************************/
/************************************************************************/
// DO the SIGNUP, POST data to the SERVER with AJAX
btnSignupForm.addEventListener("click", function (e) {
postAjax( "api_signup_users.php", frmSignup, signupUser );
});
function signupUser( ajUserDataFromServer, showMessage ) {
if ( ajUserDataFromServer.status == "ok" ) {
//console.log( "SIGNUP SUCCESFULL" );
pageLogin.style.display = "flex";
pageSignup.style.display = "none";
showSuccessMessage( "Account succesfully created - Signup please" );
} else {
//console.log( "SIGNUP FAIL - TRY AGAIN" );
pageViewProducts.style.display = "none";
pageLogin.style.display = "none";
pageSignup.style.display = "flex";
showErrorMessage( "Signup Failed - Try again" );
}
}
/************************************************************************/
/************************************************************************/
/************************************************************************/
function showSuccessMessage ( sSuccessMessage ) {
var alblMessages = document.getElementsByClassName( "lblMessage" );
for ( var i = 0; i < alblMessages.length; i++ ) {
alblMessages[i].innerHTML = sSuccessMessage.fontcolor("#549839");
}
}
/************************************************************************/
/************************************************************************/
/************************************************************************/
function showErrorMessage (sErrorMessage) {
var alblMessages = document.getElementsByClassName( "lblMessage" );
for ( var i = 0; i < alblMessages.length; i++ ) {
alblMessages[i].innerHTML = sErrorMessage;
}
}
*Code rewritten
I'm trying to convert antirez's autocompleter to javascript to use it with node.js.
I can't pass the closure Problem. Maybe someone can help me out.
I see where the problems are but can't figure out how to solve them.
The while loop is firing, the break is not correct and won't work etc.
Code:
var acp = {
vars: {
dict : false,
count : false,
prefix : false,
rangeLen : 10,
start : false,
results : false,
range : false,
},
sendResults: function(){
console.log(acp.vars.results);
},
getzrank: function(){
redis.zrank( acp.vars.dict, acp.vars.prefix, function( err, start ){
acp.vars.start = start;
});
},
getzrange: function(){
redis.zrange( acp.vars.dict, acp.vars.start, parseFloat( acp.vars.start+acp.vars.rangeLen-1 ), function( err, range ){
acp.vars.range = range;
});
},
createAutocomplete: function(){
while( acp.vars.results.length != acp.vars.count ){
acp.getzrange();
acp.vars.start+=acp.vars.rangeLen;
if( ! acp.vars.range || acp.vars.range.length == 0 ) { break; }
for ( var i in acp.vars.range ){
var minLen = Math.min(i.length,acp.vars.prefix.length);
if( i.substr( 0, minLen ) != acp.vars.prefix.substr( 0, minLen ) ){
acp.vars.count = acp.vars.results.length;
}
if( i.substr( 0, i.length-1 ) == "*" && acp.vars.results.length != acp.vars.count) {
acp.vars.results.push( i.substr(0,-1) );
}
}
}
acp.sendResults();
},
init: function(dict,prefix,count){
acp.vars.range = false;
acp.vars.dict = dict;
acp.vars.prefix = prefix;
acp.vars.count = count;
acp.vars.results = [];
acp.vars.start = acp.getzrank();
if( ! acp.vars.start ){ acp.sendResults(); }
else{ acp.createAutocomplete(); }
}
}
The break statement is outside the scope of the while loop since its nested in the anonymous function. Not sure if that solves your problem.
Hi everyone I'm having an issue that I can't seem to wrap my head around. I'll try to keep this as brief as possible.
I'm attempting to set and get cookies in the background switcher I'm using. The switcher works well... It iterates through 7 background themes on click and the cookies seem to be working as well, but still on page refresh it reverts back to to the default "theme". I don't think it's a problem with the cookies because according to the alerts I attached to the cookies, it's returning the correct background (in the alert). It's just not loading the correct theme even though the cookie says it is.
I believe I narrowed it down to a bit of code in my javascript that might be responsible for the wrong background, however I don't know how to adjust it to make it do what I want.
The background (on refresh) will be whatever var current says it will be. Values of 0-6 will be a new background (on refresh) depending on what value it is. But it doesn't remember the user's selection on refresh. I've tried making var current into an array var current = [0,1,2,3,4,5,6],, but that didn't seem to help. When I did that it didn't show any of my 7 themes, and only showed the default color in body tag css.
When I tried the array, I changed this:
if( current < pagesCount - 1 ) {
++current;
alert($.cookie('style', current, { expires: 365, path: '/' }));
}
else {
current = 0;
}
to this:
for(var i = 0; i < current.length; i++){
if( current < pagesCount - 1 ) {
++current;
alert($.cookie('style', current, { expires: 365, path: '/' }));
}
else {
current = 0;
}
}
This is the click function, but I didn't change anything here
$iterate.on( 'click', function() {
if( isAnimating ) {
return false;
}
nextPage( animcursor);
++animcursor;
} );
I'm still pretty inexperienced with javascript so I'm sure there's a better way to do what I'm trying for. Any help would be appreciated! Thanks in advance.
The entire code block:
var changeTheme = (function() {
var $main = $( '#bg-main' ),
$pages = $main.children( 'div.bg-page' ),
$iterate = $( '#iterateEffects' ),
animcursor = 1,
pagesCount = $pages.length,
current = 0,
isAnimating = false,
endCurrPage = false,
endNextPage = false,
animEndEventNames = {
'WebkitAnimation' : 'webkitAnimationEnd',
'OAnimation' : 'oAnimationEnd',
'msAnimation' : 'MSAnimationEnd',
'animation' : 'animationend'
},
// animation end event name
animEndEventName = animEndEventNames[ Modernizr.prefixed( 'animation' ) ],
// support css animations
support = Modernizr.cssanimations;
function init() {
$pages.each( function() {
var $page = $( this );
$page.data( 'originalClassList', $page.attr( 'class' ) );
} );
$pages.eq( current ).addClass( 'bg-page-current' );
$iterate.on( 'click', function() {
if( isAnimating ) {
return false;
}
nextPage( animcursor);
++animcursor;
} );
}
function nextPage( animation ) {
if( isAnimating ) {
return false;
}
isAnimating = true;
var $currPage = $pages.eq( current );
if( current < pagesCount - 1 ) {
++current;
alert($.cookie('style', current, { expires: 365, path: '/' }));
}
else {
current = 0;
}
var $nextPage = $pages.eq( current ).addClass( 'bg-page-current' ),
outClass = '', inClass = '';
outClass = 'bg-page-scaleDown';
inClass = 'bg-page-scaleUpDown bg-page-delay300';
var classes = ['bg-page-0 bg-page-current','bg-page-1 bg-page-current', 'bg-page-2 bg-page-current', 'bg-page-3 bg-page-current', 'bg-page-4 bg-page-current', 'bg-page-5 bg-page-current', 'bg-page-6 bg-page-current'];
$currPage.addClass( outClass ).on( animEndEventName, function() {
$currPage.off( animEndEventName );
endCurrPage = true;
if( endNextPage ) {
onEndAnimation( $currPage, $nextPage );
}
} );
$nextPage.addClass( inClass ).on( animEndEventName, function() {
$nextPage.off( animEndEventName );
endNextPage = true;
if( endCurrPage ) {
onEndAnimation( $currPage, $nextPage );
}
} );
if( !support ) {
onEndAnimation( $currPage, $nextPage );
}
}
function onEndAnimation( $outpage, $inpage ) {
endCurrPage = false;
endNextPage = false;
resetPage( $outpage, $inpage );
isAnimating = false;
}
function resetPage( $outpage, $inpage ) {
$outpage.attr( 'class', $outpage.data( 'originalClassList' ) );
$inpage.attr( 'class', $inpage.data( 'originalClassList' ) + ' bg-page-current' );
}
//Cookies
window.onload = function(e) {
if($.cookie('style') == undefined) {
alert($.cookie('style', current, { expires: 365, path: '/' }));
current = 0;
} else {
current = current;
alert($.cookie('style'));
}
}
init();
return { init : init };
})();
If this hits the 'else' portion of the if statement, current is not defined on page load. I think you'd need do do something like
current = $.cookie('style');
Or is it always reporting as undefined on page load?
I'd just of made a comment, but lack of rep points prevents this.
//Cookies
window.onload = function(e) {
if($.cookie('style') == undefined) {
alert($.cookie('style', current, { expires: 365, path: '/' }));
current = 0;
} else {
current = current;
alert($.cookie('style'));
}
}