set jinja2 url_for as an href in getJSON callback - javascript

I am working inside a jquery, getJSON callback function using flask as my web framework.
I am trying to set the link desination for a dynamically created dom element. I want to set it to the jinja2 code for url_for. So, I would like to do something like this:
a.href ="{{ url_for('write_response', id=".concat(data.libArticles[i].id.toString(), ") }}");
I have had the worst time doing this. First, it would not recognize the "{{" and "}}" strings, removing them, opening quotes and doing other weird stuff because of those characters. Finally, by doing this:
var url1 = "{url_for('write_response', id=".concat(data.libArticles[i].id.toString(),")}");
var url2 ="{".concat(url1, "}");
a.href = url2;
it finally accepted the string with two instances of "{", so it accepted "{{somethig}}"
This still did not work and instead, when the link is clicked, it redirects to the following and fails :
http://localhost:5000/write_response/%7B%7Burl_for('write_response',%20id=3)%7D%7D
Does anyone know how to do this?

Your mixing up your python and javascript. Your first attempt failed, because your trying to execute javascript inside python. What's actually happening is everything, including the ".concat is being treated as the value for your id. Your second attempt is even more confused.
It's worth remembering that the python code gets executed on the server and then sent to the browser, the javascript gets executed after the fact in the browser. So the python/jinja code can't possibly know about the value of a javascript variable.
I think you should be able to do something like the following to get it to work:
var url = "{{ url_for('write_response') }}";
var id = encodeURIComponent(data.libArticles[i].id.toString());
url += '?id='+id;
Everything inside the set of {{ }} is considered jinja code, seperate from whatever is going on around it in the file. this should translate into the following in the browser:
var url = "/write-response";
var id = encodeURIComponent(data.libArticles[i].id.toString());
url += '?id='+id;
which should get you something like /write-response?id=12345
The encodeURLComponent(..) call just makes sure the value is url safe.

Related

set twig variable from json array

As twig renders prior to any javascript, I'm running into what feels like a minor problem.
I need to set a variable in twig that I receive from JSON array, but I'm running into some problems, and I feel like this should be simple.
The data is fed to twig through symfony through a json array, and renders different messages depending on one element in the array; this part works without trouble.
I am able to print the output to the twig file; that works fine. The problem is that I'm having a hard time setting this to a twig variable so that I can use it in a few places.
This works fine:
$('.id').html(items[0].id);
and prints out to the twig here correctly:
<div class="id"></div>
I tried to do do something like this:
{% set requestid = '<div class="id"></div>' %}
{{ requestid }}
But as expected this simply rendered the HTML without the value.
I've been attempting to do something like this:
In the twig I have this:
{% set requestid = "request_holder" %}
{{ requestid }}
And in the jquery I have something like this:
var reqid = items[0].id;
reqid.replace("request_holder",reqid);
I also attempted something like this
var request_id = items[0].id;
window.location = request_id.replace("request_holder",request_id)
I feel like I'm missing a small piece.
**Edit for clarity **
The JSON array is being parsed by jquery.
I have the value of items[0].id
Additional edit here - to make it clear that I was confused: cleaning up a little so as not to send future readers down the wrong path
I believe[d] that the variable needs to be assigned in the javascript because the twig, which is php, is generated prior to the javascript.
I have been attempting to generate the twig in the javascript to no avail.
Here's what I have been attempting:
var requestitem = items[0].id;
$('.id').html("{% set requestId = " + requestitem + " %} <br/> {{ requestId }}");
This defines requestId as a string and is only returning + requestitem + onto the page.
When I attempt this (without the quotations)
var requestitem = items[0].id;
$('.id').html("{% set requestId = requestitem %} <br/> {{ requestId }}");
The twig does not recognize requestitem at all
I have attempted quoting out the twig brackets (e.g. "{" + "%" etc) but this of course only prints them onto the page and does not interpret them.
Twig processes on the server side. It takes variables and renders them as HTML and text. What gets displayed in the browser is just HTML / text / and Javascript. So your set requestid = "request_holder" and {{ requestid}} are just turned to text before they get to the browser.
After that, you have HTML and text on the front end which Javascript can interact with. If you need this id to change on the front end, it needs to be done in Javascript.
What are you using the id to do?
Thanks to the hint from ASOlivieri, I was able to realize what I was doing wrong. I'm putting this here in case anyone comes across this. I was simply looking for a way to create a variable and make it reusable (I didn't go into details as that seemed extraneous).
The data was only available in the JSON array, so any attempt to write it to a twig file would fail, quite simply because it had already been converted to HTML, so I was forced to find another solution,
I was able to keep the variable in a javascript as I had it before
var request_item = items[0].id;
As my original goal was to get the value to update the application through php, I simply needed to use this variable in an AJAX call, and pass it through the path I had wanted to use in twig. Here's a brief summary:
$('#mark-received').click(function()
{
var requestURL = "{{ path('my_path') }}";
jQuery.ajax({
url: requestURL,
type: 'GET',
data: {'id' : request_item},
success: function success(data, text, xhr){
$('#mark-received').addClass('hidden');
$('#received-canceled').removeClass('hidden');
$('header > .alerts').append( $('<div>Success Message</div>').addClass('alert alert-success'));
},
error: function error( xhr, status, err){
$('header > .alerts').append( $('<div>There is a problem. <div class="close">x</div></div>', err).addClass('alert alert-danger'));
}
})
});

