Getting an Ajax error "xxx" is not defined - javascript

I have looked through the numerous Stackoverflow questions, various tutorials and youtube vids and so far none (that I have found) address this issue for me...
I have a form to load a single file. It submits this fine without ajax.
<form asp-action="FileIndexView"
asp-controller="SuburbsAndPostcodesAdmin"
method="post"
enctype="multipart/form-data">
<div class="form-horizontal">
<div class="form-group">
<label class="col-md-4 control-label">Select the Suburbs and Postcodes latest CSV File:</label>
<input type="file"
name="CSVFile"
id="txtFileUpload"
class="col-md-8 control-label" />
</div>
<div class="form-group">
<input type="submit"
name="Submit"
value="Submit"
class="col-md-1 btn btn-primary"
disabled="disabled"
id="SubmitFile" />
</div>
</div>
I have an Ajax POST method. its called when you click the submit button. All good.
Here is the code.
$('#SubmitFile').click(function (e) {
e.preventDefault(); // <------------------ stop default behaviour of button
//var fileUpload = input.files[0];
var url = "/SuburbsAndPostcodesAdmin/test";
var connId = $.connection.hub.id;
var fd = new FormData();
fd.append('File', input.files[0]);
fd.append('connId', connId);
$.ajax({
type: "POST",
url: url,
data: fd,
processData: false,
contentType: false,
});
When I step through this it errors on the:
"fd.append('File', input.files[0]);"
line with the following error in the console.
ReferenceError: input is not defined
<anonymous>
FileIndexView:127
n.event.dispatch()
jquery.min.js:3
n.event.add/r.handle()
jquery.min.js:3
EventLoop.prototype.enter()
...
Why is this erroring on this line?
How should it read so it is defined?
What should the file name be and why? (does this need to address back to the form)

The problem is with input.files[0] because here input is undefined.
Instead of
fd.append('File', input.files[0]); //here input is not defined
Try
fd.append('File', $("#txtFileUpload")[0].files[0]);

This "Formdata" object seems suspect. jQuery likes simple objects, i.e.
$.ajax({
type: "POST",
url: url,
data: {input: "A", somethingelse: 2, somethingmore: true},
processData: false,
contentType: false,
});
In your browser, use the developer options and go to the Network tab to see exactly what's being pushed to the server in the POST operation. I'll bet it doesn't fit what your server method is expecting, hence the exception.
EDIT
Didn't notice until now that you're trying to do file upload. It is well-documented as a pain-in-the-butt via AJAX. I've had success with a plug-in called DropZone. http://www.dropzonejs.com/

Related

Append File to Form before Submit HTML and PHP

I have an application that I am building. The app creates a json file, then a jar file is uploaded and the json file is inserted into the jar, and the new jar is returned.
I have created a basic HTML form and PHP file that currently works, but the user must select both the jar and the json file to upload. I need to modify this now so that the user chooses the zip file, but the form would select the JSON from the JS.
THE HTML:
<form id="jar-form">
<div class="mb-3">
<label for="test-jar-upload" class="form-label">Select Jar File Files:</label>
<input type="file" id="test-jar-upload" name="jar" accept=".jar" class="form-control">
</div>
<div class="mb-3">
<button type="button" class="btn btn-primary" ng-click="export.exTest()" name="upload_file">Submit</button>
</div>
THE JS:
$scope.export.exTest = function(){
console.log('New Manual Submit');
let formData = new FormData();
let tFile = new Blob([JSON.stringify($scope.export.file)], {type: 'application/json'});
formData.append('jar',document.getElementById('test-jar-upload').files[0]);
formData.append('desc',tFile);
$scope.newData = formData;
$.ajax({
url: './assets/api/test.php',
data: formData,
type: "POST",
contentType: false,
processData: false
})
}
The AJAX call was taken from another answer, but doesn't successfully open the test.php file. If I change the path, I do get a 404 error returned.

Adapting a jQuery function to send files

A function on our website fires for all of our forms. It uses jquery's serializearray method and works great.
I need to add a form with a file input, and serializearray doesn't handle files. I'm not new to Python and Django, but I am new to Jquery. And I'm having trouble adapting the function.
Since the formData class handles files, I thought I could change "data: serializedform" to "data: new formData(form)".
When I did that, Chrome's console displayed "Uncaught TypeError: Illegal invocation". Firefox's console displayed "Uncaught TypeError: 'append' called on an object that does not implement interface FormData."
Do I need to convert the FormData object to another type?
A snippet follows:
uploadfile.html:
function postAndLoad(form, url, panelDivID, btnName){
var serializedForm = $(form).serializeArray();
return request = $.ajax({
url: url,
dataType : 'html',
cache: 'false',
type : 'POST',
data: serializedForm, //data: new FormData(form) produces an error.
success: function (data) {
console.log("Completed POST");
error: function(data) {
console.log('There was a problem in postAndLoad()');
console.log(data);
}
});
return false;
};
…
<form enctype="multipart/form-data" onsubmit="postAndLoad(this, '{% url 'UploadFile' %}', 'panel_upload'); return false;" method='post'>
{% csrf_token %}
{{ form | crispy}}
<div class="row w-100">
<input class="btn" type='submit' name="form1btn" value="button" />
</div>
</form>
forms.py:
class UploadFile(forms.Form):
uploadFile = forms.FileField(label="Select file to upload")
sampleText = forms.CharField(label="Enter some text")

POST convert to GET when I want to fetch formData?

I want to send an image to server
my code works perfect in Chrome Version 77.0.3865.90
BUT
in Mozilla Firefox (version 69.0.1) POST method changes to GET with this error
Form contains a file input, but is missing method=POST and enctype=multipart/form-data on the form. The file will not be sent.
Request URL: http://localhost:3000/...
Request method: GET
Status code: 200
<form class="form-horizontal" id="form" >
<div class="col">
<label for="images" class="control-label">image</label>
<input type="file" class="form-control" name="images" id="images" >
</div>
<div class="form-group row">
<div class="col">
<button type="submit" class="btn btn-danger">Send</button>
</div>
</div>
</form>
<script>
document.getElementById('form').addEventListener('submit' , async function(event) {
let images = document.querySelector('input[name="images"]');
let formData = new FormData();
formData.append('images' , images.files[0] );
try {
const response = await fetch('http://exampleurl.com/profile', {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-Token': "<%= req.csrfToken() %>",
},
body: formData,
credentials: 'same-origin'
});
} catch (error) {
console.error(error);
}
})
</script>
I can't use method ="POST" and enctype= "multipart/form-data" in the form because csrf tokens can't implement in forms with multipart/form-data enctype
I suspect your form might be submitting twice.
1) AJAX event handler
2) The submit button in the form actually posting the form through html
Try adding the event handler to the form itself, rather than the submit button.
There you can prevent the form from doing what it wants to do so only your AJAX request will go through.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit_event

