Show a popup window in NetSuite with a form

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

Leave a comment

Your email address will not be published. Required fields are marked *