Mental Jetsam

By Peter Finch

Archive for October, 2010

Simple JQuery popup context menu

Posted by pcfinch on October 13, 2010

Below is a simple JQuery right click popup context menu. The aim of the code is to be short, simple and flexible.

(function($) {
  $.fn.contextMenu = function(items) {
    var target, menu = $("<div>")
      .css({"background-color":"#eee",border:"1px solid black",padding:"5px"})
      .appendTo("body").hide()
      .hover(jQuery.noop(), function() { $(this).hide() }) ;
    for(var i = 0; i < items.length; i++) (function() {
      var item = items[i] ;
      menu.append($("<div>").html(item.title).css({"padding":"0 5 0 5"})
        .click(function() { item.action(target) ; menu.hide() } ) 
        .hover(
          function() { $(this).css({"background-color":"#aaf","color":"white"}) },
          function() { $(this).css({"background-color":"","color":""}) } )
      ) ;    
    })() ;
    this.each(function() { 
      $(this).bind('contextmenu', function(e) {
        target = $(this) ;
        menu.css({position:"absolute",left:e.pageX - 2,top:e.pageY - 2}).show() ;
        return (false) ; // don't propagate up
      }) ;
    } ) ;
  } ;
})(jQuery) ;

The code is implented as a JQuery function so it’s simple to add to existing HTML. The JQuery element, to which the context menu is attached, is passed in as the first argument in the menu callback, so it’s easy to relate it back to what was selected. e.g.

<script type="text/javascript">
$(document).ready(function() {
  var items = [
    {title:"<img src='public.png'>Small", action:function(e) { e.animate({"font-size":"16px"}, 200) ; } },
    {title:"<img src='private.png'>Mediam", action:function(e) { e.animate({"font-size":"26px"}, 200) ; } },
    {title:"<img src='group.png'>Large", action:function(e) { e.animate({"font-size":"36px"}, 200) ; } },
    {title:"<img src='cancel.png'>Huge", action:function(e) { e.animate({"font-size":"46px"}, 200) ; } }
  ] ;
  $(".popup").contextMenu(items) ;
}) ;
</script>
</head>
<body>
<div class="popup">popup1</div>
<div class="popup">popup2</div>
<div class="popup">popup3</div>
<div class="popup">popup4</div>
</body>

I have tested this code and IE 7+, Firefox, Safari and Chrome and it seems to work ok. Here is an example of what it should look like. Please let me know if you have any problems and I hope you fine it useful.

Simple JQuery context menu

Advertisements

Posted in javascript, JQuery | Leave a Comment »

C++ STL vector of pointers

Posted by pcfinch on October 11, 2010

Storing pointers in a C++ STL vector (e.g. vector<CBase *>) can be problematic, as you always have to remember to manually delete the pointers from the vector before deleting the vector, or before the vector goes out of scope. A simple way to get around the problem, is to subclass the vector template with another template and provide a destructor that deletes the contents of the array.

template<class _T> class prt_vector : public vector<_T*> {
public :
  virtual ~prt_vector() {
    for (unsigned int i=0; i<size(); i++) 
      delete (*this)[i] ;
  } ;
} ;

prt_vector<CBase> list ;
list.push_back(new CBase("Peter") ) ;
list.push_back(new CCake("Annette", "Fruit") ) ;

for (unsigned int i=0; i<list.size(); i++) {
  list[i]->print(cout) ; 
}

Storing pointers to the objects in the vector means you also get the added advantage of being able to store subclasses of the base class in the vector as well.

Posted in C++/MFC | Leave a Comment »