Featurefrage/wunsch: Listen mit Mehrfachauswahl?

Begonnen von Reinerlein, 15 März 2017, 09:42:40

Vorheriges Thema - Nächstes Thema

Reinerlein

Hallo,

kann man mit FTUI Widgets auch Listen von mehrfach auswählbaren Elementen anzeigen?
Also im Prinzip eine Erweiterung der Combobox, welches die Darstellung nicht eingeklappt macht, und man halt mehrere Elemente aktivieren kann (z.B. über ein Checkbox-Widget).

Beispiel:
Ich habe in einem Reading eine separierte Liste von Werten (wie bei der Combobox z.B.). Diese sollen als sichtbare Liste (im Overflow dann auch mit Scrollbalken) dargestellt werden, deren Elemente einzeln an- oder abgeschaltet werden können (über sowas wie das Checkbox-Widget).
Das Widget kann am Besten bei jedem Ändern einer Checkbox die komplette Liste aktivierter Elemente an FHEM übertragen.

In meinem konkreten Usecase geht es um Sonosgruppen. Ich würde das gerne wie im Sonoscontroller anbieten, sodass ich die aktuelle Wiedergabe auf andere Player erweitern kann.
Dazu bräuchte ich dann eine Liste von meinen verfügbaren Playern, die ich beliebig an und abhaken kann.

Geht sowas schon irgendwie?

Danke schon mal im vorraus...

Grüße
Reiner

CoolTux

Ich melde mich da mal auch mit an. Bräuchte das ganze für das HEOS Multiroomsystem.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Standarduser

Wo seht Ihr denn den Vorteil einer solchen Liste gegenüber eines (beschrifteten) Push- oder Switch-Widgets?
Dass die Teilnehmer, und somit die Länge der Liste, dynamisch ermittelt und angepasst werden kann?

Reinerlein

Hi Standarduser,

genau. Selbst bei meiner Sonoslandschaft mit 4 Playern kann es mal sein, dass bereits andere Gruppen existieren, deren Player ich dann erstmal nicht in der Auswahl haben will. Außerdem muss man dann weniger anpassen, wenn sich was an der Zonenlandschaft ändert.

Außerdem habe ich noch einen weiteren Anwendungsfall: Singleauswahlmöglichkeit in der Liste. Das ist aber mehr eine Combobox ohne Combo (also ohne aufklappen). Das finde ich für eine Titelauswahl (für die ich gerade das Sonosmodul erweitere) optisch ansprechender.
Bei Favoriten und ähnlichem finde ich die Klappbox noch ok, auch wenn mir dort sowas wie ein inneres Image-Widget fehlt, da ich auch gerne Cover für jedes Element anzeigen würde...
Aber nicht alles auf einmal... das braucht Zeit :)

Grüße
Reiner

Standarduser

Klingt interessant. Ich suche auch noch eine Möglichkeit, mir die verfügbaren Playlisten anzeigen zu lassen.
Vielleicht kann man für solche Anwendungen auch das Medialist-Widget verwenden? Hat das schonmal jemand probiert?

setstate

Ich habe am WE mal angefangen auf Basis des Medialist Widgets eine Multiselect Checklist zu bauen. An/Wegklicken klappt schon mal, muss nur noch aufgehübscht werden und das Wegsenden der Liste eingebaut werden.

Reinerlein

Hi setstate,

das klingt doch super... danke schon mal :)

Grüße
Reinerlein

Standarduser

Super, danke setstate.
Seitdem Reinerlein hier danach gefragt habe ich auch schon mehrfach den Bedarf bei mir festgestellt.

Masterfunk

Damit könnte ich meinen letzten Wunsch bezüglich ftui dann auch umsetzen.
Ich warte mit großer Vorfreude.

Gruß Detlef

setstate

Kann aber noch dauern. Sorry!
Wie gesagt, bin ich gerade intensiv mit meinem ETS5 Projekt beschäftigt und es bleibt nur noch wenig Zeit. Es würde ganz viele WAF Minuspunkte hageln, wenn nach dem Umzug in die neue Wohnung die Bude kalt bleibt und das Licht nicht angeht.  :o

Standarduser

Hallo setstate,

ich wollte mal freundlich nachfragen, ob Du schon die Gelegenheit hattest, am Widget weiterzuarbeiten?

setstate

Gut, dass du nachfragst. Ist in totale Vergessenheit geraten.

Standarduser

Ich habe mir das jetzt auch schonmal angeschaut.

Ich für meinen Teil brauche eigentlich ein select, das wie eine Liste aussieht, ohne Mehrfachauswahl.
Dafür würde eigentlich das Einfügen von size="<Anzahl der Listeneinträge>" im HTML-Select-Element, sowie das weglassen der CSS-Klassen für das Select, und das hinzufügen einer anderen CSS-Klasse zur Formatierung reichen.
Kann man das noch in das Selectwidget integrieren oder macht da schon einen neues, jedoch sehr ähnliches Widget Sinn?

setstate

das size Attribute einzubauen, ist easy, aber das Style "abzuklemmen" ist nicht ohne. Es ist nicht nur eine Klasse für alles, sondern mehrere. Einfacher wäre, wenn man eine Extra-Klasse dem Widget hinzufügen würde und dann eine eigene CSS Definition dafür festzulegen.

Standarduser

Zitat von: setstate am 08 September 2017, 22:26:22
das size Attribute einzubauen, ist easy...

Für Dich vielleicht  ;D

Ich habe mich jetzt mal daran versucht.

Hab ganz oben var items_count; eingefügt und zähle das in der for-Schleife in function fillList(elem) { hoch, um die Anzahl der Elemente zu ermitteln und so die benötigte Anzahl der Zeilen festzulegen.
Dann wollte ich die Größe in der Zeile var select_elem = $('<select/>', {size: items_count}) in function init_ui(elem) { festlegen. Aber wie es aussieht sind die Elemente zu diesem Zeitpunkt noch garnicht eingefügt. Das zusätzliche Aufrufen von fillList(elem); hat auch nicht zum gewünschten Erfolg geführt.

Ich habe dann versucht, weiter unten mit setAttribute (und anderen Wegen, die ich ergoogeln konnte) das HTML-Attribut "size", items_count zu setzten - an verschiedenen Stellen. Aber weder wird items_count; überhaupt außerhalb der for-Schleife verändert, noch war es mir möglich, das Attribut, oder überhaupt nur irgendeine Klasse an <select> anzuhängen, obwohl es dazu unzählige Anleitungen im Netz gibt. Die Versuche hab ich jetzt wieder entfernt.

/* FTUI Plugin
* Copyright (c) 2015-2016 Mario Stephan <mstephan@shared-files.de>
* Under MIT License (http://www.opensource.org/licenses/mit-license.php)
*/

/* global ftui:true, Modul_widget:true */

"use strict";

var Modul_selectlist = function () {

var items_count;

    function fillList(elem) {
        var select_elem = elem.find('select');
        if (select_elem) {
            var items = elem.data('items') || '';
            var alias = elem.data('alias') || elem.data('items');
            select_elem.empty();
            for (var i = 0; i < items.length; i++) {
                select_elem.append('<option value="' + items[i] + '">' + (alias && alias[i] || items[i]) + '</option>');
                items_count = i;
            }
           
        }
    }

    function setCurrentItem(elem) {
        var value = elem.getReading('get').val;
        elem.find('select').val(value);
        elem.data('value', value);
    }

    function init_attr(elem) {
        elem.initData('get', 'STATE');
        elem.initData('set', ((elem.data('get') !== 'STATE') ? elem.attr('data-get') : ''));
        elem.initData('cmd', 'set');
        elem.initData('quote', '');
        elem.initData('filter', '');
        elem.initData('list', 'setList');
        elem.initData('delimiter', ':');

        me.addReading(elem, 'get');
        me.addReading(elem, 'list');
        if (elem.isValidData('alias') && !$.isArray(elem.data('alias'))) {
            me.addReading(elem, 'alias');
        }
    }

    function init_ui(elem) {
        // prepare select element
        elem.addClass('selectlist');
        var wrap_elem = $('<div/>', {}).addClass('selectlist_wrapper').appendTo(elem);
        fillList(elem);
        var select_elem = $('<select/>', {size: items_count})
            .on('change', function (e) {
                var value = $("option:selected", this).val();
                elem.data('value', elem.data('quote') + value + elem.data('filter') + elem.data('quote'));
                $(this).blur();
                elem.transmitCommand();
                elem.trigger('changedValue');
            })
            .appendTo(wrap_elem);       
        fillList(elem);
        elem.data('value', elem.data('quote') + $("option:selected", select_elem).val() + elem.data('quote'));
       
    }

    function update(dev, par) {
        // update from normal state reading
        me.elements.filterDeviceReading('get', dev, par)
            .each(function (index) {
                setCurrentItem($(this));
            });

        // update alias reading
        me.elements.filterDeviceReading('alias', dev, par)
            .each(function (index) {
                var elem = $(this);
                var delimiter = elem.data('delimiter');
                var items = elem.getReading('alias').val;
                if (ftui.isValid(items)) {
                    items = items.split(delimiter);
                    elem.data('alias', items);
                    fillList(elem);
                }
            });

        //extra reading for list items
        me.elements.filterDeviceReading('list', dev, par)
            .each(function (idx) {
                var elem = $(this);
                var delimiter = elem.data('delimiter');
                var items = elem.getReading('list').val;
                if (ftui.isValid(items)) {
                    if (elem.data('list') === 'setList') {
                        var setreading = (elem.data('set') === '') ? 'state' : elem.data('set');
                        items = items.split(' ');
                        var founditems = items;
                        $.each(items, function (key, value) {
                            var tokens = value.split(delimiter);
                            if (tokens && tokens.length > 1) {
                                if (tokens[0] == setreading)
                                    founditems = tokens[1].split(',');
                            }
                        });
                        items = founditems;
                    } else
                        items = items.split(delimiter);
                }
                elem.data('items', items);
                fillList(elem);
                setCurrentItem(elem);
            });
    }

    // public
    // inherit all public members from base class
    var me = $.extend(new Modul_widget(), {
        //override or own public members
        widgetname: 'selectlist',
        init_attr: init_attr,
        init_ui: init_ui,
        update: update,
    });

    return me;
};


Und das Debuggen erst  ::)
Normalerweise fällt mir die Programmierung verschiedenster Sprachen recht leicht, aber hier steig ich im Moment noch nicht durch.