Skip to main content

Restrict custom field to product variant

More
1 year 5 months ago #366496 by arnask
Hello, i need to show custom field only on special product variant, not just for whole product, but for one or couple of variants. How to do that?

Please Log in or Create an account to join the conversation.

More
1 year 5 months ago #366498 by nicolas
Hi,

If you have a custom field of the table "product" and you configure different values for it in different variants of the product in the backend, the system will automatically refresh the displayed value of that custom field on the frontend when you change the variant.

If you're talking about a custom field of the table "item", which you want to be available only for some variants of the product, there is no option to do that. Now, it's not impossible, but it requires to add some custom code. Here is a subject where someone else did it :
www.hikashop.com/forum/product-category-...characteristics.html

Please Log in or Create an account to join the conversation.

More
1 year 5 months ago #366512 by arnask
My custom field is in table "order"

Please Log in or Create an account to join the conversation.

More
1 year 5 months ago #366513 by nicolas
Hi,

For a custom field of the table "order", you'll want to customize the file checkout / show_block_fields via the menu Display>Views.
There, you'll want to take into account the product objects in $cart->products to skip or not the display of the fields.

Please Log in or Create an account to join the conversation.

More
1 year 5 months ago #366590 by arnask
Can you give some example, course for me its too complicated

Please Log in or Create an account to join the conversation.

More
1 year 5 months ago #366592 by nicolas
Well, something like that at the beginning (not tested):
Code:
<?php // check if the products with the id XX or YY or ZZ are in the cart $found = false; foreach($cart->products as $product) { if(in_array($product->product_id, array(XX, YY, ZZ))) { $found = true; } } // if none of them are in the cart, remove the field AA from the array of fields to be displayed if(!$found) { foreach($cart->order_fields as $k => $field) { if($field->field_namekey == 'AA') { unset($cart->order_fields[$k]); break; } } } ?>

Please Log in or Create an account to join the conversation.

