Jump to content

  • You cannot start a new topic
  • You cannot reply to this topic

Problem Submitting Form By Ajax Rate Topic   - - - - -

 
  • Karstedt
  • Member
  • Members
  • Join Date: 09-Dec 15
  • 40 posts

Posted 24 August 2018 - 02:28 AM #1

I am making a dynamically updated search results page and am having trouble with the 'add to cart' form submit.

 

Firstly, I tried to just rely on the ajax microformats and basically reproduced the DOM structure of an existing add to cart form with qty changer.

 

The result works but causes a page reload instead of showing the cm-ajax-status-middle indicator and not reloading the page like the static form does.

 

I came to suspect that this was because the form is relying on the attached event listener that runs the function '_check(form)'.

 

So I made my own event listener. I can't directly call the _check function (it's undefined if called in my add-on script), so I tried to reproduce the final outcome which looks like this:

// event listener for all 'add to cart' forms in container
$('#container').on('submit', function (event) {
  var clicked_elm = $(event.target);
  var form = $(event.target);
  return $.ceAjax('submitForm', form, clicked_elm);
});

Originally I thought clicked_elm and form would be the 'a' element and the 'form' element respectively, but watching the variables showed them both to be the 'form' element on the working static version. Anyhow, I get the status indicator, but the form doesn't submit and gives an error notification:

 

Error Oops, something went wrong (SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data). Please try again.

 

So the post request is not getting passed as JSON, probably because I'm bypassing the _check function.

 

Any ideas to correct the problem?

 

Side question - the docs imply that using microformats is sufficient to achieve the 'background' form submit without a page reload and don't mention the event listener. Is that just an oversight?

 

 



 
  • tbirnseth
  • CS Cart Expert
  • Authorized Reseller
  • Join Date: 08-Nov 08
  • 10838 posts

Posted 24 August 2018 - 05:04 AM #2

Make sure the div that contains your form the the id in comments just before the closing div tag.

EZ Merchant Solutions: Custom (USA based) B2B Development, Consulting, Development and Special Projects (get a quote here).
Commercial addons, payment methods and modifications to meet your business and operations needs.


 
  • Karstedt
  • Member
  • Members
  • Join Date: 09-Dec 15
  • 40 posts

Posted 24 August 2018 - 05:27 AM #3

Make sure the div that contains your form the the id in comments just before the closing div tag.

What do you mean? Like this:

<!--{{objectID}}-->
</form>

I tried this and it gives the same error... but some of the input data does get dynamically rewritten just under the comment.



 
  • tbirnseth
  • CS Cart Expert
  • Authorized Reseller
  • Join Date: 08-Nov 08
  • 10838 posts

Posted 24 August 2018 - 07:19 PM #4

You should be able to subimit a form via ajax without re-rendering any part of the page.  However, if the result from the server side has html content returned, then it will effectively reload the page.  If the server just exits without output, then no re-rendering is done since the JS simply sent data to the server.

 

To render a certain area within a page in cs-cart from an ajax request, it uses JS to figure out what portion of the fully rendered page to apply from the response.  A 'result_ids' request parameter contains the id's of elements to re-render upon return.

 

Example

<form blah blah>
<input type="hidden" name="result_ids" value="shipping_rates_list" />
<div id="shipping_rates_list">
  Your html here
<!--shipping_rates_list--></div>
</form>

 

Just look for some examples where cm-ajax is used in common templates like products, cart, checkout, etc..  Using cm-ajax should cause an ajax request, but to render the response, you need the comment before the closing div and these need to be in a result_ids request element.

 

What this does is sends the form via ajax and then the whole page is re-rendered on the server side.  It's sent to the browser and the JS in the browser finds the appropriate areas to update within the DOM.  It keeps things pretty simple on the server side since the whole page is always re-rendered.

 

Hope this makes sense.  Don't want to do a tutorial here, no time.


EZ Merchant Solutions: Custom (USA based) B2B Development, Consulting, Development and Special Projects (get a quote here).
Commercial addons, payment methods and modifications to meet your business and operations needs.


 
  • Karstedt
  • Member
  • Members
  • Join Date: 09-Dec 15
  • 40 posts

Posted 25 August 2018 - 12:09 AM #5

I think I get what you are saying... to dynamically update a DOM element you pass the id to 'result_ids' and include a comment at the end of the DOM element. I don't think that is the problem though.

 

