How to send POST requests from dynamic fields? - javascript

I'm creating a quiz form to pass into a JSON file, but I'm having trouble sending the POST requests. I'm not sure which fields I can access, or how.
This is the form: https://i.imgur.com/6xtmt3a.png
<script>
// input field
$(document).ready(function() {
var wrapper = $(".div1");
var newbutton = $(".add_form_field");
var fields = 1;
$(newbutton).click(function(e) {
e.preventDefault();
$(wrapper).append(' <div class="input-group"> <input type="text" value = "Question" class="form-control" placeholder="Recipients username" <div class="input-group-append" id="button-addon4"><button class="btn btn-outline-secondary" id ="delete" type="button">Delete</button><button class="btn btn-outline-secondary" id ="add" type="button">Add</button></div></div></div>'); //add input box
//$(wrapper).append('<button type="button" id ="test1" class="btn btn-primary">Primary</button>'); //add input box
//$(wrapper).append('<div><input type="text" value = "Question"name="mytext[]"/> Delete add </div> '); //add input box
var d = $(this).parent('form').serialize();
console.log(d);
});
//delete buttons
$(wrapper).on("click", "#delete", function(e) {
e.preventDefault();
$(this).parent('div').remove();
fields--;
})
// remove div
$(wrapper).on("click", '#s1', function(e) {
//$(this).parent('div').parent('div').remove();
var q= $(this).parent().serialize();
console.log(q);
})
//add answer
$(wrapper).on("click", "#add", function(e) {
e.preventDefault();
$(this).parent('div').append('\n <div class="input-group flex-nowrap"><div class="input-group-prepend"><span class="input-group-text" id="addon-wrapping">-</span></div><input type="text" class="form-control" placeholder="Answer" aria-label="Username" aria-describedby="addon-wrapping"></div> ' );
var d = $(this).parent('form').serialize();
console.log(d);
//$(this).parent('div').parent('div').append('<div class="input-group mb-3"><input type="text" class="form-control" placeholder="Recipients username" aria-label="Recipients username" aria-describedby="button-addon2"><div class="input-group-append"><button class="btn btn-outline-secondary" type="button" id="button-addon2">Button</button></div></div>' );
fields--;
})
});
$( "#quizForm" ).submit(function( event ) {
var $form = $( this ),
path = $form.attr( "action" );
payload = {"testKey":"test"};
var posting = $.ajax({
url: path,
method: "POST",
headers: {'X-CSRFToken': '{{ csrf_token }}'},
data: payload,
dataType: "application-json",
});
console.log(payload);
posting.done(function() {
console.log("posted");
});
});
</script>
I need to have a JSON file output on submit that contains the questions and answers to each question (right or wrong for now) Thanks!

I would suggest adding an attribute contains the object's key on each question - let's say it will be the "question ID".
we will have something like that:
<div class="question-container" question-id="01"></div>
Assuming that answers are an .answer div with an input inside we will have something like that on form submit:
let formObject = new Object();
$('.question-container')
.each(function () {
const questionID = this.attr('question-id');
const answersArray = new Array();
this.find('.answer input')
.each(function () { // assuming answer is a div contains an input tag
answersArray.push(this.value());
})
formObject[questionID] = answersArray;
})
/// here formObject contains the formatted form as json

Related

jQuery validate , how to make validation rules for dynamically generated fields?

