Pentaho Spoon: JavaScript split is only putting one element in array - javascript

I have strings in the following format in Pentaho Spoon:
"0.31;0.45"
Now I want these to split in Javascript
var str = "0.31;0.45"
var res1 = str.split(";");
However, this returns an array where only the first element is filled as
res1[0] = "0.310.45"
While I'm expecting this:
res1[0] = "0.31"
res1[1] = "0.45"
What am I doing wrong? I've been looking for quite some time now but didn't discover any solution.
The string has been sanitized before, because it was imported from an excel sheet where enters were added between the different values:
str = strold.replace(new RegExp("\n", "gi"), ";");
Snippet of the excel sheet data can be found here (can't disclose complete records due to the sensitive nature of the data):
Exceldata
Any pointers on the right track will be greatly appreciated :)
Thanks!
Rob

If you want to do this in a Modified JavaScript step, this should word fine:
After Excel-Input of the field test1 with value "0.31;0.45" (as string) your JS-Code should look like this:
var str = test1;
var split = str.split(";");
var res1 = split[0];
var res2 = split[1];
The new fields res1 and res2 now show the splitted values. I think your problem was a missing second variable here like split in my code above, maybe a kettle-specific thing...
As a second possible way to solve this without a JavaScript-Step use the Split-Fields-step:
After Excel input set the step Split-Fields. Here set the field to split (in my testscenario test1), set the delimiter (;) and define the two new fields.
Hope it works!

Related

Searching a string

