Jump to content

How to remove save button for customized fields?


otzy

Recommended Posts

Working 1.5.3.1 Mod to remove save button! (without Ajax Cart)

 

The Zip file attached includes what is needed to modify the basic "default" theme on Prestashop 1.5.3.1 to eliminate the save button so you can add to cart directly. Thanks to shamun who got this to work on version 1.5.2 in post #124 above, the CartController.php override file has been updated with 1.5.3.1 code.

 

1. Put the CartController.php file in the override/controllers/front directory

2. Put the product.tpl file in your default theme directory (or the theme directory you created from the default theme).

3. In the BO under modules, set the Cart block configuration to deactivate the Ajax cart

4. In the BO on the Advnaced Parameters menu, select performance, Turn off the smarty cache and compile templates, then try it in the front office. It should work. Then reenable the smarty cache and turn compile off in the BO.

 

If anyone is able to accomplish the following that is NOT incorporated in this mod, please post in this thread:

1. update to include uploading of files & images

2. Get the Ajax cart working with this mod

SVP je peux savoir quesque vous avez changer sur la page produit, parce que après l’intégration de ce code le prix ne se change pas selon la declinaison, y-a un bug ici

Link to comment
Share on other sites

  • 6 months later...

Hi mates,

 

I don't know if it is too late to answer but I found an article where it is explained how to do it and it works perfectly in PS 1.6.

 

I copy the link:

 

http://nemops.com/save-prestashop-custom-fields-add-to-cart/#.VqJEQvE8zkx

 

The only negative point is that it requires a little modification in the file /js/tools.js and it can't be saved in the override directory (the modification will be lost if you update prestashop).

 

So if you use this solution, save a copy of your modified file tools.js

  • Like 1
Link to comment
Share on other sites

  • 9 months later...

I don't want to edit too much files to achieve this functionality to save customization on adding cart. For some ppl as a tip, you can and just "onchange" option f.e file upload. My webshop sells edible cake toppers from custom photos, at least 3-5 customers per day forgets to press "Save" button so order does not have uploaded picture and I need to bother customers to send photo as email so I needed to find a quick solution:

 
Open product.tpl file and find file upload form input line and add "onchange":

... <input onchange="javascript:this.form.submit();" type="file" name="file{$field.id_customization_field}" id="img{$customizationField}" class="form-control
customization_block_input ....

For me this solution works like charm. If you have time to write js-script, you can also make custom balloon popup to wait until photo is uploaded and visible on product.

  • Like 1
Link to comment
Share on other sites

  • 8 months later...
  • 2 years later...
  • 2 weeks later...

Thirtybees 1.10 and Prestashop 1.6

Kakkupaperi's solution adapted to my <TEXTAREA></TEXTAREA> form, except that the orders got mixed-up; it could order no selection or the previous customers' selection and a javascript expert could probably solve that problem.

My change is to use <SELECT>
<OPTION>choose
<OPTION>first
<OPTION>second</SELECT> 

Onchange is replaced  by Onselect

It might do for hakunamataza.com above.

The default system for making a choice compulsory works on this form; if you click the box of the customization page in the backoffice, it produces a popup with some words to translate if you choose "choose", but there may be quicker prettier ways of doing it.

<select onselect="javascript:this.form=''" " name="textField{$field.id_customization_field}" class="form-control customization_block_input" id="textField{$customizationField}" rows="3" cols="20">{strip}
                            {if isset($textFields.$key)}
                              {$textFields.$key|stripslashes}
                            {/if}
                          {/strip}
                          
                          <option>choose</option>
                          <option>first</option>
                          <option>second</option>
                          <option>third</option>
                          <option>fourth</option>
                          </select>
                        </li>
  • The {strip}{/strip} bit is copied but probably not used.
  • ID="textfield looks wrong as this is a select field, but the form worked on the first one or two tries.
  • The rows and columns make this a very wide select form. It could be more intuitive if it looked the same as other select forms on the same theme.


The customization is limited to selections, just like an attribute, but with no stock control, so if you want stock control for one attribute and not for another, this is a solution.

If anyone spots obvious mistakes or other solutions, please post.