I have an HTML form with dynamically add more fields. For example company name. I am trying to use the jQuery validate method to validate. It is working fine with the existing company name field. Here is the code.
<script>
$("#company_creation_form").validate({
rules:{
company_name: {
required: true,
minlength: 3
}
},
submitHandler: function (form) {
$.ajax({
type: "POST",
url: "<?php echo BASE_URL;?>crm/thankyou/",
data: $(form).serialize()+"&company_count="+company_count,
success: function () {
alert("thanks");
}
});
return false; // required to block normal submit since you used ajax
}
});
</script>
When I click on add more button another company name field will create on the form. The below code is failed to validate the dynamically generated field. Here I am getting the field count globally in this variable company_count
<script>
$("#company_creation_form").validate({
rules:{
company_name: {
required: true,
minlength: 3
},
I tried like below, but this is giving me error
if(company_count> 0){
var new_field = jQuery("#company_name"+company_count);
new_field : {
required: true,
minlength: 3
},
}
The above block code is showing error in the text editor it self
},
submitHandler: function (form) {
$.ajax({
type: "POST",
url: "<?php echo BASE_URL;?>crm/thankyou/",
data: $(form).serialize()+"&company_count="+company_count,
success: function () {
alert("thanks");
}
});
return false; // required to block normal submit since you used ajax
}
});
</script>
Can anyone help me with how to make validation for these dynamically generated fields? Any help would be greatly appreciated. I am using form submission by using Ajax.
Code to add company fields dynamically
var company_room = 0;
var company_room1 = 0;
function add_another_company() {
company_room++;
company_room1++;
var objTo = document.getElementById('company_field')
var divtest = document.createElement("div");
divtest.setAttribute("class", "form-group removeclass2" + company_room);
//var rdiv = 'removeclass2' + company_room;
divtest.innerHTML = '<div class="form-row"><div class="col-sm-5"> <div class="form-group pad-tp-5"><input type="text" class="form-control aj4" id="company_name" name="company_name" placeholder="Company Name"></div></div><div class="col-sm-2"> <div class="form-group"> <button class="btn btn-danger bdr-rds-100 btn-pad" type="button" onclick="remove_another_company(' + company_room + ');"> <i class="fa fa-minus"></i> </button> </div></div></div>';
objTo.appendChild(divtest);
var E_fields = $('.aj4');
var E_count = 1;
$.each(E_fields, function() {
jQuery(this).attr('id','company_name' + E_count);
jQuery(this).attr('name','company_name' + E_count);
E_count++;
});
}
function remove_another_company(rid2) {
company_room1--;
$('.removeclass2' + rid2).remove();
var E_fields = $('.aj4');
var E_count = 1;
$.each(E_fields, function() {
jQuery(this).attr('id','company_name' + E_count);
jQuery(this).attr('name','company_name' + E_count);
E_count++;
});
}
OK, so I didn't have your HTML so I had to mock some up. You will obviously have to tweak this a little to work with your ID's. I tried to keep it as close as possible to the ID's/classes you were already using.
I removed the pure javascript functions and the onclick events in favor of jquery since you were already using it. Hopefully this kind of simplifies things a bit and makes it more manageable.
NOTE: I added a hidden input field to keep track of company count. This way it will be included when you $(form).serialize in your ajax options (as you are adding it with a variable now). I included code to preserve the company_count variable also, so basically you will have 2 company counts. I did this just to show you an easier way to keep track of this without having to micro manage it. :)
Try out this code and let me know what your getting in console if it is not working. Thanks
MOCK HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="form-wrapper">
<p>Dynamic Form</p>
<button id="addField">Add Dynamic Field</button>
<form id="dynForm">
Static Field: <input id="company_name" name="company_name" minlength="3" type="text" value="Static Company Name" required>
<br>
<input type="hidden" id="companyCount" name="companyCount" value="1">
<div id="company_field">
</div>
</form>
</div>
JQUERY/JS
$(function() { // <---- Document Ready!
$("#addField").on("click", () => {
var count = parseInt($("#companyCount").val(), 10);
count += 1;
$("#companyCount").val(count.toString());
var thisId = "company_name" + count.toString();
var html = '<div class="form-row"><div class="col-sm-5"> <div class="form-group pad-tp-5"><input type="text" class="form-control aj4" id="'+thisId+'" name="'+thisId+'" minlength="3" placeholder="Company Name" required></div></div><div class="col-sm-2"> <div class="form-group"> <button class="btn btn-danger bdr-rds-100 btn-pad" type="button"> <i class="fa fa-minus"></i> </button> </div></div></div>';
var ele = $.parseHTML(html);
$("#company_field").append(ele);
});
$("#company_field").on("click", "button", () => $(this).closest(".form-row").remove());
$("#company_creation_form").validate({
submitHandler: function(form) {
var company_count = parseInt($("#companyCount").val(), 10);
$.ajax({
type: "POST",
url: "<?php echo BASE_URL;?>crm/thankyou/",
data: $(form).serialize() + "&company_count=" + company_count,
success: function() {
alert("thanks");
}
});
return false;
}
});
});

