NetSuite中Item Fulfillment添加Save & Edit按钮的实现问题咨询
NetSuite Item Fulfillment表单添加「Save & Edit」按钮的解决方案
问题背景
需要在Item Fulfillment交易表单中添加「Save & Edit」按钮,点击后保存当前记录并直接进入该记录的编辑模式。尝试通过Client Script + User Event Script实现时,遇到错误提示rec.save()不是函数,原因是NetSuite 2.x Client Script中的currentRecord对象不支持save()方法(该方法仅在Server Script中可用)。
可行解决方案
方法一:客户端触发原生保存+延迟跳转
利用NetSuite原生的保存按钮完成保存操作,之后延迟跳转到记录的编辑页面,实现逻辑简单,无需额外Server Script。
修正后的代码
User Event Script(负责添加按钮并关联Client Script):
/** * @NApiVersion 2.x * @NScriptType UserEventScript */ define([], function() { function beforeLoad(context) { var form = context.form; // 在编辑和创建模式下显示按钮,可根据需求调整触发场景 if (context.type === context.UserEventType.EDIT || context.type === context.UserEventType.CREATE) { form.addButton({ id: 'custpage_save_and_edit', label: 'Save & Edit', functionName: 'onSaveAndEditClick' }); // 替换为你的Client Script实际文件路径 form.clientScriptModulePath = './save_and_edit_client.js'; } } return { beforeLoad: beforeLoad }; });
Client Script(处理按钮点击事件):
/** * @NApiVersion 2.x * @NScriptType ClientScript */ define(['N/currentRecord', 'N/url'], function(currentRecord, url) { function pageInit(context) {} function onSaveAndEditClick() { var rec = currentRecord.get(); var recordType = rec.type; var recordId = rec.id; // 模拟点击原生保存按钮提交记录 document.getElementById('submitter').click(); // 延迟跳转,确保服务器完成保存操作(时间可根据实际环境调整) window.setTimeout(function() { var editUrl = url.resolveRecord({ recordType: recordType, recordId: recordId || null, // 新建记录时id为null,保存后NetSuite会自动处理跳转 isEditMode: true }); window.location.href = editUrl; }, 3000); } return { pageInit: pageInit, onSaveAndEditClick: onSaveAndEditClick }; });
方法二:Suitelet中间层处理保存与跳转
通过Suitelet作为服务器端中间层,接收客户端提交的字段数据,完成保存后返回编辑页面URL,适合需要添加额外业务逻辑(如字段验证、自定义处理)的场景。
修正后的代码
Suitelet Script(服务器端处理保存逻辑):
/** * @NApiVersion 2.x * @NScriptType Suitelet */ define(['N/record', 'N/url'], function(record, url) { function onRequest(context) { if (context.request.method === 'POST') { try { var recordType = context.request.parameters.recordType; var recordId = context.request.parameters.recordId; var fieldValues = JSON.parse(context.request.parameters.fieldValues); // 加载或创建记录 var rec = recordId ? record.load({type: recordType, id: recordId}) : record.create({type: recordType}); // 批量设置字段值 Object.keys(fieldValues).forEach(function(fieldId) { rec.setValue({fieldId: fieldId, value: fieldValues[fieldId]}); }); // 保存记录并获取ID var savedId = rec.save({ignoreMandatoryFields: false}); // 生成编辑页面URL并返回 var editUrl = url.resolveRecord({ recordType: recordType, recordId: savedId, isEditMode: true }); context.response.write(JSON.stringify({success: true, editUrl: editUrl})); } catch (e) { context.response.write(JSON.stringify({success: false, error: e.message})); } } } return { onRequest: onRequest }; });
Client Script(提交数据到Suitelet并处理跳转):
/** * @NApiVersion 2.x * @NScriptType ClientScript */ define(['N/currentRecord', 'N/url', 'N/http'], function(currentRecord, url, http) { function pageInit(context) {} function onSaveAndEditClick() { var rec = currentRecord.get(); var recordType = rec.type; var recordId = rec.id; // 收集所有可编辑字段的值 var fieldValues = {}; rec.getFields().forEach(function(fieldId) { try { fieldValues[fieldId] = rec.getValue({fieldId: fieldId}); } catch (e) { // 跳过无法获取值的系统字段 } }); // 构建Suitelet访问URL(替换为你的脚本ID和部署ID) var suiteletUrl = url.resolveScript({ scriptId: 'customscript_save_and_edit_suitelet', deploymentId: 'customdeploy_save_and_edit_suitelet' }); // 提交数据到Suitelet var response = http.post({ url: suiteletUrl, body: { recordType: recordType, recordId: recordId, fieldValues: JSON.stringify(fieldValues) } }); var result = JSON.parse(response.body); if (result.success) { window.location.href = result.editUrl; } else { alert('保存失败:' + result.error); } } return { pageInit: pageInit, onSaveAndEditClick: onSaveAndEditClick }; });
方案对比
- 方法一:实现成本低,无需额外部署Suitelet,但依赖原生保存按钮的ID(
submitter),延迟时间需根据环境调整,避免跳转过早。 - 方法二:逻辑可控性强,可扩展额外业务处理,但需要创建并部署Suitelet,代码量相对较大。
内容的提问来源于stack exchange,提问作者Arnob Dep
相关产品推荐
相关产品推荐

