I have read a few similar questions, but no one seems to have asked about this specifically. I am sending a JSON object I know has the properties I want, but one of them disappears fromt he body durint a $.post() request. I have the following form, I know that the DOM ids are correct and that their .val()s are there, because I console log the json object before sending it as a parameter to authenticate(user):
Here is an example for completeness:
const authenticate = (user) => {
console.log(user);
$.post("http://localhost:8080/auth",user)
.done(
(data,status,xhr) => {
console.log(data.user+"---user---");
}
).fail(xhr => console.log(JSON.parse(xhr.responseText).message));
}
}
$('#login_form').on('submit', event => {
event.preventDefault();
console.log({email:$('#username').val(),password:$('#password').val()});
authenticate({email:'user#email.com',password:$('#password').val()});
});
<form id="login_form" onsubmit="false">
<label for="username">Email</label>
<input id="username" name="username" placeholder="jimmy#john.com" type="email" class="form-control" required autofocus>
<label for="password">Password</label>
<input id="password" name="password" placeholder="Password" type="password" class="form-control" required>
<button type="submit" class="btn btn-primary btn-lg btn-block" style="margin-top:10px">Log in</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
{email:$('#username').val(),password:$('password').val()}
But I have tried replacing them with string values of a real user, and I can see that the .val()s are there in the console log. What I am seeing in the beowser's dev tools is that the post request is sending this as the body:
{email:"",password:"password"}
where it definitely is passing the right object, but the email field is either empty or a blank string. I have tried stringifying the object and sending it as a template literal, and I have tried setting the $.post() datatype to JSON, but nothing seems to make it parse the email, so I get a 400 back from the server's authenticator for missing credentials. I have exhausted every path I know to try, and not found someone with this issue on Google. Pls halp, and as always, thanks!
here is the working example, seems you were using same name for const & function
$('#login_form').on('submit', event => {
event.preventDefault();
authenticate({
email: $('#username').val(),
password: $('#password').val()
});
});
function authenticate(user){
console.log(user);
$.post("http://localhost:8080/auth", user)
.done(
(data, status, xhr) => {
console.log(data.user + "---user---");
}
).fail(xhr => console.log(JSON.parse(xhr.responseText).message));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="login_form" onsubmit="false">
<label for="username">Email</label>
<input id="username" name="username" placeholder="jimmy#john.com" type="email" class="form-control" required autofocus>
<label for="password">Password</label>
<input id="password" name="password" placeholder="Password" type="password" class="form-control" required>
<button type="submit" class="btn btn-primary btn-lg btn-block" style="margin-top:10px">Log in</button>
</form>
Thanks all, I will probably be pulling this down soon because it was just one of those "i'm an idiot" things. I had another event listener that I forgot to delete that was causing the issue. I knew something was up because when I posted my jsFiddle smippet, it worked...so there is nothing wrong with my using const in an es6 function definition. The correct listener was the one I posted:
$('#login_form').on('submit', event => {
event.preventDefault();
console.log({email:$('#username').val(),password:$('#password').val()});
authenticate({email:$('#username').val(),password:$('#password').val()});
});
But there was another one that had the wrong DOM id $('#email).val():
$('#login_form').on('submit', event => {
event.preventDefault();
console.log({email:$('#email').val(),password:$('#password').val()});
authenticate({email:$('#email').val()',password:$('#password').val()});
});
Don't be dumb like me, read before you ask...
Related
it's probably a simple logic problem and I'm probably doing something wrong but I can't find why.
When my form is submitted i'm using a little API to send a mail with some JS code (emailJS). I can make the html say "Please fill out this field" but the mail is still sended.
I tried with preventDefault and stopImmediatePropagation :
HTML
<label for="watts1">Device 1:</label>
<input type="number" required/>
<input type="submit" id="submitButton" value="Send form"/>
JS
document.getElementById("submitButton").addEventListener("click", function (e) {
// e.preventDefault();
// e.stopImmediatePropagation();
form.subject = `${form.name} ${form.surname} ...`
form.body = `${form.name} ${form.surname} ...`
Email.send({
SecureToken: "***",
To: "***",
From: `***`,
Subject: `${form.subject}`,
Body: `${form.body}`,
}).then((message) => alert(message));
});
I'm pretty new to coding, I found much solutions on different websites for any previous issue but here I'd like to find an easy way to make it instead of weird solutions that I can't yet understand.
Thanks in advance !
HTML5 required validation normally works on submit events
If you do not want a form, you can check the validity of the field:
Note I changed the button to type="button"
document.getElementById("sendButton").addEventListener("click", function(e) {
if (document.getElementById("number").checkValidity()) {
console.log("sending"); // never reached if number is empty
/*
Email.send({
SecureToken: "***",
To: "***",
From: `***`,
Subject: `${form.subject}`,
Body: `${form.body}`,
}).then((message) => alert(message));
*/
}
});
<label for="watts1">Device 1:</label>
<input type="number" required id="number" />
<input type="button" id="sendButton" value="Send form" />
Using form submit event
document.getElementById("formID").addEventListener("submit", function(e) {
e.preventDefault(); // necessary here
console.log("sending"); // never reached if number is empty
/*
Email.send({
SecureToken: "***",
To: "***",
From: `***`,
Subject: `${form.subject}`,
Body: `${form.body}`,
}).then((message) => alert(message));
*/
});
<form id="formID">
<label for="watts1">Device 1:</label>
<input type="number" required/>
<input type="submit" id="submitButton" value="Send form" />
</form>
I have a headless WordPress site. I'm working on the event handler to submit the contact form. I'm using Contact Form 7. I've tried using vanilla JS, I'm using jQuery here because it seems like a better option, and I'm losing my mind.
Essentially, the form submits but the fields do not clear. I've tried form.reset() in JS, $('#formid')[0].reset() in jQuery, and the code below. I don't know why this isn't working and the result is really suboptimal. Any ideas?
I will fully admit that I am more comfortable working in javascript than jQuery so I might be missing something obvious.
If I don't have the iframe set as the form target, the page redirects to a white page with JSON data. Am I missing something about event.preventDefault()? It's not working the way it should, and has in my experience.
$(document).ready(function() {
$('#formElem').on('submit', function(event) {
event.preventDefault();
let request = $.ajax({
url: "https://api.chloemedranophotography.com/wp-json/contact-form-7/v1/contact-forms/54/feedback",
type: "post",
data: new FormData(this)
}).done(resetForm());
})
function resetForm($form) {
$form.find('input:text, input:tel, input:file, select, textarea').val('');
$('datePicker').val('').attr('type', 'text').attr('type', 'date');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="https://api.chloemedranophotography.com/wp-json/contact-form-7/v1/contact-forms/54/feedback" id="formElem" name="contactForm" method="post" class="contact__form" target="formtarget">
<h3 class="contact__form--heading">Contact</h3>
<p class="contact__form--paragraph">Currently operating out of Minot, North Dakota. Soon to be in South Korea!</p>
<input id="your-name" class="contact__form--input" type="text" name="your-name" placeholder="Name">
<input id="your-email" class="contact__form--input" type="text" name="your-email" placeholder="Email">
<input id="your-tel" class="contact__form--input" type="tel" name="your-tel" placeholder="Phone">
<input id="preferred-date" class="contact__form--input" placeholder="Select session date" type="date" name="preferred-date">
<textarea id="your-info" class="contact__form--input" placeholder="Tell me about yourself!" name="your-info"></textarea>
<textarea id="services" class="contact__form--input" placeholder="What services are you interested in booking?"></textarea>
<textarea id="how-heard" class="contact__form--input" placeholder="How did you hear about my business?" name="how-heard"></textarea>
<input id="btnSubmit" class="contact__form--input btn-contact" type="submit" name="submit">
<div id="messageArea"></div>
<iframe class="formtarget" name="formtarget"></iframe>
</form>
There's several separate issues:
.done(resetForm()) is incorrect as it immediately calls resetForm() and sets the returned value from that call as the event handler.
You need to send the $form argument in the resetForm() method call, so provide a full function block to the done() handler, including that argument
When sending a FormData object in a jQuery AJAX call you need to set processData and contentType to false so the data is encoded correctly.
jQuery does not have :tel and :file pseudo selectors. Instead you can use :input to select all input, textarea and select elements to reset their values.
Changing the type of the date control to text and then back to date is not necessary, even without the above point.
$(document).ready(function() {
const $form = $('#formElem').on('submit', function(e) {
e.preventDefault();
let data = new FormData(this);
let request = $.ajax({
url: "https://api.chloemedranophotography.com/wp-json/contact-form-7/v1/contact-forms/54/feedback",
type: "post",
data: data,
contentType: false,
processData: false
}).done(function() {
resetForm($form)
});
})
function resetForm($form) {
$form.find(':input').val('');
// alternatively to reset the form to original state, not wipe all fields use this
// $form.get(0).reset();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="https://api.chloemedranophotography.com/wp-json/contact-form-7/v1/contact-forms/54/feedback" id="formElem" name="contactForm" method="post" class="contact__form" target="formtarget">
<h3 class="contact__form--heading">Contact</h3>
<p class="contact__form--paragraph">Currently operating out of Minot, North Dakota. Soon to be in South Korea!</p>
<input id="your-name" class="contact__form--input" type="text" name="your-name" placeholder="Name">
<input id="your-email" class="contact__form--input" type="text" name="your-email" placeholder="Email">
<input id="your-tel" class="contact__form--input" type="tel" name="your-tel" placeholder="Phone">
<input id="preferred-date" class="contact__form--input" placeholder="Select session date" type="date" name="preferred-date">
<textarea id="your-info" class="contact__form--input" placeholder="Tell me about yourself!" name="your-info"></textarea>
<textarea id="services" class="contact__form--input" placeholder="What services are you interested in booking?"></textarea>
<textarea id="how-heard" class="contact__form--input" placeholder="How did you hear about my business?" name="how-heard"></textarea>
<input id="btnSubmit" class="contact__form--input btn-contact" type="submit" name="submit">
<div id="messageArea"></div>
<iframe class="formtarget" name="formtarget"></iframe>
</form>
In your code you are calling resetForm and assigning what it returns to the done event handler. It is not calling that function when done is called.
You also are not passing the form reference to the function. So you will have an error message in your console.
$(document).ready(function() {
$('#formElem').on('submit', function(event) {
var form = this;
event.preventDefault();
let request = $.ajax({
url: "https://api.chloemedranophotography.com/wp-json/contact-form-7/v1/contact-forms/54/feedback",
type: "post",
data: new FormData(form)
}).done(function () { resetForm(form); });
})
function resetForm($form) {
$form.find('input:text, input:tel, input:file, select, textarea').val('');
$('datePicker').val('').attr('type', 'text').attr('type', 'date');
}
});
I have developed some forms using Eleventy and I never had any issues with the credentials appending themselves to URL, but now I have made a new password authentication form and this one is appending the password to the url and I am unclear as to why.
This is the Eleventy form:
module.exports = function() {
return `
<form class="rds-form">
<div>
<input
type="password"
id="input_password"
name="Password"
aria-required="true"
class="form-control to-switch"
maxlength="32"
data-required-message="A password is required to login. Please add it now"
/ >
</div>
<div class="pull-right">
<button
type="submit"
class="btn btn-primary btn-lg submit-btn"
id="custom-password"
>
Login
</button>
</div>
</form>
`
}
the logic for it:
document.querySelector('.rds-form').addEventListener('submit', function () {
alert('form submitted!');
});
The form default method is GET so set the method attribute to POST.
<form class="rds-form" method="post">
So apparently the API I am working with from a third party vendor does an AJAX call, so I had to add e.preventDefault() to prevent the default browser behavior like so:
document.querySelector('.rds-form').addEventListener('submit', function (e) {
e.preventDefault();
alert('form submitted!');
});
I have an ASP.NET MVC project and currently I am using ViewData["ResultMessage"] to show the result of a form (which is done after the user submits & refreshes the page).
I want to do it right after he clicks submit (without refreshing the page). So I have to use Javascript for that, which I am new with. No experience what so ever.
How my form looks like is this:
<form id="contactForm" method="post" action="..">
<div class="field half first">
<label for="Name">Name</label>
<input type="text" name="Name" id="Name" placeholder="Your name" required />
</div>
<div class="field half">
<label for="Email">Email</label>
<input type="email" name="Email" id="Email" placeholder="Your email" required />
</div>
<div class="field">
<label for="Message">Message</label>
<textarea name="Message" id="Message" rows="5" placeholder="Your message" required minlength="20"></textarea>
</div>
<input type="submit" value="Send Message" />
<p>#ViewData["ContactActionResult"]</p>
</form>
You can see the result is displayed with Razor using ViewData. Now I want to do it without refreshing the page and learn JS on the way.
What I have tried so far:
$(function () {
$("button").click(function (e) {
e.preventDefault()
$.ajax({
type: "POST",
url: "/Receiver",
data: car,
datatype: "html",
success: function (data) {
alert("Congratulations, it worked!");
$('#contactForm').html(data);
},
error: function(data) {
alert("Failed.");
}
});
});
});
But I am not sure if I did something wrong or simply not implementing it right. I have the above function inside <script> here </script> in my HTML page. Nothing happens when I click the submit button on the form.
If it is an ajax call, It is best if you return a JSON response . You can use the Request.IsAjaxRequest() to determine whether the request is normal form request or ajax call.
You should also consider using to the PRG pattern. After successfully saving, you should do a redirect to a GET action where you can render a view, instead of returning to the same view with a viewbag message. If you want to pass some message to the new view/action, use TempData instead of ViewData.
[HttpPost]
public ActionResult Receiver(string name, string Email)
{
// Your existing code to save
if(Request.IsAjaxRequest())
{
return Json(new { status = "success", message = "Created successfully" });
}
// Normal form submit. So let's follow PRG pattern
TempData["ResultMessage"] = "Created successfully";
return RedirectToAction("Index");
}
You can also put a try/catch and return a json like this for error usecase
return Json(new { status = "error", message = "some serious error" });
In Index action/view, you can read TempData["ResultMessage"] and display to user.
Now, for the ajax usecase, in your current view, you can add a div to show the message
<form id="contactForm" method="post" asp-action="Receiver">
<div id="msg"></div>
<div class="field half first">
<label for="Name">Name</label>
<input type="text" name="Name" id="Name" placeholder="Your name" required />
</div>
<div class="field half">
<label for="Email">Email</label>
<input type="email" name="Email" id="Email" required />
</div>
<div class="field">
<label for="Message">Message</label>
<textarea name="Message" id="Message" rows="5"
placeholder="Your message" required minlength="20"></textarea>
</div>
<input type="submit" value="Send Message" />
</form>
and now in your ajax call's success callback, check the json response coming back from server and show the message property as needed. If you are putting the script inside the razor view file, make sure you are putting it inside a Scripts section so that it will be evaluated in the proper order (After jQuery is loaded, assuming you load jQuery before calling RenderSection("scripts") inside the layout)
#section Scripts
{
<script>
$(function (){
$("#contactForm").submit(function (e){
e.preventDefault()
$.ajax({
type: "POST",
url: $(this).attr("action"),
data: car,
success: function (data){
if (data.status === "success")
{
$('#msg').html(message);
}
//to do : handle statuss=="error" as needed
},
error: function (data)
{
alert("Failed.");
}
});
});
});
</script>
}
For asp.net core, you can write a IsAjaxRequest method in your base controller and use that. jQuery will add X-Requested-With header with value XMLHttpRequest for your ajax calls.
protected bool IsAjaxRequest()
{
return Request.Headers["X-Requested-With"] == "XMLHttpRequest";
}
I am attempting to store information that is put into this form with meteor:
<form class="form-group" id="lost_form">
<label for="item_name">Type</label>
<input id="item_name" class="form-control" type="text" placeholder="What is the item? Ex: Water bottle" required/>
<label for="item_brand">Brand</label>
<input id="item_brand" class="form-control" type="text" placeholder="What brand is the item? Ex: Nalgene" required/>
<label for="item_desc">Description</label>
<input id="item_desc" class="form-control" type="text" placeholder="Describe the item. Ex: Green, name on bottom" required/>
<label for="item_loc">Location</label>
<input id="item_loc" class="form-control" type="text" placeholder="Where did you have it last? Ex: Main common room"/>
<label for="item_date">Date Missing</label>
<input id="item_date" class="form-control" type="date"/>
<br>
<input id="submit_lost_form" class="btn btn-primary btn-block" type="submit" value="Submit" />
</form>
The JS I am using to put it into a collection is below:
LostItems = new Meteor.Collection('lostitems');
Meteor.methods({
'insertItem': function(iname, ibrand, idesc, iloc, idate){
LostItems.insert({
user: Meteor.user(),
name: iname,
brand: ibrand,
description: idesc,
location: iloc,
date: idate
})
}
});
if (Meteor.isClient) {
Template.lost_form.events({
'submit form': function (event) {
event.preventDefault();
var itemName = event.target.item_name.value;
var itemBrand = event.target.item_brand.value;
var itemDesc = event.target.item_desc.value;
var itemLoc = event.target.item_loc.value;
var itemDate = event.target.item_date.value;
Meteor.call('insertItem', itemName, itemBrand, itemDesc, itemLoc, itemDate);
}
});
}
But whenever I submit the form, nothing happens. There are no errors in the developer console, or on the meteor console, and when I do LostItems.find().fetch() there is nothing there.
I am new to meteor so this is probably a really dumb question, but I appreciate any help!
You might need to use Meteor.userId() instead of Meteor.user() in your call to insert(). Without the autopublish package, the doc returned by Meteor.user() can be different on the client than it is on the server (for security reasons). That would mean that the client-side insert into your mini-mongodb and the server-side insert into the real mongodb could conflict with each other. I would expect the client-side insert to be ignored after the result of the server-side insert propagates back to the client. I'm not sure why it isn't being replaced by the server-side insert though. What does LostItems.find().fetch() return when you run it on the server (e.g. in meteor shell)?
I fixed the issue by adding insecure, yogiben:autoform-tags and autopublish to my package list. I think autopublish is the one that made the difference. I am sure there is a better way to do this and that this probably has some security flaws to it, but this is not a big project and it isn't storing sensitive data, so this will work for now.