Get files from form without querying for input field - javascript

I'm trying to upload files using AJAX. However, I'm having issues grabbing the files from my form. I want to gather all the
<input type="file">
fields that are nested within the form, without using their specific ids. So, not like this:
console.log($( "#i_dont_want_to_query_for_this_id" )[0].files);
//FileList {0: File, length: 1}
I feel there must a be way to get them from the form element itself:
<form class="part-form">
...
<input type="file" id="i_dont_want_to_query_for_this_id">
</form>
This is how I handle the submit:
$( ".part-form" ).each(function () {
var $me = $( this );
$me.on('submit', function (event) {
event.preventDefault();
var formElement = $me[0];
var fd = new FormData(formElement);
...
}
I guess this can also be achieved using classes and each() on these, but I feel there must be a way to grab all files in a submitted form by simply using the data in the form itself, I just cannot find it.
Any help is greatly appreciated!

You can use an attribute selector like $("file[type=input]") to get all the file inputs. Here's a fiddle.
$(document).ready(function() {
$( ".part-form" ).each(function () {
var $me = $( this );
$me.on('submit', function (event) {
event.preventDefault();
var $resultDiv = $("#result-div");
$me.find("input[type=file]").each(function(index, fileInput) {
for(var i = 0; i < fileInput.files.length; i++) {
// Do whatever you really want to do with the file.
var $span = $("<span />");
$span.text(fileInput.files[i].name);
$resultDiv.append($span);
}
})
});
});
})

Use can use selector $("input[type='file']")
$(document).on('change', 'input[type="file"]', function(){
console.log($(this)[0].files)
alert($(this)[0].files)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="part-form">
...
<input type="file" id="i_dont_want_to_query_for_this_id">
<input type="file" id="i_dont_want_to_query_for_this_id2">
</form>

Related

Uncaught ReferenceError: (function) is not defined at HTMLButtonElement.onclick

I have a search form where I'm trying to have it output the results at the bottom of the page without reloading.
<form action='' method='post'>
<div id="search-form">
<input type="text" name="search" class="search-field" id="search" value="" />
<div class="submit-container">
<button type="button" value="" class="submit" id="searchbutton" onclick="searchoutput()" /></button>
</div>
</form>
<br><br>
<p>Type First Name</p>
I want the search results to show below when the button is clicked, using Ajax call to another script. I keep getting an error: "Uncaught ReferenceError: searchoutput is not defined at HTMLButtonElement.onclick
Here is my javascript (using jquery):
$( document ).ready(function() {
function searchoutput() {
if($(".search-field").val().length > 5) { //only shows results when more than 5 characters have been entered
var search = $(".search-field").val();
var update = $(".result");
var goal = 0;
$.get("query-include.php" , {search: search, goal: goal})
.done(function( data ) {
update.empty();
update.append(data);
$(this).remove();
});
};
}
$( ".search-field" ).keydown(function() {
var update =$(".results");
update.empty();
});
});
I have checked other posts and spent a long time trying to get the solution on my own. The odd thing is if I add an event listener for "keyup" in order to run the same function searchoutput as the user types:
var searchfield = document.getElementById("search");
searchfield.addEventListener("keyup", searchoutput);
Then I don't get the ReferenceError and the script runs fine.. I only get the function issue on button click.
It's a scoping issue - searchOutput is defined within the scope of the $(document).ready() function. What you could try is to declare a var for searchOutput before that code, then assign it to the function like this:
var searchOutput;
$( document ).ready(function() {
searchOutput = function () {
if($(".search-field").val().length > 5) {
//etc.
I add an eventListener in the place of searchoutput();
$( document ).ready(function() {
$('.submit').addEventListener('click', function(){
if($(".search-field").val().length > 5) { //only shows results when more than 5 characters have been entered
var search = $(".search-field").val();
var update = $(".result");
var goal = 0;
$.get("query-include.php" , {search: search, goal: goal})
.done(function( data ) {
update.empty();
update.append(data);
$(this).remove();
});
}
});
$( ".search-field" ).keydown(function() {
var update =$(".results");
update.empty();
});
});
In my case,
I was using modular code in my JS (i.e. import and export statements) so when I tried to use onclick, it wasn't calling my submit function. When I simply removed the import statement from my JS code and replaced dependent code with some default values, onclick called my function. Then I tried the addEventListener with import/export and finally it worked for me.

How to get updated json file for new form inputs using javascript or jquery?

Can I know that how to get updated json file for the newly entered form input fields. As of now, I can able to save my form input fields into my json file, but if I enter any new input value then if I hit my Save button, then this newly entered values are not storing into my json file(I can still see my old key/values). Please let me know where I'm doing wrong and how to do this ?
html:
<form id="imagesId">
<input type="hidden" value="/images/Image1.png" name="Image1">
<input type="hidden" value="/images/Image2.png" name="Image2" >
<input type="hidden" value="/images/Image3.png" name="Image3">
<input type="hidden" value="/images/Image4.png" name="Image4">
<input type="hidden" value="/images/Image5.png" name="Image5">
<input type="button" id="submitButton" value="Save">
</form>
json:
[{"name":"Image1","value":"/images/Image1.png"},{"name":"Image2","value":"/images/Image2.png"},{"name":"Image3","value":"/images/Image3.png"},{"name":"Image4","value":"/images/Image4.png"},{"name":"Image5","value":"/images/Image5.png"}]
jQuery:
$("#submitButton").on('click', function(e) {
var jsonToSave = $("#imagesId").serializeArray();
var jsonData = JSON.stringify( jsonToSave );
var $downloadAnchor = $("<a/>", {
href: 'data:text/json;charset=UTF-8,' + jsonData,
download: "Image.json"
});
$downloadAnchor.text("Click here to download JSON");
$("#imagesId").append($downloadAnchor);
e.preventDefault();
return false;
});
The problem was that $downloadAnchor holds a reference to a DOM element (a jQuery object = a DOM element wrapped in $()). When you append that element to the DOM, $downloadAnchor still refers to that same object. It doesn't magically duplicate it when you want to insert it again into the DOM, unless you .clone() it.
What you need do is to check if that anchor (thru it's ID/class) is already in the DOM, if yes, just update it's href with the new data as below.
$("#submitButton").on('click', function(e) {
e.preventDefault();
var $form = $("#imagesId");
var jsonToSave = $form.serializeArray();
var jsonData = JSON.stringify(jsonToSave);
var $downloadLink = $("#download");
if ( $downloadLink.length ) {
$downloadLink.attr({
'href': 'data:text/json;charset=UTF-8,' + jsonData
});
} else {
$form.append(
$("<a/>", {
'href': 'data:text/json;charset=UTF-8,' + jsonData,
'download': "Image.json",
'id': 'download',
'text': "Click here to download JSON"
})
);
}
});
A demo for the above.
Edit: To be able to append each file uploaded as an input (with a unique name + value of the uploaded file) to the form, you need to do 2 things.
Bind a change handler to the file input, if a file is uploaded (meaning, not just a click and cancel on the file upload dialog), append it to the form as an input with the file as the value (after whatever find/replace you want to do).
The click handler on the $("#submitButton") would only take in all the inputs, serialize them and then create/modify the download anchor link as in my first code attempt.
Here is a demo for the above (the edit part).
var $form = $("#imagesId"); //The form
var len = $form.find('input[type="hidden"]').length; //Number of files in the form
$form.on("change", ":file", function() {
var file = $(this).val() || false;
if (file) {
//Do your replace etc. here
//.replace(/C:\\fakepath\\/i, '');
len++;
$form.append('<input type="hidden" value="' +file+ '" name="image' +len+ '" />');
}
});
$("#submitButton").on('click', function(e) {
e.preventDefault();
var jsonToSave = $form.serializeArray();
var jsonData = JSON.stringify(jsonToSave, null, 4);
var $downloadLink = $("#download");
alert (jsonData);
//Other code goes here such as create anchor, append/modify etc.
});
Link to the demo for the edits above.
You Can use push like this
oldJson.push(newJSon);

append textbox value to form action url

I have a search form and I need to pass the keyword into the URL. I know using the GET method is much easier but for some reason when I use it nothing happens. It doesn't move to the action URL. But the POST method works for me.
So what I need to do is when a user types in a keyword it automatically needs to be appended to the form action URL so I can grab it when the user submits the form. I need to pass it to the URL.
Below is what I have done so far:
<script>
$('#input-search').on('change', function (event) {
var myVal = $(this).val();
$('form').attr('action', function(i, value) {
return value + "&search=" + myVal;
});
});
</script>
<form action="http://loclahost/index.php?route=catering/search" method="POST">
<input type="text" id="input-search" name="keyword" />
<input type="submit" name="search" value="search"/>
</form>
It's better to use keyup instead of change and also grab default attribute action and use it
$val = $('form').attr('action');
$('#input-search').on('keyup', function (event) {
var myVal = $val
+ "&search=" + $(this).val();
$('form').attr('action', myVal);
});
var formAction = $('form').attr('action');
$('#input-search').on('change', function (event) {
$('form').attr('action', formAction+ "&search=" + this.value);
});

Sending one of multiple forms with jQuery

I'm doing a thing like the follow-:
$.each(data2, function(key2, val2) {
$('#posts').append('<div class="send_comment" align="right">');
$('#posts').append('<input type="hidden" class="com_post_id" value="'+i+'"><br /\>');
$('#posts').append('Author: <input type="text" class="com_author"><br /\>');
$('#posts').append('Img: <input type="text" class="com_img"><br /\>');
$('#posts').append('Text: <input type="text" class="com_text"><br /\>');
$('#posts').append('<button class="new_comment">Send</button>');
$('#posts').append('</div>');
});
How can I send these fields with $.post? With $(this), I can get the clicked element, but then?
Since it is dynamically injected element,you should bind the functionality using jQuery on
$(function(){
$(".send_comment").on("click",".new_comment",function(e){
e.preventDefault();
var item=$(this);
var postId=item.parent().find(".com_post_id");
var author=item.parent().find(".com_author");
var msg=item.parent().find(".com_text");
$.post("yourPage.php", { id : postId, author:author ,msg:msg },function(result){
//do whatever with result
alert(result);
});
});
});
http://api.jquery.com/on/
jQuery on will work on current and future elements.
data = $(this).closest('form').serialize()
I always found the modal form example from jqueryui's site as a good example of how to send data from a form: http://jqueryui.com/demos/dialog/#modal-form
Essentially give your fields ids, then:
var author = $( "#author" ),
image = $( "#image" ),
text = $( "#text" ),
allFields = $( [] ).add( author ).add( image ).add( text );
Then use post:
$.post("your_url_that_processes_data",allFields, function(data){
// do something with data
});
If you have multiple forms that vary slightly there are plenty of ways to go about that. I'd recommend either changing the action URL OR grabbing an "id" from some DOM element some how. Maybe you can change the form id to something like : "form-".id in your script then read it before you submit.
I can potentially try to help with a more detailed use case?

Javascript: convert form to static

I'm working on an online application that uses a lot of forms like this:
<form action="..." id=".." method="post">
<label for="i0">something</label>
<input type="text" id="i0" .... />
<label for="i1">something</label>
<select id="i1"..> <option>a</option> <option>b</option> </select>
.....
<input type="submit" ...>
</form>
I use some JQuery plugins to serialize and deserialize data so I can save all data to database in one JQuery line and fill form with another instruction. My problem now is that in some context I need to show only the data, not editable form.
The question is: is there any JQuery plugin or some code that converts a <form> into a textual data preserving the form structure?
Note: a simple option is to show the form and disable all form fields, but this is not a good option if the user wants to print the data.
var html = '';
var $form = $('#form');
$form.find('label').each(function() {
var $label = $(this);
html += '<p>' + $label.text() + ': ' + $('#' + $label.attr('for')).val() + '</p>';
})
$form.replaceWith('<div>' + html + '</div>');
If you're doing that on submit, you could use jQuery form plugin and the formSerialize() function or beforeSubmit() callback.
var queryString = $('#myFormId').formSerialize();
or
$("#myFormId").ajaxForm({
beforeSubmit: function(arr, $form, options) {
// The array of form data takes the following form:
// [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
// return false to cancel submit
return true;
},
success: function() {
//success (your actions here)
}
});
(Use $form).
Here is non-jquery crossbrowser workaround:
var getOuterHtml = function(node){
var wrapper = document.createElement('div');
document.body.appendChild(wrapper);
var clone = node.cloneNode(true);
wrapper.appendChild(clone);
var result = wrapper.innerHTML;
document.body.removeChild(wrapper);
return result;
};
Here is working example.
P.S. By the way in ie you can use node.outerHTML.
EDIT: little bit modified example so that it wouldn't remove original form
I would propose a little different, but seems more appopriate solution - jQuery Templates
You keep you common code as template, depending on actual needs, you wrap those templates either to <forms> or <div>. This is more clear and easy to support.

Categories