[AngularJS] Resizable Views


Resizable Views via AngularJS.

Demo

Real world application of resizable views is Pāli Tipiṭaka.

Source code:

index.html | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!doctype html>
<html ng-app="demoResizableViews">
<head>
  <meta charset="utf-8">
  <title>AngularJS Resizable Views Demo</title>
  <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>

<div id="allContainer">
  <div id="leftview">left view here.</div>
  <div id="viewwrapper">
    <div id="viewarrow"></div>
    <div id="viewseparator"></div>
  </div>
  <div id="rightview">right view here.</div>
  <div style="clear: both;"></div>
</div>

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script src="resizableViews.js"></script>
<script src="app.js"></script>
</body>
</html>
app.js | repository | view raw
1
2
3
4
5
6
7
8
9
'use strict';


angular.module('demoResizableViews', ['resizableViews']).
  run(['resizableViews',
  function(resizableViews) {
    // initialize resizable views
    resizableViews.initViews('allContainer', 'leftview', 'viewwrapper', 'viewarrow', 'viewseparator', 'rightview');
  }]);
resizableViews.js | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
'use strict';

/* Services */


angular.module('resizableViews', []).
  factory('resizableViews', ['$document', function($document) {
    var leftView, viewwrapper, arrow, separator, rightView;
    var startLeftViewWidth, startRightViewWidth, initialMouseX;

    function initViews(allContainerId, leftViewId, viewwrapperId, arrowId, separatorId, rightViewId) {
      leftView    = angular.element(document.getElementById(leftViewId));
      viewwrapper = angular.element(document.getElementById(viewwrapperId));
      arrow       = angular.element(document.getElementById(arrowId));
      separator   = angular.element(document.getElementById(separatorId));
      rightView   = angular.element(document.getElementById(rightViewId));

      var width = document.getElementById(allContainerId).offsetWidth;
      var leftViewWidth = 250; //px
      var viewwrapperWidth = 7; //px
      var rightViewWidth = width - leftViewWidth - viewwrapperWidth;

      // set default width
      leftView.css(   'width', leftViewWidth    + 'px');
      rightView.css(  'width', rightViewWidth   + 'px');
      viewwrapper.css('width', viewwrapperWidth + 'px');

      arrow.bind('click', function() {
        var lwidth = parseInt(leftView.css('width').replace('px', ''));
        var rwidth = parseInt(rightView.css('width').replace('px', ''));
        leftView.css('width', '0');
        rightView.css('width', lwidth + rwidth + 'px');
      });

      separator.bind('mousedown', function($event) {
        $event.preventDefault();
        startLeftViewWidth = parseInt(leftView.css('width').replace('px', ''));
        startRightViewWidth = parseInt(rightView.css('width').replace('px', ''));
        initialMouseX = $event.clientX;
        $document.bind('mousemove', mousemove);
        $document.bind('mouseup', mouseup);
        return false;
      });
    }

    function mousemove($event) {
      // calculate the delta of mouse cursor movement
      var dx = $event.clientX - initialMouseX;

      var newlw = startLeftViewWidth + dx;
      if (newlw < 0) {
        leftView.css('width', '0');
        rightView.css('width', startLeftViewWidth + startRightViewWidth + 'px');
        return false;
      }

      var newrw = startRightViewWidth - dx;
      if (newrw < 0) {
        leftView.css('width', startLeftViewWidth + startRightViewWidth + 'px');
        rightView.css('width', '0');
        return false;
      }

      leftView.css('width', newlw + 'px');
      rightView.css('width', newrw + 'px');
      return false;
    }

    function mouseup() {
      $document.unbind('mousemove', mousemove);
      $document.unbind('mouseup', mouseup);
    }

    var serviceInstance = { initViews: initViews };
    return serviceInstance;
  }]);
style.css | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
html, body { height: 100%; }

/**
 * http://stackoverflow.com/questions/526294/how-might-i-force-a-floating-div-to-match-the-height-of-another-floating-div
 */

#allContainer {
  width: 100%;
}

#leftview {
  float: left;
  overflow: auto;
  font-family: Tahoma, Arial, serif;
  padding-bottom:100%;
  margin-bottom:-100%;
}

#viewwrapper {
  position: relative;
  float: left;
  padding-bottom:100%;
  margin-bottom:-100%;
}

/**
 * http://stackoverflow.com/questions/7778306/css-how-to-force-elements-to-100-of-remaining-available-space-of-parent-eleme
 */
#viewarrow {
  width: 0;
  height: 0;
  border-top: 7px solid transparent;
  border-bottom: 7px solid transparent;
  border-right: 7px solid blue;
  margin-bottom: 3px;
  cursor: pointer;
}

#viewseparator {
  position: absolute;
  top: 17px;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: #EEE;
  cursor: col-resize;
}

#rightview {
  float: left;
  font-family: Tahoma, Arial, serif;
  min-height: 100%;
  padding-bottom:100%;
  margin-bottom:-100%;
}

Tested on: Chromium Version 50.0.2661.102 Ubuntu 16.04 (64-bit), AngularJS 1.5.5 and 1.1.4.


References:

[1]html - How might I force a floating DIV to match the height of another floating DIV? - Stack Overflow
[2]html - CSS - How to force elements to 100% of remaining/available space of parent element without extending beyond it? - Stack Overflow