Submit button and Client script button conflicting on Suitelet. SS 2.0 - netsuite

i have 2 buttons on my suitelet form, Standard Submit Button and Client Script button. The submit button does not execute if i have the clientScriptModulePath in my suitelet code. once i remove the clientScriptModulePath , the submit button starts working. Anyone have any idea what could be the reason?
Suitelet:
function onRequest(context) {
log.debug('request type', context.request.method);
var form = serverWidget.createForm({ title: 'Item Search' });
if (context.request.method === 'GET') {
var rec_id = context.request.parameters.id;
log.debug('rec id', rec_id)
form.addButton({
id: 'custpage_btn_goback',
label: 'Go Back',
functionName: 'onBackButtonClick'
});
form.clientScriptModulePath = '../client/mx_itemsearch_filter_cs.js';
form.addSubmitButton({
label: 'Submit'
});
context.response.writePage(form);
}
else {
log.debug('POST', 'POST')
}
}
Client script function:
function onBackButtonClick() {//TODO:
try {
console.log('in back button')
var currRec = currentRecord.get();
var suiteletUrl = url.resolveScript({
scriptId: 'customscript_mx_itemsearch_sl',
deploymentId: 'customdeploy_mx_itemsearch_sl'
});
console.log(suiteletUrl)
window.open(suiteletUrl, '_self');
} catch (e) {
log.error({ title: fx, details: 'Error - Code: ' + e.code + ', Message: ' + e.message });
}
}

You need to add one valid client side endpoint function. The endpoint function can just be a blank function. Example
function pageInit (context) {};
The your client script should have export the client endpoint function and your custom function.
return { pageInit: pageInit, onBackButtonClick: onBackButtonClick};

Related

Netsuite Print Button - "error.SuiteScriptError","name":"MISSING_PDF_PARAMETERS",

I have created a print button to print an advanced PDF from a sales order, so the client can get a commercial invoice generated. I have done this for other clients with success but I am running into an issue where the standard templates will print a pdf from the button but the customized ones will not. Where am I going wrong in the code here:
Suitelet:
function onRequest(context) {
var custom_id = context.request.parameters.custom_id;
var tempid = context.request.parameters.tempid;
log.debug("id", custom_id);
log.debug("id", context.request.parameters);
var pdfFileName = "Commercial Invoice";
var renderer = render.create();
var content = renderer.addRecord({
templateName: 'record',
record: record.load({
type: record.Type.SALES_ORDER,
id: custom_id
})
});
renderer.setTemplateByScriptId(tempid);
var pdfFile = renderer.renderAsPdf();
log.debug ("pdf", pdfFile)
context.response.writeFile(renderer.renderAsPdf(),true);
}
return {
onRequest: onRequest
}
});
Client Script:
function onButtonClick() {
var suiteletUrl = url.resolveScript({
scriptId: 'customscript_commercialinv_so_sl',
deploymentId: 'customdeploy_commercialinv_so_sl',
returnExternalUrl: true,
params: {
custom_id: currentRecord.get().id, tempid: "CUSTTMPL_109_4753601_SB1_795"
},
});
window.open(suiteletUrl,"_blank");
}
exports.onButtonClick = onButtonClick;
exports.pageInit = pageInit;
return exports;
});
My user script looks solid. I am getting this error when I direct the Client script to a custom template as referenced above:
{"type":"error.SuiteScriptError","name":"MISSING_PDF_PARAMETERS","message":"Missing parameters required to generate PDF","stack":["renderAsPdf(N/render)","onRequest(/SuiteScripts/MegWebb/cust_SOprinttemplate_SL.js:28)"],"cause":{"type":"internal error","code":"MISSING_PDF_PARAMETERS","details":"Missing parameters required to generate PDF","userEvent":null,"stackTrace":["renderAsPdf(N/render)","onRequest(/SuiteScripts/MegWebb/cust_SOprinttemplate_SL.js:28)"],"notifyOff":false},"id":"","notifyOff":false,"userFacing":false}
Any help would be much appreciated!

Pagination in Suitescript 2.0 Netsuite

I tried implementing netsuite pagination in suitescript 2.0, the prev button is working but instead of 20 search data it's return like whole. Next button is not working always throwing error INVALID_PAGE_RANGE
Here is the suitelet code
var loadSearch = search.load({
id: 'customsearch_inv123'
});
var i = 0;
var pagedData = loadSearch.runPaged({
pageSize: 20
});
pagedData.pageRanges.forEach(function (pageRange) {
var lastPageRange = pagedData.pageRanges[pagedData.pageRanges.length - 1];
var Page = pagedData.fetch({
index: lastPageRange.index
});
if (context.request.parameters.next) {
Page = Page.next();
}
if (context.request.parameters.prev) {
Page =Page.prev();
}
Page.data.forEach(function (result) {
var number = result.getValue({
name: 'inventorynumber'
});
if (number) {
updateSublist.setSublistValue({
id: 'custpage_number',
line: i,
value: number
});
}
i++;
});
});
// submit button
form.addSubmitButton({
label: 'Submit'
});
form.addButton({
id: '_next',
label: 'Next',
functionName: 'next'
});
form.addButton({
id: '_prev',
label: 'Prev',
functionName: 'prev'
});
form.clientScriptModulePath = 'SuiteScripts/client.js';
In client script i wrote the function next and prev, and redirected to the same page with next or prev parameters and based on that i called page.next and page.prev.
If you have implemented this please help me.
here is client code.
next: function () {
window.location.href = 'example.com' + '&next=t';
},
prev: function () {
window.location.href = 'example.com' + '&prev=t';
}
You should pass current/requested pageNumber from client script and then use it to fetch data for that specific page like below
var pagedData = loadSearch.runPaged({
pageSize: 20
});
requestedPageNumber = 2
var page = pagedData.fetch({ index: requestedPageNumber });
page.data.forEach(function (result) {
// result is the searchResult object
// YOUR CODE GOES HERE
var number = result.getValue({
name: 'inventorynumber'
});
})
What you did wrong was you were starting from the last index and then trying to fetch unexisting array index in case where user clicks next.
Note: previous button should be disabled/hidden where there are no pages so as to not run into the same error and the same could be done for the next button too.

Creating form in netsuite using suitscript 2.0

var formData = new FormData();
formData.append("name", "John");
formData.append("age", "31");
for (var value of formData.values()) {
log.debug(value);
}
but when i want to log form values using formData api. It's giving below error.
ReferenceError: "FormData" is not defined.
FormData is a client side API managed under XMHttpRequest
UserEvent scripts are server side scripts with no browser based APIs available at all.
So you could use FormData in a client script to send info to a Suitelet or RESTlet but it's not present in a UserEvent script.
If you want to create a form in a Suitelet using SS2.0 you can use the following as a sample:
/**
*#NApiVersion 2.x
*#NScriptType Suitelet
*/
define(["N/log", "N/redirect", "N/runtime", "N/ui/serverWidget", "N/url", "./kotnRECBCFilters"],
function (log, redirect, runtime, ui, url, kotnRECBCFilters_1) {
function showPropertiesForm(context) {
var form = ui.createForm({
title: 'Property Trust Ledger'
});
var req = context.request;
var fromLoc = form.addField({
id: 'custpage_loc',
type: ui.FieldType.SELECT,
label: 'For Property',
source: 'location'
});
fromLoc.updateLayoutType({ layoutType: ui.FieldLayoutType.NORMAL });
fromLoc.updateBreakType({ breakType: ui.FieldBreakType.STARTCOL });
if (req.parameters.custpage_loc) {
fromLoc.defaultValue = req.parameters.custpage_loc;
}
var notAfterDate = form.addField({
id: 'custpage_not_after',
type: ui.FieldType.DATE,
label: 'On or Before'
});
if (req.parameters.custpage_not_after) {
notAfterDate.defaultValue = req.parameters.custpage_not_after;
}
form.addSubmitButton({
label: 'Get Detail'
});
//... bunch of stuff removed
context.response.writePage(form);
}
function onRequest(context) {
if (context.request.method === 'POST') {
var currentScript = runtime.getCurrentScript();
var params = {};
for (var k in context.request.parameters) {
if (k.indexOf('custpage_') == 0 && k.indexOf('custpage_transactions') == -1) {
if ((/^custpage_.*_display$/).test(k))
continue;
params[k] = context.request.parameters[k];
}
}
redirect.toSuitelet({
scriptId: currentScript.id,
deploymentId: currentScript.deploymentId,
parameters: params
});
return;
}
showPropertiesForm(context);
}
exports.onRequest = onRequest;
});

