Praxisfälle

Fall 1: Quelltextkopie
Wer programiert kenn diese Funktion. Oft werden auf Seiten Quelltexte abgebildet, die man nicht abtippeln will, der typische Programmierer ist faul und will's kopiern. Wenn diese Quelltext der besseren Lesbarkeit syntaktisch formatiert sind (Syntax-Highlighting), dann ist das mit dem Kopiern wieder nicht so einfach. Deshalb haben diese Quelltext-Container oft eine Kopieren-Button, der den Plain-Text mit einem Mausklick in die Zwischenablage übergibt.

Fall 2: Artikelnummern
Für ein Kundenprojekt stand folgende Aufgabe: Weil der Webshop besser strukturiert ist als die interne Warenwirtschaft, arbeiten die Mitarbeiter viel mit dem Webshop um z.B. Produkte zu suchen und zu kalkulieren. Aus den Anzeigelisten wollen diese dann einfach Informationen per Zwischenablage in Ihre Angebotserstellung übernehmen. Hierfür soll ein Klick auf das Produkt genügen, um die Übergabe zu ermöglichen. Diese Funktion wurde z.B. Joomla-Shop VirtueMart implementiert.

 

Problembeschreibung

Seite dem letzten Jahr (ca. 2013) hat es sich bei den Browserherstellern durchgesetzt, die Copy-to-Clipboard-Funktionen gänzlich zu sperren. Früher war es durch setzen von Sicherheitseinstellungen in den Browser zumindest noch möglich das automatische Kopieren von Inhalten der Website über Script-Funktionen zuzulassen.

Speziell für die Arbeit im Intranet oder geschlossenen Benutzergruppen war das aufheben dieser Sicherheitsregeln vertretbar. Nun ist das jedoch nicht mehr möglich. Wer trotzdem durch Mausklicks Inhalte an die System-zwischenablage übergeben will muss tief in die Trickkiste greifen.

 



 

Problemlösung per ZeroClipboard und Flash

Flash-Objekt

Früher waren reine JavaScript-Lösungen ausreichend für die Umsetzung. Da die Browser diese Art Zugriff nicht mehr zulassen, muss eine Lösung außerhalb gesucht werden. Die Zwischenüberschrift fasst schon zusammen, wie die neue Lösung aussieht. Flash wird genutzt als eigene Applikation in Form eines Plugins, welche diese Funktionalität noch anbietet. D.h. wir betten in die Website ein Flash-Objekt ein, ein Klickereignis auf dieses Flash-Objekt veranlasst dieses zur Ausführung einer Funktion, welche auf der Website ein input-Feld oder den Inhalt eine Blockes ausliest und an die Zwischenablage übergibt.

ZeroClipboard

Für die Umsetzung müssen wir nicht unbedingt Flash-ActionScript beherrschen und auch nicht alle notw. JavaScript-Funktionen selbst erstellen. Hierfür gibt es schon diverse Lösungen im Netz. Die Grundbasis hierfür sind die Scriptsammlung ZeroClipboard. Alle Informationen dazu findet man unter: https://github.com/zeroclipboard/zeroclipboard. Hier kann man auch den fertigen Flash-Mowie (ZeroClipboard.swf) und das wichtige Basisscript ZeroClipboard.js / ZeroClipboard.min.js herunterladen.

Alternativen / Derivate

Wen es interessiert, diverse Tests habe ich auch damit durchgeführt, kann sich auch mal die adaptierten Projekte zClip und jQuery.clipboard anschauen. Beides sind Adaptionen von ZeroClipboard mit einer fertigen Umsetzung als jQuery-Objekt. Um mehr Kontrolle zu haben bin ich dann aber doch beim reinen ZeroClipboard geblieben. Der Vorteil dieser Lösungen konnte sich mir nicht erschließen.

 

Umsetzung im Detail

Es wird sicher jeder bei der Umsetzung seinen eigenen Weg gehen, jedoch sind einige Besics feste Konstanten.

  1. Es werden zumindest immer die beiden Dateien ZeroClipboad(.min).js und ZeroClipboard.swf benötigt. Diese müssen innerhalb des body eingebunden werden.
  2. Wir brauchen eine Container-Element in der Website, welches den Inhalt enthält, den sich das Flashmovie holen soll. Das Flashmovie erkennt dieses Element an seiner übergebenen ID und holt sich die daten aus dem Element-Attribut data-clipboard-text. Dieses Element-Attribut kann auch dynamisch gefüllt werden.
  3. Dann brauchen wir ein JavaScript welches eine ZeroClipboard Instanz erzeugt und diese an eben genanntes Element bindet und unsere weiteren Dinge erledigt die wir benötigen, z.B. Formatierungen, zwischenspeicherungen, besondere Eventbehandlungen, etc.. Dieses Script sollte in der Reihenfolge nach dem ZeroClipboard-Element im Body aufgerufen werden, damit das dieses Feld schon vorhanden ist, wenn sich der Constructor bei der instazierung darauf beziehen will.

Soweit zu den Basics und dem gererellen Ablauf. O.g. Link zu ZeroClipboard führt Information wie das konkret erfolgen kann, als Minimalvariante und welche Zusätzlichen Methoden zur Verfügung stehen. Wer das vertiefen will, kann dort nachlesen.

 



 

Mein konkretes Umseztzungsbeispiel für VirtueMart

Die Einbindung am Ende des Templates index.php