More
1 year 5 months ago - 1 year 5 months ago #366595 by arnask
I have managed to get this code (show_block_fields.php) with help of chatgpt:
Code:
<?php /** * @package HikaShop for Joomla! * @version 5.1.5 * @author hikashop.com * @copyright (C) 2010-2025 HIKARI SOFTWARE. All rights reserved. * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html */ defined('_JEXEC') or die('Restricted access'); $cart = $this->checkoutHelper->getCart(); if(!hikashop_level(2)) { $this->emptyBlocksCount++; return; } // Check wheather there is products 78 or 79 in cart $target_ids = array(78, 79); $found = false; if (!empty($cart->products) && is_array($cart->products)) { foreach ($cart->products as $product) { if (in_array((int)$product->product_id, $target_ids)) { $found = true; break; } } } $fields = null; if (!empty($cart->order_fields)) { $fields = hikashop_copy($cart->order_fields); } // If there are none of products 78 or 79 in cart we hide field "sleepwith" if (!$found && !empty($fields)) { foreach ($fields as $k => $field) { if (isset($field->field_namekey) && $field->field_namekey === 'sleepwith') { unset($fields[$k]); // Pašalina tik "sleepwith" lauką break; } } } // If there is 78 or 79 in cart, make "sleepwith" field reguired if ($found && !empty($fields)) { foreach ($fields as $k => $field) { if (isset($field->field_namekey) && $field->field_namekey === 'sleepwith') { $field->field_required = 1; // Padarome lauką privalomu break; } } } $labelcolumnclass = 'hkc-sm-4'; $inputcolumnclass = 'hkc-sm-8'; if(empty($this->ajax)) { ?> <div id="hikashop_checkout_fields_<?php echo $this->step; ?>_<?php echo $this->module_position; ?>" data-checkout-step="<?php echo $this->step; ?>" data-checkout-pos="<?php echo $this->module_position; ?>" class="hikashop_checkout_fields"> <?php } ?> <div class="hikashop_checkout_loading_elem"></div> <div class="hikashop_checkout_loading_spinner"></div> <?php $this->checkoutHelper->displayMessages('fields'); ?> <fieldset class="hkform-horizontal"> <?php if(!empty($fields)) { if(!empty($this->options['show_title'])) { ?> <legend><?php echo JText::_('ADDITIONAL_INFORMATION'); ?></legend> <?php } $after = array(); foreach($fields as $fieldName => $oneExtraField) { $oneExtraField->registration_page = @$this->registration_page; if(isset($_SESSION['hikashop_order_data']) && is_object($_SESSION['hikashop_order_data']) && isset($_SESSION['hikashop_order_data']->$fieldName) && !is_null($_SESSION['hikashop_order_data']->$fieldName)) { $element = $_SESSION['hikashop_order_data']; } else { $element = $cart->cart_fields; } $value = @$element->$fieldName; if(empty($value) && !empty($this->options['read_only'])) continue; if(empty($this->options['read_only'])) { $onWhat = ($oneExtraField->field_type == 'radio') ? 'onclick' : 'onchange'; $html = $this->fieldClass->display( $oneExtraField, $value, 'data[order_' . $this->step . '_' . $this->module_position.']['.$fieldName.']', false, ' class="'.HK_FORM_CONTROL_CLASS.'" '.$onWhat.'="window.hikashop.toggleField(this,\''.$fieldName.'\',\'order_' . $this->step . '_' . $this->module_position.'\',0,\'hikashop_\');"', false, $fields, $cart->cart_fields, false ); if($oneExtraField->field_type == 'hidden') { $after[] = $html; continue; } }else{ $oneExtraField->currentElement = $element; $html = $this->fieldClass->show($oneExtraField, $value); } ?> <div class="hkform-group control-group hikashop_checkout_<?php echo $fieldName;?>_line" id="hikashop_order_<?php echo $this->step . '_' . $this->module_position . '_' . $oneExtraField->field_namekey; ?>"> <?php $requiredDisplay = true; if(!empty($this->options['read_only'])) { $requiredDisplay = false; } $label = $this->fieldClass->getFieldName($oneExtraField, $requiredDisplay, $labelcolumnclass.' hkcontrol-label'); if(!empty($this->options['read_only'])) { $label = str_replace('</label>',' :</label>',$label); } echo $label; ?> <div class="<?php echo $inputcolumnclass;?>"> <?php echo $html; ?> </div> </div> <?php } if(count($after)) { echo implode("\r\n", $after); } if(!empty($this->options['show_submit'])) { ?> <div class="hkform-group control-group hikashop_fields_button_line"> <div class="<?php echo $labelcolumnclass;?> hkcontrol-label"></div> <div class=" <?php echo $inputcolumnclass;?>"> <button type="submit" onclick="return window.checkout.submitFields(<?php echo $this->step.','.$this->module_position; ?>);" class="<?php echo $this->config->get('css_button','hikabtn'); ?> hikabtn_checkout_fields_submit"> <?php echo JText::_('HIKA_SUBMIT_FIELDS'); ?> </button> </div> </div> <?php } } else { $this->emptyBlocksCount++; } ?> </fieldset> <?php if(!empty($this->options['js'])) { ?> <script type="text/javascript"> <?php echo $this->options['js']; ?> </script> <?php } if(empty($this->ajax)) { ?> </div> <script type="text/javascript"> if(!window.checkout) window.checkout = {}; window.Oby.registerAjax(['checkout.fields.updated','cart.updated','checkout.shipping.changed','checkout.payment.changed'], function(params){ window.checkout.refreshFields(<?php echo (int)$this->step; ?>, <?php echo (int)$this->module_position; ?>); }); window.checkout.refreshFields = function(step, id) { return window.checkout.refreshBlock('fields', step, id); }; // make sure field is filled window.checkout.submitFields = function(step, id) { // Check weather "sleepwith" is fiiled if products 78 or 79 is in cart var sleepwithField = document.querySelector('[name="data[order_<?php echo $this->step; ?>_<?php echo $this->module_position; ?>][sleepwith]"]'); if (sleepwithField && sleepwithField.value == "" && <?php echo $found ? 'true' : 'false'; ?>) { alert("Please fill this field"); return false; // Stops if its empty } return window.checkout.submitBlock('fields', step, id); }; </script> <?php } ?>
Basically it checks if there are products with special IDs in cart and if there it is, then make custom field visible and required. All working good, except of field requirement. It shows in red that its required, but i'm still able to proceed without filling anything in. Even chatgpt could not help me with that. Maybe you can?
Last edit: 1 year 5 months ago by arnask.

Please Log in or Create an account to join the conversation.

More
1 year 5 months ago #366597 by nicolas
Hi,

The check on the required attribute is done on the server side, when your browser sends the form data to the server.
Here, by adding the required attribute, you tell the client side (the browser) that the field is required (that's why it is red) but the server side still bases itself on the required attribute in the database.

Adding a check on the server side is not impossible, but it's a bit harder than just a view override.
You'll need to develop a small HikaShop plugin and implement the onBeforeCartSave(&$element,&$do) event ( www.hikashop.com/support/documentation/6...tml#onBeforeCartSave ).
There, check the data in $cart->cart_fields basing yourself on $cart->products for the products, and if something is not ok, you can set $do to false and use $app->enqueueMessage to add an error message.
So, it's still possible, but it's a bit more complex.

Please Log in or Create an account to join the conversation.

Time to create page: 0.217 seconds
Powered by Kunena Forum