Variantenauswahl automatisch mit nächst möglichem Wert befüllen (Frontend)

Hallo zusammen,

im Forum und über Google bin ich bisher leider nicht explizit fündig geworden, vielleicht kann mir einer von Euch ein Modul empfehlen, das ich übersehen hab, oder hat etwas Ähnliches schon mal in einem Projekt umgesetzt.

Es geht um das Thema Variantenauswahl im Frontend auf der Artikeldetailseite. Bei Varianten mit mehreren Ausprägungen/Eigenschaften soll nach Auswahl des ersten Werts automatisch für die nächste Eigenschaft ein Wert ausgewählt sein, sofern es sonst keine anderen Ausprägungen zur Auswahl gibt usw.

Beispiel:

Vater-Artikel mit 5 Eigenschaften (Länge, Breite, Beschriftung, Material, Mengeneinheit), davon beispielhaft die folgenden Varianten.

  • Variante A: 100mm, 100mm, „Text“, Folie dünn, Rolle
  • Variante B: 100mm, 100mm, “Text B”, Folie dick, Rolle

Sobald die Länge (100mm) ausgewählt ist, sollte bei Breite automatisch der Wert 100mm ausgewählt sein, sofern das die einzig weitere freie Möglichkeit ist.

Jemand schon mal über sowas für OXID 6.x gestolpert oder umgesetzt?

Schon mal vielen Dank für Eure Antworten und Grüße
Romy

Ich hatte sowas ähnliches mal vor einer Weile in einem 4er Shop. Ich poste den Code mal hier ohne Gewähr und eher als Denk-Anstoß. Teile müssen wahrscheinlich auch noch an die neue v6-Konvention angepasst werden.

Ich habe die oxwarticledetails damals wiefolgt erweitert:

public function getProduct()
{
    $product = parent::getProduct();

    // Check for "single option" selections only for not full chosen variants
    if (!$product->isVariant() && !$this->checkedForSingleSelection) {
        // Get current selection and load the selection tree
        $sVarSelId = oxRegistry::getConfig()->getRequestParameter("varselid");
        $aVarSelections = $product->getVariantSelections($sVarSelId);

        // Foreach selection list check if there is exactly one selection available if not already active
        // if we find a selection list with only one available option we store this in the submitted varSelection array
        $selectionchanged = false;
        foreach($aVarSelections['selections'] as $key => $selectionlist) {
            if($selectionlist->getActiveSelection() !== null) {
                continue;
            }
            $availableSelection = null;
            $blOnlyOneAvailable = false;
            foreach ($selectionlist->getSelections() as $selection) {
                if(!$selection->isDisabled()) {
                    if(null !== $availableSelection) {
                        $blOnlyOneAvailable = false;
                        break;
                    } else {
                        $availableSelection = $selection->getValue();
                        $blOnlyOneAvailable = true;
                    }
                }
            }
            if($blOnlyOneAvailable) {
                $sVarSelId[$key] = $availableSelection;
                $selectionchanged = true;
            }
        }

        // if we found single options aka added a new entry to the var selection array we recalculate
        // and check if there is a variant active under these circumstances. In that case we use this variant.
        if($selectionchanged) {
            $sOxid = oxRegistry::getConfig()->getRequestParameter('anid');
            $newProduct = oxNew("oxarticle");
            $newProduct->load($sOxid);
            $aVarSelections = $newProduct->getVariantSelections($sVarSelId);
            if ($aVarSelections && $aVarSelections['oActiveVariant'] && $aVarSelections['blPerfectFit']) {
                $this->_oProduct = $aVarSelections['oActiveVariant'];
            }
        }

        $this->checkedForSingleSelection = true;
    }

    return $this->_oProduct;
}

Hoffe das hilft dir weiter…

Super, herzlichen Dank! Werde es die Tage mal testen.

1 Like

Hat perfekt funktioniert :slight_smile: Wie du erwähnt hast, musste ich an den passenden Stellen an die v6-Konvention anpassen, aber es funktioniert so, wie ich es mir vorgestellt habe.

Herzlichen Dank für Deine Unterstützung!

1 Like

Könntest du das für die Nachwelt noch hier posten?

1 Like

Hier der Code zur Anpassung von Application/Component/Widget/ArticleDetails:

public function getProduct() 
{
	$product = parent::getProduct();

	// Check for "single option" selections only for not full chosen variants
	if (!$product->isVariant() && !$this->checkedForSingleSelection) {
		// Get current selection and load the selection tree
		$sVarSelId = \OxidEsales\Eshop\Core\Registry::getConfig()->getRequestParameter("varselid");
		$aVarSelections = $product->getVariantSelections($sVarSelId);

		// Foreach selection list check if there is exactly one selection available if not already active
		// if we find a selection list with only one available option we store this in the submitted varSelection array
		$selectionchanged = false;
		foreach($aVarSelections['selections'] as $key => $selectionlist) {
			if($selectionlist->getActiveSelection() !== null) {
				continue;
			}
			$availableSelection = null;
			$blOnlyOneAvailable = false;
			foreach ($selectionlist->getSelections() as $selection) {
				if(!$selection->isDisabled()) {
					if(null !== $availableSelection) {
						$blOnlyOneAvailable = false;
						break;
					} else {
						$availableSelection = $selection->getValue();
						$blOnlyOneAvailable = true;
					}
				}
			}
			if($blOnlyOneAvailable) {
				$sVarSelId[$key] = $availableSelection;
				$selectionchanged = true;
			}
		}

		// if we found single options aka added a new entry to the var selection array we recalculate
		// and check if there is a variant active under these circumstances. In that case we use this variant.
		if($selectionchanged) {
			$sOxid = \OxidEsales\Eshop\Core\Registry::getConfig()->getRequestParameter('anid');
			$newProduct = oxNew(\OxidEsales\Eshop\Application\Model\Article::class);
			$newProduct->load($sOxid);
			$aVarSelections = $newProduct->getVariantSelections($sVarSelId);
			if ($aVarSelections && $aVarSelections['oActiveVariant'] && $aVarSelections['blPerfectFit']) {
				$this->_oProduct = $aVarSelections['oActiveVariant'];
			}
		}

		$this->checkedForSingleSelection = true;
	}

	return $this->_oProduct;
}

Was allerdings noch etwas holprig bzw. nicht gut funktioniert, ist das “Zurücksetzen” der Auswahl. D. h., wenn ich meine Auswahl mitten drin ändern möchte und bei eine der Eigenschaften wieder auf “Option auswählen” klicke, setzt es die Werte entweder gar nicht zurück oder stark verzögert.

Leider bin ich hier nicht ganz so versiert, sonst hätte ich noch ergänzt, dass alle folgenden Eigenschaften nach der “zurückgesetzten” Eigenschaft wieder den Wert “Option auswählen” erhalten.

Falls hier jemand eine Idee hat oder mir einen Hinweis geben kann, wäre ich dankbar.

1 Like

Der letzte Punkt hat sich erledigt - ich hatte selbst noch Anpassungen in der selectbox.tpl gemacht und hier genau diese Funktion überschrieben. War mein eigener Fehler :slightly_smiling_face: