Symfony2: AJAX request returns full page html - javascript

I'm trying to get a simple AJAX request to work in Symfony2. It seems that the request is never reaching the controller. Instead of alerting the number '123', the AJAX request returns the HTML of the current page (index.html.twig). I have a feeling that since the pattern of the AJAX route is pointing to the current page I am on, the AJAX response is being filled with the output of the current page rather than getting the response from the Controller. Is there any way that I can get just the value from the Controller? Any help would be greatly appreciated.
Here is my Twig template (index.html.twig):
{% extends 'base.html.twig' %}
{% block body %}
<a href="123" class="test">Test</div>
{% endblock %}
{% block javascripts %}
{% javascripts '#AppBundle/js/jquery.js' %}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('.test').on('click', function(){
var id = jQuery(this).attr('href');
jQuery.post('{{path('task_ajax')}}',
{data: id},
function(response){
alert(response);
}
);
return false;
});
});
</script>
{% endblock %}
Here is my routing.yml file:
task_ajax:
pattern: /jobs
defaults: { _controller: AppBundle:Ajax:task }
requirements:
_method: POST
Here is my controller:
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class AjaxController extends Controller
{
public function taskAction() {
$request = $this->container->get('request');
$data = $request->query->get('data');
return new Response($data);
}
}

check routing order. Move Ajax route to first place.

Related

How to compare Django template language variables with javascript variables?

I've got something like this in my Django template:
<script>
var selected_direction = $("#id_direction").val();
{% for bus_stop in bus_stops %}
{% if bus_stop.direction == selected_direction %}
// Do something //
{% endif %}
{% endfor %}
</script>
I can do everything with bus_stops until it reaches the {% if %} statement. How can i compare javascript variable with django variable?
/Edit
Maybe the question was not constructed properly. However i solved my problem by doing this:
<script>
var selected_direction = $("#id_direction").val();
var temp_direction;
{% for bus_stop in bus_stops %}
temp_direction = "{{ stop.direction }}";
if (temp_direction == selected_direction){
////////
///////
}
{% endfor %}
</script>
you can compare this condition
{% if bus_stop.direction == selected_direction %}
by converting you template value to js value, and compare it in js if condition as follows.
if(selected_direction == '{{bus_stop.direction}}')
{
//code here
}
Here is a post that explains how they work together. There is a injection risk involved with this. Maybe make an ajax call for your data and do everything in javscript.

How to Embed multiple tweets of various users into HTML in django framework?