focusout handler also fires on focusin

I have jQuery code that executes an AJAX request every time the text input is focused out. The thing I don't understand is when I focus back in the AJAX request gets executed. There's no focusin function defined. Code snippet below:
$(function() {
// some other functions here but no focusin function defined.
$( "#additem" ).click(function(e) {
e.preventDefault();
var _id = "new_pn", _holder = "Enter part number here", btnId = "post", btnIcon = "fa fa-save", btnText = " Add Serial", formId = "new-sn";
openModal(_id, _holder, btnId, btnIcon, btnText, formId);
});
var openModal = function(a,b,c,d,e, f) {
var txtInput = $("#myModal form input")[1], btn = $("#myModal form button")[0], icon = $("#myModal form i")[0], form = $("#myModal form")[0];
txtInput.id = a;
txtInput.placeholder = b;
btn.id = c;
icon.className = d;
form.id = f;
$($("#myModal form span")[1]).text(e);
$("#myModal").attr('style', 'display:block');
};
//Check serial before saving when text field is focusout. 2nd argument, #new-sn is a dynamically created form id.
$('#myModal').on('focusout', $('#new-sn input')[0], function() {
var sn = $("#serial").val();
if (sn) {
Promise.resolve(GetDocumentItems(serialsDb, sn)).then(function() {
console.log(sn.toUpperCase() + " already exists in the database");
}).catch(function() {
console.log(sn.toUpperCase() + " is cleared to save in database.");
});
}
});
});
What am I doing wrong here? Cheers
Added HTML code below:
<div id="myModal" class="modal">
<div class="modal-content">
<!--variable form id (depends on the caller)-->
<form>
<div class="container">
<span class="close">×</span>
<input id="serial" type="text" placeholder="Enter serial number here">
<!--2nd text box, variable id and placeholder (depends on the caller)-->
<input type="text">
<!--button variable id and i variable class (invoker dependent).-->
<button class="green"><i></i> <span></span></button>
</div>
</form>
</div>
</div>

User input does not get captured/stored

I am trying to figure out why this onclick function in my JavaScript and Jquery code are not working.
I am referring my "userInput" in the JavaScript code and storing it in a variable called "userDate". For some reason, the user input does not get captured/stored.
This is my HTML:
<form role="form">
<p> Enter the date:
<input id="userInput" type="text" placeholder="yyyy-mm-dd" autofocus required></p>
<button id="convert" type="submit" class="btn btn-primary btn-lg" padding="center">
<span class="glyphicon glyphicon-euro"></span>
</button>
</form>
This is my JS code:
$(function () {
// cache the DOM element
var $currencies = $("#currencies");
var $userInput = $("#userInput");
// We are listening on the 'document',
// for a click on an element with an ID of #convert in the HTML
$("#convert").on("click", function() {
var userDate = $userInput;
// testing
console.log(userDate);
alert ("Handler for .click() is called.");
// AJAX call for GET request
$.ajax({
type: 'GET',
url: 'http://xxx.xx',
success: function(currencies) {
console.log("success func is called");
console.log(userDate);
$.each(currencies, function(i, currency){
$currencies.append("<div> EUR: " + currencies.rates["EUR"] + ", date: " + currencies.date + "</div>");
});
},
// error handling for my request
error: function() {
alert("error loading currencies");
}
});
});
});
change
var userDate = $userInput;
to
var userDate = $userInput.val();
$userInput is a reference to the jquery object holding the input element. Using .val() returns the text value of that input element.

Getting sibling text input value

