oTree Forum >

Live Pages Tables not Updating

#1 by amarchal

I am using live pages for a double auction experiment with two goods simultaneously. I've designed four separate tables to list the bids and asks for each good, but the tables are not updating when the bids are submitted. I have event listeners that show the data is being submitted, so I'm not sure why it's not being received by the tables. Additionally, a minor bug is that participants can only trade item, but I want them to be able to watch the rest of the round. Why is the disabled button still appearing? Thanks!

{% extends "global/Page.html" %}
{% block styles %}
<link rel="stylesheet" type="text/css" href="{% static 'global/styles.css' %}">
{% endblock %}

{% block title %}
Trade
{% endblock %}
{% block content %}

<p id="news" style="color: green"></p>

<p> In this round, you are a <b> {% if player.is_buyer %}buyer{% else %}seller{% endif %} </b>. </p>

<table class="table">
    <tr>
        <td><b style="color: #ff8400;">Squares</b> Owned: </td>
        <th id="own_square">{{ player.num_square }}</th>
        <td><b style="color: #007bff;">Circles</b> Owned: </td>
        <th id="own_circle">{{ player.num_circle }}</th>
    </tr>
    <tr>
        <td>Current Offer for <b style="color: #ff8400;">Square</b>:</td>
        <th id="current_offer_square">{{ player.current_offer_square }}</th>
        <td>Current Offer for <b style="color: #007bff;">Circle</b>:</td>
        <th id="current_offer_circle">{{ player.current_offer_circle }}</th>
    </tr>

    <tr>
        <td>Previous <b style="color: #ff8400;">Square</b> Price:</td>
        <th id="current_value_square">{{ Constants.baseline_value }}</th>
        <td>Previous <b style="color: #007bff;">Circle</b> Price:</td>
        <th id="current_value_circle">{{ Constants.baseline_value }}</th>
    </tr>

    <tr>
        <td>
            Carbon offset per <b style="color: #ff8400;">Square</b>:
        </td>
        <th> N/A </th>
        <td>
            Carbon offset per <b style="color: #007bff;">Circle</b>:
        </td>
        <th> {{ Constants.carbon_offset_unit }} </th>
    </tr>
</table>

<!-- Input for making an offer (Subjects make seperate offers for Circle and Square) -->
<input type="number" id="my_offer">
<select id="asset_type">
    <option disabled selected value> -- </option>
    <option value="Square">Square</option>
    <option value="Circle">Circle</option>
</select>
<button type="button" onclick="sendOffer()" id="btn-offer">Make offer</button>
<br><br>

<!-- Displaying bid and ask tables for Circle and Square -->
<div class="container">
    <div class="row">
        <div class="col-sm">
            <h4>Bids <b style="color: #ff8400;">Square</b></h4>
            <table id="bids_table_square"></table>
        </div>
        <div class="col-sm">
            <h4>Bids <b style="color: #007bff;">Circle</b></h4>
            <table id="bids_table_circle"></table>
        </div>
    </div>
    <br><br>
    <div class="row">
        <div class="col-sm">
            <h4>Asks <b style="color: #ff8400;">Square</b></h4>
            <table id="asks_table_square"></table>
        </div>
        <div class="col-sm">
            <h4>Asks <b style="color: #007bff;">Circle</b></h4>
            <table id="asks_table_circle"><tbody></tbody></table>
        </div>
    </div>
</div>

<br><br>