upload image with reactjs and ajax

I'm trying to upload an image through a form to a url/api.
I call handleImgUpload() method on submitting the form.
The problem is that the request sent is empty.
I think that new FormData(this) does not work with react or something.
There's another function that sets the image path.
handleImgUpload(e){
e.preventDefault();
$.ajax({
url: "my url goes here", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
contentType: false, // The content type used when sending data to the server.
cache: false, // To unable request pages to be cached
processData:false, // To send DOMDocument or non processed data file it is set to false
success: function(data){ // A function to be called if request succeeds
console.log(new FormData(this));
}
});
}
here is the form:
<form id="uploadimage" onSubmit={this.handleImgUpload} action="" method="post" encType="multipart/form-data">
<Row id="image_preview" className="row">
<img id="previewing" src={this.state.imgPath}/>
</Row>
<div id="selectImage">
<label>Select Your Image</label><br/>
<input type="file" name="image" id="file" onChange={this.handleImgChange} required />
<Button type="submit" className="btn btn-primary" id="upload">Upload</Button>
</div>
</form>
this is going to be the React component, not the form, which can be found in event.target
handleImgUpload(e) {
e.preventDefault()
let formData = new FormData(e.target)
for (let [key, val] of d.entries()) {
console.log(key, val) <-- should log the correct form data
}
// ajax stuff
}

