Combining two separate forms into one - javascript

I've been messing around with a two forms and would like to combine them. Each form has a separate JS.
I'd like to be able to take the values in Form #1 and have them placed in the Form#2 answers.
Could somebody please assist?
Form #1
$(window).load(function(){
jQuery(function($) {
var multiTags = $("#multi");
function handler(e) {
var jqEl = $(e.currentTarget);
var tag = jqEl.parent();
switch (jqEl.attr("data-action")) {
case "add":
tag.after(tag.clone().find("input").val("").end());
break;
case "delete":
tag.remove();
break;
}
return false;
}
function save(e) {
var tags = multiTags.find("input.tag").map(function() {
return $(this).val();
}).get().join(',');
alert(tags);
return false;
}
multiTags.submit(save).find("a").live("click", handler);
});
});
</script>
Form #2
$(document).ready(function(){
$('.submit').click(function(){
var answers = [];
$.each($('.field'), function() {
answers.push($(this).val());
});
if(answers.length == 0) {
answers = "none";
}
alert(answers);
return false;
});
});

I'll make my comment an answer, and elaborate a little bit more.
I made a simple little fiddle that you can use as a jumping off point for this. Basically, it will grab all values of the inputs on the page and assign them to a variable. From there, your script could send that variable to your mailer script which processes everything...
var data = "";
$("input").each(function(index, element) {
data += $(this).val() + ", ";
});
alert(data);​
The script looks for all <input> tags, and then gets the value from them via .val(). In your form, you'd run this on click, $("input[type=submit]").click(function(){ ... }); where the ... would be the code above. Obviously, you wouldn't want to alert what the user had typed into the box (they typed it, after all), so you'd then pass that variable on to your mailing script (I'd google on how to do this, as your mailer script is probably written in PHP, so google something like pass jQuery variable onto PHP).
Fiddle: http://jsfiddle.net/charlescarver/4AfTR/2/
Is there a way to group the inputs so that data only uses input boxes 1,2,3 (for example).
Yes, this line here...
$("input")
...finds all <input> tags on the page. If you only want <input> boxes 1,2 and 3 to have their value assigned to a variable, then give them a class and change "input" to ".classname". Ex.) $(".tag") will only assign <input> boxes with the class .tag to a variable (<input class="tag />).

Related

Store HTML form data in JS variable using jQuery serializeArray

I am trying to use Javascript/jQuery to get data from a form and save the value to a variable. There is only a single text input and submit button in the form, and only one piece of data will need to be retrieved. I pieced together this code from examples online but it isn't giving me any output.
$("#submit").onclick = function() {
var input = "";
$("#binary-input").click(function() {
var x = $("form").serializeArray();
$.each(x, function(i, field) {
input = field.value;
});
});
console.log("Input: ");
console.log(input);
}
A fix for my code is what I'm requesting, but a more efficient approach would also be much appreciated.
First off jQuery doesn't have an 'onclick' event handler. You can either use 'click' (https://api.jquery.com/click/) like so:
$("#submit").click(function()...
Or use 'on' (https://api.jquery.com/on/) and specify the type of event you want to handle
This is what I'd normally do:
$("#submit").on("click", function(){
// Get the input and its value
var inputValue = $("#binary-input").val();
// Output the value
console.log(inputValue);
}
Hope that helps.

Form Event Handling Pattern

I am using a backend where it is ideal that I send an ajax post request rather than using the default action on forms.
With this in mind, I need to extract the final fields that are selected in my form.
I have various text fields, radio buttons, checkboxes, etc.
I've always struggled gaining a good understanding of event delegation and event propagation. I'm not entirely sure if this is the topic I should be worried about with what I am trying to achieve.
I know I can write code that grabs all of the information in my form by placing an ID on each field and a have a function extract each value on the ID such as:
function example(){
var field0 = $('#field0').val();
var field1 = $('#field1').parent().hasClass('active')
// ... and more
}
I've used this pattern for a while and I don't feel like it is efficient.
I have two pattern idea, but I am still not sure if this is a "common practice"
Since I am not concerned about the data in each field until the form is submitted, I could run a loop on all of my input based fields on my form and extract the contents, instead of assigning an ID to each individual input field.
I can listen to changes on the form (I am not exactly sure how to do this, this is where event delegation/propagation will come into play). Instead of waiting for the submit button to gather all the info in the form, I will have some type of listener that detects a change on the form (not sure if that is possible).
I've been using my current pattern for several months and would like to improve myself, If anyone has any suggestions, links, or criticism about my thoughts on a new approach I'd appreciate it.
So, you basically propose 3 ways to get all form fields with a value on submit (or a similar event):
hard-code IDs and retrieve their values, e.g.
var field_a = document.getElementById('a')
, field_b = document.getElementById('b')
, form = document.getElementById('my_form');
form.addEventListener('submit', function() {
fetch('//your/api/endpoint', {
method: 'POST',
body: JSON.stringify({a: field_a.value, b: field_b.value})
});
});
loop all and retrieve their values, e.g.
var form = document.getElementById('my_form');
form.addEventListener('submit', function() {
var values = [].reduce.call(
form.querySelectorAll('input, textarea, select'),
function(values, element) {
values[element.name] = element.value;
return values;
},
{}
);
fetch('//your/api/endpoint', {
method: 'POST',
body: JSON.stringify(values)
});
});
watch for changes inside the form, accumulate them
var form = document.getElementById('my_form')
, state = {};
form.addEventListener('change', function(e) {
state[e.srcElement.name] = e.value;
});
form.addEventListener('submit', function() {
fetch('//your/api/endpoint', {
method: 'POST',
body: JSON.stringify(state)
});
});
From a performance perspective, option 1. will be the fastest, followed by 2 followed by 3 (with the last 2 I'm not 100% certain, querySelectorAll can be expensive, but listening for tons of change events might be as well -- depends on how often change events are triggered I'd say).
From development perspective (how long does it take to set up a form), 2 and 3 should not be that different as they are both generic (and you can use my code sample as a start).
"Real" data-binding (like Angular) or "pure state" (like React) pretty much come down to options 2/3 as well (just that the framework will perform the heavy lifting for you).
Regarding option 3 (listening for a change on the whole form): https://stackoverflow.com/a/4616720/1168892 explains quite well how event bubbling in JavaScript happens. To use that you have to make sure that no element inside the form cancels the change event (otherwise it would not bubble to the form itself). To not cancel events is the default behavior, so you would have to explicitly make this wrong (and with that you can just have an eye on it in your implementation).
I didn't use jQuery in my examples as that can all be done by browsers directly now. What I used are Element.querySelectorAll, Array.reduce and window.fetch.
Pattern #1 (use serializeArray)
$('#formId').on('submit', function(e){
var allData;
e.preventDefault();
allData = $(this).serializeArray();
// use the allData variable when sending the ajax request
});
Pattern #2 (use the delegated form of $container.on('event', 'selector', ..) and the change event)
$('#formId').on('change', 'input,textarea,select', function(){
var element = $(this), // element that changed
value = element.val(); // its new value
// do what you want ..
});
Without jquery I once wrote a function that return in an object all input value tie with its name.
I think it's better than plain id link, because you don't have to worry about what's inside your form, as long as your giving a name attribute to your inputs.
function getFormData(form) {
var data = {};
for (var i = 0; i < form.elements.length; i++) {
var input = form.elements[i];
if (input.value && input.type !== 'submit' && input.type !== 'button') {
data[input.name] = input.value;
}
}
return data;
}
All you need to do is passing your form like this:
var form = document.querySelector('.monFormulaire');
// your form data
var data = getFormData(form);

jQuery AJAX call from multiple input fields within the 1 script

I'm working on my first HTML form that performs an AJAX HTTP POST using jQuery. When a user makes a change to an input text field and tabs out of the field it triggers the AJAX script which in turn calls a PHP script which performs a database update.
I've got this working successfully for my first input field - I would now like to extend this to a 2nd, 3rd etc input fields but want to try and avoid having multiple scripts that perform very similar functions. I'm new to jQuery and AJAX so learning the syntax as I go.
Here's my input fields:
Manager
Phone
Here's my Javascript that is working on the storeManager input field:
<script type="text/javascript">
$(document).ready(function() {
$("#storeManager").change(function(){
var storeManager = $("#storeManager").val();
$.post('editProject.php', { storeManager: storeManager, id: '1E1DDA14-D2C6-4FC8-BA5F-DBCCC7ABAF7F' }, function(data) {
$("#managerRow").addClass("success");
}).fail(function () {
// no data available in this context
$("#managerRow").addClass("danger");
$("#ajaxAlert").addClass("alert alert-danger");
});
});
});
</script>
I essentially need to branch and pass an additional POST parameter to the editProject.php script so it knows which database field to update, and then conditionally add a class to the appropriate row.
Everything I've tried breaks the script when I try and get it to branch or pass a parameter based on the input field that is being edited. I haven't been able to find any examples that show the correct syntax to have the one script that is called by different input fields - I'm presuming this is possible instead of having multiple versions of the same script acting on different fields.
This works for multiple fields. Just call the same function from different input fields. I just broke your code into two parts.
1. onChange function of each individual field, and
2. function call by passing the field parameters.
<script type="text/javascript">
$(document).ready(function() {
$("#storeManager").change(function(){ yourFunction(this) }):
$("#worker").change(function(){ yourFunction(this) }):
$("#someX").change(function(){ yourFunction(this) }):
yourFunction(field)
{
var value = $(field).val();
var inputId=field.id;
$.post('editProject.php', { inputValue: value, id: inputId }, function(data) {
$('#'+inputId+'Row').addClass("success"); // (this looks like: *#storeManagerRow* ) you can change your Row id's accordingly to make your work easier. Eg: for **#storeManager** make this id as **storeManagerRow**
}).fail(function () {
// no data available in this context
$('#'+inputId+'Row').addClass("danger");
$("#ajaxAlert").addClass("alert alert-danger");
});
});
</script>
You just try to post a value. for example type. Which should contain some value for identify the ajax call.
If it is for login, then add type = 'login'. Then check the value of $_POST['type'] and write php according to it
sample.php
if(isset($_POST['type']))
{
if($_POST['type'] == 'login')
{
//your code goes here
}
}
you can use this kind of code :
$("#storeManager, #Manager, #Phone").change(function(){
You could do something like this using :input or a class that they all have
$(":input").on("change", function(){
var text = $(this).val();
var idOfInput = $(this).attr("id");
//your post to php function using the above variables
});
From this you could post the id of the input to your php script using the idOfInput variable which you could then on the php side use a case switch to do a different query depending on which id is sent to the php
Here is a jsfiddle showing how it works

Returning a value to another function

I am new to jQuery. I have created a form where I hide some fields. I have created a function on the click of a button field. Here in this function definition I unhide the hidden fields one being my text field and another a button. I code that I use is:
finishOrder: function() {
document.getElementById("create-pwd").style.display = "block"
document.getElementById("finish-ok").style.display = "block" // this is my another button
// do further processing
},
Now on the click of another button (please see the comment "this is my another button") I call another function like this:
FinishcheckPassword: function() {
var pas = document.getElementById("pos-password")
var user = new db.web.Model("res.users").get_func("read")(this.session.uid, ['password']).pipe(function(result) {
if(pas.value == result.password){
return true
});
},
After the if condition returns true value, I want to the control to be transferred to the first function where I can do further processing. Is it possible, if yes how can this be achieved? Any help will be appreciated.
Sure, something like this:
$('#finish-ok').click(function(){
if(FinishcheckPassword()){
finishOrder();
}
}
Of course, this is probably not exactly the right code for you. The fact that you are assigning all your functions with : rather than = suggests that they are inside of some larger object. Therefore, they'd have to be called like myObject.finishOrder(). But the general approach of what I wrote above will work.
As a couple side notes, you have tagged the question with jQuery and refer to it in your post, but there isn't actually a single line of jQuery in your code.

Trying to clean out form inputs with jQuery so I can add it back into the form

I have a pretty simple HTML form where users can enter in information about a person. Below that form is a button which allows them to 'add more'. When clicked, the 'person' form is copied and appended to the page.
The way I used to do this was to take my HTML file, copy out the relevant section (the part that gets 'added more') and then save it into a variable in the Javascript. This became rather annoying when I had to make changes to the form as I would then have to make the same changes to the Javascript variable.
My new method is to create the variable dynamically in Javascript. When the page loads, I use jQuery to grab out the 'add more' part of the code and cache the HTML into a variable. Then when the 'add more' button is clicked, I append that cached HTML to the page.
The problem is with form inputs. The server-side code autofills the form with the user's data from the database. I want to cache that HTML data with no form inputs...
My current function looks like this:
function getHTML($obj, clean)
{
if (clean)
{
var $html = $obj.clone();
$html.find('input').each(function() { $(this)[0].value = ''; });
}
else
{
var $html = $obj;
}
var html = $html.wrap('<div></div>').parent()[0].innerHTML;
$html.unwrap();
return html;
}
It doesn't work. I'm also unsure if this is the best approach to solving the problem.
Any ideas?
I don't know why this wouldn't work. I can't see how the function is being called, or what is being passed to it.
I guess one thing I'd do differently would be to create a .clone() whether or not you're "cleaning" the inputs. Then you're not wrapping and unwrapping an element that is in the DOM. Just use the if() statement to decide whether or not to clean it.
Something like this:
function getHTML($obj, clean) {
var $clone = $obj.clone();
if (clean) {
$clone.find('input').each(function() { this.value = ''; });
}
return $clone.wrap('<div></div>').parent()[0].innerHTML;
}
Or a little more jQuery and less code:
function getHTML($obj) {
return $obj.clone().find('input').val('').end().wrap('<div/>').parent().html();
}
A little less efficient, but if it only runs once at the page load, then perhaps not a concern.
Or if it is going to be made into a jQuery object eventually anyway, why not just return that?
function getHTML($obj) {
return $obj.clone().find('input').val('').end();
}
Now you've returned a cleaned clone of the original that is ready to be inserted whenever you want.
EDIT:
Can't figure out right now why we can't get a new string.
Here's a function that will return the DOM elements. Beyond that, I'm stumped!
function getHTML($obj, clean) {
var $clone = $obj.clone();
if (clean) {
$clone.find('input').each(function() {
this.value = '';
});
}
return $clone.get(); // Return Array of DOM Elements
}
EDIT: Works now.
I ditched most of the jQuery, and used .setAttribute("value","") instead of this.value.
Give it a try:
function getHTML($obj, clean) {
var clone = $obj[0].cloneNode(true);
var inputs = clone.getElementsByTagName('input');
console.log(inputs);
for(var i = 0, len = inputs.length; i < len; i++) {
inputs[i].setAttribute('value','');
}
return $('<div></div>').append(clone)[0].innerHTML;
}
I would wrap the part of the form that needs to be cloned in a <fieldset>:
<form id="my_form">
<fieldset id="clone_1">
<input name="field_1_1">
<input name="field_2_1">
<input name="field_3_1">
</fieldset>
</form>
Add one more
Then for the jQuery script:
$("#fieldset_clone").click(function(event) {
// Get the number of current clones and set the new count ...
var cloneCount = parseInt($("fieldset[id^=clone_]").size());
var newCloneCount = cloneCount++;
// ... then create new clone based on the first fieldset ...
var newClone = $("#clone_1").clone();
// .. and do the cleanup, make sure it has
// unique IDs and name for server-side parsing
newClone.attr('id', 'clone_' + newCloneCount);
newClone.find("input[id^=clone_]").each(function() {
$(this).val('').attr('name', ($(this).attr('name').substr(0,7)) + newCloneCount);
});
// .. and finally insert it after the last fieldset
newClone.insertAfter("#clone_" + cloneCount);
event.preventDefault();
});
This would not only clone and clean the set of input fields, but it would also set new ID's and names so once the form is posted, their values would not be overwritten by the last set.
Also, in case you want to add the option of removing sets as well (one might add too many by mistake, or whatever other reason), having them wrapped in a <fieldset> that has an unique ID will help in accessing it and doing a .remove() on it.
Hope this helps.

Categories