I have the following HTML
<li class='user_attributes'><b>username: </b>{{username}}
<input class='user_input form-control edit_fields {{_id}}' id='username_field' type="text" name='username' placeholder="username">
<button type="submit" class="btn btn-default submit_button edit_fields {{_id}}" id='update_username'>update</button>
</li>
And I'd like to get the value of the input field whenever that <li>'s submit button is clicked (not the value of other input fields with the same name).
I have the following jQuery, but all of it returns undefined:
'click #update_username': function(ev, template){
ev.preventDefault();
// var username_field = template.$('input[id="username_field"]').val();
// var username_field = $(ev.target).find('[name = message]').val();
var input_field = $(this).siblings($('input[id="username_field"]')).val();
console.log(input_field);
// Meteor.call('updateUsername', this._id, username_field);
}
EDIT
this is an issue of the framework Im using (Meteor.js) and the scope of 'this'
Try that
https://jsfiddle.net/zy7qy3v5/3/
$('button').click(function(){
var value = $(this).siblings('input').val();
alert(value);
})
Dont put an unecessary jquery object in the siblings function. Your selector is returning every siblings.
$('button').siblings('input') //Returns 1 element
is not the same as
$(this).siblings($('input[id="username_field"]')) //Returns 2 element
See https://jsfiddle.net/8x04nbyx/5/
$(document).ready(function(){
$('#update_username').on('click',function(ev, template){
ev.preventDefault();
// var username_field = template.$('input[id="username_field"]').val();
// var username_field = $(ev.target).find('[name = message]').val();
var input_field = $(this).closest('li').find('input').val();
console.log(input_field);
// Meteor.call('updateUsername', this._id, username_field);
});
});
I'm not sure if it's this that you want but give it a try:
$('#update_username').click(function(){
var test = $('#username_field').val()
alert (test)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<li class='user_attributes'><b>username: </b>{{username}}
<input class='user_input form-control edit_fields {{_id}}' id='username_field' type="text" name='username' placeholder="username">
<button type="submit" class="btn btn-default submit_button edit_fields {{_id}}" id='update_username'>update</button>
</li>

ajaxForm is sending empty POST when submit from dynamically built form

Submitting a file with ajaxSubmit() works fine when the form is hard-coded. But the data received by the server is empty when the form is created dynamically.
This version works
HTML
<form id='file_upload_form' method="POST" enctype="multipart/form-data" action="/upload">
<input type="file" id='myfile' name="myfile" />
<br/>
<input type="submit" />
</form>
<div id='status'> </div>
JavaScript
jQuery(document).ready(function() {
jQuery("#file_upload_form").on("submit", function(e) {
e.preventDefault();
jQuery(this).ajaxSubmit({
target: '#status'
});
});
});
Debuggin in .on("submit"... , jQuery(this).formSerialize() yields "myfile=%5Bobject+File%5D"
But this version using a dynamically created form sends empty data
HTML
<div id='parent_elem_div'> </div>
<div id='status'> </div>
JavaScript
jQuery(document).ready(function() {
var parent_elem = jQuery('#parent_elem_div');
var new_form_elem = build_form();
parent_elem.append(new_form_elem);
});
jQuery(document).ready(function() {
jQuery("#file_upload_form").on("submit", function(e) {
e.preventDefault();
jQuery(this).ajaxSubmit({
target: '#status'
});
});
});
But here, debuggin in .on("submit"... , jQuery(this).formSerialize() yields "".
This function builds the form...
//
function build_form (){
var new_inner_div_elem = document.createElement('div');
new_inner_div_elem.id = 'parent_elem_div';
var upload_form = document.createElement('form');
upload_form.id = 'file_upload_form';
upload_form.action = '/upload';
upload_form.method = 'POST';
upload_form.enctype="multipart/form-data";
var file_input = document.createElement('input');
file_input.type = 'file';
file_input.id = 'file_upload_input';
var file_upload_submit = document.createElement('input');
file_upload_submit.type = 'submit';
upload_form.appendChild(file_input);
upload_form.appendChild(file_upload_submit);
new_inner_div_elem.appendChild(upload_form);
return new_inner_div_elem;
}
Aha! Here it go, in your code:
var file_input = document.createElement('input');
file_input.type = 'file';
file_input.id = 'file_upload_input';
This is missing:
file_input.attr('name', 'myfile');
This is the only part that your HTML form has, and dynamical doesn't, so I guess that's the trick
If an HTML doesn't have a name it won't be passed to the
querystring or the POST data - there will be no way to retrieve it
from PHP
This is from here - stackoverflow

Categories