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 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
i am trying to load docx file into variable, display it and then do the parsing to export the necessary. Currently i found only one way to do it - via ActiveX which is however supported only on IE, and also unluckily another manipulation like match or contains of regex is thus not supported in IE so I am in a dead way now. Are there any other options to do this? I tried replace, split etc but nothing is working in IE and now i dont know if I should leave the IE activeX and find another way to read docx or find something different from matches or contains to be used in IE
This is my code for now, working as well just in IE11:
//LOAD FWRC
function loadworddoc(){
let doc = new ActiveXObject("Word.Application"); // creates the word object
let inputDoc = document.getElementById("inputFWRC").value;
doc.Visible=false; // doesn't display Word window
doc.Documents.Open(inputDoc); // specify path to document
var forma; //copy the content from my word document and throw it into my variable
forma = doc.Documents(inputDoc).Content;
document.all.myarea.value = forma;
doc.quit(0); // quit word (very important or you'll quickly chew up memory!)
let regex = /tcp-\d{1,5}|TCP-\d{1,5}|udp-\d{1,5}|UDP-\d{1,5}|ICMP|icmp|SSH|ssh|HTTPS|https/;
/*let parsedPorts = forma.replace(regex, parsedPorts);
if (forma.match(regex)) {
forma = forma.replace(regex, "$1" + "1" + "$2");
}*/
console.log(forma);
//console.log(parsedPorts);
}
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.
For example, assuming that x = filename.jpg, I want to get filename, where filename could be any file name (Let's assume the file name only contains [a-zA-Z0-9-_] to simplify.).
I saw x.substring(0, x.indexOf('.jpg')) on DZone Snippets, but wouldn't x.substring(0, x.length-4) perform better? Because, length is a property and doesn't do character checking whereas indexOf() is a function and does character checking.
Not sure what would perform faster but this would be more reliable when it comes to extension like .jpeg or .html
x.replace(/\.[^/.]+$/, "")
In node.js, the name of the file without the extension can be obtained as follows.
const path = require('path');
const filename = 'hello.html';
path.parse(filename).name; //=> "hello"
path.parse(filename).ext; //=> ".html"
path.parse(filename).base; //=> "hello.html"
Further explanation at Node.js documentation page.
If you know the length of the extension, you can use x.slice(0, -4) (where 4 is the three characters of the extension and the dot).
If you don't know the length #John Hartsock regex would be the right approach.
If you'd rather not use regular expressions, you can try this (less performant):
filename.split('.').slice(0, -1).join('.')
Note that it will fail on files without extension.
x.length-4 only accounts for extensions of 3 characters. What if you have filename.jpegor filename.pl?
EDIT:
To answer... sure, if you always have an extension of .jpg, x.length-4 would work just fine.
However, if you don't know the length of your extension, any of a number of solutions are better/more robust.
x = x.replace(/\..+$/, '');
OR
x = x.substring(0, x.lastIndexOf('.'));
OR
x = x.replace(/(.*)\.(.*?)$/, "$1");
OR (with the assumption filename only has one dot)
parts = x.match(/[^\.]+/);
x = parts[0];
OR (also with only one dot)
parts = x.split(".");
x = parts[0];
I like this one because it is a one liner which isn't too hard to read:
filename.substring(0, filename.lastIndexOf('.')) || filename
You can perhaps use the assumption that the last dot will be the extension delimiter.
var x = 'filename.jpg';
var f = x.substr(0, x.lastIndexOf('.'));
If file has no extension, it will return empty string. To fix that use this function
function removeExtension(filename){
var lastDotPosition = filename.lastIndexOf(".");
if (lastDotPosition === -1) return filename;
else return filename.substr(0, lastDotPosition);
}
In Node.js versions prior to 0.12.x:
path.basename(filename, path.extname(filename))
Of course this also works in 0.12.x and later.
I don't know if it's a valid option but I use this:
name = filename.split(".");
// trimming with pop()
name.pop();
// getting the name with join()
name.join('.'); // we split by '.' and we join by '.' to restore other eventual points.
It's not just one operation I know, but at least it should always work!
UPDATE: If you want a oneliner, here you are:
(name.split('.').slice(0, -1)).join('.')
This works, even when the delimiter is not present in the string.
String.prototype.beforeLastIndex = function (delimiter) {
return this.split(delimiter).slice(0,-1).join(delimiter) || this + ""
}
"image".beforeLastIndex(".") // "image"
"image.jpeg".beforeLastIndex(".") // "image"
"image.second.jpeg".beforeLastIndex(".") // "image.second"
"image.second.third.jpeg".beforeLastIndex(".") // "image.second.third"
Can also be used as a one-liner like this:
var filename = "this.is.a.filename.txt";
console.log(filename.split(".").slice(0,-1).join(".") || filename + "");
EDIT: This is a more efficient solution:
String.prototype.beforeLastIndex = function (delimiter) {
return this.substr(0,this.lastIndexOf(delimiter)) || this + ""
}
Another one-liner:
x.split(".").slice(0, -1).join(".")
Here's another regex-based solution:
filename.replace(/\.[^.$]+$/, '');
This should only chop off the last segment.
Simple one:
var n = str.lastIndexOf(".");
return n > -1 ? str.substr(0, n) : str;
The accepted answer strips the last extension part only (.jpeg), which might be a good choice in most cases.
I once had to strip all extensions (.tar.gz) and the file names were restricted to not contain dots (so 2015-01-01.backup.tar would not be a problem):
var name = "2015-01-01_backup.tar.gz";
name.replace(/(\.[^/.]+)+$/, "");
var fileName = "something.extension";
fileName.slice(0, -path.extname(fileName).length) // === "something"
If you have to process a variable that contains the complete path (ex.: thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg") and you want to return just "filename" you can use:
theName = thePath.split("/").slice(-1).join().split(".").shift();
the result will be theName == "filename";
To try it write the following command into the console window of your chrome debugger:
window.location.pathname.split("/").slice(-1).join().split(".").shift()
If you have to process just the file name and its extension (ex.: theNameWithExt = "filename.jpg"):
theName = theNameWithExt.split(".").shift();
the result will be theName == "filename", the same as above;
Notes:
The first one is a little bit slower cause performes more
operations; but works in both cases, in other words it can extract
the file name without extension from a given string that contains a path or a file name with ex. While the second works only if the given variable contains a filename with ext like filename.ext but is a little bit quicker.
Both solutions work for both local and server files;
But I can't say nothing about neither performances comparison with other answers nor for browser or OS compatibility.
working snippet 1: the complete path
var thePath = "http://stackoverflow.com/directory/subdirectory/filename.jpg";
theName = thePath.split("/").slice(-1).join().split(".").shift();
alert(theName);
working snippet 2: the file name with extension
var theNameWithExt = "filename.jpg";
theName = theNameWithExt.split("/").slice(-1).join().split(".").shift();
alert(theName);
working snippet 2: the file name with double extension
var theNameWithExt = "filename.tar.gz";
theName = theNameWithExt.split("/").slice(-1).join().split(".").shift();
alert(theName);
Node.js remove extension from full path keeping directory
https://stackoverflow.com/a/31615711/895245 for example did path/hello.html -> hello, but if you want path/hello.html -> path/hello, you can use this:
#!/usr/bin/env node
const path = require('path');
const filename = 'path/hello.html';
const filename_parsed = path.parse(filename);
console.log(path.join(filename_parsed.dir, filename_parsed.name));
outputs directory as well:
path/hello
https://stackoverflow.com/a/36099196/895245 also achieves this, but I find this approach a bit more semantically pleasing.
Tested in Node.js v10.15.2.
Though it's pretty late, I will add another approach to get the filename without extension using plain old JS-
path.replace(path.substr(path.lastIndexOf('.')), '')
A straightforward answer, if you are using Node.js, is the one in the first comment.
My task was I need to delete an image in Cloudinary from the Node server and I just need to get the image name only.
Example:
const path = require("path")
const image=xyz.jpg;
const img= path.parse(image).name
console.log(img) // xyz
This is where regular expressions come in handy! Javascript's .replace() method will take a regular expression, and you can utilize that to accomplish what you want:
// assuming var x = filename.jpg or some extension
x = x.replace(/(.*)\.[^.]+$/, "$1");
You can use path to maneuver.
var MYPATH = '/User/HELLO/WORLD/FILENAME.js';
var MYEXT = '.js';
var fileName = path.basename(MYPATH, MYEXT);
var filePath = path.dirname(MYPATH) + '/' + fileName;
Output
> filePath
'/User/HELLO/WORLD/FILENAME'
> fileName
'FILENAME'
> MYPATH
'/User/HELLO/WORLD/FILENAME.js'
This is the code I use to remove the extension from a filename, without using either regex or indexOf (indexOf is not supported in IE8). It assumes that the extension is any text after the last '.' character.
It works for:
files without an extension: "myletter"
files with '.' in the name: "my.letter.txt"
unknown length of file extension: "my.letter.html"
Here's the code:
var filename = "my.letter.txt" // some filename
var substrings = filename.split('.'); // split the string at '.'
if (substrings.length == 1)
{
return filename; // there was no file extension, file was something like 'myfile'
}
else
{
var ext = substrings.pop(); // remove the last element
var name = substrings.join(""); // rejoin the remaining elements without separator
name = ([name, ext]).join("."); // readd the extension
return name;
}
I like to use the regex to do that. It's short and easy to understand.
for (const regexPattern of [
/\..+$/, // Find the first dot and all the content after it.
/\.[^/.]+$/ // Get the last dot and all the content after it.
]) {
console.log("myFont.ttf".replace(regexPattern, ""))
console.log("myFont.ttf.log".replace(regexPattern, ""))
}
/* output
myFont
myFont
myFont
myFont.ttf
*/
The above explanation may not be very rigorous. If you want to get a more accurate explanation can go to regex101 to check
\..+$
\.[^/.]+$
We might come across filename or file path with multiple extension suffix. Consider the following to trim them.
text = "/dir/path/filename.tar.gz"
output = text.replace(/(\.\w+)+$/,"")
result of output: "/dir/path/filename"
It solves the file extension problem especially when the input has multiple extensions.
Another one liner - we presume our file is a jpg picture >> ex: var yourStr = 'test.jpg';
yourStr = yourStr.slice(0, -4); // 'test'
x.slice(0, -(x.split('.').pop().length + 1));
name.split('.').slice(0, -1).join('.')
that's all enjoy your coding...
I would use something like x.substring(0, x.lastIndexOf('.')). If you're going for performance, don't go for javascript at all :-p No, one more statement really doesn't matter for 99.99999% of all purposes.