Why can I not run javascript (Js2Py) in Python (Streamlit)? - javascript

I am using Streamlit to build a simple app. In this app I made a simple form using FormSubmit to let people contact me. But I don't want them to leave the website when they click on Send button, so I am trying to send the form using AJAX.
To integrate JS in Python I am using Js2Py, but I can't solve this.
This is the form:
contact_form = """
<form id="myForm">
<input type="hidden" name="_captcha" value="false">
<input type="text" name="name" style="font-size:20px;background-color:#72c2dd; color:#000000" placeholder="Your name" required>
<input type="email" name="email" style="font-size:20px;background-color:#72c2dd; color:#000000" placeholder="Your email" required>
<textarea name="message" style="font-family:'Alegreya, serif';
font-size:20px;" placeholder="Your message here" required></textarea>
<input type="hidden" name="_template" value="table">
<button type="submit" value="Submit" id="sendButton" class="block">Send</button>
</form>
"""
so I made a javascript variable, to check when Send button is clicked:
check_submit = '''<script src="https://code.jquery.com/jquery-3.6.1.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#sendButton").click(function(e) {
e.preventDefault();
var form = $('myForm'[0]);
var data = new FormData(form);
$.ajax({
method: "POST",
url: "https://formsubmit.co/my-email",
dataType: 'json',
data: data,
success: (data) => console.log(data),
error: (err) => console.log(err)
});
});
});
</script>
'''
then:
st.markdown(contact_form, unsafe_allow_html=True)
So I am passing the javascript variable into the function eval_js() from Js2Py:
js2py.eval_js(check_submit)
I got my form up, and an error message below the form:
JsException: SyntaxError: Line 1: Unexpected token <
and when I fill the form and clicking the Send button, nothing happens.
This means according to me that I misunderstood how to use JS2Py in Python!!!
Any help/suggestion to show me where I did wrong, is very appreciated

Related

POST request Fetch API prevent redirect

So i want to make a pure html and javascript form and submit it to server.
Here is my html form code:
<form id="email-signup" action="http://www.server.com" method="post">
<input id="firstname-input" type="hidden" name="firstname" value="">
<input type="text" name="email" placeholder="Input Email">
<input type="hidden" name="campaign[id]" value="1">
<input type="hidden" name="campaign[name]" value="Text Campaign">
<input type="submit" value="Submit">
</form>
And here is my javascript code:
var element = document.getElementById("email-signup");
element.addEventListener("submit", function(event) {
event.preventDefault()
fetch("http://www.endpoint.api", {
method: "POST",
body: new FormData(document.getElementById('email-signup'))
})
})
.then(() => {
alert('Selamat email anda sudah terdaftar!')
})
The problem is, whenever i submit an email to that form it redirects me to a new page with a response of success. I want to prevent that to happen and instead it will pop up an alert that tells me the email submission is succeeded.
You're putting the .then in the wrong place - put it right after the fetch, not after the event listener.
var element = document.getElementById("email-signup");
element.addEventListener("submit", function(event) {
event.preventDefault()
fetch("", {
method: "POST",
body: new FormData(document.getElementById('email-signup'))
}).then((res) => {
if (res.ok) alert('Selamat email anda sudah terdaftar!')
})
})
Consistent indentation will help you avoid problems like this in the future. (see your question, I fixed the formatting - should be pretty clear what the problem was now)
Possibly, you are putting JavaScript code before HTML and .then() after EventListner.
The solution will be to place JavaScript code after HTML and place .then() just after fetch.
<form id="email-signup" action="http://www.server.com" method="post">
<input id="firstname-input" type="hidden" name="firstname" value="">
<input type="text" name="email" placeholder="Input Email">
<input type="hidden" name="campaign[id]" value="1">
<input type="hidden" name="campaign[name]" value="Text Campaign">
<input type="submit" value="Submit">
</form>
<script>
var element = document.getElementById("email-signup");
element.addEventListener("submit", function(event) {
event.preventDefault()
fetch("", {
method: "POST",
body: new FormData(document.getElementById('email-signup'))
}).then(() => {
alert('Selamat email anda sudah terdaftar!')
})
})
</script>

AJAX for redirecting to external domain when submitting form

