Restrict custom field to product variant

  • Posts: 183
  • Thank you received: 3
  • Hikaserial Standard Hikashop Business
2 weeks 2 days ago #366496

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.

  • Posts: 83603
  • Thank you received: 13533
  • MODERATOR
2 weeks 2 days ago #366498

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.

  • Posts: 183
  • Thank you received: 3
  • Hikaserial Standard Hikashop Business
2 weeks 1 day ago #366512

My custom field is in table "order"

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

  • Posts: 83603
  • Thank you received: 13533
  • MODERATOR
2 weeks 1 day ago #366513

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.

  • Posts: 183
  • Thank you received: 3
  • Hikaserial Standard Hikashop Business
1 week 4 days ago #366590

Can you give some example, course for me its too complicated

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

  • Posts: 83603
  • Thank you received: 13533
  • MODERATOR
1 week 4 days ago #366592

Well, something like that at the beginning (not tested):

<?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.

  • Posts: 183
  • Thank you received: 3
  • Hikaserial Standard Hikashop Business
1 week 3 days ago #366595

I have managed to get this code (show_block_fields.php) with help of chatgpt:

<?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 week 3 days ago by arnask.

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

  • Posts: 83603
  • Thank you received: 13533
  • MODERATOR
1 week 3 days ago #366597

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.066 seconds
Powered by Kunena Forum