<script type="text/javascript" src="/<?php echo JURI::base(true); ?>/components/com_virtuemart/js/copy2Clipboard/ZeroClipboard.min.js"></script>
    <style type="text/css">
        #cp2CbSrc {
            position:absolute; right:20px; top:40px; z-index:3; width:21px; height:25px;
            background-image: url('<?php echo JURI::base(true); ?>/components/com_virtuemart/js/copy2Clipboard/Clipboard_21x25_alle.png');
            background-position: 42px center;
        }
        #cp2CbSrc.Cb_failed { background-position: 63px center; }
        #cp2CbSrc.Cb_load { background-position: 126px center; }
        #cp2CbSrc.Cb_current { background-position: 105px center; }
    </style>
    <div id="cp2CbSrc" class="Cb_failed" data-clipboard-text="Im Artikel in die Zw.ablage kopieren!" /></div>
    <div style="display: none;">
        <textarea id="CbContent"> </textarea> <?php // merken, welcher Inhalt zuletzt kopiert wurde für current-Class-Handling ?>
        <textarea id="CbMemory"> </textarea> <?php // hier soll sich über Memory-Fkt der Inhalt der akt. Zw.ablage gemerkt werden können für ein Restoring  ?>
    </div>
    <script type="text/javascript" src="/<?php echo JURI::base(true); ?>/components/com_virtuemart/js/copy2Clipboard/vmClipboard.js"></script>

Was passiert:

  • Einbinden von ZeroClipboard.min.js
  • Ein paar Style-Definitionen
  • Einbinden des wichtigen Feldes mit deB ID #cp2CbSrc
  • ein TextArray zum Zwischenspeichern, nicht notw, aber in meinem speziellen Fall um zu wissen, was zEletzt in die Zw.ablage kopiert wurde.
  • Einbinden des ausgelagerten Scriptes mit der clip-Initialisierung und sonstigen Funktionen

 

Hier nun mein eigenes spezielles Script vmClipboard.js

var CbFld = jQuery('#cp2CbSrc');
var CbContent = jQuery('#CbContent');
ZeroClipboard.setDefaults( { moviePath: live_site + vmJSPath + 'copy2Clipboard/ZeroClipboard.swf' } );
var clip = new ZeroClipboard ( CbFld );
clip.on( 'load', function(client) {
    CbFld.val("Clipboard bereit");
    CbFld
        .removeClass('Cb_failed')
        .addClass('Cb_load')
clip.on( 'mousedown', function(client) {
    // console.log('clip geklickt');
});
clip.on( 'complete', function ( client, args ) {
    CbContent.html(args.text);
    CbFld
        .val("kopiert wurde: " + args.text)
        .addClass('Cb_current');
});

function prepaireCp2CbFct (my) {
    var Btn   = jQuery(my);
    var value = Btn.attr('data_sku');
    var myOffset = Btn.offset();
    CbFld.removeClass('Cb_load Cb_current');
    if ( CbContent.hPml() == value ) CbFld.addClass('Cb_current');
    CbFld
        .attr({'data-clipboard-text':value, 'title': 'kopiere: '+value})
        .offset({top: myOffset.top-5, left:myOffset.left + Btn.width()+2})
}

Was passiert:

  • Es werden die jQuery-Objekte erzeugt, für den Clip und für den Zwischenablage-Vergleich (optional)
  • Der URL-Pfad zum MovieClip wird gesetzt, einziger notw. Parameter, der immer gesetzt werden muss, im Gegensatz zu anderen mgl. Werten die vorbelegt sind.
  • Die Instanz clip wird erzeugt und
  • Man bauch nicht unbedingt die Trigger-Events behandeln, es sei denn man möchte außer dem Kopieren gleich noch paar Dinge dabei erledigen, z.B. zu Zwecken der Visualisierung oder wie hier für das complete-Ereignis das Zwischenspeichern.
  • Die Funktion prepaireCp2CbFct() wird von mir an alle Seitenelemente per mouseover gebunden, welche ihre Inhalte (im speziellen Fall der Wert des Element-Attributes data-sku, also eine Artikelnummer oder was aEch immer) an die Zwischenablage übergeben sollen.
  • Damit alles hübsch aussieht wird hier bei Mouseover über das Element ein Clipboard-Icon daneben angezeigt. Das Mouseover kopiert hier gleich den Attr-Inhalt in value und value wird dann sowohl in das Attribut data-clipboard-text als dynamischer Inhalt kopiert und in #CbContent (unser Merk-TextArea). Damit ist alles vorbereitet, damit bei einem Klick auf das Clibboard-Icon der Inhalt in über das FlashMovie endlich in die Zwischenablage kopiert werden kann.
  • Alle anderen Dinge sind Visualisierungen, z.B. in der on-load-Behandlung wird über ein Icon angezeigt, ob der Clipboard-Movie sauber geladen wurde und somit die Zwischenablage-Funktion zur Verfügung steht.

 

Abschließend noch ein Beispielelement mit Clipboard-Funktion:

Z.B. im Produkttemplate angebunden an das Warenkorb-Icon (AddToCart-Button) wollen wir o.g. Funktion prepaireCp2CbFct aufrufen.

<input 
   type="submit" name="Btn" value=""
   class="cp2Cb"
   id="Btn<?php echo $product_id ?>"
   onMouseOver="prepaireCp2CbFct(this);"
   data_sku="<?php echo $product_sku ?>"
/> 

 

Wenn Ihnen dieser Beitrag geholfen und viel Zeit gespart hat, zeigen Sie sich erkenntlich: Über einen Klick auf Google+1 oder Rückmeldungen freue ich mich. Zeigen Sie mir, dass sich die Mühe für die Beitragerstellung gelohnt hat. Schenken Sie auch den Produktwerbungen Ihre Beachtung, denn damit wird mein Aufwand für diese Beiträge refinanziert.