I was wondering if it's possible to have a nested data tree where the child row has different headers that the parent row.
E.g.
Parent row has the following headers: Make, Model, SellDate, Warranty
The data type for the headers above are: String, String, Date, Boolean
The child row will have the following headers: Warranty Start Date, Warranty End Date, Type of Warranty
The data type for the headers above are: Date, Date, String
So I would like to create something like this:
Make, Model, Selldate, Warranty
BMW, S3, 13-DEC-2017, Yes
13-DEC-2017, 13-DEC-2010, Labour & Parts
I just got finished writing this same thing. You can accomplish this with a combination of Nested Data and Row Formatters.
On your outer table configuration, specify:
dataTree: true,
rowFormatter: childRowFormatter,
Then, for the rowFormatter function, you can specify something like the below (following the lead from Tabulator's own Nested Tables example):
function childRowFormatter(row) {
// skip if not a child/nested data row - let main table rows render as usual
if (!row.getTreeParent())
return;
var rowEl = row.getElement();
var parentChildData = row.getTreeParent().getData()._children;
// only generate a new table for the first row of child data
if (
row.getPrevRow().getIndex() !== row.getTreeParent().getIndex() ||
row.getPrevRow().getPosition() < 0
) {
rowEl.remove();
// set row element to empty element without size
row._row.element = document.createElement('span');
return;
}
// remove generated cell elements
row._row.deleteCells();
// create and style holder elements
var holderEl = document.createElement("div");
var tableEl = document.createElement("div");
holderEl.style.boxSizing = "border-box";
holderEl.style.padding = "10px 30px 10px 10px";
holderEl.style.background = "#ddd";
holderEl.appendChild(tableEl);
// replace with holder
rowEl.appendChild(holderEl);
// create the new table
var subTable = new Tabulator(tableEl, {
data: parentChildData,
columns: [
{ ... },
...
],
dataTree: true,
dataTreeStartExpanded: true,
rowFormatter: childRowFormatter,
});
}
EDIT: I updated my code after realizing it was a bit more intricate than first revealed. Be cautious, as this code uses some undocumented properties and methods that weren't meant to be exposed to the developer.
Related
I am trying to iterate through and existing smartsheet to get the rowIds (which I need for setting parent/child relationships).
I am struggling :-(
Obviously I don't get the required syntax on this one. Here is what I tried:
var options = {
Id: *******************
};
var row_ids = '';
// get the sheet
smartsheet.sheets.getSheet(options)
.then(function(sheetinfo) {
// iterate through the rows array and build comma-delimited list of row ids
for (rowIds in sheetinfo) {
row_ids += row_ids.concat(', ');
}
});
console.log(row_ids);
Any help would be most appreciated.
Bowow99
In the Get Sheet response, sheetInfo contains a collection of rows and each row object in that collection contains the property id. So to successfully implement the scenario you've described, you need to loop through the sheetInfo.rows array, and for each row in that array, append the value of its id property (followed by a comma) to create the comma-delimited string that you're attempting to build. At the end of this loop, there'll be an extra comma at the end (following the last row id you added to the string) -- so you'll need to remove it using the substring function.
The following code does what I've described above. Please note, I'm not a JavaScript expert -- so there may be a more efficient way to do this...but this code gets you the end result you're after: a comma-delimited string of the row Ids within the specified sheet.
var options = {
id: 8337220210845572 // Id of Sheet
};
var row_ids = '';
// Get sheet
smartsheet.sheets.getSheet(options)
.then(function(sheetInfo) {
// iterate through rows in the sheet and build comma-delimited string of row ids
for (var i=0; i < sheetInfo.rows.length; i++) {
row_ids += sheetInfo.rows[i].id + ',';
}
// remove the final (excess) comma from the end of the row_ids string
row_ids = row_ids.substring(0, row_ids.length-1);
console.log(row_ids);
})
.catch(function(error) {
console.log(error);
});
I understand SharePoint lists are like excel, so I was wondering if it was possible to conditionally highlight whole rows/ cells based on the text value of a field.
I have a column in a list called "Status" with 4 options (initial, in progress, completed, awaiting developer resource). I would like to highlight these rows (or even just the status field) a different colour, depending on the value of the status.
Is this possible? Cant find anything relating to this for SP 2016
Cheers
Please use JavaScript to highlight the row based on the Status field:
<script type="text/javascript">
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function() {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
OnPostRender: function(ctx) {
var statusColors = {
'initial' : '#FFF1AD',
'in progress' : '#FFD800',
'completed' : '#01DF3A',
'awaiting developer resource':'#ff0000'
};
var rows = ctx.ListData.Row;
for (var i=0;i<rows.length;i++)
{
var status = rows[i]["Status"];
var rowId = GenerateIIDForListItem(ctx, rows[i]);
var row = document.getElementById(rowId);
row.style.backgroundColor = statusColors[status];
}
}
});
});
</script>
And place the code above in a Content Editor Web Part in the list view page, so the list row will render different color based on status:
I want to get the value from a Item sublist of Sales Order record.
But unable to get it. Though I can get the value of entity fields of the SO record.
Below is the snippet of the code:
var filters = new Array();
filters[0] = new nlobjSearchFilter("mainline",null,"is","T");
var column=new Array();
column[0] = new nlobjSearchColumn("trandate");
column[1] = new nlobjSearchColumn("item");
column[2] = new nlobjSearchColumn("cust_col_1");
var result = nlapiSearchRecord('salesorder', null, filters, column);
for(var i = 0; i<result.length; i++)
{
var col = result[i].getAllColumns();
var date = result[i].getFieldValue("trandate"); //I get this
var item_id = result[i].getLineItemValue("item", "item", i+1); // I don't get this
var cust_col = result[i].getLineItemValue("item", "cust_col_1", i+1); //I don't get this
}
I think I am defining the columns wrong.
This part
var item_id = result[i].getLineItemValue("item", "item", i+1); // I don't get this
var cust_col = result[i].getLineItemValue("item", "cust_col_1", i+1); //I don't get this
is also wrong, you use this syntax if you have loaded the record but for search results you just use
result[i].getValue('cust_col_1")
By specifying the filter new nlobjSearchFilter("mainline",null,"is","T"), you're basically telling the search that you don't want any line item data. This means that you will be unable to read any column data, custom or otherwise.
The mainline filter parameter has basically three options, 'F' means you want the line item details. 'T' means you just want the header data. Leaving this filter out will return one row for the header information and one row for each line item on the transaction.
I have a custom list that is used as a matrix option of Inventory item. Its 'Color'. This custom list has an abbreviation column. I am creating a saved search on item and using Color field(join) and trying to access 'Abbreviation' field of color.
Abbreviation on custom list is available on when 'Matrix Option List' is checked.
Can someone please help me achieve this? I tried to do this through script and it seems like we cannot access 'Abbreviation' column through script. I also tried to use script to write a search directly on 'Color' - custom list and get the 'abbreviation' through search columns. It did not work. Is there a way to access 'Abbreviation' from custom lists?
Thanks in Advance
You can access it via suitescript by using the record type "customlist" and the internal id of the list like so:
var rec = nlapiLoadRecord('customlist', 5);
var abbreviation = rec.getLineItemValue('customvalue', 'abbreviation', 1);
nlapiLogExecution('DEBUG', 'abbreviation', abbreviation);
Keep in mind that the third argument of getLineItemValue is the line number, not the internal ID of the item in the list. If you want to find a specifc line item, you may want to use rec.findLineItemValue(group, fldnam, value).
Unfortunately, it doesn't look like this translates to saved searches. The suiteanswer at https://netsuite.custhelp.com/app/answers/detail/a_id/10653 has the following code:
var col = new Array();
col[0] = new nlobjSearchColumn('name');
col[1] = new nlobjSearchColumn('internalid');
var results = nlapiSearchRecord('customlist25', null, null, col);
for ( var i = 0; results != null && i < results.length; i++ )
{
var res = results[i];
var listValue = (res.getValue('name'));
var listID = (res.getValue('internalid'));
nlapiLogExecution('DEBUG', (listValue + ", " + listID));
}
However, whatever part of the application layer translates this into a query doesn't handle the abbreviation field. One thing to keep in mind is that the 'custom list' record is basically a header record, and each individual entry is it's own record that ties to it. You can see some of the underlying structure here, but the takeaway is that you'd need some way to drill-down into the list entries, and the saved search interface doesn't really support it.
I could be wrong, but I don't think there's any way to get it to execute in a saved search as-is. I thought the first part of my answer might help you find a workaround though.
Here is a NetSuite SuiteScript 2.0 search I use to find the internalId for a given abbreviation in a custom list.
/**
* look up the internal id value for an abbreviation in a custom list
* #param string custom_list_name
* #param string abbreviation
* #return int
* */
function lookupNetsuiteCustomListInternalId( custom_list_name, abbreviation ){
var internal_id = -1;
var custom_list_search = search.create({
type: custom_list_name,
columns: [ { name:'internalId' }, { name:'abbreviation' } ]
});
var filters = [];
filters.push(
search.createFilter({
name: 'formulatext',
formula: "{abbreviation}",
operator: search.Operator.IS,
values: abbreviation
})
);
custom_list_search.filters = filters;
var result_set = custom_list_search.run();
var results = result_set.getRange( { start:0, end:1 } );
for( var i in results ){
log.debug( 'found custom list record', results[i] );
internal_id = results[i].getValue( { name:'internalId' } );
}
return internal_id;
}
Currently NetSuite does not allows using join on matrix option field. But as you mentioned, you can use an extra search to get the result, you could first fetch color id from item and then use search.lookupFields as follows
search.lookupFields({ type: MATRIX_COLOR_LIST_ID, id: COLOR_ID, columns: ['abbreviation'] });
Note: Once you have internalid of the color its better to use search.lookupFields rather than creating a new search with search.create.
Basically my requirement is to create a matrix item through the script. I'm wondering if is there any way to create a matrix item through Restlet or any Workflow. I succeeded creating the parent item with some specific attributes but it seems after submitting the record there is no child items getting created.
Bellow is the code snippet what I'm using right now.
var record= nlapiCreateRecord('serviceitem');
record.setFieldValue('name', 'Matrix Parent Record');
record.setFieldValue('matrixtype', 'PARENT');
record.setFieldValue('custitem_matrix_op1', '2');
record.setFieldValue('custitem_matrix_op2', '3');
var id=nlapiSubmitRecord(record);
Any help or suggestions would be appreciated.
Thank You.
Little example:
var parent = nlapiCreateRecord('noninventoryitem');
parent.setFieldValue('matrixtype', 'PARENT');
parent.setFieldValue('itemid', 'zzz ttt');
parent.setFieldValue('subsidiary', 2);// internalid for subs.
parent.setFieldValue('taxschedule', 4);// internalid for N/A in my account
parent.setFieldValues('itemoptions', ['CUSTCOL_LLL_EVENTLOCATION_OPT']);//option to be shown at PDP
parent.setFieldValue('custitem_event_location', 11);// particular option id (see in your list)
var parentid = nlapiSubmitRecord(parent);
var child = nlapiCreateRecord('noninventoryitem');
child.setFieldValue('matrixtype', 'CHILD');
child.setFieldValue('parent', parentid);
child.setFieldValue('itemid', 'zzz ttt child');
child.setFieldValue('taxschedule', 4);// internalid for N/A in my account
child.setFieldValues('itemoptions', ['CUSTCOL_LLL_EVENTLOCATION_OPT']);// same as in parent record
child.setFieldValue('matrixoptioncustitem_event_location', 11);// same as in parent record
var childid = nlapiSubmitRecord(child );
It will create a matrix with one child item.
Do not forget to set up additional fields like price and "display in web store" (isonline field).
After creating the parent item, you need to create child item as well,In the child item set the parent item internal ID & submit the record.
but here there is a drawback. because of static sub list, am not able to append the child items to parent in the Matrix sub list.
Using Suite Talk you could do something like this
/** Create Sweaters as matrix items.
* First create the parent - no matrix properties except "Matrix Type" is Parent
* Second create the matrix children with a combination of sizes and colors.
* This can be done in a single addList (as shown).
*/
//Define mrr method
public static RecordRef mrr(String internalId)
{
RecordRef toRet = new RecordRef();
toRet.setInternalId(internalId);
return toRet;
}
// Define makeListOrRecordRef method
public static ListOrRecordRef makeListOrRecordRef(String sTypeId, String internalId, String sName)
{
ListOrRecordRef toRet = new ListOrRecordRef();
toRet.setInternalId(internalId);
toRet.setName(sName);
toRet.setTypeId(sTypeId);
return toRet;
}
public void testMatrixSample() throws Exception
{
// Color is a Custom List of TypeId/RecType 1 that has already been created. 1,2,3 represent the
// internalIds of Red, Green, Blue
ListOrRecordRef[] colorArray = new
ListOrRecordRef[] {makeListOrRecordRef("1","1","Red"), makeListOrRecordRef("1","2","Green"),
makeListOrRecordRef("1","3","Blue")}; // Representing red, green and blue
// Size is a CustomList of TypeId/RecType 2 that has already been created
ListOrRecordRef[] sizeArray = new ListOrRecordRef[]{makeListOrRecordRef("2","2","Large"),makeListOrRecordRef("2","3","Small")};
//Representing large and small
InventoryItem[] toSubmit = new InventoryItem[1+colorArray.length*sizeArray.length];
toSubmit[0] = new InventoryItem();
toSubmit[0].setExternalId("parentSweater");
toSubmit[0].setItemId("sweater");
toSubmit[0].setMatrixType(ItemMatrixType._parent);
// set other fields on the Parent
for (int i=0;i<colorArray.length*sizeArray.length;i++)
{
toSubmit[i+1] = new InventoryItem();
toSubmit[i+1].setMatrixType(ItemMatrixType._child);
// mrr Creates a recordRef given an internal and externalId, the latter of which we specify.
// This makes it so we can submit all the records at once
toSubmit[i+1].setParent(mrr((String)null,"parentSweater"));
// "sweater-large-red","sweater-large-green"...
toSubmit[i+1].setItemId("sweater-"+colorArray[i%3].getName() + "-" +
sizeArray[i % 2].getName());
// set externalId so it's easier to find later
toSubmit[i+1].setExternalId(toSubmit[i+1].getItemId());
// CUSTITEM_COLOR,SIZE are the names of the Item Custom Fields, applied to
//InventoryItem that were setup as a Matrix types.
SelectCustomFieldRef colorRef = new SelectCustomFieldRef();
colorRef.setInternalId("CUSTITEM_COLOR");
colorRef.setValue(colorArray[i%3]);
SelectCustomFieldRef sizeRef = new SelectCustomFieldRef();
sizeRef.setInternalId("CUSTITEM_SIZE");
sizeRef.setValue(sizeArray[i%2]);
toSubmit[i+1].setMatrixOptionList(new MatrixOptionList(new
SelectCustomFieldRef[]{colorRef,sizeRef}));
// Set other matrix item child files
//....
}
WriteResponseList wr = c.getPort().addList(toSubmit);
}