I have a form as so, which submits data to an outside domain:
<form action="https://EXTERNALdomain.com/register" id="form_register" method="POST">
<input type="text" id="first-name" name="first-name" value="" placeholder="First Name" required/>
<input type="text" id="last-name" name="last-name" value="" placeholder="Last Name" required/>
<input type="email" id="email" value="" name="email" placeholder="Email Address" required/>
<input type="password" id="password" name="password" placeholder="Password" required/>
<input type="submit" value="Create Account" />
</form>
However, I'm trying to be able to submit the form AND redirect it to a different page, also externally. So far, my attempts have been unsuccessful with AJAX.
<script type="text/javascript">
function sform() {
$.ajax({
url: "https://EXTERNALdomain.com/home",
data: $('#request').serialize(),
type: 'POST',
success: function (resp) {
alert(resp);
},
error: function(e) {
alert('Error: '+e);
}
});
}
I've then been calling the form as so:
<form onsubmit="sform()" id="request">
This isn't working. I just get a long URL, and the form doesn't actually post, the page just reloads
This is because you're letting the form submit, which changes the page url and POSTs data there.
From "submit the form AND redirect it to a different page" I assume you want to submit the form to https://EXTERNALdomain.com/register and redirect to https://EXTERNALdomain.com/home. To do this, you need to use $.ajax to submit the form, them change the location on success.
function sform() {
$.ajax({
url: $('#request').attr("action"),
data: $('#request').serialize(),
type: $('#request').attr("method"),
success: function (resp) {
location.href = "https://EXTERNALdomain.com/home"; // redirect
},
error: function(e) {
alert('Error: '+e);
}
});
return false; // cancel default action
}

AJAX HTTP post request is triggered 3 times

