Quicker way for DOM?

A

adam

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
 
D

Darko

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.
 
R

RobG

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/ >
 
A

adam

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.
 
C

ChrisHolland@InternetBrands

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, 8:51 pm, (e-mail address removed) wrote:
[... ~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:

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.
 
A

adam

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, 8:51 pm, (e-mail address removed) 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.
 
C

ChrisHolland@InternetBrands

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 :)



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
-->

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, (e-mail address removed) wrote:
On May 31, 8:51 pm, (e-mail address removed) 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.
 
A

adam

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 1 Jun, 10:32, "ChrisHolland@InternetBrands" <[email protected]>
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, (e-mail address removed) wrote:
On May 31, 8:51 pm, (e-mail address removed) 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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top