0
votes

My Shopify app replaces the product pages 'Add To Cart' form / product form, with it's own form of sorts. It is Liquid logic that decides whether or not to render the entire <form> element.

This works great, but on some themes (like Jumpstart by Shopify), the product page bugs out completely, throwing me an error saying: option_selection.js - can't access its "parentNode" property Which I believe is the option_selection.js function where it is looking for the select box / variant ID somewhere on the page.

Of course, this variant ID / select box does not exist because it is not being rendered.

How can I replace the add to cart form while satisfying the option_selection.js functions?

Usually this wouldn't be a big deal, but Shopify's app review team will give me problems with this, and on the Jumpstart theme specifically, this error causes the product photos to not render; breaking the page completely.

Any ideas here? Much appreciated!

1

1 Answers

1
votes

Axing the entire product form seems a bit extreme - there's no way to do what you need to do in a less invasive way?

Assuming not, you'll want to expand your install so that you can update any code in a theme that initializes the product form to take into account the possibility that you've defied the theme's simplistic assumptions.

For the option_selection.js compatibility, you'll be looking for where new Shopify.OptionSelectors is being invoked. If your code has set a variable through Javascript, that may be the easiest check to make. Example of an inline install that assumes your code creates a function named MyAppNamespace.isProdHidden:

Original:

new Shopify.OptionSelectors( ... 

Updated:

!(window.MyAppNamespace && MyAppNamespace.isProdHidden({{ product.id | json }}) ) && new Shopify.OptionSelectors( ...

The added piece of code will evaluate to false if and only if your app has loaded properly and your isProdHidden function returns a truthy value. This scenario would prevent the new Shopify.OptionSelectors part from running, since we're using the && as a sort of short-circuit/emergency-stop operation.

If your app failed to load (or was uninstalled from the store without the liquid code being updated), or if MyAppNamespace.isProdHidden returns false, then the added block of code evaluates as true and the new Shopify.OptionSelectors happens as normal.

The above is equivalent to wrapping the entire new Shopify.OptionSelectors call in an if statement, with the install benefit that the party installing your app doesn't need to read the theme code to figure out where the OptionSelectors call ends. In most themes the OptionSelectors code is spread out over multiple lines and occasionally theme developers declare their onVariantChange function as an inline anonymous function - neither of which are big obstacles for experienced developers, but a huge complication for novices and store owners without this kind of expertise.

Making the status of your app available somehow through Javascript is probably the best thing for you to do as far as theme-install-compatibility goes. Some themes have their OptionSelectors call right in the product page, which can be affected by dynamic Liquid variables, but many have this code tucked away in a .js file in the assets folder instead. Still other themes don't use Shopify's OptionSelectors code at all and instead run their own thing, and thus your app could interfere in completely unexpected ways or places. Creating tools to make it easier to integrate your app into somebody else's code is therefore one of the best things you can do.

You'll also want to make sure that your code is able to handle multiple products, as many stores have quick-shops all through the site which can load arbitrary product forms. By making sure you have made the tools available, it's possible for you, your support team (if any) and theme devs can make the required updates to (almost!) any arbitrary theme.

Hope that helps!