How to access variables from background.js to pop up in chrome extension

in chrome extension, I am creating a new html page as popup through background.js. Check the background.js code below,
chrome.contextMenus.create({
title: "share this",
contexts: ["selection"],
onclick: myFunction
});
var test0 = "Testing content Outside the myfunction";
function myFunction(data) {
var theSelection = data.selectionText;
console.log(theSelection);
chrome.tabs.query({'active': true, "lastFocusedWindow":true}, function(tabs) {
var sourceURL = tabs[0].url;
chrome.windows.create({
url: chrome.runtime.getURL('redirect.html'), type: 'popup'},
function(tab)
{
});
return record;
})
}
I have gone through getbackgroundpage function given here. I am able to access variable test0 with it but not sourceURL (as it is not in window scope).
by redirect popup window code is below,
var bg = chrome.extension.getBackgroundPage();
var sourceURL = bg.sourceURL;
var testvariable = bg.test0;
sourceURL is undefined.
Not getting a clue on how to define variables as global so that access in popup.
is there any better way, we can do it?
Dude , try to use Gogle message passing .
Little example from link before
BackgroundScript
var myFunc = function(){
//some code
}
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.messageType == "callSomeFunc") {
myFunc();
sendResponse({
status: "Function myFunc called."
});
}
//use return true for async response
return true;
});
contentScript
chrome.runtime.sendMessage({
messageType: "callSomeFunc"
},
function(response) {
// response contain {status: "Function myFunc called."}
console.log(response);
});

Automate login + posting to forum using nodejs + phantomjs

