am trying to add new row to tabulator using the key board ,so i followed the given below steps
Created an extended part as below
Tabulator.prototype.extendModule("keybindings", "actions", {
"addNewRow":function(){ //delete selected rows
var id = Math.floor((Math.random() * 10000) + 1) * -1;
Tabulator.addRow({ iD: id });
},
});
hut i found that to add new row i need to refer to the tabulator object to do so , i need this to be generic to all my tabulators in the whole site ,so i do not want to refer to tabulator object every time
to run ti now i must have it like below
Tabulator.prototype.extendModule("keybindings", "actions", {
"addNewRow":function(){ //delete selected rows
var id = Math.floor((Math.random() * 10000) + 1) * -1;
tblgridPage1.addRow({ iD: id });
},
});
You can use the scope that the module is executed in to do this, so your code should look like this:
Tabulator.prototype.extendModule("keybindings", "actions", {
"addNewRow":function(){
var id = Math.floor((Math.random() * 10000) + 1) * -1;
this.table.addRow({ iD: id });
},
});
the this.table gives you access to the table that the function is being executed on
Related
How can I make my script work? The goal is to have a custom field that will count the line items in Deposit page while on Edit mode.
Please note that I am an accountant and interested in learning javascript so my script is a mess.
/**
* #NApiVersion 2.1
* #NScriptType UserEventScript
*/
define(['N/currentRecord'], currentRecord => {
test_set_getValue: () => {
// Get a reference to the currently active record
let myRecord = currentRecord.get();
var numLines = objRecord.getLineCount({
sublistId: 'item'
});
// Set the value of a custom field
myRecord.setValue({
fieldId: 'custbody_ns_acs_item_count',
value: numLines
});
},
return {
beforeSubmit: beforeSubmit
};
});
It looks like your script was copied from a couple of different places.
For a bank deposit you need to use the correct sublines ids.
See the data dictionary for deposits
try:
/**
* #NApiVersion 2.1
* #NScriptType UserEventScript
*/
define([], () => {
function beforeSubmit(ctx){
// Get a reference to the currently active record
let myRecord = ctx.newRecord;
const subLines = (sublist)=>{
const lineCount = myRecord.getLineCount({sublistId:sublist});
return lineCount == -1 ? 0 : lineCount;
};
// Set the value of a custom field
myRecord.setValue({
fieldId: 'custbody_ns_acs_item_count',
value: subLines('cashback') + subLines('other') + subLines('deposit')
});
},
return {
beforeSubmit: beforeSubmit
};
});
I want to create a suitelet that could fetch some sales order then be able to edit those on click on submit button, so far I was I'm able to fetch records but I'm not able to add checkboxes and update records in netsuite - suitescript
var list=form.createList({title:"Sales order"});
list.addColumn({
id : 'column1',
type : serverWidget.FieldType.TEXT,
label : 'tranid',
align : serverWidget.LayoutJustification.LEFT
});list.addColumn({
id : 'column2',
type : serverWidget.FieldType.TEXT,
label : 'shipaddress',
align : serverWidget.LayoutJustification.LEFT
});list.addColumn({
id : 'column3',
type : serverWidget.FieldType.TEXT,
label : 'rate',
align : serverWidget.LayoutJustification.LEFT
});
salesorderSearchObj.run().each(function(result){
tranid= result.getValue({name: 'tranid'})
shipaddress= result.getValue({name: 'shipaddress'})
rate= result.getValue({name: 'rate'})
list.addRows({
rows : [{
column1 : tranid,
column2 : shipaddress,
column3 : rate
}]
});
Suite Answer Id 40768 has sample code in SuiteScript 1.0. An outline in 2.0 format is below. The full 1.0 sample from NetSuite is also below. The key is to for the GET req method create the page and display the information as a Sublist instead of a List. Then for all other req methods, get the parameters and take desired action.
2.0 partial outline
define(['N/ui/serverWidget'], function(serverWidget) {
function onRequest(context){
if(context.request.method === 'GET'){
//create page to display results and allow for user input
var form = serverWidget.createForm({
title : 'Simple Form'
});
var sublist = form.addSublist({
id : 'sublistid',
type : serverWidget.SublistType.INLINEEDITOR,
label : 'Inline Editor Sublist'
});
//Add checkbox and atleast internalid
var printField = sublist.addField({
id: 'custpage_rec_process',
label: 'Process',
type: serverWidget.FieldType.CHECKBOX
});
var idField = sublist.addField({
id: 'custpage_rec_id',
label: 'Internal ID',
type: serverWidget.FieldType.TEXT
});
//empty Array to hold Sales Order data
var TranIds = [];
//run search to get Sales Order data
...salesorderSearchObj.run().each(function(result){
//add search column names as columns in the sublist
//add each column value to the sublist
}
//add buttons to sublist and form
sublist.addMarkAllButtons();
sublist.addRefreshButton();
form.addResetButton({label: 'Reset'});
form.addSubmitButton({label: 'Create File'});
//display page for user input
context.response.writePage(form);
} else { //if the previously created/displayed form has been submitted display the following to the user
var req = context.request;
var params = JSON.stringify(context.request.parameters);//can log this to see exactly how the information comes through
//gather submitted data
//take desired action
//display response to user
context.response.writePage('Done');
}
} return {
onRequest: onRequest
}
});
1.0 full sample
function suitelet(request, response){
//Create the form that will be used by the POST and GET requests
var form = nlapiCreateForm('Delete Transactions');
//GET - Show a list of transactions from the search results so the user can select the ones to be deleted
if (request.getMethod() == 'GET' )
{
// Run an existing transaction search
var results = nlapiSearchRecord('transaction', 'customsearch_mass_deletion_results');
// Create a sublist to show the search results
var sublist = form.addSubList('custpage_transaction_list', 'list','Transactions');
// Create an array to store the transactions from the search results
var transactionArray = new Array();
if (results!=null)
{
// Add a checkbox column to the sublist to select the transactions that will be deleted.
sublist.addField('delete','checkbox', 'Delete');
// Add hidden columns for the Internal ID and for the Record type.
// These fields are necessary for the nlapiDeleteRecord function.
sublist.addField('internalid','text', 'Internal ID').setDisplayType('hidden');
sublist.addField('recordtype','text', 'Record Type').setDisplayType('hidden');
// Add a column for the Internal ID link
sublist.addField('internalidlink','text', 'Internal ID');
// Get the the search result columns
var columns = results[0].getAllColumns();
// Add the search columns to the sublist
for(var i=0; i< columns.length; i++)
{
sublist.addField(columns[i].getName() ,'text', columns[i].getName() );
}
// For each search results row, create a transaction object and attach it to the transactionArray
for(var i=0; i< results.length; i++)
{
var transaction = new Object();
// Set the Delete column to False
transaction['delete'] = 'F';
// Set the hidden internal ID field
transaction['internalid'] = results[i].getId();
// Set the hidden record type field
transaction['recordtype'] = results[i].getRecordType();
// Create a link so users can navigate from the list of transactions to a specific transaction
var url = nlapiResolveURL('RECORD', results[i].getRecordType() ,results[i].getId(), null);
internalIdLink = " " + results[i].getId() +" ";
// Set the link
transaction['internalidlink'] = internalIdLink;
// Copy the row values to the transaction object
for(var j=0; j< columns.length ; j++)
{
transaction[columns[j].getName()] = results[i].getValue(columns[j].getName());
}
// Attach the transaction object to the transaction array
transactionArray[i] = transaction;
}
}
// Initiate the sublist with the transactionArray
sublist.setLineItemValues(transactionArray);
sublist.addMarkAllButtons();
form.addSubmitButton('Submit' );
response.writePage( form );
}
//POST - Delete the selected transactions and show a confirmation message
else
{
// Check how many lines in the sublist
var count = request.getLineItemCount('custpage_transaction_list');
// This variable will keep track of how many records are deleted.
var num = 0;
//for each line in the sublist
for(var i=1; i< count+1; i++)
{
//get the value of the Delete checkbox
var deleteTransaction = request.getLineItemValue('custpage_transaction_list', 'delete', i);
// If it's checked, delete the transaction
if(deleteTransaction == 'T')
{
// Get the transaction internal ID
var internalId = request.getLineItemValue('custpage_transaction_list', 'internalid', i);
// Get the transaction type
var recordType = request.getLineItemValue('custpage_transaction_list', 'recordtype', i);
try
{
// Delete the transaction
nlapiDeleteRecord(recordType, internalId);
num++;
}
// Errors will be logged in the Execution Log
catch(ex)
{
nlapiLogExecution('ERROR', 'Error', 'Transaction ID '+ internalId +': '+ ex);
}
}
}
// Show how many records were deleted.
form.addField("custpage_transaction_total", "text").setDisplayType('inline').setDefaultValue(num + " transactions deleted");
response.writePage( form );
}
}
Here's what I'm trying to accomplish:
Set a list of names and numbers (my "group")
When a text message is sent to the Twilio number, forward it on to every member in the group
At a high-level, the idea seems straight forward enough. My programming / syntax skills are rusty, though, and I'd love some help.
I'm using Twilio Functions, and I've been able to send and receive messages successfully. Now I am stuck on how to carry this idea of iterating through a group.
Here's what I've written so far:
var groupmembers = {
jonathan:{
name: 'Jonathan',
number: '+0000000000'
},
joshua:{
name: 'Joshua',
number: '+1110000000'
}
}
exports.handler = function(context, event, callback) {
// Set some values for later use
this.fromNumber = event.From
this.body = event.Body || ''
let twiml = new Twilio.twiml.MessagingResponse();
groupmembers.forEach(function(member) {
// Skip sending if it's the same number
if (member.number === this.fromNumber ) {
return;
}
// Otherwise, let's send a mesage!
twiml.message("Hello World").to( member.number );
callback(null, twiml);
});
};
The issues I believe I have:
Not being sure how to properly set my array or "dictionary"
Not knowing the proper syntax for passing the "to" variable to the message
Not knowing the proper syntax for doing a loop in NodeJS (the Functions console is telling me that 'groupmembers.forEach is not a function')
Thank you for any and all feedback and for pointing me in the right direction!
The mistake you have is pretty simple. groupmembers is an object, you want an array.
You may want something akin to this instead:
var groupmembers = [{
name: 'Jonathan',
number: '+0000000000'
},
{
name: 'Joshua',
number: '+1110000000'
}]
Apart from that, it looks to me as okay.
With more searching and the point in the right direction from Slava I was able to figure it out! Here's the complete code:
/**
* Represents a search trough an array.
* #function search
* #param {Array} array - The array you wanna search trough
* #param {string} key - The key to search for
* #param {string} [prop] - The property name to find it in
* Props: https://stackoverflow.com/a/33097318/315818
*/
function search(array, key, prop){
// Optional, but fallback to key['name'] if not selected
prop = (typeof prop === 'undefined') ? 'name' : prop;
for (var i=0; i < array.length; i++) {
if (array[i][prop] === key) {
return array[i];
}
}
}
var groupmembers = [
{
name: 'Jonathan',
number: '+000000000'
},
{
name: 'Joshua',
number: '+111111111'
}
];
exports.handler = function(context, event, callback) {
let twiml = new Twilio.twiml.MessagingResponse();
// Search for the group member that matches the sender number
let sender = search(groupmembers, event.From, 'number');
// Now, loop through each of the group members
groupmembers.forEach(function(member) {
// Skip sending if it's the same number
if (member.number === event.From ) {
return;
}
// Now, forward on the message to the group member, using the sender's name
twiml.message(`${sender.name}: ${event.Body}`, {
to: member.number
});
});
// Loop ended
callback(null, twiml);
};
My company runs several different types of projects and would like to view the project record differently depending on the type of project being run in the selected project record.
I have the field that selects the form to use, which is titled "custom form" (this is a select field) and a field that our staff enter the type of project "custentityjt_fie_pro_projecttype" (also a select field).
I have created the following before load user event script to try to achieve this:
/**
* #NApiVersion 2.x
* #NScriptType UserEventScript
* #NModuleScope SameAccount
*/
define(["N/record"], function(r) {
function beforeLoad(context) {
var currentRecord = context.newRecord;
var projectType = currentRecord.getValue({
fieldId: "custentityjt_fie_pro_projecttype",
});
currentRecord.setValue({
fieldID: 'customform',
value: projectType
})
}
return {
beforeLoad: beforeLoad,
}
})
When loading the project record in edit mode, the custom form selection does not change, and when loading the project record in view mode, I get the following:
{"type":"error.SuiteScriptError","name":"UNEXPECTED_ERROR","message":null,"stack":["anonymous(N/recordService)","beforeLoad(/SuiteScripts/setForm.js:13)"],"cause":{"type":"internal error","code":"UNEXPECTED_ERROR","details":null,"userEvent":"beforeload","stackTrace":["anonymous(N/recordService)","beforeLoad(/SuiteScripts/setForm.js:13)"],"notifyOff":false},"id":"","notifyOff":false}
I'm very new to Netsuite and programming in general so please be gentle :)
You need to use a Client Script in order to change the Custom Form. Best bet would be to do it in two places, a pageInit() and a fieldChanged(). Another potential issue would be trying to set the Custom form value to a value that was retrieved in the getValue of your field custentityjt_fie_pro_projecttype. The value returned from the currentRecord.getValue() from your example will be the internal id of the custom list value for the Project Type that is set there (go back to your custom list and you will see the internal id values listed). That is an issue because when setting the value of Custom Form field you will need to reference the Internal Id of the Custom Form you wish to use. It would be remarkable if the Internal ID of the Project Type referenced ever matched the Custom Form Internal Id. My recommendation would be to create a hash table in your code to store the references (assuming your list of Project Types didn't frequently change). Give this a try (just make sure you update the values in the lookup variable as those are made up.
/**
*#NApiVersion 2.x
*#NScriptType ClientScript
*/
define([
'N/record'
],
function (
nsRecord
) {
//
// lookup table where the object property represents the internal IDs of the
// custom list values, and the value of each property represents the
// internal id's of the Custom Forms you wish to associate with each list value.
//
var lookup = {
1: 122,
2: 123,
3: 125,
4: 136
};
function fieldChanged(context) {
var field = context.fieldId;
var rec = context.currentRecord;
var projId;
if (field === 'custentityjt_fie_pro_projecttype' && rec.getValue('custentityjt_fie_pro_projecttype')) {
projId = rec.getValue('custentityjt_fie_pro_projecttype');
if (lookup[projId]) {
rec.setValue({
fieldId: 'customform',
value: lookup[projId],
ignoreFieldChange: true,
fireSlavingSync: true
});
}
}
}
function pageInit(context) {
var rec = context.currentRecord;
var mode = context.mode;
var projId;
var formId;
if (mode !== 'create') {
formId = rec.getValue('customform');
projId = rec.getValue('custentityjt_fie_pro_projecttype');
if (lookup[projId] && lookup[projId] !== formId) {
rec.setValue({
fieldId: 'customform',
value: lookup[projId],
ignoreFieldChange: true,
fireSlavingSync: true
});
}
}
}
return {
fieldChanged: fieldChanged,
pageInit: pageInit
};
});
There is a specific reason to have the information in the following way so I can't change how the parent and child object relate:
I have a parent object that contains information about a multi-day fair. There is a child object that references information for each day of the fair, each of these days is referred to as an event. I need to have the event child objects automatically generated at the time the fair object is generated. Then I need to separately generate an array of ObjectID's from the generated child objects. In addition I need to be able to generate arbitrary event objects at a later time that are not based on the fair object. That's why I have the ObjectID's array so I know what was automatically generated and what was user generated.
This is my schema (just the useful parts):
/**
* This is the main object, the user only supplies information for this object
* name, start and end are all provided by the user, num_days is automatically calculated
*/
var FairSchema = new Schema({
name: {
type: String,
default: '',
required: 'Please fill Fair name',
trim: true
},
start_date: {
type: Date,
required: 'Please provide a start date'
},
end_date: {
type: Date,
required: 'Please provide an end date'
},
num_days: {
type: Number,
required: true,
default: 1
},
events: EventsSchema
});
/**
* This is the child object it should pull all of it's information from the parent at the time the parent is created if
* the parent object has more than one day an event child object is created for each day.
*
* name: The same as the parent object, unless multiday then it's the name plus 'Day #'
* start_date: The same as the parent object unless multiday then it's the parent object time + the child object day
* end_date: the same as the parent object unless multiday then it's the parent object time + the child object day
*
*/
var EventSchema = new Schema({
name: {
type: String,
required: 'Please provide a name for the event',
trim: true
},
start_date: Date,
end_date: Date,
});
I've tried something like this in my controller and then called it before the fair object is saved:
initializeFairEvents = function (fair) {
var fairLengthDays = fair.num_days;
var eventStart = Date.parse(fair.start_date);
var eventEnd = Date.parse(fair.end_date);
var one_day = (24 * 60 * 60 * 1000);
var events = fair.events;
var dailyEventLength = eventEnd - eventStart - one_day*(fairLengthDays-1);
if (events !== null && events.length > 0){}
else {
for (var i = 0; i < fairLengthDays; i++) {
var name, start_date, end_date, preserve;
start_date = (i * one_day) + eventStart;
end_date = (i * one_day) + eventStart + dailyEventLength;
preserve = true;
if (fairLengthDays === 1) {
name = fair.name;
} else {
name = fair.name + ' - day ' + (i + 1).toString();
}
fair.events.push({
name: name,
start_date: start_date,
end_date: end_date,
preserve: preserve
});
}
}
};
But then I don't have ObjectID's because nothing has gone to the database to have the ID's generated.
I feel like I'm caught in a loop. Any tips or thoughts would be appreciated.
Since you are using Mongoose you can create a local model instance from the model constructors (assuming Event for Event) like so:
var event = Event();
Or if you only have the parent model instance (assuming fair for Fair) you can use the subdoc create method:
var event = fair.events.create();
You can also include an object to the constructors provided they are of the same form as the intended model. The returned instances will include object IDs automatically that will be used by MongoDB.
That said, the subdoc array push method should do this automatically and each array item should have an ID. None of this is of course on the remote database until you save the parent document.
var one_day = 86400000; // (24 * 60 * 60 * 1000) no sense in computing a static value
initializeFairEvents = function(fair) {
// Assuming fair is a model instance
var fairLengthDays = fair.num_days;
var eventStart = Date.parse(fair.start_date);
var eventEnd = Date.parse(fair.end_date);
var events = fair.events;
var dailyEventLength = eventEnd - eventStart - one_day * (fairLengthDays - 1);
// It looks like you only want to add events if there are no events currently
if (events === null || events.length === 0) {
for (var i = 0; i < fairLengthDays; i++) {
var newEvent = fair.events.create({
name: (fairLengthDays === 1) ?
fair.name :
(fair.name + ' - day ' + (i + 1)),
start_date: (i * one_day) + eventStart,
end_date: (i * one_day) + eventStart + dailyEventLength,
preserve: true
});
// newEvent.id
fair.events.push(newEvent);
}
}
};