<script>

    // Define variables that will display in the table or will be an input
    let bids_table_square = document.getElementById('bids_table_square');
    let bids_table_circle = document.getElementById('bids_table_circle');
    let asks_table_square = document.getElementById('asks_table_square');
    let asks_table_circle = document.getElementById('asks_table_circle');
    let news_div = document.getElementById('news');
    let my_offer = document.getElementById('my_offer');

    // Get variables from js_vars in __init__.py
    let my_id = js_vars.id_in_group;
    let is_buyer = js_vars.is_buyer;

    function showNews(msg) {
        news_div.innerText = msg;
        setTimeout(function () {
            news_div.innerText = ''
        }, 10000);
    }

    function cu(amount) {
        return `${amount} eFrancs`;
    }

    function liveRecv(data) {
        console.log(data);

        // Initializing elements and variables with default values
        let news = data.news;
        let trade_quota = data.trade_quota;
        let current_offer_circle = data.current_offer_circle || 'N/A';
        if (current_offer_circle > 9997) {
            current_offer_circle = 'N/A'
        }
        if (current_offer_circle === 0) {
            current_offer_circle = 'N/A'
        }
        let current_offer_square = data.current_offer_square || 'N/A';
        if (current_offer_square > 9997) {
            current_offer_square = 'N/A'
        }
        if (current_offer_square === 0) {
            current_offer_square = 'N/A'
        }
        let num_square
        if (is_buyer) {
            num_square = data.num_square || 0;
        } else {
            num_square = data.num_square || 1;
        }
        let num_circle
        if (is_buyer) {
            num_circle = data.num_circle || 0;
        } else {
            num_circle = data.num_circle || 1;
        }
        let bids_circle = data.bids_circle;
        let asks_square = data.asks_square;
        let asks_circle = data.asks_circle;
        let circle_value = data.circle_value;
        let square_value = data.square_value;


        // Ensure the arrays are not undefined and have the correct data
        console.log('bids_square:', bids_square);
        console.log('bids_circle:', bids_circle);
        console.log('asks_square:', asks_square);
        console.log('asks_circle:', asks_circle);


        // Update HTML elements with received data (updating the content within the table)
        document.getElementById('own_square').innerText = num_square;
        document.getElementById('own_circle').innerText = num_circle;
        document.getElementById('current_value_circle').innerText = circle_value || js_vars.baseline_value;
        document.getElementById('current_value_square').innerText = square_value || js_vars.baseline_value;


        // Pop-up news messages
        if (news) {
            let {buyer, seller, price, asset} = news;
            if (buyer === my_id) {
                showNews(`You bought a ${asset} from player ${seller} for ${cu(price)}`);
            } else if (seller === my_id) {
                showNews(`You sold a ${asset} to player ${buyer} for ${cu(price)}`);
            }
        }

        // Update HTML elements with received data (updating the content within the table)
        document.getElementById('current_offer_square').innerText = current_offer_square;
        document.getElementById('current_offer_circle').innerText = current_offer_circle;

        // Disable the offer button if quota is <= 0
        let buttonOffer = document.getElementById('btn-offer')
        if (trade_quota === 0) {
            buttonOffer.style.display = 'none';
        } else {
            buttonOffer.style.display = 'inline-block';
        }

        // Update bid and ask tables
        document.getElementById('bids_table_square').innerHTML = bids_square.map(e => `<tr><td>$cu{e}</td></tr>`).join('');
        document.getElementById('bids_table_circle').innerHTML = bids_circle.map(e => `<tr><td>$cu{e}</td></tr>`).join('');
        document.getElementById('asks_table_square').innerHTML = asks_square.map(e => `<tr><td>$cu{e}</td></tr>`).join('');
        document.getElementById('asks_table_circle').innerHTML = asks_circle.map(e => `<tr><td>$cu{e}</td></tr>`).join('');
    }

    function sendOffer() {
        let offerValue = parseInt(my_offer.value);
        if (offerValue > 0) {
            if (offerValue > 300) {
                swal("Oops", "You can't offer more than your money holdings", "error", {
                    button: "Please try a lower offer",
                });
            } else {
                liveSend({'asset': asset_type.value, 'offer': offerValue});
            }
        } else if (offerValue < 0) {
            swal("Oops", "You can't make negative offers", "error", {
                button: "Please try a higher offer",
            });
        } else {
            liveSend({'asset': asset_type.value, 'offer': offerValue});
        }
    }

    // Event listener to send offer on pressing Enter key
    my_offer.addEventListener("keydown", function (event) {
        if (event.key === "Enter") {
            sendOffer();
        }
    });

    document.addEventListener('DOMContentLoaded', (event) => {
        liveSend({});
    });
</script>

{% endblock %}

Write a reply

Set forum username