Returning ajax response from django - javascript

I have exhausted my brain trying to get something simple to work. I want to change the behavior of a form from post reload to ajax with django. I just can't get it to work.
The form is something like:
<form id="form1" action="/myurl/" method="post" onsubmit="doexchange">
<input id="input1" type="hidden" name="serializedData" value=""/>
<button id="button1" type="submit">render<button/>
</form>
Using jquery, I have something like:
function doexchange(){
var dataBuffer = new Object();
dataBuffer = myCollecter(dataBuffer);
$("#input1").attr("value", JSON.stringify(dataBuffer));
$.get($("#form1").attr("action"),
{serializedData: $("#input1").attr("value")},
function(data){
alert('yes' + data);
});
return false;
}
Now the return false is to prevent the original form from doing a POST of its own.
On the server side, I have something really simple like:
def handler(request, data):
return HttpResponse('{}', 'application/json')
The client successfully sends the data to the server through an ajax request. The server also returns the {} empty bracket to the client. But instead of the callback function getting called and seeing and alert, the whole page reloads and I see only {} on a new page.
As I said I have tried so many different things, but I think I am missing something elephant big... Any ideas? Oh, and I am using the latest Mozilla firefox, but I don't think this is a browser specific issue...

I don't think a solution needs to be very convoluted to achieve the outcome you're going for. Consider something on the lines of:
A page that looks like:
<a class="btn" onclick="doexchange">render</a>
An JavaScript that looks like the following:
function doexchange(){
var dataBuffer = myCollecter(dataBuffer);
$.get('/myurl/', {serializedData: JSON.stringify(dataBuffer)}, function(data) {
alert('yes' + data);
});
}

