I am trying to post my form data using Http post method in Angular 2 and receive that data in Java EE back end web service so this is my code for UserComponent:
export class UserComponent{
form : FormGroup;
output: string ;
public pro: Client[]=[];
constructor(private http: Http,public fb: FormBuilder,private ClientService: ClientService) {
this.form=this.fb.group({
userName : '',
password : '',
nom : '',
email : '',
phone : '',
adress : '',
});
}
This is my template code for UserComponent:
<md-card>
<form [formGroup]="form" class="form-group">
<md-input placeholder="Name" formControlName="name"></md-input><br>
<md-input placeholder="userEmail" formControlName="email"></md-input><br>
<md-input placeholder="userPhone" formControlName="phone"></md-input><br>
<md-input placeholder="username" formControlName="userName"></md-input><br>
<md-input placeholder="shippingAddress" formControlName="adress"></md-input><br>
<md-input placeholder="password" formControlName="password"></md-input><br>
</form>
<md-card>
<button (click)="onSubmit(form.value);" md-raised-button ">Create User</button>
</md-card>
for the userService:
sendInfo(value){
const body = new URLSearchParams(value);
body.set('Email', value.email);
body.set('name', value.name);
body.set('Address', value.adress);
body.set('Phone', value.phone);
body.set('password', value.password);
body.set('username', value.userName);
let headers = new Headers();
//headers.append('Content-Type', 'application/json');
headers.append('Content-Type', 'application/x-www-form-urlencoded');
return this.http.post('http://localhost:8080/BCWEB/AddUser',body.toString(), {
headers : headers
}).map(res => res.json());
}
Now for the backend Java EE web service:
#POST
#Path("/AjouterClient")
#Consumes("application/x-www-form-urlencoded")
public void post(
#FormParam(value="Clientnom")String nom ,
#FormParam(value="ClientEmail")String email,
#FormParam(value="ClientPhone")String tel ,
#FormParam(value="username")String adress ,
#FormParam(value="password")String username ,
#FormParam(value="shippingAddress")String password) {
metier.ajouterClient(new Client(nom,email,tel,username,password,adress));
}
Related
Each form's input is associated with a unique data-comment-pk. I'm trying to access the value of data-comment-pk of the input which is submitted. Currently, the AJAX success function's alert(comment_pk) is only fetching me the comment_pk of the first form. How can I access the comment_pk of the form which is submitted instead of getting the comment_pk of the first form?
html template
{% for comment in object_list %}
<h3>{{comment.comment}} by {{comment.username}}</h3>
<form class="score-form">
<input type="submit" value="Up" name="up" class="Up" data-comment-pk="{{comment.pk}}" />
<input type="submit" value="Down" name="down" />
</form>
{% endfor %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script>
$(".score-form").submit(function (e) {
e.preventDefault();
var comment_pk = $(".Up").attr("data-comment-pk");
var url = comment_pk + "/vote";
console.log(url)
$.ajax({
type: 'GET',
url: url,
data: { "up": 'UP' },
success: function (response) {
if (response["valid"]) {
alert(comment_pk);
}
},
error: function (response) {
console.log(response)
}
})
})
</script>
models.py
class CommentModel(VoteModel, models.Model):
comment = models.TextField()
username = models.ForeignKey(User, on_delete=models.CASCADE)
views.py
class CommentView(ListView):
model = CommentModel
def comment_vote(request, comment_id):
if request.is_ajax and request.method == "GET":
# do some stuff
return JsonResponse({"valid": True}, status=200)
Here is the solution to this problem :
var comment_pk = $(".Up", this ).attr("data-comment-pk");
Using this will return the current HTML element.
try: add "this" to before .Up in the comment_pk.
let me know if it works.
this- will get the currect form that have been submit and get the .Up Class
<script>
$(".score-form").submit(function (e) {
e.preventDefault();
var comment_pk = $("this .Up").attr("data-comment-pk");
var url = comment_pk + "/vote";
console.log(url)
$.ajax({
type: 'GET',
url: url,
data: { "up": 'UP' },
success: function (response) {
if (response["valid"]) {
alert(comment_pk);
}
},
error: function (response) {
console.log(response)
}
})
})
</script>
I am currently setting up a file upload with React for the frontend and Django for the backend. More specifically, I want to pass a file + some data to my database via an API.
But while uploading the file I get the error: "The submitted data was not a file. Check the encoding type on the form."
models.py (Django)
class Story (models.Model):
title = models.CharField(max_length=100,blank=False)
content = models.TextField(blank=False)
author = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
audio = models.FileField(default='SOME STRING', upload_to='audio_stories/',null=True, validators=[validate_file_extension_audio])
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('story-detail', kwargs={'pk': self.pk})
serializers.py (Django)
class StorySerializer(serializers.ModelSerializer):
class Meta:
model = Story
fields = '__all__'
A MultiPartParser is used to pass file + data.
api.py (Django)
class StoryViewSet(viewsets.ModelViewSet) (Django):
serializer_class = StorySerializer
parser_classes = (MultipartJsonParser, parsers.JSONParser)
queryset = Story.objects.all()
permission_classes = [
permissions.IsAuthenticated
]
def perform_create(self, serializer):
serializer.save(author=self.request.user)
utils.py (Django)
class MultipartJsonParser(parsers.MultiPartParser):
def parse(self, stream, media_type=None, parser_context=None):
result = super().parse(
stream,
media_type=media_type,
parser_context=parser_context
)
data = {}
# find the data field and parse it
data = json.loads(result.data["data"])
qdict = QueryDict('', mutable=True)
qdict.update(data)
return parsers.DataAndFiles(qdict, result.files)
In actions story.js (React)
import axios from "axios";
import { tokenConfig } from './auth';
import { createMessage, returnErrors } from "./messages";
import {ADD_STORY} from "./types";
const apiBase = "http://localhost:8000/api";
export const addStory = story => (dispatch, getState) => {
axios
.post(apiBase +"/story/", story, tokenConfig(getState))
.then(res => {
dispatch(createMessage({ addStory: "Story Added" }));
dispatch({
type: ADD_STORY,
payload: res.data
});
})
.catch(err =>
dispatch(returnErrors(err.response.data, err.response.status))
);
};
In components create_story.js (React)
import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { addStory } from "../../actions/story";
export class CreateStory extends Component {
state = {
title: "",
content:""
};
static propTypes = {
addStory: PropTypes.func.isRequired
};
onChange = e => this.setState({ [e.target.name]: e.target.value });
onSubmit = e => {
e.preventDefault();
const { title,content, audio} = this.state;
const story = { title, content, audio};
this.props.addStory(story);
this.setState({
title: "",
content:"",
audio:""
});
};
render() {
const {title, content, audio} = this.state;
return (
<div className="card card-body mt-4 mb-4">
<h2>Add Story</h2>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Title</label>
<input
className="form-control"
type="text"
name="title"
onChange={this.onChange}
value={title}
/>
</div>
<div className="form-group">
<label>Content</label>
<input
className="form-control"
type="text"
name="content"
onChange={this.onChange}
value={content}
/>
</div>
<div className="form-group">
<label>Audio</label>
<input
className="form-control"
type="file"
name="audio"
onChange={this.onChange}
value={audio}
/>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary">
Submit
</button>
</div>
</form>
</div>
);
}
}
export default connect(
null,
{ addStory }
)(CreateStory);
I'm having trouble tracing the error in my code. I assume that the react form does not provide the correct data format, i.e. formdata. But i dont know how and wehre to change this. Without the file upload I was able to successfully pass data to my database.
Many thanks.
Your onChange function in create_story.js is not gathering the file. You may need to reformat that function to something like:
onChange = (e) => {
if(e.target.name === 'audio') {
this.setState({
[e.target.name]: e.target.files[0]
}, () => console.log(this.state.audio))
} else {
this.setState({
[e.target.name]: e.target.value
}, () => console.log(this.state))
}
}
I have a home view with a form as footer to contact. Everything works fine, except that when there is some error in the form and the view redisplays everything with the corresponding errors, it doesn't keep the focus in the form (it shows the view as though you were entering for the first time, and so users can't see their form wasn't correct unless they scroll down).
I had thought of sending a message with JS, but it is really ugly.
I have tried with all the ways I have found to display errors ( raising them from different functions) but the problem persists.
Any idea?
Besides, even though I set required = False, the form keeps showing a message ("Complete this field") which I think comes from html, how can I remove it?
Thank you very much!
Code:
<form method="post">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.message.errors }}
<label for="{{ form.message.id_for_label }}">Your message:</label>
{{ form.message }}
</div>
<div class="fieldWrapper">
<strong>{{ form.mail.errors }}</strong>
<label for="{{ form.mail.id_for_label }}">Your email address:</label>
{{ form.mail }}
</div>
<div class="fieldWrapper">
{{ form.number.errors }}
<label for="{{ form.number.id_for_label }}">CC yourself?</label>
{{ form.number }}
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
class ContactForm(forms.Form):
mail = forms.CharField(required=False, label=_('Mail'))
number = forms.CharField(required=False, label=_('Number'))
message = forms.CharField(min_length = 0, max_length=500, label=_('Message'))
def clean_mail(self):
mail = self.cleaned_data['mail']
if '#' not in mail:
raise ValidationError({"mail": _('The mail should contain "#"')})
return mail
Any idea?
I have an idea using jquery validation plugin, but I'm not sure if you can use it in your project. It is very simple to integrate with django error messages (error_messages). Let me explain you.
First: Function in JavaScript to check if you need to send csrf:
function csrfSafeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
Second: Function in JavaScript if you need to show generic errors (non field errors) dynamically.
function showGenericErrors(errorMessages, id) {
len = errorMessages.length
if (len > 0) {
errorDiv = `
<div class="alert alert-danger alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>`;
for (var i = 0; i < len; i++) {
errorDiv += errorMessages[i];
errorDiv += (i === len-1) ? '' : '<br>';
}
errorDiv += '</div>';
$(errorDiv).insertAfter($('SOME_ELEMENT_OF_YOUR_PREFERENCE'));
}
}
Third: Django response with JsonResponse in your view (remember -> from django.http import Json response).
return JsonResponse({'messages': form.errors}, status=500, safe=False)
Fourth: Activating jquery validation plugin and handle your submit event with ajax to send data to Django for validation purpose.
form = $('form');
var $validator = $(form).validate({
rules: {
mail: {
required: true,
email: true
},
number: {
required: true,
minlength: 7,
maxlength: 15
},
message: {
required: true,
maxlength: 500
},
},
messages: {
mail: {
required: 'Mail required',
email: 'Invalid mail'
},
number: {
required: 'Number required',
minlength: 'Please enter at least {0} characters', //{0} will take the minlength specified in rules
maxlength: 'Please enter no more than {0} characters'
},
message: {
required: 'Message required',
maxlength: 'Please enter no more than {0} characters'
},
},
submitHandler: function(form) {
$('.alert').remove();
var formData = new FormData(form);
$.ajax({
url: 'contactus',
type: 'POST',
data: formData,
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader('X-CSRFToken', $('[name=csrfmiddlewaretoken]').val());
}
},
success: function(data) {
console.log(data);
},
error: function(xhr) {
console.log(xhr.responseJSON);
data = xhr.responseJSON;
if (data.messages) {
genericErrors = [];
fieldErrors = {};
for (var i in data.messages) {
if (i === '__all__') {
genericErrors = data.messages[i];
} else {
fieldErrors[i] = data.messages[i][0];
}
}
$validator.showErrors(fieldErrors);
showGenericErrors(genericErrors, id);
}
},
cache: false,
contentType: false,
processData: false
});
},
errorElement: "em",
errorPlacement: function(error, element) {
error.addClass("help-block");
if (element.prop("type") === "checkbox") {
error.insertAfter(element.parent("label"));
} else {
error.insertAfter(element);
}
},
highlight: function(element, errorClass, validClass) {
$(element).parents(".fieldWrapper").addClass("has-error").removeClass("has-success");
},
unhighlight: function(element, errorClass, validClass) {
$(element).parents(".fieldWrapper").addClass("has-success").removeClass("has-error");
}
});
i create Rest API for login in Django and i want to call it in angular4
heare is my angular4 code
login.components.ts
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { Http, Response, Headers} from '#angular/http';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
constructor(private router:Router, private http:Http) { }
getData = [];
with this function i get data from my APIand i am trying to compare this data with form data
fatchData = function(){
this.http.get("http://127.0.0.1:8000/loginAdmin/").subscribe((res:Response) => {
this.getData = res.json();
})
}
loginUser(e){
e.preventDefault();
var username = e.target.elements[0].value;
var password = e.target.elements[1].value;
if(username == 'this.getData.username' && password == 'this.getData.password')
{
this.router.navigate(['/deshbord'])
}
else{
console.log('Error Find');
}
}
ngOnInit() {
this.fatchData();
}
}
this is my login.comonents.login i want that when user give user name and password its compare with my API data and it's true then navigate to other page..
<form (submit)="loginUser($event)">
<div class="input">
<label>UserName</label>
<input type="text">
</div>
<div class="input">
<label>password</label>
<input type="password">
</div>
<div class="input">
<input type="submit" value="Login">
</div>
</form>
I am trying to make an AJAX request from my reactjs frontend to my django backend but I am getting this error upon POST. I'm not sure how to properly pass CSRF tokens around for my form POST to work properly
Forbidden (CSRF token missing or incorrect.): /api/contact
[05/Nov/2016 03:43:14] "POST /api/contact HTTP/1.1" 403 2502
I created a react component and added it into my form
CSRF component
import React from 'react';
import $ from 'jquery';
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = $.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const Csrf = () => {
let csrfToken = getCookie('csrftoken');
return (
<input type="hidden" name="csrfmiddlewaretoken" value={ csrfToken } />
);
};
export default Csrf;
Contact form component:
const ContactForm = ({ formOnChange, onFormSubmit, isFullNameValid, isEmailValid, isMsgValid }) => {
let rows = 10;
let tabindex = 8;
let isSubmitDisabled = !(isFullNameValid && isEmailValid && isMsgValid);
return(
<div className="form-wrapper">
<form className="contact-form" onChange={ formOnChange }>
<Csrf />
<input className={ isFullNameValid ? "" : "active" } type="text" name="fullname" placeholder="Full Name *" />
<div className="email-phone-group">
<input type="text" name="phonenumber" placeholder="Phone Number"/>
<input className={ isEmailValid ? "" : "active" } type="text" name="email" placeholder="Email *"/>
</div>
<textarea className={ isMsgValid ? "" : "active" } rows={ rows } tabIndex={ tabindex } name="message" placeholder="Message... *"/>
<button disabled={ isSubmitDisabled } className="contact-form-submit-btn" type="button" onClick={ onFormSubmit }>Submit</button>
</form>
</div>
);
};
My redux action calls this AJAX function
export function contactSubmission(contactSubmission) {
// thunk
return dispatch => {
console.log("contact form submitted");
console.log(contactSubmission);
$.ajax({
method: 'POST',
url: '/api/contact',
dataType: 'json',
success: payload => {
if (payload.error) {
return dispatch(contactSubmissionFailure());
} else {
return dispatch(contactSubmissionSuccess(payload));
}
},
error: payload => {
console.log("ajax error");
console.log(payload);
return dispatch(contactSubmissionFailure());
}
});
};
}
you should put the following code before $.ajax to send a CSRF code:
$.ajaxSetup({
headers: {"X-CSRFToken": getCookie("csrftoken")}
});
...THEN YOUR CODE
$.ajax({...});
You can notice that you have already set getCookie.
With this should work properly.