views:

240

answers:

5

I have a JavaScript library that updates a hidden <textarea> HTML element with some data based on some things.

In my (JavaScript) application I'd like to know when these updates occur without having to go through the existing library code.

I was hoping there was an event for this, but apparently not.

How would I listen for changes of the textarea?

Changes can be as simple as document.getElementById("myTextarea").value = "hello";

EDIT I will be using FireFox only, since this code will only be part of a test suite I'm building.

+2  A: 

If you control the Javascript library you mention, I would say the easiest way would be to manually trigger the change event every time you change a field's value.

I think this is how it's done in JQuery: Events/change Otherwise, a simple document.getElementById('myTextarea').onchange() might work as well.

If you have many calls, you could wrap the changing of the value, and the triggering of the event into a changeFormElement(id, value) function.

This requires, of course, that you can modify every instance of when a textarea is changed. If that is given, this is probably the most elegant way.

Pekka
`change` in jQuery is only fired when someone loses focus on an input field
Harmen
+1 Pekka. I agree that editing the library would be the best course of action if possible. *@Harmen:* He's talking about editing the library the asker is using to make it fire the `change` event.
Andy E
+1  A: 

DOM events do not occur when value to the node is setted programmatically through node.value; Search for API documentation of your JavaScript library and see if they have some notification mechanism.

EDITED: Firefox? Oh great, then there is such interesting function as watch. It watches for property changes. For you, this means, that when library change the 'value' property of the textarea you receive notification. What more nice, is that you even can control the value setted to the property. See in action.

var textnode = document.createElement('textarea');
textnode.watch('value', function(attr, oldv, newv){
    alert(newv);
    return newv; // you have to return correct value back.
});

//and now trigger the change to see that this works.
textnode.value = 'Bla';

Maybe this helps? :)

nemisj
Yes i know, but i thought at least textarea would have such functionality since it's more of a 'data container' rather than just a textual element.
Luca Matteis
+1  A: 

I know it's probably not what you want to hear but only IE seems to have an event that can handle this. It's the onpropertychange event.

textArea.onpropertychange = function ()
{
    if (event.propertyName == "innerText")
        alert('innerText has changed.');
}

If you're allowed to modify the library's code, I would do as Pekka mentioned and adjust the code so that it fires the change event. The only real cross-browser thing you could do is use a timer. If you use a low enough frequency timer, it probably wouldn't even be noticeable to the end user that you weren't using an event.

Andy E
+1 This is good to know.
Pekka
I'm always dubious about mentioning IE-only solutions. No matter how much you might be posting it for the sake of the asker, and how correct it might be, some IE-hating maniac downvotes you without mentioning why.
Andy E
+1  A: 

There is of course an unelegant and dishonorificabilitudinitatible way to achieve this, by setting a timer:

var oldVal, el;
function setTimer(){
    setTimeout(function(){
        if(el.value != oldVal){
            console.log('something happened');
            oldVal = el.value;
        }
        setTimer();
    }, 5000);
};

This will compare the value every five seconds to the value of five seconds ago.

Harmen
+2  A: 

In FireFox you can extend the value setter:

HTMLTextAreaElement.prototype.__defineSetter__("value", function(t) {
    alert('someone is setting the value of a textarea');
    return this.textContent = t;
});
Darin Dimitrov
This is great since I will be using Firefox only! I should've specified that it won't be an application delivered to users, but just part of a test suite I'm building. Thanks!
Luca Matteis
Can I fire this for a specific element?
Luca Matteis
No, but you can test `this.id` inside.
Darin Dimitrov
@Luca: yes you can fire it for a specific element: `textareaObj.__defineSetter__('value', ...)`
Roatin Marth