3

I have many pair of text fields and submit button, with id to submit button and class to text field as same but different for each pair. So I want to pass the value entered in text field after button click to ajax function.

    function update_rate(id){
      // var price = document.getElementsByClassName(id)[0].innerHTML;
    
      var price = document.getElementsByClassName(id);
      console.log(price);
      $.ajax({
        type: "POST",
        url: "update_rate.php", // Name of the php files
        data: {subcategory : id , price: price},
        success: function(res)
          {
            // console.log(html);
            alert(res);
          }
      }); 
    }
first pair:

    <div class="form-group">
        <input type="text" class="form-control" name="a" placeholder="Your task rate excl. taxes">
    </div>
    <button type="submit" id="a" onclick="update_rate(this.id)" class="btn btn-primary">Update</button>



    <div class="form-group">
        <input type="text" class="form-control" name="b" placeholder="Your task rate excl. taxes">
    </div>
    <button type="submit" id="b" onclick="update_rate(this.id)" class="btn btn-primary">Update</button>

But I can't get the value of text field into variable.

JaviL
  • 102
  • 1
  • 7
Intern
  • 39
  • 1
  • 5

3 Answers3

2

This can and should be done in a different and more simple manner. Connecting the buttons with their text fields by id and class is not a scalable solution and requires constant updating of the code to keep all the naming in sync. Just get the value of the text field that comes just prior to the button. This will be easier if you modify your HTML structure so that the text field and the button are in the same div together.

See comments below.

// Do your event handling in JavaScript, not with inline HTML event handling attributes
// Also, set up just one handler at a parent level of the items that might trigger
// the event (event delegation).
$(".wrapper").on("click", update_rate);

function update_rate(event){
  // See if it was a submit button that got clicked
  if(event.target.classList.contains("btn")){
    // A submit button was pressed.
    // Locate the nearest ancestor element that has the form-group class
    // (event.target references the actual element that triggered the event).
    let formGroup = event.target.closest(".form-group");
    
    // and then, from there, find the first input (which is the one you want).
    var input = formGroup.querySelector("input");
 
    // The following code is already added to the success handler below and
    // that's where it should be. It's only added here to be able to see the
    // effect since the AJAX call won't run in Stack Overflow. The next 3 lines
    // should be removed when used for real.
    input.classList.add("hidden");
    formGroup.querySelector("button").classList.add("hidden");
    formGroup.querySelector("span").classList.remove("hidden");
    
    console.log(input.value);
    $.ajax({
      type: "POST",
      url: "update_rate.php", // Name of the php files
      // Use the dataset API to extract the custom attribute on the input
      data: {subcategory : input.dataset.category , price: input.value},
      success: function(res){
        alert(res);
        
        // Hide the input and the button and show the updated message
        input.classList.add("hidden");
        formGroup.querySelector("button").classList.add("hidden");
        formGroup.querySelector("span").classList.remove("hidden");
      }
    });
  }
}
.hidden { display:none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
  <div class="form-group">
    <input type="text" class="form-control" data-category="a" placeholder="Your task rate excl. taxes">
    <button type="submit" class="btn btn-primary">Update</button>
    <span class="hidden">Updated</span>
  </div>

  <div class="form-group">
    <input type="text" class="form-control"  data-category="b" placeholder="Your task rate excl. taxes">
    <button type="submit" class="btn btn-primary">Update</button>
    <span class="hidden">Updated</span>
  </div>
</div>

In the end, you have no id or unique class names to have to match up against each other, your HTML is more simplified, and you only have one event handler to set up.

Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • Please note my html is loading dynamically through ajax call. – Intern Oct 15 '20 at 17:59
  • Thanks man , Tried your method . At start it didn't work cause I was loading wrapper class also dynamically, so just made it Static. and added in edits. – Intern Oct 15 '20 at 18:46
  • Can you please tell me , how can I access elements in this type , like i want to hide text field and button and replace with text `updated` on button click. I read the documentation but couldn't do it. – Intern Oct 15 '20 at 19:56
  • @Intern That's just a matter of showing and hiding things, which I've added to the answer. – Scott Marcus Oct 16 '20 at 17:05
1

Several things

var price = document.getElementsByClassName(id); is plural and you need the value, so

var price = document.getElementsByClassName(id)[0].value; if you must

BUT it is not a class. It is a name

var price = document.getElementsName(id)[0].value; if you must

but if you have jQuery, why not use it?

Here I take the button ID and find the input by name

I also change to type="button" - you do not want to submit when you use Ajax

$(function() { // on page load
  $("#container").on("click","[type=button]",function() { // click on type="button" you can use a Class here too
    const id = $(this).attr("id");
    const price = $("[name="+id+"]").val(); // get the input by name
    console.log(id, price)
    if (price) {

      $.ajax({
        type: "POST",
        url: "update_rate.php", // Name of the php files
        data: {
          subcategory: id,
          price: price
        },
        success: function(res) {
          // console.log(html);
          alert(res);
        }
      });
    }
  })

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">

first pair:
<div class="form-group">
  <input type="text" class="form-control" name="a" placeholder="Your task rate excl. taxes">
</div>
<button type="button" id="a" class="btn btn-primary">Update</button>

<div class="form-group">
  <input type="text" class="form-control" name="b" placeholder="Your task rate excl. taxes">
</div>
<button type="button" id="b" class="btn btn-primary">Update</button>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • I see your answer is perfectly working , but it's not working in my case , Does loading html dynamically through ajax call makes any difference ? – Intern Oct 15 '20 at 18:15
  • Yes, very. That was important information- then we need to delegate from a container - please show where you append the new data – mplungjan Oct 15 '20 at 18:31
  • See the container I added – mplungjan Oct 15 '20 at 18:35
  • Thank you for your solution and time. I should have added information about dynamic loading previously. – Intern Oct 15 '20 at 18:47
0

As you're already passing the id in the function, using jQuery, you can do something like:

var selector = 'input[name="' + id + '"]' // Compose the selector string for jQuery
var value = $(selector).val()             // Get input value
JaviL
  • 102
  • 1
  • 7
  • As I already did. Please reload the page to see my answer – mplungjan Oct 15 '20 at 15:18
  • I see your this answer works fine, but it's not working in my case , Does loading html dynamically through ajax call makes any difference ? – Intern Oct 15 '20 at 18:15