Oh God How Did This Get Here, I Am Not Good With Computers

Senseless rambling about .NET, SQL and Application Development

  Home  |   Contact  |   Syndication    |   Login
  6 Posts | 0 Stories | 12 Comments | 0 Trackbacks

News

All statements in this blog are my personal opinions and do not reflect the opinions of my employer.

Locations of visitors to this page

Add to Google Reader or Homepage

 Subscribe

Tag Cloud


Archives

Post Categories

Suppose you want your users to submit a list of items through your web page. These items could be inputted through many means such as a text box, combobox, listbox, etc. There are many ghetto solutions you could use to implement this like comma delimited lists or multiple postbacks. There are however much more elegant, and suprisingly easier ways of doing this using javascript. As an example we will start with an input box with a link below it that allows you to spawn several more input boxes. In addition, each spawned input box comes with its own delete link, allowing the user to remove items if they choose to. Each input box is given a unique incremented ID that can be easily accessed later on through postback.

Here's the javascript that makes it work:
<script type="text/javascript" language="javascript">     
var software_number = 1;
function addSoftwareInput()
{
var d = document.createElement("div");
var l = document.createElement("a");
var software = document.createElement("input");
software.setAttribute("type", "text");
software.setAttribute("id", "software"+software_number);
software.setAttribute("name", "software"+software_number);
software.setAttribute("size", "50");
software.setAttribute("maxlength", "74");
l.setAttribute("href", "javascript:removeSoftwareInput('s"+software_number+"');");
d.setAttribute("id", "s"+software_number);

var image = document.createTextNode("Delete");
l.appendChild(image);


d.appendChild(software);
d.appendChild(l);

document.getElementById("moreSoftware").appendChild(d);
software_number++;
software.focus();
}

function removeSoftwareInput(i)
{
var elm = document.getElementById(i);
document.getElementById("moreSoftware").removeChild(elm);
}
</script>
And the tiny amount of html to get it to show up:
<input type="text" name="software0" id="software0" size="50" maxlength="74" />                
<div id="moreSoftware"></div> <div id="moreSoftwareLink" style="display:block;"><a href="javascript:addSoftwareInput();">Add Another Item</a></div>
You can paste the above HTML and javascript into your own webpage to see it in action.

In some languages such as PHP, accessing these dynamically created elements after postback isn't an issue, it's a simple matter of using a for loop to iterate through each element. However this becomes a challenge if you're using ASP.NET. The problem is that these new elements are created on the client side, and once submitted, the server no longer sees them. The workaround is to use javascript to collect the contents of each element and stuff them into a hidden element in a delimited format. In the case of ASP.NET this hidden element would have to be declared within the page that is originally sent to the client. Then on postback we can collect the contents of this single element, break up each list item by the delimiter and deal with them as we normally would. First we create our hidden attribute to dump our item contents on submit:
<input id="ninjainput" type="hidden" name="ninjainput" />
We'll call it "ninjainput", because it's stealthy and mysterious, like a ninja. Next, we'll insert an additional javascript function that will populate our ninjainput when the user submits the page.
function populateStaticInput()
{
var n = document.getElementById("ninjainput");
var allsoftware = "";
for( var i = 0; i < software_number; i++)
{
var currentele = document.getElementById("software"+i);
if(currentele != null)
{
if(currentele.value.length > 0)
{
if(currentele.value.length > 74)
currentele.value = currentele.value.substring(0, 74);
allsoftware = allsoftware + "~<>~" + currentele.value;
}
}
}
n.value = allsoftware;
}
Notice that we are delimiting each item with a "~<>~". Make sure to add this attribute to your form tag: onsubmit="javascript:populateStaticInput();" This way the javascript will run and populate our ninjainput control before the page is sent to the server. Lastly, we will need a function (the example below is in C#) that will cut up the submitted list of items into a usable format, in this case an array of strings.
public string[] GetAllSoftwareInList(string rawsoftlist)
{
string[] asoft = rawsoftlist.Split("~<>~".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries);
return asoft;
}
And there you have it, the user doesn't have to endure multiple postbacks or keep track of a comma delimited list. It's presented in an organized and intuitive manner to the user and not too painful to implement for the developer.
posted on Monday, November 26, 2007 3:59 PM

Feedback

# re: Dynamically Creating HTML Elements Using Javascript 11/27/2007 2:43 PM Joel
Due to many bugs in IE, your code will not work.

http://webbugtrack.blogspot.com/2007/10/bug-235-createelement-is-broken-in-ie.html

On the link above, you'll find that attempting to set the name attribute on the input element will fail in IE (because IE doesn't support the .setAttribute() method correctly (more details at this link):

http://webbugtrack.blogspot.com/2007/08/bug-242-setattribute-doesnt-always-work.html

This is the true reason why the ASP isn't seeing the params on the request, because they never get assigned a name.

The good news, is there is a workaround for it! Its a very ugly hack, but it works!

Best of luck!

Joel



# re: Dynamically Creating HTML Elements Using Javascript 5/28/2008 3:43 AM MaheshJana
good to see this code. this is very help for me. and i want to insert an image in that text field.So i need dynamically creating id for every image in text field . please help

# re: Dynamically Creating HTML Elements Using Javascript 9/16/2008 4:30 AM chiranjita
chiiiii

Post Feedback

Title:
Name:
Email: (never displayed)
Url:
Comments: 
Please add 2 and 3 and type the answer here: