I have a variable extracted in my Twig file which is the result of a selected :
<div class="col-sm-7">
<div class="product-information"><!--/product-information-->
<img src="images/product-details/new.jpg" class="newarrival" alt="" />
<h2>{{ produit.nom }}</h2>
<p>{{ produit.categorie.nomcat }}</p>
<p>{{ produit.description }}</p>
<span>
<span>€ {{ produit.prix}}</span>
</span>
<p>
<script>
function myFunction() {
var x = document.getElementById("co").value;
document.getElementById("demo").innerHTML = x;
}
</script>
<b>Couleur :</b>
<select id="co" onchange="myFunction()">
{% for coul in produit.couleur %}
<option value="{{ coul.nomc }}">{{ coul.nomc }}</option>
{% endfor %}
</select>
</p>
<p><b>Marque :</b> {{ produit.marque}}</p>
<p>
<a href="{{ path('ajouter', { 'id' : produit.id }) }}">
<button type="button" class="btn btn-fefault cart" >
<i class="fa fa-shopping-cart"></i>
Ajouter au Panier
</button>
</a>
</p>
</div><!--/product-information-->
i try to extract the selected item from the select by put it in a variable,
somthing like that : {% set var %} <p id=demo> </p>
when i put the variable {{ var }} i get the selected item in my screen
but when i put it in the path i get the problem :
the path is somthing like that : ../../../id/ /
he put the balise p not the value of my variable
I have tried : <a href="{{ path('ajouter', { 'id' : produit.id, 'coul' : {{ var }} }) }}">
you can use FOSJsRoutingBundle to generate routes on client side (right in JS)
Related
I'm working on a Symfony5 project and I want to call a JavaScript function and pass an Ajax Request (which I get from a controller) from a Twig.
i create a function phoneverif() in order to do some verification before the validation of form ..like doing a test if the fields are blanks then an alert will appears also the verification of the existence of data in db.
But a first, very simple test already failed, and an error appear :
Uncaught ReferenceError: phoneverif is not defined
onclick http://localhost:8000/super_admin/telephone/nouveau:1
here is my twig code :
{% extends 'superadmin.html.twig'%}
{% block body %}
<div class="container-fluid">
<!-- Page Heading -->
<h1 class="h3 mb-4 text-gray-800">Nouveau téléphone</h1>
</div>
<div class="col-md-12">
{% for flashMessage in app.session.flashbag.get('notice') %}
<div class="alert alert-success alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h4><i class="icon fa fa-check"></i>{{ flashMessage }}</h4>
</div>
{% endfor %}
<!-- general form elements -->
<div>
<!-- form start -->
{{ form_start(form)}}
<div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>{{ form_label(form.userGroup) }}</label>
{{ form_widget(form.userGroup) }}
<span class="text-danger">{{ form_errors(form.userGroup) }}</span>
</div>
<div class="form-group">
<label>{{ form_label(form.protocol) }}</label>
{{ form_widget(form.protocol) }}
<span class="text-danger">{{ form_errors(form.protocol) }}</span>
</div>
<div class="form-group">
<label>{{ form_label(form.extension) }}</label>
{{ form_widget(form.extension) }}
<span class="text-danger">{{ form_errors(form.extension) }}</span>
</div>
<div class="form-group">
<label>{{ form_label(form.dialplanNumber) }}</label>
{{ form_widget(form.dialplanNumber) }}
<span class="text-danger">{{ form_errors(form.dialplanNumber) }}</span>
</div>
<div class="form-group">
<label>{{ form_label(form.voicemailId) }}</label>
{{ form_widget(form.voicemailId) }}
<span class="text-danger">{{ form_errors(form.voicemailId) }}</span>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>{{ form_label(form.login) }}</label>
{{ form_widget(form.login) }}
<span class="text-danger">{{ form_errors(form.login) }}</span>
</div>
<div class="form-group">
<label>{{ form_label(form.pass) }}</label>
{{ form_widget(form.pass) }}
<span class="text-danger">{{ form_errors(form.pass) }}</span>
</div>
<div class="form-group">
<label>{{ form_label(form.confSecret) }}</label>
{{ form_widget(form.confSecret) }}
<span class="text-danger">{{ form_errors(form.confSecret) }}</span>
</div>
<div class="form-group">
<label>{{ form_label(form.serverIp) }}</label>
{{ form_widget(form.serverIp) }}
<span class="text-danger">{{ form_errors(form.serverIp) }}</span>
</div>
</div>
</div>
</div>
<div>
<button type="button" class="btn btn-primary" onclick="phoneverif();">Ajouter</button>
<a class="btn btn-warning" href="{{ path('Les_telephones') }}">Retour</a>
</div>
{{ form_end(form)}}
</div>
</div>
</div>
{% endblock %}
{% block javascripts %}
<script src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script>
<script src="{{ path('fos_js_routing_js', { callback: 'fos.Router.setData' }) }}"></script>
<script type="text/javascript">
function phoneverif() {
if ($("#telephone_extension").val() == '') {
alert('Vous devez saisir une extension');
} else {
if ($("#telephone_dialplanNumber").val() == '') {
alert('Vous devez saisir le dialplan du téléphone');
} else {
if ($("#telephone_login").val() == '') {
alert('Vous devez saisir le login du téléphone');
} else {
if ($("#telephone_pass").val() == '') {
alert('Vous devez saisir le mot de passe du téléphone');
} else {
$.ajax({
type: 'get',
url: Routing.generate('phone_verif', {extension: $("#telephone_extension").val()}),
success: function (data) {
if (data.existe == 1) {
alert('Téléphone non valide');
} else {
$("form").submit();
}
},
error: function() { alert('Erreur lors de l'appel AJAX'); }
});
}
}
}
}
}
</script>
{% endblock %}
function verifphone :
public function Phoneverif1(Request $request , $extension){
if ($request->isXmlHttpRequest()) {
$em = $this->getDoctrine()->getManager();
$phone = $em->getRepository(Phones::class)->findOneByExtension($extension);
if ($phone) {
$existe = 1;
} else {
$existe = 0;
}
$response = new JsonResponse();
return $response->setData(array('existe' => $existe));
} else {
throw new \Exception('Erreur');
}
}
my fosjsrouting configuration :
config/packages/routing.yaml:
framework:
router:
utf8: true
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
#default_uri: http://localhost
fos_js_routing:
routes_to_expose: [ phone_verif ]
config/routes/fos_js_routing.yaml:
fos_js_routing:
resource: "#FOSJsRoutingBundle/Resources/config/routing/routing.xml"
routes.yaml :
verification_telephone:
path: /verification/phone/{extension}
controller: App\Controller\TelephoneController::Phoneverif1
options:
expose: true
Rename the function and try again
I solved this problem by renaming the function. You try too.
Phoneverif1()
{% extends 'superadmin.html.twig'%}
{% block body %}
<div class="container-fluid">
<!-- Page Heading -->
<h1 class="h3 mb-4 text-gray-800">Nouveau téléphone</h1>
</div>
<div class="col-md-12">
{% for flashMessage in app.session.flashbag.get('notice') %}
<div class="alert alert-success alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h4><i class="icon fa fa-check"></i>{{ flashMessage }}</h4>
</div>
{% endfor %}
<!-- general form elements -->
<div>
<!-- form start -->
{{ form_start(form)}}
<div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label>{{ form_label(form.userGroup) }}</label>
{{ form_widget(form.userGroup) }}
<span class="text-danger">{{ form_errors(form.userGroup) }}</span>
</div>
<div class="form-group">
<label>{{ form_label(form.protocol) }}</label>
{{ form_widget(form.protocol) }}
<span class="text-danger">{{ form_errors(form.protocol) }}</span>
</div>
<div class="form-group">
<label>{{ form_label(form.extension) }}</label>
{{ form_widget(form.extension) }}
<span class="text-danger">{{ form_errors(form.extension) }}</span>
</div>
<div class="form-group">
<label>{{ form_label(form.dialplanNumber) }}</label>
{{ form_widget(form.dialplanNumber) }}
<span class="text-danger">{{ form_errors(form.dialplanNumber) }}</span>
</div>
<div class="form-group">
<label>{{ form_label(form.voicemailId) }}</label>
{{ form_widget(form.voicemailId) }}
<span class="text-danger">{{ form_errors(form.voicemailId) }}</span>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>{{ form_label(form.login) }}</label>
{{ form_widget(form.login) }}
<span class="text-danger">{{ form_errors(form.login) }}</span>
</div>
<div class="form-group">
<label>{{ form_label(form.pass) }}</label>
{{ form_widget(form.pass) }}
<span class="text-danger">{{ form_errors(form.pass) }}</span>
</div>
<div class="form-group">
<label>{{ form_label(form.confSecret) }}</label>
{{ form_widget(form.confSecret) }}
<span class="text-danger">{{ form_errors(form.confSecret) }}</span>
</div>
<div class="form-group">
<label>{{ form_label(form.serverIp) }}</label>
{{ form_widget(form.serverIp) }}
<span class="text-danger">{{ form_errors(form.serverIp) }}</span>
</div>
</div>
</div>
</div>
<div>
<button type="button" class="btn btn-primary" onclick="Phoneverif1()">Ajouter</button>
<a class="btn btn-warning" href="{{ path('Les_telephones') }}">Retour</a>
</div>
{{ form_end(form)}}
</div>
</div>
</div>
{% endblock %}
{% block javascripts %}
<script src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script>
<script src="{{ path('fos_js_routing_js', { callback: 'fos.Router.setData' }) }}"></script>
<script type="text/javascript">
function Phoneverif1() {
if ($("#telephone_extension").val() == '') {
alert('Vous devez saisir une extension');
} else {
if ($("#telephone_dialplanNumber").val() == '') {
alert('Vous devez saisir le dialplan du téléphone');
} else {
if ($("#telephone_login").val() == '') {
alert('Vous devez saisir le login du téléphone');
} else {
if ($("#telephone_pass").val() == '') {
alert('Vous devez saisir le mot de passe du téléphone');
} else {
$.ajax({
type: 'get',
url: Routing.generate('phone_verif', {extension: $("#telephone_extension").val()}),
success: function (data) {
if (data.existe == 1) {
alert('Téléphone non valide');
} else {
$("form").submit();
}
},
error: function() { alert('Erreur lors de l'appel AJAX'); }
});
}
}
}
}
}
</script>
{% endblock %}
I am using Django and Bootstrap 4. I want to customize the way form validation information is displayed in a template I am using. When an error occurs in the current template, the invalid input element has a red outline and the error message is displayed as a pop-up. Also, the input elements that have been inputted correctly don't have a green outline, they just remain without an outline.
I'd like to do the following:
display the error message underneath the field when an error occurs
give the green outline to the fields whose input is correct
I tried multiple solutions, including:
this tutorial
this GitHub gist
the Stack Overflow answers from this question
None worked from my case.
My current code:
submit_job_listing.html (the template):
{% extends "base.html" %}
{% block title %} Submit a job {% endblock %}
{% block nav_item_post_a_job %}active{% endblock nav_item_post_a_job %}
{% block head %}
{{ job_listing_form.media.css }}
{% endblock %}
{% block content %}
<h1>Submit a job listing</h1>
<div class="container">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="row text-center">
<h2> <b>Job listing information</b> </h2>
</div>
<br/>
{% for field in job_listing_form.visible_fields %}
<div class="form-group">
<div class="row">
<p>{{ field.label_tag }}</p>
</div>
<div class="row">
{% if field.help_text %}
<p class="form-text text-muted">{{ field.help_text }}</p>
{% endif %}
</div>
<div class="row">
{{ field }}
</div>
</div>
{% endfor %}
<br/>
<div class="row text-center">
<h2> <b>Employer information</b> </h2>
</div>
<br/>
{% for field in employer_form.visible_fields %}
<div class="form-group">
<div class="row">
<p>{{ field.label_tag }}</p>
</div>
<div class="row">
{% if field.help_text %}
<p class="form-text text-muted">{{ field.help_text }}</p>
{% endif %}
</div>
<div class="row">
{{ field }}
</div>
</div>
{% endfor %}
<input type="submit" value="Submit" class="btn btn-primary" />
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
{{ job_listing_form.media.js }}
</div>
{% endblock %}
views.py (relevant parts):
def submitJobListing(request):
if request.method == "POST":
employer_form = EmployerForm(request.POST, request.FILES)
job_listing_form = JobListingForm(request.POST, request.FILES)
#check if employer with that name already exists
employer_name = str(request.POST.get("name", ""))
try:
employer_with_the_same_name = Employer.objects.get(name=employer_name)
except ObjectDoesNotExist:
employer_with_the_same_name = None
employer = None
if (employer_with_the_same_name != None):
employer = employer_with_the_same_name
if employer == None and employer_form.is_valid() and job_listing_form.is_valid():
employer = employer_form.save()
job_listing = job_listing_form.save(commit=False)
job_listing.employer = employer
job_listing.save()
job_listing_form.save_m2m()
return SimpleTemplateResponse("employers/successful_job_listing_submission.html")
else:
employer_form = EmployerForm()
job_listing_form = JobListingForm()
context = {
"employer_form": employer_form,
"job_listing_form": job_listing_form,
}
return render(request, 'employers/submit_job_listing.html', context)
forms.py (relevant parts):
class EmployerForm(forms.ModelForm):
name = forms.CharField(max_length=100)
#location = forms.CharField(widget=LocationWidget)
short_bio = forms.CharField(widget=forms.Textarea)
website = forms.URLField()
profile_picture = forms.ImageField()
def __init__(self, *args, **kwargs):
super(EmployerForm, self).__init__(*args, **kwargs)
for visible in self.visible_fields():
if isinstance(visible.field.widget, (forms.widgets.TextInput, forms.widgets.Textarea, forms.widgets.URLInput, LocationWidget)):
visible.field.widget.attrs['class'] = 'form-control'
if isinstance(visible.field.widget, forms.widgets.ClearableFileInput):
visible.field.widget.attrs['class'] = 'form-control-file'
class Meta:
model = Employer
fields = ["name", "short_bio", "website", "profile_picture"]
class JobListingForm(forms.ModelForm):
job_title = forms.CharField(max_length=100, help_text="What's the job title?")
job_description = forms.CharField(widget=forms.Textarea)
job_requirements = forms.CharField(widget=forms.Textarea)
what_we_offer = forms.CharField(widget=forms.Textarea)
location = forms.CharField(widget=LocationWidget)
remote = forms.BooleanField()
job_application_url = forms.URLField()
point_of_contact = forms.EmailField()
categories = forms.ModelMultipleChoiceField(
queryset=Category.objects.all(),
widget=forms.CheckboxSelectMultiple,
required=True)
def __init__(self, *args, **kwargs):
super(JobListingForm, self).__init__(*args, **kwargs)
for visible in self.visible_fields():
if isinstance(visible.field.widget, (forms.widgets.TextInput, forms.widgets.Textarea, forms.widgets.URLInput, forms.widgets.EmailInput, LocationWidget)):
visible.field.widget.attrs['class'] = 'form-control'
if isinstance(visible.field.widget, (forms.widgets.CheckboxInput, forms.widgets.CheckboxSelectMultiple)):
visible.field.widget.attrs['class'] = 'form-check'
class Meta:
model = JobListing
fields = ["job_title", "job_description", "job_requirements", "what_we_offer", "location", "remote", "job_application_url", "categories", "point_of_contact"]
Can someone tell me how can I achieve the effects that I want?
Update 1:
I tried adding the code that checks for field.errors, but it doesn't work.
This is the submit_job_listing.html template file:
{% extends "base.html" %}
{% load widget_tweaks %}
{% block title %} Submit a job {% endblock %}
{% comment %} https://stackoverflow.com/questions/50028673/changing-active-class-in-bootstrap-navbar-not-staying-in-inherited-django-templa {% endcomment %}
{% block nav_item_post_a_job %}active{% endblock nav_item_post_a_job %}
{% block head %}
{{ job_listing_form.media.css }}
<!---
<style>
input, select {width: 100%}
</style>
--->
{% endblock %}
{% block content %}
{% comment %}
https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html
{% endcomment %}
<h1>Submit a job listing</h1>
<div class="container">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="row text-center">
<h2> <b>Job listing information</b> </h2>
</div>
<br />
<div class="row text-center">
<p> <b>Note: Fields marked with an asterisk (*) are required</b> </p>
</div>
<br/>
{% for field in job_listing_form.visible_fields %}
<div class="form-group">
<div class="row">
<p>{{ field.label_tag }}{{ field.field.required|yesno:"*," }}</p>
</div>
<div class="row">
{% if field.help_text %}
<p class="form-text text-muted">{{ field.help_text }}</p>
{% endif %}
</div>
<div class="row">
{{ field }}
<p> {{ field.errors }} </p>
{% if field.errors %}
<div class="border-bottom-danger">
{{ field.errors }}
</div>
{% endif %}
</div>
</div>
{% endfor %}
<br/>
<div class="row text-center">
<h2> <b>Employer information</b> </h2>
</div>
<br />
<div class="row text-center">
<p> <b>Note: Fields marked with an asterisk (*) are required</b> </p>
</div>
<br/>
{% for field in employer_form.visible_fields %}
<div class="form-group">
<div class="row">
<p>{{ field.label_tag }}{{ field.field.required|yesno:"*," }}</p>
</div>
<div class="row">
{% if field.help_text %}
<p class="form-text text-muted">{{ field.help_text }}</p>
{% endif %}
</div>
<div class="row">
{{ field }}
</div>
</div>
{% endfor %}
<input type="submit" value="Submit" class="btn btn-primary" />
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
{{ job_listing_form.media.js }}
</div>
{% endblock %}
When I just click the submit button without inputting anything, all the inputs have a red outline, but nothing gets printed out as field.errors. I don't know why is that. Why is that?
Did you tried debugging in the template ?
I did something like you want to achieve :
<form method="post"> {% csrf_token %}
{% for field in form %}
<div class="form-group">
{{ field }}
<label class="control-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
{% if field.errors %}
<div class="border-bottom-danger">
{{ field.errors }}
</div>
{% endif %}
</div>
{% endfor %}
<button class="btn btn-block" type="submit">Submit</button>
</form>
Where :
{{ field }} is the input, where you are correctly adding visible.field.widget.attrs['class'] = 'form-control'
Then, errors you want (I guess) are stored in the field, so you could get its with {{ field.errors }} if it has some.
The difference between your code and mine is that I'm using field.errors instead if field.help_text, I hope it can help.
I suggest you to put breakpoint in your template, then analyze your form object. Then you can do whatever you want in your frontend.
If no error : Add class outline-green to your input wrapper (the <div class="row")
If error : Display the error within a div underneath your input
PS : If you want to outline the input, and not the row wrapper, you can do it through css (or better with Sass if you are using it):
.row.outline-green > input{
border: 1px solid green;
}
<div class="row outline-green">
{{ field }}
</div>
{% load widget_tweaks %}
<div class="col-12 col-md-6">
<div class="form-group">
<label for="{{ form.field1.id_for_label }}" class="text-capitalize">{{ form.field1.label|title }}{% if form.field1.field.required %}<span class="text-danger ml-1">*</span>{% endif %}</label>
{% if form.is_bound %}
{% if form.field1.errors %}
{% render_field form.name class="form-control is-invalid" %}
{% for error in form.field1.errors %}
<div class="invalid-feedback">
{{ error }}
</div>
{% endfor %}
{% else %}
{% render_field form.field1 class="form-control is-valid" %}
{% endif %}
{% else %}
{% render_field form.field1 class="form-control" %}
{% endif %}
{% if form.field1.help_text %}
<small class="form-text text-muted">{{ form.field1.help_text }}</small>
{% endif %}
</div>
</div>
</div>
I am making a todo app, with 2 lists: To-Do and Completed Items. I want alternating background colors for both these lists. While adding the items, everything works fine.
However, as soon as I move Item #2 to the completed list, this is what I get:
My code is as follows:
HTML:
<div class = "ItemList">
{% for todo in todos %}
<div>
{% if todo.complete == False %}
<div class = "item">
<span id="editable"> {{ todo.todoitem }} </span>
<div class = "button">
<input type = "Button" value = "Done" class="button2">
<input type = "Button" value = "Remove" class="button2">
</div>
</div>
{% endif %}
</div>
{% endfor %}
</div>
<h3 style="text-align: center;">Completed Items</h3>
<div class = "CompletedList">
{% for todo in todos %}
<div>
{% if todo.complete == True %}
<span class = "completed">
<strike> {{ todo.todoitem }} </strike>
<span class = "button">
<input type = "Button" value = "Move to Incomplete"class="button2">
<input type = "Button" value = "Remove" class="button2">
</span>
</span>
{% endif %}
</div>
{% endfor %}
</div>
CSS:
div.ItemList> div:nth-of-type(odd){
background-color: #adb6be;
}
div.ItemList> div:nth-of-type(even){
background-color: #eaecee;
}
div.CompletedList> div:nth-of-type(odd){
background-color: #adb6be;
}
div.CompletedList> div:nth-of-type(even){
background-color: #eaecee;
}
How can I make the lists appear with alternating colors after modification? Both lists should start with the color #adb6be and then alternate. I have tried including them within the same class element, but that doesn't work either. Any help will be appreciated.
This is due to the way that you are outputting the HTML, for each list you are generating all items so the nth-child is still being applied to the DIV even if it has no content inside. You would need to adjust the HTML:
<div class = "ItemList">
{% for todo in todos %}
{% if todo.complete == False %}
<div class = "item">
<span id="editable"> {{ todo.todoitem }} </span>
<div class = "button">
<input type = "Button" value = "Done" class="button2">
<input type = "Button" value = "Remove" class="button2">
</div>
</div>
{% endif %}
{% endfor %}
</div>
<h3 style="text-align: center;">Completed Items</h3>
<div class = "CompletedList">
{% for todo in todos %}
{% if todo.complete == True %}
<span class = "completed">
<strike> {{ todo.todoitem }} </strike>
<span class = "button">
<input type = "Button" value = "Move to Incomplete"class="button2">
<input type = "Button" value = "Remove" class="button2">
</span>
</span>
{% endif %}
{% endfor %}
</div>
I'm using macro to display a collection of videos in my form.
Form
{% import "macros/prototype.html.twig" as prototype %}
{{ form_start(form) }}
<div class="row">
<div class="col-md-6">
{{ form_row(form.title) }}
{{ form_row(form.description) }}
<fieldset class="form-group">
{{ form_label(form.videos) }}
<div id="course_videos" class="collection_holder" data-prototype="{{ prototype.tagCollectionLinkItem(form.videos.vars.prototype)|e }}">
{% for video in form.videos.children %}
{{ prototype.tagCollectionLinkItem(video) }}
{% endfor %}
</div>
<button type="button" id="add-video-btn" data-target-collection="#{{ form.videos.vars.id }}" class="btn btn-sm btn-info"><i class="la la-plus"></i> {{ 'course.buttons.add_video' | trans({}, 'labels') }}</button>
</fieldset>
</div>
</div>
<hr>
<input type="submit" class="btn m-btn--pill at-btn--primary pull-right" value="{{ button_name }}">
{{ form_end(form) }}
Macro
{% macro tagCollectionFileItem(item) %}
<fieldset class="form-group">
<div id="{{ item.vars.id }}">
{% if item.uploadedFile.vars.file_url or item.uploadedFile.vars.image_url %}
{{ form_errors(item.uploadedFile) }}
{{ form_widget(item.uploadedFile, {'attr': {'hidden': true}}) }}
{% else %}
<div class="custom-file">
{{ form_widget(item.uploadedFile) }}
{{ form_label(item.uploadedFile, item.uploadedFile.vars.label, {'label_attr': {'class': 'custom-file-label'}}) }}
</div>
{% endif %}
</div>
</fieldset>
{% endmacro %}
form_end makes form.videos label to display twice. I guess because I never used form_widget(form.videos) so form_end makes it appears. Should I replace my macro with a form theme?
Because you never rendered form.video with the widget you need to set the field as rendered. Just use {{ do form.videos.setRendered }} and you are good to go
How can I access an entity attribute in Twig (using the Winzou Symfony2 tutorial on OpenClassroom)?
Category is an attribute of my class Advert which contains all my adverts. I just want to show an error message if there are no Advert entities.
Here is my accordion that lists "adverts" from my Advert entity. One accordion is for the category incident and the one other is for the category general.
<div class="well">
<div class="accordion" id="accordion2">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#collapseGen">
<h3><i class="icon-chevron-right"></i> Incidents</h3>
</a>
</div>
<div id="collapseGen" class="accordion-body collapse">
<div class="accordion-inner">
<div class="accordion" id="accordion4">
{% for advert in listAdverts %}
{% if advert.category == "incident" %}
<div class="accordion-group">
<div class="accordion-heading decalage">
<a href="{{ path('info_view', {'id': advert.id}) }}">
<h3 class="{{ advert.category }}">{{ advert.title }}</h3>
</a>
<div>
<span>{{ advert.content|truncate(100, true, '...')|raw }}</span>
</div>
<div>
{% if (advert.UpdatedAt is empty) %}
<i>Créé par {{ advert.author }}, le {{ advert.date|date('d/m/Y') }}
à {{ advert.date|date('H:i') }}</i>
{% else %}
<i>Modifié par {{ advert.author }},
le {{ advert.updatedAt|date('d/m/Y') }}
à {{ advert.updatedAt|date('H:i') }}</i>
{% endif %}
</div>
<div>{% if advert.readers is not empty %}
<i>Vu par :
{% for reader in advert.readers %}
{{ reader.username }},
{% endfor %}
{% endif %}</i>
</div>
<br>
<div>
{% if is_granted("IS_AUTHENTICATED_FULLY") %}
<p>
<a href="{{ path('info_edit', {'id': advert.id}) }}"
class="btn btn-default">
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
Modifier
</a>
<a href="#myModal{{ advert.id }}" role="button" class="btn btn-danger"
data-toggle="modal">
<i class="fa fa-trash-o" aria-hidden="true"></i>
Supprimer
</a>
</p>
<div id="myModal{{ advert.id }}" class="modal hide fade">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">×</button>
<h3>Suppression annonce "{{ advert.title }}"</h3>
</div>
<div class="modal-body">
<p>Voulez-vous vraiment supprimer l'annonce : "{{ advert.title }}" ? </p>
</div>
<div class="modal-footer parente">
<div>Annuler</div>
<div>
<form class="nomargin"
action="{{ path('info_delete', {'id': advert.id}) }}"
method="post">
<input type="submit" value="Supprimer"
class="btn btn-danger"/>{{ form_rest(form) }}
</form>
</div>
</div>
</div>
{% endif %}
</div>
</div>
</div>
{# HERE I DONT KNOW HOW TO DO IT #}
{% else %} No Advert !
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href="#collapseCo">
<h3><i class="icon-chevron-right"></i> Général</h3>
</a>
</div>
<div id="collapseCo" class="accordion-body collapse">
<div class="accordion-inner">
<div class="accordion" id="accordion4">
{% for advert in listAdverts %}
{% if advert.category == "general" %}
<div class="accordion-group">
<div class="accordion-heading decalage">
<div class="accordion-heading">
<a href="{{ path('info_view', {'id': advert.id}) }}">
<h3 class="{{ advert.category }}">{{ advert.title }}</h3>
</a>
<span>{{ advert.content|truncate(100, true, '...')|raw }}</span>
<div>
{% if (advert.UpdatedAt is empty) %}
<i>Créé par {{ advert.author }}, le {{ advert.date|date('d/m/Y') }}
à {{ advert.date|date('H:i') }}</i>
{% else %}
<i>Modifié par {{ advert.author }},
le {{ advert.updatedAt|date('d/m/Y') }}
à {{ advert.updatedAt|date('H:i') }}</i>
{% endif %}
</div>
<div>{% if advert.readers is not empty %}
<i>Vu par :
{% for reader in advert.readers %}
{{ reader.username }},
{% endfor %}
{% endif %}</i>
</div>
<br>
<div>
{% if is_granted("IS_AUTHENTICATED_FULLY") %}
<p>
<a href="{{ path('info_edit', {'id': advert.id}) }}"
class="btn btn-default">
<i class="fa fa-pencil-square-o" aria-hidden="true"></i>
Modifier
</a>
<a href="#myModal{{ advert.id }}" role="button" class="btn btn-danger"
data-toggle="modal">
<i class="fa fa-trash-o" aria-hidden="true"></i>
Supprimer
</a>
</p>
<div id="myModal{{ advert.id }}" class="modal hide fade">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">×</button>
<h3>Suppression annonce "{{ advert.title }}"</h3>
</div>
<div class="modal-body">
<p>Voulez-vous vraiment supprimer l'annonce : "{{ advert.title }}" ? </p>
</div>
<div class="modal-footer parente">
<div>Annuler</div>
<div>
<form class="nomargin"
action="{{ path('info_delete', {'id': advert.id}) }}"
method="post">
<input type="submit" value="Supprimer"
class="btn btn-danger"/>{{ form_rest(form) }}
</form>
</div>
</div>
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
My error message " No Adverts !" doesnt appears..
EDIT : According to Mitchel's answer, i've tried this :
{% endif %}
{% else %}<li>No Adverts</li>
{% endfor %}
I don't know why it doesn't work when one advert is in the other category...
{% for advert in listAdverts if advert.category == "incident" %}
{% if listAdverts is empty%}
<li>No Adverts</li>
{% endif %}
{% endfor %}
That code does not work.
I'm not sure to understand your question, but if so, you can maybe try a thing like this according to the documentation:
{% for user in users %}
<li>{{ user.username|e }}</li>
{% else %}
<li><em>no user found</em></li>
{% endfor %}
In Twig a for statement can have an associated else. It basically means that if the for has no results, the else is used. You should put the {% endif %} before the {% else %} and it should work.