I have an HTML form with at least two forms in, each with the class 'myform' applied. The input buttons in each have a different id, and once clicked should send the data to a database. The problem is the javascript, which stops the refresh and controls buttons states doesn't select the right form - it always sends the details of the form closest to the script... here are the html forms.
<div class="booking_box">
<form method="post" class='myform'>
<button class="button" id='b2' name = "8">Book room 8</button>
<input type="hidden" name="salutation" value="<?php echo $_SESSION["salutation"]?>">
<input type="hidden" name="firstname" value="<?php echo $_SESSION["firstname"]?>">
<input type="hidden" name="room" value="8">
<input type="hidden" name="period" value="1">
</form>
</div>
<div class="booking_box">
<form method="post" class='myform'>
<button class="button" id='b3' name = "7">Book room 7</button>
<input type="hidden" name="salutation" value="<?php echo $_SESSION["salutation"]?>">
<input type="hidden" name="firstname" value="<?php echo $_SESSION["firstname"]?>">
<input type="hidden" name="room" value="7">
<input type="hidden" name="period" value="1">
</form>
</div>
Here is the script at the bottom of the page. I've tried '.closest' and '.parent' but nothing seems to work. I've also tried adding these to the '$.post' section, but then the data is sent to the DB but it's empty fields. Confused...
<script>
$("button").click(function() {
var myID = ($(this).attr('id'));
var theName = ($(this).attr('name'));
var isAdd = $("#" + myID).text();
if (isAdd == "Book room " + theName){
$('#' + myID).text(isAdd ? 'Cancel room' + theName : 'Book room ' + theName);
$('#' + myID).closest('.myform').attr('action', isAdd ? 'bookRoom.php' : 'update.php');
} else {
$('#' + myID).text(isAdd ? 'Book room ' + theName : 'Cancel room ' . theName);
$('#' + myID).closest('.myform').attr('action', isAdd ? 'update.php' : 'bookRoom.php');
}
$('.myform').submit(function(){
return false;
});
$.post(
$('.myform').attr('action'),
$('.myform :input').serializeArray(),
function(result){
$('#result').html(result);
}
);
});
</script>
As always, any help would be massively appreciated!
You should be able to use $(this).closest(".myform") to get the form that should be submitted.
It's also not necessary to use $("#" + myID), since that's the same as $(this).
And the submit handler that prevents normal submission should not be inside the click handler.
$('.myform').submit(function(){
return false;
});
$("button").click(function() {
var theName = ($(this).attr('name'));
var isAdd = $(this).text();
var form = $(this).closest(".myform");
if (isAdd == "Book room " + theName){
$(this).text(isAdd ? 'Cancel room' + theName : 'Book room ' + theName);
form.attr('action', isAdd ? 'bookRoom.php' : 'update.php');
} else {
$(this).text(isAdd ? 'Book room ' + theName : 'Cancel room ' . theName);
form.attr('action', isAdd ? 'update.php' : 'bookRoom.php');
}
$.post(
form.attr('action'),
form.serialize(),
function(result){
$('#result').html(result);
}
);
});
Use the event to get the form from the button. Define "e" in your function and e will be the event, e.target is the button, and e.target.form is the form. (tested with jquery 2.2.4)
$("button").click(function(e) {
var myID = ($(this).attr('id'));
var theName = ($(this).attr('name'));
var isAdd = $("#" + myID).text();
var frm = e.target.form;
You could either choose to set the id of both forms, for example:
<form method="post" class='myform' id="form1">...</form>
<form method="post" class='myform' id="form2">...</form>
Or if you do not want to set an id, you can use :nth-child, for example:
$('.myform:nth-child(1)') //will select the 1st form
$('.myform:nth-child(2)') //will select the 2nd form
just add another class to forms like
<div class="booking_box">
<form method="post" class='myform 8'>
<button class="button" id='b2' name = "8">Book room 8</button>
<input type="hidden" name="salutation" value="<?php echo $_SESSION["salutation"]?>">
<input type="hidden" name="firstname" value="<?php echo $_SESSION["firstname"]?>">
<input type="hidden" name="room" value="8">
<input type="hidden" name="period" value="1">
</form>
</div>
<div class="booking_box">
<form method="post" class='myform 7'>
<button class="button" id='b3' name = "7">Book room 7</button>
<input type="hidden" name="salutation" value="<?php echo $_SESSION["salutation"]?>">
<input type="hidden" name="firstname" value="<?php echo $_SESSION["firstname"]?>">
<input type="hidden" name="room" value="7">
<input type="hidden" name="period" value="1">
</form>
</div>
Now in your script, you are already getting the button id as "7" or "8". Use this "myID" for selecting forms.
Add this to your script.
$('.myform').each(function( index ) {
if($(this).hasClass(myID)){
$(this).submit(function(){
return false;
});
}
});
It just iterate over your all form having "myform" as class and check if they are also having a class as "7" or "8" fetched from the button pressed.
https://api.jquery.com/each/
https://api.jquery.com/hasclass/
If you want to get the current form of your buttons, you can use .closest(). When you have the current form, you can extract all the information (input) inside.
You can do this:
$("button").click(function () {
var currentForm = $(this).closest("form");
var actionForm = $(currentForm).attr('action');
$.post(
actionFormF,
$(currentForm).find('input').serializeArray(),
function (result) {
$('#result').html(result);
}
);
});
Related
<input type="text" name="members[0].name">
<input type="text" name="members[0].address">
Javascript code :
var input_text;
var inputs=document.querySelectorAll("input[type=text],textarea, select");
_.each(inputs, function(e, i) {
var keyName = $(e).attr("name");
if (typeof keyName != "undefined") {
var text = $(e).parent().find('label').text();
if ($(e).is('select')) {
input_text = input_text + "<tr><td>" + text + "</td><td> " + $(e).find(':selected').text() + "</td></tr>";
}
else {
input_text = input_text + "<tr><td>" + text + "</td><td> " + $(e).val() + "</td></tr>";
}
}
});
console.log(input_text);
As You can see, I m getting the values of all the inputs in $(e).val() except those above mentioned inputs.
Those inputs aren't an "array" in the browser. They just use a naming convention in their name which is used by some server-side handling (for instance, in PHP) to organize the form data for you when it's submitted.
I don't know what you mean by "previewing," but you can see the values of those elements by simply looping through the elements of your form (yourForm.elements), or by using yourForm.querySelectorAll("input[type=text]") (or $(yourForm).find("input[type=text]") using jQuery — I missed the jquery tag on your question at first).
Example of theForm.elements:
document.querySelector("form input[type=button]").addEventListener("click", function() {
var form = document.getElementById("the-form");
Array.prototype.forEach.call(form.elements, function(element) {
if (element.type === "text") {
console.log(element.name + " = " + element.value);
}
});
});
<form id="the-form">
<input type="text" name="members[0].name" value="name 0">
<input type="text" name="members[0].address" value="address 0">
<input type="text" name="members[1].name" value="name 1">
<input type="text" name="members[1].address" value="address 1">
<input type="text" name="members[2].name" value="name 2">
<input type="text" name="members[2].address" value="address 2">
<div>
<input type="button" value="Show">
</div>
</form>
Example of theForm.querySelectorAll:
document.querySelector("form input[type=button]").addEventListener("click", function() {
var form = document.getElementById("the-form");
Array.prototype.forEach.call(form.querySelectorAll("input[type=text]"), function(element) {
console.log(element.name + " = " + element.value);
});
});
<form id="the-form">
<input type="text" name="members[0].name" value="name 0">
<input type="text" name="members[0].address" value="address 0">
<input type="text" name="members[1].name" value="name 1">
<input type="text" name="members[1].address" value="address 1">
<input type="text" name="members[2].name" value="name 2">
<input type="text" name="members[2].address" value="address 2">
<div>
<input type="button" value="Show">
</div>
</form>
Example of $(theForm).find:
$("form input[type=button]").on("click", function() {
var form = document.getElementById("the-form");
$(form).find("input[type=text]").each(function() {
console.log(this.name + " = " + this.value);
});
// Of course, we could have just used `$("#the-form input[type=text]").each`...
// but I was assuming you'd already have `form`
});
<form id="the-form">
<input type="text" name="members[0].name" value="name 0">
<input type="text" name="members[0].address" value="address 0">
<input type="text" name="members[1].name" value="name 1">
<input type="text" name="members[1].address" value="address 1">
<input type="text" name="members[2].name" value="name 2">
<input type="text" name="members[2].address" value="address 2">
<div>
<input type="button" value="Show">
</div>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
So many ways to get the input type values using formID
$('#formId input, #formId select').each(
function(index){
var input = $(this);
}
);
OR
var formElements = new Array();
$("form :input").each(function(){
formElements.push($(this));
});
OR
var $form_elements = $("#form_id").find(":input");
hope it helps you.
You can use serializeArray or serialize for it .
$("form").serializeArray();
The .serializeArray() method creates a JavaScript array of objects, ready to be encoded as a JSON string. Doc
I am currently working on JavaScript form validation. For individual it is applying all errors but my task is to loop all element at once and display error at once. Is there any solution?
<form action="" id="register" onsubmit="return validation()">
Name<input type="text" id="name">
<p id="error"></p>
Email<input type="text" id="email">
<p id="error"></p>
Password<input type="text" id="password">
<p id="error"></p>
<input type="submit" name="submit" value="Submit">
</form>
<script>
function validation() {
if (document.getElementById('name').value=="") {
document.getElementById("error").innerHTML="Please fill your name";
}
and so.. on..
}
</script>
Can anyone help me how to for loop all errors to display at once when user click submit buttton?
First of all, create an error box. This can be done using a simply div.
<div id="error-box" style="color: red"></div>
Second, you don't need to chain infinite if statements. You can use the fantastic and wonderful for loop!
function validation() {
var inputs = document.forms['myForm'].getElementsByTagName('input').length;
for (i = 0; i <= inputs; i++) {
if (document.forms['myForm'][i].value == "") {
document.getElementById("error-box").innerHTML="Please fill " + document.forms['myForm'][i].name;
}
}
}
This will create an array of inputs and read one by one. If any field is empty, it will return an error into your error box. If not, execution continues.
Or you can use jQuery and Validation plugin. Check here for more info. A simple jQuery form validation script
Happy coding!
First the id should be unique in same document so you have to replace duplicate ones by classes, e.g :
Name<input type="text" id="name">
<p class="error"></p>
Email<input type="text" id="email">
<p class="error"></p>
Password<input type="text" id="password">
<p class="error"></p>
Then just show the error message of the input in the related .error paragraph :
function validation() {
if ($('#name').val()==="") {
$('#name').next(".error").html("Please fill your name");
}
}
Hope this helps.
$('#register').on('submit', function(){
var submit = true;
if ($('#country').val()==='-1'){
$('#country').next(".error").html("Please fill your country");
submit = false;
}else
$('#country').next(".error").html("");
if ($('#name').val()===""){
$('#name').next(".error").html("Please fill your name");
submit = false;
}else
$('#name').next(".error").html("");
if ($('#email').val()===""){
$('#email').next(".error").html("Please fill your email");
submit = false;
}else
$('#email').next(".error").html("");
if ($('#password').val()===""){
$('#password').next(".error").html("Please fill your password");
submit = false;
}else
$('#password').next(".error").html("");
if ($('[name="check"]:checked').length===0){
$('[name="check"]:last').next(".error").html("Please check one at least");
submit = false;
}else
$('[name="check"]').next(".error").html("");
return submit;
})
.error{
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="" name="register" id="register">
Country
<select name="country" id="country">
<option value="-1">Select country please</option>
<option value="usa">USA</option>
<option value="austriala">Austriala</option>
<option value="india">India</option>
</select>
<p class="error"></p>
Name <input type="text" id="name">
<p class="error"></p>
Email <input type="text" id="email">
<p class="error"></p>
Password <input type="text" id="password">
<p class="error"></p>
Checkboxes
<br>
<input type="checkbox" name="check" value="check_1">check 1
<br>
<input type="checkbox" name="check" value="check_2">check 2
<br>
<input type="checkbox" name="check" value="check_3">check 3
<p class="error"></p>
<input type="submit" name="submit" value="Submit">
</form>
Hmm. How about a native way? :)
function select( cssSelector ){ return document.querySleectorAll( cssSelector ) };
var inputs = select( '#register input' ); // selects array of all child inputs
//setup all validations within an object
var validations = {
name: function( nameText ){
//shorthand if-statements, expand if you need to
return ( nameText === "" ) ? "error, cannot be empty" : "ok";
},
password: function( passText ){
return ( passText.length < 8 )? "too short" : "ok";
}
};
//iterate over all inputs
for( var elem in inputs ){
if( validations[ inputs[ elem ].id ] ){ // if validation rule exists..
console.log( "input nr " + elem + "tested\n" +
"id = " + inputs[ elem ].id + "\n" +
"outcome: " + validations[ inputs[ elem ] ] );
}
}
I have not tested this so there might be typos
I´m working in a payment gateway where the user Name the Price for my digital books. An input box (to text the price) and a "Pay now" button are displayed. BUT:
If the price is less than 0.50 the payment button disapear and the download button appear
If the user introduce a "," instead a "." a box is displayed (please, enter a valid number)
Here is the form with the input box:
<form id="hikashop_paypal_form" name="hikashop_paypal_form" action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_cart">
<input type="hidden" name="business" value="X" />
<input type="hidden" name="item_name_1" value="X" />
<input id="amount_1" name="amount_1" class="amount_1"/></form>
Pay Now button (it should be hiden if 1 is true)
<div id="PayNow" class="PayNow">
<input id="PayNow_button" type="submit" class="btn btn-primary" value="Pay now" name="" />
</div>
Download Now Button (it should be shown if 1 is true)
<div id="downloadNow" class="downloadNow">
Download now
</div>
Info box (It should be shown if 2 is true)
<div id="info" class="info">
Enter a valid number
</div>
And the question is: How can I do it?
I supose the solution passes by using javascript, but I don´t know how exactly... Thanks for you time...
I don´t know how, but it works for me:
Try it here: IBIZA! Book Download
<form id="pplaunch" action="https://www.paypal.com/cgi-bin/webscr" method="POST">
<input type="hidden" name="cmd" value="_xclick">
<input id="issueid" name="issueid" type="hidden" value="ARCHIVE NAME">
<input type="hidden" id="currency" name="currency" value="EUR">
<input type="hidden" name="business" value="YOUR PAYPAL ID" />
<input type="hidden" value="0" name="test_ipn"></input>
<input type="hidden" name="item_name" value="PRODUC NAME">
<input type="hidden" value="1" name="no_shipping"></input>
<input type="hidden" value="0" name="no_note"></input>
<input type="hidden" value="utf-8" name="charset"></input>
<input type="hidden" value="Super" name="first_name"></input>
<input type="hidden" value="http://www.YOURWEBSITE.com/return" name="return"></input>
<input type="hidden" value="http://www.OURWEBSITE.com/cancel" name="cancel_return"></input>
<div class="nameprice" style="float:left;margin-right:15px;>
<span style="font-size:small;">Name your price: </span><input id="amount" name="amount" size="6" maxlength="5" type="text"> <span style="font-size:small;color:#ccc;">From 0.00€</span>
</div>
<div id="pricerror"></div>
<div class="buttonspace">
<button id="buybutton" class="buybutton" type="button">Checkout</button>
<div id="descargaGratisMensaje"></div>
<div style="display: block;" class="pay">
</div>
</div>
</form>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
<script type="text/javascript">
function newPopup(url, width, height){
popupWindow = window.open(url,'_blank','height='+height+',width='+width+',left=10,top=10,resizable=yes,scrollbars=yes,toolbar=yes,menubar=no,location=no,directories=no,status=yes');
return false;
}
function displaybutton(displayclass){
if(displayclass == 'pay'){
$('.pay').css('display','block');
$('#pplaunch').attr('action', 'https://www.paypal.com/cgi-binwebscr');
$('#buybutton').html('Pagar');
}else{
$('.pay').css('display','none');
$('#pplaunch').attr('action', 'http://www.example.com/archive/'+$('#issueid').val());
$('#buybutton').html('Descargar');
$('#descargaGratisMensaje').html('Un Me Gusta podría ser un buen intercambio');
}
}
function isNumber(n){
return !isNaN(parseFloat(n)) && isFinite(n) && (n.search(/0x/i)<0);
}
function price(n){
// return null if n is not a price, or n rounded to 2 dec. places
if(!isNumber(n)){
// maybe the user entered a comma as a decimal separator
n = n.replace(/,/g,'.');
if(!isNumber(n)){
return null;
}
}
// now we know it is a number, round it up to 2 dec. places
return Math.round(parseFloat(n)*100)/100;
}
function pricecheck(){
var data = $.trim($('#amount').val());
var myprice = price(data);
if(myprice == null){
if(data == ''){
$('#pricerror').html('');
}else{
$('#pricerror').html('Please enter a price.');
}
displaybutton('pay');
return false;
}
if(myprice == 0){
$('#pricerror').html('');
displaybutton('nopay');
}else if(myprice < 0.5){
$('#pricerror').html('The minimum price is '+currencysymbol+'0.50.
Please enter either zero, or at least '+currencysymbol+'0.50.');
displaybutton('pay');
}else{
$('#pricerror').html('');
displaybutton('pay');
}
jQuery('.content').hide();
}
var currencysymbol = '$';
$.getScript('//www.geoplugin.ne/javascript.gp?ref=panelsyndicate.com', function() {
if(geoplugin_continentCode() != 'EU'){return;}
$('#currency').val('EUR');
currencysymbol = '€';
$('.currencysymbol').html(currencysymbol);
});
$(document).ready(function(){
var dialog = $('#modal').dialog({
title: 'IBIZA!'
, autoOpen: false
, closeText: ''
, modal: true
, resizable: false
, width: 500
});
$('#buybutton').click(function() {
$('#pplaunch').submit();
});
$('#pplaunch').submit(function() {
var myprice = price($.trim($('#amount').val()));
if((myprice != 0) && ((myprice == null) || (myprice < 0.5))){
$('#pricerror').html('Please enter your price.');
$('#amount').focus();
return false;
}
});
$('.modaltrigger').click(function() {
var issueid = $(this).attr('href').substr(1);
$('#issueid').val(issueid); // Comic ID
$('#include_a_message_to').html(issues[issueid].include_a_message_to); // Destinee of the message
dialog.dialog('option', 'title', issues[issueid].title); // Title of the comic
$('#issuelangs').html(issues[issueid].langs); // Languages in which the comic is available
dialog.dialog('option', 'position', { my: "center", at: "center", of: window });
dialog.dialog('open');
// prevent the default action, e.g., following a link
pricecheck();
return false;
});
$('#amount').bind('input propertychange', function() {
pricecheck();
});
$('.custommsg').hide();
$('.msgtrigger').click(function() {
var cmsg = $('.custommsg');
if(cmsg.is(':visible')){
cmsg.hide();
$('.sendmsg').show();
}else{
$('.sendmsg').hide();
cmsg.show();
$('.msgtxt').focus();
}
return false;
});
$('.msgtxt').keyup(function(){
if($(this).val().length > maxlength){
$(this).val($(this).val().substr(0, maxlength));
}
var remaining = maxlength - $(this).val().length;
$('#msgtxtnumcharsleft').text(remaining);
});
var maxlength = 200;
var remaining = maxlength - $('.msgtxt').val().length;
$('#msgtxtnumcharsleft').text(remaining);
});
</script>
I am using this code to generate dynamically ADD More input fields and then plan on using Save button to save their values in database. The challenge is that on Save button, I want to keep displaying the User Generated Input fields. However they are being refreshed on Save button clicked.
javascript:
<script type="text/javascript">
var rowNum = 0;
function addRow(frm) {
rowNum++;
var row = '<p id="rowNum' + rowNum + '">Item quantity: <input type="text" name="qty[]" size="4" value="' + frm.add_qty.value + '"> Item name: <input type="text" name="name[]" value="' + frm.add_name.value + '"> <input type="button" value="Remove" onclick="removeRow(' + rowNum + ');"></p>';
jQuery('#itemRows').append(row);
frm.add_qty.value = '';
frm.add_name.value = '';
}
function removeRow(rnum) {
jQuery('#rowNum' + rnum).remove();
}
</script>
HTML:
<form method="post">
<div id="itemRows">Item quantity:
<input type="text" name="add_qty" size="4" />Item name:
<input type="text" name="add_name" />
<input onclick="addRow(this.form);" type="button" value="Add row" />
</div>
<p>
<button id="_save">Save by grabbing html</button>
<br>
</p>
</form>
One approach is to define a template to add it dynamically via jQuery
Template
<script type="text/html" id="form_tpl">
<div class = "control-group" >
<label class = "control-label"for = 'emp_name' > Employer Name </label>
<div class="controls">
<input type="text" name="work_emp_name[<%= element.i %>]" class="work_emp_name"
value="" />
</div>
</div>
Button click event
$("form").on("click", ".add_employer", function (e) {
e.preventDefault();
var tplData = {
i: counter
};
$("#word_exp_area").append(tpl(tplData));
counter += 1;
});
The main thing is to call e.preventDefault(); to prevent the page from reload.
You might want to check this working example
http://jsfiddle.net/hatemalimam/EpM7W/
along with what Hatem Alimam wrote,
have your form call an upate.php file, targeting an iframe of 1px.
I have this JQuery:
$(document).ready(function() {
$("#generate").click(function() {
var texts = [];
alert();
$("form label").each(function() {
var oLabel = $(this);
var oInput = oLabel.next();
texts.push(oLabel.text() + " " + oInput.val());
});
texts[0] += texts[1];
texts[2] += texts[3];
for(i=3;i<texts.length;i++)
texts[i-1] = texts[i];
texts[texts.length-1] = null;
$("#cont").html(texts.join("<br />"));
});
});
What it do is it reads form elements then types them as regular text (there is a purpose for this).
And this is how my form looks like ...
<div id="cont" style="float:right; width:75%; height:auto">
<form onSubmit="return generate();">
<label class="itemLabel" for="name">Name : </label>
<input name="name" type="text" class="itemInput" value="<? echo $queryB[1]; ?>" readonly="readonly" />
<label># Some Text</label><br />
<label for="priPhone" class="itemLabel">Customer Telephone Number : </label>Phone#
<input name="priPhone" type="text" class="itemInput" readonly="readonly" value="<? echo $queryB[2]; ?>" />
<label for="secPhone"> // Mobile#</label>
<input name="secPhone" type="text" class="itemInput" readonly="readonly" value="<? echo $queryB[3]; ?>" /><br />
<label class="itemLabel" for="email">Customer Email Address : </label>
<input name="email" type="text" class="itemInput" readonly="readonly" value="<? echo $queryB[4]; ?>" /><br />
<label>***************</label><br />
<label>Best Regards,</label><br />
<input name="another_field" type="text" /><br />
<label>last thing</label><br />
<button type="button" id="generate">Generate</button>
</form>
</div>
now, when I click the button "Generate", everything goes well except that it ignores "another_field" and doesn't get its value
Anyone got an idea to solve this? (Note: This piece of code will be running on around 25 forms so I need to have it working.)
UPDATE:
Sample output:
Name : username # Some Text
Customer Telephone Number : 90237590 // 3298579
Customer Email Address : email#host.com
***************
Best Regards,
last_field
last thing
Workaround
Since I'm having all the forms have the same ending, I've been able to get to this code:
texts[0] += " " + texts[1];
texts[1] = texts[2] + " " + texts[3];
for(i=4;i<texts.length;i++)
texts[i-2] = texts[i];
texts[texts.length-2] = texts[texts.length-3];
texts[texts.length-3] = $("#agent").val() ;
texts[texts.length-1] = null;
It solved the problem, but I'm looking for a better way to accomplish this.
Try this javascript:
$(document).ready(function() {
$("#generate").click(function() {
var texts = [];
$("form").children().each(function() {
var el = $(this);
if (el.prop('tagName') == "LABEL") texts.push(el.text());
if (el.prop('tagName') == "INPUT") texts.push(el.val());
if (el.prop('tagName') == "BR") texts.push("<br />");
});
$("#cont").html(texts.join(""));
});
});
Working example here:
http://jsfiddle.net/Q5AD4/6/
Your <br/> tag is the next tag after the label before "another_field". You should probably make your next call something like:
var oInput = oLabel.next('input');