ComboBox: stateful dropdown
authorSven Schöling <s.schoeling@linet-services.de>
Wed, 19 Oct 2016 12:08:45 +0000 (14:08 +0200)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Tue, 28 Feb 2017 09:04:33 +0000 (10:04 +0100)
SL/Layout/ActionBar/ComboBox.pm
css/lx-office-erp/main.css
js/kivi.ActionBar.js

index 3416df8..5e5c863 100644 (file)
@@ -21,7 +21,7 @@ sub add_actions {
 sub render {
   my ($first, @rest) = @{ $_[0]->parsed_actions };
   $_[0]->p->html_tag('div',
-    $_[0]->p->html_tag('div', $first->render, class => 'layout-actionbar-combobox-head') .
+    $_[0]->p->html_tag('div', $first->render . $_[0]->p->html_tag('span'), class => 'layout-actionbar-combobox-head') .
     $_[0]->p->html_tag('div', join('', map { $_->render } @rest), class => 'layout-actionbar-combobox-list'),
     id    => $_[0]->id,
     class => 'layout-actionbar-combobox',
index eee23c9..50038aa 100644 (file)
@@ -564,7 +564,7 @@ div.layout-actionbar ~ div {
 
 div.layout-actionbar-separator {
   display: inline-block;
-  width: 10px;
+  width: 20px;
 }
 
 div.layout-actionbar div.layout-actionbar-submit,
@@ -609,12 +609,40 @@ div.layout-actionbar-combobox {
   display: inline-block;
 }
 
-div.layout-actionbar-combobox div.layout-actionbar-combobox-head:after {
+div.layout-actionbar-combobox div.layout-actionbar-combobox-head div {
+  width: 100px
+}
+
+div.layout-actionbar-combobox div.layout-actionbar-combobox-head span {
+  display: inline-block;
+  border-width: 1px 1px 1px 1px;
+  border-style: solid;
+  border-color: darkgray;
+  padding: 4px;
+  width: 14px;
+  height: 15px;
+  position: absolute;
+  top: 0;
+  right: 0;
+  -webkit-border-top-right-radius: 2px;
+  -webkit-border-bottom-right-radius: 2px;
+  -moz-border-radius-topright: 2px;
+  -moz-border-radius-bottomright: 2px;
+  border-top-right-radius: 2px;
+  border-bottom-right-radius: 2px;
+  background-color: whitesmoke;
+}
+
+div.layout-actionbar-combobox div.layout-actionbar-combobox-head span:hover {
+  background-color: lightgray;
+}
+
+div.layout-actionbar-combobox div.layout-actionbar-combobox-head span:after {
   content: "";
   width: 0;
   height: 0;
   position: absolute;
-  right: 10px;
+  right: 8px;
   top: 50%;
   margin-top: -3px;
   border-width: 3px 3px 0 3px;
@@ -622,26 +650,24 @@ div.layout-actionbar-combobox div.layout-actionbar-combobox-head:after {
   border-color: black transparent;
 }
 
-div.layout-actionbar-combobox div.layout-actionbar-combobox-head.active:after {
-  border-width: 3px 3px 0 3px;
+div.layout-actionbar-combobox.active div.layout-actionbar-combobox-head span:after {
+  border-width: 0 3px 3px 3px;
 }
 
 
 div.layout-actionbar-combobox div.layout-actionbar-combobox-head {
+  padding-right: 20px;
   white-space: nowrap;
   display: block;
 }
 
-div.layout-actionbar-combobox div.layout-actionbar-combobox-head div.layout-actionbar-action::after {
-}
-
 div.layout-actionbar-combobox div.layout-actionbar-combobox-list {
   position: absolute;
   display: none;
   min-width: 120px;
 }
 
-div.layout-actionbar-combobox:hover div.layout-actionbar-combobox-list {
+div.layout-actionbar-combobox.active div.layout-actionbar-combobox-list {
   display: inline-block;
   z-index: 10;
 }
index d87b578..1c883ed 100644 (file)
@@ -2,52 +2,82 @@ namespace('kivi', function(k){
   'use strict';
 
   var CLASSES = {
-    disabled: 'layout-actionbar-action-disabled'
+    active:   'active',
+    actionbar: 'layout-actionbar',
+    disabled: 'layout-actionbar-action-disabled',
+    action:   'layout-actionbar-action',
+    combobox: 'layout-actionbar-combobox',
   }
 
-   k.ActionBarAction = function(e) {
-     var data = $(e).data('action');
-     if (undefined === data) return;
+  k.ActionBarCombobox = function(e) {
+    this.combobox = e;
+    this.head     = e.childNodes[0];
+    this.toggle   = this.head.childNodes[1];
+    this.list     = e.childNodes[0];
+    this.init();
+  }
+  k.ActionBarCombobox.prototype = {
+    init: function() {
+      var obj = this;
+      $(obj.toggle).on('click', function(event){
+        $(obj.combobox).toggleClass(CLASSES.active);
+        event.stopPropagation();
+      });
+    }
+  }
+
+  k.ActionBarAction = function(e) {
+    var data = $(e).data('action');
+    if (undefined === data) return;
 
-     if (data.disabled) {
-       $(e).addClass(CLASSES.disabled);
-     }
+    if (data.disabled) {
+      $(e).addClass(CLASSES.disabled);
+    }
 
-     if (data.call || data.submit) {
-       $(e).click(function(event) {
-         var $hidden, key, func, check;
-         if ($(e).hasClass(CLASSES.disabled)) return;
-         if (data.checks) {
-           for (var i=0; i < data.checks.length; i++) {
-             check = data.checks[i];
-             func = kivi.get_function_by_name(check);
-             if (!func) console.log('Cannot find check function: ' + check);
-             if (!func()) return;
-           }
-         }
-         if (data.confirm && !confirm(data.confirm)) return;
-         if (data.call) {
-           func = kivi.get_function_by_name(data.call[0]);
-           func.apply(document, data.call.slice(1))
-         }
-         if (data.submit) {
-           var form   = data.submit[0];
-           var params = data.submit[1];
-           for (key in params) {
-             $hidden = $('<input type=hidden>')
-             $hidden.attr('name', key)
-             $hidden.attr('value', params[key])
-             $(form).append($hidden)
-           }
-           $(form).submit();
-         }
-       });
-     }
-   }
+    if (data.call || data.submit) {
+      $(e).click(function(event) {
+        var $hidden, key, func, check;
+        if ($(e).hasClass(CLASSES.disabled)) {
+          event.stopPropagation();
+          return;
+        }
+        if (data.checks) {
+          for (var i=0; i < data.checks.length; i++) {
+            check = data.checks[i];
+            func = kivi.get_function_by_name(check);
+            if (!func) console.log('Cannot find check function: ' + check);
+            if (!func()) return;
+          }
+        }
+        if (data.confirm && !confirm(data.confirm)) return;
+        if (data.call) {
+          func = kivi.get_function_by_name(data.call[0]);
+          func.apply(document, data.call.slice(1))
+        }
+        if (data.submit) {
+          var form   = data.submit[0];
+          var params = data.submit[1];
+          for (key in params) {
+            $hidden = $('<input type=hidden>')
+            $hidden.attr('name', key)
+            $hidden.attr('value', params[key])
+            $(form).append($hidden)
+          }
+          $(form).submit();
+        }
+      });
+    }
+  }
 });
 
 $(function(){
   $('div.layout-actionbar .layout-actionbar-action').each(function(_, e) {
-    kivi.ActionBarAction(e);
+    kivi.ActionBarAction(e)
+  });
+  $('div.layout-actionbar-combobox').each(function(_, e) {
+    $(e).data('combobox', new kivi.ActionBarCombobox(e));
+  });
+   $(document).click(function() {
+    $('div.layout-actionbar-combobox').removeClass('active');
   });
 });