Edited by johnrobertson (see edit history)
Link to comment
Share on other sites

  • 4 months later...
On 8/19/2014 at 2:54 PM, defuzed said:

I haven't followed this thread in a while so I'm not sure about the findings beyond page 7. But the solutions posted page 7 by Rhapsody ( http://www.prestashop.com/forums/topic/76874-how-to-remove-save-button-for-customized-fields/?p=1140428 ) [for text fields] and my addition for file uploads ( http://www.prestashop.com/forums/topic/76874-how-to-remove-save-button-for-customized-fields/?p=1185115work perfectly on 1.6 !

 

You will need to disable ajax-cart though since those solutions do not work with ajax cart. I think some modifications for getting it to work with ajax cart have been posted after page 7, just read carefully.

I had to try something like this because inline javascript in my previous post got cached along with the previous customers' text; it might work for file uploads but not text. People would buy the order from the customer before. Instead, this method changes a cartcontroller.php file including some code to check that this is a current cart. The new file sits in a slot for over-rides, that doesn't get updated like the rest of the code:
/override/controllers/front/CartController.php

I have not got it working with attributes like size and color. They stop working when I install this, so I need to use it only on products that have no normal attributes, using a separate template which is possible in Thirtybees.
I have not tested with quantity.

<?php
/*
* 2007-2012 PrestaShop 1.5.3.1 source
*
* NOTICE OF LICENSE
*
* This override removes the need to submit customization
* as a separate step. It's from shamun's post (#124) on page 7 of this thread:
* http://www.prestashop.com/forums/index.php?/topic/76874-how-to-remove-save-button-for-customized-fields/page__view__findpost__p__1054781
*/

class CartController extends CartControllerCore
{

	/**
	 * This process add or update a product in the cart
	 */
	protected function processChangeProductInCart()
	{
		$mode = (Tools::getIsset('update') && $this->id_product) ? 'update' : 'add';

		if ($this->qty == 0)
			$this->errors[] = Tools::displayError('Null quantity');
		else if (!$this->id_product)
			$this->errors[] = Tools::displayError('Product not found');

		$product = new Product($this->id_product, true, $this->context->language->id);
		if (!$product->id || !$product->active)
		{
			$this->errors[] = Tools::displayError('Product is no longer available.', false);
			return;
		}
		
		/* Added to allow for customizations without saving.  Almost the same as from ProductController.  Image removed. */
		if (Tools::isSubmit('submitCustomizedDatas'))
		{
			// If cart has not been saved, we need to do it so that customization fields can have an id_cart
			// We check that the cookie exists first to avoid ghost carts
			if (!$this->context->cart->id && isset($_COOKIE[$this->context->cookie->getName()]))
			{
				$this->context->cart->add();
				$this->context->cookie->id_cart = (int)$this->context->cart->id;
			}
			$this->textRecord($product);
		}
		/* End customization without saving */

		// Check product quantity availability
		if ($this->id_product_attribute)
		{
			if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $this->qty))
				$this->errors[] = Tools::displayError('There is not enough product in stock.');
		}
		else if ($product->hasAttributes())
		{
			$minimumQuantity = ($product->out_of_stock == 2) ? !Configuration::get('PS_ORDER_OUT_OF_STOCK') : !$product->out_of_stock;
			$this->id_product_attribute = Product::getDefaultAttribute($product->id, $minimumQuantity);
			// @todo do something better than a redirect admin !!
			if (!$this->id_product_attribute)
				Tools::redirectAdmin($this->context->link->getProductLink($product));
			else if (!Product::isAvailableWhenOutOfStock($product->out_of_stock) && !Attribute::checkAttributeQty($this->id_product_attribute, $this->qty))
				$this->errors[] = Tools::displayError('There is not enough product in stock.');
		}
		else if (!$product->checkQty($this->qty))
			$this->errors[] = Tools::displayError('There is not enough product in stock.');

		// If no errors, process product addition
		if (!$this->errors && $mode == 'add')
		{
			// Add cart if no cart found
			if (!$this->context->cart->id)
			{
				$this->context->cart->add();
				if ($this->context->cart->id)
					$this->context->cookie->id_cart = (int)$this->context->cart->id;
			}

			// Check customizable fields
			if (!$product->hasAllRequiredCustomizableFields() && !$this->customization_id)
				$this->errors[] = Tools::displayError('Please fill in all required fields, then save the customization.');

			if (!$this->errors)
			{
				$cart_rules = $this->context->cart->getCartRules();
				$update_quantity = $this->context->cart->updateQty($this->qty, $this->id_product, $this->id_product_attribute, $this->customization_id, Tools::getValue('op', 'up'), $this->id_address_delivery);
				if ($update_quantity < 0)
				{
					// If product has attribute, minimal quantity is set with minimal quantity of attribute
					$minimal_quantity = ($this->id_product_attribute) ? Attribute::getAttributeMinimalQty($this->id_product_attribute) : $product->minimal_quantity;
					$this->errors[] = sprintf(Tools::displayError('You must add %d minimum quantity', false), $minimal_quantity);
				}
				elseif (!$update_quantity)
					$this->errors[] = Tools::displayError('You already have the maximum quantity available for this product.', false);
				elseif ((int)Tools::getValue('allow_refresh'))
				{
					// If the cart rules has changed, we need to refresh the whole cart
					$cart_rules2 = $this->context->cart->getCartRules();
					if (count($cart_rules2) != count($cart_rules))
						$this->ajax_refresh = true;
					else
					{
						$rule_list = array();
						foreach ($cart_rules2 as $rule)
							$rule_list[] = $rule['id_cart_rule'];
						foreach ($cart_rules as $rule)
							if (!in_array($rule['id_cart_rule'], $rule_list))
							{
								$this->ajax_refresh = true;
								break;
							}
					}
				}
			}
		}

		$removed = CartRule::autoRemoveFromCart();
		if (count($removed) && (int)Tools::getValue('allow_refresh'))
			$this->ajax_refresh = true;
	}

	/* Allows addition of customized text inputs without saving.
		Modified parts: 
			Method now requires an input.  The input needs to be the $product !
			Replaced $this->product-> with $product->
	*/
	protected function textRecord($product)
	{
		if (!$field_ids = $product->getCustomizationFieldIds())
			return false;
			
		$authorized_text_fields = array();
		foreach ($field_ids as $field_id)
			if ($field_id['type'] == Product::CUSTOMIZE_TEXTFIELD)
				$authorized_text_fields[(int)$field_id['id_customization_field']] = 'textField'.(int)$field_id['id_customization_field'];
				
		$indexes = array_flip($authorized_text_fields);
		foreach ($_POST as $field_name => $value)
			if (in_array($field_name, $authorized_text_fields) && !empty($value))
			{
				if (!Validate::isMessage($value))
					$this->errors[] = Tools::displayError('Invalid message');
				else
					$this->context->cart->addTextFieldToProduct($product->id, $indexes[$field_name], Product::CUSTOMIZE_TEXTFIELD, $value);
			}
			else if (in_array($field_name, $authorized_text_fields) && empty($value))
				$this->context->cart->deleteCustomizationToProduct((int)$product->id, $indexes[$field_name]);
	}
}

 

 


