cubecart / v6

CubeCart Version 6
https://cubecart.com
71 stars 59 forks source link

Weird Javascript Result #3542

Closed bhsmither closed 3 months ago

bhsmither commented 3 months ago

In 2.cubecart.js, near line 538, there is:

product_image = $(this).find(':selected').attr('data-image');

This line is executed when there is a product option that is not a radio button when it gets changed.

In my experiments, this line assigns an undefined state to product_image.

This is my test code:

if($(this).attr('type')==='radio') { console.log("Radio");
    product_image = $(this).attr('data-image'); console.log('product_image = ' + product_image);
} else { console.log("Not Radio"); console.log('before_product_image = ' + product_image); console.log('before_product_image:checked = ' + $(this).find(':checked')); console.log($(this).find(':checked'));
    product_image = $(this).find(':checked').attr('data-image'); console.log('product_image = ' + product_image);
} console.log(typeof product_image);

I used :checked because it catches selectors as well as checkboxes and radios. But this is irrelevant to the problem.

The console logs this:

Not Radio
before_product_image = {empty string}
before_product_image:checked = [object Object]
Object { length: 0, prevObject: {…}, context: input#checkrad_nested_option_-45.nomarg.ui-checkboxradio.ui-helper-hidden-accessible, selector: ":checked" }
product_image = undefined
undefined

I do not understand why the object has length zero -- other than, perhaps, because this project involves applying a 'theme' to checkboxes, where the display of the actual checkboxes are being squeezed to nothing-ness (but not 'hidden').

I would imagine that a textbox would also trigger this because it (I guess?) has no :selected pseudo-attribute.

The problem reveals itself at line 540 where product_image.length is supposedly defined.

bhsmither commented 3 months ago

This conversation has some interesting info:

https://stackoverflow.com/questions/2204250/check-if-checkbox-is-checked-with-jquery
bhsmither commented 3 months ago

This seems to be working for me:

if($(this).is('input:radio, input:checkbox, input:hidden')) { /* textarea, input:text */
    product_image = $(this).is(':checked') ? $(this).attr('data-image') : '';
} else if ($(this).is('select')) {
    product_image = $('option:selected', this).attr('data-image');
}

It looks similar to the code in price_inc_option().

Text and textarea types of inputs are not included because there is no data-image in the template for these option types, even though admin seems to be able to accommodate.

abrookbanks commented 3 months ago

Thanks so much for this.