I have this code for jQuery spinner up-down number :
HTML:
<div class="container">
<div class="input-group spinner">
<input type="text" class="form-control" value="42">
<div class="input-group-btn-vertical">
<div class="btn btn-default"><i class="fa fa-caret-up"></i></div>
<div class="btn btn-default"><i class="fa fa-caret-down"></i></div>
</div>
</div>
</div>
JS:
(function ($) {
$('.spinner .btn:first-of-type').on('click', function() {
$('.spinner input').val( parseInt($('.spinner input').val(), 10) + 1);
});
$('.spinner .btn:last-of-type').on('click', function() {
$('.spinner input').val( parseInt($('.spinner input').val(), 10) - 1);
});
})(jQuery);
This Worked But I need to add two option:
prevent user add number to input
set Maximum and Minimum for number
How do add this option?!
DEMO FIDDLE
Change:
<input type="text" class="form-control" value="42">
To:
<input type="number" min="0" max="10" steps="1" class="form-control" value="5">
I didn't quite understand from your question if you wanted the user to be able to change the value or not, in the case that you don't want them to change the value, just add the readonly attribute to the input field, like this
<input type="number" min="0" max="10" steps="1" class="form-control" value="5" readonly>
To do this all with jQuery which i assume you want:
$(document).ready(function(){
//Stop people from typing
$('.spinner input').keydown(function(e){
e.preventDefault();
return false;
});
var minNumber = 1;
var maxNumber = 10;
$('.spinner .btn:first-of-type').on('click', function() {
if($('.spinner input').val() == maxNumber){
return false;
}else{
$('.spinner input').val( parseInt($('.spinner input').val(), 10) + 1);
}
});
$('.spinner .btn:last-of-type').on('click', function() {
if($('.spinner input').val() == minNumber){
return false;
}else{
$('.spinner input').val( parseInt($('.spinner input').val(), 10) - 1);
}
});
});
I haven't check but should be pretty accurate
Working Fiddle: http://jsfiddle.net/7jtLa3py/3/
Better Ways :
bootstrap spinner DEMO
jQuery Spinner
jQueryUI spinner
bootstrap snipper worked easy:
HTML
<input type="text" class="aSpinEdit" />
Javascript
$('.aSpinEdit').spinedit({
minimum: -10,
maximum: 50,
step: 1
});
Assuming you have to send that data back to the server, setting the input readonly attribute and adding some limits to the input value its fairly easy.
Here's the demo
http://jsbin.com/yebawihune/7/
With this you can dynamically add as many spinners as you want that are cross browser compatible (even IE). Of course you have to have included the needed js and css files for jquery.
First you have to create your input. Keep note of the id as you will use that later. I always just put the same value for the id and name parameters in the input.
<input id="elementName" name="elementName">
Then put this in your head section.
function createSpinner(elemName, elemVal, elemMin, elemMax, elemStep){
var mySpinner = $( '#' + elemName ).spinner({
min: elemMin,
max: elemMax,
step: elemStep,
change: function( event, ui ) {
var typedVal = $( '#' + elemName ).spinner( 'value' );
if (typedVal < elemMin || typedVal > elemMax) {
alert('Value must be between ' + elemMin + ' and ' + elemMax);
$('#' + elemName).spinner('value', elemVal);
}
}
});
$('#' + elemName).spinner('value', elemVal);
};
Then you just call the function, passing the needed parameters (the first parameter will be the value of the ID of your input).
createSpinner('elementName','0','0','10000','1');
Related
How to make sure that every field has greater value than the value of previous input? If condition is true, then I can submit a form.
$('#add').on('click', function() {
$('#box').append('<div id="p1"><input required type="number" min="1" max="120" name="val" ></div>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="add" href="javascript:void(0);">Add </a>
<form>
<div id="box"></div>
<input type="submit" value="Submit">
</form>
You need to loop through all the inputs, keeping the value of the previous one to compare it. Keep in mind, your current "add input" code will give all the inputs the same name, which will make it problematic to use on your action page. You can use an array for that.
$("#add").on("click", function() {
$("#box").append('<div id="p1"><input required type="number" min="1" max="120" name="val[]" ></div>');
});
$("form").submit(function(e) {
return higherThanBefore(); //send depending on validation
});
function higherThanBefore() {
var lastValue = null;
var valid = true;
$("input[name^=val]").each(function() {
var val = $(this).val();
if (lastValue !== null && lastValue >= val) { // not higher than before, not valid
valid = false;
}
lastValue = val;
});
return valid; // if we got here, it's valid
}
<a id="add" href="javascript:void(0);">Add </a>
<form action="test">
<div id="box"></div>
<input type="submit" value="Submit">
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
One line added, one line changed. Simply get the last input's value, and use that as the min value for the new input.
$('#add').on('click', function() {
// get the current last input, save its value.
// This will be used as the min value for the new el
var newMin = $("#box").find(".p1 input").last().val() || 1;
// Append the new div, but set the min value to the
// value we just saved.
$('#box').append('<div class="p1"><input required type="number" min="'+newMin+'" max="120" name="val" ></div>');
$(".p1 input").on("keyup mouseup", function(){
var triggeringEl = $(this);
if (triggeringEl.val() >= triggeringEl.attr("min") ) {
triggeringEl.removeClass("error");
}
triggeringEl.parent().nextAll(".p1").children("input").each(function(){
if($(this).attr("min") < triggeringEl.val() )
$(this).attr("min", triggeringEl.val() );
if ($(this).val() < $(this).attr("min")){
$(this).addClass("error");
} else {
$(this).removeClass("error");
}
})
})
});
.error {
border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="add" href="javascript:void(0);">Add </a>
<form>
<div id="box"></div>
<input type="submit" value="Submit">
</form>
So I made changes, to reflect the comments (great catch, by the way), but there is a challenge here. If I set the minimum value when the current el's value changes, works great. But I can't assume that the current el is the highest value in the collection, so if the current el is being decremented, I haven't figured the logic to decrement all subsequent minimums. Sigh...
At any rate, the section that creates the new input and sets the minimum remains the same. Then I had to add a listener to handle changes to the input. If the input is changed, by either keyboard or mouse, all subsequent minimums (minima?) are checked against this value. Those that are lower are set to this value, and then all elements are checked, minimum vs. value, and an error signal is set if needed. Still needs work, as I can't figure how to handle decrementing a value, but it's a start.
You can use .filter(): for each input field you can test if the next one has a value greater then the current one.
$('#add').on('click', function() {
var idx = $('#box').find('div[id^=p]').length;
$('#box').append('<div id="p' + idx + '"><input required type="number" min="1" max="120" name="val' + idx + '" ></div>');
});
$('form').on('submit', function(e) {
var cachedValues = $('form [type=number]');
var noOrderRespected = cachedValues.filter(function(idx, ele) {
var nvalue = cachedValues.eq(idx + 1).val();
return (+ele.value < (+nvalue||+ele.value+1)) ? false : true;
}).length;
console.log('noOrderRespected: ' + noOrderRespected);
if (noOrderRespected > 0) {
e.preventDefault();
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="add" href="javascript:void(0);">Add </a>
<form>
<div id="box"></div>
<input type="submit" value="Submit">
</form>
I was going to use jQuery mobile for this one to get the mobile theme http://jsfiddle.net/hhken790/
HTML
<input type="button" value="-" class="qtyminus" />
<input type="text" name="myInputs[qty][]" value="0" class="qty" />
<input type="button" value="+" class="qtyplus" />
jQuery
$("#dynamic").on("click", ".qtyplus", function (e) {
e.preventDefault();
var $input = $(this).prev("input");
var currentVal = parseInt($input.val());
if (!isNaN(currentVal)) {
$input.val(currentVal + 1);
} else {
$input.val(0);
}
});
However, the plus and minus wont work here. Any idea what causing this?
When you add jQM, it enhances/styles many DOM elements by adding container divs and other DOM elements. This means that your buttons and text inputs are no longer siblings in the DOM and prev() will not work. Instead traverse up the DOM and then down:
var $input = $(this).closest("div#dynamic").find(".qty");
e.g:
$("#dynamic").on("click", ".qtyplus, .qtyminus", function (e) {
e.preventDefault();
var $input = $(this).closest("div#dynamic").find(".qty");
var currentVal = parseInt($input.val());
if (!isNaN(currentVal)) {
$(this).hasClass("qtyplus") ? $input.val(currentVal + 1) : $input.val(currentVal - 1);
} else {
$input.val(0);
}
});
Updated FIDDLE
I have 2 buttons, one + and one - that increments the quantity of items.
I also have a "Price" of the item and a span that displays the price of the item.
What i need is: When the user clicks the + or - buttons, it increments the quantity of items and the total price.
So far my code looks like this:
HTML:
<input type="number" size="4" class="input-text qty text" title="Cantidad" value="1" name="quantity" min="1" step="1">
<input type="button" class="plus" value="+">
<input type="button" class="minus" value="-">
<span class="price">90.00 €</span>
JS
function inc() {
var price = "price";
var elems = document.getElementsByTagName('*'), i;
for (i in elems) {
var a = document.getElementsByName("quantity")[0].value;
if((' ' + elems[i].className + ' ').indexOf(' ' + price + ' ') > -1) {
var valOfItem = parseInt(elems[i].innerHTML);
var x = a * valOfItem;
elems[i].innerHTML = x;
}
}
}
I haven't tried it yet but i guess everything will be working as soon as i add my func() to the onClick event on those buttons, i was hoping to do it with jQuery after the document is done loading but i'm not sure how.
Any ideas?
Why not just use javascript (in head) to disable the buttons until page load?
<script language="text/javascript">
window.addEventListener("plus", function() { document.getElementById('plus').disabled = false; }, false);
window.addEventListener("minus", function() { document.getElementById('minus').disabled = false; }, false);
</script>
Then have the buttons disabled by default.
<input type="button" class="plus" value="+" disabled="disabled">
<input type="button" class="minus" value="-" disabled="disabled">
The downside of this is any non-JS users will be unable to use the site. Then again, that's likely the case already.
You can add click event handlers to .plus and .minus and calculate sum based on input value using .text() and .val():
Fiddle.
$(document).ready(function()
{
var basePrice = parseFloat($(".price").text());
$(".plus").click(function()
{
changeValue(1);
});
$(".minus").click(function()
{
changeValue(-1);
});
function changeValue(sign)
{
$("[name='quantity']").val(parseInt($("[name='quantity']").val()) + sign);
var countValue = $("[name='quantity']").val();
var newValue = (basePrice * countValue).toFixed(2);
$(".price").text(newValue);
}
});
I have tried and failed trying to get this to work so time to ask the experts.
I've got the following HTML:
<input type="button" value="-" class="minus">
<input type="number" value="20" class="input-text">
<input type="button" value="+" class="plus">
<div class="newprice">
20
</div>
Using javascript (jQuery specific is fine) I need to be able to have it so that when someone clicks the plus button, the number inside the .newprice div gets incremented by 20. Likewise when they hit the minus button the number gets decreased by 20.
Also the same goes for if they use the little up/down arrows on the .input-text field.
Or if they type in a value instead of using any of the buttons, then the number in the .input-text div changes accordingly (if someone typed in 3, the .input-text number would change to 60).
PS: if it's easier the .newprice div can be an text field instead. Whatever works.
[To put this all into context, basically its part of a shopping cart but I am trying to show the user how much they will be paying for the product when they enter a quantity. For example, the product costs $20, and if they want 3 of them they will be able to see straight away (before adding to their cart) that this is going to cost them $60.]
I hope I explained it properly.
Thanks in advance.
You can do this.
// how many to increment each button click
var increment = 20;
$('.plus, .minus').on('click', function() {
// the current total
var total = parseInt($('#newprice').text());
// increment the total based on the class
total += (this.className == 'plus' ? 1 : -1) * increment;
// update the div's total
$('#newprice').text(total);
// update the input's total
$('.input-text').val(total);
});
$('.input-text').on('change', function() {
// update the div's total
$('#newprice').text( $(this).val() );
});
Edit based on comments
// how many to increment each button click
var increment = 20;
$('.plus, .minus').on('click', function() {
// the current total
var total = parseInt($('#newprice').text());
// increment the total based on the class
total += (this.className == 'plus' ? 1 : -1) * increment;
// update the div's total
$('#newprice').text(total);
});
$('.input-text').on('change', function() {
// update the div's total
$('#newprice').text( $(this).val() );
});
To increment the number input by 20, add the attribute step like so. The number in that attribute represents how much the value will be incremented each time the up and down buttons are pressed.
<input type="number" value="20" step="20" class="input-text">
I already add some calculation and html for handle the basic price. See demo in jsfiddle
HTML:
Price per item:<input name="basicPrice" value="20" class="input-text">
<br />
<input type="button" value="-" class="minus">
<input name="quantity" id="quantity" type="number" value="1" class="input-text">
<input type="button" value="+" class="plus">
<br />Money much pay:
<span class="newprice">20</span>
JS by jquery :
function calculate(){
var basicPrice = parseInt($(":input[name='basicPrice']").val());
var quantity = parseInt($(":input[name='quantity']").val());
console.log(quantity);
var total = basicPrice * quantity;
$(".newprice").text(total);
}
function changeQuantity(num){
$(":input[name='quantity']").val( parseInt($(":input[name='quantity']").val())+num);
}
$().ready(function(){
calculate();
$(".minus").click(function(){
changeQuantity(-1);
calculate();
});
$(".plus").click(function(){
changeQuantity(1);
calculate();
});
$(":input[name='quantity']").keyup(function(e){
if (e.keyCode == 38) changeQuantity(1);
if (e.keyCode == 40) changeQuantity(-1);
calculate();
});
$(":input[name='basicPrice']").keyup(function(e){
calculate();
});
var quantity = document.getElementById("quantity");
quantity.addEventListener("input", function(e) {
calculate();
});
});
Let's me know if you need any support.
You can do...
var $counter = $('.counter');
$('button').on('click', function(){
var $button = $(this);
$counter.text(function(i,val){
return +val + ( $button.hasClass('up') ? 1 : - 1 );
});
});
with this HTML...
<div class="counter">10</div>
<button class="down">-</button>
<button class="up">+</button>
For the record, you should definitely be using an input for the counter element.
Here's your pure JS example but I believe to catch anything below IE9 you'll have to attach event listeners as well.
jsFiddle
<form>
<input type="button" id="value-change-dec" value="-">
<input type="text" id="new-price" value="0" disabled>
<input type="button" id="value-change-inc" value="+">
<br>
<input type="number" id="change-price">
</form>
document.getElementById("value-change-dec").addEventListener("click", function() {
var value = parseInt(document.getElementById('new-price').value);
value=value-20;
document.getElementById('new-price').value = value;
});
document.getElementById("value-change-inc").addEventListener("click", function() {
var value = parseInt(document.getElementById('new-price').value);
value=value+20;
document.getElementById('new-price').value = value;
});
function changeIt() {
document.getElementById('new-price').value = document.getElementById('change-price').value*20;
}
var changer = document.getElementById('change-price');
changer.addEventListener('keydown', changeIt, false);
changer.addEventListener('keyup', changeIt, false);
changer.addEventListener('click', changeIt, false);
Issue: The (jQuery) auto-complete works only for the first input (displayed by default). It doesn't work for additional row/s which are added using the add row function.
I have read other posts and understood that I have to use class and not id. But it still doesn't work.
I am using jquery autocomplete and some javascript to add and delete rows for a specific id.
Here is the headers:
<link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
Here is the jquery code:
jQuery(document).ready(function ($) {
/* availableTags = [
"Demo",
"Senna",
"Adam",
"Eva",
];*/
$('.autofill').autocomplete({
source:'suggest.php', minLength:2
});
});
Here is the HTML code:
<div class="content-left">
Add rows
<div id="p_scents">
<p>
<label style="margin-bottom:10px;" for="p_scnts">
<input class="autofill" type="text" id="p_scnt" size="20" name="p_scnt[]"
value="" placeholder="Enter text" />
</label>
</p>
</div>
</div>
**Here is the Javascript to add rows:**
$(function () {
var scntDiv = $('#p_scents');
var i = $('#p_scents p').size() + 1;
$('#addScnt').on('click', function () {
$('<p><label style="margin-bottom:10px;" for="p_scnts"><input class="autofill" type="text" name="p_scnt[]" size="20" id="p_scnt_' + i + '" value="" placeholder="Add text" /></label for="remScnt"> <label style="padding-left:400px;">Remove</label></p>').appendTo(scntDiv);
//i++;
//return false;
//Added the 5 lines below
$(function ($) {
$('#p_scnt_' + i).autocomplete({
source:'suggest.php', minLength:2
});
});
i++;
return false;
});
$('#remScnt').on('click', function () {
if (i > 2) {
$(this).parents('p').remove();
i--;
}
return false;
});
});
So the above code is working fine. Cheers all for your help ;)
For your latest code, you've made two mistakes:
Increase the counter i before apply autocomplete to text field
Stopped the script by return false
Also, it's recommended to use .on() to replace .live() as it's deprecated in version 1.7 .
Demo: http://jsfiddle.net/indream/f8mt4/
$('#addScnt').on('click', function () {
$(...).appendTo(scntDiv);
//i++; Should not be done here
//return false; Stopped the script
//Added the 5 lines below
$(function ($) {
$('#p_scnt_' + i).autocomplete({
source: window.availableTags,
minLength: 1
});
});
i++; // should increase counter here
return false;
});
p.s. I've changed availableTags to global variable in order to make the demo works,
but I think you would use query to retrieve the tags.
$('#addScnt').live('click', function() {
.........................
$('#p_scnt_'+i).autocomplete({
source:'suggest_fill.php',
minLength:1
});
return false;
..................
});
I think it's the sequence of js file load problem.
Try to put your second file above the 1st file.
Hope it helps you.
the second $(function(){is too much. it should look like this
<script>
$(function() {
var scntDiv = $('#p_scents');
var i = $('#p_scents p').size() + 1;
$('#addScnt').live('click', function() {
$('<p><label style="margin-bottom:10px;" for="p_scnts"><input class="autofill" type="text" name="p_scnt[]" size="20" id="p_scnt_' + i +'" value="" placeholder="Add text" /></label for="remScnt"> <label style="padding-left:400px;"><img src="../../img/remove.jpg" width="" height="" class="img" alt="" title=""/></label></p>').appendTo(scntDiv);
i++;
//Added the 5 lines below
$('#p_scnt_'+i).autocomplete({
source:'suggest_fill.php',
minLength:1
});
return false;
});
$('#remScnt').live('click', function() {
if( i > 2 ) {
$(this).parents('p').remove();
i--;
}
return false;
});
});
</script>