Django: One template or two templates for different CSS? - css

I am making a website in Django for an online multiple-choice test. For each question, the question text is displayed on the webpage, together with a set of radio buttons for the possible answers, and a submit button. The user chooses on of the answers, and presses the button. Then, I want to give feedback to the user: A green "Correct", or a red "Incorrect", together with a button to retrieve the next question.
What is the best way to do this in Django? I could have two templates: one for the question, and one for the feedback, and each with one associated view function. For the question, I would pass variables for the question text, together with the text for the possible answers. This seems to work well. However, for the feedback, I would pass the text "Correct" or "Incorrect" as a variable, but how do I now change the CSS to set the text to be green if "Correct", and red if "Incorrect"? Would it be more sensible to have a separate template for the "Correct" case, and the "Incorrect" case?
Thank you.

The Django view should pass whether the answer is correct or not, i.e. a boolean.
Suppose the boolean variable in the template context is called correct; your template code could be something along these lines:
{% if correct %}
// correct html markup in here
<span class="correct">Correct!</span>
{% else %}
// incorrect html markup in here
<span class="incorrect">Woops, not correct!</span>
{% endif %}
The above should all go in the same template, i.e. one template only.

Related

Passing html in string in include

I have the code below and I need to pass an html element (anchor) as shown. I have tried using filters like raw and escape but it always prints out the html element as regular text. I also tried setting a new variable that contains the same string text and passed that to testLink and then applied filters to it, but same result. Any ideas how to tackle this problem?
{% include 'example.html.twig' with {'testLink': 'Hurry, Click me NOW'} %}
You cannot handle your problem in the template that is including the example.html.twig template as autoescaping will step in when the passed value is displayed in the included template. Instead, you will have to use the raw filter in example.html.twig (be careful with that solution though as the template is probably used in other places too which might not be safe).

How to render only one field of a form with symfony

I want to render only one field of a form. When i put {{form_end(form)}} every other field are coming (symfony doc show it clearly) but how to render only one field ? If i dont put {{form_end(form)}}, there is only one field, but no save button
thanks
Yes, CSS can do the trick. But do you want the working of your application to depend on client side styling rules? In most cases it might beter not to render the field HTML at all.
There are two ways in which you can fix this in your template.
Put {% do form.field_you_want_to_hide.setRendered %} before your {{form_end(form)}}.
This will mark the field as rendered and thus it will not show up when form_rest is called.
Instead of {{form_end(form)}}, use {{ form_end(form, {'render_rest': false}) }}, as explained in the Symfony Twig documentation.
It would be even better to change your form class such that the fields are removed from your form. Is it your own form you would like to render, or a form from a third party bundle?

Can't render an action in base layout and execute it from child template

Am working on a Symfony2 application whose among its functions will allow the user to select to visit different sections of the site, and this from anywhere (any page) of the site. For simplifying let's say: when a user want to sort he/she choose from a drop down select form and submit.
I built the action and template with a test root to verify this function and this work (when I use directly the rendering of that sortAction() on my app_dev/test adress.
The issu is that when I try to make this action accessible from the general template (app/Resources/views/base.html) I can view the select form with default view, but when I select for a sort and try to Submit page relaods and return to the defaut view.
I use {% render "MycompanyMybundleBundle:Mycontroller:sort" %} in .../base.html and I want this action to work on (like) mysite/anypage this last extending bundle layout which (layout also extent base).
Can anyone help me?
The description of your problem isn't realy clear, but I think the problem lies at the form action. Do you've configured this action? You should leave it empty if you want to submit it to the same page.
Another solution would be to make use of the extending posibilities of Twig. Define the form as a block in the parent, and override it in the child.
http://twig.sensiolabs.org/doc/tags/extends.html
EDIT:
You could make the form action a block, that is what I mean...
<form action="{% block formAction %}defaulttargetpage.php{ %endblock% }"> <!-- formcontent --> </form>

How to remove inputs/fields created by a form in Django

I have a simple form for uploading a profile picture and then a thumbnail image showing what has been uploaded. The HTML code is:
<form action="{% url 'base-welcome' %}" enctype="multipart/form-data" method="post">
{% csrf_token %}
<ul>
<li><span>Upload A Profile Picture:</span> <img src="{{ user.profile.get_thumbnail }}">{{ profile_form.picture }}</li> , then closing elements, etc..
The problem is that the form is creating unwanted elements in the "li". See the following image:
The "currently" and "change" have been created. I've already hidden a checkbox that was created using display: none. I can't really do that with these elements because they are just text that was generated.
I think this is a problem with the models.py/views.py pages, but I may be wrong. Just looking for a simple HTML/CSS fix. Thank you so much!!
It looks like picture field is using ClearableFileInput widget. To use standard FileInput widget (without these extra words and checkbox), do just in your form:
picture = forms.ImageField(upload_to='/path/', widget=forms.FileInput)
In that case you just have to render your forms manually :)
You could either write your own helpers - I can see this as ie. custom filters: {{ form.field|as_file_input_field }} or you could use some external helpers like: http://djangopackages.com/grids/g/forms/
I would still suggest writing your own helpers just to learn how django forms renderer works :)
You could also take a look here for some samples of how we tried to solved this problem while before: https://github.com/efabryka/django-template_widgets :)
This is how the ImageField default widget is rendered - maybe it will be worth your while: https://github.com/django/django/blob/master/django/forms/widgets.py#L298
Are you just wanting to hide some text? I haven't touched HTML/CSS in a while but can't you just put the text inside a div or a span and then hide that?
set color: white; for that element, then all text will be "invisible" lol.

