views:

344

answers:

3

I have the need to trigger the opening of the browser (IE, Firefox, Safari, etc) context-menu via javascript. The problem I am trying to solve, is when an overlaid element is right-clicked, the element below it shows its context menu. So if the top element is a label, when you right click, I need to show the context menu for the input element below.

I know how to keep the label's context menu from showing, but I don't know how to open a context menu arbitrarily.

Any help is appreciated!

+3  A: 

Sorry to be the bearer of unfortunate news, but this is impossible to do with Javascript.

Josh Stodola
I was hoping this wasn't the answer. Going to leave it open for a little longer.... just in case. :)
Doug Neiner
Yes, I would leave it open if I were you.
Josh Stodola
+1  A: 

I don't want to frustrate you, quite the contrary, especially because you answered my own question :)

I don't think that a browser's contect menu is accessible via an ordinary script on a web page.

If what you are asking for was actually doable, then the browser makers would possibly consider this a bug and remove this behavior. Cross-browser, this behavior is very unlikely to be available today.

Why don't you capture mouse events, and whenever the mouse is directly in the area of the element below that you want to show the context menu for, push the covering element below, otherwise back on top?

That is one possiblity I could think of, basically revealing/exposing the hidden element depending on mouse position. Like cutting a hole into the overlay.

Or why don't you make the text field transparent and put the overlay below the text field entirely?

If this does not work out technically, then at least you have a point in filing bugs or enhancements against the targeted browsers.

BTW it looks like the context menu actually works if the user right-clicks directly at the position of the caret, so this might be another loophole for you to consider.

All very good thoughts. I think on the new release I am going to add support for showing the label *below* the input element as this will solve the issue. It just means the wrapping element needs to provide the background color for the input element or textarea. Should work though!
Doug Neiner
A: 

I have a possible solution that may suit your needs. It is not perfect yet, I have only done a few quick tests in a few browsers (Fox 3.6, IE7, IE8, Chrome 4, Safari 3 on xp) It will need to be tweaked and improved but its a start. Basically the idea is to remove the label on right-click mousedown so that the desired field is hit by the mouseup event and therefore fires up the context menu on the relevant field.

// Remove the contextmenu from "In-Field" Labels
base.$label.bind("contextmenu",function(e){
    return false;
}); 

// Detect right click on "In-Field" label:
// hide label on mousedown so mouseup will target the field underneath.
base.$label.mousedown(function(e){          
    if ( e.which == 3 ){
        var elLbl = $(this); 
        elLbl.hide();
        var elFid = $(this).attr("for");
        // bind blur event to replace the label when we are done.
        $("#" + elFid ).bind("blur.infieldlabel",function(){                    
            elLbl.show();
            $("#" + elFid ).unbind("blur.infieldlabel");                    
        });             
        return false;
    }
}); 

The IE and Safari browsers experience a strange issue where you need to click in and out twice before the label will display again (something to do with event timing I think). You may be able to easily see why this is happening by looking at the code. Also noticed slight glitch sometimes in the fox after pasting into the field, on blur the label appeared for a split second when it should not. This should be a fairly simply thing to rectify if you decide to incorporate this method into your code.

Brad Kelly