Django URL using javascript to get client end information

My problem that I am trying to resolve is that I made an Ajax-autocorrect input feature and "onclick" of a button I get the value inside that input and attempt to make the page redirect to a Django URL.
Here is the URL inside my url.py file:
url(r'^groups/add-member/(?:/(?P<pk_group>[-\w]+))?/(?:/(?P<pk_member>[-\w]+))?/$', views.add_member, name='add-member')
inside the HTML I have this script:
<script>
function add_member(id){
var input=document.getElementById("myText").value
console.log(id) //Correctly gets ID #
console.log(input) //Correctly gets the name (string) of member instance
url = "{% url 'add-member' 0 zzzz %}".replace('0', id).replace('zzzz',input);
}
</script>
And the resulting error that I get is:
Reverse for 'add-member' with arguments '(0, '')' not found. 1 pattern(s) tried:
['flexfeed/groups/add-member/(?:/(?P<pk_group>[-\\w]+))?/(?:/(?P<pk_member>[-\\w]+))?/$']
I'm having trouble understanding my error. If anyone could suggest how to fix this issue or possibly suggest a difdferent approach to this particular problem I'd really appreciate it!
The end goal is that I want my page to redirect to my update view at the correct link!
Ok, so there is a problem with the order of what's happening. When Django renders your template it processes the tags. This happens before any javascript is called.
So you are trying to call the url with 0 and zzzz as the arguments. Django tries to fetch this and because the second argument is an empty variable here it doesn't match anything.
I would fix this by calling the url with two variables that are valid, then changing them with javascript.
url = "{% url 'add-member' 0 'change-team' %}";
url = url.replace(0, id).replace('change-team', input);
You might also be able to just put quotation marks around the zzzz.

How to pass javascript variable to Django template

This piece of code is a javascript variable which passes url to a callback function and clicking on certian part of a map renders associated views and subsequently the template "Country_Details.html"
var var_1 = "{% url 'County_Details' pk=1 %}"
In the given example, I have passed an argument, that was "pk=1" it work fine fetched the object associated with the "id" = 1.
def County_Details(request,pk):
C_Details = CountryDiseases.objects.filter(country__pk=pk)
return render(request, 'DATAPLO/Country_Details.html', {'C_Details': C_Details })
but I have a list of ids and I want a solutions that can replace the pk values dynamically according to clicks through a variable, say, "my_id".
Though i have tried many things but nothing is working for me. A very close thread as of mine, I found on web is given bellow.
Get javascript variable's value in Django url template tag
I have tried all the solution suggested but nothing is working.
How could I solve this problem.
Thanks
There's a couple things to know about django and templates and js.
1. All django code is server side. It is evaluated on the server BEFORE it gets to the end user.
2. All javascript is client side. It is evaluated AFTER it gets to the user.
3. Django template logic can be considered django code and therefor is also server side (evaluated BEFORE it gets to the end user).
4. You can intermix django template tags and js but only in templates that are rendered, not seperate js files. If you do this, realize that the django template logic is only dynamic on the server. It essentially acts as place holders that hold a single, value that, once on the client will never change. In other words, javascript cannot manipulate django template tag logic. but django template tag logic can manipulate javascript logic ONCE while being rendered by server.
That may not necessarilly be useful in this case but it might help a little with understanding.
So try this:
in mytemplate.html:
var url_option1 = "{% url 'my_url', pk = django_var_1, somevar = django_var_2, ... %}";
var url_option2 = "{% url 'my_url', pk = " + {{ django_var_1 }} + ", somevar = " + {{ django_var_2 }} + " %}";
I'm not sure if that first option will work syntactically. If so, use that and don't do the second one. Otherwise, I know that the second one will always work syntactically but doesn't look as clean. So if syntax works, use the first one.
For the second one, if {{ django_var_? }} returns a string, you will need to put single quotes around the " + {{ django_var_? }} + " like so:
var url_option2 = "{% url 'my_url', pk = '" + {{ django_var_1 }} + "', somevar = '" + {{ django_var_2 }} + "' %}";

Django: reverse parametrized url in JavaScript