I am trying to automate login to a forum ( yet another forum , test forum available here: http://testforum.yetanotherforum.net/ ) using node-phantom.
This is my code:
/**
* Yet Another Forum Object
*
*
*/
var yaf = function() {}; //
module.exports = new yaf();
var phantom = require('node-phantom');
//var sleep = require('sleep');
var configTestForum = {
loginUrl: "http://testforum.yetanotherforum.net/login",
loginFormDetail: {
usernameBox: 'forum_ctl03_Login1_UserName', // dom element ID
passwordBox: 'forum_ctl03_Login1_Password',
submitButton: 'forum_ctl03_Login1_LoginButton'
},
loginInfo: {
username: 'testbot',
password: 'testbot123'
}
};
var config = configTestForum;
// program logic
yaf.prototype.login = function(username, password, cb) {
var steps = [];
var testindex = 0;
var loadInProgress = false; //This is set to true when a page is still loading
/*********SETTINGS*********************/
phantom.create(function(error, ph) {
ph.createPage(function(err, page) {
page.set('settings', {
userAgent: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0",
javascriptEnabled: true,
loadImages: false,
});
phantom.cookiesEnabled = true;
phantom.javascriptEnabled = true;
/*********SETTINGS END*****************/
console.log('All settings loaded, start with execution');
/**********DEFINE STEPS THAT FANTOM SHOULD DO***********************/
steps = [
//Step 1 - Open Amazon home page
function() {
console.log('Step 1 - Open Login Page');
page.open(config.loginUrl, function(status) {
});
},
function() {
console.log('Step 2 - Populate and submit the login form');
var submitForm = function(config) {
console.log('Form Submit 1 ( putting login )');
document.getElementById(config.loginFormDetail.usernameBox).value = config.loginInfo.username;
console.log('Form Submit 2 ( putting pass )');
//jQuery('#' + config.loginFormDetail.passwordBox).val(config.loginInfo.password);
//jQuery('#' + config.loginFormDetail.usernameBox).val(config.loginInfo.password);
document.getElementById(config.loginFormDetail.passwordBox).value = config.loginInfo.password;
console.log('Form Submit 3 ( clicking button ) ');
document.getElementById(config.loginFormDetail.submitButton).click();
//var clickElement = function (el) {
// var ev = document.createEvent("MouseEvent");
// ev.initMouseEvent(
// "click",
// true /* bubble */, true /* cancelable */,
// window, null,
// 0, 0, 0, 0, /* coordinates */
// false, false, false, false, /* modifier keys */
// 0 /*left*/, null
// );
// el.dispatchEvent(ev);
// console.log('dispatched!');
//};
//document.getElementById(config.loginFormDetail.submitButton).click();
//clickElement(jQuery("#forum_ctl03_Login1_LoginButton")[0]);
//
//var form = document.getElementById('form1');
////var list = function(object) {
//// for(var key in object) {
//// console.log(key);
//// }
////};
////list(form);
//
//
//// jQuery('#form1').submit();
//
//form.submit();
//
//document.forms[0].submit();
//HTMLFormElement.prototype.submit.call(jQuery('form')[0]);
console.log('Form Has Been Submitted <-----------------');
};
var subittedForm = function(err, retVal) {
console.log('Form Submit error : ' + err);
console.log('Form Submit returned : ' + retVal);
};
//page.evaluateJavaScript(jsCode);
page.evaluate(submitForm, subittedForm, config);
},
//Step 3 - wait for submit form to finish loading..
function() {
//sleep.sleep(5);
console.log("Step 3 - wait for submit form to finish loading..");
//sleep.sleep(3);
page.render('loginComplete.png');
page.get('cookies', function(err, cookies) {
// console.log(cookies);
});
page.evaluate(function() {
console.log(document.URL);
});
},
function() {
console.log('Exiting');
}
];
/**********END STEPS THAT FANTOM SHOULD DO***********************/
//Execute steps one by one
interval = setInterval(executeRequestsStepByStep, 500);
function executeRequestsStepByStep() {
if (loadInProgress == false && typeof steps[testindex] == "function") {
//console.log("step " + (testindex + 1));
steps[testindex]();
testindex++;
}
if (typeof steps[testindex] != "function") {
console.log("test complete!");
ph.exit();
// cb(ph);
cb('done');
}
}
page.onLoadStarted = function() {
loadInProgress = true;
console.log('Loading started');
};
page.onLoadFinished = function() {
loadInProgress = false;
console.log('Loading finished');
};
page.onConsoleMessage = function(msg) {
console.log(msg);
};
page.onError = function(msg, trace) {
var msgStack = ['ERROR: ' + msg];
if (trace && trace.length) {
msgStack.push('TRACE:');
trace.forEach(function(t) {
msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function+'")' : ''));
});
}
console.error('\n' + msgStack.join('\n'));
};
page.onResourceError = function(resourceError) {
console.error('Unable to load resource (#' + resourceError.id + ' URL:' + resourceError.url + ')');
console.error('Error code: ' + resourceError.errorCode + '. Description: ' + resourceError.errorString);
};
page.onResourceTimeout = function(msg) {
console.error('onResourceTimeout!!>' + msg);
};
page.onAlert = function(msg) {
console.error('onAlert!!> ' + msg);
};
});
});
// var page = webPage.create();
};
Output of the code is :
Step 1 - Open Login Page
Loading started
Loading finished
Step 2 - Populate and submit the login form
Form Submit 1(putting login)
Form Submit 2(putting pass)
Form Submit 3(clicking button)
Form Has Been Submitted < -----------------
Form Submit error: null
Form Submit returned: null
Unable to load resource(#14 URL:http://testforum.yetanotherforum.net/login?g= login &= )
Error code: 5.Description: Operation canceled
ERROR: TypeError: 'undefined'
is not an object(evaluating 'Sys.WebForms.Res.PRM_TimeoutError'), [object Object], [object Object], [object Object], [object Object], [object Object], [object Object], [object Object]
Step 3 - wait
for submit form to finish loading..
http: //testforum.yetanotherforum.net/login
Exiting
test complete!
done
Option client store expiration is not valid.Please refer to the README.
Process finished with exit code 0
What it attempts to do is :
Open login page : http://testforum.yetanotherforum.net/login?returnurl=%2fcategory%2f1-Test-Category
Try to login using login name / password and then clicking the button.
Take a screenshot and Retrieve the cookies ( containing the auth data )
Currently it is getting stuck in step 2. It can populate the login and password box, but no kind of clicking or submitting the form is working.Basically it is stuck as shown:
(as you can see the login / password are filled correctly ).
By looking at step 2 ( Step 2 - Populate and submit the login form ) in my code, do you notice anything obvious? or am I doing something wrong in the page settings?

Resources