7

I am using this plugin for fly-out menus: http://www.filamentgroup.com/lab/jquery_ipod_style_and_flyout_menus/

The button is inside a div like that:

<div class="stuff">
some stuff
<a class="quickfire">menu</a>
</div>

I am applying it to some link like so:

jQuery('.quickfire').menu({ 
        content: jQuery('#search-engines').html(), // grab content from this page
        showSpeed: 400 
    });

Where .quickfire is the class name of the link. So far so good, works.

However the user can also trigger an AJAX call, which will fetch a bunch of HTML from the server and replace the div "stuff" with new content (which itself will contain a quickfire link).

jQuery.ajax({
            url: 'ajax_file.php',
            data: {
                action: 'create_option_new_version', 
                id: jQuery('#qid').val(),
                div: jQuery("#addMoreOptions").parent().parent().attr('id'),
                cleanOutput: true
            },
            success: function(data, textStatus, jqXHR){                                
                jQuery(".stuff").html(data);


            }
        });

As expected, the quickfire link is no longer attached to the jQuery Menu. So, i'm linking it again every time:

jQuery.ajax({
            url: 'ajax_file.php',
            data: {
                action: 'create_option_new_version', 
                id: jQuery('#qid').val(),
                div: jQuery("#addMoreOptions").parent().parent().attr('id'),
                cleanOutput: true
            },
            success: function(data, textStatus, jqXHR){                                
                jQuery(".stuff").html(data);

                var position = jQuery('.quickfire').position();
                console.log("left: " + position.left + " top: " + position.top);


                jQuery('.quickfire').menu({ 
                    content: jQuery('#search-engines').html(), // grab content from this page
                    showSpeed: 400
                });


            }
        });

Almost there!

The issue is that, when I click on the newly created quickfire button, it works, but the menu appears at the top left corner of my screen, instead of next to the button!

I tried to print out the "position" of the quickfire button. For the initial load one, it said 361 x 527. For the subsequent ones, they all say 0 x 320

Here is the real code:

jQuery("#addMoreOptions").live('click',function(){
        jQuery(".lastPollOptionInput").removeClass("lastPollOptionInput");

        jQuery.ajax({
            url: 'ajax_file.php',
            data: {
                action: 'create_option_new_version', 
                id: jQuery('#qid').val(),
                div: jQuery("#addMoreOptions").parent().parent().attr('id'),
                cleanOutput: true
            },
            success: function(data, textStatus, jqXHR){                                
                jQuery("#addMoreOptions").parent().parent().html(data);

                jQuery('.quickfire').fgmenu({ 
                    content: jQuery('#search-engines').html(), // grab content from this page
                    showSpeed: 400
                });


            }
        });


    });
Nathan H
  • 48,033
  • 60
  • 165
  • 247
  • I tried to "detach" the quickfire button right before replacing the content, then re-insert it. Now it doesn't put the menu on the top left, instead it puts the menu exactly where it was before I did the ajax call (which I guess makes sense). Not exactly the correct location, but at least a lot closer geographically – Nathan H Sep 08 '11 at 15:53
  • Can you link to the page where you are seeing this problem? A rudimentary test on jsfiddle (http://jsfiddle.net/6VrgD/3/) suggests there might something wrong elsewhere in your code... – Chris Sep 12 '11 at 13:16
  • Unfortunately no, it lives on my computer and the client doesn't want me to share much. But I added some code. – Nathan H Sep 12 '11 at 13:26
  • I managed to work around by calling "remove" on quickfire, then re-inserting it manually writing jquery code. – Nathan H Sep 12 '11 at 14:36
  • 1
    Can you work with `.delegate()` or `.live()` to avoid having to rebind the newly created `.quickfire`? – Matijs Sep 18 '11 at 19:32
  • +1 to Matijs' comment, but please only use .delegate()...never use .live() http://stackoverflow.com/questions/4579117/jquery-live-vs-delegate – brandwaffle Dec 22 '11 at 00:49
  • Total stab in the dark here, but can you check the CSS on the element in the inspector and see if it's maybe being changed from position: absolute to position: relative or something like that when it gets removed and re-added? – brandwaffle Dec 22 '11 at 00:50

3 Answers3

1

I would go the easy way. Just get the position of the element before the AJAX call:

var x = $('#old-div').offset().left;
var y = $('#old-div').offset().top;

After the AJAX call apply the position to the new element:

$('#new-div').css({ "left" : x, "top" : y });

Also, I didn't understand if the menu is position: absolute, or whatever. Check for that as well. Hope I was useful, cheers and good luck!

Nikolay Dyankov
  • 6,491
  • 11
  • 58
  • 79
0

Could it be that you're using fgmenu() instead of just menu()? (Update: You said you renamed the function from menu to fgmenu yourself, so it's possible that it's calling $.fn.menu -- in other words, the conflicting jQuery UI function -- internally in places...)

Check the console for errors, just in case there's anything obvious in there.

My next guess would be that jQuery("#addMoreOptions").parent().parent() might not be the element you expect it to be, and could in fact be the <html> element or some other similarly unexpected node.

The other thing is that because you're calling $(something).parent().html("blah") means that you're replacing the $(something) node, which may not exist on subsequent calls.

If there's a better way to locate and keep a reference to the intended node, I would suggest doing that instead.

Chris
  • 9,994
  • 3
  • 29
  • 31
  • No that's on purpose, I renamed menu to fgmenu because it conflicted with jquery-ui "autocomplete" – Nathan H Sep 12 '11 at 13:46
  • Without being able to see a working example that demonstrates the problem, I'm afraid I've not got any fresh ideas on what might be the problem :\ – Chris Sep 12 '11 at 13:49
0

If the element is being shown in the wrong spot after being reinserted / reattached, then you need to check the css of the object. Firebug is an easy tool to use for this purpose, and has saved me countless hours when working with CSS issues. When the content is being readded, either two things have changed:

1) the parent container for the new content has changed, and so the context in how the position of the menu element has changed. 2) the css of the menu has changed, perhaps from Absolute to Relative or Inherit?

Usually, the simplest answer is the correct on in this case, but Firebug will be the way to find it. You can select any element with it to see the css attached to it... just need to find out the change.

http://getfirebug.com/layout

gdbj
  • 16,102
  • 5
  • 35
  • 47