I am passing a data in the form of a dictionary from views.py to results.html in Django framework. The dictionary has the following format
'tweet': (tweet_analysis, tweet_id)
now in results.html, called by the views.py,
I am trying to Embed all the tweets that are passed to results.html, but the following code only displays one embedded tweet.
dicPositive: This is the dictionary containing all the tweets data
{% for tweet, tweet_feel in dicPositive.items %}
<div id="tweet" tweetID="{{tweet_feel.1}}"></div>
<script sync src="https://platform.twitter.com/widgets.js"></script>
<script>
window.onload = (function(){
var tweet = document.getElementById("tweet");
var id = tweet.getAttribute("tweetID");
twttr.widgets.createTweet(
id, tweet,
{
conversation : 'none', // or all
cards : 'hidden', // or visible
linkColor : '#cc0000', // default is blue
theme : 'light' // or dark
})
.then (function (el) {
el.contentDocument.querySelector(".footer").style.display = "none";
});
});
</script>
<!-- <li>{{tweet}} –> {{tweet_feel.0}} –> {{tweet_feel.1}}</li> -->
{% endfor %}
It is because you have used same id for multiple HTMLElements created while looping.
You must add loop counter to id attribute of div and also when
you are fetching it using getElementById inside script tag
{% for tweet, tweet_feel in dicPositive.items %}
<div id="tweet_{{forloop.counter}}" tweetID="{{tweet_feel.1}}"></div>
<script sync src="https://platform.twitter.com/widgets.js"></script>
<script>
window.onload = (function(){
var tweet = document.getElementById("tweet_{{forloop.counter}}");
# Rest of your code
...
</script>
{% endfor %}

Make an AJAX request to Flask application

I'm trying to refresh a Jenkins build console output in my Flask web application, however I am having trouble with the jQuery/AJAX to do it.
As you can see below, i'm just trying to get this working using a refresh button. Ideally I want to refresh {{buildinfo}} on a timer.
Currently my test function/jQuery is returning the error: Uncaught TypeError: Illegal invocation.
Heres the (working) function from my app.py I was using before I started down this path:
#app.route('/buildinfo/<job_id>/<job_number>', methods=['GET', 'POST'])
def buildInfo(job_id, job_number):
try:
console_output = server.get_build_console_output(job_id, int(job_number))
return render_template("buildinfo.html", buildinfo=console_output, job_id=job_id, job_number=job_number)
except Exception as e:
return render_template("buildinfo.html", error=str(e))
Here's the test function I have been using to receive the request and send back to the client:
#app.route('/_test')
def foo():
a = request.args.get('a', None, type=str)
b = request.args.get('b', 0, type=int)
bar = server.get_build_console_output(a, int(b))
return jsonify(result=bar)
And here is the buildinfo.html:
{% extends "base.html" %}
{% block content %}
<script type="text/javascript" src="{{ url_for('static', filename='jquery-1.12.0.min.js') }}"></script>
<script type="text/javascript">
var $SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
</script>
$(function() {
$('a#load').bind('click', function() {
$.getJSON($SCRIPT_ROOT + '/_test', {
a: $('{{job_id}}'),
b: $('{{job_number}}')
}, function(data) {
$("#result").text(data.result);
});
return false;
});
});
</script>
<div class="col-md-10">
<h1>Build Info</h1>
<br>
<p>retrieving {{job_id}}, build number {{job_number}}</p>
<br>
<p>{{buildinfo}}</p>
<br>
<span id="result">?</span>
go
</div>
{% endblock %}
You're feeding a HTML elements to the ajax call, when you should be passing values. Change this:
a: $('{{job_id}}'),
b: $('{{job_number}}')
to this:
a: {{job_id}},
b: {{job_number}},
...
I'm not sure about the types you're sending, if you need to send strings- wrap quotes around the double-moustache, but this should get you going. See here for a similar issue.
For anyone in the same boat, I am able to refresh a Flask value using the following. I may update this answer to include clearInterval() once the build is complete. Thanks to GG_Python for pointing out my mistake.
app.py :
#app.route('/buildinfo/<job_id>/<job_number>', methods=['GET', 'POST'])
def buildInfo(job_id, job_number):
try:
console_output = server.get_build_console_output(job_id, int(job_number))
return render_template("buildinfo.html", buildinfo=console_output, job_id=job_id, job_number=job_number)
except Exception as e:
return render_template("buildinfo.html", error=str(e))
#app.route('/_test')
def foo():
a = request.args.get('a', None, type=str)
b = request.args.get('b', 0, type=int)
bar = server.get_build_console_output(a, int(b))
return jsonify(result=bar)
buildinfo.html :
{% extends "base.html" %}
{% block content %}
<script type="text/javascript" src="{{ url_for('static', filename='jquery-1.12.0.min.js') }}"></script>
<script type="text/javascript">
var $SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
</script>
<script type="text/javascript">
setInterval(function() {
$.getJSON($SCRIPT_ROOT + '/_test', {
a: "{{job_id}}",
b: {{job_number}}
}, function(data) {
$("#result").text(data.result);
});
return false;
}, 3000);
</script>
<div class="col-md-10">
<h1>Build Info</h1>
<br>
<p>retrieving {{job_id}}, build number {{job_number}}</p>
<br>
<p id="result">{{buildinfo}}</p>
<br>
</div>
{% endblock %}

symfony twig javascript function undefined

I'm trying to use an external JS file in my twig. The goal is just to verify client's input.
When I put directly my script in my Transfert.html.twig , my script is well executed but when I used an external file with assetic nothing happen. The link created by assetic is good(I can see my script when i click on it in my web page source code).but firebug says
"SyntaxError: expected expression, got '<'
<script type="text/javascript">" "ReferenceError: verifyMontant is not defined"
I registred my bundle into app/config/config.yml:
" bundles: [FASTTransfertBundle]", so I guess no problem form here
Now this is my code: Transfert.html.twig:
{# src/FAST/TransfertBundle/Resources/views/Default/Transfert.html.twig #}
{% extends "FASTTransfertBundle::layout.html.twig" %}
{% block title %}{{ parent() }} - Index{% endblock %}
{% block body %}
{{ form_label(form.montant) }} {{ form_widget(form.montant,{'attr':{'onblur':'verifyMontant(this)'}}) }}
{% javascripts '#FASTTransfertBundle/Resources/public/javascript/verifyTransfert.js' %}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
And this is my javascript file :
<script type="text/javascript">
//color if wrong
function changeColor(field,error)
{
if(error)
field.style.backgroundColor = "#fba";
else
field.style.backgroundColor = "";
}
function verifyMontant(field)
{
var montant= field.value.replace(/\D+/g,'');
var regex = /^\-?[0-9]*\.?[0-9]+$/;
if(!regex.test(field.value)){
changeColor(field, true);
return false;
}
else if(montant.length != 11){
changeColor(field, true);
return false;
}
else{
changeColor(field,false);
return true;
}
}
</script>
You must remove
<script type="text/javascript">
from your javascript file.

Using Django Templates, how can I access values from my model in the JavaScript header?

Using Django, I can successfully read and display values from my model in the content segment of my template, but I can't get the values from my model in the head segment of my template.
Here's the code -->
view.py:
from django.shortcuts import render_to_response
from django.template import RequestContext
from host.models import Event
def EventSingle(request, slug):
return render_to_response('event.html', {'eventobject': Event.objects.get(slug=slug)})
event.html:
{% extends "base.html" %}
{% block extrahead %}
<script type="text/javascript" src="https://ajax.microsoft.com/ajax/jQuery/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
var variable1;
variable1="click worked";
//variable1={{ eventobject.datetime }};
$(document).ready(function () {
$("#pic").click(function (b) {
alert(variable1);
});
});
</script>
{% endblock %}
{% block content %}
<div id="eventobject">
<p>{{ eventobject }}</p>
<p>{{ eventobject.location }}</p>
<p>{{ eventobject.datetime }}</p>
<img id="pic" src="{{ eventobject.image1.url }}" />
</div>
{% endblock %}
When clicking on the image, an alert box pops up with the text "click worked", but if I comment out variable1="click worked"; and un-comment variable1={{ eventobject.datetime }}; nothing happens when I click on the image. Can I not use model references in the head section of django template? All other references to the model in the content block display the values from the DB properly.
I guess eventobject.datetime must be a string or python datetime object.
If it is a string, change your code to :
variable1= "{{ eventobject.datetime }}" ;
If it is a datetime object, use django template filter :
variable1= "{{ eventobject.datetime|date:"D d M Y" }}"
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
If you do not put the quotes, the javascript statement looks like:
variable1 = 2013-05-30 ;
which is INCORRECT javascript syntax, the quotes are needed.
Per Django docs, you can use a date filter to format date:
variable1= '{{ eventobject.datetime|date:"d-m-Y" }}';
Additionally, you can also set DATE_FORMAT (or DATETIME_FORMAT) setting to set a project-wide default for displaying such values.

Categories

Resources