*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.
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 );
}
I am trying to use while loop in Angular.
If I use alert in while loop, it give same quantity output. but I remove alert, the quantity is different. So what is wrong in my code.
var quantity= $scope.quantity;
var i=0;
while(i< quantity)
{
order.createOrderLineItem( localStorage.getItem( "orderID" ), itemStr, undefined, $scope.errorCallback )
.success(function(data){
$scope.lineItemID = data.id;
alert("i:"+i);
var orderLineItemData = {};
if( $scope.cusNote == "" )
{
var existedNote = data.note || "";
orderLineItemData = {
"unitQty": $scope.quantity,
"note": existedNote,
};
//if adding taxRates 0, clover will returns error
if($scope.taxRates !== 0) {
orderLineItemData.taxRates = $scope.taxRates;
}
}
else
{
var customerNote = "";
if( data.note != undefined && data.note != null ) customerNote = data.note;
customerNote = customerNote + "#order-request-[";
customerNote = customerNote + $scope.cusNote;
customerNote = customerNote + "]";
customerNote = customerNote.replace(/\\/g, '\\\\');
customerNote = customerNote.replace(/\"/g, '\\"');
console.log( "customerNote:" + customerNote );
orderLineItemData = {
"unitQty":$scope.quantity,
"note": customerNote,
"taxRates": $scope.taxRates
}
}
order.updateOrderLineItem( localStorage.getItem( "orderID" ), $scope.lineItemID, JSON.stringify(orderLineItemData), undefined, $scope.errorCallback )
.success( function( data ){
if( $scope.modCount == 0 )
{
location.href = "/" + $routeParams.slug;
}
$scope.addModifierItem( $scope.lineItemID );
});
});
i++;
}
So how can I correct this code?
I am not sure but, alert may be the reason of that. Can you try to use console.log("i:"+i); instead of the alert. Browser may interrupt when you use alert because of the pop up.
--Edited--
this is the service that you will need to implement into your application. You will need to notify this service at your success and it will trigger any observe that is implemented after the notify
app.service('checkService',['$q',function($q){
var checkRequest = $q.defer();
this.notifyRequestIsDone= function(){
checkRequest .notify();
};
this.observeRequestStatus = function(){
return checkRequest .promise;
};
}]);
Here is observe example of the code above add this to your controller where you need to increase your value after the request is done
checkService.observeRequestStatus ().then(null,null,function(){
//... Your code
});
I am using infinite scroll to load posts and tried to integrate a custom like button for every single posts that needs a small jquery script to work. My problem is I added this Jquery directly after the sucess in ajax load posts. But when I load eg the 3. page my jquery script executes twice and on the posts of the 2nd page the lke buttons are not working correctly. How can I handle this? If I dont execute the code after the ajax request and only call this jquery code globally the like buttons do not work in the new loaded posts of the ajax infinite scroll. Maybe I need to stop the sript of before when eg loadin 3. page through the ajax infinite scroll but how? This is my code:
function load_more_posts(selector){
var url = $(selector).attr('href');
var data;
loading = true;
$.ajax({
url: url,
data: data,
success: function( data ) {
var $items = $( '.loading-content .item', data );
$new_anchor = $( selector, data );
$items.addClass('hidden');
if ( $('#cooked-plugin-page .result-section.masonry-layout .loading-content').length ){
$( '.loading-content').isotope( 'insert', $items );
} else {
$( '.loading-content').append($items);
setTimeout(function() {
$items.removeClass('hidden');
}, 200);
}
if($new_anchor.length) {
$(selector).attr('href', $new_anchor.attr('href'));
} else {
$(selector).remove();
}
loading = false;
$('.like-btn').each(function() {
var $button = $(this),
$icon = $button.find('> i'),
likedRecipes = $.cookie('cpLikedRecipes'),
recipeID = $button.attr('data-recipe-id');
cookied = $button.attr('data-cookied');
userLiked = $button.attr('data-userliked');
if ( cookied == 1 && typeof likedRecipes !== 'undefined' && likedRecipes.split(',').indexOf(recipeID) > -1 || userLiked == 1 ) {
$icon.removeClass('fa-heart-o').addClass('fa-heart');
}
});
$('#cooked-plugin-page .like-btn').on('click', function() {
var $button = $(this),
$icon = $button.find('> i'),
$count = $button.find('.like-count'),
count = parseInt($count.text()),
likedRecipes = $.cookie('cpLikedRecipes'),
recipeID = $button.attr('data-recipe-id'),
cookied = $button.attr('data-cookied'),
likeURL = $button.attr('href'),
likeAction;
if ( $icon.hasClass('fa-heart-o') ) {
$icon.removeClass('fa-heart-o').addClass('fa-heart');
count++;
if (cookied == 1){
if ( typeof likedRecipes === 'undefined' ) {
likedRecipes = recipeID;
} else {
likedRecipes = likedRecipes + ',' + recipeID;
}
$.cookie('cpLikedRecipes', likedRecipes, { expires: 365 } );
}
likeAction = 'like';
} else {
$icon.removeClass('fa-heart').addClass('fa-heart-o');
count--;
if (cookied == 1){
if ( typeof likedRecipes === 'undefied' ) {
return false;
}
}
if (cookied == 1){
var likedSplit = likedRecipes.split(','),
recipeIdx = likedSplit.indexOf(recipeID);
if ( recipeIdx > -1 ) {
likedSplit.splice( recipeIdx, 1 );
likedRecipes = likedSplit.join(',');
$.cookie('cpLikedRecipes', likedRecipes, { expires: 365 } );
likeAction = 'dislike';
}
} else {
likeAction = 'dislike';
}
}
$.ajax({
'url' : likeURL,
'data': {
'action' : 'cp_like',
'likeAction': likeAction
},
success: function(data) {
$count.text(data);
}
});
return false;
});
$('#cooked-plugin-page .tab-links a').on('click', function() {
var tab = $(this).attr('href');
if ( !$(this).is('.current') ){
$(this).addClass('current').siblings('.current').removeClass('current');
$('#cooked-plugin-page.fullscreen .tab').removeClass('current');
$(tab).addClass('current');
$win.scrollTop(0);
}
return false;
});
if($('.rating-holder').length) {
$('.rating-holder .rate')
.on('mouseenter', function() {
var $me = $(this);
var $parent = $me.parents('.rating-holder');
var my_index = $me.index();
var rated = $parent.attr('data-rated');
$parent.removeClass(function(index, css) {
return (css.match (/(^|\s)rate-\S+/g) || []).join(' ');
});
$parent.addClass('rate-' + (my_index + 1));
})
.on('mouseleave', function() {
var $me = $(this);
var $parent = $me.parents('.rating-holder');
var my_index = $me.index();
var rated = $parent.attr('data-rated');
$parent.removeClass(function(index, css) {
return (css.match (/(^|\s)rate-\S+/g) || []).join(' ');
});
if(rated !== undefined) {
$parent.addClass('rate-' + rated);
}
})
.on('click', function() {
var $me = $(this);
var $parent = $me.parents('.rating-holder');
var my_index = $me.index();
$('.rating-real-value').val(my_index + 1);
$parent.attr('data-rated', my_index + 1);
$parent.addClass('rate-' + (my_index + 1));
});
}
setTimeout(function() {
masonry();
}, 500);
}
});
}
There's a great plugin for scrolling. He has methods such as bund, unbind, destroy and e.t.c.:
https://github.com/infinite-scroll/infinite-scroll#methods
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'));
}
}
i'm using the FileTree jquery plugin from http://labs.abeautifulsite.net/projects/js/jquery/fileTree/demo/
i'm trying to fix one bug
i lost all day trying different thing but i'm a beginner at javascript and i had no luck
i modified the code a bit but the problem is the same even with the original code
to see the bug go to the link above
from the first example select "documents" then "excel docs" then "documents" again
the li element containing "excel docs" has the class "expanded" even if the parent "documents" is closed
how can i remove the class from all children when a parent is closed ?
this is my last version of the code
if(jQuery) (function($){
$.extend($.fn, {
fileTree: function(o, h, dire) {
// Defaults
if( !o ) var o = {};
if( o.root == undefined ) o.root = '/';
if( o.script == undefined ) o.script = 'jqueryFileTree.php';
if( o.folderEvent == undefined ) o.folderEvent = 'click';
if( o.expandSpeed == undefined ) o.expandSpeed= 500;
if( o.collapseSpeed == undefined ) o.collapseSpeed= 500;
if( o.expandEasing == undefined ) o.expandEasing = null;
if( o.collapseEasing == undefined ) o.collapseEasing = null;
if( o.multiFolder == undefined ) o.multiFolder = true;
if( o.loadMessage == undefined ) o.loadMessage = 'Loading...';
if(o.expanded == undefined) o.expanded = '';
$(this).each( function() {
function showTree(c, t) {
$(c).addClass('wait');
$(".jqueryFileTree.start").remove();
$.post(o.script, { dir: t }, function(data) {
$(c).find('.start').html('');
$(c).removeClass('wait').append(data);
if( o.root == t ) $(c).find('UL:hidden').show(); else $(c).find('UL:hidden').slideDown({ duration: o.expandSpeed, easing: o.expandEasing });
bindTree(c);
if (o.expanded != null) {
$(c).find('.directory.collapsed').each(function (i, f) {
if ((o.expanded).match($(f).children().attr('rel'))) {
showTree($(f), escape($(f).children().attr('rel').match(/.*\//)));
$(f).removeClass('collapsed').addClass('expanded');
};
});
};
},"html");
};
function bindTree(t) {
$(t).find('LI A').bind(o.folderEvent, function() {
if( $(this).parent().hasClass('directory') ) {
if( $(this).parent().hasClass('collapsed') ) {
// Expand
dire($(this).attr('rel'));
if( !o.multiFolder ) {
$(this).parent().parent().find('UL').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing });
$(this).parent().parent().find('LI.directory').removeClass('expanded').addClass('collapsed');
}
$(this).parent().find('UL').remove(); // cleanup
showTree( $(this).parent(), escape($(this).attr('rel').match( /.*\// )) );
$(this).parent().removeClass('collapsed').addClass('expanded');
} else {
// Collapse
$(this).parent().find('UL').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing });
$(this).parent().removeClass('expanded').addClass('collapsed');
}
} else {
h($(this).attr('rel'));
}
return false;
});
if( o.folderEvent.toLowerCase != 'click' ) $(t).find('LI A').bind('click', function() { return false; });
}
$(this).html('<ul class="jqueryFileTree start"><li class="wait">' + o.loadMessage + '<li></ul>');
showTree( $(this), escape(o.root) );
});
}
});
})(jQuery);