Manjunath
Manjunath

Reputation: 59

Show Progress bar with limit and completed values in jQuery Ui

I have a requirement to show progressed value and remaining value in Progress Bar.

Here is my html content.

<html>

<head>
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
  <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
  <script type="text/javascript" src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
 <style>
 .bar {
    width: 100px;
    height: 20px;
    margin: 2px;
    border: 1px solid black;
    background-color: lightgreen;
    text-align: center;
    float: left;
    margin: 2px;
    padding: 2px;
    cursor: pointer;
    border-radius: 3px;
  }

  .list {
    background-color: lightblue;
    border: 1px solid gray;
  }

  .items .ui-selected {
    background: red;
    color: white;
    font-weight: bold;
  }

  .items {
    list-style-type: none;
    margin: 0;
    padding: 0;
    width: 100px;
  }

  .items li {
    margin: 2px;
    padding: 2px;
    cursor: pointer;
    border-radius: 3px;
  }

  .weekday {
    float: left;
  }

  .availablelist {
    background-color: orange;
    display: inline;
  }
   </style>
   </head>

  <body>
   <div style="float:left;width:500px;">
   <div><h2>Total Credits = <span id="total-credits">80</span></h2> </div>
 </div>

<div style="clear:both"></div>
<br>
<div id="timetable" style="float:left;width:700px;">    
  <div class="weekday">
     <ul class="items">
        <li class="list">
        <label class="core-ins-tag-numb">Jhonny</label>
        <input type="hidden" value="15" name="credits" class="credits">
        </li>
        <li class="list">
        <label class="core-ins-tag-numb">Tim</label>
        <input type="hidden" value="10" name="credits" class="credits">
        </li>
        <li class="list">
       <label class="core-ins-tag-numb">George</label>
        <input type="hidden" value="25" name="credits" class="credits">
        </li>
        <li class="list">
       <label class="core-ins-tag-numb">Melissa</label>
        <input type="hidden" value="20" name="credits" class="credits">
        </li>
        <li class="list">
        <label class="core-ins-tag-numb">Alice</label>
        <input type="hidden" value="5" name="credits" class="credits">
        </li>
    </ul>
</div>
<div class="weekday">
    <ul class="items">
        <li class="list">
        <label class="core-ins-tag-numb">Jhonny</label>
        <input type="hidden" value="20" name="credits" class="credits">
        </li>
        <li class="list">
        <label class="core-ins-tag-numb">Tim</label>
        <input type="hidden" value="10" name="credits" class="credits">
        </li>
        <li class="list">
        <label class="core-ins-tag-numb">George</label>
        <input type="hidden" value="10" name="credits" class="credits">
        </li>
        <li class="list">
        <label class="core-ins-tag-numb">Melissa</label>
        <input type="hidden" value="10" name="credits" class="credits">
        </li>
        <li class="list">
        <label class="core-ins-tag-numb">Alice</label>
        <input type="hidden" value="10" name="credits" class="credits">
        </li>
    </ul>
</div>
<br>

 <div id = "progressbar"></div>
 </div>
 <script>
$(function () {
    $("#timetable .items").sortable({
        connectWith: "ul"   
    });        

    /* for progress bar */ 
    var progressbar = $( "#progressbar" );
    $( "#progressbar" ).progressbar({
       value: 0,
       max:300
    });

    function progress() {
       var val = progressbar.progressbar( "value" ) || 0;
       progressbar.progressbar( "value", val + 1 );
       if ( val <= 00 ) {
          setTimeout( progress, 100 );
       }
    }
    setTimeout(progress, 3000);
    /* for progress bar */ 
});

I have a hidden value for each li items with some credits, so Whenever any li is dragged from right and dropped to left side, I need to sum the value of each left hand side li credits and match with the Total credits and show the Progress bar with values like below Image

enter image description here

Also I need to ensure drag should not allow if credit limit is crossed to 80,

How this can be done?

Upvotes: 0

Views: 3249

Answers (2)

