If it possible to submit form form Ajax with Flask? - javascript

I have an application using Flask and JavaScript. I have a function in JavaScript when the user click the button and the data are send to Flask. This function create a marker on the map and set the data from function in Flask to marker popup. I use form in popup because I want to get the name form this popup. I want to submit this form from popup and get the name but when I do it print("Name :",nazwa_event) it return me None. I create a input with hidden tag in html and I set input value to the name from form $('input[id=nameOF]').val(nazwa.value);. It is possible to do that or I can't submit form from Ajax ?
HTML code:
<input type="text" id="name_of_event" class="form-control mb-2" name="name_event" placeholder="Nazwa wydarzenia">
<input name="nameOfEvent" type="hidden" value="" id="nameOF">
<br>
<button id="search-button_event" type='submit' name="event_form" class="btn btn-primary">Szukaj</button>
JS code:
$("#search-button_event").click(function () { // make ajax request on btn click
$.ajax({
type: "POST",
url: "/mapaa", // url to the function
data: {
nameevent: $("#name_of_event").val(), // value of the form
},
success: function (response) {
nazwa = (response['name']);
let marker_event = L.marker(array[0]).bindPopup()
marker_event._popup.setContent(
'<form method="POST" action="/mapaa"'+
'<p>Nazwa: '+nazwa+'</p>'+
'<button type="submit" id="form-submit" name="form-submit" class="btn btn-warning btn-block">Dołącz do wydarzenia</button>'+
'</form>')
marker_event.addTo(mymap)
polyline_event = L.polyline(array,{color: 'red'})
marker_event.on('click',function(){
polyline_event.addTo(mymap)
})
marker_event.getPopup().on('remove', function() {
polyline_event.remove()
})
$('input[id=nameOF]').val(nazwa.value);
mymap.setView(array[0],14)
},
});
});
FLASK code:
#app.route('/mapaa',methods=['GET','POST'])
def mapa():
user_id = current_user.get_id()
slownik = {}
if request.method == "POST":
if request.is_json:
req = request.get_json()
nazwa = req['name']
data_pocz = req['data_start']
data_kon = req['data_end']
typ = req['type']
dlugosc = req['len_route']
coord = req['coordinates']
event_database = Event(date_start=data_pocz, date_end=data_kon, type=typ, name=nazwa, len_route=dlugosc,admin=user_id, route=coord)
db.session.add(event_database)
db.session.commit()
print('Dodano wydarzenie')
if 'form-submit' in request.form:
nazwa_event = request.form.get('nameOfEvent')
print("Id ev:",nazwa_event)
else:
name_ev = request.form.get('nameevent')
all_data = Event.query.filter_by(name=name_ev).all()
for row in all_data:
date_st_string = str(row.date_start)
date_end_string = str(row.date_end)
slownik = {'id':row.id,'date_st':date_st_string,'date_end':date_end_string,'type':row.type,'name':row.name,'len_route':row.len_route,'route':row.route}
return jsonify(slownik)
return render_template('mapaa.html', title='Mapa')

I can't test it but as for me you have hidden <input> in wrong place - it has to be inside form inside popup. And you can set value directly in HTML without using jQuery
marker_event._popup.setContent(
'<form method="POST" action="/mapaa"' +
'<input name="nameOfEvent" type="hidden" value="' + nazwa.value + '" id="nameOF">' +
'<p>Nazwa: ' + nazwa + '</p>' +
'<button type="submit" id="form-submit" name="form-submit" class="btn btn-warning btn-block">Dołącz do wydarzenia</button>' +
'</form>'
)
I'm not sure if it should be nazwa.value or only nazwa like in '<p>Nazwa: ' + nazwa + '</p>'

Related

Loop through JSON name/value pair string to populate form input field values for edit mode

