1

I wish to take the value of an HTML string contained within <bdi> tags - perform a calculation on it - and output the results in a separate <bdi> string, dependent on which input is selected on-page.

The source <bdi> value changes dynamically based on user interaction, but I want to know if what I'm asking is feasible and a rough guide on how to achieve it?

Screenshot to illustrate the user elements: Screenshot to illustrate the user elements

In the DOM, the source value is nested in the below tag:

<li class="grand_total">
  <span class="name">Grand Total</span> 
  <span class="price">
     <span class="woocommerce-Price-amount amount">
        <bdi>
          <span class="woocommerce-Price-currencySymbol">£</span>
          301.00
         </bdi>
     </span>
   </span>
</li>

If the deposit input option is selected, how can I target this value (or string - sorry if incorrect terminology) using jQuery to divide it by 100 and multiply by 20 - and then output the resultant figure in the target which is nested as follows:

<li class="deposit_free_total">
   <span class="name">Due Today</span>
   <span class="price">
       <span class="woocommerce-Price-amount amount">
            <bdi>
               <span class="woocommerce-Price-currencySymbol">£</span>301.00
            </bdi>
       </span>
   </span>
</li>

The input which needs to be selected to initiate the above has an id of #wc-option-pay-deposit. I'm not sure where to start, so any help is appreciated!

PROGRESS UPDATE:

I've devised the following code, which works as expected:

<script>
jQuery(document).ready(function(changeToPay){
    if (jQuery('#wc-option-pay-deposit').is(':checked')) {
            (jQuery("h1").html("Test"));
    } 
})
jQuery(document).ready(function(){ 
    changeToPay();
});
</script>

Seems like the next step would be to create variables, so that data can be acquired and calculations can be performed, but I've no idea how to join up the dots...

  • What you try to achieve is to change what is displayed on screen... That will not affect the data sent to the server when the user will click on "Add to basket". – Louys Patrice Bessette Jan 20 '21 at 16:40
  • Yes, all I want to do is affect the client side and what the user sees. I do not need to manipulate the actual data, but I have no idea how to proceed. – Steven Leek Jan 22 '21 at 21:52

1 Answers1

0

Given you only want to change what is displayed on the client-side...

Try this... And if it works as expected, I will edit with explanations.

jQuery(document).ready(function(changeToPay){

  setInterval(function(){
    if (jQuery('#wc-option-pay-deposit').is(':checked') && !jQuery(".deposit_free_total bdi").is(".calculated")) {
      jQuery(".deposit_free_total bdi").html(jQuery(".grand_total .woocommerce-Price-currencySymbol")[0].outerHTML + (parseFloat(jQuery(".grand_total bdi").text().replace("£","").trim())*0.2).toFixed(2)).addClass("calculated")
    } 
  },50)
  
})

EDIT for GB number formatting over a thousand:

You have to remove the thousand separator coma... Easy using .replace().
But you have to re-add it if the 20% result still is over a thousand! You need .toLocaleString() with specific options! I admit that would not have been easy to find.

So the statement inside the if condition now is:

jQuery(".deposit_free_total bdi").html(jQuery(".grand_total .woocommerce-Price-currencySymbol")[0].outerHTML + (parseFloat(jQuery(".grand_total bdi").text().replace("£","").replace(",","").trim())*0.2).toLocaleString('en-GB',{minimumFractionDigits:2, maximumFractionDigits:2})).addClass("calculated")
Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64
  • Hey, thank you so much for the reply and the attempted solution! On the face of it, your code looks like it should work, although throws a console error. Please bear in mind that you are dealing with an absolute novice, so I am sorry if I have not wrapped this correctly. You may be able to see it better for yourself live-on page: https://freedomholidaysuk.co.uk/motorhomes/swift-escape-624/ – Steven Leek Jan 22 '21 at 22:45
  • I have no acces to that page: `Block Reason: Access from your area has been temporarily limited for security reasons.` -- anyway, try it yourself. – Louys Patrice Bessette Jan 22 '21 at 22:52
  • Do you have access now? – Steven Leek Jan 22 '21 at 22:54
  • Yes... And I found a mistake I made + I changed all `$` for `jQuery` because you use jQuery migrate. ;) retry. – Louys Patrice Bessette Jan 22 '21 at 23:07
  • I've applied this: It still does not seem to work. Could it be because the totals update when the date picker values change via Ajax - therefore overwriting any initial changes? – Steven Leek Jan 22 '21 at 23:38
  • Sure it's a possibility. Do you have access to that ajax code? It would be best to make the changes there. – Louys Patrice Bessette Jan 22 '21 at 23:42
  • I can possibly dig it out, but my concern is that the page uses two plugins: WooCommerce Bookings and RnB Rental and Booking. Would editing the AJAX code cause a conflict? – Steven Leek Jan 22 '21 at 23:52
  • Can't tell... But I had a second taught. The calculation seems to update on the datepickers change. I really don't think any ajax request (read: external data) is needed to multiply a known price by the time period that is selected ;) So I would look for a `change` handler on those inputs. – Louys Patrice Bessette Jan 23 '21 at 00:00
  • This is very advanced for me, but the logic makes sense. Where would I need to look in order to find/apply the change handler? – Steven Leek Jan 23 '21 at 00:02
  • Hold on. I just had an *hacky* idea for you to try... Will edit in a couple minutes. – Louys Patrice Bessette Jan 23 '21 at 00:19
  • So here is something to try... It will ***try*** to make the calculation every 50 milliseconds. So even if some ajax or other function changes the display, it should make the calculation right away. – Louys Patrice Bessette Jan 23 '21 at 00:26
  • This is incredible, thank you so much @LouysPatriceBessette! – Steven Leek Jan 23 '21 at 01:18
  • 1
    As far as I can tell, it works perfectly - you're a wizard! Check it out for yourself :) – Steven Leek Jan 23 '21 at 01:22
  • Cool! :D So when I will visit UK someday, I expect a nice rebate on that motorhome :D -- I will edit with more details on the function a bit later today or tomorrow. – Louys Patrice Bessette Jan 23 '21 at 01:26
  • 1
    Haha! Unfortunately it is not my motorhome, but I am sure a substantial discount code could be arranged for you ;) Many thanks for taking the time to work over the solution, I honestly thought it was impossible. You have made my weekend already! – Steven Leek Jan 23 '21 at 01:30
  • Hey again @Louys. The calculation works flawlessly, apart from when the figure that needs to be divided exceeds 999. Is it possible to update your code to also strip out any commas (,) before the calculation is performed? – Steven Leek Jan 26 '21 at 01:23
  • I've answered my own question - it needed another .replace("," , "") tagged straight onto the first one. Thanks again for your help with this, I feel like I've learnt a lot! – Steven Leek Jan 26 '21 at 01:32
  • Naa.... You also need to re-add the coma if the 20% result is above 1000. See my edit ;) I tested it quick in this [CodePen](https://codepen.io/Bes7weB/pen/XWjLLPM?editors=1011). – Louys Patrice Bessette Jan 26 '21 at 01:42
  • Unfortunately replacing this revision as the statement inside the IF condition does not work. It throws an error of .toLocaleString(...).addClass is not a function. – Steven Leek Jan 27 '21 at 15:26
  • Fixed... There was a missing parenthesis. – Louys Patrice Bessette Jan 27 '21 at 16:09
  • Working perfectly now, I used Hint JS but must have put the missing parenthesis in the wrong place like the noob that I am. Thanks again for your help @Louys. Don't suppose you are able to pass on your jQuery wizardry for another issue I'm having on the same project? I tried to adapt your code, but to no avail... https://stackoverflow.com/questions/65865939/strip-spaces-on-one-condition-add-them-on-another-jquery-not-working?noredirect=1#comment116458177_65865939 – Steven Leek Jan 28 '21 at 23:27