Drupal views - splitting up the exposed form possible?

I need to display part of the exposed form in my page's sidebar, and the rest of the form and content in the $content area. There's really no good way that I can find to do this. I sort of got it to show up in a way by making a "block" view with "exposed form" set and then trying to only show the part that i needed through .tpl files. The problem is that then, when the submit button is clicked (the submit button is in the $content area), then the filters that are in the sidebar are not taken into account.
Some lateral thinking... Why not explore CSS-only options? You can place that form element playing with position:absolute ? Or (considering is a right-sidebar) float:right and then some negative right margin to push it to the sidebar? If you are using 960 grid system, play with pull and push classes.
First I am going to answer your question, then I will explain why you are asking the wrong question:
If you build the form outside of the formapi, you might have some luck. This will get upgly and will require you to take a lot of extra care about attack-vectors such as mass-assignment.
views_some_view.tpl.php:
<form name="input" action="/link/to/view" method="get">
Country: <input type="text" name="country" />
my_custom_exposed_view.module:hook_block()
City:
That would make a form, which in most situations will start with <form>, have some input fields, then have a lot of random HTML, then some more input fields and then the closing .
As you may know, a <input type="submit" value="Submit" /> will only post everything of the form tags it is enclosed in. The submit button in the following HTML:
<form name="input_1" action="/link/to/view" method="get">
Country: <input type="text" name="country" />
</form>
<form name="input_2" action="/link/to/view" method="get">
City: <input type="text" name="city" />
<input type="submit" value="Submit" />
</form>
will only send the City. These are not the droids you are looking for.
It will need to be one, big form, but since everything between form and /form is very dynamic, and contains a large quantity of HTML, including potential other forms, this is really not what you want. Moreover: a blocks appearance (shown/not-shown) is controlled completely independent of the content. You will need a lot of sturdy code to ensure the block a) never shows up when the starting form tag is not present, and b) the block will guaranteed to be shown when that opening form tag is present. Else you have not just invalid HTML, but broken HTML that will truly render your page unusable in most cases.
You simply don't want a part of the form in a block and the other part in the content.
However, you want it visualised as if one part is in the body, the rest in a sidebar.
The good news, is that with HTML presentation structure are independant. That is where your solution lies.
Give your form-fields good ids and classes. You could use a hook_form_alter to change existing forms, but you probably simply just want to create the HTML for that entire form yourself. The theme layer allows that.
Use CSS to pick out either single form-fields by ID and position:absolute them into the correct place. Or pick out classes of fields by CLASS and position:relative them into the correct place.
Make a simple identification-routine that allows adding a class to the body-tag. (see below).
Add some CSS to shift the sidebar lower, making space for the form-fields to be moved in, when that class is in the body-tag.
<body class="<?php print $splitform ?>">
function my_themename_preprocess_page() {
if ($GET['q'] == 'path/to/view') {
$vars['spliform'] = "splitform"
}
}
From the above explanation I am assuming that you are printing same form in block and in content area and you are hiding some part of form in page.tpl , if this is true then you can use hook_form_alter() in your custom module then
Store the value of the form element(present in block) in global variable.
Now use that global variable and set form element(present in content area, this form element is not visible to user).
Provide more information if you implemented other way.
Regards,
Chintan.
There is a related issue here:
https://drupal.stackexchange.com/questions/3827/multiple-copies-of-views-filter-form-exposed-filters
which describes how to duplicate your filters. However it seems like an ugly hack.
A bit cleaner seems this solution mentioned in #6:
http://drupal.org/node/641838#comment-3247748
Haven't tested it out, but it looks good.
It will still give you some overhead (duplicate views) but it might be the easiest way doing this using views.
On the other hand you might write a module and build your own custom filter block which hooks into your view. Here is a blog post about this:
http://www.hashbangcode.com/blog/creating-custom-views-filters-exposed-form-element-drupal-6-561.html
If you use something like context you could get the exposed filters block to display twice in the same page. You could then use CSS to hide the fields you don't want to do display in each form.
The fundamental problem you're having is that to have the two forms in different places, they'll each have their own form element - when a submit is triggered, only the form fields within the same form element are sent. You need to move them into one form, or rely on JavaScript to gather the fields from both forms and construct the post.
You could create the block as an empty div and have javascript from the main page populate it with the secondary filter form and whatever else you need in there. Again, you could use javascript to copy the form values from the block form to hidden fields in the main form on submit. That gives you all the control you need from one place (the node output). Only caveat is that it relies a lot more on javascript to join it all together.

Resources