1

I am working on a site that has the ability of creating/adding a new element on the page. and I want to have a controll on z-index for each element added on the page. So that I can put a div on top of another div.

<div class="element ui-resizable ui-draggable" style="z-index:10000">
  <div id="controller">
    <a href="#" class="zup"> move up </a>
    <a href="#" class="zdown"> move down </a>
  </div>
  <div class="content">
    some text content her
  </div>
</div>

javascript

$('.zup').click(function() {
  $cur_zindex = $(this).parents('.element').css('zIndex');
  $(this).parents('.element').css({ zIndex: $cur_zindex+1 })
})

$('.zdown').click(function() {
  $cur_zindex = $(this).parents('.element').css('zIndex');
  $(this).parents('.element').css({ zIndex: $cur_zindex-1 })
})

the problem on this is when I click multiple times on "move up" of an element, then I also need to click the "move down" multiple times before I can make the current element position at the back. That's because of the gap on z-index when I click multiple times.

In short I want to have a easy way for the user to set the z index, where in no matter how much you click the "move up", then if someone click "move up" on the other element it will automatically position on the top of that multiple clicked zindex/move up

Any suggestions are very welcome.

Thank you

dstarh
  • 4,976
  • 5
  • 36
  • 68
King Pangilinan
  • 597
  • 1
  • 14
  • 26
  • Are all elements originally added at th same z-index? If so you could reset all elements to that index and then increase the one the user wants moved up by one. – Ryan Fiorini Apr 27 '12 at 02:23
  • all elements have same z-index at first, "YES", but when the user starts to rearrange the element position I want to preserve it, because there will can be more than 20 elements on a page.. thanks for you respone. – King Pangilinan Apr 27 '12 at 02:38
  • Have a variable store the next z-index to be used and when an element is hit to move to the top use the store index from the variable then increment it for the next one. This will ensure the element will be on top. – Ryan Fiorini Apr 27 '12 at 02:46

2 Answers2

0

Here is my idea.

$('.zup').click(function () {
  var max_zindex = -10000;
  $('.zup').each(function () {
    if ($(this).css('zIndex') > max_zindex) { max_zindex = $(this).css('zIndex'); }
  });

  // If we don't already have the max_zindex, then set the zindex to the max + 1
  // Notice that if the element clicked does have the max zindex, nothing happens.
  if (max_zindex != $(this).css('zIndex')) {
    $(this).css('zIndex', max_zindex + 1);
  }
});


$('.zdown').click(function () {
  var min_zindex = 10000;
  $('.zup').each(function () {
    if ($(this).css('zIndex') < min_zindex) { min_zindex = $(this).css('zIndex'); }
  });

  if (min_zindex != $(this).css('zIndex')) {
    $(this).css('zIndex', min_zindex + 1);
  }
});
Max
  • 15,157
  • 17
  • 82
  • 127
  • does not work for Max, It gives my element a -9999 z-index value that results to make the element disappear. btw I modify the question a little to make it clear. Thank you – King Pangilinan Apr 27 '12 at 05:00
0

So my approach is a little different in that there are 4 controls (up/down/top/bottom). I could not think of a way to combine moving an element up or down 1 increment or jumping to the top or the bottom of the stack. I made a demo where you can see the z-index on each element after clicking on the + or -. More elements can be added to play around with.

It might not be exactly the solution you are after but I hope it helps. Code from fiddle duplicated below:

HTML

<a href="#" id="add">add element</a>
<div id="elements">
    <div class="element ui-draggable">
      <div class="controller">
        <a href="#" class="top">⇈</a>
        <a href="#" class="zup">+</a>
        <a href="#" class="zdown">-</a>
        <a href="#" class="bottom">⇊</a>
      </div>
      <div class="content">lorum ipsum</div>
      <div class="zIndex"></div>
    </div>
</div>​

CSS

.element {
    background-color:lightblue;
    border:1px solid darkblue;
    width:96px;
    height:96px;
    padding:2px;
    z-index:0;
}

.content {
    margin-top:4px;
}

.controller a {
    margin:0 4px;
    text-decoration:none;
}

.zIndex {
    position:absolute;
    right:0;
    bottom:0
}​

JavaScript (run against jquery 1.7.2)

$('#add').on('click', function() {
    var $clone = $('.element:first')
                 .clone()
                 .attr('id', 'e' + $('.element').length++)
                 .draggable();

    $('#elements').append($clone);
    return false;
});

$('#elements').on('click', 'a', function() {
    var $element = $(this).closest('.element');
    var $siblings = $element.siblings();
    var zIndexes = $siblings.map(function() {
        return $(this).css('z-index');
    });

    var zIndex = parseInt($element.css('z-index'));

    switch(this.className) {
        case 'top':
            zIndex = Array.max(zIndexes) + 1;
            break;
        case 'zup':
             zIndex += 1;
            break;
        case 'zdown':
            zIndex -= 1;
            break;
        case 'bottom':
            zIndex = Array.min(zIndexes) - 1;
            break;
    }

    // workaround for negative z-index madness (simply set lowest as 0 and raise everything else by 1)
    if (zIndex === -1) {
        zIndex = 0;
        $siblings.each(function() {
            var z = parseInt($(this).css('z-index')) + 1;
            $(this).css('z-index', z);
            $(this).find('.zIndex').text(z);
        });
    }

    $element.css({zIndex:zIndex});
    $element.find('.zIndex').text(zIndex);
    return false;
});

$('.element').draggable();

Array.max = function(array) {
    return Math.max.apply(Math, array);
};

Array.min = function(array) {
    return Math.min.apply(Math, array);
};

Whilst doing some research for this, the following links were useful Setting z-index on draggable elements, jQuery min/max property from array of elements and in particular (for the negative z-index issue) http://bugs.jqueryui.com/ticket/4461

Community
  • 1
  • 1
andyb
  • 43,435
  • 12
  • 121
  • 150