update twig for loop in ajax - php

I'm doing chatroom project, and trying to update user status with ajax.
the problem is that a user may have multiple friends, so first i use twig for loop to show all friends, like this, function getLastActivity() is to get user's last online time, if it is bigger than current time, then show the user is online.
{% for user in users%}
{% if app.user.name != user.getName() %}
<div id="status">
{% if getLastActivity(user.getId()) > date("now + 8 hours - 10 seconds") %}
<span class="online_icon"></span>
{% else %}
<span class="online_icon offline"></span>
{% endif %}
</div>
{% endif %}
{% endfor %}
i am not really good at ajax, if there is something strange please let me know. my idea is to update status field every 3 sec. but it can only update the first friend.
My guess is that because, in twig template i only write one time, so it didn't update the rest of the friends.
$(document).ready(function () {
setInterval(function(){
update_status();
}, 3000);
function update_status()
{
$.ajax({
success:function(){
$('#status').load(" #status");
}
})
}
})
i have inspired by this article, Change Twig Template variable with AJAX, but not sure how to implement this in my problem.
my question is, is it possible to use ajax to update all the friends status, or there is a better way to achieve this.
thanks

The problem you have is that you create an element for each user with the ID status. An ID is a unique identifier, yet you use the same for each element.
What you could do is, for example, create the element with the id based on the user obj:
{% for user in users%}
{% if app.user.name != user.getName() %}
<div id="status-{{ user.id }}">
{* ... *}
</div>
{% endif %}
{% endfor %}
I don't know what exactly your update_status() function looks like, but you will need to get the user ID somehow. You can either return it in for the ajax, like so:
$.ajax({
success: function(userId){
$('#status-' + userId).load(" #status");
}
})
or you loop over all elements and you will have the id using el.attr('id').

Related

Limit, pagination in Symfony

I am trying to add pagination to my current project. I am pretty new to Symfony so I am not sure if there is something out there that can help me build such. My current code looks like this:
Controller class:
class MovieDisplayController extends Controller
{
public function showAction()
{
$movies = $this->getDoctrine()->getEntityManager()->getRepository('AppBundle:Movie')->FindAll();
return $this->render('movies/index.html.twig', array(
'movies' => $movies
));
}
}
Twig template:
{% block body %}
{% if movies|length == 0 %}
There are no movie items available. Add a movie here to get started.
{% elseif movies|length != 0 %}
These are the results: <br />
<ul>
{% for x in movies %}
<li>Title: {{ x.title }} - Price: {{ x.price }} - Edit - Details - Delete</li>
{% endfor %}
</ul>
Add more movie entries
{% endif %}
{% endblock %}
This will return all results within the database. I would like to only show 5 results (rows per page) and add paging buttons below the list and I wonder how/if this is possible?
The findAll() function will not work if you want to set limit.
You can try KnpPaginatorBundle to add pagination in symfony. It will work with fine to add pagination.
https://github.com/KnpLabs/KnpPaginatorBundle

Name of Twig variable in a Twig variable

I get a list of collections right from Doctrine and I store them into an array.
For example:
$data['collList'] = $heyDoctrine->giveMeMyColls();
But I also want to retrieve some informations about these collections.
I store it into $data['collectionId'].
Until this point, everything works fine.
But in my Twig template, I want to create ordered lists with the name of my collection and every item of this list would be an information about this collection.
So, in PHP, I would do this:
foreach($data['collList'] as $collItem){
echo $collItem['name'];
echo '<ul>';
foreach($data[$collItem['id']] as $collItemData){
echo '<li>'.$collItemData.'</li>';
}
}
My problem is: how to do this with Twig?
I don't know how to say to Twig «hey, use «coll.id» as THE NAME of an other variable!
I've looked a bit and I've found the «attribute» function, but I wasn't able to make it work.
How should I do that?
Thanks a lot.
So, try next twig code:
{% for key, collItem in data.collList %}
{{ collItem.name }}
<ul>
{% for collItemData in data[collItem.key] if key == 'id' %}
<li> {{ collItemData }} </li>
{% endfor %}
</ul>
{% endfor %}

Django unique URL redirection issue

