Search code examples
javascriptprototypejs

prototype setAttribute() not working with $$() selector


I want to change the button onclick function inside a div. The HTML code is as bellow

<div class="buttons-set" id="payment-buttons-container">
    <button type="button" class="button" onclick="payment.save()" id="payment_button"></button>
</div>

I am using the following prototype to change the onlick function payment.save() to something else.

if(payment_method=='gate') {
   var e = $$('div#payment-buttons-container button.button');
   e.setAttribute('onclick','return false;'); // not working
} else {
    var e = $$('div#payment-buttons-container button.button');
    e.setAttribute('onclick','payment.save();'); // not working
}

Which is not working and saying "Uncaught TypeError: Object [object HTMLButtonElement] has no method 'setAttribute'"But when i am using this code by taking the id of the button statically, than its working

if(payment_method=='gate') {
    $('payment_button').setAttribute('onclick','return false;');// Works
}
else {
    $('payment_button').setAttribute('onclick','payment.save();');// Works
}

Where "payment_button" is the ID of the button which i taken.


Solution

  • The problem is that $$() returns a list of elements that match the CSS selector

    try this if you just want the first element the matches the selector

    if(payment_method=='gate') {
       var e = $$('div#payment-buttons-container button.button')[0];
       e.setAttribute('onclick','return false;'); // not working
    } else {
       var e = $$('div#payment-buttons-container button.button')[0];
       e.setAttribute('onclick','payment.save();'); // not working
    }
    

    if you want to apply it to all the elements that the CSS selector matches do it this way using the invoke() method

    if(payment_method=='gate') {
       $$('div#payment-buttons-container button.button').invoke('writeAttribute','onclick','return false;');
    } else {
        $$('div#payment-buttons-container button.button').invoke('writeAttribute','onclick','payment.save();'); // not working
    }
    

    the reason I used writeAttribute() instead of setAttribute() is that writeAttribute() is the PrototypeJS method and will work across all the browsers that PrototypeJS supports, setAttbribute() is the standard method that is not always available.