let's say one of my urlpatterns looks like this.
url('^objects/update/(?P<pk>\d+)$', views.UpdateView.as_view(), name = 'update-object'),
I need to redirect user to the update page depending on the selected object (the list of objects is populated using Ajax). So I'd like to pass that named url pattern to the JavaScript, in order to build the actual url on the client side.
Example of what I want to achieve:
pass the name 'update-objects' to the function
get the actual url pattern, replace (?P<pk>..) with {pk}
pass the result to the javascript, resulting in : objects/update/{pk}
any tips?
thanks
to make it more clear: at the moment of rendering, I can't do url reverse because the PK is not known yet. I need to make kind of javascript-urlpattern which will later be converted to the real url (i.e. my JS code will replace {pk} part with the actual pk value)
The actual URL reversing must happen on the server side. There are several ways to do this, and the most elegant of these probably depends on how exactly your script and markup are set up for this. One thing I've done recently is to attach the URL to a logical element using HTML5 data attributes, which are easy to retrieve using jQuery. If you're not using jQuery, I'll leave it up to you to translate to pure JS. You haven't provided any code or specifics for your client-side, so I'm kind of shooting in the dark here, but maybe this will give you the idea:
Django HTML template:
<ul class="object-list">
{% for object in objectList %}
<li data-update-url="{% url update-objects object.pk %}">object.name</li>
{% endfor %}
</ul>
JS:
$('.object-list').on('click', 'li' function () {
var updateUrl = $(this).data('update-url')
...
});
It sounds like you need to make an additional ajax call once the object has actually been selected. Don't try and second guess your url.conf by trying to work out the url on the client side - you'd just be making trouble for yourself later. Wait till you can get a pk, then use django's reverse function to give you your url (doing anything else violates DRY).
How about creating a simple view that returns the url -
from django.core.urlresolvers import reverse
from django.http import HttpResponse, HttpResponseBadRequest
def get_url(request):
if request.is_ajax() and request.method == 'POST':
obj_id = request.POST['obj_id']
url = reverse('object-update', kwargs{'pk': obj_id})
return HttpResponse(obj_id)
return HttpResponseBadRequest()
Then write a javascript function that gets the url using an ajax call to your new view and then redirects. You'd call this function as soon as the object's been selected. I would suggest using JQuery to do this, pure javascript will require you to write more code, and probably write browser specific code (depending on your target). Also it supports dealing with django's csrf protection (you'll need to implement this for ajax calls if you haven't already).
var redirect = function(obj) {
$.ajax({
url: '/your-get-url-view/',
method: 'post',
data: {'obj_id': obj},
success: function(url){
window.location = url;
}
});
}
I'm afraid I don't know how you're getting from the selected object to the pk (For simplicity I've assumed it's available to the redirect function) - you may have to do some processing in the view to get there.
I haven't tested the above code, but it should give you an idea of what I'm suggesting.
Try this one:
Reverse method for generating Django urls
https://github.com/mlouro/django-js-utils
One more
https://github.com/Dimitri-Gnidash/django-js-utils
If you have a URL that only has one PK field in it, you could resolve it with any number (e.g. 0), then substitute the number as required.
In my scenario my URL had a pk then an upload_id, so I had to replace on the right most instance of a 0, with <upload_id>, which the JS would replace this string occurance as required:
detele_url_upload_id_0 = reverse(f'{APP_NAME}:api_upload_delete', args=[pk, 0])
prefix, suffix = detele_url_upload_id_0.rsplit('0', 1)
context['generic_delete_url'] = prefix + '<upload_id>' + suffix
Then in the JS:
const deleteUrl = genericDeleteUrl.replace('<upload_id>', uploadId)

how to assign a javascript variable to a jsp string variable?

i m doing a database project using mysql as the database and jsp for my frontend part along with javascript and ajax for interaction.
Now the problem is i need to assign a java script variable which is having a string to a jsp variable.
I did this using the following statement?
<% String str="document.write(s)"; %>
where "s" is already defined as
<script type="text/javascript">
var s="hello world";
<script>
but i m getting error in the assignment statement(which is shown in bold above) as incorrect syntax?
the error i m getting is-
check the manual that corresponds to your MySQL server version for the right syntax to use near '<script>document.write(s)</script>'
what is the error in this stmt or is there any other method in doing this assignment?
Can anyone help in doing this?
You cannot do this. The JSP statement is executed server-side, before the execution of the Javascript statement, that is executed client-side after the browser received the http response.
It is not clear your goal, but if you only need to display in the page the value of a javascript variable, you can use:
trivial javascript:
document.write(s);
targeting existing element:
document.getElementById('myElementId').innerHTML = s;
using jQuery:
$('#myElementId').html(s);
If i understand correctly you are trying to build and execute a sql query based on user input that is handled by javascript. As ADC said this can not be done since jsp is executed server side therefore before browser executes javascript. What you can do is create the sql query and pass this as a parameter a different jsp/servlet (or the same if you can handle this case) which will execute the query
In the first page where sql statement is constructed in variable s you should put something like this
<script>
var s = "hello world";
function createLink(){
document.getElementById('mylink').href= 'page2.jsp?statement='+s;
}
window.onload=createLink;
</script>
<a id="mylink" href=""/>Click to exexute query</a>
which create a link to you second page (page2.jsp) passing the statement as parameter.
Now in page2.jsp you should retreive the parameter value like
<% String statement = request.getParameter("statement") %>
and then execute your query.
Even better you should use a servlet instead of a jsp page to perform the query. You could read a tutorial for jsp/sevlets to see how this can be done
eg. http://www.laliluna.de/articles/posts/first-java-servlets-jsp-tutorial.html

Categories