There is still a default customization block at the bottom of the page. I suppose I should comment it out and maybe experiment using its code instead of the transplanted code, in case one is better than another. 
So I had a look back through the thread and found the quote above, turned off ajax, logged-on to this message board so I could download the zipfile with a cartcontroller.php override and a product.tpl template, and it sort of worked. I have a test site on a server; found the "Themes" section and my theme, found product.tpl in there and just edited it to add the new text.

I am on the Thirtybees fork of PS1.6 that uses Niara theme; the template file is from PS 1.5.3.1, and formatting didn't work in my version. Photos. Layout. Luckily, Rhapsody has labelled the changes in his template. He has a block of code for a moved customization form, and he has put it somewhere inside the <form> </form> tag of the order form. So I reverted to my default product.tpl file (cut and pasted from github onto my server) and added the block of code. It worked. He put it just before the closing </form> but it will probably work higher-up the page. His code avoids the

The block of code looks like this.
 

	{* Rhapsody Moved customization block below *}	
	<!-- Customizable products -->	
	{if isset($product) && $product->customizable}	
	<ul id="more_info_tabs" class="idTabs idTabsShort clearfix">	
		<div id="idTab10" class="bullet customization_block">	
		{$HOOK_PRODUCT_TAB}	
	</ul>	
{* Rhapsody comment out this section	
			<form method="post" action="{$customizationFormTarget}" enctype="multipart/form-data" id="customizationForm" class="clearfix">	
				<p class="infoCustomizable">	
					{l s='After saving your customized product, remember to add it to your cart.'}	
					{if $product->uploadable_files}<br />{l s='Allowed file formats are: GIF, JPG, PNG'}{/if}	
				</p>	
Rhapsody Commented out  *}	
				{if $product->uploadable_files|intval}	
				<div class="customizableProductsFile">	
					<h3>{l s='Pictures'}</h3>	
					<ul id="uploadable_files" class="clearfix">	
						{counter start=0 assign='customizationField'}	
						{foreach from=$customizationFields item='field' name='customizationFields'}	
							{if $field.type == 0}	
								<li class="customizationUploadLine{if $field.required} required{/if}">{assign var='key' value='pictures_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field}	
									{if isset($pictures.$key)}	
									<div class="customizationUploadBrowse">	
										<img src="{$pic_dir}{$pictures.$key}_small" alt="" />	
										<a href="{$link->getProductDeletePictureLink($product, $field.id_customization_field)}" title="{l s='Delete'}" >	
											<img src="{$img_dir}icon/delete.gif" alt="{l s='Delete'}" class="customization_delete_icon" width="11" height="13" />	
										</a>	
									</div>	
									{/if}	
									<div class="customizationUploadBrowse">	
										<label class="customizationUploadBrowseDescription">{if !empty($field.name)}{$field.name}{else}{l s='Please select an image file from your hard drive'}{/if}{if $field.required}<sup>*</sup>{/if}</label>	
										<input type="file" name="file{$field.id_customization_field}" id="img{$customizationField}" class="customization_block_input {if isset($pictures.$key)}filled{/if}" />	
									</div>	
								</li>	
								{counter}	
							{/if}	
						{/foreach}	
					</ul>	
				</div>	
				{/if}	
				{if $product->text_fields|intval}	
				<div class="customizableProductsText">	
					<h3>{l s='Type your text in the blanks below'}</h3>	
					<ul id="text_fields">	
					<p class="clear required"><sup>*</sup> {l s='Mandatory entry fields have red labels'}</p>	
					{counter start=0 assign='customizationField'}	
					{foreach from=$customizationFields item='field' name='customizationFields'}	
						{if $field.type == 1}	
						<li class="customizationUploadLine{if $field.required} required{/if}">	
							<label for ="textField{$customizationField}">{assign var='key' value='textFields_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field} {if !empty($field.name)}{$field.name}{/if}{if $field.required}<sup>*</sup>{/if}</label>	
							<textarea type="text" name="textField{$field.id_customization_field}" id="textField{$customizationField}" rows="1" cols="40" class="customization_block_input" />{if isset($textFields.$key)}{$textFields.$key|stripslashes}{/if}</textarea>	
						</li>	
						{counter}	
						{/if}	
					{/foreach}	
					</ul>	
				</div>	
				{/if}	
				<p id="customizedDatas">	
					<input type="hidden" name="quantityBackup" id="quantityBackup" value="" />	
					<input type="hidden" name="submitCustomizedDatas" value="1" />	
{* Rhapsody hid save button in next line	
					<input type="button" class="button" value="{l s='Save'}" onclick="javascript:saveCustomization()" />	
* * * * end of comment *}	
					<span id="ajax-loader" style="display:none"><img src="{$img_ps_dir}loader.gif" alt="loader" /></span>	
				</p>	
				
			</form>	
	{/if}	
{* Rhapsody moved customization block above  *}

I suppose I should now work out where to paste it as an over-ride, so that next time the site automatically updates, this page won't be changed. Or maybe use the free DH42 module that allows you to have custom code for a template controlled from the back office.

Edited by johnrobertson (see edit history)
Link to comment
Share on other sites

  • 4 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...