Last active
June 12, 2022 00:23
-
-
Save acabreragnz/9ee0631e6bc15cde6ac72bb8ebdc4f88 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
document.addEventListener('DOMContentLoaded', function() { | |
console.log('loading zendesk form builder'); | |
let REPORT_BUG_ARTICLE_ID = '6509556532759'; | |
let REPORT_BUG_TICKET_ID = '6504444995991'; | |
let CONTACT_US_ARTICLE_ID = '6510266315671'; | |
let CONTACT_US_TICKET_ID = '5754824917015'; | |
let FORM_PARENT_ID = 'request-form'; | |
let FORM_PARENT_CLASS = 'article-content'; | |
const CUSTOM_FIELDS = { | |
firstName: { | |
id: '6505585946775', | |
labelText: 'First Name', | |
}, | |
lastName: { | |
id: '6505541331223', | |
labelText: 'Last Name', | |
}, | |
operatingSystem: { | |
id: '5843778091287', | |
labelText: 'Operating System', | |
}, | |
browser: { | |
id: '5843796719767', | |
labelText: 'Browser Type & Version', | |
hintText: 'Please enter the model and version', | |
}, | |
} | |
if (TEST_MODE) { | |
REPORT_BUG_ARTICLE_ID = '6941241013140'; | |
// https://bixlabs7184.zendesk.com/admin/objects-rules/tickets/ticket-forms | |
REPORT_BUG_TICKET_ID = '6509556532759'; | |
// CONTACT_US_ARTICLE_ID = ''; | |
// CONTACT_US_TICKET_ID = ''; | |
// https://bixlabs7184.zendesk.com/admin/objects-rules/tickets/ticket-fields | |
CUSTOM_FIELDS.browser.id = '6942533341204'; | |
} | |
const CUSTOM_FIELDS_IN_CONTACT_US_REQUEST = [ | |
CUSTOM_FIELDS.firstName, | |
CUSTOM_FIELDS.lastName, | |
] | |
const CUSTOM_FIELDS_IN_REPORT_A_BUG_REQUEST = [ | |
CUSTOM_FIELDS.firstName, | |
CUSTOM_FIELDS.lastName, | |
CUSTOM_FIELDS.operatingSystem, | |
CUSTOM_FIELDS.browser, | |
] | |
const hasToBuildReportBugForm = window.location.pathname.includes(REPORT_BUG_ARTICLE_ID); | |
const hasToBuildContactUsForm = window.location.pathname.includes(CONTACT_US_ARTICLE_ID); | |
let currentRequestId; | |
if (hasToBuildReportBugForm) { | |
currentRequestId = REPORT_BUG_TICKET_ID; | |
buildReportBugForm(); | |
} else if (hasToBuildContactUsForm) { | |
currentRequestId = CONTACT_US_TICKET_ID; | |
buildContactUsForm(); | |
} else { | |
// NOW: borrar | |
currentRequestId = REPORT_BUG_TICKET_ID; | |
buildReportBugForm(); | |
} | |
function buildReportBugForm() { | |
const form = createForm(trigger); | |
appendChildToForm(form, CUSTOM_FIELDS_IN_REPORT_A_BUG_REQUEST); | |
appendFormToParent(form); | |
} | |
function buildContactUsForm() { | |
const form = createForm(trigger); | |
appendChildToForm(form, CUSTOM_FIELDS_IN_CONTACT_US_REQUEST); | |
appendFormToParent(form); | |
} | |
function createForm(submitListener) { | |
const form = document.createElement('form'); | |
form.setAttribute('action', ''); | |
form.setAttribute('method', 'POST'); | |
form.addEventListener('submit', submitListener); | |
return form; | |
} | |
function appendChildToForm(form, customFieldsToAppend) { | |
const emailEl = createFormInput({ | |
name: 'email', | |
labelText: 'Your email address', | |
}); | |
form.appendChild(emailEl); | |
createAndAppendCustomFields(form, customFieldsToAppend); | |
const subjectEl = createFormInput({ | |
name: 'subject', | |
labelText: 'Subject', | |
}); | |
const descriptionEl = createFormTextArea({ | |
name: 'description', | |
labelText: 'Description', | |
hintText: 'Please enter the details of your request. A member of our support staff will respond as soon as possible.', | |
}); | |
const attachmentsEl = createFormInput({ | |
name: 'attachments', | |
labelText: 'Attachments (optional)', | |
type: 'file', | |
}); | |
form.appendChild(subjectEl); | |
form.appendChild(descriptionEl); | |
form.appendChild(attachmentsEl); | |
createAndAppendSubmitButton(form); | |
} | |
function createFormInput({ | |
name = '', | |
labelText = '', | |
isCustomField = false, | |
customFieldId = '', | |
hintText = '', | |
type = 'text', | |
}) { | |
const baseId = isCustomField && customFieldId ? `request_custom_fields_${customFieldId}` : `request_${name}`; | |
const inputId = baseId; | |
const labelEl = createLabelEl({ | |
id: baseId + '_label', | |
htmlFor: inputId, | |
text: labelText, | |
}); | |
const inputEl = createInputEl({ | |
id: inputId, | |
name: name || (isCustomField ? generateNameForCustomField(customFieldId) : ''), | |
type, | |
}); | |
const formFieldEl = document.createElement('div'); | |
formFieldEl.setAttribute('class', 'form-field string required'); | |
formFieldEl.appendChild(labelEl); | |
formFieldEl.appendChild(inputEl); | |
if (hintText) { | |
const hintEl = document.createElement('p'); | |
hintEl.setAttribute('id', baseId + '_hint'); | |
hintEl.innerText = hintText; | |
formFieldEl.appendChild(hintEl); | |
} | |
return formFieldEl; | |
}; | |
function createAndAppendCustomFields(form, customFieldsToAppend) { | |
customFieldsToAppend.forEach(({ id, name, labelText, hintText }) => { | |
form.appendChild(createFormInput({ | |
customFieldId: id, | |
isCustomField: true, | |
name, | |
labelText, | |
hintText, | |
})); | |
}); | |
} | |
function appendFormToParent(form) { | |
let formParentEl = document.getElementById(FORM_PARENT_ID); | |
formParentEl ??= document.getElementsByClassName(FORM_PARENT_CLASS)[0]; | |
formParentEl.appendChild(form); | |
formParentEl.setAttribute('class', 'form'); | |
} | |
function createAndAppendSubmitButton(form) { | |
const footer = document.createElement('footer'); | |
const submitButton = document.createElement('input'); | |
submitButton.setAttribute('type', 'submit'); | |
submitButton.innerText = 'Submit'; | |
footer.appendChild(submitButton); | |
form.appendChild(footer); | |
} | |
function createFormTextArea({ | |
name = '', | |
labelText = '', | |
isCustomField = false, | |
customFieldId = '', | |
hintText = '', | |
}) { | |
const baseId = isCustomField && customFieldId ? `request_custom_fields_${customFieldId}` : `request_${name}`; | |
const textAreaId = baseId; | |
const labelEl = createLabelEl({ | |
id: baseId + '_label', | |
htmlFor: textAreaId, | |
text: labelText, | |
}); | |
const textAreaEl = createTextAreaEl({ | |
id: textAreaId, | |
name: name || (isCustomField ? generateNameForCustomField(customFieldId) : ''), | |
}); | |
const formFieldEl = document.createElement('div'); | |
formFieldEl.setAttribute('class', 'form-field string required'); | |
formFieldEl.appendChild(labelEl); | |
formFieldEl.appendChild(textAreaEl); | |
if (hintText) { | |
const hintEl = document.createElement('p'); | |
hintEl.setAttribute('id', baseId + '_hint'); | |
hintEl.innerText = hintText; | |
formFieldEl.appendChild(hintEl); | |
} | |
return formFieldEl; | |
}; | |
function createLabelEl({ | |
id, | |
text, | |
htmlFor, | |
}) { | |
const labelEl = document.createElement('label'); | |
labelEl.setAttribute('id', id); | |
labelEl.setAttribute('for', htmlFor); | |
labelEl.innerText = text; | |
return labelEl; | |
} | |
function createInputEl({ | |
id, | |
name, | |
placeholder = '', | |
type = 'text', | |
required = false, | |
className = '', | |
}) { | |
const inputEl = document.createElement('input'); | |
inputEl.setAttribute('id', id); | |
inputEl.setAttribute('type', type); | |
inputEl.setAttribute('class', className); | |
inputEl.setAttribute('name', name); | |
inputEl.setAttribute('required', required); | |
inputEl.setAttribute('placeholder', placeholder); | |
if (type === 'file') { | |
inputEl.setAttribute('multiple', true); | |
} | |
return inputEl; | |
} | |
function createTextAreaEl({ | |
id, | |
name, | |
required = false, | |
className = '', | |
}) { | |
const textAreaEl = document.createElement('textarea'); | |
textAreaEl.setAttribute('id', id); | |
textAreaEl.setAttribute('class', className); | |
textAreaEl.setAttribute('name', name); | |
textAreaEl.setAttribute('required', required); | |
return textAreaEl; | |
} | |
function generateNameForCustomField(fieldId) { | |
return `request[custom_fields][${fieldId}]` | |
} | |
async function trigger(event) { | |
event.preventDefault(); | |
const formData = new FormData(event.target); | |
const value = Object.fromEntries(formData.entries()); | |
const uploadResults = await uploadAttachments(); | |
const customFields = buildCustomFields(value) | |
const uploads = uploadResults | |
.filter((result) => result.status === 'fulfilled') | |
.map((result) => result.value); | |
fetch("/api/v2/requests.json", | |
{ | |
body: JSON.stringify({ | |
request: { | |
requester: { | |
name: value.email | |
}, | |
subject: value.subject, | |
comment: { | |
body: value.description, | |
uploads: uploads.map(({ upload }) => upload.token), | |
}, | |
custom_fields: customFields, | |
ticket_form_id: currentRequestId, | |
} | |
}), | |
headers: { | |
"Content-Type": "application/json" | |
}, | |
method: "POST" | |
}) | |
} | |
function buildCustomFields(formData) { | |
return Object | |
.entries(formData) | |
.flatMap(([key, value]) => { | |
const matches = key.match(/request\[custom_fields]\[(\d+)]/); | |
if (matches) return [{ id: matches[1], value }]; | |
}) | |
.filter(Boolean); | |
} | |
async function uploadAttachments() { | |
const input = document.getElementById('request_attachments') | |
return Promise.allSettled(Array.from(input.files).map(async (file) => { | |
var data = new FormData() | |
data.append('file', file) | |
// access to file name | |
console.log(file.name) | |
// access to file extension | |
console.log(file.type) | |
return fetch(`/api/v2/uploads.json?filename=${file.name}`, { | |
body: data, | |
// headers: { | |
// "Content-Type": "application/binary" | |
// }, | |
method: "POST" | |
}) | |
.then((response) => response.json()) | |
.then((response) => { | |
if (response.error) { | |
return Promise.reject(response); | |
} | |
return response.error | |
? Promise.reject(response) | |
: response; | |
}) | |
})) | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment