Search code examples
javascriptdomdynamicdom-eventsmootools

Appending to dynamically created divs using Javascript and mootools


Using mootools I have a 'builder' class that manufactures form objects, dynamically creating divs as it does so. Some of the form objects are made up of several different objects. For example, a selection object features a textbox which filters the contents of the selector and a button to save the selection.

In this case I want the filter box and button to be located in a div which is appended to the div of the overall form object so as to have a 'wrapper'.

However, I'm having a problem appending to the div of the dynamically created form object.

After the dom is loaded, the 'builder' class is called:

window.addEvent('domready', function()
{
builder = new Build();
});         

Builder creates a new div as such

var div = document.createElement('div');
var div_id = 'the_div_id_for_my_form_object';

div.setAttribute('id', div_id);

It then creates the form object which takes in the div as one of its parameters

var form_obj = superSelector(div);

Inside the form_obj constructor, this div is saved as a member variable, this.div = div. The filter textbox is created as well as the button.

Here is where I'm seeing a problem. (since the issue is the same for both the filter textbox and the button, I'll describe only the textbox case)

The div of form_obj is passed to the constructor of the filter textbox. When the filter textbox is created, it creates a div for itself

 var div = document.createElement('div');
 var div_id = 'the_div_id_for_my_filter_box';

When I attempt to append this div to the div of form_obj, I get a js error saying that I am attempting to append to 'null'

 var filterBox = new Class({
 initialize: function(name, form_obj)
 { 
   this.name = name;

   this.div = document.createElement('div');
   this.div.setAttribute('id', name);

   document.getElementById(form_obj.div).appendChild(this.div);
  }

Yields:

"Uncaught TypeError: Cannot call method 'appendChild' of null"

I'm not sure how to get around this. I get the sense that the div I want to append to doesn't exist at the time I try to append to it. However I see no way of generating an event which tells me when it does exist so that I can postpone the construction of any 'child' divs until that point


Solution

  • right. several things you do that are not mootoolsy.

    var div = document.createElement('div');
    var div_id = 'the_div_id_for_my_form_object';
    
    div.setAttribute('id', div_id);
    

    should be:

    var div = new Element('div', {
        id: 'the_div_id_for_my_form_object'
    }); // or even new Element('div#foobar'); 
    
    
    div.setAttribute('id', div_id); -> div.set('id', div_id);
    

    then appending to the dom:

    document.getElementById(form_obj.div).appendChild(this.div);
    

    why? what are you trying to do? grab an element and add to the div in memory?

    document.id(form_obj.div).inject(this.div); 
    // if this element exist, it will be moved as a child to the new div, not safe
    // you really ought to rewrite to:
    var el = document.id(form_obj.div);
    el && el.inject(this.div); 
    

    keep in mind this div is not injected to the dom yet at this point.

    and so on. read the manual/api - you can always use native js but that kind of defeats the purpose of using a library that fixes things for you.

    On a side note, doing what you are doing is not exactly easy, I am currently working with a friend (well, colleague!) of mine on something of a form-builder (for mootools, AMD) and it does what you will probably want to do, more or less - input types, groups, infinite dependencies triggered by values (on all el types), all sorts of form elements and custom looks / feels, validators, default values, placeholders, custom events.. Model/controller like behaviour, default values, server side data / validation, persisted per input data (sessionStorage / window.name)

    gets created with AMD builder manifests that support versioning, pagination and languages over twitter bootstrap markup and elements and a single-page restful app via hashtags... basically, it is really a big task.

    if we ever decide to open-source it (and I hope we can), and ppl have interest, who knows - you can pretty much build things like interactive tests, survey monkeys, quick forms, complex forms, whatever with it... its extendible and flexible. hope we finish it....