HTML5 FormData sending empty objects via JQuery

I have a basic script that is as follows:
$(".submit").click(function(){
var fd = new FormData();
fd.append('username', 'Bob');
$.ajax({
url: '/signup',
type: 'post',
data: fd,
processData: false,
contentType: false,
success: function (data) {
console.log("Success: ", data);
}
});
});
When the request hits my server, I receive a req.body of {} (empty) and there is nothing in req that points to data being sent. Whats going on here? How can I send data with FormData?
I wanted to test getting basic preset data from FormData and was unsuccessful. The values console logged in Chrome show an empty formData object, with only its constructor and the available 'append' method.
I am using jQuery v 2.1.4 and HTML5 and have confirmed that window.FormData is a valid object in Google Chrome.
My goal is to have a form that a user can enter an email, password, avatar, and a profile background image with the following form:
<form id="msform" enctype="multipart/form-data" name="msform">
<!-- Progress Bar -->
<ul id="progressbar">
<li class="active">Basic Information</li>
<li>Profile Customization</li>
</ul>
<!-- Step One -->
<fieldset>
<h2 class="title">Basic Information</h2>
<input type="text" name="username" placeholder="Username" />
<input type="text" name="password" placeholder="Password" />
Avatar Image <input type='file' id='avatarImage' accept="image/*" name='avatarImage'>
<input type="button" name="next" class="next action-button" value="Next" />
</fieldset>
<!-- Step Two -->
<fieldset>
<h2 class="title">Profile Customization</h2>
<select id="dropdown" name="profileColor">
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="yellow">Yellow</option>
</select>
Background Photo <input type='file' id='bgPhoto' accept="image/*" name='bgPhoto'> </div>
<input type="button" name="previous" class="previous action-button" value="Previous" />
<input type="submit" name="submit" class="submit action-button" value="Submit" />
</fieldset>
</form>
Whats going on with FormData, it seems like a valid object, but I'm unable to append anything to it. I've looked, and it appears that others have seen an empty object in their console, but the data 'automagically(?)' appears on their server? My first code block is basically a copy for the docs and I'm having trouble with it. Would and CORS issues or CDN errors be the case? Something maybe not able to access as it should? No errors print in the log, only a blank object on my post request.
Thanks for the help!
If you are using Express as the backend, body-parser does not handle multipart/form-data, and you are referred to using multiparty instead. You can integrate Express with multiparty like so :
var express = require('express');
var multiparty = require('multiparty');
var app = express();
var data = new multiparty.Form();
app.post('/signup', function(req, res) {
data.parse(req, function(err, fields, files) {
if(err) throw err;
Object.keys(fields).forEach(function(name) {
console.log('got field named : ' + name + ', value : ' + fields[name]);
});
Object.keys(files).forEach(function(name) {
console.log('got file named : ' + name);
});
});
});
Do include event.preventDefault() in your click event handler
$(".submit").click(function(e){
e.preventDefault();
var fd = new FormData();
fd.append('username', 'Bob');
...
});
You aren't preventing the default form submit event and neither are you catching a submit by keyboard if user hits enter.
Try:
$("#msform").submit(function(e){
e.preventDefault();
var fd = new FormData();
fd.append('username', 'Bob');
$.ajax({
url: '/signup',
type: 'post',
data: fd,
processData: false,
contentType: false,
success: function (data) {
console.log("Success: ", data);
}
});
});
If you aren't sending files I would suggest using the simpler approach of removing the processData and contentType options and using $(this).serialize() for the data value

Categories

Resources