JQuery Form Builder Additional Input Fields on Checkbox / Radio Groups
Hi there, I hope you all are well. Happy 2025! I am having a bit of an issue with JQuery Form Builder. I have tried, ChatGPT, ClaudeDev, and Cursor - however I am not able to get the results that I am looking for. I have also tried several callbacks on the API documentation.
I would like to add two extra input fields or alternatively data attributes to the Radio / Checkbox Groups.
The area mainly being the section where one Adds or Removes the Options, it gives two input fields there. The name and value. I would like to add Points for Yes and Points for No, as this will serve as a survey Form Builder. So far the AI and even myself having tried - I only get 2 input fields as extras below the Label, Class etc.
I have also hit a rock with the Signature Render on the Frontend of the Form.
Any guidance or feedback will be greatly appreciated.
$(document).ready(function () {
// Define custom signature field
const signatureField = {
label: 'Signature',
attrs: {
type: 'signature'
},
icon: '✍️',
field: `
<div class="signature-field">
<label>Signature *</label>
<div class="signature-pad" style="border:1px solid #ccc; height:200px; width:100%;"></div>
<div class="signature-controls">
<button type="button" class="clear-signature btn btn-warning">Clear</button>
</div>
</div>
`,
build: function () {
return this.field;
},
onRender: function () {
const $wrapper = $('<div></div>');
$wrapper.html(`
<label>${this.label || 'Signature'} ${this.required ? '*' : ''}</label>
<div class="signature-pad" style="border:1px solid #ccc; height:200px; width:100%;"></div>
<div class="signature-controls">
<button type="button" class="clear-signature btn btn-warning">Clear</button>
</div>
${this.description ? `<span class="description">${this.description}</span>` : ''}
`);
// Initialize jq-signature after rendering
setTimeout(() => {
const $signaturePad = $wrapper.find('.signature-pad');
// Initialize jq-signature plugin on the signature pad
$signaturePad.jqSignature({
lineColor: "#000", // Pen color
backgroundColor: "#fff", // Background color
width: $signaturePad.width(),
height: 200
});
// Resize the signature pad on window resize
const resizeCanvas = () => {
$signaturePad.jqSignature('reset');
$signaturePad.jqSignature('resize', $wrapper.width(), 200); // Adjust to wrapper size
};
resizeCanvas();
$(window).on('resize', resizeCanvas);
// Clear signature when the button is clicked
$wrapper.find('.clear-signature').on('click', function () {
$signaturePad.jqSignature('reset');
});
}, 100);
return $wrapper[0];
}
};
// Handle the rest of the JQuery Form Builder
const auditOptions = {
// Add a custom action button
actionButtons: [{
id: 'code_preview',
className: 'btn btn-primary',
label: '👩💻',
type: 'button',
events: {
click: function () {
// Get the current form data
const formBuilder = $('.form-builder-wrapper').data('formBuilder');
const formData = formBuilder.actions.getData();
// Format the form data as HTML
const formHtml = formData.map(field => {
let html = '';
switch (field.type) {
case 'radio-group':
html = `<div class="form-group">
<label>${field.label}</label>
${field.values.map(value =>
`<div class="radio">
<label>
<input type="radio" name="${field.name}" value="${value.value}">
${value.label}
</label>
</div>`).join('\n')}
</div>`;
break;
case 'select':
html = `<div class="form-group">
<label>${field.label}</label>
<select class="form-control" name="${field.name}">
${field.values.map(value =>
`<option value="${value.value}">${value.label}</option>`).join('\n')}
</select>
</div>`;
break;
case 'signature':
html = `<div class="form-group">
<label>${field.label}</label>
<div class="signature-pad" style="border:1px solid #ccc; height:200px;"></div>
<div class="signature-controls">
<button type="button" class="clear-signature">Clear</button>
</div>
</div>`;
break;
default:
html = `<div class="form-group">
<label>${field.label}</label>
<input type="${field.type}" class="form-control" name="${field.name}">
</div>`;
}
return html;
}).join('\n\n');
// Format the complete form HTML
const completeHtml = `${formHtml}`;
// Display the HTML in the input textarea
$('#code_preview_wrapper').text(completeHtml);
// Show the code preview section
$('#form_code_preview').show();
}
}
}],
onAddFieldAfter: function () {
// Get the current form data
const formBuilder = $('.form-builder-wrapper').data('formBuilder');
const formData = formBuilder.actions.getData();
// Format the form data as HTML
const formHtml = formData.map(field => {
let html = '';
switch (field.type) {
case 'radio-group':
html = `<div class="form-group">
<label>${field.label}</label>
${field.values.map(value =>
`<div class="radio">
<label>
<input type="radio" name="${field.name}" value="${value.value}">
${value.label}
</label>
</div>`).join('\n')}
</div>`;
break;
case 'select':
html = `<div class="form-group">
<label>${field.label}</label>
<select class="form-control" name="${field.name}">
${field.values.map(value =>
`<option value="${value.value}">${value.label}</option>`).join('\n')}
</select>
</div>`;
break;
case 'signature':
html = `<div class="form-group">
<label>${field.label}</label>
<div class="signature-pad" style="border:1px solid #ccc; height:200px;"></div>
<div class="signature-controls">
<button type="button" class="clear-signature">Clear</button>
</div>
</div>`;
break;
default:
html = `<div class="form-group">
<label>${field.label}</label>
<input type="${field.type}" class="form-control" name="${field.name}">
</div>`;
}
return html;
}).join('\n\n');
// Format the complete form HTML
const completeHtml = `${formHtml}`;
// Display the HTML in the input textarea
$('#code_preview_wrapper').text(completeHtml);
// Show the code preview section
$('#form_code_preview').show();
},
// Add custom fields
typeUserEvents: {
'signature': {
'onadd': function (fld) {
const $field = $(fld);
setTimeout(() => {
const $signaturePad = $field.find('.signature-pad');
$signaturePad.jqSignature({
lineColor: "#000", // Pen color
backgroundColor: "#fff", // Background color
width: $signaturePad.width(),
height: 200
});
// Resize the signature pad when the window is resized
const resizeCanvas = () => {
$signaturePad.jqSignature('reset');
$signaturePad.jqSignature('resize', $field.width(), 200); // Fixed height
};
resizeCanvas();
$(window).on('resize', resizeCanvas);
// Clear signature when the button is clicked
$field.find('.clear-signature').on('click', function () {
$signaturePad.jqSignature('reset');
});
}, 100); // Adjust timeout if needed
}
}
},
fields: [signatureField],
// Add the html of the Signature in the form
templates: {
signature: function (fieldData) {
return `
<div class="signature-wrapper">
<label>${fieldData.label || 'Signature'} ${fieldData.required ? '*' : ''}</label>
<div class="signature-pad" style="border:1px solid #ccc; height:200px; width:100%;"></div>
<div class="signature-controls">
<button type="button" class="clear-signature btn btn-warning">Clear</button>
</div>
</div>
`;
}
},
// Remove the custom code when the Clear button is pressed
onClearAll: function (formData) {
$('#code_preview_wrapper').text('');
},
// Existing options
disabledActionButtons: ['save'], // Remove the save button
disableFields: ['autocomplete', 'button', 'file', 'paragraph', 'hidden'], // Remove these fields
disabledAttrs: ['value', 'className', 'placeholder', 'description', 'required', 'other'], // Remove these attributes
typeUserAttrs: {
'checkbox-group': {
points_yes: {
label: 'Points for Yes',
type: 'number',
value: '1',
placeholder: 'Enter points for Yes'
},
points_no: {
label: 'Points for No',
type: 'number',
value: '0',
placeholder: 'Enter points for No'
}
},
'radio-group': {
points_yes: {
label: 'Points for Yes',
type: 'number',
value: '1',
placeholder: 'Enter points for Yes'
},
points_no: {
label: 'Points for No',
type: 'number',
value: '0',
placeholder: 'Enter points for No'
}
},
'select': {
points_yes: {
label: 'Points for Yes',
type: 'number',
value: '1',
placeholder: 'Enter points for Yes'
},
points_no: {
label: 'Points for No',
type: 'number',
value: '0',
placeholder: 'Enter points for No'
},
points_na: {
label: 'Points for N/A',
type: 'number',
value: '0',
placeholder: 'Enter points for N/A'
}
},
'date': {
points_yes: {
label: 'Points for Yes',
type: 'number',
value: '1',
placeholder: 'Enter points for Yes'
},
points_no: {
label: 'Points for No',
type: 'number',
value: '0',
placeholder: 'Enter points for No'
}
}
} // Add extra attributes to the fields
};
// Initialize form builder
$('.form-builder-wrapper').formBuilder(auditOptions);
});
Please or to participate in this conversation.