Reputation: 847
I'm working on a progress bar using the progress
element that increases as the user completes fields in a lengthy form. I found this SO thread which was helpful in getting some baseline functionality using a data-*
attribute, but my form has a "Save Progress" feature that will save any entered field information to the browser's local storage to be retrieved later. Thus, in the event that a user returns to the form with saved data, I'd like the bar to reflect that level of progress.
Here's what is working thus far- sample markup using the data-attribute data-prog
for a form field:
<!-- FORM - SAMPLE FIELD -->
<div id="form">
<div class="field-group required">
<label for="mgd_org_name">Organization Name:</label>
<div>
<input id="mgd_org_name" type="text" name="mgd_org_name" placeholder="Please enter your organization's name" required data-prog="6">
</div>
</div>
</form>
<!-- Progress bar -->
<div id="form-progress">
<p>Form Progress</p>
<progress max="100" value="0" id="progress"></progress>
</div>
And the jQuery thus far:
$(function() {
// get all form inputs w/ data-prog values
var inputs = $('#dossier-form').find('input[data-prog], textarea[data-prog]');
var progBar = $('#progress');
var progVal = 0;
$(inputs).change(function() {
if ($(this).val().length > 0) {
progVal += $(this).data('prog');
progBar.attr('value', progVal);
}
});
});
In this way, each field has a data-prog
value that will be added to the progVal
and reflected in the progress bar level. What I'm having trouble with is loading an initial value for any form fields that might already be filled on load—thus, I would need to find all fields that have a value entered, add the associated data-prog
values, and initially load that value into the progress bar. I would also like to accordingly decrease the progress value in the event that a field is cleared.
For the initial load, I've been trying something like the following (not working):
var inputsSaved = $(inputs).val();
if($(inputsSaved).length > 0) {
progVal = $(inputs).data('prog');
console.log('has existing progress');
} else {
progVal = 0;
console.log('does not have existing progress');
}
I'm not quite sure how to find the fields with text entered on load and grab the associated prog values nor how to decrease the value accordingly if a field is cleared. Any assistance here is greatly appreciated!
Upvotes: 0
Views: 1108
Reputation: 33933
First, your inputs
selector can be replaced by:
var inputs = $('#dossier-form [data-prog]');
Then, $(inputs).change(...
, inputs
already is a jQuery object. No need to wrap it with $()
.
You had the progress update function correct. I just placed it in a named function to be able to call it from different places in code (and avoid duplicate code).
I added the localStorage
save and retreive...
$(function() {
// get all form inputs w/ data-prog values
var inputs = $('#dossier-form [data-prog]');
var progBar = $('#progress');
var progVal = 0;
// Establish the "dificulty unit" base.
var totalDifficulty = 0;
inputs.each(function(){
totalDifficulty += $(this).data('prog');
});
var difficultyUnit = 100/totalDifficulty;
// Update progressbar
function updateProgress(el){
progVal += parseFloat($(el).data('prog')) * difficultyUnit;
progBar.val(progVal);
}
// LocalStorage on load
inputs.each(function(){
var value = localStorage.getItem(this.id);
if(value !=null && value !=""){
$(this).val(value);
updateProgress(this);
}
}); // End load from LocalStorage
// Blur handler to save user inputs
inputs.on("blur",function(){
// Reset the progress
progVal = 0;
progBar.val(progVal);
// Loop through all inputs for progress
inputs.each(function(){
if ($(this).val().length > 0) {
updateProgress(this);
}
// LocalStorage
localStorage.setItem(this.id,this.value);
});
}); // End on blur
}); // End ready
localStorage
isn't allowed in the SO snippets... So have a look at this CodePen.
So you can now give some "difficulty level" without worring about the total obtained by all the data-prog
to be 100. Just give an arbitrary number you feel like. ;)
Upvotes: 1
Reputation: 4596
If you always add up the progress from scratch, you can do the same thing in both cases.
$(function() {
// get all form inputs w/ data-prog values
var inputs = $('#dossier-form').find('input[data-prog], textarea[data-prog]');
var progBar = $('#progress');
function update () {
var progVal = 0;
inputs.each( function () {
if ($(this).val().length > 0) {
progVal += Number( $(this).data('prog') );
}
})
progBar.attr('value', progVal);
}
inputs.change( update );
// Fill in fields from localStorage, then:
update();
});
Upvotes: 1