<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NemoPS &#187; ajax</title>
	<atom:link href="http://nemops.com/tag/ajax/feed/" rel="self" type="application/rss+xml" />
	<link>http://nemops.com</link>
	<description>Prestashop Tutorials, Modules and More!</description>
	<lastBuildDate>Wed, 05 Dec 2018 13:25:23 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.35</generator>
	<item>
		<title>Images in PrestaShop 1.6&#8217;s Ajax Search</title>
		<link>http://nemops.com/prestashop-1-6-ajax-search-images/</link>
		<comments>http://nemops.com/prestashop-1-6-ajax-search-images/#comments</comments>
		<pubDate>Mon, 19 Dec 2016 11:51:25 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Tips n Tricks]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[prestashop 1.6]]></category>
		<category><![CDATA[search]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2934</guid>
		<description><![CDATA[<p>Let&#8217;s make the default ajax search more interesting by adding images to it, it&#8217;s not overly complicated!</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-1-6-ajax-search-images/">Images in PrestaShop 1.6&#8217;s Ajax Search</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Let&#8217;s make the default ajax search more interesting by adding images to it, it&#8217;s not overly complicated!</p>
<p><span id="more-2934"></span></p>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/bkMFRX519zY" frameborder="0" allowfullscreen></iframe><p><a href="https://www.youtube.com/user/NemoPostScriptum/videos" rel="nofollow" title="Subscribe Post Scriptum's Youtube Channel">Subscribe Post Scriptum's Youtube Channel</a></p>	</div>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-1-6-ajax-search-images/">Images in PrestaShop 1.6&#8217;s Ajax Search</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-1-6-ajax-search-images/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Create an Ajax Contact Form in PrestaShop</title>
		<link>http://nemops.com/prestashop-ajax-contact-form/</link>
		<comments>http://nemops.com/prestashop-ajax-contact-form/#comments</comments>
		<pubDate>Tue, 01 Nov 2016 10:33:03 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Tips n Tricks]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[contact]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[prestashop]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2878</guid>
		<description><![CDATA[<p>In this awesome PrestaShop tutorial, we will add an ajax contact form to the product page View Demo (click Contact Us next to &#8220;In Stock&#8221;) Watch the Screencast</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-ajax-contact-form/">Create an Ajax Contact Form in PrestaShop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In this awesome PrestaShop tutorial, we will add an ajax contact form to the product page<br />
<span id="more-2878"></span></p>
<p><a href="http://demo.nemops.com/en/women/tops/tshirts/faded-short-sleeve-t-shirts" title="PrestaShop ajax contact form demo" target="_blank">View Demo (click Contact Us next to &#8220;In Stock&#8221;)</a></p>
<h2>Watch the Screencast</h2>

	<div class="video-embed">
		<iframe width="640" height="360" src="http://www.youtube.com/embed/F4FRr_GLLpw" frameborder="0" allowfullscreen></iframe><p><a href="https://www.youtube.com/user/NemoPostScriptum/videos" rel="nofollow" title="Subscribe Post Scriptum's Youtube Channel">Subscribe Post Scriptum's Youtube Channel</a></p>	</div>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-ajax-contact-form/">Create an Ajax Contact Form in PrestaShop</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-ajax-contact-form/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Save Prestashop Custom fields on &#8220;Add to cart&#8221; &#8211; Part 2</title>
		<link>http://nemops.com/save-prestashop-custom-fields-add-to-cart-2/</link>
		<comments>http://nemops.com/save-prestashop-custom-fields-add-to-cart-2/#comments</comments>
		<pubDate>Wed, 06 May 2015 08:11:40 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[cart]]></category>
		<category><![CDATA[customization]]></category>
		<category><![CDATA[prestashop]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2406</guid>
		<description><![CDATA[<p>After tackling text fields, in this second part we will see how to add ajax uploads for file customizations in Prestashop. Version used: Prestashop 1.6 &#171; Save Prestashop Custom fields on “Add to cart” – Part 1 Demo here &#160; &#160; Continuing from what we did in the previous tutorial, instead of modifying the ajax-cart.js [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/save-prestashop-custom-fields-add-to-cart-2/">Save Prestashop Custom fields on &#8220;Add to cart&#8221; &#8211; Part 2</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>After tackling text fields, in this second part we will see how to add ajax uploads for file customizations in Prestashop.</p>
<p><span id="more-2406"></span></p>
<ul>
<li>Version used: Prestashop 1.6</li>
</ul>
<p><a href="http://nemops.com/save-prestashop-custom-fields-add-to-cart/#.VUibJfnzrmg" title="Save Prestashop Custom fields on “Add to cart” – Part 1"> &laquo; Save Prestashop Custom fields on “Add to cart” – Part 1</a></p>
<p><a class="button style1" style="float:left;" href="http://demo.nemops.com/blouses/blouse" title="Save Prestashop Custom fields - Demo">Demo here </a>&nbsp;</p>
<p>&nbsp;</p>
<p>Continuing from what we did in the previous tutorial, instead of modifying the ajax-cart.js file, this time we will handle <strong>product.js</strong>, located in the theme folder /js/. To make things easier we will also add atrigger button to fire the upload event, and modify our previously amended <strong>tools.js</strong>.</p>
<p>Before starting, it&#8217;s important to notice this kind of upload will not work for older browsers (like ie9), so you might want to add some kind of warning, or completely hide the ajax button in this case.</p>
<div class="separator"></div>
<h2>Handling ajax file uploads in Prestashop &#8211; product.js</h2>
<p>First off, let&#8217;s create our small trigger. Locate <strong>product.tpl</strong> in your theme&#8217;s folder, open it up and right before this</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
						&lt;/div&gt;
					{/if}
					{if $product-&gt;text_fields|intval}
</pre>
<p>Add the following</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
&lt;a class=&quot;btn btn-default&quot; href=&quot;javascript:void(0)&quot; id=&quot;uploadTrigger&quot;&gt;Upload&lt;/a&gt;
</pre>
<p>If your theme looks different, make sure it&#8217;s inside this conditional, at least:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
{if $product-&gt;uploadable_files|intval}
...
{/if}
</pre>
<p>Then, let&#8217;s deal with Javascript.</p>
<p>Open up <strong>product.js</strong> and make sure you put your cursor inside the very first  $(document).ready(function() block. The first thing we need to do is create a list of files that the user might want to upload, as soon as the file inputs change:</p>
<pre class="brush: jscript; title: ; notranslate">
	var files = new Array();
	$('.customizationUploadLine').find('input[type=&quot;file&quot;]').on('change', prepareUpload);
	function prepareUpload(event)
	{
	  files.push({'name' : event.target.name, 'file' :event.target.files[0]});
	}

</pre>
<p><strong>Explanation:</strong> we are taking advantage of the &#8216;files&#8217; property of the change event, which holds the file(s) currently being added to the clicked input. We want to record modifications to all our file customization fields, and push the files array with each of the possible uploads. We will need each entry to be named as the form field, so we use a new object for each file, holding the correct name in the &#8216;name&#8217; property, and the actual file content in the &#8216;file&#8217; one.</p>
<p>The original method I used came from this tutorial, in case you want to have a reference of the source code: <a href="http://abandon.ie/notebook/simple-file-uploads-using-jquery-ajax" title="Ajax file uploads with jQuery">Ajax file uploads with jQuery</a></p>
<p>Now, let&#8217;s target the upload button&#8217;s click;</p>
<pre class="brush: jscript; title: ; notranslate">
	$('#uploadTrigger').click(function(e) {
		if(files.length &gt; 0)
		{
			// here will be out ajax
		} // end checking files length
		else alert('Nothing to upload!');
	});
</pre>
<p>We have to make sure we have at least one file to upload; otherwise it&#8217;s useless to continue with the call.</p>
<p>Since we do not know how long the file upload will take, it&#8217;s better to prevent the user from taking further actions before it&#8217;s completed. Let&#8217;s add some feedback:</p>
<pre class="brush: jscript; title: ; notranslate">

			$('&lt;div class=&quot;myoverlay&quot;&gt;&lt;/div&gt;').css({

				'position' : 'fixed',
				'top' : 0,
				'left' : 0,
				'background' : 'black',
				'background' : 'rgba(0,0,0,.5)',
				'z-index' : 5999,
				'width' : '100%',
				'height' : '100%',
				'cursor' : 'pointer'
			}).appendTo('body');
			
			$('&lt;div class=&quot;uploadingfiles&quot;&gt;Your files are being uploaded...&lt;img src=&quot;'+baseUri+'themes/default-bootstrap/img/ajax-loader.gif&quot;&gt;&lt;/div&gt;')
				.css({
					'position' : 'absolute',
					'top' : '30%',
					'left' : '50%',
					'width' : '300px',
					'margin-left' : '-150px',
					'text-align' : 'center',
					'padding' : '10px',
					'background' : 'white'
				})
				.appendTo('.myoverlay');


</pre>
<p>Now the tricky part. We will use the new HTML5, supported with XHR2 (that is why it will not work on old browsers!). Right after appending the box, add the following:</p>
<pre class="brush: jscript; title: ; notranslate">

			var data = new FormData();

		    $.each(files, function(key, obj)
		    {
		        data.append(obj.name, obj.file);
		    });

		    data.append('submitCustomizedDatas', 1);
		    data.append('ajax', 1);

</pre>
<p><strong>Explanation:</strong> as mentioned, we need a FormData object to hold our data. Then, we iterate through each of the files, assigning them to the respective name. The <strong>append</strong> method works like data.append(key, data). Lastly, since in the previous tutorial we only ran the customization scripts when having two specific queries sent to the server, we also append them to our form data. The value here is not important, as long as it&#8217;s more than 0.</p>
<h3>The ajax call</h3>
<p>Here is our code so far:</p>
<pre class="brush: jscript; title: ; notranslate">

	var files = new Array();
	$('.customizationUploadLine').find('input[type=&quot;file&quot;]').on('change', prepareUpload);
	// Grab the files and set them to our variable
	function prepareUpload(event)
	{
	  files.push({'name' : event.target.name, 'file' :event.target.files[0]});
	}
	

	$('#uploadTrigger').click(function(e) {

	
		if(files.length &gt; 0)
		{

			$('&lt;div class=&quot;myoverlay&quot;&gt;&lt;/div&gt;').css({

				'position' : 'fixed',
				'top' : 0,
				'left' : 0,
				'background' : 'black',
				'background' : 'rgba(0,0,0,.5)',
				'z-index' : 5999,
				'width' : '100%',
				'height' : '100%',
				'cursor' : 'pointer'
			}).appendTo('body');
			
			$('&lt;div class=&quot;uploadingfiles&quot;&gt;Your files are being uploaded...&lt;img src=&quot;'+baseUri+'themes/default-bootstrap/img/ajax-loader.gif&quot;&gt;&lt;/div&gt;')
				.css({
					'position' : 'absolute',
					'top' : '30%',
					'left' : '50%',
					'width' : '300px',
					'margin-left' : '-150px',
					'text-align' : 'center',
					'padding' : '10px',
					'background' : 'white'
				})
				.appendTo('.myoverlay');


			var data = new FormData();

		    $.each(files, function(key, obj)
		    {
		        data.append(obj.name, obj.file);
		    });

		    data.append('submitCustomizedDatas', 1);
		    data.append('ajax', 1);
		 

		} // end checking files length
		else alert('Nothing to upload!');
	});
</pre>
<p>Pretty long already! But we need to tackle the most important part: the ajax call. Right after appending &#8216;ajax&#8217;, add the following:</p>
<pre class="brush: jscript; title: ; notranslate">
$.ajax({
    url: $('#customizationForm').attr('action'),
    type: 'POST',
    data: data,
    cache: false,
    dataType: 'json',
    processData: false,
    contentType: false, 
    success: function(data, textStatus, jqXHR)
    {
      
    },
    error: function(jqXHR, textStatus, errorThrown)
    {
    }
});
</pre>
<p><strong>Explanation:</strong> two parts of this call deserve a better explanation; first, we are telling jQuery <strong>not to process data</strong>. Otherwise, the files array will be converted into a string, making it impossible to be further processed; then, <strong>we are setting contentType to false as well</strong>, to prevent the script to send over a normally encoded form (without files).</p>
<p>At this point, it&#8217;s worth testing out the script. It will inevitably break at some point, but you can see the upload being successful or not by refreshing the page when you see the call is complete. <strong>Make sure you keep an eye on the Network Tab</strong> in the browser&#8217;s console for this, to also troubleshoot any eventual error.</p>
<p>When it&#8217;s done, refresh the page. If everything went smoothly, the image will appear at the top of the file input!</p>
<h3>Giving some feedback to the user</h3>
<p>If we were the only ones using the site, we could as well jump to the next step. But since it&#8217;s rarely the case, let&#8217;s give our customers a bit of feedback on what&#8217;s up with files. In the &#8220;success&#8221; method of the ajax call, add the following:</p>
<pre class="brush: jscript; title: ; notranslate">

if(typeof data.errors === 'undefined')
{

	$.each(files, function(key, obj)
    {
        $('input[name=&quot;'+obj.name+'&quot;]').addClass('filled');
        previewFile($('input[name=&quot;'+obj.name+'&quot;]'), obj.file);

    });
    $('.uploadingfiles').text('Upload Complete!');
}
else
{
   $('.uploadingfiles').text('Error while uploading, please refresh the page and try again');
}
$('.myoverlay').click(function(){$(this).remove()});
</pre>
<p><strong>Explanation:</strong> first off, we must check that we don&#8217;t have any error coming back from the call. If we do, we replace our &#8220;uploading&#8221; text with the error string. If everything is ok (if(typeof data.errors === &#8216;undefined&#8217;)) we iterate through our files list, and add a preview above the list. Notice I am calling a function named  <strong>previewFile</strong>, which we do not have yet!</p>
<p>You might have noticed I added a &#8220;filled&#8221; class as well to the input. Why? We will see this shortly, when amending tools.js.</p>
<p>Make sure you always add </p>
<pre class="brush: jscript; title: ; notranslate">

$('.myoverlay').click(function(){$(this).remove()});
</pre>
<p>So that users can get rid of the overlay when needed.</p>
<h3>Adding an image Preview</h3>
<p>We are almost done! let&#8217;s create the previewFile function. Right before this:</p>
<pre class="brush: jscript; title: ; notranslate">
	$('#uploadTrigger').click(function(e) {
</pre>
<p>Add</p>
<pre class="brush: jscript; title: ; notranslate">
	function previewFile(target, file) {

		$('#uniform-'+target.attr('id')).before($('&lt;img id=&quot;preview-'+target.attr('id')+'&quot;/&gt;'));
		var preview = $('#preview-'+target.attr('id'));
		var reader  = new FileReader();

		preview.attr('width', 64);

		reader.onloadend = function () {
			preview.attr('src', reader.result);
		}

		if (file) {
			reader.readAsDataURL(file);
		} else {
			preview.attr('src', &quot;&quot;);
		}
	}

</pre>
<p><strong>Explanation:</strong> we are taking advantage of the FileReader class. First, we prepend an image tag to our input&#8217;s parent, making sure the preview box is no larger than 64 pixels. Then, we replace out image source after the reader has actually read the file, if it exists, passing in the one we got before, out of the original &#8220;files&#8221; array. It&#8217;s a bit confusing, but you can basically copy/paste to have it working. Here is the source: <a href="https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL" title="Image preview for ajax file uploads">Image preview for ajax file uploads</a></p>
<p>As a finishing touch, we might want to handle failed ajax requests as well:</p>
<pre class="brush: jscript; title: ; notranslate">
 error: function(jqXHR, textStatus, errorThrown)
{
   $('.uploadingfiles').text('ERRORS: ' + errorThrown);
    $('.myoverlay').click(function(){$(this).remove()});
}
</pre>
<div class="separator"></div>
<h2>Yet again, tools.js!</h2>
<p>Back to our beloved tools.js! Here is where we left off:</p>
<pre class="brush: jscript; title: ; notranslate">
function checkCustomizations()
{
    var pattern = new RegExp(' ?filled ?');
 
    if (typeof customizationFields != 'undefined')
        for (var i = 0; i &lt; customizationFields.length; i++)
        {
            if (parseInt(customizationFields[i][1]) == 1 &amp;&amp; ($('#' + customizationFields[i][0]).val() == ''))
  			return false;
        }
    return true;
}
</pre>
<p>Now, this will make it impossible to save our current files. In order to be able to do it, we need to modify the function as follows</p>
<pre class="brush: jscript; title: ; notranslate">
function checkCustomizations()
{
    var pattern = new RegExp(' ?filled ?');
 
    if (typeof customizationFields != 'undefined')
        for (var i = 0; i &lt; customizationFields.length; i++)
        {
            if (parseInt(customizationFields[i][1]) == 1 &amp;&amp; $('#' + customizationFields[i][0]).val() == '' &amp;&amp; !pattern.test($('#' + customizationFields[i][0]).attr('class')))
				return false;
        }
    return true;
}
</pre>
<p><strong>Explanation:</strong> remember when we added the &#8216;filled&#8217; class? Now we also want to make sure the class is not there, to return false. This way, the field will validate if it hass the &#8216;filled&#8217; class!</p>
<p>Save and try it out, it should work!</p>
<p>The final code for product.js:</p>
<pre class="brush: jscript; title: ; notranslate">

	var files = new Array();
	$('.customizationUploadLine').find('input[type=&quot;file&quot;]').on('change', prepareUpload);
	// Grab the files and set them to our variable
	function prepareUpload(event)
	{
	  files.push({'name' : event.target.name, 'file' :event.target.files[0]});
	}
	


	function previewFile(target, file) {

		$('#uniform-'+target.attr('id')).before($('&lt;img id=&quot;preview-'+target.attr('id')+'&quot;/&gt;'));
		var preview = $('#preview-'+target.attr('id'));
		var reader  = new FileReader();

		preview.attr('width', 64);

		reader.onloadend = function () {
			preview.attr('src', reader.result);
		}

		if (file) {
			reader.readAsDataURL(file);
		} else {
			preview.attr('src', &quot;&quot;);
		}
	}


	$('#uploadTrigger').click(function(e) {

	
		if(files.length &gt; 0)
		{

			$('&lt;div class=&quot;myoverlay&quot;&gt;&lt;/div&gt;').css({

				'position' : 'fixed',
				'top' : 0,
				'left' : 0,
				'background' : 'black',
				'background' : 'rgba(0,0,0,.5)',
				'z-index' : 5999,
				'width' : '100%',
				'height' : '100%',
				'cursor' : 'pointer'
			}).appendTo('body');
			
			$('&lt;div class=&quot;uploadingfiles&quot;&gt;Your files are being uploaded...&lt;img src=&quot;'+baseUri+'themes/default-bootstrap/img/ajax-loader.gif&quot;&gt;&lt;/div&gt;')
				.css({
					'position' : 'absolute',
					'top' : '30%',
					'left' : '50%',
					'width' : '300px',
					'margin-left' : '-150px',
					'text-align' : 'center',
					'padding' : '10px',
					'background' : 'white'
				})
				.appendTo('.myoverlay');


			var data = new FormData();

		    $.each(files, function(key, obj)
		    {
		        data.append(obj.name, obj.file);
		    });

		    data.append('submitCustomizedDatas', 1);
		    data.append('ajax', 1);
		    $.ajax({
		        url: $('#customizationForm').attr('action'),
		        type: 'POST',
		        data: data,
		        cache: false,
		        dataType: 'json',
		        processData: false,
		        contentType: false,
		        success: function(data, textStatus, jqXHR)
		        {
		            if(typeof data.errors === 'undefined')
		            {
		            	$.each(files, function(key, obj)
					    {
					        $('input[name=&quot;'+obj.name+'&quot;]').addClass('filled');
					        previewFile($('input[name=&quot;'+obj.name+'&quot;]'), obj.file);

					    });
					    $('.uploadingfiles').text('Upload Complete!');
		            }
		            else
		            {
		               $('.uploadingfiles').text('Error while uploading, please refresh the page and try again');
		            }
		            $('.myoverlay').click(function(){$(this).remove()});
		        },
		        error: function(jqXHR, textStatus, errorThrown)
		        {
		           $('.uploadingfiles').text('ERRORS: ' + errorThrown);
		            $('.myoverlay').click(function(){$(this).remove()});
		        }
		    });

		} // end checking files length
		else alert('Nothing to upload!');
	});

</pre>
<div class="separator"></div>
<h2>Taking it a step further</h2>
<p>Given that the previous works for you, we can try taking it a step further. If you really (really!) think your customers will never hit the upload button, you can automate the process and build it inside the ajax-cart as well. How? Opening ajax-cart.js, locate the previous code we added in part1:</p>
<pre class="brush: jscript; title: ; notranslate">

		if(addedFromProductPage &amp;&amp; $('#customizationForm').length &gt; 0)
		{
			...
		}
</pre>
<p>Right before it, add:</p>
<pre class="brush: jscript; title: ; notranslate">
	$('#uploadTrigger').click();
</pre>
<p>Then, inside product.js, <strong>make sure you also add </strong></p>
<pre class="brush: jscript; title: ; notranslate">
	async: false,
</pre>
<p>As property of the ajax call, otherwise the add to cart will run before the upload is completed!</p>
<p>The post <a rel="nofollow" href="http://nemops.com/save-prestashop-custom-fields-add-to-cart-2/">Save Prestashop Custom fields on &#8220;Add to cart&#8221; &#8211; Part 2</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/save-prestashop-custom-fields-add-to-cart-2/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Save Prestashop Custom fields on &#8220;Add to cart&#8221; &#8211; Part 1</title>
		<link>http://nemops.com/save-prestashop-custom-fields-add-to-cart/</link>
		<comments>http://nemops.com/save-prestashop-custom-fields-add-to-cart/#comments</comments>
		<pubDate>Wed, 29 Apr 2015 09:39:23 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[cart]]></category>
		<category><![CDATA[customization]]></category>
		<category><![CDATA[prestashop]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2390</guid>
		<description><![CDATA[<p>Having to save product customization before adding to the cart can be quite annoying. Some customers might even forget to do it if fields are not required. In the first part of this two-stage tutorial, we will see how to save customization text when the add to cart button is pressed. Version used: Prestashop 1.6 [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/save-prestashop-custom-fields-add-to-cart/">Save Prestashop Custom fields on &#8220;Add to cart&#8221; &#8211; Part 1</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Having to save product customization before adding to the cart can be quite annoying. Some customers might even forget to do it if fields are not required. In the first part of this two-stage tutorial, we will see how to save customization text when the add to cart button is pressed.<br />
<span id="more-2390"></span></p>
<ul>
<li>Version used: Prestashop 1.6</li>
</ul>
<p><a href="http://nemops.com/save-prestashop-custom-fields-add-to-cart-2/#.VUnNyfnzrmi" title="Save Prestashop Custom fields on “Add to cart” – Part 2"> Save Prestashop Custom fields on “Add to cart” – Part 2 &raquo;</a></p>
<p><a class="button style1" style="float:left;" href="http://demo.nemops.com/blouses/blouse" title="Save Prestashop Custom fields - Demo">Demo here </a>&nbsp;</p>
<div class="separator"></div>
<h2>We do need ajax</h2>
<p>Before starting, it&#8217;s important to notice we do need to activate the ajax cart, as we will be catching the fields&#8217; content and serialize it; then intercept the &#8220;add&#8221; method of the ajax cart and send another ajax request to the product controller, to save customized data before anything is added to the cart itself.<br />
That said, we need to modify two javascript files, and one controller:</p>
<ul>
<li>ajax-cart.js</li>
<li>tools.js</li>
<li>ProductController.php</li>
</ul>
<p>While we can use an override for the controller, and clone the template for the ajax-cart file, we really need to amend the original <strong>tools.js</strong>, located in the main <em>js/</em> folder.</p>
<p>That said, in this first part we will only deal with text inputs, leaving the file upload to the next tutorial.</p>
<div class="separator"></div>
<h2>Ajax-cart.php</h2>
<p>After reaching the product page (of a product having a text customization field, of course), open up <strong>themes/*yourthemename*/modules/blockcart/ajax-cart.js</strong></p>
<p>Locate the following method</p>
<pre class="brush: jscript; title: ; notranslate">
	add : function(idProduct, idCombination, addedFromProductPage, callerElement, quantity, whishlist)
</pre>
<p>It should be around line 271 in Prestashop 1.6.0.14</p>
<p>Inside it, at the very beginning, right before:</p>
<pre class="brush: jscript; title: ; notranslate">
if (addedFromProductPage &amp;&amp; !checkCustomizations())
</pre>
<p>Add the following:</p>
<pre class="brush: jscript; title: ; notranslate">
		if(addedFromProductPage &amp;&amp; $('#customizationForm').length &gt; 0)
		{
	
			$('#quantityBackup').val($('#quantity_wanted').val());
			customAction = $('#customizationForm').attr('action');
			$('body select[id^=&quot;group_&quot;]').each(function() {
				customAction = customAction.replace(new RegExp(this.id + '=\\d+'), this.id +'=' + this.value);
			});
			
		}
</pre>
<p><strong>Explanation:</strong> first, we have to make sure we are adding to the cart from the single product view (it would make no sense in the list) and that the current item does have customization fields. What comes inside is almost a 1:1 copy of the <strong>saveCustomization()</strong> method we can find in the product.js file. We need to modify the action so that it considers attributes as well. <strong>customAction</strong> is the url we will send the ajax POST to.</p>
<p>Therefore, continuing from it:</p>
<pre class="brush: jscript; title: ; notranslate">
		if(addedFromProductPage &amp;&amp; $('#customizationForm').length &gt; 0)
		{
	
			$('#quantityBackup').val($('#quantity_wanted').val());
			customAction = $('#customizationForm').attr('action');
			$('body select[id^=&quot;group_&quot;]').each(function() {
				customAction = customAction.replace(new RegExp(this.id + '=\\d+'), this.id +'=' + this.value);
			});
			// ajax to product page with custom action
			var customization_entries = $('#customizationForm').serialize();
			$.ajax({
				async:false,
				type: 'POST',
				data: customization_entries+ '&amp;ajax=1',
				dataType: 'json',
				url: customAction,
				success: function(data){
					
				}
			})	
		}
</pre>
<p><strong>Explanation:</strong> after serializing the array&#8217;s entries (remember we are only using text fields for the time being), we send them over to the actionUrl (that is, the ProductController) so it can further take care of our data. Notice I also appended <strong>&#038;ajax=1</strong> as the controller will need to know it&#8217;s receiving an ajax request. Time to move to the override!</p>
<p><strong>IMPORTANT!</strong> Make sure you set the ajax request as async:false, otherwise the add to cart will run before our customization is saved!</p>
<p><strong>Note:</strong> do not try adding the product to the cart at this stage, it will not work, saying the customization field is required.</p>
<div class="separator"></div>
<h2>The Product Controller</h2>
<p>Having our javascript all setup, let&#8217;s deal with the product controller. To make it quick, I will append the new method to the original file, but you can feel free to use an override instead. What it needs is a method that handles data before anything is outputted to screen. Fortunately, we don&#8217;t even need to create it, it&#8217;s built in, and it is named <strong>postProcess</strong>. The only issue is that the ProductController.php file doesn&#8217;t use, so we need to append it ourselves.</p>
<p>Open up <em>controllers/front/ProductController.php</em>, reach the end of the file, and add the following (make sure you are inside the class!)</p>
<pre class="brush: php; title: ; notranslate">
	public function postProcess()
	{
		if (Tools::getValue('ajax') &amp;&amp; Tools::isSubmit('submitCustomizedDatas'))
		{
			if (!$this-&gt;context-&gt;cart-&gt;id &amp;&amp; isset($_COOKIE[$this-&gt;context-&gt;cookie-&gt;getName()]))
			{
				$this-&gt;context-&gt;cart-&gt;add();
				$this-&gt;context-&gt;cookie-&gt;id_cart = (int)$this-&gt;context-&gt;cart-&gt;id;
			}

			$this-&gt;pictureUpload();
			$this-&gt;textRecord();
			$this-&gt;formTargetFormat();

			if($this-&gt;errors)
			{
				$error_list = implode('; ', $this-&gt;errors);
				die(Tools::jsonEncode(array('errors' =&gt; $error_list)));
			} else 
				die(Tools::jsonEncode(array('success' =&gt; true)));
				
		}
	}
</pre>
<p><strong>Explanation:</strong> We only need to run this method for our ajax call, and only when customization data is sent over. After checking it, we simply run the methods Prestashop uses when submitting a regular customization form:</p>
<pre class="brush: php; title: ; notranslate">

			$this-&gt;pictureUpload();
			$this-&gt;textRecord();
			$this-&gt;formTargetFormat();


</pre>
<p>Please notice <strong>pictureUpload</strong> is currently not being used, as we are not uploading anything. Also, we need to create a new cart in case it does not exist, before adding the text to it, so it has an id to deal with.</p>
<p>Then, we check for errors, sending them back to the ajax-cart.js file if there are, otherwise returning success. Since we want to make sure data has been saved, let&#8217;s go back to our JS for a second, and do something on the &#8220;success&#8221; method of the ajax call:</p>
<pre class="brush: jscript; title: ; notranslate">
		if(addedFromProductPage &amp;&amp; $('#customizationForm').length &gt; 0)
		{
	
			$('#quantityBackup').val($('#quantity_wanted').val());
			customAction = $('#customizationForm').attr('action');
			$('body select[id^=&quot;group_&quot;]').each(function() {
				customAction = customAction.replace(new RegExp(this.id + '=\\d+'), this.id +'=' + this.value);
			});
			// ajax to product page with custom action
			var customization_entries = $('#customizationForm').serialize();
			$.ajax({
				type: 'POST',
				data: customization_entries+ '&amp;ajax=1',
				dataType: 'json',
				url: customAction,
				success: function(data){
					if(typeof(data.errors) !== 'undefined')
					{
						alert('Error while saving customization data');
						return;
					}
						
				}
			})	
		}
</pre>
<p>We basically only added this part</p>
<pre class="brush: jscript; title: ; notranslate">

if(typeof(data.errors) !== 'undefined')
{
	alert('Error while saving customization data');
	return;
}

</pre>
<p>To the success handler, that triggers when the ajax call is successful. Of course, you might want to expand this, and add a further level of checks to make sure data has really been saved. However, if the field is required, your product will not be added to the cart, in any case.</p>
<p>At this point, try writing something in the field, then click add to cart. <strong>What? Not working? Why?</strong> Prestashop can be nasty to deal with; we have to perform one last modification.</p>
<div class="separator"></div>
<h2>Tools.js</h2>
<p>The last file we need to deal with might be a pain in case you upgrade. Therefore, make sure you keep a backup of the modification and/or write these steps somewhere, in case you need to apply them again. Open up <em>js/tools.js</em>. What we are interested in is the <strong>checkCustomizations</strong> method:</p>
<pre class="brush: jscript; title: ; notranslate">
function checkCustomizations()
{
	var pattern = new RegExp(' ?filled ?');

	if (typeof customizationFields != 'undefined')
		for (var i = 0; i &lt; customizationFields.length; i++)
		{
			/* If the field is required and empty then we abort */
			if (parseInt(customizationFields[i][1]) == 1 &amp;&amp; ($('#' + customizationFields[i][0]).html() == '' ||  $('#' + customizationFields[i][0]).text() != $('#' + customizationFields[i][0]).val()) &amp;&amp; !pattern.test($('#' + customizationFields[i][0]).attr('class')))
				return false;
		}
	return true;
}
</pre>
<p>Pay attention to the following line</p>
<pre class="brush: jscript; title: ; notranslate">
function checkCustomizations()
{
	if (parseInt(customizationFields[i][1]) == 1 &amp;&amp; ($('#' + customizationFields[i][0]).html() == '' ||  $('#' + customizationFields[i][0]).text() != $('#' + customizationFields[i][0]).val()) &amp;&amp; !pattern.test($('#' + customizationFields[i][0]).attr('class')))
				return false;


</pre>
<p>This is what is currently preventing us from saving our customization. Actually, it gets saved, but the product is not added to the cart.<br />
let&#8217;s get rid of a good portion of it</p>
<pre class="brush: jscript; title: ; notranslate">

	if (parseInt(customizationFields[i][1]) == 1 &amp;&amp; ($('#' + customizationFields[i][0]).val() == ''))
		return false;


</pre>
<p>The only thing we are doing to check it, is making sure it has a value. THat is all we need for now!<br />
Refresh and test, it should be working now!</p>
<div class="separator"></div>
<h2>Next up&#8230;</h2>
<p>Saving text customization fields when hitting the add to cart button was not too complicated. Things will get really nasty in the next tutorial, when we will deal with asynchronous file uploads! Stay tuned!</p>
<p><a href="http://nemops.com/save-prestashop-custom-fields-add-to-cart-2/#.VUnNyfnzrmi" title="Save Prestashop Custom fields on “Add to cart” – Part 2"> Save Prestashop Custom fields on “Add to cart” – Part 2 &raquo;</a></p>
<p>The post <a rel="nofollow" href="http://nemops.com/save-prestashop-custom-fields-add-to-cart/">Save Prestashop Custom fields on &#8220;Add to cart&#8221; &#8211; Part 1</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/save-prestashop-custom-fields-add-to-cart/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
	</channel>
</rss>