OK Ive been able to get the following to partially work
var Global_Wound_array =[{"WoundNumber":1,"BodySide":"Front","BodyPart":"Nose"},{"WoundNumber":2,"BodySide":"Left","BodyPart":"Head"},{"WoundNumber":3,"BodySide":"Back","BodyPart":"Ear"}]
var Global_Wound_Counter = 1
I can get the page to loop through and display the individual wounds but I need a way to say at a particular page one of the values eg on WoundNumber 2 BodyPart has changed and updated the string without affecting the rest of it.
page9200.setEventHandler("pageFinishing", function () {
//getSelectedButtonLabel this is ok - specific on the system
let Q1 = Q3_WoundNumber.getValue();
let Q2 = Q1_BodySide.getSelectedButtonLabel();
let Q3 = Q2_BodyPart.getSelectedButtonLabel();
for (var i = 0; i < Global_Wound_array.length; i++) {
if (i+1 == Q1){
//create new temp variable array
var Temp_Wound_obj2 = {"WoundNumber": Q1,"BodySide": Q2,"BodyPart":Q3}
Global_Wound_array.push(Temp_Wound_obj2)
}
}
});
As well as being able to reach the end of the string to present a blank set of values to have the option to add a new wound.
Every time I think Ive got something that looks like it would work I go around in circles, when I try to update the system at the end I get and error that the - invaid parameters for RPC call: variable is bad
It seems you are pasting JSON onto JSON, with no separator. This creates a messy and non-standard data structure. If you wrote your JSON with a newline at the end, you would end up with a JSONL file, which is very simple to process.
const jsonl = `
[{"WCount":1,"Side":"Centre","Part":"Ocipit","Type":"Other","SurroundingSkin":"Dermatitis","Height":"","Width":"","Depth":""}]
[{"WCount":2,"Side":"Front","Part":"Neck","Type":"Diabetic foot wound","SurroundingSkin":"Healthy/intact","Height":"3","Width":"4","Depth":"5"}]
`;
const jsonItems = jsonl.trim().split("\n");
const lastJsonItem = jsonItems[jsonItems.length - 1];
const lastItem = JSON.parse(lastJsonItem);
const lastWCount = lastItem[0].WCount;
console.log(lastWCount);
If you already have a file without newlines... it would be best to insert them, and correct your data to JSONL. This is simple in your case just by replacing ][ with ]\n[ (and making sure the file ends with a newline too, so the next write would not be messed up), since you have no nesting and (hopefully) no ][ in your text, but in general it is not easy - I don't know of a JSON parser that will return unconsumed text, so it would probably involve writing a JSON parser. Much easier to write data correctly in the first place.

I used js to create my command syntax, now how can I use it?

I have a Google Sheet with .gs script that is successfully generating dynamicnewRichTextValue() parameters which are meant to be injected into a Sheet cell that will contain multiple lines of text each with their own URL. I do not know all of the parameters in advance (might be one text and one link, or two each, or more) which is why I am dynamically generating the parameters.
Let's say the end-state should be this (in this case there are only two line items, but there could be more or less:
var RichTextValue=SpreadsheetApp.newRichTextValue()
.setText("mailto:fred#abcdef.com,mailto:jim#abcdef.com")
.setLinkUrl(0,6,"mailto:fred#abcdef.com")
.setLinkUrl(7,19,"mailto:jim#abcdef.com")
.build();
In my script I don't know how many "setText" parameters or "setLinkUrl" statements I will need to generate, so I am doing it dynamically.
This is simple to handle for "setText" because I can just pass a single variable constructed during an earlier loop that builds the "setText" parameters. Let's call that variable setTextContent, and it works like this:
var RichTextValue=SpreadsheetApp.newRichTextValue()
.setText(setTextContent)
So up to this point, everything is great. The problem is that I have another variable that generates the URL portion of the newrichtextvalue() parameters up to the ".build();" statement. So let's call that variable setUrlContent and it is built in an earlier loop and contains the string for the rest of the statement:
.setLinkURL(0,22,"mailto:fred#abcdef.com").setLinkURL(23,44,"mailto:jim#abcdef.com")
I am stumped trying to figure out how to attach it to the earlier bit. I feel like this is something simple I am forgetting. But I can't find it after much research. How do I hook up setUrlContent to the code above so that the command executes? I want to attach the bits above and get back to assigning it all to a variable I can put into a cell:
var emailCell=SpreadsheetApp.newRichTextValue()
.setText("mailto:fred#abcdef.com,mailto:jim#abcdef.com") // I can dynamically create up to here
.setLinkUrl(0,6,"mailto:fred#abcdef.com") // ...but these last couple lines are
.setLinkUrl(7,19,"mailto:jim#abcdef.com") // stuck in a string variable.
.build();
sheet.getRange(1,1,1,1).setRichTextValue(emailCell)
Thanks!
I believe your goal and situation as follows.
You want to use your script by dynamically changing the number of emails.
Modification points:
When your following script is run, I think that the links are reflected to mailto and fred#abcdef..
var emailCell=SpreadsheetApp.newRichTextValue()
.setText("mailto:fred#abcdef.com,mailto:jim#abcdef.com")
.setLinkUrl(0,6,"mailto:fred#abcdef.com")
.setLinkUrl(7,19,"mailto:jim#abcdef.com")
.build();
sheet.getRange(1,1,1,1).setRichTextValue(emailCell)
I thought that you might have wanted the linked email addresses like below.
fred#abcdef.com has the link of mailto:fred#abcdef.com.
jim#abcdef.com has the link of mailto:jim#abcdef.com.
In this answer, I would like to propose the modified script for above direction.
Modified script:
var inputText = "mailto:fred#abcdef.com,mailto:jim#abcdef.com"; // This is your sample text value.
var ar = inputText.split(",").map(e => {
var v = e.trim();
return [v.split(":")[1], v];
});
var text = ar.map(([e]) => e).join(",");
var emailCell = SpreadsheetApp.newRichTextValue().setText(text);
var start = 0;
ar.forEach(([t, u], i) => {
var len = t.length;
emailCell.setLinkUrl(start, start + len, u);
start += len + 1;
});
SpreadsheetApp.getActiveSheet().getRange(1,1,1,1).setRichTextValue(emailCell.build());
In this modification, inputText is splitted to the hyperlink and the text (for example, when your sample value is used, it's fred#abcdef.com and mailto:fred#abcdef.com.), and the text including the hyperlink are put to the cell.
In this case, for example, even when var inputText = "mailto:fred#abcdef.com,mailto:jim#abcdef.com" is modified to var inputText = "mailto:fred#abcdef.com" and var inputText = "mailto:fred#abcdef.com,mailto:jim#abcdef.com,mailto:sample#abcdef.com", each hyperlink are reflected to each text.
Note:
When you want to the hyperlink of mailto:fred#abcdef.com to the text of mailto:fred#abcdef.com, you can also use the following modified script.
var inputText = "mailto:fred#abcdef.com,mailto:jim#abcdef.com"; // This is your sample text value.
var ar = inputText.split(",").map(e => e.trim());
var emailCell = SpreadsheetApp.newRichTextValue().setText(inputText);
var start = 0;
ar.forEach((t, i) => {
var len = t.length;
emailCell.setLinkUrl(start, start + len, t);
start += len + 1;
});
SpreadsheetApp.getActiveSheet().getRange(1,1,1,1).setRichTextValue(emailCell.build());
References:
newRichTextValue()
Class RichTextValueBuilder
Class RichTextValue

How to replace 'special' characters in a string of code with an expanded piece of that same code?

I'm creating a chrome extension that basically finds a string of text such as this (note the different numbers):
id%22%3A99986%2C%22name%22%3A%22null%22%7D%2C%7B%22id%22%3A1002938%2C%22name%22%3A%22null%22%7D%2C%7B%22
and then usese javascript to swap that text above with this:
id%22%3A77764%2C%22name%22%3A%22null%22%7D%2C%7B%22id%22%3A77984%2C%22name%22%3A%22null%22%7D%2C%7B%22id%22%3A87746%2C%22name%22%3A%22null%22%7D%2C%7B%22
I can't manage to make this work whatsoever. All I'm able to do is swap out the ID numbers and replace individual parts of the code whereas I want to improve it by replacing with larger pieces of code. Can someone help me get past this because I'm confused.
Here is the code that works for me:
document.body.innerHTML = document.body.innerHTML.replace(/99986/g, '77764');
What I'm trying to do is to replace one piece of code with two pieces of code (obviously wrong but it's clear what I'm trying to do):
document.body.innerHTML = document.body.innerHTML.replace(/id%22%3A99986%2C%22name%22%3A%22null%22%7D%2C%7B%22/g, 'id%22%3A77764%2C%22name%22%3A%22null%22%7D%2C%7B%22id%22%3A77984%2C%22name%22%3A%22null%22%7D%2C%7B%22');
Update 1:
Thank you Emeeus, your code worked great! Unfortunately I made an error in my example so I had to fix it up a bit from my end. This is the new code using your layout:
var strA =
"%7Bid%22%3A1001%2C%22name%22%3A%22The+Antique+Store%22%7D%2C%7B%22id%22%3A1010%2C%22name%22%3A%22Clothes%22%7D%2C%7B%22id%22%3A1349%2C%22name%22%3A%22Old+Store%22%7D";
var strB = "%7Bid%22%3A1001%2C%22name%22%3A%22The+Modern+Store%22%7D%2C%7B%22id%22%3A1010%2C%22name%22%3A%22Clothes%22%7D%2C%7B%22id%22%3A1349%2C%22name%22%3A%22New+Store%22%7D";
var arrA = JSON.parse(decodeURIComponent(',{""' + strA + '",:""}'));
var arrB = JSON.parse(decodeURIComponent(',{""' + strB + '",:""}'));
console.log(arrA)
console.log(arrB)
var res = Object.assign(arrA, arrB);
console.log(encodeURIComponent(JSON.stringify(res)))
But I'm met with this error "Error: Unexpected token , in JSON at position 0". Any ideas?
I think you should check if the typeof string you are trying to replace is string. I tested, check if that solves your problem.
See screenshot:
Your strings are parts of a JSON URI-encoded, so I suggest first to decode the strings an then parse them using JSON.parse, then you could work with objects literals, which is easier most of times, here an example:
var strA = "id%22%3A99986%2C%22name%22%3A%22null%22%7D%2C%7B%22id%22%3A1002938%2C%22name%22%3A%22null%22%7D%2C%7B%22";
var strB = "id%22%3A77764%2C%22name%22%3A%22null%22%7D%2C%7B%22id%22%3A77984%2C%22name%22%3A%22null%22%7D%2C%7B%22id%22%3A87746%2C%22name%22%3A%22null%22%7D%2C%7B%22";
var arrA = JSON.parse(decodeURIComponent('[{"' + strA + '":""}]'));
var arrB = JSON.parse(decodeURIComponent('[{"' + strB + '":""}]'));
console.log(arrA)
console.log(arrB)
var res = Object.assign(arrA, arrB);//<-- example
console.log(encodeURIComponent(JSON.stringify(res)))//<-- you could encode the result again

Need to get an array of the names of all applicationScope variables

In an application I am working on I need to get a list of the names of all applicationScope variable then I need to cycle through them and filter out the ones starting with a know string say $xyx. I thought that the applicationScope.keySet().
I'm using this code for starter:
var col = applicationScope.keySet();
var itr:java.util.Iterator = col.iterator();
if (itr.hasNext()){
var str:String = itr.next();
dBar.info(str,"Value = ");
}
if I put the variable col in a viewScope it shows a list of all the keys. but when I run the script the values displayed in the dBar info are not the keys but some other information that I'm not sure where it comes from.
I should just be able to iterat through the list of keys, am I missing something?
This code is in the before page loads event
After some poking around and experimenting I got this to work:
var col = applicationScope.keySet();
var itr:java.util.Iterator = col.iterator();
while (itr.hasNext()){
var str:Map.Entry = itr.next();
if (str.substring(0,9) == "$wfsLock_"){
//do stuff
}
}
so I'm now a happy camper.
Although your code works in SSJS, it is not correct (and that's why I don't like SSJS...).
The applicationScope is an implementation of the java.util.Map interface and the keySet() method returns a Set containing the keys in that Map. Every entry is (probably) a String (other data types like integers are actually also valid). The line
var str:Map.Entry = itr.next();
doesn't cast it to a Map.Entry: it doesn't really do anything: str remains a string.
The Map interface also has an entrySet() method that returns the entries (Map.Entry). You can use that to retrieve the key as well as the value:
var it = applicationScope.entrySet().iterator();
while (it.hasNext()) {
var entry = it.next();
print( entry.getKey() + " = " + entry.getValue() );
}
(in this code the print() line will use the toString() method of the key as well as the value to send information to the console)
I see from your code that you've installed my XPages Debug Toolbar. You can also use that to quickly check what's in the scopes and what the actual datatype is.

Extract word from Url

I have a search function, and would like to display the search term in the search input.
My url is: search-1.html?keyword=XXXXXX
How do I get this, and display it in an input?
Thank you in advance.
Use this:
http://ajaxcssblog.com/jquery/url-read-get-variables/
Take luck!
Oh and then you can use the following to display its value in an input field:
$("#inputId").val($.url.param("keyword"));
If it is just one key=value in the url you can use simple regex like this:
var theValueYouWant = window.location.href.match(/keyword=(.+)/)[1]
And set the value of an input like this
$('input').val(theValueYouWant)
If you want to parse the GET string more thoroughly, this function should do it...
gets = {};
$.each(location.search.replace(/^\?/,'').split('&'),function(k,v){
bits = v.split('=');
gets[bits[0]] = bits[1];
});
Regex solution:
var S = window.location.search; // "?keyword=..." etc.
var T = S.match(/^\?(?:[^\b]*&+)?keyword=([^&]*)/);
if (T)
T = T[1]
else
T = "no keywords found"
If multiple values are given for "keyword" (e.x. ?keyword=XXX&keyword=YYY), the regex will only find the first of these values (e.x. XXX). This regex works even if there are other variables in the query string.
jQuery-less solution:
<script type="text/javascript">
var $_GET=[],pairs=location.href.toString().substring(location.href.toString().indexOf("?")+1).split("&");for(key in pairs){pos=pairs[key].indexOf("=");$_GET[pairs[key].substring(0,pos)]=decodeURIComponent(pairs[key].substring(pos+1).replace(/\+/g," "))};
// Now just access with $_GET
// example...
keyword = $_GET["keyword"];
</script>

Categories

Resources