I'm trying loop through a json name/value pair string and populate generated input field values. Wanting this logic for edit mode. I feel I'm almost there but I'm only populating two fields. Oh, The input fields are in group of two (Title url and url itself)
// * Edit mode * - Populates input fields with current stored urls
let wrapper = '#wrapper';
let urlJson = '{\"Hello World\": \"www.google.com\"\r\n}'
if (urlJson) {
var result = $.parseJSON(urlJson);
var urlTitle = $('[name="url_title[]"]');
var url = $('[name="url[]"]');
$.each(result, function(key, value) {
console.log('key: ' + key + ' - value: ' + value);
urlTitle.val(key);
url.val(value);
$(wrapper).append(
'<div id="title_and_url_group"><br><hr class="title_and_url"><div class="col-md-9 title_and_url">' +
'{!! Form::text("url_title", old("url_title"), ["class"=>"form-control", "name" => "url_title[]", "placeholder"=>"Title of URL"]) !!}' +
'</div><br><div class="col-md-9 title_and_url">' +
'{!! Form::text("url", old("url"), ["class"=>"form-control", "name" => "url[]", "placeholder"=>"Ex: http or https in url"]) !!}' +
'X</div></div>'
);
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" name="url_title[]" value="Bike"> URL Title<br>
<input type="checkbox" name="url[]" value="Car"> URL<br>
<div id="wrapper"></div>
You are using laravel's form facade in your javascript method, Laravel facade is executed at the server before the processed web page is passed to the client.
Since you're looping through js at client, form facade will be rendered as plain text, no php function will work, you'll need to write down the mark up instead of using Form Facade.
Document.querySelector('#wrapper').innerHTML =
result.forEach((res, index)=>{
`<div id="title_and_url_group">
<br>
<hr class="title_and_url">
<div class="col-md-9 title_and_url">
<input type="text" name="url_title[${index}]" value="${res.url_title}" class="form-control">
</div>
<br>
<div class="col-md-9 title_and_url">
<input type="checkbox" name="url[${index}]" value="${res.url}" class="form-control">
X
</div>`
}
I have this so far. I can't seem to get them into the values into the input fields. Here's the code. When I do a console.log it iterates correctly.
// *** Edit mode *** - Populates url tile and url fields
if (url) {
var result = JSON.parse(url);
var url_title = $('[name="url_title[]"]');
var url = $('[name="url[]"]');
$.each(result, function(key, value) {
console.log('key: ' + key + ' - value: ' + value);
url_title.val(key);
url.val(value);
$(wrapper).append(
'<div id="title_and_url_group"><br><hr class="title_and_url"><div class="col-md-9 title_and_url">' +
'{!! Form::text("url_title", old("url_title"), ["class"=>"form-control", "name" => "url_title[]"]) !!}' +
'</div><br><div class="col-md-9 title_and_url">' +
'{!! Form::text("url", old("url"), ["class"=>"form-control", "name" => "url[]"]) !!}' +
'X</div></div>'
);
});
}

Submitting 2 forms separately via AJAX - Python Flask

I'm trying to submit 2 separate forms via AJAX, but on submitting form2 I get a 500 bad request error.
My HTML code is below, but basically my page is a flask template that works as follows:
*User makes selections
*These selections are then posted via the submit button named "button" Value "Calculate Available Overall Heights".
*This runs some SQL query to determine a list of entries that are placed into a newly generated <select id="mySelect" class="form-control" onchange="myFunction()"></select>
This is done by JS which is also listed below as MyJS.js
OAH.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p class="h2">XXX</p>
<form method="post" id="form1">
<fieldset>
</div>
<div class="col-sm-3">
<span style="float:left"><label>Overall Height</label></span>
///my inputs, various selects etc ///
<div id="response">
<!-- Empty element until form submitted-->
</div>
<p id="ApertureHeight"></p>
<p id="ApertureHeightBelowPelmet"></p>
<p id="ApertureHeightUnderRoofSticks"></p><br>
<p id="OverallWidth"></p>
<p id="RearAppWidth"></p>
<p id="RearPillarNS"></p>
<p id="OAH"></p>
</div>
</fieldset>
<script src="/static/js/MyJS.js"></script>
</form>
<form method="post" id="form2">
<div class="col-sm-3">
<label>
<span style="float:left"><input type="text" id="myText" value=""></span>
</label>
<br>
<input type="button" value="Click Me!" onclick="submitForms()" />
</div>
</form>
</body>
</html>
form2 has a button called "Click Me!" which calls a function that submits form 2.
submitForms = function(){
document.getElementById("form2").submit();
};
MyJS.js
$("#form1").on("submit", function(event) {
$targetElement = $('#response');
event.preventDefault();
// Perform ajax call
//
console.log("Sending data: " + $(this).serialize());
$.ajax({
url: '/OAH',
data: $('form').serialize(),
datatype: 'json',
type: 'POST',
success: function(response) {
// Success handler
var TableTing = response["table"];
$("#TableThing").empty();
$("#TableThing").append(TableTing);
for (key in response) {
if (key == 'myList') {
// Add the new elements from 'myList' to the form
$targetElement.empty();
select = $('<select id="mySelect" class="form-control" onchange="myFunction()"></select>');
response[key].forEach(function(item) {
select.append($('<option>').text(item));
});
$targetElement.html(select);
} else {
// Update existing controls to those of the response.
$(':input[name="' + key + '"]').val(response[key]);
}
}
return myFunction()
// End handler
}
// Proceed with normal submission or new ajax call
})
});
submitForms = function(){
document.getElementById("form2").submit();
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
$("#form2").on("submit", function(event) {
event.preventDefault();
console.log("Sending data: " + $(this).serialize());
$.ajax({
url: '/OAH',
data: $('#form2').serialize(),
datatype: 'json',
type: 'POST',
success: function(response) {
return myFunction()
// End handler
}
// Proceed with normal submission or new ajax call
})
});
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function myFunction() {
var FifthWheel = document.getElementById("FifthWheelHeight").value;
var NeckDepth = document.getElementById("NeckDepth").value;
var CantRailDepth = document.getElementById("CantRailDepth").value;
var RearTensioner = document.getElementById("RearTensioner").value;
var OAH = document.getElementById("mySelect").value;
if (CantRailDepth = 115) {
var PelmetDim = 100;
} else {
PelmetDim = 75;
}
var ApertureHeight = Number(OAH) - Number(FifthWheel) - Number(NeckDepth) - Number(CantRailDepth);
var ApertureHeightBelowPelment = Number(ApertureHeight) - Number(PelmetDim);
var ApertureHeightUnderRoofSticks = Number(OAH) - Number(FifthWheel) - Number(NeckDepth) - 35;
document.getElementById("ApertureHeight").innerHTML = "Aperture below Cantrail = " + ApertureHeight + "mm";
document.getElementById("ApertureHeightBelowPelmet").innerHTML = "Aperture below pelmet = " +
ApertureHeightBelowPelment + "mm";
document.getElementById("ApertureHeightUnderRoofSticks").innerHTML = "Aperture below roof sticks = " +
ApertureHeightUnderRoofSticks + "mm";
document.getElementById("OverallWidth").innerHTML = "Overall Width = 2548mm (2550mm on spec)";
document.getElementById("OAH").innerHTML = OAH;
document.getElementById("myText").value = document.getElementById("OAH").innerHTML;
}
I need this form to submit separately, via AJAX without refreshing the page, as I need the JSON array to be able to calculate further stuff that will be passed into Python Flask. My issue is I am getting a bad request when submitting form2.
Anyone got any ideas on what I have done wrong?
I think you are using the same endpoint URL to try handle 2 different requests. The 2nd form does not send the correct data and you're then getting Server errors. Try creating another endpoint on your python flask server for handling form2 and the myText field value.

Pressing enter to search not working?

I'm trying to build a wikipedia viewer using Wikipedia's API, but I have a minor problem. If I manually press the search button, everything works fine, but if I press enter, nothing happens. Here's the js code:
$(document).ready(function () {
$("#input").keyup(function (event) {
if (event.keyCode == 13) {
$("#submit-button").click();
}
});
});
function wikiSearch() {
var query = document.getElementById("input").value;
var wiki_api = 'https://en.wikipedia.org/w/api.php';
var api = "https://en.wikipedia.org/w/api.php?action=query&prop=extracts&exlimit=max&format=json&exsentences=1&exintro=&explaintext=&generator=search&gsrlimit=10&gsrsearch=";
var wikilink = 'http://en.wikipedia.org/?curid=';
var link = api + query;
var html = "";
$.ajax({
url: link,
type: "get",
dataType: "JSONP",
success: function (data) {
var results = data.query.pages;
var pgs = Object.keys(results);
pgs.forEach(function (page) {
var title = results[page].title;
var text = results[page].extract;
var pagelink = wikilink + results[page].pageid;
html += '' + '<div class="item">' + title + '<br>' + '<p class="description-text" >' + text + '</p>' + '</div> <br> ';
});
$('#display').html(html);
}
});
}
And here's the html code:
<div class="container" id="content">
<h1>Wikipedia Viewer</h1>
<form>
<input type="text" name="search" placeholder="Search Wikipedia" id="input">
</form>
Random page
<input id="submit-button" type="button" value="Search" onclick="wikiSearch()" class="btn btn-success">
<div id="display"></div>
</div>
Here's a jsfiddle: https://jsfiddle.net/tbgoy836/
Replace input type="button" to submit. Also the input type="submit" should be inside the form. In that case you don't need to check the keycode & preventDefault will prevent the default behaviour of the form submit, since form is getting submitted using ajax. On pressing enter/return it will find the first submit button by itself and will trigger a click action
$(document).ready(function() {
$("#searchForm").submit(function(e) {
e.preventDefault();
wikiSearch()
})
});
function wikiSearch() {
console.log('wikiSearch')
var query = document.getElementById("input").value;
var wiki_api = 'https://en.wikipedia.org/w/api.php';
var api = "https://en.wikipedia.org/w/api.php?action=query&prop=extracts&exlimit=max&format=json&exsentences=1&exintro=&explaintext=&generator=search&gsrlimit=10&gsrsearch=";
var wikilink = 'http://en.wikipedia.org/?curid=';
var link = api + query;
var html = "";
$.ajax({
url: link,
type: "get",
dataType: "JSONP",
success: function(data) {
var results = data.query.pages;
var pgs = Object.keys(results);
pgs.forEach(function(page) {
var title = results[page].title;
var text = results[page].extract;
var pagelink = wikilink + results[page].pageid;
html += '' + '<div class="item">' + title + '<br>' + '<p class="description-text" >' + text + '</p>' + '</div> <br> ';
});
$('#display').append(html);
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container" id="content">
<h1>Wikipedia Viewer</h1>
<form id="searchForm">
<input type="text" name="search" placeholder="Search Wikipedia" id="input">
<div>
Random page
<input id="submit-button" type="submit" value="Search" onclick="wikiSearch()" class="btn btn-success">
</div>
</form>
<div id="display"></div>
</div>
Why you don't call function in javascript?
$("#submit-button").click(function(){
wikiSearch();
})
And remove onclick parameter of input.
Try $("#submit-button").trigger("click");
Or
you can simply call the function wikiSearch() instead of trigger the click event of submit button

closure loop in ajax callback

i have a data which were parsed from json, i display the data in a box like facebook's friends suggestion box. i want when the user click on any of the suggested users the request to be added to DB via ajax and its corresponding button disappears,everything is working just fine except the last thing(button disappears) instead the very first button in the list gets disappear, while im searching for a solution to my problem i came across something called closure but i reaaly couldn't know how to implement it in my code, another problem appeared when i tried to declare the listener anonymous function inside the loop was the data get inserted in the DB multiple times
(because its inside a loop), i know it might seems duplicated question but i just need someone pointing me the right place to declare my inner function,
my code looks like this
$(document).ready(function() {
var suggest = new XMLHttpRequest();
suggest.onreadystatechange = function() {
if (suggest.readyState === 4 && suggest.status === 200) {
var susers = JSON.parse(suggest.responseText);
for (var i = 0; i < susers.length; i += 1) {
var sphoto = '<div class="col-md-4 text-left "> <div id="fimage">';
sphoto += '<img width="50" height="50" src="user/';
sphoto += susers[i].activation + '/' + susers[i].pic + '"> </div> </div>';
var sname = '<div id="fname">' + susers[i].name + '</div>';
// here is the form im targetting to pull informtion from
var hidden = '<form id="fform"><input id="fnameh" name="name" type="hidden" value="' + susers[i].name + '" >';
hidden += '<input name="id" type="hidden" value="' + susers[i].id + '" >';
var fbutton = '<button id="addfriend"class="btn btn-info btn-xs pull-right text-center" type="submit" >Follow <span class=" glyphicon glyphicon-plus" aria-hidden="true"></span> </button></form';
var display = document.getElementById('fsuggest');
display.innerHTML += '<div class="scroller"><div id="fspace" > <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>' + sphoto + sname + hidden + fbutton +'</div></div>'
$('#addfriend').live('click', function(arg) {
return function() {
arg.preventDefault();
var data = $('#fform').serialize();
$.ajax({
data: data,
type: "post",
url: "addnew.php",
success: function(data) {
//make the text area empty
$('#addfriend').css("display", "none");
console.log(data);
}
}); // end of $.ajax
}(i); // end of inner function
}); // end of click listner
} //end of for loop
}
};
suggest.open('GET', 'box.php');
suggest.send();
}); // end of JQUERY ready
I am not sure why exactly you need closure here. The problem seems to be with the multiple form & button with same id.
All these buttons have same id so the forms. So
$('#addfriend').live('click', function(arg) {..}) has no reference to the particular button
Hope this change will help
Con-cat the value of iwith the id of the form & add an attribute data-id=i the button.
Beside instead of id add class addfriend to the button. So when this button will be clicked take the data-id value. Use this value to get the relevant form with id , & serialize that
var hidden = '<form id="fform_' + i + '"><input id="fnameh" name="name" type="hidden" value="' + susers[i].name + '" >';
hidden += '<input name="id" type="hidden" value="' + susers[i].id + '" >';
var fbutton = '<button data-id="' + i + '" id=""class=" addfriend btn btn-info btn-xs pull-right text-center" type="submit" >Follow <span class=" glyphicon glyphicon-plus" aria-hidden="true"></span> </button>';
Make below change to the click function.
Also reason of adding the event handler inside loop is not clear.
$('.addfriend').live('click', function(arg) {
arg.preventDefault();
var getDataId = $(this).attr('data-id') // get the data-id
var data = $('#fform_'+getDataId).serialize(); // get relevant form
$.ajax({
// rest of code
}); // end of $.ajax
})
Try to use jquery version above 1.9 to use the on method for event delegation
I made a few changes to your code.
With the new javascript, I believe most browsers support string interpolation natively (without any extra plugins or pre-compiling with babel for example) so you can just interpolate your variables within backticks ``.
Also, you seemed to be creating a form with the id of #fform and a button with the id of #addfriend for each iteration. The problem is that calling $('#fform') or $('#addfriend') will return an array with as many elements as you have users.
So I added an extra data-suser-id attribute with unique id's on those. I am not sure the code will work because I can't actually try it and changed quite a few things but let me know if you are getting closer to your solution.
$(document).ready(function() {
var suggest = new XMLHttpRequest();
suggest.onreadystatechange = function() {
if (suggest.readyState === 4 && suggest.status === 200) {
var susers = JSON.parse(suggest.responseText);
var limit = susers.length;
for (var i = 0; i < limit; i += 1) {
var sphoto = `<div class="col-md-4 text-left ">
<div id="fimage">
<img width="50" height="50" src="user/${susers[i].activation}/${susers[i].pic}">
</div>
</div>`
var sname = `<div id="fname">${susers[i].name}</div>`
// here is the form im targetting to pull informtion from
var hidden = `<form id="fform" data-suser-id='${susers[i].id}'>
<input id="fnameh" name="name" type="hidden" value="${susers[i].name}" >
<input name="id" type="hidden" value="${susers[i].id}">`
var mutalusers = `</form><div id="mutal" class="text-left">
<h6>
<div id="fmutal">
<?php echo $c = mutal(${susers[i].id}, $me, $db) ?>
</div>
</h6>
</div>`
var fbutton = `<button id="addfriend" class="btn btn-info btn-xs pull-right text-center" type="submit" data-suser-id='${susers[i].id}'>Follow <span class=" glyphicon glyphicon-plus" aria-hidden="true"></span> </button>`;
var display = document.getElementById('fsuggest');
display.innerHTML += `<div class="scroller">
<div id="fspace">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
${sphoto}
${sname}
${hidden}
${fbutton}
${mutalusers}
</div>
</div>`
// #live method is deprecated : http://api.jquery.com/live/
var addfriend_button = $(`#addfriend[data-suser-id=${susers[i].id}]`)
addfriend_button.on('click', function(arg) {
// return function(){
arg.preventDefault();
// the selector `#fform` doesn't seem to be unique to the current user's form data, so I added an data-attribute to make sure we are getting the correct form data
var data = $(`#fform[data-suser-id=${susers[i].id}]`).serialize();
$.ajax({
data: data,
type: "post",
url: "addnew.php",
success: function(data) {
//make the text area empty for the current user's `#addfriend` button
addfriend_button.html('done');
console.log(data);
}
}); // end of $.ajax
// }(i); // end of inner function : not sure why this inner function is necessary
}); // end of click listner
} //end of for loop
console.log(susers);
}
};
var suugestFile = 'box.php';
suggest.open('GET', suugestFile);
suggest.send();
}); // end of JQUERY ready

How to pass Json string as a javascript method parameter

I formed a Json String.
var jsonProduct = "{Product:'" + Details[0] + "',Brand:'" + Details[1] + "',Model:'" + Details[2] + "',Price:'" + Details[3] + "'}"
<input class="button black" type="submit" value="Add To Cart" onclick="return addOrderItem(' + jsonProduct + ')" />
How to pass this 'jsonproduct to javascript function addOrderItem as follows
function addOrderItem(product)
{
cartproduct[cartproduct.length] = " + product + ";
//cartproduct[cartproduct.length] = " + {Product:'1001',Brand:Dell',Model:'Inspiron',Price:'25000'} + ";
}
When I pass product as parameter it is not working
You could parse it using
var product = JSON.parse(jsonProduct);
but you don't have to use JSON at all. Do this :
var product = {
Product: Details[0], Brand:Details[1],
Model:Details[2], Price:Details[3]
};
addOrderItem(product);
If you want to call this from an input click, you can bind the call using
onclick="return addOrderItem(product)"
or, better, give an id to your element and then bind the event handler from the JS code :
<input id=submit class="button black" type="submit" value="Add To Cart">
<script>
document.getElementById('submit').onclick=function(){addOrderItem(product)};
</script>

Categories