Progress bar animation when inputing form - javascript

I want to make when my form is filled by someone, the progress bar width increase by 20.
<form action="class/action.php" method="post">
<div class="col-sm-3">
<div class="form-group label-floating">
<label class="control-label">Name </label>
<input id="1" type="text" class="form-control pgbar" name="name" required>
</div>
</div>
</form>
<!-- Progress bar -->
<div class="container">
<div class="row">
<div class="col-md-offset-6">
<div class="progress progress-line-primary ">
<div class="progress-bar" id="progressbar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 1%;"> </div>
</div>
</div>
</div>
</div>
//javascript
$( "#progressbar" ).progressbar({
value: 0
});
$(".pgbar").change(function() {
var pbVal = 0;
if ($("#1").val().length > 0) pbVal += 20;
if ($("#2").val().length > 0) pbVal += 20;
if ($("#3").val().length > 0) pbVal += 20;
if ($("#4").val().length > 0) pbVal += 20;
if ($("#5").val().length > 0) pbVal += 20;
$( "#progressbar" ).progressbar( "option", "value", pbVal );
return false;
});
i am not sure its wrong with my html or javascript. Thanks for help, appreciate it.

Hopefully, you've included the theme CSS file so that you can see your progress bar in the first place (code below).
And, speaking of style, your style is set to 1% by default. Even when it works, you'll never see it. The width doesn't have to be 100%, but it has to be big enough to see.
Next, it's easier to keep a count of the non-empty elements, not necessarily the final progress bar value because if you add responses or remove responses later, your math will be wrong.
Then you just divide the number of non-empty fields by the amount of fields and set that as the value. You were setting value as an option, but according to the docs, that's not how to do it:
( ".selector" ).progressbar( "value", 50 );
Also, it's simpler (and more scalable) to just loop through each of the fields and check their val() for non-empty than to test each one individually.
Here's an example with the non-relevant stuff taken out:
$(function() {
$("#progressbar").progressbar({ value: 0 });
// Apply the styling that is defined in the linked CSS stylesheet
$("#progressbar").progressbar( "option", "classes.ui-progressbar", "highlight" );
});
// Us the ".on()" method instead of "change" as recommended by jQuery
$("input").on("change", function() {
var count = 0; // We won't be storing a final value, just a count of non-empty fields
// Loop through the fields (better than testing one-by-one)
$("input").each(function(idx, input){
// Test the value for non-empty and increase the count if empty
if($(input).val() !== "") { count++ };
});
// Now you can calculate the whole number representation of the % of completed fields
var pbVal = (count / $("input").length) * 100;
// Set the progress bar to the value
$("#progressbar").progressbar("value", pbVal);
// EXTRA CREDIT: When the progress = 100%, enable the submit button
$("button").prop("disabled", pbVal !== 100);
});
input { display: block; }
#progressbar { display:inline-block; width:75%; border-radius:25px; }
div { margin:1em 0; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<!-- Make sure you have the CSS linked to for visibility and styling -->
<link href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet">
<!-- **************************************************************************** -->
<form action="class/action.php" method="post">
<input id="1">
<input id="2">
<input id="3">
<input id="4">
<input id="5">
</form>
<!-- Progress bar -->
<div>0%<span id="progressbar"></span>100%</div>
<button disabled>Submit</button>

I'm unsure of the issue because I cannot see a working example. Here is a working solution.
$("#progressbar").progressbar({
value: 0
});
var $inputs = $(".form-group").children("input");
var totalInputs = $inputs.length;
$inputs.on('keyup', function() {
var pbVal = 0;
$inputs.each(function(){
if($(this).val().length > 0) pbVal ++;
});
$("#progressbar").progressbar("option", "value", (pbVal/totalInputs)*100)
});
.container{
width: 100%
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>
<form action="class/action.php" method="post">
<div class="col-sm-3">
<div class="form-group label-floating">
<label class="control-label">1</label>
<input id="input-1" type="text" class="form-control pgbar" name="name" required>
<label class="control-label">2</label>
<input id="input-2" type="text" class="form-control pgbar" name="name" required>
<label class="control-label">3</label>
<input id="input-3" type="text" class="form-control pgbar" name="name" required>
<label class="control-label">4</label>
<input id="input-4" type="text" class="form-control pgbar" name="name" required>
</div>
</div>
</form>
<!-- Progress bar -->
<div class="container">
<div class="row">
<div class="col-md-offset-6">
<div class="progress progress-line-primary ">
<div class="progress-bar" id="progressbar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"> </div>
</div>
</div>
</div>
</div>

Related

Combined total for multiple Sliders (Bootstrap v4 & jQuery)

I'm trying to implement a page with 3 sliders. The combined total of all 3 sliders should never go over 100%.
The page uses the Bootstrap 4 framework and jQuery 3.6.2
These is where I struggle:
The combined value of all three sliders should never be over 100%. Increasing one slider should decrease the other two values and vice versa.
Here is what I have done so far:
HTML
<div id="sliders">
<div class="row">
<label for="Focus1" class="form-label">Slider 1</label>
</div>
<div class="row">
<input id="sl1" type="text" data-slider-min="0" data-slider-max="100" data-slider-step="1" data-slider-value="34" data-value="34" value="34" style="display: none;">
<span id="sl1CurrentSliderValLabel"> <span class="value" id="sl1SliderVal">34</span>%</span>
</div>
<div class="row">
<label for="Focus2" class="form-label">Slider 2</label>
</div>
<div class="row">
<input id="sl2" type="text" data-slider-min="0" data-slider-max="100" data-slider-step="1" data-slider-value="33" data-value="33" value="33" style="display: none;"/>
<span id="sl2CurrentSliderValLabel"> <span class="value" id="sl2SliderVal">33</span>%</span>
</div>
<div class="row">
<label for="Focus3" class="form-label">Slider 3</label>
</div>
<div class="row">
<input id="sl3" type="text" data-slider-min="0" data-slider-max="100" data-slider-step="1" data-slider-value="33" data-value="33" value="33" style="display: none;"/>
<span id="sl3CurrentSliderValLabel"> <span class="value" id="sl3SliderVal">33</span>%</span>
</div>
</div>
JS
`
<script>
$(document).ready(function() {
$('.tooltip').tooltip();
/* Slider 1 */
$("#sl1").slider();
$("#sl1").on('slide', function(slideEvt) {
$("#sl1SliderVal").text(slideEvt.value);
});
/* Slider 2 */
$("#sl2").slider();
$("#sl2").on('slide', function(slideEvt) {
$("#sl2SliderVal").text(slideEvt.value);
});
/* Slider 3 */
$("#sl3").slider();
$("#sl3").on('slide', function(slideEvt) {
$("#sl3SliderVal").text(slideEvt.value);
});
});
/* Start Slider Logic */
var sliders = $("#sliders .slider");
var availableTotal = 100;
sliders.each(function() {
var init_value = parseInt($(this).text());
$(this).siblings('.value').text(init_value);
$(this).empty().slider({
value: init_value,
min: 0,
max: availableTotal,
range: "max",
step: 2,
animate: 0,
slide: function(event, ui) {
// Update display to current value
$(this).siblings('.value').text(ui.value);
// Get current total
var total = 0;
sliders.not(this).each(function() {
total += $(this).slider("option", "value");
});
total += ui.value;
var delta = availableTotal - total;
// Update each slider
sliders.not(this).each(function() {
var t = $(this),
value = t.slider("option", "value");
var new_value = value + (delta/2);
if (new_value < 0 || ui.value == 100)
new_value = 0;
if (new_value > 100)
new_value = 100;
t.siblings('.value').text(new_value);
t.slider('value', new_value);
});
}
});
});
</script>`
CSS
<link href="../css/bootstrap.min.css" rel="stylesheet">
<link href="../css/bootstrap-slider.css" rel="stylesheet">
Thanks a lot for your help!
The main problem was to use the correct API call at the right time.
This is the correct code to make the sliders work as intended:
JS
`
<script>
$(document).ready(function() {
$('.tooltip').tooltip();
var sliders = $("#sliders .slider");
var availableTotal = 100;
sliders.each(function() {
var init_value = parseInt(this.value);
$(this).siblings('.value').text(init_value);
$(this).empty().slider({
value: init_value,
min: 0,
max: availableTotal,
range: false,
step: 2,
animate: 0
});
$(this).on( "slide", function( event ) {
var slVal = parseInt($(this).val());
// Update display to current value
$(this).siblings('.value').text(slVal);
// Get current total
var total = 0;
sliders.not(this).each(function() {
total += parseInt($(this).val());
});
// Need to do this because apparently jQ UI
// does not update value until this event completes
total += slVal;
var delta = availableTotal - total;
// Update each slider
sliders.not(this).each(function() {
var t = $(this),
value = parseInt(t.slider('getValue'));
var new_value = parseInt(value + (delta/2));
if (new_value < 0 || slVal == 100)
new_value = 0;
if (new_value > 100)
new_value = 100;
t.siblings('.value').text(new_value);
t.slider('setValue',new_value);
});} );
});
});
</script>`
HTML
<div id="sliders">
<div class="row g-6">
<label for="Focus1" class="form-label">Slider 1</label>
</div>
<div class="row g-6">
<input class="slider" id="sl1" type="text" data-slider-min="0" data-slider-max="100" data-slider-step="1" data-slider-value="34" data-value="34" value="34" style="display: none;">
<span class="value" id="sl1SliderVal">34</span><span id="sl1CurrentSliderValLabel">%</span>
</div>
<div class="row g-6">
<label for="Focus2" class="form-label">Slider 2</label>
</div>
<div class="row g-6">
<input class="slider" id="sl2" type="text" data-slider-min="0" data-slider-max="100" data-slider-step="1" data-slider-value="33" data-value="33" value="33" style="display: none;"/>
<span class="value" id="sl2SliderVal">33</span><span id="sl2CurrentSliderValLabel">%</span>
</div>
<div class="row g-6">
<label for="Focus3" class="form-label">Slider 3</label>
</div>
<div class="row g-6">
<input class="slider" id="sl3" type="text" data-slider-min="0" data-slider-max="100" data-slider-step="1" data-slider-value="33" data-value="33" value="33" style="display: none;"/>
<span class="value" id="sl3SliderVal">33</span><span id="sl3CurrentSliderValLabel">%</span>
</div>
</div>
The CSS section from the question is unchanged.

jQuery input field .val() is undefined

I'm having a problem with an error: jQuery input val() is undefiend.
I have 3 inputs which are referring to one item.
On add Row i can add an new Item ( 3 rows ).
All those rows have to be prepared in array to be sent to a PHP file.
I believe that my id="item[0]['name']" is wrong.
$(document).ready(function() {
var counter = 1;
$("#addRow").click(function() {
$("#ItemContainer").append(`
<div class="item">
<div><input type="text" id="item[${counter}]['name']" placeholder="Name" ></div>
<div><input type="text" id="item[${counter}]['amount']" placeholder="Amount" ></div>
<div><input type="text" id="item[${counter}]['count']" placeholder="Count" ></div>
<div></div>
</div>
`);
counter = counter + 1;
});
$("#setKasse").click(function() {
for (let i = 0; i <= (counter - 1); i++) {
console.log($(`#item[${i}]`));
console.log($(`#item[${i}]["name"]`).val());
};
});
});
*{
padding: 0;
margin: 0;
}
body{
background-color: #E6E6FA;
color : #191970;
padding-left : 5%;
padding-top : 70px
}
#Container, #ItemContainer, .item {
width: 20%;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto;
row-gap : 18px;
}
#ItemContainer, .item{
width: 100%;
row-gap : 2px;
}
input{
height: 30px;
width: 100%;
border: none;
box-sizing: border-box;
padding-left: 4px;
font-size: 14px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="Container">
<div><button id="addRow"> Add Row </button></div>
<div id="ItemContainer">
<div class="item">
<div><input type="text" id="item[0]['name']" placeholder="Name" ></div>
<div><input type="text" id="item[0]['amount']" placeholder="Amount" ></div>
<div><input type="text" id="item[0]['count']" placeholder="Count" ></div>
<div></div>
</div>
</div>
<div><button id="setKasse"> Set Kasse </button></div>
</div>
So, I want a way to be able to cycle and loop into objects|Arrays
My main goal is to send the data via Ajax Post request, and for that I want to refactor the Array in another Format.
In selectors, [ is used to indicate an attribute selector. If you want to use it as a literal character in the ID, you need to escape it with backslash. You also need to escape the ' characters.
You also need to include the ['name'] part of the ID (or ['amount'] or ['count'] if you want to get those inputs).
$(document).ready(function() {
var counter = 1;
$("#addRow").click(function() {
$("#ItemContainer").append(`
<div class="item">
<div><input type="text" id="item[${counter}]['name']" placeholder="Name" ></div>
<div><input type="text" id="item[${counter}]['amount']" placeholder="Amount" ></div>
<div><input type="text" id="item[${counter}]['count']" placeholder="Count" ></div>
<div></div>
</div>
`);
counter = counter + 1;
}); // end of $("#addRow").click
$("#setKasse").click(function() {
for (let i = 0; i <= (counter - 1); i++) {
console.log($(`#item\\[${i}\\]\\[\\'name\\'\\]`).val());
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="Container">
<div><button id="addRow"> Add Row </button></div>
<div id="ItemContainer">
<div class="item">
<div><input type="text" id="item[0]['name']" placeholder="Name"></div>
<div><input type="text" id="item[0]['amount']" placeholder="Amount"></div>
<div><input type="text" id="item[0]['count']" placeholder="Count"></div>
<div></div>
</div>
</div>
<div><button id="setKasse"> Set Kasse </button></div>
</div>
In my opinion, it's best to avoid using characters that have special meaning in CSS selectors in your IDs, it complicates the code unnecessarily. You could use id="item-${counter}-name". Or don't use IDs for dynamically created elements at all. Use a class like class="name", and then use dynamic indexing. $(".item").eq(i).find("input.name").
$(document).ready(function() {
var counter = 1;
$("#addRow").click(function() {
$("#ItemContainer").append(`
<div class="item">
<div><input type="text" class="name" placeholder="Name" ></div>
<div><input type="text" class="amount" placeholder="Amount" ></div>
<div><input type="text" class="count" placeholder="Count" ></div>
<div></div>
</div>
`);
counter = counter + 1;
}); // end of $("#addRow").click
$("#setKasse").click(function() {
for (let i = 0; i < counter; i++) {
console.log($(".item").eq(i).find(".name").val());
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="Container">
<div><button id="addRow"> Add Row </button></div>
<div id="ItemContainer">
<div class="item">
<div><input type="text" class="name" placeholder="Name"></div>
<div><input type="text" class="amount" placeholder="Amount"></div>
<div><input type="text" class="count" placeholder="Count"></div>
<div></div>
</div>
</div>
<div><button id="setKasse"> Set Kasse </button></div>
</div>

Appending and detaching dynamically created inputs

I have two radio buttons:
fixed_price_option (Selected by default.)
variable_price_option (Disabled by default)
I also have two types of inputs:
fixed_price_input (Visable by default. Only one occurance.)
variable_price_input (Not present in code as it has to be added dynamically. One or more occurances.)
When fixed_price_option is selected an input called fixed_price_input should be visable and included when later running .serialize().
When fixed_price_option is selected no variable_price_input´s should be visible or included when later running .serialize().
variable_price_option should only be selectable when the difference between two date inputs are more than 12 months. (this I have solved)
When variable_price_option is selected there should be one more variable_price_input´s visable as there are whole years between the two date inputs (i.e. durationMonths + 1). They also need to be included when later running .serialize() so they need to have names like price_year_1, price_year_2, price_year_3 and so on, depending on how many whole years there are between the two date inputs.
When variable_price_option is selected fixed_price_input should not be visible or included when later running .serialize().
I have supplied the code as far as I have come. The missing logic needs to be put in the event handler at the bottom of the js code.
Any suggestions on how to solve this?
-- UPDATE --
My question needed clarification:
What I'm struggling with is to toggle the existence of the two types of inputs (fixed_price_input and variable_price_input) depending on which radio button is checked. Hiding/showing them isn't enough because I'm going to use .serialize() at a later point. Should I use .detach() and .append() somehow?
I'm also struggling with how to create one more variable_price_input's than there are years between the start and end date. Should I use <template> or .clone() somehow?
$(document).ready(function() {
$("#inputStartDate, #inputEndDate").change(function() {
if ($('#inputStartDate').val() && $('#inputEndDate').val()) {
var startDate = moment($('#inputStartDate').val());
var endDate = moment($('#inputEndDate').val());
var durationMonths = endDate.diff(startDate, 'months');
$('#durationMonths').text(durationMonths);
var durationYears = endDate.diff(startDate, 'years');
$('#durationYears').text(durationYears);
if (duration > 12) {
$('#variablePriceOption').prop("disabled", false);
} else {
$('#variablePriceOption').prop("disabled", true);
}
}
});
$('#variablePriceOption, #fixedPriceOption').change(function() {
if (this.value == 'fixedPrice') {
//Logic needed
} else if (this.value == 'variablePrice') {
//Logic needed
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<div class="container">
<div class="row mt-3">
<div class="col">
<div class="form-group">
<label for="inputStartDate">Start date</label>
<input type="date" class="form-control" id="inputStartDate" name="land_contract_start_date">
</div>
</div>
<div class="col">
<div class="form-group">
<label for="inputEndDate">End date</label>
<input type="date" class="form-control" id="inputEndDate" name="land_contract_end_date">
</div>
</div>
</div>
<div class="text-center">Months between selected dates = <span id="durationMonths"></span>. Years between selected dates = <span id="durationYears"></span>.
</div>
<div class="form-group">
<label for="inputPriceModel">Price model</label>
<div id="inputPriceModel">
<div class="form-check">
<input class="form-check-input" type="radio" name="inputPriceModel" id="fixedPriceOption" value="fixedPrice" required checked="checked">
<label class="form-check-label" for="fixedPriceOption">
Fixed price
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="inputPriceModel" id="variablePriceOption" value="variablePrice" disabled="disabled">
<label class="form-check-label" for="variablePriceOption">
Variable price
</label>
</div>
</div>
</div>
<div class="form-group fixedPriceModelFormGroup">
<label for="fixed_price_input">Fixed price amount</label>
<div class="input-group">
<input type="number" class="form-control" id="fixed_price_input" name="land_contract_fixed_annual_price">
<div class="input-group-append">
<span class="input-group-text">$</span>
</div>
</div>
</div>
</div>
This should help get you started as far as variable pricing inputs showing for each # of year difference of the calendar dates. The code could be broken out into other functions for handling the display/hiding of elements, etc. You need to move your <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> code above your other JS references to get rid of the errors you're seeing for bootstrap.
Also, your duration variable should be durationMonths for comparing > 12, as duration is undefined. durationYears should be moved outside the change function of the calendar dates so you can reference it in your other processing functions. I added Math.abs() to the date calculations to ensure you're dealing with a positive integer for comparisons.
Using the disabled attribute on the inputs that are hidden will allow you to serialize the visible form data and ensure you won't get hidden inputs (variable pricing fields, etc) as part of the serialization data.
As #Twisty mentioned in the comments on your post, you will want to use .detach() or some sort of way to store the variable pricing input values if you toggle back and forth between Fixed/Variable options (localStorage, sessionStorage also options for storing data), if you want to maintain any values placed in the variable/fixed inputs. You will need to remove the .empty() usage on the input fields in my example as well, if you intend to store the data values of the inputs.
The loop function handleVariablePricing for determining how many variable pricing inputs should show would need to hook into the stored data functionality to ensure you are creating the same amount of fields with previously entered values, and not adding additional new fields on top of the existing fields/values.
$(document).ready(function() {
var durationYears = 0;
$("#inputStartDate, #inputEndDate").change(function() {
if ($('#inputStartDate').val() && $('#inputEndDate').val()) {
var startDate = moment($('#inputStartDate').val());
var endDate = moment($('#inputEndDate').val());
var durationMonths = Math.abs(endDate.diff(startDate, 'months'));
$('#durationMonths').text(durationMonths);
// maintain value outside of change function
durationYears = Math.abs(endDate.diff(startDate, 'years'));
$('#durationYears').text(durationYears);
if (durationMonths > 12) {
$('#variablePriceOption').prop("disabled", false);
} else {
$('#variablePriceOption').prop("disabled", true);
}
// If dates changed, update variable inputs shown
if ($('#variablePriceOption').is(':checked')) {
if (durationMonths > 12) {
$('#variable_price_input_1').val('');
$('.duration-years-input').remove();
handleVariablePricing();
} else {
$('#fixedPriceOption').click();
}
}
}
});
$('#variablePriceOption, #fixedPriceOption').change(function() {
if (this.value == 'fixedPrice') {
$('.variablePriceModelFormGroup').removeClass('d-block').addClass('d-none');
$('.variablePriceModelFormGroup input').each(function() {
$(this).val('').attr('disabled', true);
});
$('.fixedPriceModelFormGroup input').prop('disabled', false);
$('.fixedPriceModelFormGroup').removeClass('d-none').addClass('d-block');
$('.duration-years-input').remove();
} else if (this.value == 'variablePrice') {
$('.fixedPriceModelFormGroup').removeClass('d-block').addClass('d-none');
$('.fixedPriceModelFormGroup input').val('').attr('disabled', true);
$('#variable_price_input_1').prop('disabled', false);
$('.variablePriceModelFormGroup').removeClass('d-none').addClass('d-block');
handleVariablePricing();
}
});
/**
* Creates inputs for variable pricing..
**/
var handleVariablePricing = function() {
$rowClone = $('.row-main').clone();
for (var i = 2; i <= durationYears + 1; i++) {
$rowClone.prop('class', 'duration-years-input');
$rowClone.find('label').text('Price Year ' + i);
$rowClone.find('input').prop('id', 'variable_price_input_' + i);
$rowClone.find('input').prop('name', 'land_contract_variable_annual_price_' + i);
if ($('.duration-years-input').length === 0) {
$('.row-main').after($rowClone);
} else {
$('.duration-years-input').last().after($rowClone);
}
$rowClone = $('.duration-years-input').last().clone();
}
};
$('button').click(function() {
console.log($('#test-form').serialize());
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<div class="container">
<form id="test-form">
<div class="row mt-3">
<div class="col">
<div class="form-group">
<label for="inputStartDate">Start date</label>
<input type="date" class="form-control" id="inputStartDate" name="land_contract_start_date">
</div>
</div>
<div class="col">
<div class="form-group">
<label for="inputEndDate">End date</label>
<input type="date" class="form-control" id="inputEndDate" name="land_contract_end_date">
</div>
</div>
</div>
<div class="text-center">Months between selected dates = <span id="durationMonths"></span>. Years between selected dates = <span id="durationYears"></span>.
</div>
<div class="form-group">
<label for="inputPriceModel">Price model</label>
<div id="inputPriceModel">
<div class="form-check">
<input class="form-check-input" type="radio" name="inputPriceModel" id="fixedPriceOption" value="fixedPrice" required checked="checked">
<label class="form-check-label" for="fixedPriceOption">
Fixed price
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="inputPriceModel" id="variablePriceOption" value="variablePrice" disabled="disabled">
<label class="form-check-label" for="variablePriceOption">
Variable price
</label>
</div>
</div>
</div>
<div class="form-group fixedPriceModelFormGroup">
<label for="fixed_price_input">Fixed price amount</label>
<div class="input-group">
<input type="number" class="form-control" id="fixed_price_input" name="land_contract_fixed_annual_price">
<div class="input-group-append">
<span class="input-group-text">$</span>
</div>
</div>
</div>
<div class="form-group variablePriceModelFormGroup d-none">
<div class="row-main">
<label for="variable_price_input">Price Year 1</label>
<div class="input-group">
<input type="number" class="form-control" id="variable_price_input_1" name="land_contract_variable_annual_price_1" disabled="disabled">
<div class="input-group-append">
<span class="input-group-text">$</span>
</div>
</div>
</div>
</div>
</form>
<button>Serialize</button>
</div>

Total of input fields should not exceed certain Amount

I have created an Add / Remove input fields. I want to get total of 'Amount' using Javascript which should not exceed 100%. Means the total of amount should not exceed 10000.
Say for example first field will have 3000, second will have 6000 and third will have 1000. If we enter larger number it should not accept it.
var i = 0;
jQuery(document).ready(function($) {
//fadeout selected item and remove
$(document).on('click', '#remove-allocation-fields', function(event) {
event.preventDefault();
$(this).parent().fadeOut(300, function() {
$(this).parent().empty();
return false;
});
});
var rows = '<div class="fund-fields"><div class="row"><div class="col-md-5"><div class="form-group"><input type="text" class="form-control" name="allocate_items[]" placeholder=""></div></div><div class="col-md-5"><div class="form-group"><input type="text" class="form-control" name="allocate_amount[]" placeholder=""></div></div><div class="col-md-2"><button type="button" class="btn btn-danger" id="remove-allocation-fields"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Remove</button></div></div><div class="clear"></div></div>';
//add input
$('#add-allocation-fields').click(function() {
$(rows).fadeIn("slow").appendTo('#fund-allocation-fields');
i++;
return false;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="panel panel-default">
<div class="panel-heading">
<center><b>Allocation of Funds</b></center>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-5">
<label>Allocation Items <b style="color:#FF0000;">*</b></label>
</div>
<div class="col-md-5">
<label>Amount <b style="color:#FF0000;">*</b></label>
</div>
<div class="col-md-2"></div>
</div>
<div class="row">
<div class="col-md-5">
<div class="form-group">
<input type="text" class="form-control" name="allocate_items[]" placeholder="">
</div>
</div>
<div class="col-md-5">
<div class="form-group">
<input type="text" class="form-control" name="allocate_amount[]" placeholder="">
</div>
</div>
<div class="col-md-2">
<button type="button" class="btn btn-success" id="add-allocation-fields">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
Add
</button>
</div>
</div>
<div id="fund-allocation-fields"></div>
<p class="help-block"><i>Total amount must be equal to the goal amount.</i></p>
</div>
</div>
Please Help me. Thanks in advance.
If I understand correctly you could do something as simple as:
var val1 = document.getElementById('inputOne').value;
var val2 = document.getElementById('inputTwo').value;
var val3 = document.getElementById('inputThree').value;
if(val1+val2+val3 < 10000){
// Less then 10000 so do your stuff
} else{
// More then 10000 so let the user know they went too far
}
You can also do it in jQuery. Just change document.getElementById('inputOne').value to $('#inputOne').val()
If the elements are built dynamically you could just do something like this:
var inputs = Array.from(document.querySelectorAll('.inputsToAdd'));
var number = 100;
document.getElementById('btn').addEventListener('click', ()=>{
inputs.map(input=>{
number+=parseInt(input.value);
})
if(number<10000)
console.log(true);
else console.log(false)
})
This is a bit of a connundrum since you have the ability to add infinite input fields, in common practice this is a bad UI experience but to resolve your issue.
You want to sum all the values on click and if the values are too high throw an error. You can accomplish this by assigning each inputField a class and then summing the collection of that class.
I made a small sample using jQuery, a conditional and .each() like so:
$('#sum').click(function(){
var nums = 0
$('.valueField').each(function(){
nums += parseInt(this.value)
});
nums > 10000 ? console.log("value too high", nums) : console.log("compute works", nums)
})
See my small demo below:
$('#sum').click(function() {
var nums = 0
$('.valueField').each(function() {
nums += parseInt(this.value)
});
nums > 10000 ? alert("value too high", nums) : alert("compute works", nums)
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<input type='number' class='valueField' />
<input type='number' class='valueField' />
<input type='number' class='valueField' />
<button id='sum'>Click</button>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</body>
</html>

Change href to tel: + number (user defined)

I'm trying to write a script where users can type a phone number and store it in the input (which works in this demo: http://bootsnipp.com/snippets/featured/iphone-number-pad) and then update href="" = "tel:" + that-same-value. So for example the if the user types 600 999 999 the href is updated to href="tel:600 999 999" and the user can then click the the button and make a call.
I've been beating myself up trying to figure this out. It seemed really simple because I'm not even trying to use restrict the phone number to 6-7 characters long.
Any help would be greatly appreciated.
$(document).ready(function() {
// Get number
$('.num').click(function() {
var num = $(this);
var text = $.trim(num.find('.txt').clone().children().remove().end().text());
var telNumber = $('#telNumber');
$(telNumber).val(telNumber.val() + text);
$('#call-this').href = "tel:" + $(telNumber).val(telNumber.val() + text)
console.log(text);
console.log(telNumber);
});
// add number to href
var call = $(#call - this).attr('target')
// Other stuff I've tired
// $('#call-this').click(
// $('#call-this').href="tel:" + $(telNumber).val(telNumber.val() + text)
// var call = $('#call-this');
// $('#call-this').href= "tel:" + telNumber;
// console.log(call);
// });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="tel" name="name" id="telNumber" class="form-control tel" value="" />
<div class="num">
<div class="txt">0</div>
</div>
<div class="num">
<div class="txt">1</div>
</div>
<div class="num">
<div class="txt">2</div>
</div>
<div class="num">
<div class="txt">3</div>
</div>
<div class="num">
<div class="txt">4</div>
</div>
<div class="num">
<div class="txt">5</div>
</div>
<div class="num">
<div class="txt">6</div>
</div>
<div class="num">
<div class="txt">7</div>
</div>
<div class="num">
<div class="txt">8</div>
</div>
<div class="num">
<div class="txt">9</div>
</div>
<button class="expand">
Call
</button>
Your function can actually be simplified into this — the reason is that you don't need to actually transverse all the way to the .txt element if it is the one and only child of .num and that it only contains the number of interest.
$(document).ready(function () {
$('.num').click(function () {
// Append trimmed number to current value
$(telNumber).val($(telNumber).val() + $(this).text().trim());
// Update href attribute on #call-this
$('#call-this').attr('href', 'tel:'+$(telNumber).val());
});
});
See fiddle here: http://jsfiddle.net/teddyrised/jwqL4o8w/3
In fact, a better choice would be to store the number in the HTML5 data- attribute, so you can freely change the innerHTML of the .txt element without having to worry about issues:
<div class="num" data-num="0">
<div class="txt">0</div>
</div>
Then for your JS, just use:
$(document).ready(function () {
$('.num').click(function () {
// Append trimmed number to current value
$(telNumber).val($(telNumber).val() + $(this).data('num'));
// Update href attribute on #call-this
$('#call-this').attr('href', 'tel:'+$(telNumber).val());
});
});
I think where you have
$('#call-this').href="tel:" + $(telNumber).val(telNumber.val() + text)
It should be
$('#call-this').attr("href", "tel:" + telNumber.val());
edit I just caught the double val()
I think you need this, i have simplified the solution.
$("#telNumber").on("blur", function() {
$("#call-this").prop("href", "tel:" + $(this).val());
alert($("#call-this").prop("href"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="tel" name="name" id="telNumber" class="form-control tel" value="" />
<button class="expand">
Call
</button>
If you want to link a button your HTML code should look like this:
<input type="tel" name="name" id="telNumber" class="form-control tel" value="" />
<div class="num">
<div class="txt">0</div>
</div>
<div class="num">
<div class="txt">1</div>
</div>
<div class="num">
<div class="txt">2</div>
</div>
<div class="num">
<div class="txt">3</div>
</div>
<div class="num">
<div class="txt">4</div>
</div>
<div class="num">
<div class="txt">5</div>
</div>
<div class="num">
<div class="txt">6</div>
</div>
<div class="num">
<div class="txt">7</div>
</div>
<div class="num">
<div class="txt">8</div>
</div>
<div class="num">
<div class="txt">9</div>
</div>
<form action="#">
<input type="submit" value="Call" />
</form>
and script will be:
$(document).ready(function () {
$('.txt').on('click', function () {
$("#telNumber").val($("#telNumber").val() + $(this).text());
$("form").attr('action', "tel:" + $("#telNumber").val());
});
});
JSFiddle

Categories