gridx shows the last record of my dynamic data - dojox.grid

hello am using grid to display dynamic data dojo, but what I get is that sample (n) times, but always shows me the last record, but if I do it with dummy data works well, I hope you help me with this issue.
define(["js/module/modControllerPersona", "dojo/store/Memory", "gridx/Grid", "gridx/core/model/cache/Sync", "dojo/data/ObjectStore"],
function(modControllerPersona, Store, Grid, Cache, ObjectStore){
var grid, store, data;
var persona = new Array();
return{
datagridx: function(){
modControllerPersona.persona().then(function(result){
persona = JSON.parse(result);
data = persona.items;
store = new Store({data: data});
var columns = [
{name: 'id', field: 'descripcion'},
{name: 'descripcion', field: 'id_Maquinaria'},
{name: 'descripcion', field: 'id_tipo_Maquinaria'},
{name: 'Nombre', field: 'kind'},
{name: 'Nombre', field: 'nombre'},
{name: 'Nombre', field: 'visible'}
];
grid = new Grid({
cacheClass: Cache,
store: store,
structure:columns
}, 'gridNode');
grid.startup();
});

Perhaps this can help you, I had a similar problem. If you don't have a column id it doesn't work right. But if you adjust your store to something like this:
var store = new Memory({
data: data,
idProperty: 'descripcion'
});
Perhaps the "new Memory" is not necassary. In my case this works (but I didn't tested it here again). I have no id but I have another unique field instead of this. I suppose it is because of your
{name: 'id', field: 'descripcion'}
If you use instead of "descripcion" the name "id" I think it should work too.

Just add "idProperty" for Gridx, I solved my problem
My dynamic data:
var data = [{"ID":"1","Số liệu thống kê":"Năng suất lập trình","Ngôn ngữ LT":"Java Web","Công đoạn":"Code - Review Code","Loại Project":"Customize/Full","Đơn vị tính":"KLOC/ManMonth","UCD1":"11.6","ITS":null},{"ID":"2","Số liệu thống kê":"Năng suất lập trình","Ngôn ngữ LT":"Java Web","Công đoạn":"Code - Review Code - UT","Loại Project":"Customize/Full","Đơn vị tính":"KLOC/ManMonth","UCD1":"4.6","ITS":null},{"ID":"3","Số liệu thống kê":"Năng suất lập trình","Ngôn ngữ LT":"Java Web","Công đoạn":"Code","Loại Project":"Customize/Full","Đơn vị tính":"KLOC/ManMonth","UCD1":"15.15","ITS":null}];
require([
'dojo/store/Memory',
'gridx/Grid',
'gridx/core/model/cache/Sync'
], function (Memory, Grid, Cache) {
var store = new Memory({
data: data,
idProperty: 'ID'
});
Hope this help

Related

SuiteScript 2.1 record updates too slow

I have afterSubmit function that I wrote that will iterate through all related transactions connected with the same CTG_ID value (which is a custom parent record) and the script will actually update just one field on all of these values.
My problem is because this is a really slow method, more transactions I have connected to the same parent more time the user needs to wait after clicking the "Save" button. Script execution time is terrible.
Is there any faster / better way to update a certain field on a group of records?
My function for updating those transactions:
function afterSubmit(context) {
const newRecord = context.newRecord;
const ctgId = newRecord.getValue({ fieldId: 'custbody_ctgid' });
const currentCustomerPo = newRecord.getValue({ fieldId: 'custbodyctg_customer_po'})
search.create({
type: 'transaction',
filters: [['custbody_ctgid', 'anyof', ctgId],
"AND",
['mainline','is','T']],
columns: ['custbodyctg_customer_po']
}).run().getRange({start: 0, end:100}).forEach((result,line) => {
const ctgPo = result.getValue('custbodyctg_customer_po') as string;
const recType = result.recordType;
const recId = result.id;
let rec = record.load({
type: recType,
id: recId,
isDynamic: true
})
rec.setValue({
fieldId: 'custbodyctg_customer_po',
value: currentCustomerPo,
ignoreFieldChange: true
})
rec.save();
})
}
Thanks to Brian Duffy's answer, this is working a lot better!
I modified the script so now I iterate through results with each instead of forEach function. I'm using record.submitFields function instead of record.load
function afterSubmit(context) {
const newRecord = context.newRecord;
const oldRecord = context.oldRecord;
const ctgId = newRecord.getValue({fieldId: 'custbody_ctgid'});
const currentCustomerPo = newRecord.getValue({fieldId: 'custbodyctg_customer_po'})
const oldCustomerPo = oldRecord.getValue({fieldId: 'custbodyctg_customer_po'})
if (oldCustomerPo !== currentCustomerPo) {
search.create({
type: 'transaction',
filters: [['custbody_ctgid', 'anyof', ctgId],
"AND",
['mainline', 'is', 'T']],
columns: ['custbodyctg_customer_po', 'type']
}).run().each((result) => {
if (result.recordType !== 'salesorder') {
const recType = result.recordType;
const recId = result.id;
record.submitFields({
type: recType,
id: recId,
values: {
custbodyctg_customer_po: currentCustomerPo
},
options: {
enableSourcing: false,
ignoreMandatoryFields: true
}
});
}
return true;
})
}
}
Still, after testing few transactions with an average of 5 linked transactions to them this is running like 5-7 seconds. Stil slow for me. If anyone has suggestions it would be AWESOME!
I would try using run.each instead of getRange for your search results and use record.sumbitFields instead of loading and saving the record.
If speed of saving the current record is key, consider making your logic asynchronous. The current record will save nearly as fast as normal, just taking the time to schedule a Map/Reduce or Scheduled script.
The user event script would just send as parameters the current record's Id, the value in CTG_ID and the value in custbodyctg_customer_po. The asynchronous script would search for all tranx with that same Id except for the one that triggered it (or skip any records with a matching value while looping thru results), then submit the custbodyctg_customer_po for each of those.
It's a heavier solution, so you must weigh priorities.
Alternatively, look into record.submitFields.promise(options). It seems a limitation is it cannot update Select fields (ie List/Record)

Source State record to sublist field

I am trying to create a custom sublist with sublist field with source to be States record that is managed in Setup > Company > States/Provinces/Countries section.
Here is the example code that I am using and it doesn't work.
_sublist.addField({
id: 'custpage_license_state,
type: serverWidgetModule.FieldType.SELECT,
label: 'LICENSE STATE',
source: 'state' //not recognizing record id
});
I have tried using 'state', 'states', '-195', -195 (was able to locate that this is the internal id for states record in our instance "-195"), but nothing works.
Does anybody has an idea on how to make that work.
Thanks.
The State/Province record isn't exposed. You'll need to add the options to the field manually. You could either perform a search against the customer records which will only return states currently assigned;
/**
* Gets customers geographical states.
*
* #returns {Array} of state information.
*/
function getStates() {
var records = [];
var customerSearchObj = search.create({
type: "customer",
filters: [
["formulatext: {country}", "isnotempty", ""],
"AND",
["formulatext: {state}", "isnotempty", ""]
],
columns: [
search.createColumn({
name: "statedisplayname",
summary: "GROUP",
sort: search.Sort.ASC
}),
search.createColumn({ // abbreviation
name: "state",
summary: "GROUP"
})
]
});
customerSearchObj.run().each(function (result) {
var rec = {
state: result.getValue({name: 'state', summary: 'GROUP'}),
stateDisplay: result.getValue({name: 'statedisplayname', summary: 'GROUP'})
};
records.push(rec);
return true;
});
return records;
}
Or, create a customer in memory and then get the states; (Sorry, SS1 code, taken from SA 63293.)
function getAllStatesForCountry() {
var customer_record = nlapiCreateRecord('customer', {recordmode: 'dynamic'});
customer_record.selectLineItem('addressbook', 1);
var addrSubrecord = customer_record.createCurrentLineItemSubrecord('addressbook', 'addressbookaddress');
addrSubrecord.setFieldValue('country', 'GB');
var stateField = addrSubrecord.getField('dropdownstate');
return stateField.getSelectOptions();
}
And then loop through the result and add them to your field using mySelect.addSelectOption().

Query attachment from a Message record

Through the UI, I have created several Message records attached to a Support Ticket record, two of which have file attachments. I have been able to retrieve the ticket, and its related messages in Suitescript - which are correctly reporting hasAttachment as 'T' - but I cannot seem to access the attachments themselves. The documentation states that the attachments are a sublist called 'mediaitem' (or 'mediaitemlist', depending on where you look), but none of the sublist APIs have any success on those names.
var record = nlapiLoadRecord('message', 1092823, {recordmode: 'dynamic'});
var itemCount = record.getLineItemCount('mediaitem');
// returns -1
The documentation and other online info is pretty sparse, so any help would be greatly appreciated.
Yeah, indeed there is a poor documentation. And mediaitem sublist did not help me either to give any meaningful result.
However, there is an alternate solution to it.
Create a saved search from UI on message record type.
Make sure you add a search column Attachments : Internal ID (i.e.
using attachment fields...)
Once, this is done, run your search in suitescript as
var res = nlapiSearchRecord('message', 'YOUR_UI_SEARCH_ID', ARRAY_OF_ADDITIONAL_FITLTERS);
res[i].getValue('internalid', 'attachments')
This is how you can do it in Suitescript 2.0. First search the message ids then search for the attachments related to those message ids. You can create the searches on the fly so no need for saved searches.
You can pass an array of internal ids of cases or messages if you want to save governance points depending on your scenario.
Note: The following code samples assumes that you loaded the search module as SEARCHMODULE.
Step 1 - This is how to get the message ids with attachments from a support case record (just change the type to support ticket):
function getMessageIdsFromCase(supportCaseId){
var supportcaseSearchObj = SEARCHMODULE.create({
type: "supportcase", //Change if you need to
filters: [
["internalid","anyof",supportCaseId],
"AND",
["messages.hasattachment","is","T"]
],
columns: [
SEARCHMODULE.createColumn({
name: "internalid",
join: "messages"
})
]
});
var resultsSet = supportcaseSearchObj.run();
var results = resultsSet.getRange(0, 999);
var messages = [];
for (var i in results) {
var result = results[i];
var message = result.getValue(result.columns[0]);
messages.push(message);
}
return messages;
}
Then you just call the function like this:
getMessageIdsFromCase(caseInternalId); //Returns an array of message ids
Step 2 - Then you search the attachments using the message internal id with this function:
function getAttachmentIdsFromMessage(messageInternalId){
var messageSearchObj = SEARCHMODULE.create({
type: "message",
filters: [
["internalid","anyof",messageInternalId]
],
columns: [
SEARCHMODULE.createColumn({
name: "internalid",
join: "attachments"
})
]
});
var resultsSet = messageSearchObj.run();
var results = resultsSet.getRange(0, 999);
var attachments = [];
for (var i in results) {
var result = results[i];
var attachment = result.getValue(result.columns[0]);
attachments.push(attachment);
}
return attachments;
}
Then you just call the function like this:
getAttachmentIdsFromMessage(messageInternalId); //Returns an array of attachment ids
UPDATE:
heard from NS after submitting a case. Appears this is not supported yet:
Hi Shane,
I hope you are doing well today.
Upon checking, the ability to access files attached to records are not yet supported in SuiteScript. You can check out SuiteScript Records Browser at SuiteAnswers ID 10511 for the full list of all available records in SuiteScripts and each's accessible sublist. Let me know if you have further questions.
Caleb Francisco | Customer Support
NetSuite: Where Business is Going
Using search.createColumn with joins is the key it looks like. I ended up using quick code below this to get any $files (html) attached to $transaction (returnauthorization), which were in my case, supposed to be mediaitems on a return auth that I couldn't get via the record module in ss2.0
var getHtmlFilesOnReturnAuth = function (return_auth_id, file_type) {
var filters = [
search.createFilter({name: "internalid", operator: "is", values: [return_auth_id]}),
search.createFilter({name: "filetype", join: "file", operator: "is", values: [file_type]}),
];
var images = [];
search.create({
type: "returnauthorization",
filters: filters,
columns: [
search.createColumn({name: "internalid", summary: "group"}),
search.createColumn({name: "internalid", join: "file", summary: "group"}),
search.createColumn({name: "filetype", join: "file", summary: "group"}),
search.createColumn({name: "name", join: "file", summary: "group"}),
]
}).run().each(function (result) {
if (result) {
images.push({
id: result.getValue({name: "internalid", join: "file", summary: "group"}),
file_name: result.getValue({name: "name", join: "file", summary: "group"}),
file_type: result.getValue({name: "filetype", join: "file", summary: "group"}),
});
}
return true;
});
return images;
};
var images = getHtmlFilesOnReturnAuth("2134404", "HTMLDOC");

How to open/show CellEditor of Alloy Datatable manually?

I'm writing a code , so that I can change column's editor manually . I'm able to set editor event on double click event ('dblClick') .
When I click on cell, effect is observe on next click .
What is missing ?
Or
How can open/show editor manually ?
My code is like .......
table.delegate('dblclick', function(e) {
var target = e.currentTarget;
var model = table.getRecord(target.get('id'));
var type = model.get('type');
var column = this.get('columns.value');
column.editor = editors[type];
this.showCellEditor(target);
},'tr', table);
this.showCellEditor(target); --> this method is of YUI (Yahoo's UI) . Is any method is resemble to this one in Alloy UI ?
Instead of selecting an editor on the fly, why not group similar data in the same column so that the same editor can be used?
var columns = [{
editor: new Y.TextAreaCellEditor(),
key: 'name'
}, {
editor: new Y.DateCellEditor({
dateFormat: '%m/%d/%Y'
}),
key: 'birthday'
}];
If you group the data like that, then you can change the editEvent of the dataTable to dblclick like so:
var dataTable = new Y.DataTable({
// ...
editEvent: 'dblclick'
}).render('#dataTable');
Here is a working example:
YUI().use('aui-datatable', function(Y) {
var columns = [{
editor: new Y.TextAreaCellEditor(),
key: 'name'
}, {
editor: new Y.DateCellEditor({
dateFormat: '%m/%d/%Y'
}),
key: 'birthday'
}];
var data = [{
birthday: '9/9/1999',
name: 'Jonathan Smithy'
}, {
birthday: '10/10/1990',
name: 'Bob Duncan'
}];
var dataTable = new Y.DataTable({
columnset: columns,
recordset: data,
editEvent: 'dblclick'
}).render('#dataTable');
});
<script src="https://cdn.rawgit.com/stiemannkj1/701826667a70997013605edcd37e92a6/raw/469fe1ae297e72a5a80eb9015003b7b04eac735e/alloy-ui-3.0.1_aui_aui-min.js"></script>
<link href="https://cdn.rawgit.com/stiemannkj1/90be22de7f48c729b443af14796d91d3/raw/a9f35ceedfac7fc0559b121bed105eaf80f10bf2/aui-css_css_bootstrap.min.css" rel="stylesheet"></link>
<div id="dataTable"></div>
If you must dynamically choose and display the editor, I'd recommend taking a look a the getEditor(record, column) method of A.DataTable.CellEditorSupport. I was unable to get getEditor() to work, but I'd assume that if you can get it working, you could do something like getEditor(data[1], column[0]).show().

Ext Js : add nested panels dynamically

I have several records of the same type that I want to show on the screen. I thought about creating several panels that will print the data of each record. I chose this solution because data structure is too complex to be printed in a simple grid. Here is a simplified example of that structure :
{
label: 'myLabel',
{
attr1: 'value1',
attr2: 'value2'
}
startValidityDate: oneDay,
endValidityDate: anotherDay
}
I try to add dynamically nested panels in my current panel :
var myStore = new Ext.data.Store({
id: 'myStore',
restful: true,
idProperty: 'OID',
root: 'tbas',
proxy: myProxy,
reader: myReader,
autoLoad: false,
listeners: {
'load': function(data){
var records = data.getRange();
var currStore = null;
for(var i=0; i<records.length; i++) {
currStore = new Ext.Panel({
layout:'vBox',
items: [{
xtype: 'textfield',
fieldLabel: I18nManager.get('label_ttbaUI_label'),
name: 'tbaLabel',
value: records[i].data.tbaLabel
},{
xtype: 'textfield',
fieldLabel: I18nManager.get('label_ttbaUI_label'),
name: 'tbaOid',
value: records[i].data.tbaoid
}]
});
recordList.add(currStore);
console.log("------------------------------");
console.log(currStore);
}
recordList.doLayout();
}
}
});
var recordList = new Ext.Panel({
id: 'recordList',
renderTo: 'recordPart',
layout:'vBox',
title: I18nManager.get('label_ttbaUI_selected_tariffs')
});
recordList.doLayout();
In the firebug console, the UI objects seems to be ok.
My problem is that the recordList elements are not visible
I can see that they exist in the FB console, but they are not well printed on the screen.
Did I forgot something that make the elements hidden ? or bad printed ?
I'm sure that it is a CSS problem, some trouble with ext-all.css : when I remove the content of that CSS, I can see my fields
There must be something wrong in the way I wrote the code so that it causes the render problem WDYT ???

Resources