DOM object assignment

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Peter  Nofelt

    DOM object assignment

    Hey all,

    I am running into an issue. My situation is that I wish to copy the
    contents of one listbox to an array, sort it by innerText value, and
    write the sorted options into a new listbox.

    Currently I am able to do this by assigning the innerText of the old
    listbox to the innerText of the new listbox. I find this tedious as i
    have some other attributes that I eventually would need to copy over to
    the new listbox.

    INSTEAD, I would like to assign the <option> object of the old listbox
    to the new listbox object by object, but when i do this I get an object
    assignment error.

    Below is a stripped down demo that you can run to see whats going on. A
    few things to note:

    o The function CHashTable is a class providing psudeo hastable
    functionality that I use as a map to reference the <option>'s from the
    old listbox.
    o I am not concerned about having this code be cross-browser compliant,
    the client is only working in an IE enviorment (due to the applications
    reliance on active X controls).

    Below is the code, to run it just click on the button. I commented out
    the debugger keywords. Also, the most important function to node is
    writeAsElement( ) considering that this is where I am having issues.

    Cheers,
    Peter


    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <html>
    <head>
    <link rel="stylesheet " type="text/css" href="style.css ">
    <title></title>
    <meta name="GENERATOR " content="Micros oft Visual Studio .NET 7.1">
    <meta name="vs_target Schema"
    content="http://schemas.microso ft.com/intellisense/ie5">
    </head>
    <body>
    <script type="text/javascript">



    /////////////////////////////////////////
    // Function class for providing psudo-hashtable functionality
    function CHashTable(){
    var m_arryHashTable = new Array();

    // function that allows the user to add a specific key
    // and value to the hash table
    this.addToLooku p = function(p_strN ewLookupKey, p_lngValue){
    m_arryHashTable[p_strNewLookupK ey] = p_lngValue;
    }

    // function to retun if a specific hash function exists
    this.checkLooku p = function(p_strL ookupKey){
    if(m_arryHashTa ble[p_strLookupKey] === undefined)
    return false;
    else
    return true;
    }

    this.hashSize = function(){retu rn m_arryHashTable .length; }

    // function to return a value the value at a specific hash key value
    this.getLookupV alue = function (p_strLookupKey ){
    return m_arryHashTable[p_strLookupKey];
    }
    }


    function allyo(){
    //debugger;
    var oSwap = new CSortList();
    oSwap.sendFormR eference();
    oSwap.writeAsEl ement();
    }

    function CSortList(){
    var m_docHtmlOption s;
    var m_hash = new CHashTable();
    var m_array = new Array();
    var m_num = new Number();

    this.swapOldOpt ionsWithNew2 = function(p_hash , p_sort){
    var docHtmlOptionsT emp = document.create Element("option s");
    for (var i = 0; i < p_sort.length; i++)
    docHtmlOptionsT emp.option[i] = p_hash.getLooku pValue(p_sort[i])
    return docHtmlOptionsT emp
    }

    this.writeAsEle ment = function(){
    //debugger;

    var docHtmlSelect = document.create Element("select ");

    /////////////////////////////////////////
    /// What currently works
    docHtmlSelect[0] = document.create Element("OPTION ");
    docHtmlSelect[1] = document.create Element("OPTION ");
    docHtmlSelect[0].innerText = "wawawewow" ;
    docHtmlSelect[1].innerText = "asdfewow";

    docHtmlSelect[0].innerText =
    m_hash.getLooku pValue(m_array[0]).innerText;
    docHtmlSelect[1].innerText =
    m_hash.getLooku pValue(m_array[1]).innerText;
    /////////////////////////////////////////
    /////////////////////////////////////////

    /////////////////////////////////////////
    /// What i would like to work
    /*
    docHtmlSelect[0] = document.create Element("OPTION "); // may not need
    this
    docHtmlSelect[1] = document.create Element("OPTION "); // may not need
    this

    docHtmlSelect[0] = m_hash.getLooku pValue(m_array[0]);
    docHtmlSelect[1] = m_hash.getLooku pValue(m_array[1]);
    */
    docHtmlSelect.i d = "hardSelect ";
    //docHtmlSelect.s tyle.display = "none";
    document.body.a ppendChild(docH tmlSelect);
    }


    this.sendFormRe ference = function()
    {
    //debugger;
    var selectToSort = document.getEle mentById("formI D")

    var selectLength = selectToSort.le ngth;
    var selectOptions = selectToSort.op tions;

    // store options into lookup table, reference via text element
    var oHashOptions = new CHashTable();
    for (var i = 0; i< selectLength; i++)
    oHashOptions.ad dToLookup( selectOptions[i].text, selectOptions[i])

    // push the text element of each option into an array
    var arryOptionsToSo rt = new Array();
    for (var i = 0; i< selectLength; i++)
    arryOptionsToSo rt.push(selectO ptions[i].text)
    // sort array
    arryOptionsToSo rt.sort();

    var docHtmlOptionsT emp = new document.create Element("option s");
    for (var i = 0; i < arryOptionsToSo rt.length; i++)
    docHtmlOptionsT emp[i] =
    oHashOptions.ge tLookupValue(ar ryOptionsToSort[i])

    m_hash = oHashOptions;
    m_array = arryOptionsToSo rt;
    m_docHtmlOption s = docHtmlOptionsT emp;
    m_num = 3;
    }
    }

    </script>
    <p><br>
    <!--<button>hey there</button>-->
    <select size="5" name="selectIdN ame" id="formID">
    <option value="value1"> cvalue1</option>
    <option value="value3"> kvalue3</option>
    <option value="value2"> avalue2</option>
    <option value="value3"> bvalue3</option>
    </select>
    <button onclick="allyo( );" ID="Button1">cl ickme</button>
    </body>
    </html>

  • Fred Oz

    #2
    Re: DOM object assignment

    Peter Nofelt wrote:[color=blue]
    > Hey all,
    >
    > I am running into an issue. My situation is that I wish to copy the
    > contents of one listbox to an array, sort it by innerText value, and
    > write the sorted options into a new listbox.[/color]
    [...]

    I'd suggest the following approach:

    Concatenate the option value and text with a delimiter
    Put them into an array
    Sort the array
    Create a new select with options based on the new sorted array
    Split the value and text based on the delimiter used above

    The following is only lightly tested, but demonstrates the method. You
    may have an issue with delimiters, but the choice is up to you. Also,
    you have great flexibility with the sort function to sort any way you
    want. If you want to sort on text rather than value, put it first in
    the array elements.

    Have fun.

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    <head>
    <title>Change Data2</title>
    <script type="text/javascript">

    function allyo(sel) {
    var arr = [];
    for (var i=0; i<sel.options.l ength; i++) {
    arr.push(sel.op tions[i].value + '.' + sel.options[i].text);
    }
    arr = arr.sort();

    // Now create the new select element
    oSel = document.create Element('SELECT ');

    // Create the options and append them
    for (var j=0; j<arr.length; j++) {
    oObj = document.create Element('OPTION ');
    oObj.value = arr[j].split('.')[0];
    oObj.text = arr[j].split('.')[1];
    oSel.appendChil d(oObj);
    }
    oSel.size = '5';
    sel.parentNode. appendChild(oSe l);
    }

    </script>
    </head>
    <body>
    <p><br>
    <form action="">
    <select size="5" name="selectIdN ame" id="selectIdNam e">
    <option value="value1"> cvalue1</option>
    <option value="value3"> kvalue3</option>
    <option value="value2"> avalue2</option>
    <option value="value3"> bvalue3</option>
    </select>
    <input type="button" onclick="allyo( this.form.selec tIdName);"
    value="click me">
    </form>
    </body>
    </html>


    --
    Fred

    Comment

    • Michael Winter

      #3
      Re: DOM object assignment

      On 20 Dec 2004 13:55:08 -0800, Peter Nofelt <pcnofelt@gmail .com> wrote:

      I presume that Fred has helped with the original problem, so I'll
      concentrate elsewhere.

      [snip]
      [color=blue]
      > // Function class for providing psudo-hashtable functionality
      > function CHashTable(){[/color]

      I thought you might like to know that your hashtable is broken.
      [color=blue]
      > var m_arryHashTable = new Array();[/color]

      The first thing to note is that the length property of an array object
      only changes if you assign values to an "array index" - I'll explain what
      that is in a moment.

      As you seem to understand, when you use square brackets with any
      object[1], the expression is used to look up a value. In fact, *every*
      expression (even a numeric literal) is evaluated, converted to string, and
      used as a property name. The only exception is with array objects.

      When the internal [[Put]] method (used to assign to property values) of an
      array is called, it performs a test on the property name. It attempts to
      convert the (string) property name to a (32-bit) number, then back to a
      string. If the number is less than (2^32)-1, and the string values before
      and after the conversion match exactly, the property name is considered an
      array index. So:

      '10' -> 10 -> '10' '10' == '10' therefore an array index
      'ff' -> NaN -> 'NaN' 'ff' != 'NaN' therefore not an array index
      '01' -> 1 -> '1' '01' != '1' therefore not an array index

      Any property name can be used with an array object, but only array
      indicies will ever change the length property. The obvious impact of this
      is that your hashSize method will fail entirely unless every key is
      considered an array index - you have to track addition and removal
      operations yourself. The other, not so obvious problem, is that you don't
      distinguish between properties that might originate from the object
      prototype, and those added as a key.

      Every object has a predefined set of properties. Some implementations may
      include more than others. It's quite feasible that code may call

      hash.checkLooku p('pop')

      on your hashtable. In this instance, checkLookup would return true even
      though the code may not have added its own key named 'pop' because array
      objects have a pop method. There are two simple ways to lessen the impact
      of this problem:

      1) Use a "plain" object to hold the properties, not an array.
      Objects have fewer predefined properties so there's less chance
      of any name collisions. Moreover, as you're not using any array
      features, its more efficient to use an object.
      2) Mutate the key before using it. You could easily add a unique
      sequence of characters, such as '_ ' (yes, the space is
      intentional) to the property name. It's highly unlikely that an
      implementation will expose properties like that.

      There are several hashtable implementations in the archives of this group
      that vary from the quick and dirty to the fully-featured and robust. See
      <URL:http://groups.google.c om/groups?q=group% 3Acomp.lang.jav ascript+%22hash +table%22+%7C+h ashtable>.

      [snip]
      [color=blue]
      > this.checkLooku p = function(p_strL ookupKey){
      > if(m_arryHashTa ble[p_strLookupKey] === undefined)
      > return false;
      > else
      > return true;
      > }[/color]

      return undefined !== m_arryHashTable[p_strLookupKey];

      or

      return 'undefined' != m_arryHashTable[p_strLookupKey];

      is preferable.

      [snip]
      [color=blue]
      > function CSortList(){
      > var m_docHtmlOption s;
      > var m_hash = new CHashTable();
      > var m_array = new Array();[/color]

      You might want to consider whether it's worth initialising these methods
      as you're only going to overwrite them.
      [color=blue]
      > var m_num = new Number();[/color]

      This is certainly unnecessary. Here you're creating an immutable Number
      object with a value of zero.

      var m_num = 0;

      would be more efficient.
      [color=blue]
      > this.swapOldOpt ionsWithNew2 = function(p_hash , p_sort){
      > var docHtmlOptionsT emp = document.create Element("option s");[/color]

      There's no such thing as an OPTIONS element.
      [color=blue]
      > for (var i = 0; i < p_sort.length; i++)
      > docHtmlOptionsT emp.option[i] = p_hash.getLooku pValue(p_sort[i])
      > return docHtmlOptionsT emp
      > }[/color]

      As this method doesn't access any private data, it would be better to add
      it to the prototype of CSortList. That goes for any method in a similar
      situation.

      [snip]
      [color=blue]
      > this.sendFormRe ference = function()[/color]

      [snip]
      [color=blue]
      > var docHtmlOptionsT emp = new document.create Element("option s");[/color]

      Again, no OPTIONS element. Also, the new operator is unnecessary.

      [snip]
      [color=blue]
      > <p><br>[/color]

      You should use padding or a margin rather than a BR element.

      Good luck,
      Mike


      [1] This could cover anything. Objects, functions and arrays are obvious
      examples, but the other types - boolean, date, number, regexp, string -
      display this ability, too.

      --
      Michael Winter
      Replace ".invalid" with ".uk" to reply by e-mail.

      Comment

      Working...