Hello Community,
I recently integrated Uploadcare with Marketo, i add the following code to the forms rich text and the upload section was visible in the form:
<script type="module">// <![CDATA[
import * as UC from 'https://cdn.jsdelivr.net/npm/@uploadcare/file-uploader@1/web/uc-file-uploader-regular.min.js';
UC.defineComponents(UC);
// ]]></script>
<uc-config ctx-name="my-uploader" use-cloud-image-editor="false" source-list="local" pubkey="public-key"></uc-config> <uc-file-uploader-regular ctx-name="my-uploader" class="uc-light"></uc-file-uploader-regular>
I’d like to know how to get the link to an uploaded asset in Marketo and currently, as soon as I upload an image, it gets immediately uploaded to Uploadcare, is there a way to prevent this and instead trigger the upload only when the form is submitted?
Thank you!
Solved! Go to Solution.
... it gets immediately uploaded to Uploadcare, is there a way to prevent this and instead trigger the upload only when the form is submitted?
Why, exactly, do you care about this? Writing the code to stop the Marketo form from submitting until the UC upload is complete is quite tricky.
If you’re concerned about storage space being used by people who don’t submit the form, mark uploads as temporary and then confirm storage using a webhook if/when they submit.
Hi @ok82, here is the HTML and CSS you have to use to get the URL in Marketo field.
Add this script in Rich text field
<script type="module">// <![CDATA[
import * as UC from "https://cdn.jsdelivr.net/npm/@uploadcare/file-uploader@1/web/uc-file-uploader-regular.min.js";
UC.defineComponents(UC);
const providerNode = document.getElementById("my-uploader-provider");
const previewsNode = document.getElementById("previews");
/*
Note: Event binding is the main way to get data and other info from File Uploader.
There plenty of events you may use.
See more: https://uploadcare.com/docs/file-uploader/events/
*/
providerNode.addEventListener("change", handleChangeEvent);
function handleChangeEvent(e) {
console.log("change event payload:", e);
renderFiles(e.detail.allEntries.filter((f) => f.status === "success"));
}
function renderFiles(files) {
const renderedFiles = files.map((file) => {
const fileNode = document.createElement("div");
fileNode.setAttribute("class", "preview-wrapper");
const imgNode = document.createElement("img");
imgNode.setAttribute("class", "preview-image");
imgNode.setAttribute("src", file.cdnUrl);
imgNode.setAttribute("width", "200");
imgNode.setAttribute("height", "auto");
fileNode.append(imgNode);
return fileNode;
});
previewsNode.replaceChildren(...renderedFiles);
}
function formatSize(bytes) {
if (!bytes) return "0 Bytes";
const k = 1024;
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return `${parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`;
}
// ]]></script>
<input type="hidden" role="my-uploader" name="my_file" id="uploadcare-file" /> <uc-config ctx-name="my-uploader" pubkey="Insert your key" sourcelist="local, url, camera, dropbox" source-list="local, url, camera, dropbox" style="--ctx-name: 'my-uploader';"></uc-config> <uc-file-uploader-regular ctx-name="my-uploader" class="uc-light" uc-wgt-common="" uc-file-uploader-regular="" style="--ctx-name: 'my-uploader';"></uc-file-uploader-regular> <uc-upload-ctx-provider ctx-name="my-uploader" id="my-uploader-provider" style="--ctx-name: 'my-uploader';"></uc-upload-ctx-provider>
<div class="previews" id="previews"><br /></div>
Then again add this script in another rich text element
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script>// <![CDATA[
MktoForms2.whenReady(function(form){
form.onValidate(function() {
var vals = form.vals();
var ImageURL = jQuery('.preview-image').attr('src');
form.vals({"Add Hidden Field Name":ImageURL });
if (vals.uploadedFile== "") {
// Prevent form submission
form.submittable(false);
// Show error message, pointed at VehicleSize element
var uploadCheck = form.getFormElem().find(".uc-light");
form.showErrorMessage("Please upload receipt", uploadCheck);
}
else {
// Enable submission for those who met the criteria
form.submittable(true);
}
});
});
// ]]></script>
Please add hidden field and update the same name in above script.
After that, please add these CSS in Custom CSS option
@import url("https://cdn.jsdelivr.net/npm/@uploadcare/file-uploader@1/web/uc-file-uploader-regular.min.css");
.my-config {
--uc-primary-oklch-dark: 69% 0.1768 258.4;
--uc-primary-oklch-light: 59% 0.22 264;
}
After adding this, you can see the value in hidden field and also the image will show the preview like this
Please let me know if you face any issue.
Thanks,
Disha
Hi @ok82, I have implemented the uploadcare integration and we can get the link of the uploaded image in one of the Marketo field but for second point that image will be uploaded when form is submit is something that we have to check.
Before sharing the solution, could you share please the test LP where I can check if my solution is working or not?
Hello @Disha_Goyal6,
Thank you for the response.
Here is a test link: https://001-nqn-302.mktoweb.com/lp/001-NQN-302/Test.html
Hi @ok82, here is the HTML and CSS you have to use to get the URL in Marketo field.
Add this script in Rich text field
<script type="module">// <![CDATA[
import * as UC from "https://cdn.jsdelivr.net/npm/@uploadcare/file-uploader@1/web/uc-file-uploader-regular.min.js";
UC.defineComponents(UC);
const providerNode = document.getElementById("my-uploader-provider");
const previewsNode = document.getElementById("previews");
/*
Note: Event binding is the main way to get data and other info from File Uploader.
There plenty of events you may use.
See more: https://uploadcare.com/docs/file-uploader/events/
*/
providerNode.addEventListener("change", handleChangeEvent);
function handleChangeEvent(e) {
console.log("change event payload:", e);
renderFiles(e.detail.allEntries.filter((f) => f.status === "success"));
}
function renderFiles(files) {
const renderedFiles = files.map((file) => {
const fileNode = document.createElement("div");
fileNode.setAttribute("class", "preview-wrapper");
const imgNode = document.createElement("img");
imgNode.setAttribute("class", "preview-image");
imgNode.setAttribute("src", file.cdnUrl);
imgNode.setAttribute("width", "200");
imgNode.setAttribute("height", "auto");
fileNode.append(imgNode);
return fileNode;
});
previewsNode.replaceChildren(...renderedFiles);
}
function formatSize(bytes) {
if (!bytes) return "0 Bytes";
const k = 1024;
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return `${parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`;
}
// ]]></script>
<input type="hidden" role="my-uploader" name="my_file" id="uploadcare-file" /> <uc-config ctx-name="my-uploader" pubkey="Insert your key" sourcelist="local, url, camera, dropbox" source-list="local, url, camera, dropbox" style="--ctx-name: 'my-uploader';"></uc-config> <uc-file-uploader-regular ctx-name="my-uploader" class="uc-light" uc-wgt-common="" uc-file-uploader-regular="" style="--ctx-name: 'my-uploader';"></uc-file-uploader-regular> <uc-upload-ctx-provider ctx-name="my-uploader" id="my-uploader-provider" style="--ctx-name: 'my-uploader';"></uc-upload-ctx-provider>
<div class="previews" id="previews"><br /></div>
Then again add this script in another rich text element
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script>// <![CDATA[
MktoForms2.whenReady(function(form){
form.onValidate(function() {
var vals = form.vals();
var ImageURL = jQuery('.preview-image').attr('src');
form.vals({"Add Hidden Field Name":ImageURL });
if (vals.uploadedFile== "") {
// Prevent form submission
form.submittable(false);
// Show error message, pointed at VehicleSize element
var uploadCheck = form.getFormElem().find(".uc-light");
form.showErrorMessage("Please upload receipt", uploadCheck);
}
else {
// Enable submission for those who met the criteria
form.submittable(true);
}
});
});
// ]]></script>
Please add hidden field and update the same name in above script.
After that, please add these CSS in Custom CSS option
@import url("https://cdn.jsdelivr.net/npm/@uploadcare/file-uploader@1/web/uc-file-uploader-regular.min.css");
.my-config {
--uc-primary-oklch-dark: 69% 0.1768 258.4;
--uc-primary-oklch-light: 59% 0.22 264;
}
After adding this, you can see the value in hidden field and also the image will show the preview like this
Please let me know if you face any issue.
Thanks,
Disha
This is a good sketch, but there are a number of problems with the code.
1. You can’t simply add form behaviors JS inside a Rich Text form field because the code runs twice. You must follow this guide to not create bugs:
As noted in that post, it’s always safer to include custom forms JS inside a separate script
element, outside the form, not in a RTA.
2. When adding a custom onValidate
listener, you should first check if the native Marketo form validation has passed and exit if it hasn’t. Typically you want validation for First Name, Last Name, etc. to run before any custom validation like whether an UploadCare upload has has finished.
So any onValidate
listener should start like this:
readyForm.onValidate(function(nativeValid){
if( !nativeValid ) return;
3. There’s no reason to use jQuery here at all but you definitely should not be loading an entire extra copy of the library as it heavily dings performance! Marketo forms already have jQuery available as MktoForms2.$
.
4. Relatively minor but you don’t need to fetch the cdnURL
of the UploadCare upload to preview the image. That’s an unnecessary network fetch, noticeable on slow connections. The locally stored file
can be used directly.
5. You should constrain any DOM queries to the current <form>
element, not search the whole document. It’s possible for there to be multiple forms on the page, each with their own uploader. The code would bug out in that case.
@SanfordWhiteman, thanks for sharing the feedback. I will try this and implement for my current and future projects.
... it gets immediately uploaded to Uploadcare, is there a way to prevent this and instead trigger the upload only when the form is submitted?
Why, exactly, do you care about this? Writing the code to stop the Marketo form from submitting until the UC upload is complete is quite tricky.
If you’re concerned about storage space being used by people who don’t submit the form, mark uploads as temporary and then confirm storage using a webhook if/when they submit.