element attribute affectation behaves like a move instead of a copy

Discussion in 'Javascript' started by Mounir, Sep 18, 2006.

  1. Mounir

    Mounir Guest

    Hi,

    Assume that right and left are multiple select elements. It's about the
    following line :

    right.options=left.options[j];

    It copies the content of left.options[j] into right.options, but
    *removes* the content of the first one !

    It's hard to google with relevant keywords. Do you know if it's a
    normal behaviour of Javascript ?

    Tested on Firefox 1.5.x/Windows.

    Regards,

    --
    Mounir.
    Mounir, Sep 18, 2006
    #1
    1. Advertising

  2. Mounir

    Paul Guest

    Mounir wrote:
    > Hi,
    >
    > Assume that right and left are multiple select elements. It's about the
    > following line :
    >
    > right.options=left.options[j];
    >
    > It copies the content of left.options[j] into right.options, but
    > *removes* the content of the first one !
    >
    > It's hard to google with relevant keywords. Do you know if it's a
    > normal behaviour of Javascript ?


    Not really a matter of JavaScript but, of the particular DOM being
    manipulated by the javascript. I see the behavior you described in
    Firefox but, in IE6 it simply removes from the right list.

    > Tested on Firefox 1.5.x/Windows.
    >
    > Regards,
    >
    > --
    > Mounir.

    What is it that you are actually trying to do ?
    Paul, Sep 18, 2006
    #2
    1. Advertising

  3. Mounir

    Mounir Guest

    > > right.options=left.options[j];

    First, I apologize not have given an HTML sample with my message.

    Paul wrote :
    > Not really a matter of JavaScript but, of the particular DOM being
    > manipulated by the javascript. I see the behavior you described in
    > Firefox but, in IE6 it simply removes from the right list.


    What ? You mean it doesn't even perform the affectation ?

    > What is it that you are actually trying to do ?


    You know, two multiple selection lists, with "Add", "Add All",
    "Remove", "Remove All" buttons, respectively to add from the first list
    to the second, to add all from the first list to the second, to remove
    one and remove all with same ways.

    The behavior of Firefox allows me to not create options instances
    (javascript command new Option()), so I wondered if it was indeed a
    normal behavior and not some bug in my source code. And as the target
    browser is Firefox, that's cool :)

    Thank you and regards,

    --
    Mounir
    Mounir, Sep 19, 2006
    #3
  4. Mounir

    Paul Guest

    Mounir wrote:
    > > > right.options=left.options[j];

    >
    > First, I apologize not have given an HTML sample with my message.
    >
    > Paul wrote :
    > > Not really a matter of JavaScript but, of the particular DOM being
    > > manipulated by the javascript. I see the behavior you described in
    > > Firefox but, in IE6 it simply removes from the right list.

    >
    > What ? You mean it doesn't even perform the affectation ?
    >
    > > What is it that you are actually trying to do ?

    >
    > You know, two multiple selection lists, with "Add", "Add All",
    > "Remove", "Remove All" buttons, respectively to add from the first list
    > to the second, to add all from the first list to the second, to remove
    > one and remove all with same ways.
    >
    > The behavior of Firefox allows me to not create options instances
    > (javascript command new Option()), so I wondered if it was indeed a
    > normal behavior and not some bug in my source code. And as the target
    > browser is Firefox, that's cool :)
    >
    > Thank you and regards,
    >
    > --
    > Mounir

    Ah, that is something I can work with :)
    See if this will work for you.

    <?xml version="1.0" encoding="utf-8" ?>
    <!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Select test</title>

    <style type="text/css">
    #selSwap fieldset{
    width: 30em;
    height: 10em;
    }
    #selSwap fieldset div{
    display:block;
    width: 30%;
    float:left;
    }
    #selSwap fieldset div input, select{
    margin-left: 1em;
    width: 90%;
    font-family: monospace;
    }

    #selSwap fieldset div input{
    height: 1.5em;
    margin-top: 0.5em;
    }
    #selSwap fieldset div select{
    height: 10em;
    }
    </style>


    <script type="text/javascript">
    function copy(selSrc,selDest){
    var opts = selSrc.options;
    for(var i=opts.length-1; i>=0; i--){
    if(opts.selected){
    selDest.appendChild(opts);
    }
    }
    }

    function copyAll(selSrc,selDest){
    var opts = selSrc.options;
    for(var i=opts.length-1; i>=0; i--){
    selDest.appendChild(opts);
    }
    }
    </script>

    </head>

    <body>

    <form action="#" id="selSwap">
    <fieldset>
    <legend>Swaping multiselect fun</legend>
    <div>
    <select multiple="multiple" name="left" id="left">
    <option value="1">Apple</option>
    <option value="2">Orange</option>
    <option value="3">Banana</option>
    <option value="4">Grape</option>
    </select>
    </div>
    <div>
    <input type="button" value="Add"
    onclick="copy(this.form.left,this.form.right)" />
    <input type="button" value="Add All"
    onclick="copyAll(this.form.left,this.form.right)" />
    <input type="button" value="Remove"
    onclick="copy(this.form.right,this.form.left)" />
    <input type="button" value="Remove All"
    onclick="copyAll(this.form.right,this.form.left)" />
    </div>
    <div>
    <select multiple="multiple" name="right" id="right">
    <option value="a">red</option>
    <option value="b">orange</option>
    <option value="c">yellow</option>
    <option value="d">purple</option>
    </select>
    </div>
    </fieldset>
    </form>

    </body>

    </html>
    Paul, Sep 19, 2006
    #4
  5. Paul wrote:
    <snip>> <?xml version="1.0" encoding="utf-8" ?>
    > <!DOCTYPE html
    > PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    > "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    > <html xmlns="http://www.w3.org/1999/xhtml">

    <snip>
    > <input type="button" value="Add"
    > onclick="copy(this.form.left,this.form.right)" />

    <snip>

    You realise that the common HTML shortcut of referencing named and IDed
    elements as named properties of the FORM element is non-standard and
    should not be expected to be available in XHTML DOMs?

    You should probably be suing DOM standard - this.form.elments.left -
    (and similar) if you want to script XHTML DOMs.

    Richard.
    Richard Cornford, Sep 19, 2006
    #5
  6. Mounir

    Paul Guest

    Richard Cornford wrote:
    > Paul wrote:
    > <snip>> <?xml version="1.0" encoding="utf-8" ?>
    > > <!DOCTYPE html
    > > PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    > > "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    > > <html xmlns="http://www.w3.org/1999/xhtml">

    > <snip>
    > > <input type="button" value="Add"
    > > onclick="copy(this.form.left,this.form.right)" />

    > <snip>
    >
    > You realise that the common HTML shortcut of referencing named and IDed
    > elements as named properties of the FORM element is non-standard and
    > should not be expected to be available in XHTML DOMs?
    >
    > You should probably be suing DOM standard - this.form.elments.left -
    > (and similar) if you want to script XHTML DOMs.
    >
    > Richard.

    True
    Paul, Sep 20, 2006
    #6
  7. Mounir

    RobG Guest

    Paul wrote:
    > Mounir wrote:
    > > Hi,
    > >
    > > Assume that right and left are multiple select elements. It's about the
    > > following line :
    > >
    > > right.options=left.options[j];
    > >
    > > It copies the content of left.options[j] into right.options, but
    > > *removes* the content of the first one !


    The "=" character is an assignment operator, it assigns the value of
    the right hand side to the value of the left hand side - it isn't a
    "copy" operator.

    I guess your quandry is to work out what should happen when a reference
    to a DOM element is assigned to the value of another DOM element
    reference. To take much of the guesswork out of the equation, use DOM
    methods (preferably W3C) when DOM elements are involved.

    Of course you still need to test widely to ensure browsers are
    compliant with whatever standard you have used.


    > > It's hard to google with relevant keywords. Do you know if it's a
    > > normal behaviour of Javascript ?

    >
    > Not really a matter of JavaScript but, of the particular DOM being
    > manipulated by the javascript. I see the behavior you described in
    > Firefox but, in IE6 it simply removes from the right list.


    In IE, option elements and DOM just don't like each other, hence the
    use of new Option() when creating options rather than createElement. A
    DOM version of the above (i.e. to move an option from one select to
    another) would be:

    right.appendChild(left.options);


    Which works fine in Firefox & Safari at least, but not IE.


    --
    Rob
    RobG, Sep 20, 2006
    #7
  8. Mounir

    Mounir Guest

    > The "=" character is an assignment operator, it assigns the value of
    > the right hand side to the value of the left hand side - it isn't a
    > "copy" operator.


    Sure, actually i meant "it copies the reference" by "copies the
    content", so an assignment.

    > I guess your quandry is to work out what should happen when a reference
    > to a DOM element is assigned to the value of another DOM element
    > reference.


    Yes. But, please, do you have an explanation for this behavior ?

    > To take much of the guesswork out of the equation, use DOM
    > methods (preferably W3C) when DOM elements are involved.


    Thanks. http://www.w3.org/TR/REC-DOM-Level-1/ seems to be a good
    starting point.

    > Of course you still need to test widely to ensure browsers are
    > compliant with whatever standard you have used.


    Yeah, in first time, I will code for firefox (this is an intrant
    applications, which assumes that the browser client will be FF).

    > In IE, option elements and DOM just don't like each other, hence the
    > use of new Option() when creating options rather than createElement. A
    > DOM version of the above (i.e. to move an option from one select to
    > another) would be:
    > right.appendChild(left.options);
    >
    > Which works fine in Firefox & Safari at least, but not IE.


    I've just seen in the previous link a pretty method, in
    chapter 2: Document Object Model (HTML) Level 1 :

    void add(in HTMLElement element, in HTMLElement before)

    It seems to be from a set of specific HTML DOM methods. No problem to
    use it, right ?

    Regards,

    --
    Mounir.
    Mounir, Sep 20, 2006
    #8
  9. Mounir

    Mounir Guest

    > Ah, that is something I can work with :)
    > See if this will work for you.


    Thank you :)
    I hope you haven't passed much time to do.

    Interesting line :

    > selDest.appendChild(opts);


    So appendChild() *removes* the refererence of child from the previous
    parent node.

    Thanks !

    Regards,

    --
    Mounir
    Mounir, Sep 20, 2006
    #9
  10. Mounir

    Mounir Guest

    I wrote :
    > Yes. But, please, do you have an explanation for this behavior ?


    Err... in Paul's reply (xhtmI file) I think I got the answer... The
    assignment behaves like a DOM child moving (i.e. appendChild()). Right
    ?

    Regards,

    --
    Mounir
    Mounir, Sep 20, 2006
    #10
  11. Mounir

    Paul Guest

    Mounir wrote:
    > > Ah, that is something I can work with :)
    > > See if this will work for you.

    >
    > Thank you :)
    > I hope you haven't passed much time to do.
    >
    > Interesting line :
    >
    > > selDest.appendChild(opts);

    >
    > So appendChild() *removes* the refererence of child from the previous
    > parent node.


    Yes, the node can only be in one place

    > Thanks !
    >
    > Regards,
    >
    > --
    > Mounir
    Paul, Sep 20, 2006
    #11
  12. Mounir

    RobG Guest

    Mounir wrote:
    > I wrote :
    > > Yes. But, please, do you have an explanation for this behavior ?

    >
    > Err... in Paul's reply (xhtmI file) I think I got the answer... The
    > assignment behaves like a DOM child moving (i.e. appendChild()). Right


    I think the issue is that DOM objects are host objects, you can't
    presume their behaviour will be consistent with ECMAScript native or
    built-in objects.

    Consider:

    var objA = new Object();
    objA.firstChild = new Object();

    var objB = new Object();
    objB.firstChild = objA.firstChild;

    Outcome: objA.firstChild and objB.firstChild reference the same object.
    Now consider something similar in DOM:

    <div id="divA><div id="divC"></div></div>
    <div id="divB"><div id="divD"></div></div>

    <script type="text/javascript">
    var divA = document.getElementById('divA');
    var divB = document.getElementById('divB');

    divB.firstChild = divA.firstChild;

    </script>

    Outcome: ?

    In a pure ECMAScript context, divB.firstChild and divA.firstChild
    should both reference divC, the firstChild of divA. However, since a
    DOM element can only have one parent, we are left to guess whether[1]:

    1. divC replaces divD
    2. divD is moved down the DOM tree to make room for divC
    3. an error.

    If the intention was that divC is inserted as divB's first child, then:

    divB.insertBefore(divA.firstChild, divB.firstChild);


    is specified in the W3C DOM HTML spec as doing exactly that, no
    guesswork. If we'd wanted divC to replace divB's firstChild:

    divB.replaceChild(divA.firstChild, divB.firstChild);


    The lesson is that where you want a specific DOM behaviour, use DOM
    methods to achieve it. That principle can be applied to any host
    object - use the host provided methods to manipulate them.

    1. Determining the correct behaviour assumes whoever is reading the
    code knows that DOM objects/elements are involved, so naming
    conventions become very important. Using DOM methods makes it pretty
    clear that DOM objects are being manipulated (though if silliness was
    the order of the day, someone may have created their own native
    ECMAScript objects and methods with the same names as well known host
    objects/methods).


    --
    Rob
    RobG, Sep 21, 2006
    #12
  13. RobG wrote:
    <snip>
    > ... . Using DOM methods makes it pretty clear that DOM
    > objects are being manipulated (though if silliness was
    > the order of the day, someone may have created their own
    > native ECMAScript objects and methods with the same names
    > as well known host objects/methods).


    I don't know if that would necessarily be silliness. If the object was a
    flexible tree structure properties such as a - childNodes - array,
    first/lastChild -, - previous/nextSibling -, - parentNode -, and methods
    such as - appendChild -, - removeChild - and - insertBefore -, would be
    just the sorts of things it would need. One would hope that the
    Identifier to the left of the dots for these methods was named in a way
    that made it clear what type of object was being acted upon.

    Richard.
    Richard Cornford, Sep 21, 2006
    #13
  14. Mounir

    RobG Guest

    Richard Cornford wrote:
    > RobG wrote:
    > <snip>
    > > ... . Using DOM methods makes it pretty clear that DOM
    > > objects are being manipulated (though if silliness was
    > > the order of the day, someone may have created their own
    > > native ECMAScript objects and methods with the same names
    > > as well known host objects/methods).

    >
    > I don't know if that would necessarily be silliness. If the object was a
    > flexible tree structure properties such as a - childNodes - array,
    > first/lastChild -, - previous/nextSibling -, - parentNode -, and methods
    > such as - appendChild -, - removeChild - and - insertBefore -, would be
    > just the sorts of things it would need. One would hope that the
    > Identifier to the left of the dots for these methods was named in a way
    > that made it clear what type of object was being acted upon.


    Yes, quite right. I was thinking 'and gave them different behaviours'
    but didn't write it. If the intention is to emulate host objects, then
    using the same naming scheme is probably good idea (adding a
    'getElementById' method to the document object in (old) browsers that
    don't natively support it springs to mind).


    --
    Rob
    RobG, Sep 21, 2006
    #14
    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. mourad

    affectation, et copie

    mourad, Oct 22, 2003, in forum: C++
    Replies:
    6
    Views:
    436
    Shane Beasley
    Oct 22, 2003
  2. titi

    double signal affectation

    titi, Mar 7, 2007, in forum: VHDL
    Replies:
    1
    Views:
    409
    Mike Treseler
    Mar 7, 2007
  3. Jonathan Lee

    move, instead of copy, assignment

    Jonathan Lee, Aug 11, 2009, in forum: C++
    Replies:
    5
    Views:
    419
  4. Paul Rubin

    affectation in if statement

    Paul Rubin, Mar 16, 2010, in forum: Python
    Replies:
    11
    Views:
    618
  5. oyster
    Replies:
    1
    Views:
    221
    Peter Otten
    Jul 19, 2010
Loading...

Share This Page