0

Context – jQuery widget factory, rendering elements and storing them in private variables.

_renderInputHolder: function () {

    var self = this;

    this._inputHolder = $(document.createElement('div'))
        .on('focusout', function (e) {
        self._hideInputHolder.apply(self, [e]);
    });

},

_renderTextInput: function () {

    var self = this;

    this._textInput = $(document.createElement('input'))
        .keypress(function (e) {
        if (e.which === 13) {
            self._hideInputHolder();
        }
    });
},

_hideInputHolder: function () {

    this._inputHolder = this._inputHolder.detach();

},

Problem – two separate elements have independent events that try to detach the container element. When the enter keypress occurs on the text input, it detaches the inputContainer but this also causes a 'focusout' event to be triggered on the inputContainer, resulting in a

Uncaught Error: NotFoundError: DOM Exception 8 

as it tries to detach it again.

What's the best way to ensure the inputContainer's removal without error OR check that .detach() can be called?

Tushar Gupta - curioustushar
  • 58,085
  • 24
  • 103
  • 107
Qro
  • 15
  • 3

2 Answers2

1

you can hold a state variable using data() to see whether the element is detached

if(!this._inputHolder.data('detached')){
    this._inputHolder = this._inputHolder.data('detached', true).detach();
}
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • I reordered .detach().data() to .data().detach() as it turns out setting data after detachment didn't work, however setting the data before detaching does. Will accept as answer, if the edit is agreeable. – Qro Jul 25 '13 at 07:34
  • another way to kill something like it... +1 – Reigel Gallarde Jul 25 '13 at 08:10
0

you can check if there's an element...

 _hideInputHolder: function() {
    if ($(this._inputHolder,'body').length) {
         this._inputHolder = this._inputHolder.detach();
    }
}
Reigel Gallarde
  • 64,198
  • 21
  • 121
  • 139
  • Thanks for answering! Unfortunately as the element is stored in a variable, the length will always return 1 (before and after detach). – Qro Jul 25 '13 at 06:18
  • @Qro how about checking if the element can be found in the body... see edited code.. – Reigel Gallarde Jul 25 '13 at 06:33
  • Unfortunately $(this._inputHolder,'body').length still returns 1 after detach, though I think this would work in other cases. – Qro Jul 25 '13 at 08:02