Hi. I am trying to add a client script function to...
# suitescript
v
Hi. I am trying to add a client script function to a suitelet in the post response of the suitelet. The client script function is a pageInit function which is supposed to close the suitelet window I am struggling with: 1 How do I call the pageinit function from the post response of the suitelet? I can't find any examples of the correct syntax. In the suitelet, I have referenced the file containing the client script using form.clientScriptFileId I am not sure how to call the function since it is not tied to a ui custom button. Instead, it is supposed to be triggered on record submit 2. In the client script itself, my script is as follows:
/**
*@NApiVersion 2.x
*@NScriptType ClientScript
*/
define(["N/url"], function (url) {
/**
* @param {ClientScriptContext.pageInit} context
*/
function pageInit(context) {
var window = document.location();
log.debug("window", window);
window.close();
}
return {
pageInit: pageInit,
};
});
I am not sure how to define 'window' as a variable so it is referring to the current window (the focused browser window) at the time the function is called i.e. I want the suitelet to trigger the client script and the client script to close the suitelet window. Thanks
b
suitelets run on netsuite's server and are triggered when they receive an html request, usually a GET
it can do many things, but in this case you want it to return a html page that is rendered by the user's browser
suitelet's have 2 ways of doing that, one is to use ServerResponse.writePage to have netsuite generate a netsuite themed form
the other is to simply write your own html using ServerResponse.write
either approach would work in this case
the code you have is for client script, which would be for the writePage approach
netsuite's forms have entry points that are triggered at certain times
you would use Form.clientScriptModulePath to add javascript functions that run when those entry points are triggered
z
It is basic school of web programming : There are two separated process, the first executed on the server side and the second executed on browser side. Client script is loaded by browser engine (Chrome, Edge, Safar...) and it is not possible to invoke any client script function from the web server (in this case NetSuite) I'm just emphasized that it is not "NetSuite" issue
Unless it is for training purpose, there is no reason for using SuiteLet which should be immediately close. It could be better to use RestLet
v
Thanks @battk for your detailed response This is the suitelet script that I am using
Copy code
/**
 *@NApiVersion 2.x
 *@NScriptType Suitelet
 */
