Reputation: 11
I create the checkout page of an eshop and I have a loop in which I display the products that the user has added to the cart. Inside the loop, I display the info for the products I have a text area so the user can choose the quantity of each product. The problem is that the id of each text area must be unique. How can I create many textareas in a loop with different ids?
textarea:
<form name='txtAreaForm' method='GET'>
<textarea disabled name='textArea' id='counter'></textarea>
</form>
Also, I have two buttons (+-) to change the value of the textarea, this is the .js file:
var counter = 1;
// Display total
$("#counter").text(counter);
// When button is clicked
$("#plusButton").click(function(){
counter = counter + 1;
$("#counter").text(counter);
});
//Subtract
$("#minusButton").click(function(){
if (counter>1) {
counter = counter - 1;
$("#counter").text(counter);
}
});
Upvotes: 0
Views: 1330
Reputation:
Special Fun solution! (but real).
I did it with only 9 lines of JavaScript / jQuery, and a little more in CSS.
And no need for textarea id. (Ok, my 2 "if"
statements have only 1 line).
For the HTML part, each text box is placed in a "p"
(paragraph), and that's it:
<p><textarea disabled > 1 </textarea></p>
<p><textarea disabled > 2 </textarea></p>
<p><textarea disabled > 3 </textarea></p>
The trick is in the CSS where I use :after
and :before
like the "+"
or "-"
buttons.
placed to the right of each box "p"
.
form p:after {
right: -22px;
content:'+';
...
form p:before {
right: -43px;
content:'-';
In the jQuery part.
I use the relative position of the mouse click to determine whether the operation should be a plus or minus. For the little story: --
$ (this) .outerWidth ();
--
Is usefull.
Of course, it would still be better to add an ID
on each textarea; but after reflection, it appeared to me that these input fields could be generated at the PHP server (?).
So, strange as it may seem, this solution is very serious. ;)
Everything is in the snippet.
$(function() {
$('form p').click(function(e) {
var
posX = (e.pageX - $(this).offset().left) - $(this).outerWidth();
Sign = (posX > 22) ? "moins" : (posX > 0) ? "plus" : "none",
Valn = parseInt($(this).children('textarea').text());
if (Sign === 'plus') $(this).children('textarea').text(++Valn);
if ((Sign === 'moins') && (Valn > 1)) $(this).children('textarea').text(--Valn);
});
});
textarea,
form,
p,
textarea {
font-family: Tahoma, sans-serif;
font-size: 16px;
}
textarea {
float: left;
width: 40px;
height: 22px;
font-weight: bold;
text-align: center;
resize: none;
line-height: 20px;
}
form p {
box-sizing: border-box;
display: block;
float: left;
clear: both;
position: relative;
border: 0;
margin: 5px 0 0 20px;
padding: 0;
}
form p:before,
form p:after {
position: absolute;
top: 2px;
width: 20px;
height: 20px;
display: block;
color: white;
background-color: darkslategray;
text-align: center;
font-size: 18px;
}
form p:after {
right: -22px;
content: '+';
line-height: 18px;
}
form p:before {
right: -43px;
content: '-';
line-height: 16px;
}
<form name="txtAreaForm" method='GET'>
<p><textarea disabled> 1 </textarea></p>
<p><textarea disabled> 2 </textarea></p>
<p><textarea disabled> 3 </textarea></p>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
Upvotes: 0
Reputation:
I prefer using a class, because I think it is more clear for the code.
Example: my_set_Of_Text_area.add ('<div><span> Ananas : </span>','</div>');
I prefer using data to made the link with the counting area and the + / - buttons.
$(function() {
class TxtAreaFab {
constructor(Form_ID, TextAreaPrefix, BtPlusClass, BtMinusClass) {
this._ref = 0;
this._TaP = TextAreaPrefix;
this._BtPlus = BtPlusClass;
this._BtMinus = BtMinusClass;
this._$ID = $('#' + Form_ID);
}
add(before, after) {
var elements = before;
this._ref++;
elements += "<textarea disabled id='TxtArea_" + this._ref + "'>1</textarea>";
elements += "<button class=" + this._BtPlus + " data-ref=\"TxtArea_" + this._ref + "\">+</button>";
elements += "<button class=" + this._BtMinus + " data-ref=\"TxtArea_" + this._ref + "\">-</button>";
elements += after;
$(elements).appendTo(this._$ID);
}
/* ----- not used , just here for sample
clear () {
this._$ID.html('');
this._ref = 0;
}
*/
};
var my_set_Of_Text_area = new TxtAreaFab('txtAreaForm', 'zoneTA_', 'ClassBtPlus', 'ClassBtMinus');
my_set_Of_Text_area.add('<div><span> Apples : </span>', '</div>');
my_set_Of_Text_area.add('<div><span> Oranges : </span>', '</div>');
my_set_Of_Text_area.add('<div><span> Pears : </span>', '</div>');
my_set_Of_Text_area.add('<div><span> Bananas : </span>', '</div>');
$('#txtAreaForm').on('click', "button", function(e) {
e.stopPropagation();
var $txtArea = $("#" + $(this).data("ref")),
v = parseInt($txtArea.val());
if ($(this).hasClass('ClassBtPlus')) $txtArea.val(++v);
if ((v > 1) && ($(this).hasClass('ClassBtMinus'))) $txtArea.val(--v);
return false;
});
my_set_Of_Text_area.add('<div><span> Ananas : </span>', '</div>');
});
#txtAreaForm div {
clear: both;
height: 30px;
}
#txtAreaForm div span {
display: block;
float: left;
width: 120px;
font-weight: bold;
text-align: right;
padding-right: 10px;
}
#txtAreaForm textarea {
display: block;
float: left;
width: 40px;
height: 16px;
font-weight: bold;
text-align: center;
resize: none;
}
<form name='txtAreaForm' id='txtAreaForm' method='GET'></form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
Upvotes: 0
Reputation: 5571
You can use just JavaScript to render a form with as many textareas with its id
as necessary and set the actions to each button related to each of them.
See this demo:
(function() {
// Set the plus action on every button with the class name «plus».
function setPlusAction() {
function plus(e) {
var textarea = e.target.previousSibling; // Find the textarea element related to the button clicked.
textarea.value = textarea.value * 1; // Convert the value into number.
textarea.value++; // Increment its value.
}
var elems = document.getElementsByClassName("plus"), i, len = elems.length, button;
for (i = 0; i < len; i++) {
button = elems[i]; // Find the current button.
button.onclick = plus; //Set the «plus» function on every button which has been found.
}
}
// Set the minus action on every button with the class name «minus».
function setMinusAction() {
function minus(e) {
var textarea = e.target.previousSibling.previousSibling; // Find the textarea element related to the button clicked.
textarea.value = textarea.value * 1; // Convert the value into number.
if (textarea.value > 1) {
textarea.value--; // Decrement its value.
}
}
var elems = document.getElementsByClassName("minus"), i, len = elems.length, button;
for (i = 0; i < len; i++) {
button = elems[i]; // Find the current button.
button.onclick = minus; //Set the minus function on every button which has been found.
}
}
// Render a form with the quantity of textareas required.
function buildForm(textareas) {
var html = "<form name=\"txtAreaForm\" method=\"GET\">", i;
for (i = 0; i < textareas; i++) {
html += "<div><textarea disabled name=\"textArea\" id=\"textarea";
html += i;
html += "\">1</textarea><button class=\"plus\" type=\"button\">+</button><button class=\"minus\" type=\"button\">-</button></div>";
}
html += "</form>";
return html; // Return the html content with the form.
}
/*
1. Render the form with document.getElementById("div").innerHTML = buildForm(50);
2. Once the form is renderd call setPlusAction() function;
3. And call setMinusAction() function;
*/
document.getElementById("div").innerHTML = buildForm(50); // Set 50 textareas.
setPlusAction();
setMinusAction();
})();
#div div {
border: solid 1px #ccc;
margin: 2px;
padding: 2px;
}
button.plus,
button.minus {
cursor: pointer;
}
<div id="div"></div>
Update:
jQuery version:
$(function() {
// Render a form with the quantity of textareas required.
function buildForm(textareas) {
var html = "<form name=\"txtAreaForm\" method=\"GET\">", i;
for (i = 0; i < textareas; i++) {
html += "<div><textarea disabled name=\"textArea\" id=\"textarea";
html += i;
html += "\">1</textarea><button class=\"plus\" type=\"button\">+</button><button class=\"minus\" type=\"button\">-</button></div>";
}
html += "</form>";
return html; // Return the html content with the form.
}
$("#div").html(buildForm(50)); // Render the form with 50 textareas.
$(".plus").on("click", function() {
var texarea = $(this).prev(), value = texarea.val() * 1;
value++;
texarea.val(value);
});
$(".minus").on("click", function() {
var texarea = $(this).prev().prev(), value = texarea.val() * 1;
if (value > 1) {
value--;
texarea.val(value);
}
});
});
#div div {
border: solid 1px #ccc;
margin: 2px;
padding: 2px;
}
button.plus,
button.minus {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="div"></div>
Remember: IDs must be unique.
Upvotes: 0
Reputation: 68933
Though the question is not quite clear to me, you can do something like the following:
var counter = 1;
// Display total
$("#counter").text(counter);
var counter = counter + 1;
for(var i=0; i<5; i++){
$("form").append('<textarea name=textArea"+counter+" id=counter"+counter+">1</textarea><input class="plus" type="button" value="+" /><input class="minus" type="button" value="-" /><br>');
}
// When button is clicked
$(".plus").click(function(){
var txtArea = $(this).prev('textarea').text();
$(this).prev('textarea').text(parseInt(txtArea)+1);
});
//Subtract
$(".minus").click(function(){
var txtArea = $(this).prev().prev('textarea').text();
if(txtArea >=2){
$(this).prev().prev('textarea').text(parseInt(txtArea)-1);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name='txtAreaForm' method='GET'>
</form>
Upvotes: 1