| @@ -54,8 +54,30 @@ | ||
| 54 | 54 | |
| 55 | 55 | // Execute once when script loads |
| 56 | 56 | addBasicNotificationCSS(); |
| 57 | 57 | |
| 58 | + /** | |
| 59 | + * Native range inputs cannot land on max when (max-min) is not a multiple | |
| 60 | + * of step (min=1, max=1000, step=10 stops at 991). Use a 1-unit step so | |
| 61 | + * the labeled maximum is a legal value. The visible min/max labels stay | |
| 62 | + * as configured in the widget. | |
| 63 | + */ | |
| 64 | + function alignRangeToLabeledMax(input) { | |
| 65 | + if (!input) { | |
| 66 | + return; | |
| 67 | + } | |
| 68 | + var min = parseFloat(input.min); | |
| 69 | + var max = parseFloat(input.max); | |
| 70 | + var step = parseFloat(input.step); | |
| 71 | + if (isNaN(min) || isNaN(max) || isNaN(step) || step <= 0) { | |
| 72 | + return; | |
| 73 | + } | |
| 74 | + if (((max - min) % step) === 0) { | |
| 75 | + return; | |
| 76 | + } | |
| 77 | + input.step = '1'; | |
| 78 | + } | |
| 79 | + | |
| 58 | 80 | // --- Shared Helper Functions --- (Moved here) |
| 59 | 81 | |
| 60 | 82 | /** |
| 61 | 83 | * Calculates the price based on the value and formula settings. |
| @@ -213,17 +235,17 @@ | ||
| 213 | 235 | var customThumb = singleSliderWrapper.find('.king-addons-pricing-slider__custom-thumb'); |
| 214 | 236 | var currentValDisplay = singleSliderWrapper.find('.king-addons-pricing-slider__current-value'); |
| 215 | 237 | |
| 216 | 238 | if (!rangeInput.length) { |
| 217 | - console.error('[KA Slider] Range input not found within:', singleSliderWrapper[0]); | |
| 239 | + // console.error('[KA Slider] Range input not found within:', singleSliderWrapper[0]); | |
| 218 | 240 | return; |
| 219 | 241 | } |
| 220 | 242 | if (!progressBar.length) { |
| 221 | - console.warn('[KA Slider] Progress bar not found within:', singleSliderWrapper[0]); | |
| 243 | + // console.warn('[KA Slider] Progress bar not found within:', singleSliderWrapper[0]); | |
| 222 | 244 | // Continue without progress bar update |
| 223 | 245 | } |
| 224 | 246 | if (!customThumb.length) { |
| 225 | - console.warn('[KA Slider] Custom thumb not found within:', singleSliderWrapper[0]); // Log raw DOM element | |
| 247 | + // console.warn('[KA Slider] Custom thumb not found within:', singleSliderWrapper[0]); // Log raw DOM element | |
| 226 | 248 | // Continue without thumb update |
| 227 | 249 | } |
| 228 | 250 | |
| 229 | 251 | var min = parseFloat(rangeInput.attr('min')) || 0; |
| @@ -235,9 +257,9 @@ | ||
| 235 | 257 | } else { |
| 236 | 258 | // If max <= min, slider is effectively fixed. Percentage is 0 if value <= min, 100 if value >= max. |
| 237 | 259 | // Or just treat as 0 to be safe. |
| 238 | 260 | percentage = (value >= max) ? 100 : 0; |
| 239 | - console.warn('[KA Slider] Max <= Min for slider:', rangeInput[0]); | |
| 261 | + // console.warn('[KA Slider] Max <= Min for slider:', rangeInput[0]); | |
| 240 | 262 | } |
| 241 | 263 | |
| 242 | 264 | percentage = Math.max(0, Math.min(100, percentage)); // Clamp percentage |
| 243 | 265 | |
| @@ -286,9 +308,9 @@ | ||
| 286 | 308 | var button = sliderWrapper.find('.king-addons-pricing-slider__button'); // Could be <a> or <button> |
| 287 | 309 | var features = sliderWrapper.find('.king-addons-pricing-slider__feature-item'); |
| 288 | 310 | |
| 289 | 311 | if (!rangeInput.length) { |
| 290 | - console.error("[KA Slider] Single slider init failed: Range input not found in", sliderWrapper[0]); | |
| 312 | + // console.error("[KA Slider] Single slider init failed: Range input not found in", sliderWrapper[0]); | |
| 291 | 313 | return; |
| 292 | 314 | } |
| 293 | 315 | |
| 294 | 316 | // Get data (use attributes as fallback for robustness) |
| @@ -302,8 +324,10 @@ | ||
| 302 | 324 | defaultValue = Math.max(minValue, Math.min(maxValue, defaultValue)); |
| 303 | 325 | if (parseFloat(rangeInput.val()) !== defaultValue) { |
| 304 | 326 | rangeInput.val(defaultValue); // Ensure input value matches calculated default |
| 305 | 327 | } |
| 328 | + alignRangeToLabeledMax(rangeInput.get(0)); | |
| 329 | + defaultValue = parseFloat(rangeInput.val()); | |
| 306 | 330 | |
| 307 | 331 | /** |
| 308 | 332 | * Updates the price display, button link (if applicable), and features for the single slider. |
| 309 | 333 | */ |
| @@ -327,9 +351,9 @@ | ||
| 327 | 351 | var params = new URLSearchParams(urlParts.length > 1 ? urlParts[1] : ''); |
| 328 | 352 | params.set('price', parseFloat(price).toFixed(priceData.decimals || 2)); // Use decimals from data |
| 329 | 353 | button.attr('href', baseUrl + '?' + params.toString()); |
| 330 | 354 | } catch (e) { |
| 331 | - console.error("[KA Slider] Error updating button URL:", e); | |
| 355 | + // console.error("[KA Slider] Error updating button URL:", e); | |
| 332 | 356 | // Potentially invalid URL, leave it as is |
| 333 | 357 | } |
| 334 | 358 | } |
| 335 | 359 | } |
| @@ -362,8 +386,9 @@ | ||
| 362 | 386 | |
| 363 | 387 | // --- Event Listener --- |
| 364 | 388 | // Ensure previous listeners are removed before adding new ones (important for editor) |
| 365 | 389 | rangeInput.off('.pricingSlider').on('input.pricingSlider change.pricingSlider', function() { |
| 390 | + alignRangeToLabeledMax(this); | |
| 366 | 391 | var value = parseFloat($(this).val()); |
| 367 | 392 | sharedUpdateSliderUI(sliderWrapper, value); // Update slider UI visuals |
| 368 | 393 | updateDisplay(); // Update price, button, features based on new value |
| 369 | 394 | }); |
| @@ -384,13 +409,13 @@ | ||
| 384 | 409 | var individualSliders = slidersContainer.find('.king-addons-single-slider'); // Wrappers for each slider |
| 385 | 410 | var allSlidersData = slidersContainer.data('sliders') || []; // Array of settings for each slider (from repeater) |
| 386 | 411 | |
| 387 | 412 | if (!individualSliders.length) { |
| 388 | - console.error("[KA Slider] Multi-slider init failed: No individual sliders found in", slidersContainer[0]); | |
| 413 | + // console.error("[KA Slider] Multi-slider init failed: No individual sliders found in", slidersContainer[0]); | |
| 389 | 414 | return; |
| 390 | 415 | } |
| 391 | 416 | if (allSlidersData.length !== individualSliders.length) { |
| 392 | - console.warn("[KA Slider] Mismatch between slider data count and slider element count."); | |
| 417 | + // console.warn("[KA Slider] Mismatch between slider data count and slider element count."); | |
| 393 | 418 | // Attempt to continue, but calculations might be off |
| 394 | 419 | } |
| 395 | 420 | |
| 396 | 421 | /** |
| @@ -467,9 +492,9 @@ | ||
| 467 | 492 | var params = new URLSearchParams(urlParts.length > 1 ? urlParts[1] : ''); |
| 468 | 493 | params.set('price', parseFloat(finalPrice).toFixed(priceData.decimals || 2)); |
| 469 | 494 | button.attr('href', baseUrl + '?' + params.toString()); |
| 470 | 495 | } catch(e) { |
| 471 | - console.error("[KA Slider] Error updating multi-slider button URL:", e); | |
| 496 | + // console.error("[KA Slider] Error updating multi-slider button URL:", e); | |
| 472 | 497 | } |
| 473 | 498 | } |
| 474 | 499 | } |
| 475 | 500 | // Update WooCommerce button data attribute (if exists) |
| @@ -496,8 +521,10 @@ | ||
| 496 | 521 | |
| 497 | 522 | if (parseFloat(rangeInput.val()) !== defaultValue) { |
| 498 | 523 | rangeInput.val(defaultValue); // Set initial value correctly |
| 499 | 524 | } |
| 525 | + alignRangeToLabeledMax(rangeInput.get(0)); | |
| 526 | + defaultValue = parseFloat(rangeInput.val()); | |
| 500 | 527 | sharedUpdateSliderUI(singleSliderWrapper, defaultValue); // Use shared function |
| 501 | 528 | }); |
| 502 | 529 | // Update the combined display based on initial values |
| 503 | 530 | updateCombinedDisplayForMulti(); |
| @@ -507,8 +534,9 @@ | ||
| 507 | 534 | slidersContainer.off('.pricingSlider', '.king-addons-pricing-slider__range'); |
| 508 | 535 | // Add new delegated listener |
| 509 | 536 | slidersContainer.on('input.pricingSlider change.pricingSlider', '.king-addons-pricing-slider__range', function() { |
| 510 | 537 | var rangeInput = $(this); // The input that triggered the event |
| 538 | + alignRangeToLabeledMax(this); | |
| 511 | 539 | var singleSliderWrapper = rangeInput.closest('.king-addons-single-slider'); |
| 512 | 540 | var value = parseFloat(rangeInput.val()); |
| 513 | 541 | |
| 514 | 542 | // Log for debugging multi-slider events |
| @@ -518,9 +546,9 @@ | ||
| 518 | 546 | // eventTarget: rangeInput[0] |
| 519 | 547 | // }); |
| 520 | 548 | |
| 521 | 549 | if (!singleSliderWrapper.length) { |
| 522 | - console.error('[KA Slider] Could not find .king-addons-single-slider parent for', rangeInput[0]); | |
| 550 | + // console.error('[KA Slider] Could not find .king-addons-single-slider parent for', rangeInput[0]); | |
| 523 | 551 | return; |
| 524 | 552 | } |
| 525 | 553 | |
| 526 | 554 | sharedUpdateSliderUI(singleSliderWrapper, value); // Update the UI of the slider that changed |
| @@ -533,9 +561,9 @@ | ||
| 533 | 561 | e.preventDefault(); |
| 534 | 562 | var $button = $(this); |
| 535 | 563 | |
| 536 | 564 | // --- DEBUGGING START --- |
| 537 | - console.log('[KA Slider] Add to Cart clicked. Localized vars:', typeof king_addons_slider_vars !== 'undefined' ? king_addons_slider_vars : 'Not Defined'); | |
| 565 | + // console.log('[KA Slider] Add to Cart clicked. Localized vars:', typeof king_addons_slider_vars !== 'undefined' ? king_addons_slider_vars : 'Not Defined'); | |
| 538 | 566 | // --- DEBUGGING END --- |
| 539 | 567 | |
| 540 | 568 | var price = $button.data('price') || calculateCombinedPriceForMulti(); // Get price |
| 541 | 569 | var productId = $button.data('product-id'); |
| @@ -554,9 +582,9 @@ | ||
| 554 | 582 | var $sliderInput = $button.closest('.king-addons-pricing-slider, .king-addons-pricing-sliders').find('.king-addons-pricing-slider__range').first(); // Get the first slider in the context |
| 555 | 583 | if ($sliderInput.length) { |
| 556 | 584 | quantity = parseInt($sliderInput.val()) || 1; |
| 557 | 585 | } else { |
| 558 | - console.warn('[KA Slider] Could not find slider input for auto quantity.'); | |
| 586 | + // console.warn('[KA Slider] Could not find slider input for auto quantity.'); | |
| 559 | 587 | } |
| 560 | 588 | quantity = Math.max(1, quantity); // Ensure quantity is at least 1 |
| 561 | 589 | } |
| 562 | 590 | |
| @@ -603,9 +631,9 @@ | ||
| 603 | 631 | case 'before_button': |
| 604 | 632 | notificationsContainer = $button.parent(); |
| 605 | 633 | // Insert before button |
| 606 | 634 | if (response.success) { |
| 607 | - console.log('[KA Slider] Product added to cart:', response.data); | |
| 635 | + // console.log('[KA Slider] Product added to cart:', response.data); | |
| 608 | 636 | // Trigger WooCommerce added_to_cart event for themes/plugins to hook into |
| 609 | 637 | $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $button]); |
| 610 | 638 | |
| 611 | 639 | var successMsg = $('<span class="king-addons-slider-notice success">' + (response.data.message || 'Added to cart!') + '</span>'); |
| @@ -644,9 +672,9 @@ | ||
| 644 | 672 | var priceElement = $button.closest('.king-addons-pricing-slider, .king-addons-pricing-sliders') |
| 645 | 673 | .find('.king-addons-pricing-slider__price'); |
| 646 | 674 | if (priceElement.length) { |
| 647 | 675 | if (response.success) { |
| 648 | - console.log('[KA Slider] Product added to cart:', response.data); | |
| 676 | + // console.log('[KA Slider] Product added to cart:', response.data); | |
| 649 | 677 | // Trigger WooCommerce added_to_cart event for themes/plugins to hook into |
| 650 | 678 | $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $button]); |
| 651 | 679 | |
| 652 | 680 | var successMsg = $('<span class="king-addons-slider-notice success">' + (response.data.message || 'Added to cart!') + '</span>'); |
| @@ -691,9 +719,9 @@ | ||
| 691 | 719 | if (customContainer.length) { |
| 692 | 720 | customContainer.empty(); // Clear previous notifications |
| 693 | 721 | |
| 694 | 722 | if (response.success) { |
| 695 | - console.log('[KA Slider] Product added to cart:', response.data); | |
| 723 | + // console.log('[KA Slider] Product added to cart:', response.data); | |
| 696 | 724 | // Trigger WooCommerce added_to_cart event for themes/plugins to hook into |
| 697 | 725 | $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $button]); |
| 698 | 726 | |
| 699 | 727 | var successMsg = $('<span class="king-addons-slider-notice success">' + (response.data.message || 'Added to cart!') + '</span>'); |
| @@ -735,9 +763,9 @@ | ||
| 735 | 763 | case 'after_button': |
| 736 | 764 | default: |
| 737 | 765 | // This is the original behavior - place notifications after the button |
| 738 | 766 | if (response.success) { |
| 739 | - console.log('[KA Slider] Product added to cart:', response.data); | |
| 767 | + // console.log('[KA Slider] Product added to cart:', response.data); | |
| 740 | 768 | // Trigger WooCommerce added_to_cart event for themes/plugins to hook into |
| 741 | 769 | $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $button]); |
| 742 | 770 | |
| 743 | 771 | var successMsg = $('<span class="king-addons-slider-notice success">' + (response.data.message || 'Added to cart!') + '</span>'); |
| @@ -757,9 +785,9 @@ | ||
| 757 | 785 | setTimeout(function(){ successMsg.fadeOut(function(){ $(this).remove(); }); }, 3000); |
| 758 | 786 | } |
| 759 | 787 | } else { |
| 760 | 788 | var errorMessage = 'Could not add product to cart. Please try again.'; |
| 761 | - console.error('[KA Slider] Error adding to cart:', response.data); | |
| 789 | + // console.error('[KA Slider] Error adding to cart:', response.data); | |
| 762 | 790 | |
| 763 | 791 | if (response.data && response.data.error_code === 'budget_too_low') { |
| 764 | 792 | var templateMessage = priceData.budget_too_low_message || 'Your selected budget is too low. Please increase the budget to at least {product_price}.'; |
| 765 | 793 | var productPrice = response.data.product_price || ''; |
| @@ -776,9 +804,9 @@ | ||
| 776 | 804 | } |
| 777 | 805 | }, |
| 778 | 806 | error: function(jqXHR, textStatus, errorThrown) { |
| 779 | 807 | $button.removeClass('loading'); |
| 780 | - console.error('[KA Slider] AJAX Error:', textStatus, errorThrown); | |
| 808 | + // console.error('[KA Slider] AJAX Error:', textStatus, errorThrown); | |
| 781 | 809 | // Show generic user-friendly error for AJAX failures |
| 782 | 810 | var errorMsg = $('<span class="king-addons-slider-notice error">An error occurred. Please try again later.</span>').insertAfter($button); |
| 783 | 811 | setTimeout(function(){ errorMsg.fadeOut(function(){ $(this).remove(); }); }, 5000); |
| 784 | 812 | } |