I found the JSON error issue (just a bad parameter), but the form still doesn't work with AJAX. Might be easier to give a sample form:

<form action="http://localhost/cscart/" method="post" name="product_form_41650" enctype="multipart/form-data" class="cm-disable-empty-files cm-ajax cm-ajax-status-middle">
  <input name="result_ids" value="cart_status*,wish_list*,checkout*,account_info*" type="hidden">
  <input name="redirect_url" value="index.php?subcats=Y&amp;pcode_from_q=Y&amp;pshort=Y&amp;pfull=Y&amp;pname=Y&amp;pkeywords=Y&amp;search_performed=Y&amp;pfull=N&amp;match=all&amp;q=lanx+10&amp;dispatch=products.search" type="hidden">
  <input name="product_data[41650][product_id]" value="41650" type="hidden">
  <div class="clearfix vs-qty-buttons small-btn">
	<div class="ty-float-left vs-qty ty-product-list__qty">
	  <div class="cm-reload-41650" id="qty_update_41650">
		<input name="appearance[show_qty]" value="1" type="hidden">
		<input name="appearance[capture_options_vs_qty]" value="" type="hidden">

		<div class="ty-qty clearfix changer" id="qty_41650">
			<div class="ty-center ty-value-changer cm-value-changer">
				<a class="cm-decrease ty-value-changer__decrease">−</a>
				<input size="5" class="input-text-short cm-amount" id="qty_count_41650" name="product_data[41650][amount]" value="1" data-ca-min-qty="1" type="text">
				<a class="cm-increase ty-value-changer__increase">+</a>
			</div>
		</div>
		<!--qty_update_41650-->
	  </div>
	</div>
	<div class="add-product clearfix ty-product-list__control">
	  <div class="cm-reload-41650" id="add_to_cart_update_41650">
		<input name="appearance[show_add_to_cart]" value="1" type="hidden">
		<input name="appearance[show_list_buttons]" value="1" type="hidden">
		<input name="appearance[but_role]" value="action" type="hidden">
		<input name="appearance[quick_view]" value="" type="hidden">
		<span id="cart_add_block_41650">
		  <a class="ty-btn vs-atc cm-submit text-button vs-text-w-icon" id="button_cart_41650" data-ca-dispatch="dispatch[checkout.add..41650]">
			<i class="vs-icon-top-cart"></i>Add to Cart
		  </a>
		</span>
		<!--add_to_cart_update_41650-->
	  </div>
	</div>
  </div>
</form>

Now, with no event listener, the form works, the cart is updated, but there is no ajax status indicator and the page reloads to the redirect URL (without the redirect URL it goes to the cart page) and gives the pop-up for product added. It works but I don't like it.

 

When I add my listener:

$('#parentcontainer').on('submit', function (event) {
  var clicked_elm = $(event.target);
  var form = $(event.target);
  return $.ceAjax('submitForm', form, clicked_elm);
});

I get the ajax status indicator for a second but nothing really happens, the cart does not update. The request looks good except is has an empty 'product_form_####' parameter (dunno why), and the response is different in that its html is an unchanged 'cart_status*' and has no 'notification' in it.



 
  • Karstedt
  • Member
  • Members
  • Join Date: 09-Dec 15
  • 40 posts

Posted 25 August 2018 - 02:09 AM #6

I found one problem, tired eyes could not see.

 

Turns out the variables 'form' and 'clicked_elm' were not the same as I originally thought. This resulted in the data-dispatch-ca parameter on the button not being passed in the request, hence the cart was not updated.

 

Solution in my listener:

$('#hits').on('submit', function (event) {
  var clicked_elm = $(event.target.lastChild);
  var form = $(event.target);
  return $.ceAjax('submitForm', form, clicked_elm);
});

Using 'target.lastChild' is probably not the ideal targeting method for getting the button/link, but since 'target' ends up being the form itself and not the clicked element, it is a quick fix.

 

Now it's all working EXCEPT.... the cart element on the page is not updating... *rips out hair*...

 

EDIT: easy fix this time, just needed cm-ajax-full-render class.



 
  • tbirnseth
  • CS Cart Expert
  • Authorized Reseller
  • Join Date: 08-Nov 08
  • 10838 posts

Posted 25 August 2018 - 07:40 PM #7

Welcome to cs-cart!

EZ Merchant Solutions: Custom (USA based) B2B Development, Consulting, Development and Special Projects (get a quote here).
Commercial addons, payment methods and modifications to meet your business and operations needs.