NetSuite uses the ExtJS library for a variety of purposes including showing popup windows for alerts and confirmations. We can make use of this to tailor this popup window for our own uses cases which would otherwise couldn’t be met using the standard ‘N/ui/dialog Module’
Note : We are using the ExtJS library which NetSuite used for building their own popup/modal/dialog purpose. If NetSuite decides to upgrade this library or change this to another library, it may break the existing scripts if we use the ExtJS library directly.
Show a popup window in NetSuite with a form
The following code snippet is for the scenario defined below :
The popup window should have a title and a message field. The message field should be a display field and it can give instructions to the user on how to enter the values.
The popup should contain a form with options like a select field, start date field, end date field, time field with the 24-hour format, time field with the 12-hour format, date-time field, text field, textarea field, checkbox field, radio button, number field, search field, disabled field, inline/display field and so on.
The popup form should be scrollable.
Every field should have validations and be mandatory.
The date-time field should be auto-populated/defaulted to the current date-time and it is disabled. When the user uses the search field, it will set the value on the disabled field and inline field. The value given by the user on the start date field should not be greater than the entered value end date field. The value given by the user on the end date field should not be greater than the entered value start date field. Both the start date and end date should not exceed the current date/today.
There should also be an option to upload a file and attach a picture. When the file is uploaded, it should show the file name and file size.
The popup should have buttons such as Submit, Reset/Clear, and Cancel/Close.
Upon submission, we should retrieve the values in the form entered by the user and send an API call.
During the API call, we should restrict the user from making any further changes to the popup form and using other buttons until the API call is resolved. We should show a loader/spinner during the API call.
If the API call is successful/failed, we should alert the user and then close the popup.
The popup should not be dismissed and should only be closed by Cancel/Close button.
Align the popup window to be centered with sufficient width and padding.
function showPopupWindow() {
// Create the form fields
var messageField = Ext.create('Ext.form.field.Display', {
fieldLabel: 'Message',
readOnly: true,
value: 'Enter the following details:'
});
var selectField = Ext.create('Ext.form.field.ComboBox', {
fieldLabel: 'Select Field',
store: ['Option 1', 'Option 2', 'Option 3'],
allowBlank: false
});
var startDateField = Ext.create('Ext.form.field.Date', {
fieldLabel: 'Start Date',
format: 'Y-m-d',
allowBlank: false,
maxValue: new Date(),
listeners: {
change: function (field, newValue) {
endDateField.setMinValue(newValue);
}
}
});
var endDateField = Ext.create('Ext.form.field.Date', {
fieldLabel: 'End Date',
format: 'Y-m-d',
allowBlank: false,
maxValue: new Date(),
listeners: {
change: function (field, newValue) {
startDateField.setMaxValue(newValue);
}
}
});
var time24Field = Ext.create('Ext.form.field.Time', {
fieldLabel: 'Time Field (24-hour format)',
format: 'H:i',
allowBlank: false
});
var time12Field = Ext.create('Ext.form.field.Time', {
fieldLabel: 'Time Field (12-hour format)',
format: 'g:i A',
allowBlank: false
});
var dateTimeField = Ext.create('Ext.form.field.Date', {
fieldLabel: 'Date-Time Field',
format: 'Y-m-d H:i',
allowBlank: false,
value: new Date(),
disabled: true
});
var textField = Ext.create('Ext.form.field.Text', {
fieldLabel: 'Text Field',
allowBlank: false
});
var textAreaField = Ext.create('Ext.form.field.TextArea', {
fieldLabel: 'Textarea Field',
allowBlank: false
});
var checkboxField = Ext.create('Ext.form.field.Checkbox', {
fieldLabel: 'Checkbox Field'
});
var radioField = Ext.create('Ext.form.RadioGroup', {
fieldLabel: 'Radio Field',
columns: 1,
items: [
{ boxLabel: 'Option 1', name: 'radioOption', inputValue: 'option1' },
{ boxLabel: 'Option 2', name: 'radioOption', inputValue: 'option2' },
{ boxLabel: 'Option 3', name: 'radioOption', inputValue: 'option3' }
],
allowBlank: false
});
var numberField = Ext.create('Ext.form.field.Number', {
fieldLabel: 'Number Field',
allowBlank: false,
minValue: 0
});
var searchField = Ext.create('Ext.form.field.Trigger', {
fieldLabel: 'Search Field',
triggerCls: 'x-form-search-trigger',
allowBlank: false,
onTriggerClick: function () {
// Perform search functionality
var searchValue = searchField.getValue(); // Example value from search
disabledField.setValue(searchValue);
inlineField.setValue(searchValue);
}
});
var disabledField = Ext.create('Ext.form.field.Text', {
fieldLabel: 'Disabled Field',
disabled: true
});
var inlineField = Ext.create('Ext.form.field.Display', {
fieldLabel: 'Inline Field'
});
// Function to display file details
function displayFileDetails(files) {
let fileNames = [];
let totalSize = 0;
// Iterate through the selected files
/*
Ext.Array.each(files, function (file) {
fileNames.push(file.name);
totalSize += file.size;
});
*/
for (let i = 0; i < files.length; i++) {
let file = files[i];
fileNames.push(file.name);
totalSize += file.size;
}
return {
fileNames: fileNames.join(', '),
totalSize: totalSize
}
}
// Function to format file size
function formatFileSize(size) {
if (size < 1024) {
return size + ' bytes';
} else if (size < 1048576) {
return (size / 1024).toFixed(2) + ' KB';
} else {
return (size / 1048576).toFixed(2) + ' MB';
}
}
// Create the file names display field
var fileUploadNamesField = Ext.create('Ext.form.field.Display', {
fieldLabel: 'Uploaded Files',
value: '',
hidden: false,
readOnly: true,
});
// Create the file size display field
var fileUploadSizeField = Ext.create('Ext.form.field.Display', {
fieldLabel: 'Total Size',
value: '',
hidden: false,
readOnly: true,
});
// Create the file upload field
var fileUploadField = Ext.create('Ext.form.field.File', {
fieldLabel: 'Upload Files',
buttonConfig: {
text: 'Browse...',
iconCls: 'x-fa fa-upload'
},
listeners: {
change: function (field, value) {
console.log('fileUploadField {field, value}', { field, value });
// Show file names
const fileName = value.split(',').map(function (name) {
return name.trim();
});
console.log('fileUploadField fileNames', fileName);
let files = field.fileInputEl.dom.files;
if (files && files.length > 0) {
let { fileNames, totalSize } = displayFileDetails(files);
console.log('fileUploadField', { fileNames, totalSize });
// Update the display of file names and total size
fileUploadNamesField.setValue(fileNames);
fileUploadSizeField.setValue(Ext.util.Format.fileSize(totalSize));
}
// Handle file upload logic
}
}
});
// Create the picture file name display field
var pictureFieldFileNameField = Ext.create('Ext.form.field.Display', {
fieldLabel: 'Attached Picture',
value: '',
hidden: false,
readOnly: true,
});
// Create the picture file size display field
var pictureFieldFileSizeField = Ext.create('Ext.form.field.Display', {
fieldLabel: 'Picture Size',
value: '',
hidden: false,
readOnly: true,
});
// Create the picture attachment field
var pictureField = Ext.create('Ext.form.field.File', {
fieldLabel: 'Attach Picture',
buttonConfig: {
text: 'Browse...',
iconCls: 'x-fa fa-picture-o'
},
listeners: {
change: function (field, value) {
console.log('pictureField {field, value}', { field, value });
// Show file names
const fileName = value.split(',').map(function (name) {
return name.trim();
});
console.log('pictureField fileName', fileName);
/*
var file = field.fileInputEl.dom.files[0];
if (file) {
// Update the display of the file name and size
pictureFieldFileNameField.setValue(file.name);
pictureFieldFileSizeField.setValue(Ext.util.Format.fileSize(file.size));
}
*/
let files = field.fileInputEl.dom.files;
if (files && files.length > 0) {
let { fileNames, totalSize } = displayFileDetails(files);
console.log('pictureField', { fileNames, totalSize });
// Update the display of the file name and size
pictureFieldFileNameField.setValue(fileNames);
pictureFieldFileSizeField.setValue(Ext.util.Format.fileSize(totalSize));
}
// Handle picture attachment logic
}
}
});
// Create the form panel
var formPanel = Ext.create('Ext.form.Panel', {
xtype: 'formpanel',
bodyPadding: 10,
scrollable: true,
defaults: {
labelAlign: 'top',
margin: '0 0 10 0',
},
items: [
// Add form fields and components here
messageField,
selectField,
startDateField,
endDateField,
time24Field,
time12Field,
dateTimeField,
textField,
textAreaField,
checkboxField,
radioField,
numberField,
searchField,
disabledField,
inlineField,
fileUploadField,
fileUploadNamesField,
fileUploadSizeField,
pictureField,
pictureFieldFileNameField,
pictureFieldFileSizeField,
]
});
// Create the submit button
var submitButton = Ext.create('Ext.button.Button', {
text: 'Submit',
handler: function () {
//Check if the form is validated
if (formPanel.getForm().isValid()) {
// Disable the form and buttons
formPanel.getForm().getFields().each(function (field) {
field.setReadOnly(true);
});
submitButton.setDisabled(true);
resetButton.setDisabled(true);
cancelButton.setDisabled(true);
// Show loader/spinner
var loader = Ext.create('Ext.LoadMask', {
target: popupWindow,
msg: 'Submitting...'
});
loader.show();
// Retrieve the form values
var formValues = formPanel.getForm().getValues();
console.log('formValues Value:', formValues);
// Retrieve the form values
var selectValue = selectField.getValue();
var startDateValue = startDateField.getRawValue();
var endDateValue = endDateField.getRawValue();
var time24Value = time24Field.getRawValue();
var time12Value = time12Field.getRawValue();
var dateTimeValue = dateTimeField.getRawValue();
var textValue = textField.getValue();
var textAreaValue = textAreaField.getValue();
var checkboxValue = checkboxField.getValue();
var radioValue = radioField.getValue().radioOption;
console.log('radioField.getValue()', radioField.getValue());
var numberValue = numberField.getValue();
var searchValue = searchField.getValue();
var disabledValue = disabledField.getValue();
var inlineValue = inlineField.getValue();
var fileUploadValue = fileUploadField.getRawValue();
var pictureValue = pictureField.getRawValue();
// Log the retrieved values
console.log('Select Value:', selectValue);
console.log('Start Date Value:', startDateValue);
console.log('End Date Value:', endDateValue);
console.log('Time Field(24 - hour format)', time24Value);
console.log('Time Field (12-hour format)', time12Value);
console.log('DateTime Value:', dateTimeValue);
console.log('Text Value:', textValue);
console.log('Textarea Field', textAreaValue);
console.log('Checkbox Value:', checkboxValue);
console.log('Radio Value:', radioValue);
console.log('Number Value:', numberValue);
console.log('Search Value:', searchValue);
console.log('Disabled Value:', disabledValue);
console.log('Inline Value:', inlineValue);
console.log('Upload Files', fileUploadValue);
console.log('Attach Picture', pictureValue);
// Prepare file data for upload
/*
var formData = new FormData();
var fileUploadFiles = fileUploadField.fileInputEl.dom.files;
Ext.Array.each(fileUploadFiles, function (file) {
formData.append('files', file);
});
*/
var fileUploadFiles = fileUploadField.fileInputEl.dom.files;
var fileUploadFilesArray = [];
Ext.Array.each(fileUploadFiles, function (file) {
fileUploadFilesArray.push(file);
});
console.log('fileUploadFilesArray', fileUploadFilesArray);
var pictureFiles = pictureField.fileInputEl.dom.files;
var pictureFilesArray = [];
Ext.Array.each(pictureFiles, function (file) {
pictureFilesArray.push(file);
});
console.log('pictureFilesArray', pictureFilesArray);
// Perform further processing or API call here
/*
// Simulate API call
Ext.defer(function () {
loader.hide();
// API call success/failure handling
var isSuccess = true; // Change this value based on the API call result
if (isSuccess) {
Ext.Msg.alert('Success', 'Form submitted successfully.', function () {
popupWindow.close();
});
} else {
Ext.Msg.alert('Failure', 'Failed to submit the form. Please try again.', function () {
// Enable form fields and buttons
formPanel.getForm().getFields().each(function (field) {
field.setReadOnly(false);
});
submitButton.setDisabled(false);
resetButton.setDisabled(false);
cancelButton.setDisabled(false);
});
}
}, 2000);
*/
// Make API call with the form values
var apiUrl = 'https://api.example.com/submit-data'; // Replace with your API endpoint
var requestData = {
selectValue: selectValue,
startDateValue: startDateValue,
endDateValue: endDateValue,
time24Value: time24Value,
time12Value: time12Value,
dateTimeValue: dateTimeValue,
textValue: textValue,
textAreaValue: textAreaValue,
checkboxValue: checkboxValue,
radioValue: radioValue,
numberValue: numberValue,
searchValue: searchValue,
disabledValue: disabledValue,
inlineValue: inlineValue,
fileUploadValue: fileUploadValue,
pictureValue: pictureValue,
};
console.log('requestData', requestData);
Ext.Ajax.request({
url: apiUrl,
method: 'POST',
// params: formValues,
jsonData: requestData,
success: function (response) {
// API call successful
// alert('Form submitted successfully!');
Ext.Msg.alert('Success', 'Form submitted successfully.', function () {
loader.hide();
// Close the popup window
popupWindow.close();
});
},
failure: function (response) {
// API call failed
// alert('Form submission failed!');
Ext.Msg.alert('Failure', 'Failed to upload files. Please try again.', function () {
loader.hide();
// Close the popup window
popupWindow.close();
});
return;
// If we want to Re-enable the form and buttons
formPanel.getForm().getFields().each(function (field) {
field.setReadOnly(false);
});
submitButton.setDisabled(false);
resetButton.setDisabled(false);
cancelButton.setDisabled(false);
return;
}
});
}
}
});
// Create the reset/clear button
var resetButton = Ext.create('Ext.button.Button', {
text: 'Reset/Clear',
handler: function () {
formPanel.getForm().reset();
}
});
// Create the cancel/close button
var cancelButton = Ext.create('Ext.button.Button', {
text: 'Cancel/Close',
handler: function () {
popupWindow.close();
}
});
// Create the popup window
var popupWindow = Ext.create('Ext.window.Window', {
title: 'Popup Form Window',
centered: true,
modal: true,// modal set to true for centering
scrollable: true,
layout: 'fit', //layout set to fit to allow scrolling content
width: 600,
height: 600,
items: [formPanel],
buttons: [submitButton, resetButton, cancelButton],
closable: false, //if true, this modal can be closed by dismissing the window using the 'X' icon on the popup titlebar
listeners: {
beforeclose: function () {
return true;
return false; // if false, it will Prevent the window from being dismissed
},
afterrender: function (window) {
// Center align the popup window
window.center();
}
}
});
// Center the popup window on the screen
popupWindow.center();
// Show the popup window
popupWindow.show();
}
showPopupWindow()
Initial Popup Form



After filling in details on the Popup Form



When submitting the popup form

Handling the response from submitting the popup form