RezaGhahari
RezaGhahari

Reputation: 413

This link solves your problem:

https://www.jqueryscript.net/other/Animated-Step-Progress-Indicator-With-jQuery-StepProgressBar.html

<link href="http://www.jqueryscript.net/css/jquerysctipttop.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css" integrity="sha384-y3tfxAZXuh4HwSYylfB+J125MxIs6mR5FOHamPBG064zB+AFeWH94NdvaCBm8qnd" crossorigin="anonymous">
<link href="https://www.jqueryscript.net/demo/Animated-Step-Progress-Indicator-With-jQuery-StepProgressBar/src/jquery.stepProgressBar.css" rel="stylesheet"/>
<div class="container">
<h1>jQuery StepProgressBar Plugin Example</h1>
<div id="myGoal"></div>
<span class="btn btn-primary" id="get-current-value-btn">get current value</span><br>
        <span class="btn btn-primary" id="set-current-value-btn">set current value to 500</span><br>
        <span class="btn btn-primary" id="find-step-btn">find step with value = 500 (see in console)</span><br>
        <span class="btn btn-primary" id="add-step-btn">add step with value = 250</span><br>
        <span class="btn btn-primary" id="remove-step-btn">remove step with value = 500</span>
        </div>
<script src="http://code.jquery.com/jquery-1.12.2.min.js"></script>

<script src="https://www.jqueryscript.net/demo/Animated-Step-Progress-Indicator-With-jQuery-StepProgressBar/src/jquery.stepProgressBar.js"></script>
<script>
$('#myGoal').stepProgressBar({
  currentValue: 200,
  steps: [
    { value: 100 },
    {
      topLabel: '500 custom unit',
      value: 500,
      bottomLabel: '<i class="material-icons">thumb_up</i>'
    },
    {
      value: 800,
      bottomLabel: '<i class="material-icons">card_giftcard</i>'
    },
    {  
      value: 1000, 
      bottomLabel: '<i class="material-icons">star</i>',
      mouseOver: function() { alert('mouseOver'); },
      click: function() { alert('click'); }
    }
  ],
  unit: '$'
});

        $('#get-current-value-btn').click(function() {
          alert($('#myGoal').stepProgressBar('getCurrentValue'));
        });
        $('#set-current-value-btn').click(function() {
          $('#myGoal').stepProgressBar('setCurrentValue', 500);
        });
        $('#find-step-btn').click(function() {
          console.log($('#myGoal').stepProgressBar('findStep', 500));
        });
        $('#add-step-btn').click(function() {
          $('#myGoal').stepProgressBar('addStep', {value: 250});
        });
        $('#remove-step-btn').click(function() {
          $('#myGoal').stepProgressBar('removeStep', 500);
        });
</script>

Upvotes: 0

Kalimah
Kalimah

Reputation: 11437

jQuery .sortable has a property called update. It is an event that first when elements move from list to another. You can add your logic there.

See this example:

$(function() {

  let progressbar = $("#progressbar");
  let fill = progressbar.find(".fill");
  let incomplete = progressbar.find(".incomplete");

  $(".items.first-col").sortable({
    connectWith: ".items.second-col",
    receive: function(event, ui) {
      recalculate(ui.item.closest(".items"));
    }
  });

  $(".items.second-col").sortable({
    connectWith: ".items.first-col",
    receive: function(event, ui) {
      recalculate(ui.sender);
    }
  });


  // Calculate items
  function recalculate(items) {
    let total = 0;

    items.find(".credits").each(function() {
      total += parseInt(jQuery(this).val());
    });

    // dont go over 80
    if (total <= 80) {
      let percentage = total * 80 / 100;
      fill.width(percentage + "%");
      fill.find("span").text(total);
      incomplete.find("span").text(80 - total);
    } else {
      $("#timetable .items").sortable('cancel');
    }

    progressbar.attr("data-full", "false");
    if (total == 80) {
      progressbar.attr("data-full", "true");
      fill.width("100%");
    }
  }
  recalculate(jQuery(".items.first-col"));
  $(".items.first-col").sortable("refresh");

});
.bar {
  width: 100px;
  height: 20px;
  margin: 2px;
  border: 1px solid black;
  background-color: lightgreen;
  text-align: center;
  float: left;
  margin: 2px;
  padding: 2px;
  cursor: pointer;
  border-radius: 3px;
}

.list {
  background-color: lightblue;
  border: 1px solid gray;
}

.items .ui-selected {
  background: red;
  color: white;
  font-weight: bold;
}

.items {
  list-style-type: none;
  margin: 0;
  padding: 0;
  width: 100px;
}

.items li {
  margin: 2px;
  padding: 2px;
  cursor: pointer;
  border-radius: 3px;
}

.weekday {
  float: left;
}

.availablelist {
  background-color: orange;
  display: inline;
}

#progressbar {
  display: flex;
  width: 100%;
  border: 1px solid lightgray;
  border-radius: 5px;
  height: 2rem;
  margin-top: 2rem;
  overflow: hidden;
}

#progressbar[data-full='true'] .incomplete {
  padding: 0;
  width: 0;
}

#progressbar>div {
  display: flex;
  align-items: center;
  padding: 1rem;
}

#progressbar .fill {
  background-color: #009a9b;
  color: white;
  transition: all 0.3s;
  white-space: nowrap;
}

#progressbar span {
  padding: 0 5px;
  display: inline-block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<div style="float:left;width:500px;">
  <div>
    <h2>Total Credits = <span id="total-credits">80</span></h2>
  </div>
</div>

<div style="clear:both"></div>
<br>
<div id="timetable" style="float:left;width:700px;">
  <div class="weekday">
    <ul class="items first-col">
      <li class="list">
        <label class="core-ins-tag-numb">Jhonny</label>
        <input type="hidden" value="15" name="credits" class="credits">
      </li>
      <li class="list">
        <label class="core-ins-tag-numb">Tim</label>
        <input type="hidden" value="10" name="credits" class="credits">
      </li>
      <li class="list">
        <label class="core-ins-tag-numb">George</label>
        <input type="hidden" value="25" name="credits" class="credits">
      </li>
      <li class="list">
        <label class="core-ins-tag-numb">Melissa</label>
        <input type="hidden" value="20" name="credits" class="credits">
      </li>
      <li class="list">
        <label class="core-ins-tag-numb">Alice</label>
        <input type="hidden" value="5" name="credits" class="credits">
      </li>
    </ul>
  </div>
  <div class="weekday">
    <ul class="items second-col">
      <li class="list">
        <label class="core-ins-tag-numb">Jhonny</label>
        <input type="hidden" value="20" name="credits" class="credits">
      </li>
      <li class="list">
        <label class="core-ins-tag-numb">Tim</label>
        <input type="hidden" value="10" name="credits" class="credits">
      </li>
      <li class="list">
        <label class="core-ins-tag-numb">George</label>
        <input type="hidden" value="10" name="credits" class="credits">
      </li>
      <li class="list">
        <label class="core-ins-tag-numb">Melissa</label>
        <input type="hidden" value="10" name="credits" class="credits">
      </li>
      <li class="list">
        <label class="core-ins-tag-numb">Alice</label>
        <input type="hidden" value="10" name="credits" class="credits">
      </li>
    </ul>
  </div>
  <br>

  <div id="progressbar" data-full='false'>
    <div class='fill'>
      Total: <span>60</span> / 80 credits
    </div>
    <div class='incomplete'>
      Incomplete: <span>20</span>credits
    </div>
  </div>
</div>

And here is a version with data-* attribute instead of hidden values:

