Search code examples
javascriptjquerycssjquery-uiselectable

Jquery UI selectable table cell outline


Ok so I'm using Jquery UI Selectable to highlight some cells in a table. I would like to be able to add a border around the highlighted cells using like a 2px border. This way each time you highlight a section you can tell the separation between each section that has been highlighted. I am also hoping I can achieve this result with overlapping sections.

I've done quite a bit of reading and haven't really seen anyone trying to do this yet. So I'm wondering if someone might be able to point me in the right direction on how to achieve this effect.

result example reult example2

Here's a fiddle of my example and some code below.

var shadeColor = $(".color-pallet > .active").css("background-color");

applySelectable = function() {
    $(".block-tools > .shade-btn").click(function() {
        var $this = $(this);    

        if (!$this.hasClass("active")) {
            $this.siblings().removeClass("active");
            $this.addClass("active");   
        }
    });

    $(".color-pallet > span").click(function() {
        var $this = $(this);

        if (!$this.hasClass("active")) {
            $this.siblings().removeClass("active");
            $this.addClass("active");   

            shadeColor = $(this).css("background-color");
        }
    });

    // keep selected shade color selected after new question
    if (shadeColor !== $(".color-pallet > .active")) {
        $(".color-pallet > span").filter(function(){
            var color = $(this).css("background-color");
            if (color === shadeColor) {
                $(this).click();    
            };
        });
    }

    $(".blocks").bind("mousedown", function(e) {
        e.metaKey = true;
    }).selectable({
        filter: "td",
        selecting: function (event, ui) {
            if ($('.block-shade').hasClass("active")) {
                $(ui.selecting).addClass('marked').css("background-color", shadeColor);
            } else {
                $(ui.selecting).removeClass('marked').css("background-color", "");
            }
            userAns = $('.marked').length+"";
        }
    });
};

applySelectable();

Thank you in advance for you time.

EDIT: For bonus points, can someone tell me when im dragging a selection, why is the containers height growing and creating a scroll bar? This has been seriously bugging me for some time and I chose to ignore it but I guess while I'm here maybe someone could explain this as well?


Solution

  • Huh... here is some kind of solution, i've added 4 css classes, and some ugly code... but it is working...

    $(".blocks").bind("mousedown", function(e) {
                e.metaKey = true;
            }).selectable({
                filter: "td",
                selecting: function (event, ui) {
                    if ($('.block-shade').hasClass("active")) {
                        $(ui.selecting).addClass('marked').css("background-color", shadeColor);
                        $(ui.selecting).addClass('top');
                         $(ui.selecting).addClass('left');
                         $(ui.selecting).addClass('bottom');
                         $(ui.selecting).addClass('right');
                        if($(ui.selecting).prev().hasClass('marked')) {
                           $(ui.selecting).removeClass('left');
                            $(ui.selecting).prev().removeClass('right');
                           }
                          if($(ui.selecting).next().hasClass('marked')) {
                           $(ui.selecting).removeClass('right');
                            $(ui.selecting).next().removeClass('left');
                           }
    
                        top_elem=$(ui.selecting).parent().prev('tr').find('td');
                         // console.log(top_elem);
    
    
                            $(top_elem).each(function(i) {
                                 if($(this).hasClass('marked')) {
                                if($(this).offset().left==$(ui.selecting).offset().left) 
                                {
                                    $(this).removeClass('bottom');
                            $(ui.selecting).removeClass('top'); 
                                }
    
                        }   
                            });
    
                        bottom_elem=$(ui.selecting).parent().next('tr').find('td');
    
    
                            $(bottom_elem).each(function(i) {
                                if($(this).hasClass('marked')) {
                                if($(this).offset().left==$(ui.selecting).offset().left) 
                                {
                                    $(this).removeClass('top');
                            $(ui.selecting).removeClass('bottom'); 
                                }
                              }
                        });
    
    
    
                    } else {
                        $(ui.selecting).removeClass('marked').css("background-color", "");
                         $(ui.selecting).removeClass('top');
                         $(ui.selecting).removeClass('left');
                         $(ui.selecting).removeClass('bottom');
                         $(ui.selecting).removeClass('right');
                    }
                    userAns = $('.marked').length+"";
                }
            });
        };
    
        applySelectable();
    });
    

    DEMO: http://jsfiddle.net/wh2ehzo3/10/

    However, overlapping is really, really tricky IF YOU WANT to KEEP borders on overlapping parts.. test... (just OUTER border of both shapes is saved, i hope you will see what i mean)

    Idea: check siblings -> remove classes accordingly, if there is .marked element, check up and down rows -> do the same...