//Define the columns of the table
var myColumnDefs = new Array();
for ( i=0; i < $names.length ; i++)
{
var colObjConfig = new Object();
colObjConfig.label =$names[i];
colObjConfig.resizeable =true;
colObjConfig.width =150;
myColumnDefs.push ( new YAHOO.widget.Column(colObjConfig));
}
var beginningScoreRow = "1111,1111|1111,1111";
var myDataSource = new YAHOO.util.FunctionDataSource( function () {
return beginningScoreRow ;} );
myDataSource.responseType = YAHOO.util.DataSource.TYPE_TEXT;
myDataSource.responseSchema = {
fieldDelim : ",",
recordDelim : "|"
};
var myDataTable = new YAHOO.widget.DataTable("statusTable", myColumnDefs,
myDataSource);
I want to use TYPE_TEXT responseType for a YUI DataSource. But the above failed to render the data in the YUI table column cells. I do not see any error in JS console either.
What am i missing?
var column = new YAHOO.widget.Column(colObjConfig);
column.field = ""+i+"";
myColumnDefs.push (column );
Changed the column definition to add the field property and it did the trick...
Related
I get stack. PLZ help.
In class "work" i creating a frame of a table. Than in object "myWork1" i must fill that frame of a table.
But it didnt works. Finally i want to creating a table with special information in it.
What im doing wrong?
<p id="demo">demo</p>
function work(td1) {
this.firstWork = function(){
var table = document.createElement("table");
var table_tr = document.createElement("tr");
var table_td = document.createElement("td");
var table_td_text = document.createTextNode(this.td1=td1);
table_td.appendChild(table_td_text);
table_tr.appendChild(table_td);
table.appendChild(table_tr);
io.appendChild(table);
}
}
var myWork1 = new work("111");
document.getElementById("demo").innerHTML =
return myWork1.tableWork();
<p id="demo">demo</p>
function work(td1) {
this.firstWork = function(){
var table = document.createElement("table");
var table_tr = document.createElement("tr");
var table_td = document.createElement("td");
var table_td_text = document.createTextNode(td1);
table_td.appendChild(table_td_text);
table_tr.appendChild(table_td);
table.appendChild(table_tr);
return table;
}
}
var myWork1 = new work("111");
document.getElementById("demo").appendChild(myWork1.firstWork());
A working example here : jsfiddle
Re-entering the code as follows, with combined suggestions from #bknights & #prasun
function main_GetVendorItems(request, response) {
response.write(JSON.stringify(getVendorItems(request)));
}
function getVendorItems(request) {
var vendorid = request.getParameter('vendor');
nlapiLogExecution('DEBUG', 'searchRes', 'Searching For Vendor ID: '+vendorid );
var filters = new Array();
var columns = new Array();
filters[0] = new nlobjSearchFilter('vendorcost', null, 'greaterthan', 0);
filters[1] = new nlobjSearchFilter('othervendor', null, 'is', [vendorid] );
columns[0] = new nlobjSearchColumn('itemid');
columns[1] = new nlobjSearchColumn('entityid', 'vendor');
columns[2] = new nlobjSearchColumn('vendorcost');
columns[3] = new nlobjSearchColumn('vendorcode');
columns[4] = new nlobjSearchColumn('vendorpricecurrency');
var searchresults = nlapiSearchRecord('item', null, filters, columns );
//for test test each element of the array
(searchresults || []).forEach(function(res){
nlapiLogExecution('DEBUG', 'searchRes', res instanceof nlobjSearchResult);
})
return searchresults;
}
The calling function as below:
function test () {
var vendorID = nlapiGetFieldValue('custrecordvpr_supplier'); alert('searching for vendor ID: '+vendorID );
var url = nlapiResolveURL('SUITELET', 'customscriptls_getvendoritems', 'customdeployls_getvendoritems', true);
var params = {}
params['vendor'] = vendorID;
var response = nlapiRequestURL(url, params);
var VendorItemsSublist = response.getBody();
nlapiSetFieldValue('custrecordvpr_comment',VendorItemsSublist );
}
I've got a comment field on my custom record/form which shows the returned object. On the code above, what's really strange, is I'm not getting any information being added to the execution log,even the first entry where it should post the vendor id being searched for.
I've checked the script and deployment records, and there is nothing untoward or amiss there... I have got to be missing something extremely simple.
Incidentally, the code is being called by a "Test" button on my custom form.
It looks like you are not writing properly to the response object in Suitelet.
function main_GetVendorItems(request, response) {
response.write(JSON.stringify(getVendorItems(request)));
}
function getVendorItems(request) {
var vendorid = request.getParameter('vendorid');
var filters = new Array();
var columns = new Array();
filters[0] = new nlobjSearchFilter('vendorcost', null, 'greaterthan', 0);
//filter should be on vendor
filters[1] = new nlobjSearchFilter('vendor', null, 'anyof', vendorid );
columns[0] = new nlobjSearchColumn('itemid');
columns[1] = new nlobjSearchColumn('entityid', 'vendor');
columns[2] = new nlobjSearchColumn('vendorcost');
columns[3] = new nlobjSearchColumn('vendorcode');
columns[4] = new nlobjSearchColumn('vendorpricecurrency');
var searchresults = nlapiSearchRecord('item', null, filters, columns );
//for test test each element of the array
(searchresults || []).forEach(function(res){
nlapiLogExecution('DEBUG', 'searchRes', res instanceof nlobjSearchResult);
})
return searchresults;
}
Also, make sure vendor id is specified in request parameter
var url = nlapiResolveURL('SUITELET', 'customscriptls_getitemvendors', 'customdeploy_getitemvendors', true);
var params = {}
params['itemid'] = itemID ; // itemID is passed to this function.
params['vendorid'] = vendorID ; // vendorID is passed to this function.
var response = nlapiRequestURL(url, params);
var itemVendorSublist = response.getBody();
If you're trying to query on item vendor then simply try
filters[1] = new nlobjSearchFilter('vendor', null,'anyof', vendorid );
This works in a console window. I suspect you are not supplying the numeric internal id in your parameter:
var vendorid = 43; // or 32 values from my test account. Want to confirm that the code works whether vendor is item's preferred vendor or not.
nlapiSearchRecord('item', null, [
new nlobjSearchFilter('vendorcost', null, 'greaterthan', 0),
new nlobjSearchFilter('internalid', 'vendor', 'anyof', [vendorid]), //numeric value
new nlobjSearchFilter('internalid', null, 'is', '42') // limit results for testing
], [
new nlobjSearchColumn('itemid'),
new nlobjSearchColumn('entityid', 'vendor'),
new nlobjSearchColumn('vendorcost'),
new nlobjSearchColumn('vendorcode'),
new nlobjSearchColumn('vendorpricecurrency')
]).forEach(function(it) {
console.log("%s from %s", it.getValue('itemid'), it.getValue('entityid', 'vendor'));
});
Although I've been working with Netsuite since 2002 I've never returned a set of search results directly from a Suitelet. I've seen that a couple of times recently in people's answers on this forum but I still find it a bit amusing.
If I were writing this I'd have tended to do the following:
var results = (nlapiSearchRecord(...) || []).map(function(res){
return { id:res.getId(), vendorName: res.getValue('entityid', 'vendor')...};
});
response.setContentType('JAVASCRIPT');
response.write(JSON.stringify(results));
Actually there's generally a little more. I have a sublime text snippet that I use for suitelet responses that handles a couple of common JSONP patterns (e.g. if you were calling this from a website):
function _sendJSResponse(request, response, respObject){
response.setContentType('JAVASCRIPT');
var callbackFcn = request.getParameter("jsoncallback") || request.getParameter('callback');
if(callbackFcn){
response.writeLine( callbackFcn + "(" + JSON.stringify(respObject) + ");");
}else response.writeLine( JSON.stringify(respObject) );
}
Below is code I came up with to run a Saved Search in NetSuite using SuiteScript, create a CSV with the Saved Search results and then email the CSV. The trouble is, the results are limited to 1000 records. I've researched this issue and it appears the solution is to run a loop that slices in increments of 1000. A sample of what I believe is used to slice searches is also below.
However, I cannot seem to be able to incorporate the slicing into my code. Can anyone help me combine the slicing code with my original search code?
var search = nlapiSearchRecord('item', 'customsearch219729');
// Creating some array's that will be populated from the saved search results
var content = new Array();
var cells = new Array();
var temp = new Array();
var x = 0;
// Looping through the search Results
for (var i = 0; i < search.length; i++) {
var resultSet = search[i];
// Returns an array of column internal Ids
var columns = resultSet.getAllColumns();
// Looping through each column and assign it to the temp array
for (var y = 0; y <= columns.length; y++) {
temp[y] = resultSet.getValue(columns[y]);
}
// Taking the content of the temp array and assigning it to the Content Array.
content[x] += temp;
// Incrementing the index of the content array
x++;
}
//Inserting headers
content.splice(0, 0, "sku,qty,");
// Creating a string variable that will be used as the CSV Content
var contents;
// Looping through the content array and assigning it to the contents string variable.
for (var z = 0; z < content.length; z++) {
contents += content[z].replace('undefined', '') + '\n';
}
// Creating a csv file and passing the contents string variable.
var file = nlapiCreateFile('InventoryUpdate.csv', 'CSV', contents.replace('undefined', ''));
// Emailing the script.
function SendSSEmail()
{
nlapiSendEmail(768, 5, 'Inventory Update', 'Sending saved search via scheduled script', 'cc#email.com', null, null, file, true, null, 'cc#email.com');
}
The following code is an example of what I found that is used to return more than a 1000 records. Again, as a novice, I can't seem to incorporate the slicing into my original, functioning SuiteScript. Any help is of course greatly appreciated.
var filters = [...];
var columns = [...];
var results = [];
var savedsearch = nlapiCreateSearch( 'customrecord_mybigfatlist', filters, columns );
var resultset = savedsearch.runSearch();
var searchid = 0;
do {
var resultslice = resultset.getResults( searchid, searchid+1000 );
for (var rs in resultslice) {
results.push( resultslice[rs] );
searchid++;
}
} while (resultslice.length >= 1000);
return results;
Try out this one :
function returnCSVFile(){
function escapeCSV(val){
if(!val) return '';
if(!(/[",\s]/).test(val)) return val;
val = val.replace(/"/g, '""');
return '"'+ val + '"';
}
function makeHeader(firstLine){
var cols = firstLine.getAllColumns();
var hdr = [];
cols.forEach(function(c){
var lbl = c.getLabel(); // column must have a custom label to be included.
if(lbl){
hdr.push(escapeCSV(lbl));
}
});
return hdr.join(",");
}
function makeLine(srchRow){
var cols = srchRow.getAllColumns();
var line = [];
cols.forEach(function(c){
if(c.getLabel()){
line.push(escapeCSV(srchRow.getText(c) || srchRow.getValue(c)));
}
});
return line.join(",");
}
function getDLFileName(prefix){
function pad(v){ if(v >= 10) return v; return "0"+v;}
var now = new Date();
return prefix + '-'+ now.getFullYear() + pad(now.getMonth()+1)+ pad(now.getDate()) + pad( now.getHours()) +pad(now.getMinutes()) + ".csv";
}
var srchRows = getItems('item', 'customsearch219729'); //function that returns your saved search results
if(!srchRows) throw nlapiCreateError("SRCH_RESULT", "No results from search");
var fileLines = [makeHeader(srchRows[0])];
srchRows.forEach(function(soLine){
fileLines.push(makeLine(soLine));
});
var file = nlapiCreateFile('InventoryUpdate.csv', 'CSV', fileLines.join('\r\n'));
nlapiSendEmail(768, 5, 'Test csv Mail','csv', null, null, null, file);
}
function getItems(recordType, searchId) {
var savedSearch = nlapiLoadSearch(recordType, searchId);
var resultset = savedSearch.runSearch();
var returnSearchResults = [];
var searchid = 0;
do {
var resultslice = resultset.getResults(searchid, searchid + 1000);
for ( var rs in resultslice) {
returnSearchResults.push(resultslice[rs]);
searchid++;
}
} while (resultslice.length >= 1000);
return returnSearchResults;
}
I looked into your code but it seems you're missing the label headers in the generated CSV file. If you are bound to use your existing code then just replace
var search = nlapiSearchRecord('item', 'customsearch219729');
with
var search = getItems('item', 'customsearch219729');
and just use the mentioned helper function to get rid off the 1000 result limit.
Cheers!
I appreciate it has been a while since this was posted and replied to but for others looking for a more generic response to the original question the following code should suffice:
var search = nlapiLoadSearch('record_type', 'savedsearch_id');
var searchresults = search.runSearch();
var resultIndex = 0;
var resultStep = 1000;
var resultSet;
do {
resultSet = searchresults.getResults(resultIndex, resultIndex + resultStep); // retrieves all possible results up to the 1000 max returned
resultIndex = resultIndex + resultStep; // increment the starting point for the next batch of records
for(var i = 0; !!resultSet && i < resultSet.length; i++){ // loop through the search results
// Your code goes here to work on a the current resultSet (upto 1000 records per pass)
}
} while (resultSet.length > 0)
Also worth mentioning, if your code is going to be updating fields / records / creating records you need to bear in mind script governance.
Moving your code to a scheduled script to process large volumes of records is more efficient and allows you to handle governance.
The following line:
var savedsearch = nlapiCreateSearch( 'customrecord_mybigfatlist', filters, columns );
can be adapted to your own saved search like this:
var savedsearch = nlapiLoadSearch('item', 'customsearch219729');
Hope this helps.
I've got this code, which takes a part of the title to perform a query and filter part of the content of a list:
<script type="text/javascript">
var items_lista;
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', Initialize);
function Initialize() {
var PDP_Link_Filter = $("title").text().split("-")[1].split(".")[0];
PDP_Link_Filter = "Link_" + PDP_Link_Filter + "_";
var contexto = SP.ClientContext.get_current();
var web = contexto.get_web();
var listas = web.get_lists();
var parametros = listas.getByTitle('Parametrizacion_WF');
var query = new SP.CamlQuery();
query.set_viewXml("<Query><Where><Contains><FieldRef Name='Title'/>" +
"<Value Type='Text'>" + PDP_Link_Filter + "</Value></Contains></Where></Query>");
console.log(query);
items_lista = parametros.getItems(query);
contexto.load(items_lista);
contexto.executeQueryAsync(Function.createDelegate(this, this.onRequestSucceeded), Function.createDelegate(this, this.onRequestFailed));
} //Initialize
function onRequestSucceeded()
{
console.log(items_lista);
for(i = 0; i < items_lista.get_count(); i++)
{
console.log(items_lista.get_item(i).get_item('Title'));
}
}
function onRequestFailed() { console.log('Error'); }
</script>
The query filter that it generates (obtained through console.log()):
<Query><Where><Contains><FieldRef Name='Title'/><Value Type='Text'>P000</Value></Contains></Where></Query>
But when the for loop runs it shows all the content of the list not just the rows that match the filter.
What am I doing wrong?
This is most probably related with malformed value for SP.CamlQuery.viewXml property. Since this property expects XML schema that defines the list view, the root element has to be View element, for example:
var ctx = SP.ClientContext.get_current();
var list = ctx.get_web().get_lists().getByTitle(listTitle);
var items = list.getItems('<View Scope="RecursiveAll"><Query></Query></View>');
In your case enclose the query with View element:
<View>
<Query>...</Query>
</View>
I need to offer a feature which allows InDesign users to select a page range in an InDesign document and create a new document out of those pages. This sounds simple, but it isn't...
I have tried many different ways of doing this but they have all failed to some degree. Some methods put all pages in a single spread (which sometimes makes InDesign crash). The best I've been able to do (see code below) still has problems at the beginning and the end (see screenshots below):
The original document:
The new document:
The question: How can I create a new document out of a subset of another document's pages (in InDesign using ExtendScript) without having the problems shown in the screenshots?
note: The behavior of the script is quite different in CS5.5 and CS6. My question concerns CS6.
The second screenshot was obtained by applying the following code to the document shown in the first screenshot:
CODE
var firstPageName = { editContents: "117" }; // This page number is actually entered by the user in an integerEditbox
var lastPageName = { editContents: "136" }; // This page number is actually entered by the user in an integerEditbox
var sourceDocument = app.activeDocument;
var destDocument = app.documents.add();
destDocument.importStyles(ImportFormat.paragraphStylesFormat, new File(sourceDocument.filePath + "/" + sourceDocument.name), GlobalClashResolutionStrategy.LOAD_ALL_WITH_OVERWRITE);
destDocument.importStyles(ImportFormat.characterStylesFormat, new File(sourceDocument.filePath + "/" + sourceDocument.name), GlobalClashResolutionStrategy.LOAD_ALL_WITH_OVERWRITE);
destDocument.viewPreferences.horizontalMeasurementUnits = sourceDocument.viewPreferences.horizontalMeasurementUnits;
destDocument.viewPreferences.verticalMeasurementUnits = sourceDocument.viewPreferences.verticalMeasurementUnits;
destDocument.documentPreferences.facingPages = sourceDocument.documentPreferences.facingPages;
destDocument.documentPreferences.pageHeight = sourceDocument.documentPreferences.pageHeight;
destDocument.documentPreferences.pageWidth = sourceDocument.documentPreferences.pageWidth;
destDocument.documentPreferences.pageSize = sourceDocument.documentPreferences.pageSize;
var sourceSpreads = sourceDocument.spreads;
var nbSourceSpreads = sourceSpreads.length;
var firstPageFound = false;
var lastPageFound = false;
var i;
var newSpreadNeeded;
var currentDestSpread;
for (i = 0; !lastPageFound, i < nbSourceSpreads; ++i) {
newSpreadNeeded = true;
var sourcePages = sourceSpreads[i].pages;
var nbSourcePages = sourcePages.length;
var j;
for (j = 0; !lastPageFound, j < nbSourcePages; ++j) {
if (sourcePages[j].name === firstPageName.editContents) {
firstPageFound = true;
destDocument.documentPreferences.startPageNumber = parseInt(firstPageName.editContents); // We want to preserve page numbers
}
if (firstPageFound) {
// Copy this page over to the new document.
var firstInNewSpread = false;
if (newSpreadNeeded) {
currentDestSpread = destDocument.spreads.add();
newSpreadNeeded = false;
firstInNewSpread = true;
}
var newPage = sourcePages[j].duplicate(LocationOptions.AT_END, currentDestSpread);
var k;
for (k = 0; k < newPage.index; ++k) {
currentDestSpread.pages[k].remove();
}
}
if (sourcePages[j].name === lastPageName.editContents) {
lastPageFound = true;
}
}
}
destDocument.spreads[0].remove();
I was hacking around and came up with this little script. Although it approaches the problem from the opposite direction, it seems to work fine here. Also, I'm still running in InDesign CS5, but maybe it will work for you. Hopefully I got the gist of your question?
This will extract pages 3 through 5 into a separate document:
var doc = app.activeDocument;
var newFilePath = doc.filePath + "/subset_" + doc.name;
var newFile = File(newFilePath); // Create a new file path
doc.saveACopy(newFile); // Save a copy of the doc
var newDoc = app.open(newFile); // Open the copy
var firstPageNum = 3; // First page number in the range
var lastPageNum = 5; // Last page number in the range
var firstPage = newDoc.pages[firstPageNum-1];
var lastPage = newDoc.pages[lastPageNum-1];
// Remove all text from the last page in the range to the end of the document
var lastPageFrames = lastPage.textFrames.everyItem().getElements();
for (var i=0; i < lastPageFrames.length; i++) {
var frame = lastPageFrames[i];
var parentStory = frame.parentStory;
var lastFrameInsert = frame.insertionPoints.lastItem();
var lastStoryInsert = parentStory.insertionPoints.lastItem();
var textAfter = parentStory.insertionPoints.itemByRange(lastFrameInsert,lastStoryInsert);
textAfter.remove();
};
// Remove all text from the beginning of the document to the first page in the range
var firstPageFrames = firstPage.textFrames.everyItem().getElements();
for (var i=0; i < firstPageFrames.length; i++) {
var frame = firstPageFrames[i];
var parentStory = frame.parentStory;
var firstFrameInsert = frame.insertionPoints.firstItem();
var textBefore = parentStory.insertionPoints.itemByRange(0,firstFrameInsert.index);
textBefore.remove();
};
// Remove the pages that aren't in the range
var allPages = newDoc.pages.everyItem().getElements();
for (var i=0; i < allPages.length; i++) {
var page = allPages[i];
if (i < firstPageNum || i > lastPageNum) {
page.remove();
}
};