Search code examples
javascripthtmlcssotree

Progressbar with vertical line


I am implementing a simulation of a Dutch- and an English-auction in otree.
For the interface, I am using a progress bar for the price that the supplier gets.
In the English-auction the price increases every half second and in the Dutch-auction the price decreases every half second.

Now I want to add a vertical line for the costs of the supplier, which changes every round. How can i add a vertical line to the progress bar?

<style>
#myProgress {
  width: 100%;
  background-color: #ddd;
}
#myCosts {
  width: 100%;
  background-color: #ddd;
}
#myBar {
  width: 100%;
  height: 30px;
  background-color: #40bf80;
  text-align: center;
  line-height: 30px;
  color: white;
}
#costLine{
  width: 0%;
  height: 30px;
  background-color: #FF0000;
  text-align: center;
  line-height: 30px;
  color: white;
}
.bg-info{
    background-color: #ddd;
}

</style>
Your costs for this round are:
<div id="myCosts">
<div id="costLine">{{player.cost}}</div>
</div>
Current price is:
<div id="myProgress">
<div id="myBar">$200</div>
</div>
<p></p>
<p id="Message"></p>
<script>
    var left_line = ({{player.cost|json}}-101);
    var right_line = (200-{{player.cost|json}});
    let cost = {{player.cost|json}}
    let bot_stop = {{player.bot_stop|json}};
    let price = {{Constants.start_value|json}};
    var Auction;
    var Auction2;
    document.getElementById("costLine").innerHTML = "$"+cost;
    document.getElementById("costLine").style.width = cost-100+'%';
    function startAuction(){
        document.getElementById("stop_button").disabled = false;
        document.getElementById("start_button").disabled = true;
        Auction = setInterval(function(){
            if(price == bot_stop){
                document.getElementById("Message").innerHTML = 'The other supplier has dropped out. You win with a price of ' + bot_stop;
                document.getElementById("stop_button").innerHTML = 'Next Page'
                stopAuction();
            }
            if(price != bot_stop){
                price = price -1;
                document.getElementById("myBar").innerHTML='$'+price;
                document.getElementById("myBar").style.width = (price-100) +'%';
            }
        },500)

    }
    function stopAuction() {
        document.querySelector("[name=winning_price]").value = price;
        document.getElementById("stop_button").innerHTML = 'Next Page'
        clearInterval(Auction);
    }
</script>
<button type="button" class="otree-btn-next btn btn-primary" id="start_button" onclick="startAuction()">Start Auction</button>
<button class="otree-btn-next btn btn-primary" disabled id="stop_button" onclick="stopAuction()">Drop Out</button>
<p></p>
<p></p>
<input  type="hidden" name="winning_price" />

enter image description here


Solution

    1. Add a child element <div id=myBarPrice></div> to <div id="myProgress">.
    2. Add position: relative; attribute to the #myProgress selector.
    3. Add new style block for a new element:
    #myBarPrice {
      background-color: #FF0000;
      width: 2px;
      height: 100%;
      position: absolute;
      right: 100%;
      top: 0;
    }
    
    1. Set #myBarPrice position with js:
    ...
        document.getElementById("costLine").innerHTML = "$"+cost;
        document.getElementById("costLine").style.width = cost-100+'%';
        document.getElementById("myBarPrice").style.right = cost+'%'; // <===== 
        function startAuction(){
            document.getElementById("stop_button").disabled = false;
            document.getElementById("start_button").disabled = true;
    ...
    
    

    Here is a mockup in codepen.io

    CSS code:

    #myProgress {
      width: 100%;
      background-color: #ddd;
      position: relative;
    }
    #myCosts {
      width: 100%;
      background-color: #ddd;
    }
    #myBar {
      width: 80%;
      height: 30px;
      background-color: #40bf80;
      text-align: center;
      line-height: 30px;
      color: white;
    }
    #myBarPrice {
      background-color: #FF0000;
      width: 2px;
      height: 100%;
      position: absolute;
      right: 40%;
      top: 0;
    }
    #costLine{
      width: 60%;
      height: 30px;
      background-color: #FF0000;
      text-align: center;
      line-height: 30px;
      color: white;
    }
    .bg-info{
        background-color: #ddd;
    }
    

    HTML code:

    Your costs for this round are:
    <div id="myCosts">
      <div id="costLine">{{player.cost}}</div>
    </div>
    Current price is:
    <div id="myProgress">
      <div id="myBar">$200</div>
      <div id=myBarPrice></div>
    </div>