diff --git a/docs/images/screenshot_main.png b/docs/images/screenshot_main.png
index 897e4b1215fcf16e412e7be6506f450d9c126e5b..30d9c739a4184b8e3f6609821467483b36682d49 100644
Binary files a/docs/images/screenshot_main.png and b/docs/images/screenshot_main.png differ
diff --git a/public_html/javascript/functions.js b/public_html/javascript/functions.js
index a2b55a0fe1354d1a70f96b8e5f703da15f40bf4c..666f1db97c33108336c7ce5c5c3052f6067662c0 100644
--- a/public_html/javascript/functions.js
+++ b/public_html/javascript/functions.js
@@ -25,6 +25,7 @@ const OUT_ID_APPS='app-section';
 const OUT_ID_TAGS='tag-section';
 const ID_TAGINPUT='E_TAGS';
 
+
 // callback object after changing a tag filter
 const FILTER_CALLBACK="oUbdApps.update()";
 
@@ -34,6 +35,7 @@ const FILTER_CALLBACK="oUbdApps.update()";
 
 var AM_TAGURL=false;
 var AM_PRETTYURL=false;
+var AM_TAGLIST={};
 
 // ----------------------------------------------------------------------
 // FUNCTIONS
@@ -104,44 +106,29 @@ function _2digits(i){
  * callback function of a button with a tagname
  * @param {string} tagname 
  */
-function tagToggle(tagname){
-    var o=document.getElementById(ID_TAGINPUT);
-    var sLast=o.value;
-    var s=sLast;
-    var re = new RegExp(",*"+tagname);
-    var s2=s.replace(re, "");
-    if(s2!==s) {
-        s=s.replace(re, "")
-        s=s.replace(/^,/, "");
-    } else {
-        s+=(s ? "," : "" ) + tagname;
+ function cbTagToggle(bClear=false){
+    var sReturn='';
+    var sLast=document.getElementById(ID_TAGINPUT).value;
+    var aCB=document.querySelectorAll('#'+OUT_ID_TAGS+' input[type=checkbox]');
+    for(var i=0; i<aCB.length; i++){
+        if(aCB[i].checked && bClear==false){
+            sReturn+=(sReturn ? ',' : '') + aCB[i].value;
+        } else {
+            aCB[i].checked=false;
+        }
     }
-
-    if(s!==sLast){
-        o.value=s;
-        // execute update of the app list
+    if(sLast!==sReturn){
+        document.getElementById(ID_TAGINPUT).value=sReturn;
         eval(FILTER_CALLBACK);
     }
 }
 
-/**
- * clear all tags
- * callback function of the [x] button
- */
-function tagClear(){
-    var o=document.getElementById(ID_TAGINPUT);
-    o.value="";
-
-    // execute update of the app list
-    eval(FILTER_CALLBACK);
-}
-
 /**
  * called from getTags
  * @param {object} aData JSON Response
  * @returns 
  */
-function _getTaglist(aData){
+function _renderTaglist(aData){
     var sReturn='';
     var sTags='';
     if(!aData['tags']){
@@ -149,17 +136,32 @@ function _getTaglist(aData){
     }
 
     // sReturn+='<code>'+sData+'</code><br>';
-    sReturn+='<input id="'+ID_TAGINPUT+'" type="text" size="20" value="'+AM_TAGS+'"'
-            +' onkeyup="eval(FILTER_CALLBACK)"'
-            +' onchange="eval(FILTER_CALLBACK)"'
-            +'>'
-        +'<button onclick="tagClear();return false;"> ❌ </button><br>'
-        ;
 
+    let _TAGLIST={};
+    var sTags='';
     for (var s in aData['tags']){
-        sTags+=(sTags ? ",": "") + aData['tags'][s];
-        sReturn+='<button onclick="tagToggle(\''+aData['tags'][s]+'\'); return false;">'+AM_ICONS['tag'] + ' ' + aData['tags'][s]+'</button>'
+        var sTag=aData['tags'][s];
+        var sId='cb-tag-'+sTag;
+        var bEnabled=AM_TAGS.indexOf(sTag)>-1;
+        _TAGLIST[s]=bEnabled;
+        sReturn+='<input type="checkbox" id="'+sId+'" '
+                +(_TAGLIST[s] ? 'checked="checked" ' : '')
+                +'onchange="cbTagToggle();" '
+                +'value="'+aData['tags'][s]
+                +'">'
+            +'<label for="'+sId+'" >'+AM_ICONS['tag'] + ' ' + aData['tags'][s]+'</label> '
+            ;
+        sTags+=(_TAGLIST[s] 
+            ? (sTags ? ',' : '' ) + sTag
+            : ''
+            );
     }
+    sReturn+='<button onclick="cbTagToggle(true);return false;"> ❌ </button>'
+    // sReturn+='<input id="'+ID_TAGINPUT+'" type="text" size="20" value="'+AM_TAGS+'"'+'>'
+    sReturn+='<input id="'+ID_TAGINPUT+'" type="hidden" size="20" value="'+AM_TAGS+'">'
+    AM_TAGLIST=_TAGLIST;
+    // cbTagToggle();
+
     return sReturn;
 }
 
@@ -277,7 +279,7 @@ var oUbdTag=new ubd(
         'domid':     OUT_ID_TAGS,
         'url':       _getUrlForTags(),
         'header':    { "headers": oHeaders },
-        'renderer':  _getTaglist,
+        'renderer':  _renderTaglist,
         'ttl':       0,
     }
 );
@@ -295,7 +297,7 @@ var oUbdApps=new ubd(
 
 
 
-// fill in initial values
+// fill in initial values ... and update based on given ttl
 oUbdTag.update();
 oUbdApps.update();
 
diff --git a/public_html/javascript/ubd.class.js b/public_html/javascript/ubd.class.js
index 2d8de8029c7f36d894d345e0452a9944a971c0b9..69ea642bfac355f2ebfc664243ab31c7c82e9f65 100644
--- a/public_html/javascript/ubd.class.js
+++ b/public_html/javascript/ubd.class.js
@@ -39,20 +39,22 @@ var ubd = function(){
      * @returns {undefined}
      */
     this.init = function(oConfig){
-        if(oConfig['domid']){
-            this.setDomid(oConfig['domid']);
-        }
-        if(oConfig['url']){
-            this.setUrl(oConfig['url']);
-        }
-        if(oConfig['header']){
-            this.setHeaders(oConfig['header']);
-        }
-        if(oConfig['renderer']){
-            this.setRenderfunction(oConfig['renderer']);
-        }
-        if(oConfig['ttl']){
-            this.setTtl(oConfig['ttl']);
+        if (oConfig){
+            if(oConfig['domid']){
+                this.setDomid(oConfig['domid']);
+            }
+            if(oConfig['url']){
+                this.setUrl(oConfig['url']);
+            }
+            if(oConfig['header']){
+                this.setHeaders(oConfig['header']);
+            }
+            if(oConfig['renderer']){
+                this.setRenderfunction(oConfig['renderer']);
+            }
+            if(oConfig['ttl']){
+                this.setTtl(oConfig['ttl']);
+            }
         }
     },
 
@@ -78,7 +80,7 @@ var ubd = function(){
 
     /**
      * set a rendering function that visualized data after a http request
-     * @param {string|function} oFunction 
+     * @param {string|function} oFunction reference to a function ... or false to disable rendering
      */
     this.setRenderfunction = function(oFunction){
         this._sRenderfunction=oFunction;
@@ -122,25 +124,30 @@ var ubd = function(){
     // ----------------------------------------------------------------------
 
     /**
-     * show rendered html content into set domid using the render function
-     * Optionally you can set a string to display an error message.
+     * show rendered html content into set domid using the render function.
+     * If no rendering function was set then the response will be written
+     * directly.
+     * You can override both by giving a parameter (a string with html)
+     * to write that one directly. It can be used to show an error message.
+     * 
+     * TODO:
+     * other output places than innerHTML by detecting the tag e.g. 
+     * to use input or textarea.
      * 
      * @param {string} sHtml  optional: htmlcode of an error message
      */
     this.render = function(sHtml) {
-        let out = sHtml ? sHtml : this._sRenderfunction(this._body);
+        let out = sHtml ? sHtml : 
+            (this._sRenderfunction 
+                ? this._sRenderfunction(this._body)
+                : this._body
+            );
         this._oDomObject.innerHTML=out;
     },
 
     /**
      * reset timer to update the content in dom id after reaching TTL
      * used in setTtl
-     * 
-     * WIP: repeating the update braks out from current instance.
-     * But what works is 
-     *   var oUbd=new ubd(...)
-     *   by setting ttl = 0 and 
-     *   window.setInterval("oUbd.update();", 3000);
      */
     this.resetTimer = function(){
         clearTimeout(this._oTimer);
@@ -192,6 +199,8 @@ var ubd = function(){
 
     if (arguments) {
         this.init(arguments[0]);
+    } else {
+        this.init();
     }
 
 };
\ No newline at end of file
diff --git a/public_html/main.css b/public_html/main.css
index d6fde9db7cbe2d24ac9e066a9d23833388c31a70..16e92b27873b8e7c7d3f6da624802b316e4e9a95 100644
--- a/public_html/main.css
+++ b/public_html/main.css
@@ -1,7 +1,7 @@
 :root{
     --color-0: #345;
-    --color-h1: #c54;
-    --color-h2: #569;
+    --color-h1: #abc;
+    --color-h2: #579;
     --color-links: #349;
 
     --bg-0: #ddd;
@@ -25,18 +25,34 @@ button:active{ border:1px solid #fc2;}
 input{ border:1px solid #ccc; padding: 0.4em;}
 
 footer{ position: fixed; bottom: 0; left: 0; width: 100%; padding: 1em; background: var(--bg-footer); border-top: 2px solid rgba(255,255,255,0.5); text-align: center;}
-h1{color: var(--color-h1); border-bottom: 1px solid; background: linear-gradient(#fff, #f0f4f8);}
+h1{color: var(--color-h1); border-bottom: 1px solid; background: linear-gradient(#fff, #f0f4f8); margin-top: 0;}
 h2{color: var(--color-h2); margin-left: 0em;}
 
-h1>span, h2>span{font-size: 200%;}
+h1>span, h2>span{font-size: 130%;}
 section{
-    margin: 0 0 2em ;
+    margin: 0 0 1em ;
     padding: 1em 2em;
     border-top: 0px dashed #e0e4f0;
     background: linear-gradient(10deg, #fff, #f0f4f8, #fff);
     border-radius: 1em;
 }
 
+section input[type=checkbox]{ display: none; }
+section input[type=checkbox] + label { 
+    border: 1px solid  rgba(0,0,0,0.05); background: #f8f8f8; border-radius: 0.3em; margin: 0 0.5em 0.5em 0; padding: 0.5em;
+    opacity: 0.6;
+    transition: all 0.3s;
+}
+section input[type=checkbox]:checked + label {
+    background: #fff; 
+    box-shadow: 0.1em 0.1em 0.2em #ddd inset;
+    border-color: #cde;
+    opacity: 1;
+}
+section input[type=checkbox]+ label:hover {
+    border-color: #89a;
+}
+
 td{vertical-align: top;}
 
 #main{