Lakos
Lakos

Reputation: 11

Create multiple textareas in a loop with different ids

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

Answers (4)

user8914070
user8914070

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

user8914070
user8914070

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

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.

enter image description here

Upvotes: 0

Mamun
Mamun

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

Related Questions