2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-15 16:19:11 +00:00

fhemweb_sortable: by Markus, Forum #35761

git-svn-id: https://svn.fhem.de/fhem/trunk@8387 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2015-04-07 09:08:26 +00:00
parent 76d5c79ac6
commit 7fae1953ad
5 changed files with 266 additions and 4 deletions

View File

@ -3203,6 +3203,21 @@ FW_widgetOverride($$)
the jQuery knob widget will be displayed. The parameters are
specified as a comma separated list of key:value pairs, where key
does not have to contain the "data-" prefix.</li>
<li>if the modifier is of the form ":sortable,val1,val2,...", then
the user can create a new list from the elements of the given
list, can add new elements by entering a text, or delete some from
the list. This new list can be sorted via drag &amp; drop. The
result is a comma separated list. </li>
<li>if the modifier is of the form ":sortable-strict,val1,val2,...",
then it behaves like :sortable, without the possibility to enter
text.</li>
<li>if the modifier is of the form ":sortable-given,val1,val2,...",
then the specified list can be sorted via drag &amp; drop, no
elements can be added or deleted. </li>
<li>else a dropdown with all the modifier values is displayed</li>
</ul>
If this attribute is specified for a FHEMWEB instance, then it is
@ -3210,7 +3225,8 @@ FW_widgetOverride($$)
<ul>
attr FS20dev widgetOverride on-till:time<br>
attr WEB widgetOverride room:textField<br>
attr dimmer widgetOverride dim:knob,min:1,max:100,step:1,linecap:round<br>
attr dimmer widgetOverride
dim:knob,min:1,max:100,step:1,linecap:round<br>
</ul>
</li>
<br>
@ -3499,7 +3515,8 @@ FW_widgetOverride($$)
<ul>
mkdir certs<br>
cd certs<br>
openssl req -new -x509 -nodes -out server-cert.pem -days 3650 -keyout server-key.pem
openssl req -new -x509 -nodes -out server-cert.pem -days 3650 -keyout
server-key.pem
</ul>
<br>
@ -3708,7 +3725,8 @@ FW_widgetOverride($$)
Anmerkung: Wenn das Icon ein SVG Bild ist, kann das @colorname Suffix
verwendet werden um das Icon einzuf&auml;rben. Z.B.:<br>
<ul>
attr Fax devStateIcon on:control_building_empty@red off:control_building_filled:278727
attr Fax devStateIcon on:control_building_empty@red
off:control_building_filled:278727
</ul>
</ul>
@ -3802,7 +3820,33 @@ FW_widgetOverride($$)
jQuery knob Widget wird angezeigt. Die Parameter werden als eine
Komma separierte Liste von Key:Value Paaren spezifiziert, wobei das
data- Pr&auml;fix entf&auml;llt. </li>
<li>Ist der Modifier ":sortable,val1,val2,...", dann ist es
m&ouml;glich aus den gegebenen Werten eine Liste der
gew&uuml;nschten Werte durch Drag &amp; Drop zusammenzustellen. Die
Reihenfolge der Werte kann dabei entsprechend ge&auml;ndert werden.
Es m&uuml;ssen keine Werte explizit vorgegeben werden, das Widget
kann auch ohne vorgegebenen Werte benutzt werden. Es k&ouml;nnen
eigene Werte zur Liste hinzugef&uuml;gt und einsortiert werden.
Das Ergebnis ist Komma-separiert entsprechend aufsteigend
sortiert.</li>
<li>Ist der Modifier ":sortable-strict,val1,val2,...", dann ist es
m&ouml;glich aus den gegebenen Werten eine Liste der
gew&uuml;nschten Werte durch Drag &amp; Drop zusammenzustellen. Die
Reihenfolge der Werte kann dabei entsprechend ge&auml;ndert werden.
Es k&ouml;nnen jedoch keine eigenen Werte zur Liste
hinzugef&uuml;gt werden. Das Ergebnis ist Komma-separiert
entsprechend aufsteigend sortiert.</li>
<li>Ist der Modifier ":sortable-given,val1,val2,...", dann ist es
m&ouml;glich aus den gegebenen Werten eine sortierte Liste der
gew&uuml;nschten Werte durch Drag & Drop zusammenzustellen. Es
k&ouml;nnen keine Elemente gel&ouml;scht und hinzugef&uuml;gt
werden. Es m&uuml;ssen alle gegeben Werte benutzt und entsprechend
sortiert sein. Das Ergebnis ist Komma-separiert entsprechend
aufsteigend sortiert.</li>
<li>In allen anderen F&auml;llen (oder falls der Modified explizit
mit :select anfaegt) erscheint ein HTML select mit allen Modifier
Werten.</li>

View File

