PDA

View Full Version : Custom Objects and appendChild



Torin Mai
05-30-2007, 06:04 PM
I'm working on a project that involves alot of SELECTS that need to be all dynamically modified and even added to the page dynamically. The current methods for the SELECT object (such as it is) in the DOM are limited and there's enough cross-platform problems to make it a headache, so I'm creating a new SELECT object. What I want is to be able to use syntax similar to when using the OPTION object (ie, new Option (text, value); option.id = "something"). Something to hide all the XML behind the scenes.

I'm doing fine so far, but the problem I've hit is this: if I have say:
somediv.appendChild(my_select_object);

The object doesn't show up where I'd like it to (because the select itself isn't actually getting appended to anything, but I would rather like to be able to keep as much like a built in object as possible. Can anyone think of a way to get it so that the statement above would actually work? or is it not possible
Much appreciated,
-Mike

(NOTE: part of the reason for making a new object is because there are extra variables that are needed.)

jscheuer1
05-30-2007, 06:24 PM
I think we would need more to go on. Have you seen this:

http://www.easy-designs.net/articles/replaceSelect/

It is not ideal, but will work for many situations and can be added to for greater utility. A discussion of this, for a particular project, is here:

http://www.dynamicdrive.com/forums/showthread.php?t=18699

Torin Mai
05-30-2007, 07:19 PM
Hmm. The replacementSelect seems geared more toward making it look good and that's not an issue for me. To show you what I'm talking about, below is an example and what I've gotten working so far.
SelectObj.js

function Select (myid, name, size, givenOptions)
{

/* Create the SELECT. After this we can add the other stuff whenever we
* happen to want to.
*/
var mySelect = document.createElement("select");

if ( ! (typeof myid == 'undefined' || myid == "") )
mySelect.id = myid;

if ( ! (typeof name == 'undefined' || name == "") )
mySelect.name = name;

if ( ! (typeof size == 'undefined' || size == "") )
mySelect.size = size;

/* This function replaces the current options with those given as input to
* the function. Takes as input an array of options as returns from the
* SELECT.options method.
*/
this.copyOptions = function (optionsToCopy)
{
opts = mySelect.options;
opts.length = 0;

for (var i = 0; i < optionsToCopy.length; i++)
{
opts[opts.length] = new Option(optionsToCopy[i].text, optionsToCopy[i].value);
}

}

if ( typeof givenOptions != 'undefined' )
{
this.copyOptions(givenOptions);
}




/* Inserts an option element into select element at the given position. The position
* can either be expressed as an number in the range [-1,length] where length
* is the number of option elements already in the list, or as a reference to an element
* in the list. Values of -1, length, and null append the item. If given a reference,
* the new option element is inserted before the referenced element. If the position is
* omitted, the option will be appended.
* Upon return, boolean true indicates success, with false signifying failure.
* Tailored from code at http://www.dynamicdrive.com/forums/showpost.php?p=91923&postcount=4
*/
this.insertOption = function (optionElement, position)
{
if (typeof position == 'number')
if (position == -1) position = null;
else position = selectElement.options[position];
else if (typeof position == 'undefined') position = null;
if (selectElement.insertBefore)
{
selectElement.insertBefore(optionElement, position);
return true;
}
return false;
}

/* This is a function that takes the minimum size and makes sure it's valid
* and then returns the modified and checked over value to the caller. Any
* non-valid entry will result in -1 being returned (-1 indicates that the
* size adjusting feature is not to be used.
*/
var adjustMinimum = function (min)
{
if (typeof min == 'undefined')
min = 0;
else
{
min = parseInt(min);
if (isNaN(min) || min < 1)
min = 0;
}

return min;
}

/* Appends the SELECT to the given element. This will be until I figure out
* a way for it to work like the option object does (ie, you append it and
* it shows up
*/
this.attachTo = function (parent)
{
parent.appendChild(mySelect);
return parent;
}

/* Removes the SELECT from it's parent if it has one. As with the attach
* method, this is to work around that problem I'm having with the adding
* the object but the SELECT not displaying
*/
this.remove = function ()
{
parent = mySelect.parentNode;
if (parent != null)
parent.removeChild(mySelect);
return parent;
}

}

test page:

<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<title>Hello!</title>
<script type="text/javascript" src="SelectObj.js">
</script><!-- -->

<script type="text/javascript">
// var num = 1;

var selObj

function ahoy()
{

if ( ! ( document.getElementById("myid") ) )
{
sel1 = document.getElementById("sel1");
selObj = new Select ("myid","myname", 5, sel1.options);
selObj.attachTo(document.getElementById("div1"));
}
else
{
p = selObj.remove();
alert("selObj's Parent was "+p.id);
}


}
</script>

</head>

<body>

<div id="div1">
<select id = "sel1" size="3"><option>option 1</option><option>option 2</option><option>option 3</option></select>
<select id = "sel2" size="3"><option>option 4</option><option>option 5</option><option>option 6</option></select>
</div>


<p><br /><input type="button" value="press" onclick="ahoy()" /></p>

</body>

</html>

One of the key features I want to include is the ability to make the list expand as the number of options increases and shrink as they decrease. It also seems like making an object is the easiest way to bind the functions that will move the options around and add and remove them to the select itself.

Again, what I'm wondering is if it is possible to set it so that it gets treated like any other page element for appendChild.

Actually, I was fooling around and I found that if I do var x = new Select() it tells me that "Select is not defined". So perhaps another question: the ideal ideal solution would be to just add the functionality I want to an actual already existing select object, but to my knowledge, such an object has to have a constructor while Select doesn't seem to have one. Can I create a constructor for the predefined Select object?

Sorry it's so long.
Thanks,
-Mike

riptide
06-01-2007, 02:46 PM
um....I never had a cross browser problem with using create.element and append.child

tell me why this is not working for you.

jscheuer1
06-01-2007, 03:43 PM
um....I never had a cross browser problem with using create.element and append.child

tell me why this is not working for you.

When I have more time, I will try to go over this one in more detail, but to answer your question, with selects and their options, there are properties. These vary in how they are perceived in the various browsers. For example, we have select.options.length. When appending or removing elements (options) from a select, this property doesn't automatically adjust as expected in all browsers. This can lead to phantom options. I haven't looked into this with as much detail with lists, but I imagine a similar thing could happen with lists and their list items. When working with selects, I have found that specifically setting the options.length property (in addition to whatever other changes one is making to the select element) is sometimes required.