Übersicht

Bei der Entwicklung von mobilen Anwendungen oder Anwendungen, die ein responsives Design mit Oracle ADF unterstützen, erhalten Sie manchmal die Aufgabe, eine Komponente so zu gestalten, dass sie wie die ursprüngliche mobile Komponente aussieht. Normalerweise sollte das bei der Verwendung von einfachem HTML kein Problem sein. Bei der Arbeit mit ADF allerdings, sind Sie in Bezug auf das Design einer Seite auf die Verwendung von Faces Components eingeschränkt.

Hier zeige ich Ihnen, wie man ein af:selectBooleanCheckbox wie einen IOS-Toggle-Button aussehen lässt. Zuerst müssen Sie einige Dinge über die JSF-Komponenten wissen, vor allem das HTML, welches sie generieren, wenn sie in Browsern gerendert werden. Für af:selectBooleanCheckbox lautet das HTML:

 

startingHTML

Der JSF-Code sieht folgendermaßen aus:

<af:selectBooleanCheckbox id="sbc1" autoSubmit="true" styleClass="toggle-button toggle-button-js" clientComponent="true"/>

Die gerenderte Komponente sieht wie folgt aus:

startingImage

Das erzeugte HTML ändern

Wir haben zwei Style-Klassen auf der Komponente, Toggle-button Toggle-button-js, da auf die erste durch die Skin verwiesen wird und auf die andere durch Javascript-Funktion. Wird die Komprimierung der Inhalte aktiviert, verhält sich ADF so, dass es die Klassen komprimiert, auf die von einer Skin-Datei aus verwiesen wird, und diejenigen beibehält, bei denen das nicht der Fall ist.

Zuallererst müssen wir die HTML-Datei modifizieren, die gerendert wird, um zwei <label>-Elemente neben dem generierten <input>-Element hinzuzufügen. Leider gibt es keine JSF-Komponente, die dies tun kann. Daher müssen wir Javascript verwenden, um das gewünschte Konstrukt zu bekommen:

function insertToggleLabel(selector) {
    $(selector).each(function () {
        var clientId = $(this).attr("id");
        var clientComp = document.getElementById(clientId);

        var hasToggleInserted = $(clientComp).attr("insert_toggle");
        if(!hasToggleInserted || hasToggleInserted == undefined) {
            $(this).after("<label for=\"" + $(this).attr("id") + "\" class=\"db-toggle-bg\"><\/label>");
            $(this).after("<label for=\"" + $(this).attr("id") + "\" class=\"db-toggle-label\"><\/label>");
            $(clientComp).attr("insert_toggle", "true");
        }
    });
}

function init() {
  insertToggleLabel('.toggle-button-js input');
};

Das entstandene HTML sieht wie folgt aus:

jsHTML

Die Komponente gestalten

Wir können die Kennzeichnungselemente verwenden, um die Schaltfläche und den Hintergrund zu erstellen. Das machen wir mit CSS:

.db-toggle-bg {
    width: 28px;
    height: 16px;
    display: inline-block;
    background: white;
    border-radius: 50px;
    border: solid 1px #d3d3d3;
    position: absolute;
    left: 0px;
    top: 0px;
    z-index: 1;
}

.db-toggle-label {
    width: 16px;
    height: 16px;
    background: white;
    border-radius: 50px;
    border: solid 1px #a9a9a9;
    position: absolute;
    left: 1px;
    top: 0px;
    z-index: 2;
    transition: all .2s ease;
    -webkit-transition: all .2s ease;
}

Dies sieht dann wie folgt aus:

renderedButton

Nun können wir CSS verwenden, um die Schaltfläche über das Kontrollkästchen zu positionieren und es auszublenden, sodass das Kontrollkästchen beim Klick auf die Schaltfläche durch den Nutzer aktiviert ist. Wir fügen auch Styling hinzu, sodass sich die Hintergrundfarbe und die Position der Schaltfläche ändern, wenn die Taste umgeschaltet wird:

af|selectBooleanCheckbox.toggle-button .AFContentCell {
    vertical-align: middle;
}

af|selectBooleanCheckbox.toggle-button::content {
    width: 30px;
    height: 18px;
    display: inline-block;
    position: relative;
    top: 2px;
}

af|selectBooleanCheckbox.toggle-button::native-input:checked {
    left: 12px;
}

af|selectBooleanCheckbox.toggle-button::native-input:checked + label {
    left: 12px;
    border-color: #0592D0;
}

af|selectBooleanCheckbox.toggle-button::native-input:checked + label + label {
    background: #0592D0;
    border-color: #0592D0;
}

af|selectBooleanCheckbox.toggle-button::native-input {
    visibility: hidden;
    width: 16px;
    height: 16px;
    z-index: 3;
    position: absolute;
    left: 0px;
    top: 0px;
    margin: 0px;
}

Der Toggle-Button sie folgendermaßen aus:

buttonFinished

Eine Einbindung ist auch in af:panelLabelAndMessage-Komponente möglich, um eine Kennzeichnung davor zu haben:

buttonFinal