define(["N/ui/serverWidget", "N/log", "N/record", "N/url"], function (
  serverWidget,
  log,
  record,
  url
) {
  /**
   * @param {SuiteletContext.onRequest} context
   */
  function onRequest(context) {
    if (context.request.method === "GET") {
      // Section One - Forms
      var invoice_id = parseInt(context.request.parameters.recordId);

      var form = serverWidget.createForm({
        id: "notes",
        title: "Notes",
      });
form.clientScriptFileId=5110;
      var customerGroup = form.addFieldGroup({
        id: "customerDetails",
        label: "Customer Details",
      });
      customerGroup.isSingleColumn = false;

      form.addSubmitButton({
        label: "Submit",
      });

      var select = form.addField({
        id: "custpage_source",
        type: serverWidget.FieldType.SELECT,
        label: "Source of Communication",
        container: "customerDetails",
      });
      //the value is the internal id of the option under customisation>lists,records and forms>lists>'source of communication' list
      select.addSelectOption({
        value: 1,
        text: "Phone",
      });

      select.addSelectOption({
        value: 2,
        text: "Email",
      });

      select.addSelectOption({
        value: 3,
        text: "Website Contact Form",
      });

      select.addSelectOption({
        value: 4,
        text: "Other",
      });

      form.addPageLink({
        type: serverWidget.FormPageLinkType.CROSSLINK,
        title: "Invoice",
        url:
          "<https://tstdrv.app.netsuite.com/app/accounting/transactions/custinvc.nl?id=>" +
          invoice_id,
      });

      var parentTransaction = form.addField({
        id: "custpage_parent_transaction",
        type: serverWidget.FieldType.SELECT,
        label: "Parent Transaction",
        container: "customerDetails",
      });

      parentTransaction.addSelectOption({
        value: invoice_id,
        text: invoice_id,
      });

      // form.updateDefaultValues({
      //   custpage_recordurl:
      //     "<https://tstdrv.app.netsuite.com/app/accounting/transactions/custinvc.nl?id=>" +
      //     recId,
      // });
      context.response.writePage(form);

      function getBaseUrl() {
        return url.resolveRecord({
          recordType: record.Type.INVOICE,
        });
      }
      // Section Two - Tabs - See "Steps for Adding a Tab to a Form"
      // Section Three - Sublist - See "Steps for Adding a Sublist to a Form"
    } else {
      // Section Four - Output - Used in all sections

      var delimiter = /\u0001/;
      var sourceField = context.request.parameters.custpage_source;
      var parentField = context.request.parameters.custpage_parent_transaction;

      var invoiceRecord = record.load({
        type: record.Type.INVOICE,
        id: parentField,
      });
      log.debug("parent record", invoiceRecord);

      //   context.response.write(
      //     "You have entered:" + "<br/>  Name: " + sourceField
      //   );
      var recObj = record.create({
        type: "customrecord_user_notes",
      });
      recObj.setValue({ fieldId: "custrecord_source", value: sourceField });
      recObj.setValue({
        fieldId: "custrecord_parent_transaction",
        value: parentField,
      });
      var userNote = recObj.save({});

      var notesFieldUpdate = record.submitFields({
        type: record.Type.INVOICE,
        id: parentField,
        values: {
          custbody_notes_check:
            "<span style='color:#e74c3c;'>Check Notes</span>",
        },
      });
      log.debug("notesfield", notesFieldUpdate);
      // context.response.write((location, "_self").close());

      context.response.write("Note Created");
      
      pageInit
    }
  }
  return {
    onRequest: onRequest,
  };
});
In the post response, I wasn't sure how to call the function from the client script
@Zoran R-DATAGRAM: Thanks for the response. It is possible to invoke a client script function from a suitelet (which is a server script) by using the method described by battk in their post above
b
you need a better understanding of where code runs
pay more attention to the previous responses
any attempt to run code meant for a client browser (like closing a window) will fail if done on the server
in this case because there is no window on the server, it doesnt render anything, there is nothing to close
v
I was able to get the window to close using context.response.write(<script>window.close();</script>) in the post part of the suitelet I had received the following advice from Netsuite on this: "you can use a client script that has the window.close function on pageInit and call it on your Suitelet on the post method context"
I was trying to trigger a client script per Netsuite's advice on how to close a window via a suitelet
since that didn't work, I have gone with the <script>window.close()</script> option
b
the it they were referring to in
call it
was the client script, not the pageInit function
which is done using Form.clientScriptModulePath
v
I called the client script near the top
Copy code
* @param {SuiteletContext.onRequest} context
   */
  function onRequest(context) {
    if (context.request.method === "GET") {
      // Section One - Forms
      var invoice_id = parseInt(context.request.parameters.recordId);

      var form = serverWidget.createForm({
        id: "notes",
        title: "Notes",
      });
form.clientScriptFileId=5110;
I was confused about this part though "call [clientscript] on your Suitelet on the post method context" How would I call it in the post method context? That's what my original query was around since I can't find the correct way to do that
b
the same way you did in during a get
create a form, set the client script module path, then write the form to the response
z
Once again : It is not possible to execute client script on the server side... It is possible to create suitelet that return (response) "HTML" page with some JavaScript code... When HTML content is accepted from the browser, at that moment suitelet is finished and no more is executed. Injecting <script> in the HTML response is correct way, but once again : it will be executed on the browser (client) side and not on the server side..
v
/**  *@NApiVersion 2.x
* *@NScriptType Suitelet
* */
define(["N/ui/serverWidget", "N/log", "N/record", "N/url"], function (
serverWidget,
log,
record,
url
) {
/**    * @param {SuiteletContext.onRequest} context    */
function onRequest(context) {
if (context.request.method === "GET") {
var invoice_id = parseInt(context.request.parameters.recordId);
var form = serverWidget.createForm({ id: "notes", title: "Notes" });
var customerGroup = form.addFieldGroup({
id: "customerDetails",
label: "Customer Details",
});
customerGroup.isSingleColumn = false;
form.addSubmitButton({ label: "Submit" });
var select = form.addField({
id: "custpage_source",
type: serverWidget.FieldType.SELECT,
label: "Source of Communication",
container: "customerDetails",
});
select.addSelectOption({ value: 1, text: "Phone" });
select.addSelectOption({ value: 2, text: "Email" });
select.addSelectOption({ value: 3, text: "Website Contact Form" });
select.addSelectOption({ value: 4, text: "Other" });
form.addPageLink({
type: serverWidget.FormPageLinkType.CROSSLINK,
title: "Invoice",
url:
"https://<accountid>.<http://app.netsuite.com/app/accounting/transactions/custinvc.nl?id=|app.netsuite.com/app/accounting/transactions/custinvc.nl?id=>" +
invoice_id,
});
var parentTransaction = form.addField({
id: "custpage_parent_transaction",
type: serverWidget.FieldType.SELECT,
label: "Parent Transaction",
container: "customerDetails",
});
parentTransaction.addSelectOption({
value: invoice_id,
text: invoice_id,
});
context.response.writePage(form);
function getBaseUrl() {
return url.resolveRecord({ recordType: record.Type.INVOICE });
}
} else {
var delimiter = /\u0001/;
var sourceField = context.request.parameters.custpage_source;
var parentField = context.request.parameters.custpage_parent_transaction;
var invoiceRecord = record.load({
type: record.Type.INVOICE,
id: parentField,
});
log.debug("parent record", invoiceRecord);
var recObj = record.create({ type: "customrecord_user_notes" });
recObj.setValue({ fieldId: "custrecord_source", value: sourceField });
recObj.setValue({
fieldId: "custrecord_parent_transaction",
value: parentField,
});
var userNote = recObj.save({});
var notesFieldUpdate = record.submitFields({
type: record.Type.INVOICE,
id: parentField,
values: {
custbody_notes_check:
"<span style='color:#e74c3c;'>Check Notes</span>",
},
});
log.debug("notesfield", notesFieldUpdate);
//  context.response.write("Note Created");
var form_close = serverWidget.createForm({ id: "notes_close", title: "Notes" });
form_close.clientScriptFileId = 2637;
context.response.writePage(form_close)
}
}
return { onRequest: onRequest };
});
This is printing the second form from the response on submit The functions from the client script (under pageinit) are not triggering however. Have I called the client script in the correct way?
b
what does the client script look like
v
Copy code
/**
 *@NApiVersion 2.x
 *@NScriptType ClientScript
 */
 define([], function () {
    /**
     * @param {ClientScriptContext.pageInit} context
     */
    function pageInit(context) {
 
   
      window.close();
      
    
    
    }

  
    return {
      pageInit: pageInit,
    };
  });
This is the close window client script (file id 2637 referenced in form_close.clientScriptFileId = 2637;)
b
looks reasonable to me
the window might not close depending on how it was opened
so dont rely on the window closing to tell if the script ran
use the debugger or the console for that
v
Thank you. I will try with the debugger The way the scripts work are: User event script creates a button on the record --> on click function is linked to a client script ---> the client script launches a suitelet --> the suitelet on submit is supposed to be linked to another client script that is supposed to close the window