@ -4,6 +4,7 @@
div.ui-dialog { border:3px solid white; padding: 0.2em; }
div.ui-dialog div.ui-dialog-titlebar { display:none; }
div.ui-widget-content { background:#444444; color:#CCCCCC; }
div.ui-widget-content a {color: #CCCCCC!important; text-decoration: none!important;}
.ui-widget { font-family:Arial,sans-serif!important; }
.ui-button-text { font-weight:normal!important; color:#555!important; }

View File

@ -80,6 +80,13 @@ select { margin-left:5px; margin-right:5px; }
border:2px solid; color:white; text-align:center; }
.downText,.makeSelect select { margin:0.7em; }
/* sortable Widget */
ul.sortable-src, ul.sortable-dest {min-width: 130px; min-height:1.8em; list-style-type: none;border: 2px solid white;vertical-align:middle; border-radius: 3px; margin: 3px; background: #aaa; padding: 2px;}
ul.sortable-src li, ul.sortable-dest li { color: black!important;font-size: 0.8em; line-height: 1.6em; white-space: nowrap; vertical-align:middle; text-align:left; border-radius:3px; margin: 3px; padding: 2px; padding-left:4px; min-width: 120px; }
ul.sortable-dest { background: #101010; }
span.sort-item-delete-link { float:right; margin:0px;vertical-align:middle; margin-left:3px; padding:0px;}
.ui-state-highlight { height: 1.1em; line-height: 1.1em; }
svg { height:32px; width:32px; fill:#fff; vertical-align:middle; margin:2px 0; }
g.on { fill:red; }

View File

@ -45,6 +45,30 @@ select.svgSrc { width:100px; }
select.svgColumn { width:50px; }
select.svgRegexp { width:120px; }
/* sortable Widget */
ul.sortable-src, ul.sortable-dest {
min-width: 130px; min-height:1.8em;
list-style-type: none;border: 2px solid black;
vertical-align:middle; border-radius: 3px; margin: 3px;
background: #eee; padding: 2px;
}
ul.sortable-src li, ul.sortable-dest li {
color: black!important;font-size: 0.8em;
line-height: 1.6em; white-space: nowrap;
vertical-align:middle; text-align:left;
border-radius:3px; margin: 3px; padding: 2px; padding-left:4px;
min-width: 120px;
}
ul.sortable-dest { background: #278727; }
span.sort-item-delete-link {
float:right; margin:0px;
vertical-align:middle;
margin-left:3px; padding:0px;
}
.ui-state-highlight { height: 1.1em; line-height: 1.1em; }
.handle { position:relative; cursor:pointer; width:50px;
height:20px; line-height:20px;
-webkit-user-select:none; -moz-user-select:none; -user-select:none;
@ -72,6 +96,7 @@ table#atWizard td:first-child { width: 240px; }
div.ui-dialog { border:3px solid #278727; padding: 0.2em; }
div.ui-dialog div.ui-dialog-titlebar { display:none; }
div.ui-widget-content { background:#FFFFE7; }
div.ui-widget-content a {color:#278727!important;}
.ui-widget { font-family:Arial,sans-serif!important; }
.ui-button-text { font-weight:normal!important; color:#555!important; }

View File

@ -0,0 +1,185 @@
// Wrapper for the widget.
FW_widgets['sortable'] = { createFn:FW_sortableCreate, };
FW_widgets['sortable-strict'] = { createFn:FW_sortableCreate, };
FW_widgets['sortable-given'] = { createFn:FW_sortableCreate, };
function
FW_sortableCreate(elName, devName, vArr, currVal, set, params, cmd)
{
if((vArr.length < 2 && (vArr[0] == "sortable-strict" || vArr[0] == "sortable-given")) || (vArr[0]!="sortable" && vArr[0]!="sortable-strict" && vArr[0]!="sortable-given") || (params && params.length)) return undefined;
var newEl = $('<input type="text" size="30" readonly>').get(0);
if(currVal)
$(newEl).val(currVal);
if(elName)
$(newEl).attr("name", elName);
newEl.setValueFn = function(arg){ $(newEl).val(arg) };
// replace # with space
for(var i1=1; i1<vArr.length; i1++)
vArr[i1] = vArr[i1].replace(/#/g, " ");
$(newEl).focus(function(){
var sel = $(newEl).val().split(","), selObj={};
// create the whole table output
var table = FW_sortableCreateTable(vArr, sel)
var strict = (vArr[0] == "sortable-strict" || vArr[0] == "sortable-given");
$('body').append(
'<div id="sortdlg" style="display:none">'+
'<table align=center">'+
table+
(!strict ? '<tr><td colspan="2" align="center"><br><input type="text" id="sort_new_item">&nbsp;&nbsp;<a href="#" id="sort_add_new_item">add</a></td></tr>' : '')+
'<tr><td colspan="2" align="center"><br>use drag & drop to sort items</td></tr>'+
'</table>'+
'</div>');
// make source list sortable
$( "ul.sortable-src").sortable({
connectWith: "ul.sortable-dest",
placeholder: "ui-state-highlight",
receive: function(event, ui) { FW_sortableSrcListSort(); },
stop: function(event, ui) { FW_sortableSrcListSort(); }
});
// make destination list sortable
$("ul.sortable-dest").sortable({
connectWith: "ul.sortable-dest",
placeholder: "ui-state-highlight",
stop: function(event, ui) { FW_sortableUpdateLinks(); },
create: function(event, ui) { FW_sortableUpdateLinks(); },
receive: function(event, ui) { FW_sortableUpdateLinks(); }
});
// add click handler for item removal in destination list
$('ul.sortable-dest').on("click", "a.sort-item-delete", function(event) {
var el = $(this).parents("li");
if(el.attr("key") !== undefined) {
el.appendTo("ul.sortable-src");
el.html(el.attr("value"));
}
else el.remove();
FW_sortableSrcListSort();
FW_sortableUpdateLinks();
});
// add click handler for quick add by click on list item in source list
$('ul.sortable-src').on("click", "li.sortable-item", function(event) {
$(this).appendTo("ul.sortable-dest");
FW_sortableUpdateLinks();
});
// add click handler for inserting a new custom value to destination list
$('a#sort_add_new_item').click(function () {
var new_val = $('input#sort_new_item').val().split(',');
$.each(new_val, function(index,value) {
var v = value.trim();
if(v.length)
{
$('ul.sortable-dest').append('<li class="sortable-item ui-state-default" value="'+v+'">'+v+'</li>');
$('input#sort_new_item').val('');
FW_sortableUpdateLinks();
}
});
});
// create the dialog
$('#sortdlg').dialog(
{ modal:true, closeOnEscape:false, maxHeight:$(window).height()*3/4, width:'auto', height:'auto',
buttons:[
{ text:"Cancel", click:function(){ $('#sortdlg').remove(); } },
{ text:"OK", click:function(){
var res=[];
$("#sortdlg ul.sortable-dest li.sortable-item").each(function(){
res.push($(this).attr("value"));
});
$('#sortdlg').remove();
$(newEl).val(res.join(","));
if(cmd)
cmd(res.join(","));
}}]}).focus();
});
return newEl;
}
// sort all items in source list according to their original given order
function
FW_sortableSrcListSort()
{
$('ul.sortable-src li.sortable-item').sort(function (a, b) {
return (($(a).attr("key") < $(b).attr("key")) ? -1 : ($(a).attr("key") > $(b).attr("key")) ? 1 : 0);
}).appendTo("ul.sortable-src");
}
// add index number and deletion link to all items in destination list
function
FW_sortableUpdateLinks()
{
$("ul.sortable-dest li.sortable-item").each(function () {
$(this).html(($(this).index() + 1)+'. '+$(this).attr("value")+($(this).attr("deletable") == "false" ? '' : '<span class="sort-item-delete-link"><a href="#" class="sort-item-delete"><span class="ui-icon ui-icon-closethick" style="display:inline-block;vertical-align:middle;"></span></a></span>'));
});
}
// create the inital html output
function
FW_sortableCreateTable(elements, selected)
{
var table = '<tr valign="top">';
if(elements[0] == "sortable" || elements[0] == "sortable-strict")
{
if(elements.length > 1)
{
table += '<td align="center">Available<br>';
table += '<ul class="sortable-src">';
for(var i=1; i<elements.length; i++) {
if($.inArray(elements[i], selected) == -1)
table+='<li class="sortable-item ui-state-default" key="'+i+'" value="'+elements[i]+'">'+elements[i]+'</li>';
}
table += '</ul></td>';
}
table += '<td align="center"><b>Selected</b><ul class="sortable-dest">';
for(var i=0; i<selected.length; i++) {
if(selected[i].trim().length)
table+='<li class="sortable-item ui-state-default" '+($.inArray(selected[i], elements) != -1 ? 'key="'+$.inArray(selected[i], elements)+'" ' : '')+'value="'+selected[i]+'">'+selected[i]+'</li>';
}
}
else if(elements[0] == "sortable-given")
{
table += '<td>&nbsp;</td><td align="center"><ul class="sortable-dest">';
if(selected.length > 1)
{
for(var i=0; i<selected.length; i++) {
if(selected[i].trim().length)
table+='<li class="sortable-item ui-state-default" deletable="false" value="'+selected[i]+'">'+selected[i]+'</li>';
}
}
else
{
for(var i=1; i<elements.length; i++) {
if(elements[i].trim().length)
table+='<li class="sortable-item ui-state-default" deletable="false" value="'+elements[i]+'">'+elements[i]+'</li>';
}
}
}
table += '</ul></td></tr>';
return table;
}