1

My purpose is to split a certain timeline in divisions.

My only idea of doing it is by doing something like this:

Dividable timeline

Another thing I want to be able to do is resize them by dragging one end to the left or to the right, when this is done, the next one adjusts so they ocupy the same space.

Any division can be split further.

this is what I've come up with but I'm not pleased with it at all:

https://jsfiddle.net/syj6z05v/2/

$(function() {
    $( "#resizable1" ).resizable({
      containment: "#container"
    });
    $( "#resizable2" ).resizable({
      containment: "#container"
    });
    $( "#resizable3" ).resizable({
      containment: "#container"
    });
});

$(function() {
    var isDragging = false;
    var okay = 0;
    var next;
    $(".a")
    .mousedown(function() {
        okay = 1;
        isDragging = false;
    })
    .mousemove(function() {
        if (okay == 1){
        next = $(".a").next();

        var width = 0;
        $(this).parent().children().each(function() {
            width += $(this).outerWidth( true );
        });
        next.width(next.parent().width() - (width - next.width()));
        isDragging = true;
        }
     })
    .mouseup(function() {
        okay = 0;
        isDragging = false;
    });
});
rrk
  • 15,677
  • 4
  • 29
  • 45
fpopa
  • 13
  • 2
  • Why are you not pleased with it? – GolezTrol Apr 09 '16 at 08:57
  • this question is quite broad. However, you can solve the second half by using jQuery UI's [`.resizable()` method](https://jqueryui.com/resizable/), with the [`resize` event](http://api.jqueryui.com/resizable/#event-resize). No need for `mouseup`, `mousedown`, or `mousemove` –  Apr 09 '16 at 08:58
  • for the first part: get the "line" positions by getting the "clicked" position using [this *mouse position* solution](http://stackoverflow.com/a/4249711/3186555) –  Apr 09 '16 at 09:06
  • I'm wondering, wouldn't it be easier to add, remove and drag separators? You basically have to just add a small line. After you're done, you can define the sections as 0 to line1, line1 to line 2, .... , line n to 100%. – GolezTrol Apr 09 '16 at 09:11
  • are you suggesting only adding some kind of movable separators? that sounds quite good, resizing objects made it looks quite bad. – fpopa Apr 09 '16 at 09:18
  • definitely going to us your suggested mouse position solution @DaMaxContent, thanks! – fpopa Apr 09 '16 at 09:21
  • @GolezTrol, He would still need the elements for the numbers, so separators would be pointless... –  Apr 09 '16 at 09:22
  • However, if you do use that solution, I would recommend [jQuery UI `.draggable()` method](http://api.jqueryui.com/draggable/) with the [`drag` event](http://api.jqueryui.com/draggable/#event-drag) –  Apr 09 '16 at 09:24
  • also, if you like a comment, the polite thing to do is to upvote it... –  Apr 09 '16 at 09:26
  • @DaMaxContent You could actually use `:before` and `:after` for that.. Would still be easier. – GolezTrol Apr 09 '16 at 09:29
  • it would be hard to center them, also the content of the before and after cannot be directly edited with JS, since they are pseudo-elements @GolezTrol –  Apr 09 '16 at 09:30
  • You can use `content: attr('xyz')` in the CSS and set the attribute through JavaScript. This way you can handle all this displaying in CSS, and strip away a lot of the logic from JavaScript. You just have to drag a single element (a line==1px width box), and update a custom attribute to the pixel value you've got anyway. `attr()` is [supported in all modern browsers](http://caniuse.com/#feat=css-gencontent), even in IE8 and above. – GolezTrol Apr 09 '16 at 09:31
  • I would be reluctant to use the attr() in CSS, as CSS functions are known not to be widely supported, but that may be just me –  Apr 09 '16 at 09:33
  • Sorry but I am really new to asking stuff here, can't even find the upvote button... thanks for all the suggestions. – fpopa Apr 09 '16 at 09:36

1 Answers1

0

As discussed in the comments, I think adding movable dividers would be easier, because you don't have to recalculate the position and width of every part.

I've made a little example below. It's not perfect, but I hope it gets you going. You can click to add a divider, right-click to remove one, and you can drag them by holding down the left button.

// Dragging a handle
var dragging = null;
$('.timeline').on('mousedown', '.divider', function(event){
  event.stopPropagation();
  if (event.which == 1)
    dragging = $(this);
});

$('.timeline').on('mousemove', function(event){
  if (dragging) {
    var left = event.offsetX;
    if ($(event.target).hasClass('divider'))
      left += dragging.position().left;
    dragging
        .css('left', left + 'px')
        .attr('data-pos', left);
  }
});

$('.timeline').on('mouseup mouseenter', function(event){
  if ((event.buttons && 1) !== 1)
    dragging = null;
});

// Adding a handle
$('.timeline').on('mouseup', function(event){
  if (! $(event.target).hasClass('timeline')) 
     return;
  
  if (event.which == 1)
  {
    var left = event.offsetX;
    var divider = 
      $('<div>')
        .addClass('divider')
        .css('left', left + 'px')
        .attr('data-pos', left)
        .appendTo(this);
  }
});

// Removing a handle
$('.timeline').on('mouseup', '.divider', function(event){
  if (event.which == 2)
    $(this).remove();
});
.timeline {
  position: relative;
  height: 20px;
  border: 1px solid blue;
}

.divider {
  position: absolute;
  background-color: red;
  width: 1px;
  height: 100%;
  /* Show a cursor to indicate draggability */
  cursor: ew-resize;
}

.divider::before {
  /* ::Before is used to display the number */
  display: block;
  position: absolute; 
  content: attr(data-pos);
  height: 100%;
  /* Since it is also a capturer for the mouse events of the divider, make sure it extends a bit to the left for easy grabbing. */
  padding-left: 6px;
  left: -3px;
  /* I added background color, so you can see the grabbable area. You would probably want to remove this in production */
  background-color: rgba(255, 0, 0, 0.1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Click the time line to add markers. Drag the markers to place them on the right spot.
<div class="timeline">
</div>
GolezTrol
  • 114,394
  • 18
  • 182
  • 210