Try binding to the form submit in your javascript.
$('#form1').bind('submit', function( e ){
e.preventDefault();
var form=$(this),
input=form.find('input[name="serializedData"]');
$.ajax({
//
});

Related

How send string parameter using Post Method from the view to the controller ASP.NET [duplicate]

Here is a line of code in my Controller class:
return JavaScript(String.Format("window.top.location.href='{0}';", Url.Action("MyAction", "MyController")))
Is there a way to make it use the verb=post version of MyAction?
You can't use POST by simply navigating to a different URL. (Which is what you'd do by changing location.href.)
Using POST only makes sense when submitting some data. It's not clear from your code what data would actually be POSTed.
If you really want to initiate a POST via javascript try using it to submit a form.
I came across the same problem myself and solved it using a data- attribute and some jQuery. The benefit of doing it this way is that you still get the correct URL when you hover over the link, even though it does a POST. Note that the Html.BeginForm contains the default action in case the user hits the enter key.
HTML (ASP.NET MVC3 Razor)
#using (Html.BeginForm("Quick", "Search"))
{
<input type="text" name="SearchText" />
Search
Advanced
}
jQuery
$("a[data-form-method='post']").click(function (event) {
event.preventDefault();
var element = $(this);
var action = element.attr("href");
element.closest("form").each(function () {
var form = $(this);
form.attr("action", action);
form.submit();
});
});
Continuing off of Matt Lacey's answer, your action could return a bit of Javascript that does this:
Use jquery to add a new form to the DOM
Use jquery to submit the newly added form
Something like this: (untested code)
var urlHelper = new UrlHelper(...);
var redirectUrl = urlHelper.Action("MyAction", "MyController");
var redirectScript = String.Format(#"
var formTag = $('<form action=""{0}"" method=""post"" id=""redirectForm""></form>');
$(body).append(formTag);
formTag.submit();"
, redirectUrl
);
return JavaScript(redirectScript);

Failing to pass data from client (JS) to server (Flask) with Ajax

First time ever using jQuery to pass a dictionary filled through a JS script to my server written in Python (Flask) when the user hits a submit button (I read somewhere that AJAX was the way to go).
Something must be broken since in the server function described below, request.get_data() or request.form are None. If any seasoned programmer could give recommendation on how to set up a jQuery request, it would be much appreciated.
In Python, I have the following:
#app.route('/submit',methods=['POST'])
def submit():
info = request.form['info']
action = request.form['action']
...
To handle the dictionary info. On my html file, I load AJAX through:
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
</head>
Define my "submit" button as followed:
<button class="btn" onclick="send(event,'s')" id="SUBMIT">Submit</button>
And handle the action through the script:
<script>
var dict = [];
function send(event,action) {
$.post('/submit', {
info: dict,
action: action
}).done(function() {
}).fail(function() {
});
}
...
</script>
Convert request.form to dictionary and print it you can able get the values
print(request.form.to_dict())

AJAX not posting values with $(form).serialize()

I have a form that I'm trying to submit via AJAX. The easiest way for me to pass the data would be using $("#myForm").serialize(), however, when doing so, the page to which I'm posting to doesn't receive the data.
Here's my form:
<form id="myForm">
<input name="field" id="field">
<button id="submitBtn" type="button">
</form>
And this is my function:
$("#submitBtn").click(function(){
alert($("#myForm").serialize()) //For testing – does alert "field=value"
var post = $.post("actions.php", $("#myForm").serialize());
post.done(function(d){alert(d)}); //Only alerts [PHPSESSID]
var post = $.post("actions.php", {field:"fieldVal"});
post.done(function(d){alert(d)}); //Alerts [PHPSESSID] and ['field']
});
This is my whole actions.php file:
<?php
print_r($_REQUEST);
exit();
Why is passing the values as JSON working but .serialize() isn't??
Looks like I just had to pass the serialized form as a variable instead of serializing it inside the $.post() function. As so:
var postData = $("#myForm").serialize()
var post = $.post("actions.php", postData);
post.done(function(d){alert(d)});
Not sure why it works when established outside and not inside the function, maybe a conflict issue. Thanks to everyone anyway
Use serializeArray() instead: https://api.jquery.com/serializeArray/

Using JQuery to get JSON from Flask is returning null sometimes

So I am developing on oracle Linux Server release 6.6 and I recently switched over to Apache 2.4 for my web server. I am developing a Flask web service so I was using Flask's local WSGI server to do all my debugging.
In the application, i have a form and when you click the submit button, it does a JQuery $.getJSON() call to my Flask backend. Then in the backend, I return JSON data and alert the user of the data. The problem is that most of the the time it returns null and doesn't return my data. Other times it returns my data and everything is fine. This worked perfectly when I was using the local WSGI server. It was once I migrated to Apache when this error started happening so I believe the problem is from Apache.
Also I print out my json data before returning so I know for sure it is not returning null data but I still get this error.
My HTML/JavaScript code
<div id="restore_submit" class="restore_submit" style="display:none;">
<form onsubmit="restoreDB()">
Type the database ID and Snapshot ID of the database you want to restore
<br><br>
RDS ID:<br>
<input type="text" id="DbName2" name="DbName">
<br>
Snapshot ID:<br>
<input type="text" id="snapshot_id" name="snapshot_id">
<br><br>
<input type="submit" value="Restore">
</form>
</div>
function restoreDB() {
var DbName = document.getElementById('DbName2').value;
var snapshot_ID = document.getElementById('snapshot_id').value;
var check = confirm('Are you sure you want to restore ' + DbName);
if(check){
$.getJSON('/restore_rds', {
Dbname: DbName,
snapshot_id: snapshot_ID
}, function(data) {
if(data){
if(data && data.error){
alert(DbName + " is being restored using this snapshot_id " + snapshot_ID);
}
else{
alert(data.error);
}
}
else{
alert("returned null");
alert(data);
}
});
}
}
My Python code
#This is for the restore script
#app.route('/restore_rds')
##login_required
def restore_rds():
DbName = request.args.get('Dbname')
snapshot_id = request.args.get('snapshot_id')
error = rds_action.restore_db(DbName, snapshot_id, rds)
if error:
error = str(error)
else:
error = 'empty'
print error
print jsonify(error = error)
return jsonify(error = error)
EDIT:
So i fixed the issue after like a week of digging. Looks like my requests were getting cancelled before returning back to the webpage. So what i did was a e.preventDefault() in my JavaScript function.
so in my html i change it to
<form onsubmit="restoreDB(event)">
and in my JavaScript i added this
function restoreDB(e) {
e.preventDefault();
Now the webpage doesn't reload and it has enough time to wait for a response. Probably not the best fix but I am just happy I fixed it. If anyone recommends anything better, that will be great
So i fixed the issue after like a week of digging. Looks like my requests were getting cancelled before returning back to the webpage. So what i did was a e.preventDefault() in my JavaScript function.
so in my html i change it to
<form onsubmit="restoreDB(event)">
and in my JavaScript i added this
function restoreDB(e) {
e.preventDefault();
Now the webpage doesn't reload and it has enough time to wait for a response. Probably not the best fix but I am just happy I fixed it. If anyone recommends anything better, that will be great

How to pass only a number in a form URL

I have the code below:
<form action="/files/" method="get">
<h3>GET /files/{fileId}</h3>
<label>File ID: </label><input type="text" name="fileID" />
<input type="submit">
<br><br>
</form>
this responds with a URL: /files/?fileID=88
However, I want the URL to look like: /files/88
Does anyone know if this is possible and if so could you point me in the right direction to do so?
It can be done from the browser, although it's not clean as you would have to use Javascript to change the form's action attribute.
// get hold of the form element (it needs an id)
var form = document.getElementById('form-id'),
// get hold of the input tag (it also needs an id)
fileIdInput = document.getElementById('file-id'),
// get the action attribute, e.g. '/files/'
baseAction = form.getAttribute('action');
// add an even listener to listen for the form being submitted
form.addEventListener('submit', function() {
// get the value from the file id input
var fileId = fileIdInput.value;
// when it submits, change the action e.g. '/files/' + 88
form.setAttribute('action', baseAction + fileId);
// return true so that the form submits
return true;
});
It's not really maintainable code and server side solutions to this sort of problem have been around for a while.
If you're using Express and you already have a handler for the /files/:id endpoint, then I would suggest using AJAX to make the request instead of a standard GET form.
For example using the fetch api. Fetch is a new interface for doing AJAX requests, however it's not yet implemented in all browsers. So you might want to include a polyfill script.
// the first argument for fetch is the URL
fetch('/files/' + id)
// fetch returns a promise that we can call `.then()` on.
// our function will be called when the ajax request is done
.then(function(data) {
console.log(data);
})

Categories

Resources