0

I get a code from other app that changes progress. Based on progress bar width property, can I change progress text?

I want an event that update the progress-indicator-text when progress-indicator-bar width changes. Code here:

$(function() {
  //For demo purpose only
  $('button').click(function() {
    var percentWidth = $('.progress-indicator-bar').width() / $('.progress-indicator-bar').parent().width() * 100;
    if (percentWidth < 100) $('.progress-indicator-bar').width(percentWidth + 10 + "%");
  })
  //Requires appropriate event/approach to change the text of .progress-indicator-text when width of .progress-indicator-bar changes.
  $('.progress-indicator-bar').change(function() {
    $('.progress-indicator-text').html($('.progress-indicator-bar').width() / $('.progress-indicator-bar').parent().width() * 100 + "%");
  })
});
.progress-indicator-bar-holder {
  width: 100px;
  height: 10px;
  background: #e4e4e4;
  float: left;
}

.progress-indicator-bar {
  background: #008000;
  height: 10px;
}

.progress-indicator-text {
  font-weight: bold;
  font-size: 11px;
  line-height: 8px;
  margin-left: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- This code embeds from another application -->
<div class="progress-indicator">
  <div class="progress-indicator-bar-holder">
    <div class="progress-indicator-bar" style="width: 30%;"></div>
  </div>
</div>
<!-- Based on progress-indicator-bar width the progress-indicator-text should change -->
<div class="progress-indicator-text">30%</div>
<br>
<button>Change</button>
Kunj
  • 1,980
  • 2
  • 22
  • 34
  • What's the problem with just calling your update function inside your `$('button').click` callback? – TKoL Jun 12 '19 at 10:41
  • Hi @TKoL , thanks for reply. Button is for demo purpose only. I want an event that update the `progress-indicator-text` when `progress-indicator-bar` width changes. – Kunj Jun 12 '19 at 10:44
  • Stack the current percent in a hidden input, inputs do benefit of the `change` event, and so, you can listen to it. – darklightcode Jun 12 '19 at 10:45
  • Just add this line ` $('.progress-indicator-bar').trigger('change') ` at the end of button.click handler – darklightcode Jun 12 '19 at 10:47
  • Hi @darklightcode , that should work, I try, thanks for reply. – Kunj Jun 12 '19 at 10:51
  • That will only work if you put that trigger code EVERYWHERE that you change the width, and if you're willing to do that, you might as well just call the function manually like I said anyway. – TKoL Jun 12 '19 at 10:57
  • If you want code that gets triggered when the element changes no matter where it changes, without having to also specify to trigger the change event, use the MutationObserver answer. – TKoL Jun 12 '19 at 10:57
  • Hi @TKoL , thanks for suggestion. I try it. – Kunj Jun 12 '19 at 11:03

3 Answers3

2

It's a bit like breaking a butterfly on a wheel but you can utilize the MutationObserver API to watch for changes in the DOM.

Just register the div holding the percentage bar and whenever it's style attribute changes update the div containing the text.

Here's an example:

//For demo purpose only
$('button').click(function() {

  var percentWidth = $('.progress-indicator-bar').width() / $('.progress-indicator-bar').parent().width() * 100;
  if (percentWidth < 100) $('.progress-indicator-bar').width(percentWidth + 10 + "%");
})

var target = document.getElementsByClassName('progress-indicator-bar');
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    if (mutation.attributeName == "style") {
      $('.progress-indicator-text').html($('.progress-indicator-bar').width() / $('.progress-indicator-bar').parent().width() * 100 + "%");
    }
  });
});

var config = {
  attributes: true,
  childList: true,
  characterData: true
};
observer.observe(target[0], config);
.progress-indicator-bar-holder {
  width: 100px;
  height: 10px;
  background: #e4e4e4;
  float: left;
}

.progress-indicator-bar {
  background: #008000;
  height: 10px;
}

.progress-indicator-text {
  font-weight: bold;
  font-size: 11px;
  line-height: 8px;
  margin-left: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="progress-indicator">
  <div class="progress-indicator-bar-holder">
    <div class="progress-indicator-bar" style="width: 30%;"></div>
  </div>
</div>
<!-- Based on progress-indicator-bar width the progress-indicator-text should change -->
<div class="progress-indicator-text">30%</div>
<br>
<button>Change</button>
obscure
  • 11,916
  • 2
  • 17
  • 36
  • Exemplary, answered a paradigm, I read MutationObserver first time and find it provides the ability to watch for changes being made to the DOM. Thanks. – Kunj Jun 12 '19 at 12:23
1

You can trigger events in jQuery with the .trigger method when you are in a handler.

$(function() {
  //For demo purpose only
  $('button').click(function() {
    var percentWidth = $('.progress-indicator-bar').width() / $('.progress-indicator-bar').parent().width() * 100;
    if (percentWidth < 100) $('.progress-indicator-bar').width(percentWidth + 10 + "%");
    $('.progress-indicator-bar').trigger('change') // i added this line
  })
  //Requires appropriate event/approach to change the text of .progress-indicator-text when width of .progress-indicator-bar changes.
  $('.progress-indicator-bar').change(function() {
    $('.progress-indicator-text').html($('.progress-indicator-bar').width() / $('.progress-indicator-bar').parent().width() * 100 + "%");
  })
});
.progress-indicator-bar-holder {
  width: 100px;
  height: 10px;
  background: #e4e4e4;
  float: left;
}

.progress-indicator-bar {
  background: #008000;
  height: 10px;
}

.progress-indicator-text {
  font-weight: bold;
  font-size: 11px;
  line-height: 8px;
  margin-left: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- This code embeds from another application -->
<div class="progress-indicator">
  <div class="progress-indicator-bar-holder">
    <div class="progress-indicator-bar" style="width: 30%;"></div>
  </div>
</div>
<!-- Based on progress-indicator-bar width the progress-indicator-text should change -->
<div class="progress-indicator-text">30%</div>
<br>
<button>Change</button>
darklightcode
  • 2,738
  • 1
  • 14
  • 17
0

you can use the ResizeSensor to detect the width change of the element. please refer this page How to detect DIV's dimension changed?

flashyhawk
  • 11
  • 1