Task with the Move to Spam Button (Practical 4)

Please advise what the issue might be—I’ve tried everything. The Move to Spam button should, upon clicking, set the spam (read-only) field to true and also change the state and urgency values. However, instead of this, the values are simply saved in the notes if they were already present; the fields themselves remain unchanged (for example, urgency is set to low but immediately reverts back). I understand that the problem is likely in the external script, but I can’t figure out what exactly:

  1. BUTTON
    if (window.confirm(‘Are you sure?’)) {
    const sAjax = new SimpleAjax(‘ScriptForMoveToSpam’);
    sAjax.addParam(‘sysparm_name’, ‘setSpamUrgState’);
    sAjax.addParam(‘sysparm_start’, s_form.getUniqueValue());
    sAjax.getXML(callback);
    async function callback(response){
    if (s_form.isChanged()) { //callback
    s_form.setValue(‘urgency’, 1);
    await s_form.save();
    __resolveServerResponse();
    } else {
    s_go.reloadWindow();
    }
    }
    }
    else{
    s_go.reloadWindow();
    }

  2. EXTERNAL SCRIPT
    class ScriptForMoveToSpam{
    setSpamUrgState(idRecord){
    const record = new SimpleRecord(‘itsm_inquiry’);
    record.get(${idRecord});
    record.setValue(‘c_spam’, true);
    record.setValue(‘urgency’, 1);
    record.setValue(‘state’, 3);
    let result = record.update();
    return result;
    }
    }

1 Like

You may be saving the form before the server script executes and there is no handling of the server script’s result.

Try doing everything through a client-side script without an external script:

UI Action (Script)

if (window.confirm('Are you sure?')) {
    // Immediately set the values
    s_form.setValue('c_spam', true);
    s_form.setValue('urgency', 1);
    s_form.setValue('state', 3);
    
    // Save
    await s_form.save();
    s_go.reloadWindow();
} else {
    s_go.reloadWindow();
}

Saving the form, if called, only works within the SimpleAjax callback; it won’t work before the external script executes.

There are issues with the external script—it at least isn’t designed for client-side invocation because it doesn’t inherit from AbstractAjaxProcessor. To make this work with the current solution, the external script should be properly created:

External Script
/**
 * It's worth rereading the documentation on Script Include
 * https://docs.simpleone.ru/ru/platform/developer-help/common-automation-tools/script-include
 * In the system, there is also an implementation of AbstractAjaxProcessor; for deeper understanding, 
 * I recommend reviewing it.
 */
ss.importIncludeScript('AbstractAjaxProcessor');
/**
 * An important point is the presence of inheritance in the external script's form,
 * with the checkbox "Available for Client API" enabled (documentation examples use
 * prototype-based inheritance, which is verbose; the platform allows a more concise solution).
 */
class ScriptForMoveToSpam extends AbstractAjaxProcessor {
  /** This method does not accept parameters; they are accessible via this.getParameter */
  setSpamUrgState() {
    /** Parameters must be retrieved using the 'sysparm_' suffix */
    const idRecord = this.getParameter('sysparm_idRecord');
    const record = new SimpleRecord('itsm_inquiry');
    record.get(idRecord);
    record.setValue('c_spam', true);
    record.setValue('urgency', 1);
    record.setValue('state', 3);
    let result = record.update();
    return result;
  }
}

Client Script
if (window.confirm('Are you sure?')) {
  const sAjax = new SimpleAjax('ScriptForMoveToSpam');
  /**
   * Just as a reminder, here we use the reserved parameter name
   * `sysparm_name`; otherwise, it won't work.
   */
  sAjax.addParam('sysparm_name', 'setSpamUrgState');
  /**
   * Here we specify the name used in the external script with this.getParameter.
   * You're passing `sysparm_start` but expecting `idRecord`—this won't work.
   */
  sAjax.addParam('sysparm_idRecord', s_form.getUniqueValue());
  sAjax.getXML(callback);
  async function callback(response) {
    if (s_form.isChanged()) {
      //callback
      s_form.setValue('urgency', 1);
      await s_form.save();
      __resolveServerResponse();
    } else {
      s_go.reloadWindow();
    }
  }
} else {
  s_go.reloadWindow();
}

Otherwise, DxCpp is right—an external script is unnecessary for your purposes.

Also, note that s_form.setValue is an asynchronous function that returns a Promise.

Before each call to s_form.setValue, add await. Otherwise, there is a risk that s_form.save will execute before the new field values are set, and the changes will not be saved.