From my controller I send several parameters in my html.twig, then I want to make a AJAX request like this one :
{% if text is defined %}
var text = {{ text }};
var sender = {{ sender }};
var date_send = {{ date_send|date('d/m/Y') }};
var mess_type = {{ mess_type }};
var to = {{ to }};
$.post('send.php', {text:text, sender:sender, date_send:date_send, mess_type:mess_type, to:to}, function(data)
{
$('#Map').text(data);
});
{% endif %}
SO when I do that, I have this error :
POST http://localhost:8000/send.php 500 (Internal Server Error)
My send.php is where my html.twig is. I just have an echo "hi" in my send.php for testing, but it does not display anything.
I also tried to put a send function in my controller :
/**
* #Route("/send.php", name="send")
*/
public function send(Request $request) {
dump("hi");
echo "send";
return null;
}
And I replace 'send.php' by {{path('send.php')}} inside my html.twig (inside $.post()).
I know I can't return null, but It does not display my dump. And I have this error :
An exception has been thrown during the rendering of a template ("Unable to generate a URL for the named route "/send" as such route does not exist.")
And it does not get me to /send.php. I don't know what can I miss, I didn't find any solution on google. Thank for your help.
A controller's method should return a Response object so try this:
/**
* #Route("/send.php", name="send")
*/
public function send(Request $request)
{
return new Response('send');
}
The twig path function need the route name instead of the path, so try the following:
{{path('send')}}
Hope this help
NB: I order to identify the real error message, try put the url in the browser and see what happen
Related
I would like to pass some data from my Python view function to a JS script using HTML. That's my view function
def home(request):
if request.method == 'POST':
params = GameOfLifeForm(request.POST)
if params.is_valid():
starting_grid = get_starting_grid(params.cleaned_data)
to_html = {
'animation': True,
'gameoflifeform': params,
'start_grid': starting_grid,
}
else:
to_html = {
'animation': False,
'warning_msg': 'Something went wrong. Try once again.'
}
return render(request, 'get_animations/home.html', to_html)
else:
form = GameOfLifeForm()
return render(request, 'get_animations/home.html', {'gameoflifeform': form})
My form contains four parameters, one of them is called iterations and that is the one I would like to pass to JS script. Moreover I would like to pass start_grid.
I tried to do it in the following way in my HTML file
{{ start_grid | json_script:"start-grid" }}
<script
type="text/javascript"
src="{% static 'js/runGameOfLife.js' %}"
></script>
Then in my JS script I wrote
var startGrid = JSON.parse(document.getElementById("start-grid").textContent);
console.log(startGrid);
Worked perfectly, I got the grid printed out in my console. Similar I could grab iterations from HTML
{{ gameoflifeform.iterations.value | json_script:"iterations"}}
<script
type="text/javascript"
src="{% static 'js/runGameOfLife.js' %}"
></script>
When I tried to add both variables into my JS script it didn't work.
{{ gameoflifeform.iterations.value | json_script:"iterations"}}
{{ start_grid | json_script:"start-grid" }}
<script
type="text/javascript"
src="{% static 'js/runGameOfLife.js' %}"
></script>
How can I pass several variables into my JS script? What would be the best way of doing it?
Best to use some combination of ajax and view functions, if you learn this pattern you can accomplish a lot:
views.py
def my_view_function(request):
''' this method accepts data from the front end,
processes it, and returns a response '''
# unpack post request:
first_value = request.POST.get('first_key')
# do some logic:
...
# pack response
response = {
"second_key" : "second_value"
}
# return a json response:
return JsonResponse(response)
scripts.js
function post_request() {
/* set an event to trigger this method
this method will then send data to the backend
and process the response */
// send an ajax post request:
$.ajax({
type : 'POST',
url : 'the_url',
data : {
first_key : 'first_value'
},
success : function(response) {
// unpack response
second_value = response.second_key
// do some logic
...
}
});
}
Once you understand this, you will be able to seamlessly pass data back and forth between the frontend and backend. Let me know if you need more details.
I have a function in js file(exp : validateMyfile.js) that get a string parameter, this String has a value in myFile.properties and I need this value.
Now I want to get parameter value by spring message source.
How to use spring message source inside js file?
function validate(msg){
-- so I need msg value (value iside myFile.properties);
}
We normally read the message into a javascript variable in jsp file before passing it to a js function as follows
<%#taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<script type="text/javascript">
var successmsg = "<fmt:message key='message.key'/>";
function validate(){
alert(successmsg);
}
</script>
Sometimes, we also pass it as a message from the Controller for a ajax call.
#Controller
public class EmployeeController{
#Value("${employee.add.success}")
private String successMessage;
#Value("${employee.add.failure}")
private String failureMessage;
#ResponseBody
#RequestMapping("/addEmployee")
public String addEmployee(...){
...
if(added){
StatusObject status = new StatusObject();
status.setCode(..);
status.setMessage(successMessage);
}else{
StatusObject status = new StatusObject();
status.setCode(..);
status.setMessage(failureMessage);
}
//return status object
}
}
And access it as follows
$.ajax({
...
success: function(status){
$("#result").text(status.message);
}
});
I'm trying to use flask with url_for. The problem is that when I try to launch an alert with the value of the javascript variable everything seems ok, but when I try to launch a alert with the url_for the content of the variable is not printed. What I'm doing wrong? or What is missing in my code?
How can I pass a JavaScript variable into the url_for function?
html code:
<a class="dissable_user_btn" data-user_id="{{user.id}}" href="#" title="Change Status"><i class="fa fa-plug"></i>
</a>
JS Code:
<script type="text/javascript">
$(document).ready(function(){
$('.dissable_user_btn').click(function( event ) {
var user_id = $(this).data("user_id")
alert(user_id) //everything ok
alert ('{{url_for('.dissable', _id=user_id)}}'); //dont print the valur of user_id
</script>
Short answer: you can't. Flask & Jinja2 render the template on the server side (e.g. Flask is translating all of the {{ }} stuff before it sends the HTML to the web browser).
For a URL like this where you're including a variable as part of the path you'd need to build this manually in javascript. If this is an XHR endpoint I'd recommend using GET/POST to transfer the values to the server as a better best practice than constructing the URL this way. This way you can use Jinja:
$(document).ready(function(){
var baseUrl = "{{ url_for('disable') }}";
$('.dissable_user_btn').click(function(event) {
var user_id = $(this).data("user_id");
// first part = url to send data
// second part = info to send as query string (url?user=user_id)
// third parameter = function to handle response from server
$.getJSON(baseUrl, {user: user_id}, function(response) {
console.log(response);
});
});
});
I found another solution for this. My problem started when I needed to pass a variable with space.
First I created a function to remove trailing and leading spaces
function strip(str) {
return str.replace(/^\s+|\s+$/g, '');}
After that, I used the function and encoded the URL
<script type="text/javascript">
$(document).ready(function(){
$('.dissable_user_btn').click(function( event ) {
var user_id = $(this).data("user_id")
alert(user_id)
user_id = strip(user_id).replace(" ","%20");
alert ('{{url_for('.dissable', _id='user_id')}}.replace('user_id',user_id);
</script>
It worked pretty nice for me!
This is how I applied to my problem
<script>
function strip(str) {
return str.replace(/^\s+|\s+$/g, '');}
$(document).ready(function() {
$('#exportcountry').click(function() {
var elemento = document.getElementById("countryexportbtn");
var country = strip(elemento.textContent).replace(" ","%20");
$('#exportevent').load("{{ url_for('get_events',country = 'pais') }}".replace('pais',country));
});
});
</script>
I am getting an error saying unexpected token while trying for passing id from django template to reatjs for uploading multiple images to its associated foreign key object. The error is shown as unexpected token }. In depth it is shown as
in console
var uploadUrl = {
url:
};
What i am trying to do is , I have created a listing page with multiple form and it is entirely developed using reactjs. I want user to fill the data about room and upload multiple images related to their room. There are two models one with room info and another gallery(multiple image is associated with one rent). I wanted the uploaded images be associated with its rent so i coded it as below
urls.py
urlpatterns = [
url(r'^add/$', AddView.as_view(), name="add"),
url(r'^add/space/$', AddSpaceView.as_view(), name="addSpace"),
url(r'^upload/image/(?P<pk>\d+)/$', ImageUpload, name="ImageUpload"),
]
views.py
def ImageUpload(request,pk=None): // for saving images only to its asscoiated rent
if request.POST or request.FILES:
rental = Rental.objects.get(id=pk)
for file in request.FILES.getlist('image'):
image = GalleryImage.objects.create(image=file,rental=rental)
image.save()
return render(request,'rentals/add.html')
class AddView(TemplateView): // for listing page
template_name = 'rentals/add.html'
class AddSpaceView(View): // for saving data to database except image
def post(self,request,*args,**kwargs):
if request.POST:
rental = Rental()
rental.ownerName = request.POST.get('ownerName')
rental.email = request.POST.get('email')
rental.phoneNumber = request.POST.get('phoneNumber')
rental.room = request.POST.get('room')
rental.price = request.POST.get('price')
rental.city = request.POST.get('city')
rental.place = request.POST.get('place')
rental.water = request.POST.get('water')
rental.amenities = request.POST.get('amenities')
rental.save()
return HttpResponseRedirect('/')
listing.js(ajax code for uploading multiple image)
var image = [];
image = new FormData(files);
$.each(files,function(i,file){
image.append('image',file);
});
$.ajax({
url:"/upload/image/", // want to used id over here that is passed from add.html script tag so that image will be uploaded to its associated foriegn key object
data:image,
contentType:false,
processData:false,
type:'POST',
mimeType: "multipart/form-data",
success: function(data) {
console.log('success');
}
});
}
add.html page
<div id="listing">
</div>
{% include 'includes/script.html'%}
<script type="text/javascript">
var uploadUrl = {
url: {% for rental in object_list %} { "id": {{ rental.id }} } {% endfor %} // here is an error
};
console.log('url is', url);
$(function() {
app.showListingSpaceForm("listing");
});
</script>
The code might explained what i was trying to achieve. If models.py is also required for more scrutiny then i will update it.
You're missing a fundamental piece: TemplateView has no concept of object_list, you have to populate it yourself. If your view is simple enough use ListView and set your model property. If not, you have to manually populate the object list, something like this:
def get_context_data(self, **kwargs):
context['object_list'] = MyModel.objects.all()
That was just an example to set you on the right path.
I'm creating a social network site using Laravel. I have a page that load all the posts created by users the currentUser follows. I have a comment section on each post. I'm using ajax to post the comments.
Here is my code.
Here is the view of the comment-box. It contains a section where I loop through each comment and display them. At the end is the type field so a user can post a new comment:
<div class="comment-box-container ajax-refresh">
<div class="comment-box">
#if ($type->comments)
#foreach ($type->comments as $comment)
<div class="user-comment-box">
<div class="user-comment">
<p class="comment">
<!-- starts off with users name in blue followed by their comment-->
<span class="tag-user">{{ $comment->owner->first_name }} {{ $comment->owner->last_name }} </span>{{ $comment->body }}
</p>
<!-- Show when the user posted comments-->
<div class="com-details">
<div class="com-time-container">
{{ $comment->created_at->diffForHumans() }} ยท
</div>
</div>
</div><!--user-comment end-->
</div><!--user-comment-box end-->
#endforeach
#endif
<!--type box-->
<div class="type-comment">
<div class="type-box">
{{ Form::open(['data-remote', 'route' => ['commentPost', $id], 'class' => 'comments_create-form']) }}
{{ Form::hidden('user_id', $currentUser->id) }}
{{ Form::hidden($idType, $id) }}
{{--{{ Form::hidden('user_id', $currentUser->id) }}--}}
{{ Form::textarea('body', null, ['class' =>'type-box d-light-solid-bg', 'placeholder' => 'Write a comment...', 'rows' => '1']) }}
{{ Form::close() }}
</div><!--type-box end-->
</div><!--type-comment-->
</div><!--comment-box end-->
The user submit the form for the comment type box by pressing the "enter/return" key. Here is the JS for that
<script>
$(document).on('keydown', '.comments_create-form', function(e) {
if (e.keyCode == 13) {
e.preventDefault();
$(this).submit();
}
});
</script>
Here is my Ajax
(function(){
$(document).on('submit', 'form[data-remote]', function(e){
e.preventDefault();
var form = $(this)
var target = form.closest('div.ajax-refresh');
var method = form.find('input[name="_method"]').val() || 'POST';
var url = form.prop('action');
$.ajax({
type: method,
url: url,
data: form.serialize(),
success: function(data) {
var tmp = $('<div>');
tmp.html(data);
target.html( tmp.find('.ajax-refresh').html() );
target.find('.type-box').html( tmp.find('.type-box').html() );
tmp.destroy();
}
});
});
})();
When I post a comment on the first post it all works fine. However, when I post a comment on the second, third, fourth etc it only displays the comments from the first post. I have to manually refresh the page, then the correct comments will display.
I'll try to illustrate this problem with images.
Starting fresh, I can easily submit 2 comments on POST 1
http://s27.postimg.org/6ej76hunn/comment1.jpg
When I scroll down to Post 2, I see it already has a comment, I will submit a new comment
http://s23.postimg.org/x65ui2ryz/comment_2.jpg
HERE'S THE PROBLEM: When I submit the comment on POST 2, the comments that were in POST 2 disappears, and are replaced by the comments from POST 1.
http://s30.postimg.org/ugl08oz01/comment_3.jpg
The back end still worked, because when I reload the page everything is the way it should be
http://s9.postimg.org/w51fgyzen/comment_4.jpg
When I check the console Ajax is returning the entire page.
I'm completely stuck. Does anyone know why this is happening and how to fix it?
EDIT
Here is my controller that is loading the page with the posts:
public function index()
{
// load posts into the view.
$posts = $this->postRepository->getFeedForUser(Auth::user());
return View::make('newsfeed', compact('posts'));
}
The getFeedForUser() is this:
public function getFeedForUser(User $user)
{
// get a list of all the ids the user follows
$userIds = $user->followedUsers()->lists('followed_id');
// add in the current users posts as well
$userIds[] = $user->id;
// Resource is the posts
return Resource::with('messages', 'media', 'user', 'videos', 'comments', 'locations')->whereIn('user_id', $userIds)->latest()->get();
}
That Resource model has the relationship for the comments. It looks like this:
class Resource extends Eloquent {
public function comments()
{
return $this->hasMany('Duuer\Comments\Comment');
}
}
The route for saving a comment to the DB looks like this:
Route::post('post/{id}/comment', ['as' => 'commentPost', 'uses' => 'CommentsController#postComment']);
The CommentsController looks like this:
class CommentsController extends \BaseController {
use CommanderTrait;
/**
* Leave a new comment
* #return Response
*/
public function postComment()
{
extract(Input::only('user_id', 'resource_id', 'body'));
$this->execute(new PostCommentCommand($user_id, $resource_id, $body));
return Redirect::back();
}
public function deleteComment()
{
$comment = new Comment;
$user = Auth::user();
$id = Input::only('id');
$comment->where('user_id', $user->id)->where('id', $id)->first()->delete();
return Redirect::back();
}
}
I'm using a command bus, so my handler class looks like this:
public function handle($command)
{
$comment = $this->postRepository->leaveComment($command->user_id, $command->resource_id, $command->body);
return $comment;
}
That leaveComment() method looks like this:
public function leaveComment($user_id, $resource_id, $body)
{
$comment = Comment::leavePostComment($resource_id, $body);
User::findOrFail($user_id)->comments()->save($comment);
return $comment;
}
The leavePostComment() method in the Comment model looks like this:
public static function leavePostComment($resource_id, $body)
{
return new static([
'resource_id' => $resource_id,
'body' => $body
]);
}
You must submit the form but bind the keydown event on the input/textarea (better IMHO for you JS).
For your AJAX request, I recommand to get only a JSON, with Laravel, you can use if(Request::ajax()) and return only JSON instead of the whole page, then, you have just to append the new messages to the DOM.