Having issues trying to redirect after from submission to edit more fields
Also with creating the hyperlink to the submission.
When submitting my form with the redirect i get the error below.
If i submit the form with the render request to another page the form saves ok.
Request Method: POST Request
URL: http://127.0.0.1:8000/resourcelib/add_pricebook Django
Version: 1.8.4 Exception Type: NoReverseMatch Exception Value:
Reverse for 'detail_pricebook' with arguments '()' and keyword
arguments '{'p_id': 22L}' not found. 0 pattern(s) tried: []
My Model.py
class PriceBook(models.Model):
pricebook_id = models.AutoField(primary_key=True)
pricebook_name = models.CharField(max_length=255,verbose_name='PriceBook Name')
discription = models.TextField(verbose_name='Discription')
date_created = models.DateTimeField(auto_now_add=True, blank=True)
active = models.SmallIntegerField(max_length=1, blank=True)
def __unicode__(self):
return self.pricebook_name
view.py
def new_pricebook(request):
if request.method == "POST":
pricebook_form = PricebookForm(request.POST)
if pricebook_form.is_valid():
post = pricebook_form.save(commit=False)
post.save()
#return render(request, 'resourcelib/thanks.html',)
return redirect('detail_pricebook', p_id=post.pricebook_id)
else:
pricebook_form = PricebookForm()
return render(request, 'resourcelib/pricebook_add.html', {'pricebook_form': pricebook_form})
def detail_pricebook(request, p_id):
pricebook_from = get_object_or_404(PriceBook, pk=p_id)
return render(request, 'resourcelib/pricebook_detail.html', {'pricebook_from':pricebook_from})
url.py
url(r'^add_pricebook', views.new_pricebook, name='new_pricebook'),
url(r'^list_pricebook', views.list_pricebook, name='list_pricebook'),
url(r'^detail_pricebook/(?P<p_id>[0-9]+)/$', views.detail_pricebook, name='detail_pricebook'),
I don't believe it's in url file, because i get no errors if i browse to the entry eg.
127.0.0.1:8000/resourcelib/detail_pricebook/3/ - works ok
However i can't get my links working either, i can list my entries ok. But the link won't work from the code below when you click on the link it just comes up 127.0.0.1:8000/resourcelib/%7B%%20url%20'detail_pricebook'%20p_id.pk%7D
{% if pricebooks %}
<ul>
{% for pricebook in pricebooks %}
<li><h1>{{ pricebook.pricebook_name }}</h1></li>
{% endfor %}
</ul>
{% else %}
<p>No price books have been created.</p>
{% endif %}
{% endblock %}
Any help would be greatly appreciated
% missing in the url tag. Be more careful.
thanks #ozgur, have the the idea that i have the wrong reference for the pk. I was able to sort out the issue. I had a name name space on the primary project urls.py ... probably information i should have give, forgot I used cookiecutter for this one
url(r'^resourcelib/', include('oneworksite.resourcelib.urls', namespace='resource')),
so i was then able to get the link working with
{{ pricebook.pricebook_name }}
Then in my redirect i changed to
return redirect('resource:detail_pricebook', p_id=post.pk)

Symfony2 render form for each list item

How could I achieve a form for each list item using csrf and validation in symfony way?
I have a Task entity, which has comments property with a relation OneToMany. So I want to list all tasks and include a hidden comment form for every task. Usually I pass generated forms from controller to template, but how to create them dinamically in template?
{% for task in tasks %}
<taskinfo>
<task comment form>
{% endfor %}
Solved using this way:
In controller:
$forms = array();
foreach($tasks as $task) {
$entity = new TaskComment();
$forms[$task -> getId()] = $this ->createTaskCommentForm($entity, $task -> getId());
}
return $this->render('Bundle:blah:index.html.twig', array(
....
'forms' => $forms
));
An then comment box near every Task box in view:
...task info...
{% for task in tasks %}
<div class="comment-box">
{{ form(forms[task.id]) }}
</div>
{% endfor %}
P.S. I'm using collapsible panels to show/hide each task.
Maybe you need to embed a collection of forms? If so, here and here you can read more.

Silex: Redirect with Flash Data

I need to redirect one page to another with a message in Silex. Hopefully there's a Laravelesque way of doing it, but I highly doubt it:
$app->redirect('/here', 301)->with('message', 'text');
I'd then want to display the message in my template:
{{ message }}
If not, is there another way?
Update
I see there's a getFlashBag method in Symfony - is that what I'm supposed to use? Specifically, I am using the Bolt Content Management system.
Yes, FlashBag is the right way.
Set a flash message in your controller (you can add multiple messages):
$app['session']->getFlashBag()->add('message', 'text');
$app->redirect('/here', 301)
And print it in the template:
{% for message in app.session.getFlashBag.get('message') %}
{{ message }}
{% endfor %}
I created this simple FlashBagTrait that may be of use:
<?php
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
trait FlashBagTrait
{
/**
* #return FlashBagInterface
*/
public function getFlashBag() {
return $this['session']->getFlashBag();
}
}
Just add it to your Application class and it will make things ever-so-slightly easier!
$app->getFlashBag()->add('message',array('type'=>"danger",'content'=>"You shouldn't be here"));
{% if app.flashbag.peek('message') %}
<div class="row">
{% for flash in app.flashbag.get('message') %}
<div class="bs-callout bs-callout-{{ flash.type }}">
<p>{{ flash.content }}</p>
</div>
{% endfor %}
</div>
{% endif %}
Its main advantage is that type-hinting will work in PhpStorm.
You can also add it as a service provider,
$app['flashbag'] = $app->share(function (Application $app) {
return $app['session']->getFlashBag();
});
Which makes it more convenient to use from PHP (but you lose the type-hinting):
$app['flashbag']->add('message',array('type'=>"danger",'content'=>"You shouldn't be here"));

Categories