0

I hope you can help me... I want to do exactly, what nth Child asked four years ago in the following contribution jquery, how to run a function as soon as another function ends . I know this problem has been solved earlier. I found the solutions here, and after long sessions of finding out how to approach and now a huge stack of frustration, I can't help other than opening this topic again. So here ist what I would like to do:

Basically I want to define the behavior of content to be toggled in and / or out when clicking of elements (reference boxes). I have two functions:

1.function 'removeRefContent'

is meant for checking, whether content of other references, than the one clicked are opened, and if yes, close

function: 'appendRefContent2EndOfLine'

just adds content of the clicked reference box and displays it.

Here are the essential code snippets:

function displayRefContent ( clickedRefID ) {

// check, if element is opened already      
if ( $( 'div#' + clickedRefID + '_refAdditionalContent' ).length )) {
      removeRefContent();           
} else {

    // check whether other element is opened and close              
    removeRefContent().then( appendRefContent2EndOfLine ( clickedRefID ) ); 

}

}

// these two functions are behind

function appendRefContent2EndOfLine ( requestedRefID ) {

// get refContent from reference storage container

var refContent = '<div id="' + requestedRefID + '_refAdditionalContent" class="refAdditionalContent">';
    refContent = refContent + $( 'div#' + requestedRefID + '_additionalContentStorageContainer' ).html();
refContent = refContent + '</div>'; 

// find last refPreviewImage in elements row and store in variable lastElementInRowID           
var lastElementInRowID = 0;     //... some more code to find lastElementInRowID ...

// add refContent after last element in row and toggle in

$( 'div#' + lastElementInRowID + '_ref' ).after( refContent );  
$( 'div#' + requestedRefID + '_refAdditionalContent' ).slideToggle( 500 );

}

var removeRefContent = function () {

var removeRefContentDeferred = $.Deferred();

$( 'div.refAdditionalContent' ).slideToggle( 500 , function() {         
    $( 'div.refAdditionalContent' ).remove( function() {
        removeRefContentDeferred.resolve();
    });     
});     

return removeRefContentDeferred.promise();      

}

Both functions do what they are meant for. The issue occuers, when line

removeRefContent().then( appendRefContent2EndOfLine ( clickedRefID ) );

is requested. I want to first remove the content of all other references (by toggle out), and only when finished and $( 'div.refAdditionalContent' ).remove is done, the other function to appendRefContent2EndOfLine shall be executed.

I read lots of stuff about asynchronuous and queueing and sequences, but simply do not understand, why my solution does not work. The result is, that both functions are executed at the same time leading to conflicts.

So far i consider among many other solution approaches the one I've chosen as the most elegant one. But I am very open to learn about your ideas...

Thank you guys!

Cheers Frank

Community
  • 1
  • 1
  • I know this is a problem solved a hundred times... I really I think I understand. But now again after endless hours of troubleshooting no solution in sight, yet... Found several work-arounds, but don't want to apply. – Frank Müller Feb 07 '17 at 22:35

1 Answers1

0

Again, the updated code:

function to control show and hide element content:

function displayRefContent ( clickedRefID ) {           
    if ( $( 'div#' + clickedRefID + '_refAdditionalContent' ).length ) { // check, if element is opened already, if yes then close only         
        removeRefContent();         
    } else {                        
        if ( $( 'div.refAdditionalContent' ).length ) {      // check whether other element is opened and close first, before open another element                      
            removeRefContent().then( appendRefContent2EndOfLine ( clickedRefID ) );                     
        } else {            
            appendRefContent2EndOfLine ( clickedRefID ); // if no other content element is opened, only open element                
        }           
    }               
}   

and the two functions to AT FIRST fade out and remove object and AFTERWARDS append and fade in new object

var removeRefContent = function () {            
    var defRemoveContent = $.Deferred();        
    $( 'div.refAdditionalContent' ).slideToggle( 500 , function()       
        $( 'div.refAdditionalContent' ).remove();
        defRemoveContent.resolve();
    });                             
    return defRemoveContent.promise();      
}

function appendRefContent2EndOfLine ( requestedRefID ) {            

    // get refContent from reference storage container (could be more elegant, but not relevant here)
    var refContent = '<div id="' + requestedRefID + '_refAdditionalContent" class="refAdditionalContent">';
        refContent = refContent + $( 'div#' + requestedRefID + '_additionalContentStorageContainer' ).html();
    refContent = refContent + '</div>'; 

    var lastElementInRowID = ...;    // some code to find last refPreviewImage in elements row and store in variable lastElementInRowID 

    // add refContent after last element in row and toggle in       
    $( 'div#' + lastElementInRowID + '_ref' ).after( refContent );  
    $( 'div#' + requestedRefID + '_refAdditionalContent' ).slideToggle( 500 );      

}

The problem is in the case of displayRefContent, in which there is already content open, which needs to be closed at first and then afterwards open the new content. It does it at the same time, so I cannot influence the order and the timing (function appendRefContent2EndOfLine after function removeRefContent is finished).

Feel like the most bloody beginner in the world, frustrated and with no more idea left to follow. Checked also, if funcitionality is impacted by other things, for example document not completely loaded of the fact, that the content is loaded after document.ready(). Don't see any impact.

Thank you, hope somebody is willing to help Frank