Quicker way for DOM?

Discussion in 'Javascript' started by adam@areasix.co.uk, May 31, 2007.

  1. Guest

    I'm currently coding a CMS system for a site which includes the
    feature to create multiple sections inside a page. To add each of
    these new sections I'm using DOM with AJAX to save, but I've got a
    pretty div for each section which needs to be created on the click of
    a button. Here's a sample of the code, I won't post it all because
    it's quite big...

    function addSection() {
    // Get number of current sections
    var sections = 0;
    var el_sections = document.getElementById('sections');

    for (i=0; i<el_sections.getElementsByTagName('li').length; i++) {
    if (el_sections.getElementsByTagName('li').parentNode ==
    el_sections) sections++;
    }

    new_section = sections + 1;

    // Create List Item
    var section_li = document.createElement('li');
    section_li.setAttribute('id', 'section_' + new_section);

    // Create section_header DIV
    var header_div = document.createElement('div');
    header_div.className='section_header';

    // Create Title Input
    var title_input = document.createElement('input');
    var title_input_id = 'section_'+new_section+'_title';
    title_input.setAttribute('type', 'text');
    title_input.setAttribute('size', '50');
    title_input.setAttribute('name', 'section['+new_section+']
    [section_title]');
    title_input.setAttribute('id', title_input_id);

    // Create Label
    var title_label = document.createElement('label');
    title_label.setAttribute('for', title_input_id);
    title_label_text = document.createTextNode('Section Title:');
    title_label.appendChild(title_label_text);

    header_div.appendChild(title_label);
    header_div.appendChild(title_input);

    .........

    section_li.appendChild(header_div);


    el_sections.appendChild(section_li);
    }


    to create something along the lines of:
    <li id="section_1">
    <div id="header_1" class="section_header">
    <label for="section_1_title">Section Title:</label>
    <input type="text" name="section[1][section_title]"
    id="section_1_title" size="50" />
    </div>
    <div class="section_options">
    <ul>
    <li>
    <label for="section_1_position">Position:</label>
    <select name="section[1][section_position]"
    id="section_1_position">
    <option value="1" selected>1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    </select>
    </li>
    <li><a href="javascript:;"
    onClick="javascript:showHideDetails('1')" id="shlink_1">hide</a></li>
    <li><a href="javascript:;"
    onClick="javascript:deleteSection('1')">delete</a></li>
    </ul>
    </div>
    <div id="details_1" class="section_content">
    <textarea name="section[1][htmlelement][htmlelement_content]"
    cols="60" rows="10" ></textarea>
    <br />
    <small>
    <input type="checkbox" name="section[1][htmlelement][parse]"
    id="section_1_parse"> <label for="section_1_parse">Parse Code (for
    Dynamic Content)</label><br />
    <input type="checkbox" name="section[1][htmlelement][hideheader]"
    id="section_1_hideheader"> <label for="section_1_hideheader">Hide
    Header</label>
    </small>
    </div>
    </li>


    I'm pretty new to this DOM lark, I've just pieced everything together
    from tutorials across the internet, so I'm wondering, is there a more
    efficient way of doing this or anything anyone can suggest?

    Thanks in advance
    , May 31, 2007
    #1
    1. Advertising

  2. Darko Guest

    On May 31, 12:51 pm, wrote:
    > I'm currently coding a CMS system for a site which includes the
    > feature to create multiple sections inside a page. To add each of
    > these new sections I'm using DOM with AJAX to save, but I've got a
    > pretty div for each section which needs to be created on the click of
    > a button. Here's a sample of the code, I won't post it all because
    > it's quite big...
    >
    > function addSection() {
    > // Get number of current sections
    > var sections = 0;
    > var el_sections = document.getElementById('sections');
    >
    > for (i=0; i<el_sections.getElementsByTagName('li').length; i++) {
    > if (el_sections.getElementsByTagName('li').parentNode ==
    > el_sections) sections++;
    > }
    >
    > new_section = sections + 1;
    >
    > // Create List Item
    > var section_li = document.createElement('li');
    > section_li.setAttribute('id', 'section_' + new_section);
    >
    > // Create section_header DIV
    > var header_div = document.createElement('div');
    > header_div.className='section_header';
    >
    > // Create Title Input
    > var title_input = document.createElement('input');
    > var title_input_id = 'section_'+new_section+'_title';
    > title_input.setAttribute('type', 'text');
    > title_input.setAttribute('size', '50');
    > title_input.setAttribute('name', 'section['+new_section+']
    > [section_title]');
    > title_input.setAttribute('id', title_input_id);
    >
    > // Create Label
    > var title_label = document.createElement('label');
    > title_label.setAttribute('for', title_input_id);
    > title_label_text = document.createTextNode('Section Title:');
    > title_label.appendChild(title_label_text);
    >
    > header_div.appendChild(title_label);
    > header_div.appendChild(title_input);
    >
    > ........
    >
    > section_li.appendChild(header_div);
    >
    > el_sections.appendChild(section_li);
    >
    > }
    >
    > to create something along the lines of:
    > <li id="section_1">
    > <div id="header_1" class="section_header">
    > <label for="section_1_title">Section Title:</label>
    > <input type="text" name="section[1][section_title]"
    > id="section_1_title" size="50" />
    > </div>
    > <div class="section_options">
    > <ul>
    > <li>
    > <label for="section_1_position">Position:</label>
    > <select name="section[1][section_position]"
    > id="section_1_position">
    > <option value="1" selected>1</option>
    > <option value="2">2</option>
    > <option value="3">3</option>
    > <option value="4">4</option>
    > <option value="5">5</option>
    > </select>
    > </li>
    > <li><a href="javascript:;"
    > onClick="javascript:showHideDetails('1')" id="shlink_1">hide</a></li>
    > <li><a href="javascript:;"
    > onClick="javascript:deleteSection('1')">delete</a></li>
    > </ul>
    > </div>
    > <div id="details_1" class="section_content">
    > <textarea name="section[1][htmlelement][htmlelement_content]"
    > cols="60" rows="10" ></textarea>
    > <br />
    > <small>
    > <input type="checkbox" name="section[1][htmlelement][parse]"
    > id="section_1_parse"> <label for="section_1_parse">Parse Code (for
    > Dynamic Content)</label><br />
    > <input type="checkbox" name="section[1][htmlelement][hideheader]"
    > id="section_1_hideheader"> <label for="section_1_hideheader">Hide
    > Header</label>
    > </small>
    > </div>
    > </li>
    >
    > I'm pretty new to this DOM lark, I've just pieced everything together
    > from tutorials across the internet, so I'm wondering, is there a more
    > efficient way of doing this or anything anyone can suggest?
    >
    > Thanks in advance


    See the reference manual for cloneNode() function - you may find it
    interesting for your case.
    Darko, May 31, 2007
    #2
    1. Advertising

  3. RobG Guest

    On May 31, 8:51 pm, wrote:
    > I'm currently coding a CMS system for a site which includes the
    > feature to create multiple sections inside a page. To add each of
    > these new sections I'm using DOM with AJAX to save, but I've got a
    > pretty div for each section which needs to be created on the click of
    > a button. Here's a sample of the code, I won't post it all because
    > it's quite big...
    >
    > function addSection() {


    [... ~90 lines of code & HTML trimmed ...]

    > I'm pretty new to this DOM lark, I've just pieced everything together
    > from tutorials across the internet, so I'm wondering, is there a more
    > efficient way of doing this or anything anyone can suggest?


    Do it on a server and send HTML to the client, it tends to be *much*
    more efficient.

    As for optimising client-side code, you have plenty of scope for
    that. :) Heed the advice given here:

    <URL: http://homepage.mac.com/rue/JS_Optimization_Techniques/ >


    --
    Rob
    RobG, May 31, 2007
    #3
  4. Guest

    On 31 May, 13:06, RobG <> wrote:
    > On May 31, 8:51 pm, wrote:
    >
    > > I'm currently coding a CMS system for a site which includes the
    > > feature to create multiple sections inside a page. To add each of
    > > these new sections I'm using DOM with AJAX to save, but I've got a
    > > pretty div for each section which needs to be created on the click of
    > > a button. Here's a sample of the code, I won't post it all because
    > > it's quite big...

    >
    > > function addSection() {

    >
    > [... ~90 lines of code & HTML trimmed ...]
    >
    > > I'm pretty new to this DOM lark, I've just pieced everything together
    > > from tutorials across the internet, so I'm wondering, is there a more
    > > efficient way of doing this or anything anyone can suggest?

    >
    > Do it on a server and send HTML to the client, it tends to be *much*
    > more efficient.
    >
    > As for optimising client-side code, you have plenty of scope for
    > that. :) Heed the advice given here:
    >
    > <URL:http://homepage.mac.com/rue/JS_Optimization_Techniques/>


    Thanks for this, Rob. So are you saying it would be quicker to do it
    server-side and sending back the response with AJAX? This could be an
    idea as I have an issue where the ID of the section needs to be
    generated at some point, but there would be no way of cancelling and
    saving the index, not sure how much of an issue this is. This will
    also be handy for browser compatibility, although touch wood so far it
    has been OK.
    , May 31, 2007
    #4
  5. i would echo Darko's recommendation to look at
    element.cloneNode(true);

    It gets hairy because you need to get to "element" in the first place,
    which would be some sort of template which you need to clone. But you
    really want to refrain to cloneNode() anything that has an "id"
    attribute because the id attribute will also get cloned, and there
    should only ever be one id on a document. So you'd have to remove the
    id attribute.

    To deal with this type of tedium, I recently released a small, simple
    JS library aimed at making it easy to "do stuff with the DOM". One key
    underlying component is the ability to define one or multiple
    "template stashes" in a given document. A Stash is simply any element
    such as a "div" that contains "templates" as one of its "class"
    attribute values, such as:

    <div class="templates">
    ..... all your templates go here
    </div>

    Inside of it you can have your <li> block.as a template, as such:

    <div class="templates" style="display:none">
    <!-- in this section, there should never be an "id" attribute, EVER
    -->
    <!-- because this section contains templates and templates are meant
    to be cloned -->
    <!-- ibdom lets you retrieve template clones based on class
    attribute values. -->



    <li class="sectionTemplate"> <!-- a template is identified by a
    class value. -->
    <div class="section_header"> <!-- id set at post-
    processing if you still need it. -->
    <label for="NO_VALUE_YET" class="title_label">Section
    Title:</label>
    <input type="text" name="NONAME_YET" size="50"
    class="section_title_text_input"/>
    </div>
    ....
    <!-- the rest of your HTML for a given section goes here.-->
    <!-- use class values to identify various elements so you can
    access them during template processing:
    templateClone.gFEBCN("section_header"); will return the same
    element that document.getElementById("header_1");
    would have otherwise returned before you'd removed all "id"
    attributes from your HTML.

    gFEBCN stands for getFirstElementByClassName
    -->

    </li>
    </div>

    back in script-land, IBDOM defines a utility function called "$t()".

    You simply pass it a class value for the template you're looking for,
    and an optional tag name. It will return A CLONE of the template. You
    can then "appendChild()" this clone anywhere in your document:

    Here's some sample code for your situation:

    templateIdNumber = 1;
    myTemplateClone = $t("sectionTemplate");
    myTemplateClone.setAttribute("id","section_" + templateIdNumber);
    /* now we have a template, we want to set various attributes based on
    templateIdNumber */
    /* IBDOM has a few methods to help you out with that! here goes: */
    myTemplateClone.gFEBCN("section_header").setAttribute("id","section_"
    + templateIdNumber);
    myTemplateClone.gFEBCN("title_label").setAttribute("for","section_" +
    templateIdNumber + "_title");
    myTemplateClone.gFEBCN("section_title_text_input").setAttribute("id","section_"
    + templateIdNumber + "_title");
    myTemplateClone.gFEBCN("section_title_text_input").setAttribute("name","section["+templateIdNumber
    +"][section_title]");
    .... continue setting other attributes for various elements.
    .... still pretty tedious but at least you're only setting attributes.
    .... and you can tweak your html more easily if needed, as long as you
    retain the class attributes.

    if you weren't dynamically setting "id" and "name" attributes all over
    the place, you could use "data:" markers in your template for most
    everything else, which would have gotten injected with
    myTemplateClone.populate(someConfigObject);

    the populate() method is good for just about all attributes except
    "id" which we can't have in a template environment, and "name" because
    of some weird Win/IE issue for which i need to find time to work
    around.

    As others mentioned, you can have an ajax call return a template
    freshly populated by the server. That's an additional roundtrip to the
    server, but it sounds like it would have limited performance hit.

    If you do want to try out IBDOM, it's at: http://ibdom.sourceforge.net/

    Feel free to ping me with Qs/thoughts/suggestions. I'm very close to
    an 0.2 release which will go live in one of our customer-facing apps
    in a few days, once it passes QE. ibdom.js in the SVN repository has
    the latest stable version.


    On May 31, 5:33 am, wrote:
    > On 31 May, 13:06, RobG <> wrote:
    >
    >
    >
    > > On May 31, 8:51 pm, wrote:

    >
    > > > I'm currently coding a CMS system for a site which includes the
    > > > feature to create multiple sections inside a page. To add each of
    > > > these new sections I'm using DOM with AJAX to save, but I've got a
    > > > pretty div for each section which needs to be created on the click of
    > > > a button. Here's a sample of the code, I won't post it all because
    > > > it's quite big...

    >
    > > > function addSection() {

    >
    > > [... ~90 lines of code & HTML trimmed ...]

    >
    > > > I'm pretty new to this DOM lark, I've just pieced everything together
    > > > from tutorials across the internet, so I'm wondering, is there a more
    > > > efficient way of doing this or anything anyone can suggest?

    >
    > > Do it on a server and send HTML to the client, it tends to be *much*
    > > more efficient.

    >
    > > As for optimising client-side code, you have plenty of scope for
    > > that. :) Heed the advice given here:

    >
    > > <URL:http://homepage.mac.com/rue/JS_Optimization_Techniques/>

    >
    > Thanks for this, Rob. So are you saying it would be quicker to do it
    > server-side and sending back the response with AJAX? This could be an
    > idea as I have an issue where the ID of the section needs to be
    > generated at some point, but there would be no way of cancelling and
    > saving the index, not sure how much of an issue this is. This will
    > also be handy for browser compatibility, although touch wood so far it
    > has been OK.
    ChrisHolland@InternetBrands, Jun 1, 2007
    #5
  6. Guest

    On 1 Jun, 10:32, "ChrisHolland@InternetBrands" <>
    wrote:
    > i would echo Darko's recommendation to look at
    > element.cloneNode(true);
    >
    > It gets hairy because you need to get to "element" in the first place,
    > which would be some sort of template which you need to clone. But you
    > really want to refrain to cloneNode() anything that has an "id"
    > attribute because the id attribute will also get cloned, and there
    > should only ever be one id on a document. So you'd have to remove the
    > id attribute.
    >
    > To deal with this type of tedium, I recently released a small, simple
    > JS library aimed at making it easy to "do stuff with the DOM". One key
    > underlying component is the ability to define one or multiple
    > "template stashes" in a given document. A Stash is simply any element
    > such as a "div" that contains "templates" as one of its "class"
    > attribute values, such as:
    >
    > <div class="templates">
    > .... all your templates go here
    > </div>
    >
    > Inside of it you can have your <li> block.as a template, as such:
    >
    > <div class="templates" style="display:none">
    > <!-- in this section, there should never be an "id" attribute, EVER
    > -->
    > <!-- because this section contains templates and templates are meant
    > to be cloned -->
    > <!-- ibdom lets you retrieve template clones based on class
    > attribute values. -->
    >
    > <li class="sectionTemplate"> <!-- a template is identified by a
    > class value. -->
    > <div class="section_header"> <!-- id set at post-
    > processing if you still need it. -->
    > <label for="NO_VALUE_YET" class="title_label">Section
    > Title:</label>
    > <input type="text" name="NONAME_YET" size="50"
    > class="section_title_text_input"/>
    > </div>
    > ....
    > <!-- the rest of your HTML for a given section goes here.-->
    > <!-- use class values to identify various elements so you can
    > access them during template processing:
    > templateClone.gFEBCN("section_header"); will return the same
    > element that document.getElementById("header_1");
    > would have otherwise returned before you'd removed all "id"
    > attributes from your HTML.
    >
    > gFEBCN stands for getFirstElementByClassName
    > -->
    >
    > </li>
    > </div>
    >
    > back in script-land, IBDOM defines a utility function called "$t()".
    >
    > You simply pass it a class value for the template you're looking for,
    > and an optional tag name. It will return A CLONE of the template. You
    > can then "appendChild()" this clone anywhere in your document:
    >
    > Here's some sample code for your situation:
    >
    > templateIdNumber = 1;
    > myTemplateClone = $t("sectionTemplate");
    > myTemplateClone.setAttribute("id","section_" + templateIdNumber);
    > /* now we have a template, we want to set various attributes based on
    > templateIdNumber */
    > /* IBDOM has a few methods to help you out with that! here goes: */
    > myTemplateClone.gFEBCN("section_header").setAttribute("id","section_"
    > + templateIdNumber);
    > myTemplateClone.gFEBCN("title_label").setAttribute("for","section_" +
    > templateIdNumber + "_title");
    > myTemplateClone.gFEBCN("section_title_text_input").setAttribute("id","section_"
    > + templateIdNumber + "_title");
    > myTemplateClone.gFEBCN("section_title_text_input").setAttribute("name","section["+templateIdNumber
    > +"][section_title]");
    > ... continue setting other attributes for various elements.
    > ... still pretty tedious but at least you're only setting attributes.
    > ... and you can tweak your html more easily if needed, as long as you
    > retain the class attributes.
    >
    > if you weren't dynamically setting "id" and "name" attributes all over
    > the place, you could use "data:" markers in your template for most
    > everything else, which would have gotten injected with
    > myTemplateClone.populate(someConfigObject);
    >
    > the populate() method is good for just about all attributes except
    > "id" which we can't have in a template environment, and "name" because
    > of some weird Win/IE issue for which i need to find time to work
    > around.
    >
    > As others mentioned, you can have an ajax call return a template
    > freshly populated by the server. That's an additional roundtrip to the
    > server, but it sounds like it would have limited performance hit.
    >
    > If you do want to try out IBDOM, it's at:http://ibdom.sourceforge.net/
    >
    > Feel free to ping me with Qs/thoughts/suggestions. I'm very close to
    > an 0.2 release which will go live in one of our customer-facing apps
    > in a few days, once it passes QE. ibdom.js in the SVN repository has
    > the latest stable version.
    >
    > On May 31, 5:33 am, wrote:
    >
    > > On 31 May, 13:06, RobG <> wrote:

    >
    > > > On May 31, 8:51 pm, wrote:

    >
    > > > > I'm currently coding a CMS system for a site which includes the
    > > > > feature to create multiple sections inside a page. To add each of
    > > > > these new sections I'm using DOM with AJAX to save, but I've got a
    > > > > pretty div for each section which needs to be created on the click of
    > > > > a button. Here's a sample of the code, I won't post it all because
    > > > > it's quite big...

    >
    > > > > function addSection() {

    >
    > > > [... ~90 lines of code & HTML trimmed ...]

    >
    > > > > I'm pretty new to this DOM lark, I've just pieced everything together
    > > > > from tutorials across the internet, so I'm wondering, is there a more
    > > > > efficient way of doing this or anything anyone can suggest?

    >
    > > > Do it on a server and send HTML to the client, it tends to be *much*
    > > > more efficient.

    >
    > > > As for optimising client-side code, you have plenty of scope for
    > > > that. :) Heed the advice given here:

    >
    > > > <URL:http://homepage.mac.com/rue/JS_Optimization_Techniques/>

    >
    > > Thanks for this, Rob. So are you saying it would be quicker to do it
    > > server-side and sending back the response with AJAX? This could be an
    > > idea as I have an issue where the ID of the section needs to be
    > > generated at some point, but there would be no way of cancelling and
    > > saving the index, not sure how much of an issue this is. This will
    > > also be handy for browser compatibility, although touch wood so far it
    > > has been OK.


    Thanks for that, it's very informative.

    The problem with cloneNode(true), as you mentioned, is the cloning of
    the elements with their class names. I think the approach I will
    adopt now will be using cloneNode, setting the ID of the parent node
    and then instead of using the id's inside, just use a
    getElementsByClassName to distinguish the details inside. This seems
    to be the best option. Thanks for all your input.
    , Jun 5, 2007
    #6
  7. sounds good. also remember that getElementsByClassName isn't part of
    the DOM spec and isn't built into any browser, you can either write
    your own (fairly trivial) or use a library that has it. i'm pretty
    sure the following JS libraries all have it:

    prototype.js
    yui
    dojotoolkit
    mootools
    and possibly a zillion more :)

    IBDOM has it too:

    Where "someID" is the parent node you speak of:
    $e("someID").gEBCN("theClassName","optionalTagName") <-- returns
    array, always, could be empty array.
    $e("someID").gFEBCN("theClassName","optionalTagName") <-- returns
    *one* element, or null

    latest snapshots:

    http://ibdom.svn.sourceforge.net/viewvc/ibdom/core/js/ibdom.compressed.js?view=markup
    (14KB)
    http://ibdom.svn.sourceforge.net/viewvc/ibdom/core/js/ibdom.js?view=markup
    (25KB)

    good luck :)



    On Jun 5, 7:28 am, wrote:
    > On 1 Jun, 10:32, "ChrisHolland@InternetBrands" <>
    > wrote:
    >
    >
    >
    > > i would echo Darko's recommendation to look at
    > > element.cloneNode(true);

    >
    > > It gets hairy because you need to get to "element" in the first place,
    > > which would be some sort of template which you need to clone. But you
    > > really want to refrain to cloneNode() anything that has an "id"
    > > attribute because the id attribute will also get cloned, and there
    > > should only ever be one id on a document. So you'd have to remove the
    > > id attribute.

    >
    > > To deal with this type of tedium, I recently released a small, simple
    > > JS library aimed at making it easy to "do stuff with the DOM". One key
    > > underlying component is the ability to define one or multiple
    > > "template stashes" in a given document. A Stash is simply any element
    > > such as a "div" that contains "templates" as one of its "class"
    > > attribute values, such as:

    >
    > > <div class="templates">
    > > .... all your templates go here
    > > </div>

    >
    > > Inside of it you can have your <li> block.as a template, as such:

    >
    > > <div class="templates" style="display:none">
    > > <!-- in this section, there should never be an "id" attribute, EVER
    > > -->
    > > <!-- because this section contains templates and templates are meant
    > > to be cloned -->
    > > <!-- ibdom lets you retrieve template clones based on class
    > > attribute values. -->

    >
    > > <li class="sectionTemplate"> <!-- a template is identified by a
    > > class value. -->
    > > <div class="section_header"> <!-- id set at post-
    > > processing if you still need it. -->
    > > <label for="NO_VALUE_YET" class="title_label">Section
    > > Title:</label>
    > > <input type="text" name="NONAME_YET" size="50"
    > > class="section_title_text_input"/>
    > > </div>
    > > ....
    > > <!-- the rest of your HTML for a given section goes here.-->
    > > <!-- use class values to identify various elements so you can
    > > access them during template processing:
    > > templateClone.gFEBCN("section_header"); will return the same
    > > element that document.getElementById("header_1");
    > > would have otherwise returned before you'd removed all "id"
    > > attributes from your HTML.

    >
    > > gFEBCN stands for getFirstElementByClassName
    > > -->

    >
    > > </li>
    > > </div>

    >
    > > back in script-land, IBDOM defines a utility function called "$t()".

    >
    > > You simply pass it a class value for the template you're looking for,
    > > and an optional tag name. It will return A CLONE of the template. You
    > > can then "appendChild()" this clone anywhere in your document:

    >
    > > Here's some sample code for your situation:

    >
    > > templateIdNumber = 1;
    > > myTemplateClone = $t("sectionTemplate");
    > > myTemplateClone.setAttribute("id","section_" + templateIdNumber);
    > > /* now we have a template, we want to set various attributes based on
    > > templateIdNumber */
    > > /* IBDOM has a few methods to help you out with that! here goes: */
    > > myTemplateClone.gFEBCN("section_header").setAttribute("id","section_"
    > > + templateIdNumber);
    > > myTemplateClone.gFEBCN("title_label").setAttribute("for","section_" +
    > > templateIdNumber + "_title");
    > > myTemplateClone.gFEBCN("section_title_text_input").setAttribute("id","secti on_"
    > > + templateIdNumber + "_title");
    > > myTemplateClone.gFEBCN("section_title_text_input").setAttribute("name","sec tion["+templateIdNumber
    > > +"][section_title]");
    > > ... continue setting other attributes for various elements.
    > > ... still pretty tedious but at least you're only setting attributes.
    > > ... and you can tweak your html more easily if needed, as long as you
    > > retain the class attributes.

    >
    > > if you weren't dynamically setting "id" and "name" attributes all over
    > > the place, you could use "data:" markers in your template for most
    > > everything else, which would have gotten injected with
    > > myTemplateClone.populate(someConfigObject);

    >
    > > the populate() method is good for just about all attributes except
    > > "id" which we can't have in a template environment, and "name" because
    > > of some weird Win/IE issue for which i need to find time to work
    > > around.

    >
    > > As others mentioned, you can have an ajax call return a template
    > > freshly populated by the server. That's an additional roundtrip to the
    > > server, but it sounds like it would have limited performance hit.

    >
    > > If you do want to try out IBDOM, it's at:http://ibdom.sourceforge.net/

    >
    > > Feel free to ping me with Qs/thoughts/suggestions. I'm very close to
    > > an 0.2 release which will go live in one of our customer-facing apps
    > > in a few days, once it passes QE. ibdom.js in the SVN repository has
    > > the latest stable version.

    >
    > > On May 31, 5:33 am, wrote:

    >
    > > > On 31 May, 13:06, RobG <> wrote:

    >
    > > > > On May 31, 8:51 pm, wrote:

    >
    > > > > > I'm currently coding a CMS system for a site which includes the
    > > > > > feature to create multiple sections inside a page. To add each of
    > > > > > these new sections I'm using DOM with AJAX to save, but I've got a
    > > > > > pretty div for each section which needs to be created on the click of
    > > > > > a button. Here's a sample of the code, I won't post it all because
    > > > > > it's quite big...

    >
    > > > > > function addSection() {

    >
    > > > > [... ~90 lines of code & HTML trimmed ...]

    >
    > > > > > I'm pretty new to this DOM lark, I've just pieced everything together
    > > > > > from tutorials across the internet, so I'm wondering, is there a more
    > > > > > efficient way of doing this or anything anyone can suggest?

    >
    > > > > Do it on a server and send HTML to the client, it tends to be *much*
    > > > > more efficient.

    >
    > > > > As for optimising client-side code, you have plenty of scope for
    > > > > that. :) Heed the advice given here:

    >
    > > > > <URL:http://homepage.mac.com/rue/JS_Optimization_Techniques/>

    >
    > > > Thanks for this, Rob. So are you saying it would be quicker to do it
    > > > server-side and sending back the response with AJAX? This could be an
    > > > idea as I have an issue where the ID of the section needs to be
    > > > generated at some point, but there would be no way of cancelling and
    > > > saving the index, not sure how much of an issue this is. This will
    > > > also be handy for browser compatibility, although touch wood so far it
    > > > has been OK.

    >
    > Thanks for that, it's very informative.
    >
    > The problem with cloneNode(true), as you mentioned, is the cloning of
    > the elements with their class names. I think the approach I will
    > adopt now will be using cloneNode, setting the ID of the parent node
    > and then instead of using the id's inside, just use a
    > getElementsByClassName to distinguish the details inside. This seems
    > to be the best option. Thanks for all your input.
    ChrisHolland@InternetBrands, Jun 6, 2007
    #7
  8. Guest

    On 6 Jun, 16:37, "ChrisHolland@InternetBrands" <>
    wrote:
    > sounds good. also remember that getElementsByClassName isn't part of
    > the DOM spec and isn't built into any browser, you can either write
    > your own (fairly trivial) or use a library that has it. i'm pretty
    > sure the following JS libraries all have it:
    >
    > prototype.js
    > yui
    > dojotoolkit
    > mootools
    > and possibly a zillion more :)
    >
    > IBDOM has it too:
    >
    > Where "someID" is the parent node you speak of:
    > $e("someID").gEBCN("theClassName","optionalTagName") <-- returns
    > array, always, could be empty array.
    > $e("someID").gFEBCN("theClassName","optionalTagName") <-- returns
    > *one* element, or null
    >
    > latest snapshots:
    >
    > http://ibdom.svn.sourceforge.net/viewvc/ibdom/core/js/ibdom.compresse...
    > (14KB)http://ibdom.svn.sourceforge.net/viewvc/ibdom/core/js/ibdom.js?view=m...
    > (25KB)
    >
    > good luck :)
    >
    > On Jun 5, 7:28 am, wrote:
    >
    > > On 1 Jun, 10:32, "ChrisHolland@InternetBrands" <>
    > > wrote:

    >
    > > > i would echo Darko's recommendation to look at
    > > > element.cloneNode(true);

    >
    > > > It gets hairy because you need to get to "element" in the first place,
    > > > which would be some sort of template which you need to clone. But you
    > > > really want to refrain to cloneNode() anything that has an "id"
    > > > attribute because the id attribute will also get cloned, and there
    > > > should only ever be one id on a document. So you'd have to remove the
    > > > id attribute.

    >
    > > > To deal with this type of tedium, I recently released a small, simple
    > > > JS library aimed at making it easy to "do stuff with the DOM". One key
    > > > underlying component is the ability to define one or multiple
    > > > "template stashes" in a given document. A Stash is simply any element
    > > > such as a "div" that contains "templates" as one of its "class"
    > > > attribute values, such as:

    >
    > > > <div class="templates">
    > > > .... all your templates go here
    > > > </div>

    >
    > > > Inside of it you can have your <li> block.as a template, as such:

    >
    > > > <div class="templates" style="display:none">
    > > > <!-- in this section, there should never be an "id" attribute, EVER
    > > > -->
    > > > <!-- because this section contains templates and templates are meant
    > > > to be cloned -->
    > > > <!-- ibdom lets you retrieve template clones based on class
    > > > attribute values. -->

    >
    > > > <li class="sectionTemplate"> <!-- a template is identified by a
    > > > class value. -->
    > > > <div class="section_header"> <!-- id set at post-
    > > > processing if you still need it. -->
    > > > <label for="NO_VALUE_YET" class="title_label">Section
    > > > Title:</label>
    > > > <input type="text" name="NONAME_YET" size="50"
    > > > class="section_title_text_input"/>
    > > > </div>
    > > > ....
    > > > <!-- the rest of your HTML for a given section goes here.-->
    > > > <!-- use class values to identify various elements so you can
    > > > access them during template processing:
    > > > templateClone.gFEBCN("section_header"); will return the same
    > > > element that document.getElementById("header_1");
    > > > would have otherwise returned before you'd removed all "id"
    > > > attributes from your HTML.

    >
    > > > gFEBCN stands for getFirstElementByClassName
    > > > -->

    >
    > > > </li>
    > > > </div>

    >
    > > > back in script-land, IBDOM defines a utility function called "$t()".

    >
    > > > You simply pass it a class value for the template you're looking for,
    > > > and an optional tag name. It will return A CLONE of the template. You
    > > > can then "appendChild()" this clone anywhere in your document:

    >
    > > > Here's some sample code for your situation:

    >
    > > > templateIdNumber = 1;
    > > > myTemplateClone = $t("sectionTemplate");
    > > > myTemplateClone.setAttribute("id","section_" + templateIdNumber);
    > > > /* now we have a template, we want to set various attributes based on
    > > > templateIdNumber */
    > > > /* IBDOM has a few methods to help you out with that! here goes: */
    > > > myTemplateClone.gFEBCN("section_header").setAttribute("id","section_"
    > > > + templateIdNumber);
    > > > myTemplateClone.gFEBCN("title_label").setAttribute("for","section_" +
    > > > templateIdNumber + "_title");
    > > > myTemplateClone.gFEBCN("section_title_text_input").setAttribute("id","secti on_"
    > > > + templateIdNumber + "_title");
    > > > myTemplateClone.gFEBCN("section_title_text_input").setAttribute("name","sec tion["+templateIdNumber
    > > > +"][section_title]");
    > > > ... continue setting other attributes for various elements.
    > > > ... still pretty tedious but at least you're only setting attributes.
    > > > ... and you can tweak your html more easily if needed, as long as you
    > > > retain the class attributes.

    >
    > > > if you weren't dynamically setting "id" and "name" attributes all over
    > > > the place, you could use "data:" markers in your template for most
    > > > everything else, which would have gotten injected with
    > > > myTemplateClone.populate(someConfigObject);

    >
    > > > the populate() method is good for just about all attributes except
    > > > "id" which we can't have in a template environment, and "name" because
    > > > of some weird Win/IE issue for which i need to find time to work
    > > > around.

    >
    > > > As others mentioned, you can have an ajax call return a template
    > > > freshly populated by the server. That's an additional roundtrip to the
    > > > server, but it sounds like it would have limited performance hit.

    >
    > > > If you do want to try out IBDOM, it's at:http://ibdom.sourceforge.net/

    >
    > > > Feel free to ping me with Qs/thoughts/suggestions. I'm very close to
    > > > an 0.2 release which will go live in one of our customer-facing apps
    > > > in a few days, once it passes QE. ibdom.js in the SVN repository has
    > > > the latest stable version.

    >
    > > > On May 31, 5:33 am, wrote:

    >
    > > > > On 31 May, 13:06, RobG <> wrote:

    >
    > > > > > On May 31, 8:51 pm, wrote:

    >
    > > > > > > I'm currently coding a CMS system for a site which includes the
    > > > > > > feature to create multiple sections inside a page. To add each of
    > > > > > > these new sections I'm using DOM with AJAX to save, but I've got a
    > > > > > > pretty div for each section which needs to be created on the click of
    > > > > > > a button. Here's a sample of the code, I won't post it all because
    > > > > > > it's quite big...

    >
    > > > > > > function addSection() {

    >
    > > > > > [... ~90 lines of code & HTML trimmed ...]

    >
    > > > > > > I'm pretty new to this DOM lark, I've just pieced everything together
    > > > > > > from tutorials across the internet, so I'm wondering, is there a more
    > > > > > > efficient way of doing this or anything anyone can suggest?

    >
    > > > > > Do it on a server and send HTML to the client, it tends to be *much*
    > > > > > more efficient.

    >
    > > > > > As for optimising client-side code, you have plenty of scope for
    > > > > > that. :) Heed the advice given here:

    >
    > > > > > <URL:http://homepage.mac.com/rue/JS_Optimization_Techniques/>

    >
    > > > > Thanks for this, Rob. So are you saying it would be quicker to do it
    > > > > server-side and sending back the response with AJAX? This could be an
    > > > > idea as I have an issue where the ID of the section needs to be
    > > > > generated at some point, but there would be no way of cancelling and
    > > > > saving the index, not sure how much of an issue this is. This will
    > > > > also be handy for browser compatibility, although touch wood so far it
    > > > > has been OK.

    >
    > > Thanks for that, it's very informative.

    >
    > > The problem with cloneNode(true), as you mentioned, is the cloning of
    > > the elements with their class names. I think the approach I will
    > > adopt now will be using cloneNode, setting the ID of the parent node
    > > and then instead of using the id's inside, just use a
    > > getElementsByClassName to distinguish the details inside. This seems
    > > to be the best option. Thanks for all your input.


    Yeah, thanks. I've been looking at prototype for a while so here's a
    chance to use it! Thanks for all your help
    , Jun 7, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Carlo Filippini
    Replies:
    3
    Views:
    397
  2. Helixpoint
    Replies:
    4
    Views:
    411
    John Saunders
    Aug 1, 2003
  3. Mark
    Replies:
    3
    Views:
    2,038
    John Saunders
    Nov 12, 2004
  4. Tarren
    Replies:
    2
    Views:
    10,256
    Brock Allen
    Sep 29, 2005
  5. has

    Quicker way to copy()?

    has, Jun 9, 2004, in forum: Python
    Replies:
    0
    Views:
    275
Loading...

Share This Page