> ## Documentation Index
> Fetch the complete documentation index at: https://dokumentation.websale.de/llms.txt
> Use this file to discover all available pages before exploring further.

# Cross-Link-Set

> Wie Sie in WEBSALE V8s zusammenpassende Produkte als Shop-the-Look-Set vorschlagen, aus dem der Käufer einzelne Teile abwählen und den Rest auf einmal bestellen kann.

Ein Cross-Link-Set schlägt dem Käufer zusammenpassende Produkte als Zusammenstellung vor, die er mit einem Klick bestellt. Verbreitet ist das bei Bekleidung unter dem Namen "Shop the Look".

Das Set wirkt wie eine Schaufensterpuppe: Es zeigt eine Idee, verpflichtet aber zu nichts. Über Checkboxen wählt der Käufer einzelne Teile ab, und je Teil kann er eine Eigenschaft wählen, beispielsweise die Größe.

Im Warenkorb landen nur die ausgewählten Einzelprodukte. Das Set selbst erscheint dort nicht.

![Outfit Sets](https://mintcdn.com/websaleag-44ee7ea6/98HtpcQDYdzjmpoC/images/outfit-sets.png?fit=max\&auto=format\&n=98HtpcQDYdzjmpoC\&q=85\&s=6698be6741e0aca9963aa205366e0ead)

![Outfit Sets Wk](https://mintcdn.com/websaleag-44ee7ea6/98HtpcQDYdzjmpoC/images/outfit-sets_wk.png?fit=max\&auto=format\&n=98HtpcQDYdzjmpoC\&q=85\&s=bfef6e8dbb5200693d8e8182de4a6b1e)

Die Einzelprodukte bleiben eigenständige Produkte. Sie stehen weiterhin in ihren Kategorien, sind über die Produktsuche auffindbar und einzeln bestellbar. Das Set fasst sie nur zusätzlich zusammen.

## Abgrenzung zu Set-Produkten

| | Cross-Link-Set | Set-Produkt mit fester Zusammenstellung |
| - | - | - |
| Zusammenstellung | Vorschlag, Teile abwählbar | fest, nur komplett bestellbar |
| Im Warenkorb | die Einzelprodukte | das Set als eine Position |
| Preis | Summe der gewählten Teile | Setpreis oder Summe der Teile |

Wegweiser: [Set-Produkte mit fester Zusammenstellung](https://dokumentation.websale.de/v8s/set-produkte/set-produkte-mit-fester-zusammenstellung.md)

## Cross-Link-Set anlegen

Ein Cross-Link-Set besteht aus einem Pseudo-Produkt und den ihm zugewiesenen Cross-Link-Produkten.

### Schritt 1: Pseudo-Produkt anlegen

Das Pseudo-Produkt repräsentiert das Set im Shop, also die Schaufensterpuppe. Geben Sie ihm einen Produktnamen, im folgenden Beispiel "Outfit Tiffany", Produktbilder und eine Beschreibung.

> [!WARNING]
>
> Legen Sie das Pseudo-Produkt ohne Varianten an und setzen Sie das Flag "Bestellbar: nein". Es soll selbst nicht im Warenkorb landen, sondern nur seine Bestandteile.

### Schritt 2: Als Cross-Link-Set kennzeichnen

Damit das Template Cross-Link-Sets von normalen Produkten unterscheiden kann, brauchen sie eine Kennzeichnung. Tragen Sie dafür in einem beliebigen freien Produktdatenfeld einen Wert ein, im Beispiel im Feld `IS_Zusatz0` den Wert `Outfit`.

Ohne diese Kennzeichnung lässt sich die Set-Darstellung im Template nicht gezielt ansteuern.

### Schritt 3: Cross-Link-Produkte zuweisen

Weisen Sie dem Pseudo-Produkt beliebig viele Cross-Link-Produkte zu. Das entspricht dem Einkleiden der Schaufensterpuppe.

Jedes zugewiesene Produkt ist ein eigenständiges Einzelprodukt und braucht Namen, Produktnummer, Preis und eigene Produktbilder.

> [!WARNING]
>
> Die Einzelprodukte dürfen höchstens eine Variante haben, beispielsweise Größe oder Farbe. Bei mehr als einer Variante kann es zu Fehlern kommen, und die Bestellung des kompletten Sets ist unter Umständen nicht mehr möglich.

Wegweiser: [Zubehörprodukte (Cross-Links) anzeigen](https://dokumentation.websale.de/v8s/zusatz-produkte/zubehoerprodukte-cross-links.md)

### Schritt 4: Preis des Sets

Im Warenkorb ergibt sich der Preis von selbst, denn dort liegen die Einzelprodukte mit ihren eigenen Preisen.

Auf den Seiten davor, beispielsweise der Produktübersicht `ws_category.htm`, gibt es diese Summe noch nicht. Damit dort ein Gesamtpreis erscheinen kann, rechnen Sie die Summe der zugeordneten Produkte aus und tragen sie am Pseudo-Produkt in das Standardfeld `Price` ein.

> [!WARNING]
>
> Dieser Preis wird nicht automatisch nachgeführt. Ändert sich der Preis eines zugewiesenen Einzelprodukts, müssen Sie die Summe am Pseudo-Produkt von Hand anpassen. Andernfalls weicht der angezeigte Setpreis vom tatsächlichen Warenkorbwert ab.

Auf der Produktdetailansicht rechnet dagegen ein JavaScript mit, sobald der Käufer Teile abwählt. Das folgende Kapitel zeigt es.

## Cross-Link-Set auf der Produktdetailansicht integrieren

### Schritt 1: Sets von normalen Produkten unterscheiden

Das freie Feld aus Schritt 2 dient als Weiche. Der Tagname folgt der üblichen Regel, also Präfix `PR-` und technischer Feldname.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{PR-Data}

   {!PR-IS_Zusatz0}
      Gestaltung Ihrer normalen Produkte
   {/!PR-IS_Zusatz0}

   {PR-IS_Zusatz0}
      Gestaltung Ihres Cross-Link-Sets
   {/PR-IS_Zusatz0}

{/PR-Data}
```

### Schritt 2: Systembibliothek und Design-Komponente einbinden

Das JavaScript im nächsten Schritt setzt beide voraus. Prüfen Sie, ob sie auf der Produktdetailansicht eingebunden sind.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<head>
   ...
   <script type="text/javascript" src="/$WS/ws_sysdata/js/ws-system-1.8.3.js"></script>
   <script type="text/javascript" src="../<Ihr Verzeichnis>/ws-design-1.8.3.js"></script>
   ...
</head>
```

Materialien: [WEBSALE JavaScript-Bibliothek](https://dokumentation.websale.de/v8s/materialien/websale-javascript-bibliothek.md)

### Schritt 3: JavaScript einfügen

Die Funktion berechnet den Gesamtpreis der noch angehakten Produkte neu. Sie gehört in den `<head>`, nach der Systembibliothek und der Design-Komponente, und nur für Cross-Link-Sets.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<head>
   ...
   {PR-Data}
   {PR-IS_Zusatz0}

   <script type="text/javascript">
   function recalcClinkSum(id)
   {
      var i;
      var sum = 0;
      var t1;
      var t2;
      var p;
      var c;
      var t3;

      // Setzen des Eingabefelds, wenn erforderlich
      if (id > 0)
      {
         t1 = "#clink_input_" + id;
         t2 = $(t1);
         if (t2.length > 0)
         {
            if (parseFloat(t2.val()) > 0)
               t2.val('0');
            else
               t2.val('1');
         }
      }

      {!WS-OTP1(recalc)}
      else
      {
         for (i = first_clinks_index + 1; i < 100; i++)
         {
            t1 = "#clink_input_" + i;
            t2 = $(t1);
            if (t2.length == 0)
               break;
            t2.val('1');
         }
      }
      {/!WS-OTP1(recalc)}

      // Preis berechnen, Auswahl pruefen CheckBox gegen InputFields
      for (i = first_clinks_index + 1; i < 100; i++)
      {
         t1 = "#clink_input_" + i;
         t2 = $(t1);
         if (t2.length == 0)
            break;
         c = parseFloat(t2.val());
         t1 = "#clink_price_" + i;
         t2 = $(t1);
         if (t2.length == 0)
            break;
         t3 = t2.val();
         p = parseFloat(t3.replace(/,/, "."));
         t1 = "#clink_check_" + i;
         t2 = $(t1);
         if (c > 0)
         {
            var tmpPrice = (p * c).toFixed(2);
            tmpPrice = parseInt(tmpPrice.replace(".", ""));
            sum = (tmpPrice + sum);
            t2.attr("checked", "checked");
         }
      }

      sum = sum / 100;
      t3 = "" + sum;
      sum = t3.replace(/\./, ",");
      if (sum.lastIndexOf(",") < 0)
         sum += ",00";
      else if (sum.lastIndexOf(",") == (sum.length - 2))
         sum += "0";
      if (sum.lastIndexOf(",") < (sum.length - 3))
         sum = sum.substring(0, sum.lastIndexOf(",") + 3);
      $('#clink_sum').html('' + sum);
   }

   $(document).ready(function()
   {
      recalcClinkSum(0);
   });
   </script>

   {/PR-IS_Zusatz0}
   {/PR-Data}
   ...
</head>
```

Die Funktion rechnet in Cent, um Rundungsfehler zu vermeiden, und formatiert am Ende auf zwei Nachkommastellen mit Komma als Trennzeichen.

Die Klammerung `{!WS-OTP1(recalc)}` umschließt den Zweig, der beim ersten Aufruf alle Teile anhakt. Beim Neuberechnen nach einem Klick wird der Parameter `otp1` mit dem Wert `recalc` mitgeschickt, und der Zweig entfällt, damit die Auswahl des Käufers erhalten bleibt.

### Schritt 4: Set im Template ausgeben

Alle Teile sind standardmäßig angehakt, sodass der Käufer das ganze Set mit einem Klick bestellt. Abwählen kann er über die Checkbox.

Die Zuordnung zwischen Checkbox, Mengenfeld, Preis und JavaScript läuft über durchnummerierte IDs, die aus [`WS-Counter`](https://dokumentation.websale.de/v8s/referenz/tags/ws/shop-seite-und-technik#die-tags-im-uberblick) und [`WS-CounterInc`](https://dokumentation.websale.de/v8s/referenz/tags/ws/shop-seite-und-technik#die-tags-im-uberblick) entstehen.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{PR-Data}
   {PR-IS_Zusatz0}
      <form action="~FORM-Product~" method="post" name="product" id="productform">

         {WS-TplComment}<!-- Informationen des Pseudo-Produkts -->{/WS-TplComment}
         {PR-Image}<img src="~PR-Image~" alt="~PR-Name_StripHtml~">{/PR-Image}
         ~PR-Name~

         {WS-TplComment}<!-- Cross-Link-Produkte mit Checkbox -->{/WS-TplComment}
         {CAT-AdvData($C-Links,999)}

            <script type="text/javascript">
               var first_clinks_index = ~WS-Counter~;
            </script>
            <input type="hidden" name="otp1" value="recalc">

            {@PR-Data}
               {PR-MiniThumbnail}<img src="~PR-MiniThumbnail~" alt="~PR-Name_StripHtml~">{/PR-MiniThumbnail}
               <input type="hidden" name="~PR-Quantity_Input~" value="~PR-Quantity~" id="clink_input_~WS-CounterInc~">
               <input type="checkbox" id="clink_check_~WS-Counter~" onClick="recalcClinkSum(~WS-Counter~);">
               <input type="hidden" id="clink_price_~WS-Counter~" value="~PR-Price~">
               ~PR-Name~
               {PR-DepVariationName1}~PR-DepVariationList1~{/PR-DepVariationName1}
               ~PR-Price~ ~WS-CurrencySymbol~
               <a href="~PR-Link~">zur Detailansicht dieses Produkts</a>
            {/@PR-Data}

         {/CAT-AdvData($C-Links,999)}

         {WS-TplComment}<!-- Gesamtpreis und Bestellbutton -->{/WS-TplComment}
         Gesamtpreis: <span id="clink_sum">~WS-TotalProductPrice~</span> ~WS-CurrencySymbol~
         <input type="submit" value="Outfit bestellen"
                onclick="return ws_AJAXaddToBasket('productform', '~BT-ProductAddToBasket_Ajax~', '~WS-Charset~')">

      </form>
   {/PR-IS_Zusatz0}
{/PR-Data}
```

> [!WARNING]
>
> Die IDs `clink_input_`, `clink_check_`, `clink_price_` und `clink_sum` sowie die Variable `first_clinks_index` sind fest mit dem JavaScript verdrahtet. Benennen Sie sie nicht um und entfernen Sie sie nicht.

Erscheinen die Cross-Link-Produkte nicht, prüfen Sie, ob die Produkte tatsächlich über die Cross-Link-Liste zugewiesen sind. Wird eine andere Produktliste verwendet, passen Sie den Index `$C-Links` in der Klammerung [`CAT-AdvData()`](https://dokumentation.websale.de/v8s/referenz/tags/cat/navigation-und-kategoriebaum#die-tags-im-uberblick) entsprechend an, beispielsweise auf `$C-Links2`.

## Verwandte Themen

* Wegweiser: Zubehörprodukte (Cross-Links) anzeigen
* Wegweiser: [Set-Produkte mit fester Zusammenstellung](https://dokumentation.websale.de/v8s/set-produkte/set-produkte-mit-fester-zusammenstellung.md)


## Related topics

- [Zubehörprodukte (Cross-Links)](https://dokumentation.websale.de/v8s/zusatz-produkte/zubehoerprodukte-cross-links.md)
- [Meta-Felder](https://dokumentation.websale.de/v8s/schnittstellen/produkte-und-kategorien/ws-sftp-produkte-pro/meta-felder.md)
- [econda Cross Sell](https://dokumentation.websale.de/v8s/integration-von-econda/econda-cross-sell.md)
- [Navigation und Kategoriebaum](https://dokumentation.websale.de/v8s/referenz/tags/cat/navigation-und-kategoriebaum.md)
- [Mehrverkauf](https://dokumentation.websale.de/v8s/marketing-produkte/mehrverkauf.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.