0

I want to add a field for my customers to upload an image when they will purchase a product or add to cart a product. When input type if file it allows to upload a photo but it does not work. Can anybody give me that solution?

<div class="product-form__item product-form__item-uplpic">
    <label for="photo">Upload Photo</label>
    <input required class="product-form__input required" id="photo" type="file" name="properties[Uploaded Image]">
</div>
Dave B
  • 3,038
  • 1
  • 13
  • 18

2 Answers2

3

You can definitely give your customers an opportunity to upload images, which on its own is fairly straightforward but often complicated by Shopify themes.

If you use a field with a type="input" and a name with name="properties[some custom property name]" you can upload images with a proper form submit. If you're already familiar with how to add custom line-item properties, this structure should look fairly familiar. If your form is submitting normally but you are still not seeing your upload, make sure that the form tag has enctype="multipart/form-data" set.

However, where things get tricky is when themes jump in to do all kinds of fancy things. If your theme keeps you on the product page when you hit the 'add-to-cart' button, your theme is using Shopify's API endpoints to add products using Javascript rather than a normal HTML POST of the form. Every theme that I have seen that implements this type of feature does so in an incomplete way, which is to use something similar to data = jQuery(form).serialize() to get a text string representing all of the user selections in the form - but a file upload field cannot be serialize'd in this way, so it will be ignored.

There are two ways to get around this common theme limitation:

1) Turn off or otherwise disable the javascript-based add-to-cart feature on your store. In some themes, this can be done by going to your theme's customization page in the admin - usually the feature can be turned off in the settings under the 'Cart' or 'Product' header by specifying that you want customers to go to the Cart page after a product add. (Exactly how it's sorted or what the wording will be is entirely under the control of the theme designer - if you're having trouble finding it, you should be able to reach out to the theme provider for assistance)

2) If you are comfortable with a bit of coding, you can customize your theme to still do the fancy stay-on-page product additions by making just a few changes to the code. Instead of using a .serialize() function (or similar) to get the data, you would instead use a FormData object. If using jQuery to post the data, you will need to specify a few additional options to stop jQuery from doing too much. Specifically, you will need to set processData: false, contentType: false in your AJAX settings object. If using Fetch or a plain ol' XHR request, just remember that your Content-type is multipart/form-data.

Note: If using method #2 to upgrade your theme's add-to-cart function, at present this will cause Shopify's built-in tracking code ("Trekkie") to fail on cart-additions. Trekkie hijacks the browser's native XMLHttpRequest.prototype.send function to wrap it with some tracking code, and that tracking code assumes that anything being posted is a JSON object/serialized form.

References: Form enctypes: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/enctype

Using FormData objects: https://developer.mozilla.org/en-US/docs/Web/API/FormData

Using FormData with jQuery: https://stackoverflow.com/a/5976031/2592369 (Note: You have an existing form, see the part on "Create FormData from an existing form"

Product customizations: https://help.shopify.com/en/themes/customization/products/features/get-customization-information-for-products#allow-file-uploads (Note: The Shopify article claims that popup/drawer carts are not compatible with file uploads - this is only partially true, as theme developers could design their themes to have such compatibility - they just choose not to)

Dave B
  • 3,038
  • 1
  • 13
  • 18
0

var file = new File([blob], "businesscard_"+new Date().getTime()+".png",{type:"image/png", lastModified:new Date().getTime()});

const addtocartform = document.querySelector('.addtocartform');
const formdataobj = new FormData(addtocartform); 
let dt = new DataTransfer();
dt.items.add(file);
let file_list = dt.files;
document.getElementById("proimagebc").files = file_list;
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 22 '22 at 08:35