$(function() {

  let progressbar = $("#progressbar");
  let fill = progressbar.find(".fill");
  let incomplete = progressbar.find(".incomplete");

  $(".items.first-col").sortable({
    connectWith: ".items.second-col",
    receive: function(event, ui) {
      recalculate(ui.item.closest(".items"));
    }
  });

  $(".items.second-col").sortable({
    connectWith: ".items.first-col",
    receive: function(event, ui) {
      recalculate(ui.sender);
    }
  });


  // Calculate items
  function recalculate(items) {
    let total = 0;

    items.find("label").each(function() {
      total += parseInt(jQuery(this).attr("data-value"));
    });

    // dont go over 80
    if (total <= 80) {
      let percentage = total * 80 / 100;
      fill.width(percentage + "%");
      fill.find("span").text(total);
      incomplete.find("span").text(80 - total);
    } else {
      $("#timetable .items").sortable('cancel');
    }

    progressbar.attr("data-full", "false");
    if (total == 80) {
      progressbar.attr("data-full", "true");
      fill.width("100%");
    }
  }

  $(".items.first-col").sortable("refresh");

});
.bar {
  width: 100px;
  height: 20px;
  margin: 2px;
  border: 1px solid black;
  background-color: lightgreen;
  text-align: center;
  float: left;
  margin: 2px;
  padding: 2px;
  cursor: pointer;
  border-radius: 3px;
}

.list {
  background-color: lightblue;
  border: 1px solid gray;
}

.items .ui-selected {
  background: red;
  color: white;
  font-weight: bold;
}

.items {
  list-style-type: none;
  margin: 0;
  padding: 0;
  width: 100px;
}

.items li {
  margin: 2px;
  padding: 2px;
  cursor: pointer;
  border-radius: 3px;
}

.weekday {
  float: left;
}

.availablelist {
  background-color: orange;
  display: inline;
}

#progressbar {
  display: flex;
  width: 100%;
  border: 1px solid lightgray;
  border-radius: 5px;
  height: 2rem;
  margin-top: 2rem;
  overflow: hidden;
}

#progressbar[data-full='true'] .incomplete {
  padding: 0;
  width: 0;
}

#progressbar>div {
  display: flex;
  align-items: center;
  padding: 1rem;
}

#progressbar .fill {
  background-color: #009a9b;
  color: white;
  transition: all 0.3s;
  white-space: nowrap;
}

#progressbar span {
  padding: 0 5px;
  display: inline-block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<div style="float:left;width:500px;">
  <div>
    <h2>Total Credits = <span id="total-credits">80</span></h2>
  </div>
</div>

<div style="clear:both"></div>
<br>
<div id="timetable" style="float:left;width:700px;">
  <div class="weekday">
    <ul class="items first-col">
      <li class="list">
        <label class="core-ins-tag-numb" data-value="15">Jhonny</label>
      </li>
      <li class="list">
        <label class="core-ins-tag-numb" data-value='10'>Tim</label>
      </li>
      <li class="list">
        <label class="core-ins-tag-numb" data-value='25'>George</label>
      </li>
      <li class="list">
        <label class="core-ins-tag-numb" data-value='20'>Melissa</label>
      </li>
      <li class="list">
        <label class="core-ins-tag-numb" data-value='5'>Alice</label>
      </li>
    </ul>
  </div>
  <div class="weekday">
    <ul class="items second-col">
      <li class="list">
        <label class="core-ins-tag-numb" data-value='20'>Jhonny</label>
      </li>
      <li class="list">
        <label class="core-ins-tag-numb" data-value='10'>Tim</label>
      </li>
      <li class="list">
        <label class="core-ins-tag-numb" data-value='10'>George</label>
      </li>
      <li class="list">
        <label class="core-ins-tag-numb" data-value='10'>Melissa</label>
      </li>
      <li class="list">
        <label class="core-ins-tag-numb" data-value='10'>Alice</label>
      </li>
    </ul>
  </div>
  <br>

  <div id="progressbar" data-full='false'>
    <div class='fill'>
      Total: <span>60</span> / 80 credits
    </div>
    <div class='incomplete'>
      Incomplete: <span>20</span>credits
    </div>
  </div>
</div>

Upvotes: 2

Related Questions