views:

570

answers:

2

I'm going to develop a firefox extension which adds a button beside the file input fields (the <input type="file"> tag) when a file is selected.

The file overlay.js, which contains the extension's logic, manages the "file choose" event through this method:

var xpitest = {
    ...
    onFileChosen: function(e) {
        var fileInput = e.explicitOriginalTarget;
        if(fileInput.type=="file"){
            var parentDiv = fileInput.parentNode;
            var newButton = top.window.content.document.createElement("input");
            newButton.setAttribute("type", "button");
            newButton.setAttribute("id", "Firefox.Now_button_id");
            newButton.setAttribute("value", "my button");
            newButton.setAttribute("name", "Firefox.Now_button_name");
            parentDiv.insertBefore(newButton, fileInput);
        }
    }
    ...
}

window.addEventListener("change", function(e) {xpitest.onFileChosen(e)},false);

My problem is that, everytime I choose a file, a new button is being added, see this picture:

If I select the same file more than once, no new button appears (this is correct).

As we can see, on the first file input, only one file has been selected.

On the second one I've chosen two different files, in effect two buttons have been created...

On the third, I've chosen three different files.

The correct behavior should be this:

  • when a file is chosen, create my_button beside the input field
  • if my_button exists, delete it and create another one (I need this, beacuse I should connect it to a custom event which will do something with the file name)

My question is: how can I correctly delete the button? Note that the my_button html code does not appear on page source!

Thanks

A: 

Pardon me if I'm thinking too simply, but couldn't you just do this?

var button = document.getElementById('Firefox.Now_button_id')
button.parentNode.removeChild(button)

Is this what you were looking for? Feel free to correct me if I misunderstood you.

musicfreak
This way may remove ALL buttons, I need to remove only the button associated to the input field... I've tryed this:var oldButton = document.getElementById("Firefox.Now_button_id");if(oldButton!=null){parentDiv.removeChild(oldButton);}I think I should use IDs but I can't get it working...
Giancarlo
How can this remove all buttons? You should only have one button with that ID.
musicfreak
Of course! But this wont remove any buttons, I think because the html code for my_button does not appear on page source!
Giancarlo
A: 

Solved. I set an ID for each with the following method:

onPageLoad: function(e){
    var inputNodes = top.window.content.document.getElementsByTagName("input");       
    for(var i=0; i<inputNodes.length; i++){
    if(inputNodes[i].type=="file")
         inputNodes[i].setAttribute("id",i.toString());
    } 
}

I call this method only on page load:

var appcontent = document.getElementById("appcontent");   // browser
if(appcontent)
    appcontent.addEventListener("DOMContentLoaded", xpitest.onPageLoad, true);

Then I've modified the onFileChosen method in this way:

onFileChosen: function(e) {
    var fileInput = e.explicitOriginalTarget;
    if(fileInput.type=="file"){
        var parentDiv = fileInput.parentNode;         
        var buttonId = fileInput.id + "Firefox.Now_button_id";
        var oldButton = top.window.content.document.getElementById(buttonId);
        if(oldButton!=null){
            parentDiv.removeChild(oldButton);
            this.count--;
        }
        var newButton = top.window.content.document.createElement("input");
        newButton.setAttribute("type", "button");      
        newButton.setAttribute("id", buttonId);
        newButton.setAttribute("value", "my button");
        newButton.setAttribute("name", "Firefox.Now_button_name");
        parentDiv.insertBefore(newButton, fileInput);
        this.count++;
    }
}
Giancarlo