Copy link to clipboard
Copied
Hello,
I'm beginner to JavaScript and Acrobat JS api. I'm trying to write a script which makes annotations on phrases instead of single words, and I wanted it to be case insensitive. Therefore logically, I thought of using .toUpperCase() method on both this.getPageNthWord(p, w) and the words searched. To simplify it's use for multiple sentences, every phrases entered are pushed in an array and the annotation function is called for every items in this array.
But the problem is that when I launch the script, the annotation is made only for the first phrase in the array and I get a "TypeError: this.getPageNthWord(p, w) has no properties" in the console.
Here is a basic case which reproduces the exact same problem.
In this example this is only an array of words which is searched for annotations, but as in my case, only the first word is highlighted and we get the same "TypeError: this.getPageNthWord(p, w) has no properties"
function DoHighlight(word)
{
for (var p = 0; p < this.numPages; p++)
{
var cnt = this.getPageNumWords(p);
for (var w = 0; w < cnt; w++)
{
if (this.getPageNthWord(p, w).toUpperCase() == word.toUpperCase())
{
this.addAnnot({
page: p,
type: "Highlight",
strokeColor: color.red,
quads: this.getPageNthWordQuads(p, w),
});
}
}
}
}
var words = ["word1","word2"];
var t = words.forEach(function Highlight(word){ DoHighlight(word) });
I know that there is already actions for phrase & word annotation here https://acrobatusers.com/actions-exchange , but as I'm a beginner I would really like to understand why it only works on the first element, and how I can fix it. And also I would like to create custom actions with this one later.
Any help / explanation would be very appreciated!
It's possible that getPageNthWord is returning null, so you need to check for that.
Change this line:
if (this.getPageNthWord(p, w).toUpperCase() == word.toUpperCase())
To:
if (this.getPageNthWord(p, w)!=null && this.getPageNthWord(p, w).toUpperCase() == word.toUpperCase())
Copy link to clipboard
Copied
This may be a problem that you have:
getPageNumWords
getPageNthWord
Then you have "getPageNthWordQuads"
That you use camel case is not a problem, though I know many that would name a variable with a "myPageNumWords" etc
I would avoid using "get" in a name or anything that would be like code.
Is there other code also? Where do you get your quads from?
Copy link to clipboard
Copied
https://forums.adobe.com/people/Lukas+Engqvist wrote
This may be a problem that you have:
getPageNumWordsgetPageNthWord
Then you have "getPageNthWordQuads"
That you use camel case is not a problem, though I know many that would name a variable with a "myPageNumWords" etc
I would avoid using "get" in a name or anything that would be like code.
Is there other code also? Where do you get your quads from?
This are functions of Adobe Acrobat and Acrobat Reader. This are not variables.
Copy link to clipboard
Copied
@Bernd I must have had my brain on vacation yesterday. I should be more focused when being on the forum.
Sorry for confusing the issue.
Copy link to clipboard
Copied
Before the line:
if (this.getPageNthWord(p, w).toUpperCase() == word.toUpperCase())
add following line:
console.println(" " + p + " " + w + " " + this.getPageNthWord(p, w));
Copy link to clipboard
Copied
Thank you for your help! So after adding this line, it seems that when I'm applying any method (like .toUpperCase() in this example) on getPageNthWord, it stops getting the words after the first page (and of course only 1st page words are highlighted).
But when no methods are applied, all pages word's are returned & highlighted.
So it looks like the script stops working after the first page, it explains why only the first word is highlighted. But I have no idea why applying a method can cause this. I would be really grateful if you could help me understand / fix this
Copy link to clipboard
Copied
I don't think that's the issue. Post your full code, please, and maybe share the file you're running it with us.
Copy link to clipboard
Copied
Thanks again, for now I'm only trying to make this basic example work to implement case insensitive later in other scripts. As said in upper replies, this function works perfectly when I'm not using .toUpperCase(), that's only when I add it that the script stops working after the first page last word is reached. I'm sure that the script stops working because when I add other actions after the loop, like a simple console.println, it is not showing in the console
function DoHighlight(word)
{
for (var p = 0; p < this.numPages; p++)
{
var cnt = this.getPageNumWords(p);
for (var w = 0; w < cnt; w++)
{
if (this.getPageNthWord(p, w).toUpperCase() == word.toUpperCase())
{
this.addAnnot({
page: p,
type: "Highlight",
strokeColor: color.red,
quads: this.getPageNthWordQuads(p, w),
});
}
}
}
}
var words = ["word1","word2"];
var t = words.forEach(function Highlight(word){ DoHighlight(word) });
Copy link to clipboard
Copied
It's possible that getPageNthWord is returning null, so you need to check for that.
Change this line:
if (this.getPageNthWord(p, w).toUpperCase() == word.toUpperCase())
To:
if (this.getPageNthWord(p, w)!=null && this.getPageNthWord(p, w).toUpperCase() == word.toUpperCase())
Copy link to clipboard
Copied
Thank you very much Try! It was exactly the issue: getPageNthWord was returning null but I didn't noticed it.
I just have a last question about what you recommended upper. Why is it better to pass a reference to the document object ? I'm very curious. Also I tried to do it but it is not working :
function DoHighlight(doc,word)
{
for (var p = 0; p < doc.numPages; p++)
{
var cnt = doc.getPageNumWords(p);
for (var w = 0; w < cnt; w++)
{
if (doc.getPageNthWord(p, w)!=null && doc.getPageNthWord(p, w);.toUpperCase() == word.toUpperCase())
{
doc.addAnnot({
page: p,
type: "Highlight",
strokeColor: color.red,
quads: doc.getPageNthWordQuads(p, w),
});
}
}
}
}
var words = ["word1","word2"];
var t = words.forEach(function Annot(word){ DoHighlight(doc,word)});
I don't get any error but words are not Highlighted ? Thanks again
Copy link to clipboard
Copied
Change this line:
var t = words.forEach(function Annot(word){ DoHighlight(doc,word)});
To:
var t = words.forEach(function Annot(word){ DoHighlight(this,word)});
However, it seems that was not the issue, after all, but the null value returned by getPageNthWord.
Copy link to clipboard
Copied
I didn't notice in the post I forgot to replace doc with this in the call, but the line is correct in the script I run. Everything works fine now it's just that when I switch to a reference to the document object instead of directly using this, the words are not highlighted. However when using event.target in the call instead of this, the words are highlighted and everything works fine. But more important what is the reason why it's better to use a reference ?? Thanks
Copy link to clipboard
Copied
The "this" object usually refers to the current Document, but not always. From my experience, when you start having functions call each other it can change its value from the Document object to something else, usually the function itself.
Anyway, it seems this was not the issue after all (it was more of a precaution), so you can simply change it back to how it was before.
Copy link to clipboard
Copied
The error message has nothing to do with toUpperCase.
I would recommend you pass a reference to the document object as a parameter to the function, instead of using the "this" keyword.
Copy link to clipboard
Copied
Thank you Try67, yes I mis explained I know that the .toUpperCase() method is not specifically & directly causing this error. What I mean is that when I use any method in my if statement I get a "TypeError: this.getPageNthWord(p, w) has no properties"
For the other part, sorry I don't really understand what you mean by "pass a reference to the document object as a parameter to the function". Do you mean something like this :
var myDoc = event.target;
function myFunction(word, myDoc) {
// The function actions here... and use like:
myDoc.getPageNthWord(p, w)
}
I would be really grateful if you could give a little example to help me understand
Copy link to clipboard
Copied
What I mean is that when you call the DoHighlight function, add another parameter to it, the Document object itself, like this:
function DoHighlight(doc, word) {
...
}
And then when you call it, change it to this:
DoHighlight(this, word)
Then within that function itself change all references to "this" to "doc".