In my webapp, the Ajax request is executed 3 times, and I have no idea why this is happening.
Can someone please help here?
My Javascript:
$(document).ready(function() {
console.log("ready!");
$('form').on('submit', function(e) { //
e.preventDefault();
// on form submission ...
console.log("the form has beeen submitted");
// grab values
valueOne = $('input[name="perfid"]').val();
valueTwo = $('input[name="hostname"]').val();
valueThree = $('input[name="iteration"]').val();
console.log(valueOne)
console.log(valueTwo)
console.log(valueThree)
$.ajax({
type: "POST",
url: "/",
dataType:'json',
data : { 'first': valueOne,'second': valueTwo,'third': valueThree},
success: function(data) {
var res = data.AVG;
var p = '<p><pre>'+res+'</pre></p>';
$('#result').append(p);
},
error: function(error) {
console.log(error)
}
});
}); });
And my HTML is:
<form role="form" method="post" onsubmit="return false;">
<div class="form-group">
<input type="text" class="input-medium" id="perfid" name="perfid" placeholder="Enter a Perf ID" required style="height:30px;">
<input type="text" class="input-medium" id="hostname" name="hostname" placeholder="Enter a HostName" style="height:30px;">
<input type="text" class="input-medium" id="iteration" name="iteration" placeholder="Enter a Iteration" required style="height:30px;">
<button type="submit" class="btn btn-default" style="height:30px;">Get Data</button>
</div>
</form>
I have written the code for only one AJAX POST request,
EDIT:
This is the console output:
Please make sure you have included the js file only once,
and add a return false at the end of the submit event callback
look at the selector
$('form').on('submit', function(e) {
if the page has 3 forms, the above selector will execute 3 times
Try to add id to the form like this. sorry about my bad english

Contact form using e.preventDefault(); not working live

UPDATE - the contact form is found at this URL.
I am trying to get the following contact form to function, using this tutorial.
I manage to get everything to work as expected on my computer using apache webserver.
After uploading the files to an online website, the ajax function does not kick in.
I seems like the e.preventDefault(); stops working after the upload, and the form is redirected to a new site,and not just being processed on the site without the reload.
I have also been trying to use the return false; instead of e.preventDefault(); without any success.
Her is my code:
.html
<form method="post" action='mail/mail.php'>
<label>Name</label>
<input name="name" id="name" placeholder="Name.." required="true" class="input-field">
<label>Mail</label>
<input type="email" name="email" placeholder="Mail.." required="true" class="input-field">
<label>Msg</label>
<textarea name="message" id="message" class="textarea-field" required="true"></textarea>
<input type="submit" id="submit" name="submit" value="Send">
</form>
<div id="loading">
Sender melding...
</div>
<div id="success">
</div>
.js
$(function(){
$('form').submit(function(e){
var thisForm = $(this);
//Prevent the default form action
//return false;
e.preventDefault();
//Hide the form
$(this).fadeOut(function(){
//Display the "loading" message
$("#loading").fadeIn(function(){
//Post the form to the send script
$.ajax({
type: 'POST',
url: thisForm.attr("action"),
data: thisForm.serialize(),
//Wait for a successful response
success: function(data){
//Hide the "loading" message
$("#loading").fadeOut(function(){
//Display the "success" message
$("#success").text(data).fadeIn();
});
}
});
});
});
})
Please help!
That's because your JS is missing a closing });. Please check this demo to confirm that the default action is indeed prevented and the ajax does kick in. However, I was expecting a POST but instead I am seeing an OPTIONS request.
NOTE: Giving an element a name or id attribute value of submit is bad practice. You cannot for example use JavaScript to submit the form via default form submission -- this.submit() or $('form')[0].submit() without getting the error ...submit() is not a function .....
$(function() {
$('form').submit(function(e) {
var thisForm = $(this);
//Prevent the default form action
//return false;
e.preventDefault();
//Hide the form
$(this).fadeOut(function() {
//Display the "loading" message
$("#loading").fadeIn(function() {
//Post the form to the send script
$.ajax({
type: 'POST',
url: thisForm.attr("action"),
data: thisForm.serialize(),
//Wait for a successful response
success: function(data) {
//Hide the "loading" message
$("#loading").fadeOut(function() {
//Display the "success" message
$("#success").text(data).fadeIn();
});
}
});
});
});
});
}); // <==== MISSING THIS
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form method="post" action='mail/mail.php'>
<label>Name</label>
<input name="name" id="name" placeholder="Name.." required="true" class="input-field">
<label>Mail</label>
<input type="email" name="email" placeholder="Mail.." required="true" class="input-field">
<label>Msg</label>
<textarea name="message" id="message" class="textarea-field" required="true"></textarea>
<input type="submit" id="submit" name="submit" value="Send">
</form>
<div id="loading">
Sender melding...
</div>
<div id="success">
</div>
Since you are submitting via AJAX anyway, you may find it easier to change your input type to button, and bind to click instead of form submit, to avoid the default submit behaviour you are trying to circumvent.

Ajax POST always returns error

I'm trying to submit a form via ajax POST to a servlet, process the parameters and then send a response. It always winds up giving me an error.
Form html :
<form id="login" >
<div class="form-group">
<label for="username"> Username : </label>
<input id="username" name="username" type="text" class="form-control" placeholder="Name">
</div>
<div class="form-group">
<label for="password"> Password : </label>
<input id="password" type="password" name="password" class="form-control" placeholder="*******">
</div>
<button id="loginBtn" onclick="posaljiLogParametre()" value="Submit" class="btn btn-primary" type="submit"> Uloguj se </button>
</form>
Ajax post :
$.ajax({
type: "POST",
url: "LogInServlet",
dataType: 'text',
data: $("#login").serialize(),
success: function (data) {
$loginParagraf.css("display","block");
alert("DA");
},
error: function(data, textStatus, errorThrown) {
alert(textStatus);
alert(errorThrown);
alert(data.message);
}
});
Servlet :
String username = request.getParameter("username");
String pass = request.getParameter("password");
JSONObject jsonReply = new JSONObject();
System.out.println(username);
System.out.println(pass);
response.setStatus(200);
PrintWriter out = response.getWriter();
response.setContentType("application/json");
jsonReply.put("success",true);
jsonReply.put("message", "Please work this time");
System.out.println(jsonReply.toString());
out.print(jsonReply);
The system prints work just fine, and the username and password are printed out in the console.
From what I can tell I have recreated your setup using an index.jsp page which includes the form and ajax call, and a servlet with a doPost method that includes your code. The code appears to work as expected. I get a successful response with the JSON message.
My first thought was changing dataType: 'text' to 'json', but it appears to work either way.
I had to wrap a try/catch (JSONException) around your jsonReply.put statements to appease the compiler.
One thing that might be causing trouble is that your form includes a submit button which will fire the onclick event and submit the form. I changed it to type="button" so that only the onclick event would fire.

Categories