I have multiple forms on the same page, at this moment I'm sending its content to another server using jQUery ajax, I'm using individual unique selectors to get their values before send. I want to change the approach in order to reduce the code:
Instead of using individual unique selectors like:
$(#form-1 button).click(function(){
var name = $("[name='name-1']").val();
});
To something like this:
$(form button).click(function(){
var name = $(this).sibbling("[name='name']").val();
});
$("#form-1 button").click(function(){
var name = $("[name='name']").val();
var phone = $("[name='phone']").val();
console.log(name);
console.log(phone);
// [...] ajax stuff
});
$("#form-2 button").click(function(){
var name = $("[name='name-2']").val();
var phone = $("[name='phone-2']").val();
console.log(name);
console.log(phone);
// [...] ajax stuff
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form-1">
<div class="form-group">
<label for="name">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="name">
</div>
<div class="form-group">
<label for="phone">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="phone">
</div>
<button type="button">Send </button>
</form>
<form id="form-2">
<div class="form-group">
<label for="nombre">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="name-2">
</div>
<div class="form-group">
<label for="phone-2">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="phone-2">
</div>
<button type="button">Send </button>
</form>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
All of my forms have the same 3 values (name, email, and phone ).
CodePudding user response:
I use event delegation here and this
in jQuery and focus on selecting by class:
An event-delegation approach attaches an event handler to only one element, the form in this case, and the event only needs to bubble up one level (from the clicked button to the form).
This also only triggers the function for the clicked button and it's associated inputs. This prevents both forms from being processed with either button press.
This jQuery selector:
let name = $(this).parent().find("[name='name']").val();
Works like this:
$(this)
is the clicked button
element. Then we go to the parent of the clicked button which is the form
. Then we use .find() which will 'Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.' And in this case we want to find the element that has the name of name
which is a text input so we use .find("[name='name']")
. More importantly, it's the specific input of potentially many inputs that we need for what we're doing. And finally we grab the value of the selector using .val()
.
$(".myForm").on('click', "button", function() {
let name = $(this).parent().find("[name='name']").val();
let phone = $(this).parent().find("[name='phone']").val();
console.log(name);
console.log(phone);
// [...] ajax stuff
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form-1" class="myForm">
<div class="form-group">
<label for="name">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="name">
</div>
<div class="form-group">
<label for="phone">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="phone">
</div>
<button type="button">Send </button>
</form>
<form id="form-2" class="myForm">
<div class="form-group">
<label for="nombre">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="name">
</div>
<div class="form-group">
<label for="phone-2">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="phone">
</div>
<button type="button">Send </button>
</form>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You need to loop on elements.
And use the right selector (Note the "^" in the selector).
jQuery selector for id starts with specific text
$("button").click(function(){
$("[name^='name']").each(function(){
console.log($(this).attr("name") " - val : " $(this).val());
})
$("[name^='phone']").each(function(){
console.log($(this).attr("name") " - val : " $(this).val());
})
// [...] ajax stuff
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form-1">
<div class="form-group">
<label for="name">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="name">
</div>
<div class="form-group">
<label for="phone">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="phone">
</div>
<button type="button">Send </button>
</form>
<form id="form-2">
<div class="form-group">
<label for="nombre">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="name-2">
</div>
<div class="form-group">
<label for="phone-2">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="phone-2">
</div>
<button type="button">Send </button>
</form>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Or with form selector
$("button").click(function(){
$("form[id^='form']").each(function(){
console.log($(this).attr('id'));
console.log($(this).find("input[name^='name']").attr("name") " - val : " $(this).find("input[name^='name']").val());
console.log($(this).find("input[name^='phone']").attr("name") " - val : " $(this).find("input[name^='phone']").val());
})
// [...] ajax stuff
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form-1">
<div class="form-group">
<label for="name">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="name">
</div>
<div class="form-group">
<label for="phone">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="phone">
</div>
<button type="button">Send </button>
</form>
<form id="form-2">
<div class="form-group">
<label for="nombre">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="name-2">
</div>
<div class="form-group">
<label for="phone-2">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="phone-2">
</div>
<button type="button">Send </button>
</form>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Or with forms selector
$("button").click(function(){
console.log($(this).parent('form').attr('id'));
console.log($(this).parent('form').find("input[name^='name']").attr("name") " - val : " $(this).parent('form').find("input[name^='name']").val());
console.log($(this).parent('form').find("input[name^='phone']").attr("name") " - val : " $(this).parent('form').find("input[name^='phone']").val());
// [...] ajax stuff
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form-1">
<div class="form-group">
<label for="name">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="name">
</div>
<div class="form-group">
<label for="phone">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="phone">
</div>
<button type="button">Send </button>
</form>
<form id="form-2">
<div class="form-group">
<label for="nombre">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="name-2">
</div>
<div class="form-group">
<label for="phone-2">Name*</label>
<input type="text" placeholder="Your name" class="form-control" name="phone-2">
</div>
<button type="button">Send </button>
</form>
<iframe name="sif5" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>