I have simple form for sending email dato to API, but i want send data via Ajax for not reaload page and give success message under input tag.
HTML Sending form
HTML:
<form action="" method="POST" class="send-modal-data">
<input type="text" id="send_email" name="subscribe-email" class="modal-input" placeholder="Email *">
<button name="subscribe-form" class="danger-btn send-subscribe">Send</button>
</form>
Ajax
$(function() {
$(".send-subscribe").click(function(e) {
e.preventDefault();
var settings = {
email: $("#send_email"),
"url": "xxxx/api/user/trial/subscribe?email=" + email,
"method": "POST",
"timeout": 0,
};
$.ajax(settings).done(function (response) {
console.log(response);
});
});
});
But when i send email, my modal window closing and not send data, how i can realize with right way ?
Your post function should look something like this:
$(".send-subscribe").click(function() {
$.post("https://xxx/api/user/subscribe", {
email : $("#send_email")
}, function(data, status){
console.log(status + " :: " + data);
});
});
You than can use status and data to continue your work.
Related
I'm creating a login page and at the bottom of the pop-up form, there is another button that takes you to the registration page. The issue appears to be that when navigating to the new page it all sits under the original sign-in form which uses an ajax call to check if the user exists so when they try to submit the registration form it then calls that ajax call from the sign-in form.
Sign-in form
<div id="myForm">
<form onsubmit="return false;" id="loginForm">
<h1>Login</h1>
<label for="email"><b>Email</b></label>
<input type="email" id="email" placeholder="Enter Email" name="email" required>
<label for="psw"><b>Password</b></label>
<input type="password" id="psw" placeholder="Enter Password" name="psw" required>
<div id="message" class="alert-danger"></div>
<br />
<button type="submit" id="submit" class="btn">Login</button>
<button type="button" class="btn cancel" onclick="closeForm();">Close</button>
</form>
<div class="d-inline">
<button class="btn-info">#Html.ActionLink("User Registration", "SignUp", "SignUp_SignIn")</button>
</div>
</div>
Then the ajax call is
$(document).ready(function () {
$("form").on('submit', function (event) {
var data = {
'email': $("#email").val(),
'psw': $("#psw").val()
};
$.ajax({
type: "POST",
url: 'SignUp_SignIn/CredentialCheck',
data: data,
success: function (result) {
if (result == true) {
$("#message").text("Login attempt was successful");
}
else {
$("#message").text("Email/Password didn't match any results");
}
},
error: function () {
alert("It failed");
}
});
return false;
});
});
After looking at the comments I realized that the reason that the login form was being called from the layout.cshtml so when the ajax call was being called it was grabbing all the form tags that existed on any page that was loaded up. After changing the ajax so it was calling a specific id for the login form instead of form it allowed for proper actions to take place.
An example of what I'm refusing to
$(document).ready(function () {
$("form").on('submit', function (event) {
$.ajax({
type: "POST",
url: url,
data: data,
success: function (result) {
//Do stuff
}
});
});
});
The above will try to redirect you on the submit of any form that is loaded up, but if we go through and change the way it accesses the form like below then it will only work if the one specific form is submitted.
$(document).ready(function () {
$("#loginForm").on('submit', function (event) {
$.ajax({
type: "POST",
url: url,
data: data,
success: function (result) {
//Do stuff
}
});
});
});
I need your help on the following please:
I'm working on a Q&A website with laravel and I'm trying to make a stars rating system for the answers with ajax, here is the code:
Question view page which includes the answers:
//question code here
#foreach($answers->sortByDesc('created_at') as $answer)
<div>
<p>{{$answer->body}}</p></div>
<form method="POST" onsubmit="return saveRatings(this);">
#csrf
<input type="hidden" name="answer_id" value="{{$answer->id}}">
<input type="submit"></input>
<div class="starrr"></div> // Rating stars
</form>
Script:
<script>
$(function (){
var ratings = 0;
$(".starrr").starrr().on("starrr:change" , function(event , value){
var ratings = value;
});
});
function saveRatings(form){
var answer_id = form.answer_id.value;
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url : "{{route('rating')}}",
method : "POST",
data : {
answer_id:answer_id,ratings:ratings,
},
success:function(response){
alert (response);
}
});
return false;
}
</script>`
Route:
Route::post('rating', 'RatingController#store')->name('rating');
when I submit the form it doesn't direct me to the URL in the ajax request and throws an error msg :
The POST method is not supported for this route. Supported methods: GET, HEAD, PUT, PATCH, DELETE.
http://127.0.0.1:8000/questions/1
I'm creating a JSP/Servlet web application and I'd like to upload a file to a servlet via Ajax. How would I go about doing this? I'm using jQuery.
I've done so far:
<form class="upload-box">
<input type="file" id="file" name="file1" />
<span id="upload-error" class="error" />
<input type="submit" id="upload-button" value="upload" />
</form>
With this jQuery:
$(document).on("#upload-button", "click", function() {
$.ajax({
type: "POST",
url: "/Upload",
async: true,
data: $(".upload-box").serialize(),
contentType: "multipart/form-data",
processData: false,
success: function(msg) {
alert("File has been uploaded successfully");
},
error:function(msg) {
$("#upload-error").html("Couldn't upload file");
}
});
});
However, it doesn't appear to send the file contents.
To the point, as of the current XMLHttpRequest version 1 as used by jQuery, it is not possible to upload files using JavaScript through XMLHttpRequest. The common workaround is to let JavaScript create a hidden <iframe> and submit the form to it instead so that the impression is created that it happens asynchronously. That's also exactly what the majority of the jQuery file upload plugins are doing, such as the jQuery Form plugin (an example).
Assuming that your JSP with the HTML form is rewritten in such way so that it's not broken when the client has JavaScript disabled (as you have now...), like below:
<form id="upload-form" class="upload-box" action="/Upload" method="post" enctype="multipart/form-data">
<input type="file" id="file" name="file1" />
<span id="upload-error" class="error">${uploadError}</span>
<input type="submit" id="upload-button" value="upload" />
</form>
Then it's, with the help of the jQuery Form plugin, just a matter of
<script src="jquery.js"></script>
<script src="jquery.form.js"></script>
<script>
$(function() {
$('#upload-form').ajaxForm({
success: function(msg) {
alert("File has been uploaded successfully");
},
error: function(msg) {
$("#upload-error").text("Couldn't upload file");
}
});
});
</script>
As to the servlet side, no special stuff needs to be done here. Just implement it exactly the same way as you would do when not using Ajax: How can I upload files to a server using JSP/Servlet?
You'll only need an additional check in the servlet if the X-Requested-With header equals XMLHttpRequest or not, so that you know how what kind of response to return for the case that the client has JavaScript disabled (as of now, it is mostly the older mobile browsers which have JavaScript disabled).
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
// Return an Ajax response (e.g. write JSON or XML).
} else {
// Return a regular response (e.g. forward to JSP).
}
Note that the relatively new XMLHttpRequest version 2 is capable of sending a selected file using the new File and FormData APIs. See also HTML5 drag and drop file upload to Java Servlet and Send a file as multipart through XMLHttpRequest.
Monsif's code works well if the form has only file type inputs. If there are some other inputs other than the file type, then they get lost. So, instead of copying each form data and appending them to FormData object, the original form itself can be given to the constructor.
<script type="text/javascript">
var files = null; // when files input changes this will be initialised.
$(function() {
$('#form2Submit').on('submit', uploadFile);
});
function uploadFile(event) {
event.stopPropagation();
event.preventDefault();
//var files = files;
var form = document.getElementById('form2Submit');
var data = new FormData(form);
postFilesData(data);
}
function postFilesData(data) {
$.ajax({
url : 'yourUrl',
type : 'POST',
data : data,
cache : false,
dataType : 'json',
processData : false,
contentType : false,
success : function(data, textStatus, jqXHR) {
alert(data);
},
error : function(jqXHR, textStatus, errorThrown) {
alert('ERRORS: ' + textStatus);
}
});
}
</script>
The HTML code can be something like following:
<form id ="form2Submit" action="yourUrl">
First name:<br>
<input type="text" name="firstname" value="Mickey">
<br>
Last name:<br>
<input type="text" name="lastname" value="Mouse">
<br>
<input id="fileSelect" name="fileSelect[]" type="file" multiple accept=".xml,txt">
<br>
<input type="submit" value="Submit">
</form>
$('#fileUploader').on('change', uploadFile);
function uploadFile(event)
{
event.stopPropagation();
event.preventDefault();
var files = event.target.files;
var data = new FormData();
$.each(files, function(key, value)
{
data.append(key, value);
});
postFilesData(data);
}
function postFilesData(data)
{
$.ajax({
url: 'yourUrl',
type: 'POST',
data: data,
cache: false,
dataType: 'json',
processData: false,
contentType: false,
success: function(data, textStatus, jqXHR)
{
//success
},
error: function(jqXHR, textStatus, errorThrown)
{
console.log('ERRORS: ' + textStatus);
}
});
}
<form method="POST" enctype="multipart/form-data">
<input type="file" name="file" id="fileUploader"/>
</form>
This code works for me.
I used Commons IO's io.jar, Commons file upload.jar, and the jQuery form plugin:
<script>
$(function() {
$('#upload-form').ajaxForm({
success: function(msg) {
alert("File has been uploaded successfully");
},
error: function(msg) {
$("#upload-error").text("Couldn't upload file");
}
});
});
</script>
<form id="upload-form" class="upload-box" action="upload" method="POST" enctype="multipart/form-data">
<input type="file" id="file" name="file1" />
<span id="upload-error" class="error">${uploadError}</span>
<input type="submit" id="upload-button" value="upload" />
</form>
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart) {
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
try {
// Parse the request
List items = upload.parseRequest(request);
Iterator iterator = items.iterator();
while (iterator.hasNext()) {
FileItem item = (FileItem) iterator.next();
if (!item.isFormField()) {
String fileName = item.getName();
String root = getServletContext().getRealPath("/");
File path = new File(root + "../../web/Images/uploads");
if (!path.exists()) {
boolean status = path.mkdirs();
}
File uploadedFile = new File(path + "/" + fileName);
System.out.println(uploadedFile.getAbsolutePath());
item.write(uploadedFile);
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
I'm getting Cannot read property 'router' of undefined with the code below.
this.transitionTo('home') is bugging, and I'm guessing it's because of the context of this. I tried binding the ajax call to this, and it didn't help either.
Any thoughts on how to simply redirect to either 'home' or '/' after this successful ajax call?
I've tried both the Navigation (transitionTo) and the History (this.pushState) mixins.
Edit: In the meantime I found a hacky working solution that uses a page refresh. Within the ajax .done section:
history.pushState({},'','/')
window.location.reload()
Code:
var Router = ReactRouter;
var Route = ReactRouter.Route;
var Routes = ReactRouter.Routes;
var Navigation = ReactRouter.Navigation;
var History = ReactRouter.History;
var Login = React.createClass({
mixins: [ History ],
mixins: [ Navigation ],
getInitialState: function(){
return{
email: "",
password: ""
}
},
submit: function(e){
e.preventDefault()
var data = {
email: this.state.email,
password: this.state.password,
}
// Submit form via jQuery/AJAX
$.ajax({
type: 'POST',
url: '/sessions',
data: data
})
.done(function(data) {
App.logIn(data.email)
alert('login successful!')
this.transitionTo('home')
// this.history.pushState(null, '/home')
// this.pushState(null, '/home')
})
.fail(function(data) {
alert('No Such Email or Incorrect Password')
});
},
handleEmailChange: function(event) {
this.setState({email: event.target.value});
},
handlePasswordChange: function(event) {
this.setState({password: event.target.value});
},
render: function(){
return(
<div>
Login To Your Account
<br/>
<form onSubmit={this.submit} >
Email: <input label="Email:" onChange={this.handleEmailChange} />
<br/>
Password: <input label="Password:" type="password" onChange={this.handlePasswordChange} />
<button type="submit">Submit</button>
</form>
</div>
)
}
})
Your context is changing in the inner function. The easiest way (in my opinion) to fix this is to place var _this = this in your outer function, then use _this.transitionTo in your callback.
I am running a Laravel 5 application that has its main view rendered using React.js. On the page, I have a simple input form, that I am handling with Ajax (sending the input back without page refresh). I validate the input data in my UserController. What I would like to do is display error messages (if the input does not pass validation) in my view.
I would also like the validation errors to appear based on state (submitted or not submitted) within the React.js code.
How would I do this using React.js and without page refresh?
Here is some code:
React.js code:
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
var SignupForm = React.createClass({
getInitialState: function() {
return {email: '', submitted: false, error: false};
},
_updateInputValue(e) {
this.setState({email: e.target.value});
},
render: function() {
var text = this.state.submitted ? 'Thank you! Expect a follow up at '+email+' soon!' : 'Enter your email to request early access:';
var style = this.state.submitted ? {"backgroundColor": "rgba(26, 188, 156, 0.4)"} : {};
return (
<div>
{this.state.submitted ? null :
<div className="overall-input">
<ReactCSSTransitionGroup transitionName="example" transitionAppear={true}>
<input type="email" className="input_field" onChange={this._updateInputValue} ref="email" value={this.state.email} />
<div className="button-row">
<a href="#" className="button" onClick={this.saveAndContinue}>Request Invite</a>
</div>
</ReactCSSTransitionGroup>
</div>
}
</div>
)
},
saveAndContinue: function(e) {
e.preventDefault()
if(this.state.submitted==false) {
email = this.refs.email.getDOMNode().value
this.setState({email: email})
this.setState({submitted: !this.state.submitted});
request = $.ajax({
url: "/user",
type: "post",
data: 'email=' + email + '&_token={{ csrf_token() }}',
data: {'email': email, '_token': $('meta[name=_token]').attr('content')},
beforeSend: function(data){console.log(data);},
success:function(data){},
});
setTimeout(function(){
this.setState({submitted:false});
}.bind(this),5000);
}
}
});
React.render(<SignupForm/>, document.getElementById('content'));
UserController:
public function store(Request $request) {
$this->validate($request, [
'email' => 'Required|Email|Min:2|Max:80'
]);
$email = $request->input('email');;
$user = new User;
$user->email = $email;
$user->save();
return $email;
}
Thank you for your help!
According to Laravel docs, they send a response with 422 code on failed validation:
If the incoming request was an AJAX request, no redirect will be
generated. Instead, an HTTP response with a 422 status code will be
returned to the browser containing a JSON representation of the
validation errors
So, you just need to handle response and, if validation failed, add a validation message to the state, something like in the following code snippet:
request = $.ajax({
url: "/user",
type: "post",
data: 'email=' + email + '&_token={{ csrf_token() }}',
data: {'email': email, '_token': $('meta[name=_token]').attr('content')},
beforeSend: function(data){console.log(data);},
error: function(jqXhr, json, errorThrown) {
if(jqXhr.status === 422) {
//status means that this is a validation error, now we need to get messages from JSON
var errors = jqXhr.responseJSON;
var theMessageFromRequest = errors['email'].join('. ');
this.setState({
validationErrorMessage: theMessageFromRequest,
submitted: false
});
}
}.bind(this)
});
After that, in the 'render' method, just check if this.state.validationErrorMessage is set and render the message somewhere:
render: function() {
var text = this.state.submitted ? 'Thank you! Expect a follow up at '+email+' soon!' : 'Enter your email to request early access:';
var style = this.state.submitted ? {"backgroundColor": "rgba(26, 188, 156, 0.4)"} : {};
return (
<div>
{this.state.submitted ? null :
<div className="overall-input">
<ReactCSSTransitionGroup transitionName="example" transitionAppear={true}>
<input type="email" className="input_field" onChange={this._updateInputValue} ref="email" value={this.state.email} />
<div className="validation-message">{this.state.validationErrorMessage}</div>
<div className="button-row">
<a href="#" className="button" onClick={this.saveAndContinue}>Request Invite</a>
</div>
</ReactCSSTransitionGroup>
</div>
}
</div>
)
}