With django_filters, I have my filterset, everything works fine it's just the display that I am stuck with (box width).
As you can see below, I have changed the "size" attribute of some of the filter options - because the default is too wide. But the "rating" one, which is a NumberInput, doesn't work for some reason. The "size" attribute works for TextInput but not NumberInput.
I want to change the size or rather the width of the NumberInput box that will be displayed in the template (see template pictures below).
Can anyone help? Thanks in advance!
class ReviewFilter(django_filters.FilterSet):
comments = CharFilter(field_name='comments', lookup_expr='icontains', label="Comments ", widget=TextInput(attrs= {'size': 15 } ))
role_title = CharFilter(field_name='role_title', lookup_expr='icontains', label="Role title ", widget=TextInput(attrs={'size': 15 } ))
date_range = DateRangeFilter(field_name="date_created", label=" Posted date ")
**rating = CharFilter(field_name="rating", lookup_expr='gte', label="Minimum rating ", widget=NumberInput(attrs={'size': 1 } ))**
class Meta:
model = Review1
fields = '__all__'
exclude = {'recruiter', 'date_created', 'user'}
I have this:
Screenshot - Look at "Minimum rating" box width
But I want this:
Screenshot with filter search bar - Look at "Minimum rating" box width
I found a solution in the thread below by using the attribute - "style" : 'width6ch'
Apparently NumberInput doesn't have a working "size" attribute in HTML yet.
Solution to my problem
You cannot directly style the django-filters search fields. I was stuck with the same problem and here is my way of solving it.
Step 0 : intall widget_tweaks by pip install django-widget-tweaks
step 1 : add widget_tweaks to INSTALLED_APPS in your settings.py
step 2 : add {% load widget_tweaks %} into your template.html
step 3 : style individual elements in template
<div class="form-group col-sm-4 col-md-3">
{{ filter.form.comments.label_tag }}
{% render_field filter.form.comments class="form-control" %}
</div>
<div class="form-group col-sm-4 col-md-3">
{{ filter.form.role_title.label_tag }}
{% render_field filter.form.role_title class="form-control" %}
</div>
this way you can style individual form elements from filters, you can also add html tag attributes such as type or class and style them based on your needs.
you can use this link for reference. Link for Reference
Related
Let say I have a taxonomy name Flavor and the terms have Vanilla, Chocolate and Green Tea.
I also have a content type name ice-cream with flavor field under 'Flavor' taxonomy which can multiple select.
I create a ice-cream page name Baskin Robin and I tick 'Vanilla' and 'Chocolate' under flavor field.
How to list all 'Flavor' terms in node.html.twig and add a class for 'Vanilla' and 'Chocolate'?
For example:
<div class="field-item active">Vanilla</div>
<div class="field-item active">Chocolate</div>
<div class="field-item">Green Tea</div>
You need a block or a views to do that.
You can also use a hook_preprocess_node to inject all flavors in the ice-cream template.
Here the documentation to create a custom block.
Here the documentation to create a views block.
Here the documentation to place a block (custom or views).
I will explain the easiest & fastest, but most dirty one, to achieve your goal - using the hook_preprocess_node.
I recommend to use the custom block or the views for scalability & maintainability. The code below is a working example, you could use it in a custom block.
Here the code using the preprocess way.
In your template.theme file:
/**
* Implements hook_preprocess_node.
*/
function template_preprocess_node(&$variables) {
$node = $variables['node'];
if($node->bundle() == 'ice-cream') {
// Should be injected.
$termStorage = \Drupal::entityManager()->getStorage('taxonomy_term');
// Load all flavors taxonomy term.
$variables['flavors'] = $termStorage->loadTree('flavors', 0, NULL, TRUE);
}
}
In your node.html.twig or node--ice-cream.html.twig:
{% for flavor in flavors %}
{% set classes = ['field-item'] %}
{% for node_flavor in node.field_flavors if node_flavor.target_id == flavor.id %}
{% set classes = classes|merge(['active'])%}
{% endfor %}
<div class="{{ classes|join(' ') }}">{{ flavor.name.value }}</div>
{% endfor %}
Hope it will help you !
I have a model field with choices. Like this:
CHAIN_CHOICES = (
('P','Public'),
('N','Private')
)
chain = models.CharField(max_length=1, choices=CHAIN_CHOICES, verbose_name=u"Chain")
In my template I would like to call it simillary to this:
<li><i class="glyphicon glyphicon-tags"></i> <span>{{mymodel.chain}}</span></li>
Problem is .... this is calling 'N' or 'P' and I would like to call the 'Public' - 'Private' values.
Any hint would be wellcome.
Regards,
J.M.
Guess I have found my answer:
{{ mymodel.get_chain_display }}
Unless there is a different way ??
#JanMejor I want to call from templates to "choices" too but without duplicates. Here is a different way you did:
...
{% for i in mymodel %}
{{ i.chain }}
{% endfor %}
...
Still, it will show duplicates if you have couple posts with the same "choice value"
Can i write ng-repeat to iterate through the choices in a Django model field and display them? How can i do it? Should I make a separate API for this or what?
APPROVAL_CHOICES = (
(u'Good condition', u'Good condition'),
(u'Bad condition', u'Bad condition'),
(u'Broken', u'Broken'),
)
status = models.CharField(max_length=20, choices=APPROVAL_CHOICES)
I have something like the following, but it's not working:
<label>Statuss</label>
<select>
<option value="" selected>--Please select Inventory statuss--</option>
<option value="inventory.status[0]" >Good Condition</option>
<option value="inventory.status[1]" >Bad Condition</option>
<option value="inventory.status[2]" >Broken</option>
</select><br/>
And here is my API:
objects: [
{
category: {},
count: 1,
created: "2014-02-24T16:07:12.903555",
description: "Car description for image",
id: 1,
location: "IT nodala",
name: "Baterija AA",
resource_uri: "/api/v1/inventory/1",
slug: "baterija-aa",
status: "Good condition"
},
using ng repeat like this
'<select data-ng-model="selectedField">' +
' <option data-ng-repeat="v in choices" value="v">v</option>' +
'</select> ' ;
I guess your question is about how to use select tag with angular js you can use the ngOption directive.
From the AngularJS docs:
ngOptions
The ngOptions attribute can be used to dynamically generate a list of elements for the element using the array or object obtained by evaluating the ngOptions comprehension_expression.
When an item in the menu is selected, the array element or object property represented by the selected option will be bound to the model identified by the ngModel directive.
...Note: ngOptions provides an iterator facility for the element which should be used instead of ngRepeat when you want the select model to be bound to a non-string value. This is because an option element can only be bound to string values at present.
with this jsfiddles:
<body ng-app="demoApp">
<div ng-controller="DemoController">
<div>
<h2>Incorrect</h2>
<p>
We might expect the select box to be initialized to "two,"
but it isn't because these are two different objects.
</p>
<select
ng-model="incorrectlySelected"
ng-options="opt as opt.label for opt in options"
>
</select>
The value selected is {{ incorrectlySelected.value }}.
</div>
<div>
<h2>Correct</h2>
<p>
Here we are referencing the same object in <code>$scope.correctlySelected</code>
as in <code>$scope.options</code>, so the select box is initialized correctly.
</p>
<select
ng-model="correctlySelected"
ng-options="opt as opt.label for opt in options"
>
</select>
The value selected is {{ correctlySelected.value }}.
</div>
</div>
</body>
Check the docs form more exmaples.
I have a sorted dictionary that contains sort options:
sort_options = SortedDict([
("importance" , ("Importance" , "warning-sign")),
("effort" , ("Effort" , "wrench" , "effort")),
("time_estimate" , ("Time Estimate" , "time")),
("date_last_completed" , ("Date Last Completed" , "calendar")),
])
I'm displaying these options in my template:
{% for key, icon in sort_options.items %}<!-- Sort Options -->
<a class="btn btn-info" href={{ request.path }}?key={{ key }}&orientation=desc><i class="icon-{{ icon.1 }} icon-large"></i></a>
{% endfor %}
I need to define the 4 sort options, but I only want to display the first 3 (the remaining options are used elsewhere). I also anticipate adding other sort options that I won't need to be displayed. I could write an if statement with a forloop counter to prevent the last option from displaying, but this seems wasteful.
I found this filter but I'm not sure how to combine it with the forloop that needs both the key and the icon data.
How can I write a django template for loop that runs on a dictionary and only loops X number of times?
Similar to Joe's answer, but there's actually a built-in filter slice that'll do this for you:
{% for key, icon in sort_options.items|slice:":3" %}
I think you could do this with a template filter. For example, in:
./mymodules/templatetags/mytags.py
#register.filter
def get_recent(object, token):
"""
Must pass a Option Dictionary
"""
return object.items()[:token]
And then in your template:
{% load mytags %}
{% for option in sort_options|get_recent:3 %}
key: {{ option.0 }}
value: {{ option.1 }}
{% endfor %}
I haven't had a chance to test the above code, but think the logic is sound. Let me know what you think.
In my django app ,I need to call a view with an argument named 'year'. Then in the template,I created a form and a dropdown list using a list of year names,At this point,I am confused as to how the view should be invoked.
The view is named 'create_report_for_data_of_the_year'.It expects a year argument.
ie,
http://127.0.0.1:8000/myapp/reports/2011
I tried to write the template as shown below.
<li id="yearlydataplots" class="report">
<form action="create_report_for_data_of_the_year" >
<select name="year" id="year">
{% for anyear in years %}
<option value={{anyear}} > {{anyear}}</option>
{% endfor %}
</select>
<input type="submit" value="Plot for entries of the year"/>
</form>
</li>
However,when the submit button is clicked,the browser goes to
http://127.0.0.1:8000/myapp/reports/create_report_for_data_of_the_year?year=2006
which causes a 404.
I changed method="post", and clicking submit goes to
http://127.0.0.1:8000/myapp/reports/create_report_for_data_of_the_year
which again causes 404
I know,I am missing something very basic :-)..If someone can kindly point it out,it would be nice
thanks in advance,
mark
def create_report_for_data_of_the_year(request,year,page_title,template_name):
dataset=MyDataModel.objects.filter(today__year=year,creator=request.user)
#today is a field in MyDataModel and is a datetime.datetime
map = create_map_of_names_and_values(dataset)
basefilename = "plotofdataforyear%s"%year
page_title = page_title+" "+year
imgfilename= create_plot(map,basefilename)
report_data={'basefilename':basefilename,'plot_image':imgfilename,'year':year,'page_title':page_title}
report_data["name_value_dict"]=map
req_context=RequestContext(request,context)
return render_to_response(template_name,req_context)
and url mapping is
...
url(r'^reports/(?P<year>\d{4})/$','myapp.views.create_report_for_data_of_the_year',
{
'template_name':'myapp/report_for_data_of_the_year.html',
'page_title':'report for data in the Year'
},name='report_data_for_year' ),
...
You need to do a redirect to desired page with JS. Or you can accept a year as a get paramener with year = request.GET.get('year').