1

Code is working, but need to refresh page to get disabled/enabled button(page show more than 30 products with button(product button is created with same code). Is it possible to change button disable/enable status without page refresh?

UPD: problem solved, code in comments

Disabling code

<script>
function beCheerful() {
<?php
$cookie_basket = $_COOKIE['basket'];    
$tempo = urlencode($cookie_basket);
$countChars = mb_strlen($tempo);
?>
let test = '<?php echo $countChars;?>';
window.addEventListener("DOMContentLoaded", function() {
    [...document.querySelectorAll('[disabled]')].forEach(btn => btn.disabled = test > 50)
});
}
for (var i = 0; i < 1; i++) {
    beCheerful();
}
</script>

Button code

<button disabled OnClick="beCheerful();" id="bt1" class="btn btn-warning btn-lg btn-block tobasket <?php echo $elem['content_tr'] ?>" product_id="<?php echo $v['id']; ?>" name="<?php echo $prdata['full_name'] ?>" nametr="<?php echo $prdata['name1_tr'] ?>" url="<?php echo $cur_url; ?>catalog/<?php echo $v['img_url']; ?>" price="<?php echo $v['price']; ?>" <?php if($v['sold']==1) echo 'sold="true"'; ?>><?php echo $elem['content'] ?></button>
Amimistik
  • 35
  • 6

2 Answers2

1

It looks like you've got PHP that's embedded in your JavaScript program, and you want some sort of live updating system to change the button statuses when the data changes. When a client requests the page from the server, the server will execute the PHP code and then insert the results from the echo statements into your code. This means that all the client sees is the result of the PHP execution, like so:

let test = '10';

The client cannot execute the PHP code to do a live update; only the server can. That's why you have to refresh the page in order for the page to be updated in your case. Calling the beCareful function again will not help either, since the PHP code has already been substituted with the result when the user initially loaded up the page.

If I were you, I would refactor your code so that there's a PHP page which contains the data only. Then, perform an XMLHttpRequest from the JavaScript code to retrieve the evaluated contents of the PHP code and use that data to then set the button disabled properties as necessary. To make this update live, you'll need to wrap the request in a timer loop using setInterval:

setInterval(function() {
    var request = new XMLHttpRequest();

    request.addEventListener("load", function() {
        console.log(request.responseText); // This will be the response you'll get from the PHP page when you request it; use this data to set the button `disabled` attributes
    });

    request.open("GET", "data.php"); // Or wherever your PHP file will be
    request.send();
}, 3000); // Update every 3,000 milliseconds, or 3 seconds

One step further would be to get the PHP page to serialise the data in the JSON format using the PHP json_encode command, and then get the JavaScript to deserialise this data using JSON.parse(request.responseText). That way, you can send multiple 'pieces' of data at once in a nice data structure.


Sidenote: From a security perspective, using PHP in your HTML can lead to cross-site scripting vulnerabilities (XSS) being present in your code. For example, your code for the buttons contains the following PHP snippet:

<?php echo $elem['content'] ?>

The problem with this is, what happens if $elem['content'] returns user-written data? If I were able to have access to your program's editor to edit the result of $elem['content'] and set it to

sample text sample text <script>alert("Oh no! Something that wasn't meant to execute has been executed!");</script> more sample text

then your code would execute the contents of the <script> element. Though this example is mild, there could be more serious code snippets which could potentially do damage to your system (eg. perform malicious tasks on the client side, such as deleting the user's account). To solve this, use the htmlspecialchars function in PHP (see this StackOverflow answer for more details), which sanitises the given input text and aims to ensure that the text can't be written to perform an XSS attack (eg. it replaces <script> with &lt;script&gt;, which will still render as <script> to the user, but won't cause the code to be executed).

James Livesey
  • 129
  • 2
  • 8
  • 1
    Welcome to StackOverflow, by the way! I'm new here, too. Your question does look similar to [this one](https://stackoverflow.com/questions/539787/php-live-updating), so I'd suggest taking a look at that. – James Livesey Jun 15 '21 at 08:48
  • 1
    Big thanks to You, now i understand why code not working like i need, i will change php code to js(coockies code part) than probably code will be able to be live. And separate Big thanks for sidenote. – Amimistik Jun 15 '21 at 09:35
  • 1
    @Amimistik No problem! Great to hear that you now better understand how PHP/JavaScript works. Changing the PHP into JavaScript code sounds like a great plan :) – James Livesey Jun 15 '21 at 16:48
  • 1
    Cos of Your explanation and idea i finally converted it to working in live mode. Will provide here working code, maybe someone, sometime will be need to solve not typical situation like mine. – Amimistik Jun 16 '21 at 13:07
1

Thanks to James Livesey answer(php - not live mode) code was converted to full js(or java) to this one, that is solving my problem and is working in live mode without page reload.

Code(can be done more simple, but for me more important condition - it's working )

<script>
//getting cookie
function getCookie(basket) {
  var name = basket + "=";
  var decodedCookie = decodeURIComponent(document.cookie);
  var ca = decodedCookie.split(';');
  for(var i = 0; i < ca.length; i++) {
    var c = ca[i];
   while (c.charAt(0) == ' ') {
      c = c.substring(1);
    }
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}
//counting lenght
function checkCookie(check_num) {
    var user=getCookie("basket");
    var test_user=encodeURI(user);
    var check_num=test_user.length;
    return check_num;
}
function checkBasketCoockie() {
    let test=checkCookie();
    if (test > 100){
    let buttons = document.getElementsByClassName("tobasket");
    for (let i = 0; i < buttons.length; i++) {
      buttons[i].disabled = true;
    }
    }else{
    let buttons = document.getElementsByClassName("tobasket");
    for (let i = 0; i < buttons.length; i++) {
      buttons[i].disabled = false;
    }
    }
}
</script>

And on button, page load is

OnClick="checkBasketCoockie(); or onload="checkBasketCoockie()"
Amimistik
  • 35
  • 6