This morning I continued working on my Greasemonkey script for our ticket system. I decided I wanted a ticket to scroll to the relevant information on load. As this location varies depending on the ticket, it would be necccessary to pick a specific page element and scroll to it. This turned out being slightly more complicated than I originally thought.
I searched Google for “get object position+javascript“. Using the helpful information on this page, I did the following:
//Finds y value of given object
function findPos(obj) {
var curtop = 0;
if (obj.offsetParent) {
do {
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return [curtop];
}
}
//Get object
var SupportDiv = document.getElementById('customer_info');
//Scroll to location of SupportDiv on load
window.scroll(0,findPos(SupportDiv));
It’s pretty easy and works just like I wanted it to.
Today I endeavored to do something I had not done before: write a Greasemonkey script. As it turns out, this is relatively simple to do, but I did run into several problems. This was mostly due to my inexperience with JavaScript and my inexperience with Greasemonkey.
But in case anyone else has the same problems, I’ll detail some of the issues I ran up against.
My goal was simple: In our helpdesk ticket system, we have a comment field that allows us to comment on a ticket. Typically, I write the following text after I complete the ticket:
Please let us know if we may further assist you.
Thanks,
Clifton Griffin
Pretty simple, but I often find myself annoyed while typing this repeatedly. Why not use copy/paste? Well, I use copy/paste for other things in the course of closing a ticket and, writing a script is more fun.
My final script is as follows:
function appendSig(theField) {
var theField = document.getElementsByTagName('textarea');
theField[0].value += '\n\nPlease let us know if we may be of further ' +
'assistance.\n\nThanks,\nClifton Griffin\nNetwork Operations Center';
}
var CommentBox = document.getElementsByTagName('textarea');
var newLink = document.createElement('a');
CommentBox[0].parentNode.insertBefore(newLink, CommentBox[0]);
newLink.innerHTML = '(Append Signature)';
newLink.addEventListener("click", appendSig, true);
Pretty simple, right?
I create a function to modify the first textarea on the page (well, the only textarea in this example).
I create a link and add an event listener that fires the function when it is clicked.
In the process of writing this script, I learned several things.
- document.getElementByName() does not seem to work reliably (though I may have made the same mistake as below–I honestly don’t remember. I gave up pretty early on).
- document.getElementsByTagName() returns an array. You might think that would be obvious but the specs do not actually use the word array. It does say it gets a list. This arguably implies an array, but they could have been more specific. (Considering the nature of the documentation)
- You cannot use onClick() to run functions with greasemonkey. This is because by the time the page asks for the function, it no longer exists. Instead, you must use addEventListener, as shown above.
- While it may be tempting to use innerHTML to modify a textarea (and indeed, many many sites recommend this), I found this to be problematic in Firefox. It adds the text (you can see it do so in firebug), but the screen does not update. I briefly worked around this by trying:
CommentBox.styles.display = "none";
CommentBox.styles.display = "block";
This worked a little. It seemed to fix the problem briefly, but upon further inspection, a couple of things didn’t work. Mainly, clicking the link added the text as long as I hadn’t manually added any text to the field. Also, clicking the link again didn’t work. This is really weird behavior that I can only blame on Firefox.
So there you have it. Four issues. I hope they help someone else save some time.