django tables2 checkbox - django

I'm new to programming so this may be a trivial question...
In django-tables2, I'd like to be able to display the column header name when using CheckBoxColumn. Right now, all the checkboxes are displaying for each row, including in the header. I don't mind having a checkbox in the header (I figure that would be a great way to do a "select all" in the long run), but I need the column name to display. Does anyone have a solution for this?

Create your own custom checkbox column class that inherits from tables.CheckBoxColumn
then override the render method, then specify the check box together with its label as html response.
class CustomCheckBoxColumn(tables.CheckBoxColumn):
def render(self, value, record, bound_column):
return mark_safe(u'column Name<input type=checkbox, … />')

Another option is to use the TemplateColumn() instead of CheckBoxColumn()
template = '<input type="checkbox" name="{{record.name}}" />'
checkbox_column_header = tables.TemplateColumn(template)

Related

django tables2 create extra column with links

I am trying to add a extra column to one of my tables, that adds url to another page.
My Table:
class ItemTable(tables.Table):
edit = tables.LinkColumn('item_edit', args=[A('pk')])
class Meta:
model = Item
fields = ('name', 'slot', 'klass', 'rarity', 'price')
my urls:
url(r'^admin/item/edit/(?P<item_id>\d+)/$', views.item_edit, name='item_edit')
Now with this, i get my table, but the last column (edit) only has dashes + the page crashes when i click the title.
i have been looking at http://django-tables2.readthedocs.org/en/latest/#django_tables2.columns.LinkColumn and im not sure where i go wrong
The problems you've encountered are caused by LinkColumn expecting to be bound to a specific attribute in your Item model, i.e. it is looking for an Item.edit attribute on your instances.
Since you don't actually have an Item.edit attribute, ordering over your edit column makes no sense, and you should mark it as non-orderable:
from django_tables2.utils import A
edit = tables.LinkColumn('item_edit', args=[A('pk')], orderable=False)
The text of the link itself would come from the value of the Item.edit attribute, which you don't have, so you will need to provide it yourself by adding a render_edit method to your table class:
def render_edit(self):
return 'Edit'
You can replace the 'Edit' string with whatever you want displayed in that column.
Update: As suggested by #SunnySydeUp, you also need to specify empty_values=() for the column, in order to get its value rendered:
edit = tables.LinkColumn('item_edit', args=[A('pk')], orderable=False, empty_values=())
References:
http://django-tables2.readthedocs.org/en/latest/pages/order-by-accessors.html#specifying-alternative-ordering-for-a-column
http://django-tables2.readthedocs.org/en/latest/pages/custom-rendering.html#table-render-foo-methods
Disclaimer: This answer is based on the django-tables2 documentation and source code, and hasn't been tested on an actual Django application.
To have the link properly formatted and with a link text of your choice, you can do the following in the table class:
def render_edit_link(self,record):
return mark_safe('<a href='+reverse("edit", args=[record.pk])+'>Edit</a>')
Where 'edit' is the name of the url.
I create clickable links in extra columns with
edit = tables.LinkColumn('item_edit', text='Edit', args=[A('pk')], \
orderable=False, empty_values=())
It's not necessary to override the render method; the 'text' parameter changes the text of the link from 'none' to 'Edit', for example.

How to set attribute on widget in flask-wtf?

I am using a TextArea provided by Flask-WTF.
numbers = forms.TextField('Numbers', [forms.validators.Required()], widget=forms.widgets.TextArea())
I want to change cols of the resulting fields to say 80. How do I accomplish this. I don't want to do it in template and would like to do this in form.
Django provides:
name = forms.TextInput(attrs={'size': 10, 'title': 'Your name',})
I want something similar.
You can do it during output in your html
like: form.numbers(cols=20)
Oh, sorry did not notice that you mentioned template.
Update:
Actualy also had this problem, my solution was to extend Form class and add dictionary to form objects.
So all custom attributes go into that dictionary and used on output. This can be done with custom template macros or redefining render methods

Setting selected entry using helper.options?

Im am using Play 2.0.4 and
helper.options(myitems)
in my template (inside of a helper.select)
In this case, how can I define the default selected entry, which shall be one entry out of myitems? Thanks for any hint!
A little bit more about my case:
Imagine a news archive, showing all news titles. This news archive uses pagination, pagination uses GET to pass the next/previous page number.
The play framework however will only correctly select the currently selected "select" item (here: news category) when a POST request was used - while pagination uses GET!
Intended behaviour: While a filter is applied / a specific news category is selected, this shall always be visible to the user by preselecting the currently selected news category in the "select" form.
A "screenshot" for illustration:
So, anyone having a good idea on how to cope with this problem? Any way to tell Play manually which entry from the "select" form it shall select? '_default always adds a new entry instead of selecting one out of the given options ): Would be great, if one wouldn't have to build the complete "select" form manually.
Try passing '_default option to select helper:
#import views.html.helper._
#select(form("email"), options(List("first", "third")), '_default -> "second")
It seems, unfortunately, the only way to figure it out is to look up the source.
Update:
Specifying _default property doesn't set selected attribute on option tag. It looks like the only way to preselect entry is to pass prefilled form to the template. For example, suppose you have following form:
case class RegInfo(email: String, color: String)
private val registrationForm = Form(
mapping(
"email" → email,
"color" → nonEmptyText(minLength = 5, maxLength = 32)
)(RegInfo.apply)(RegInfo.unapply)
)
Then in the action prefill form before passing to the view:
def create = Action {
Ok(html.create(registrationForm.fill(RegInfo("user#qwe.com", "blue"))))
}
Then in template use helper:
#select(form("color"), options(List("red", "green", "blue")))
And value will be preselected.
Ended up with the pragmatic approach:
<select id="myfield" name="myfield" >
<option class="blank" value="">-- All items --</option>
#for((key, value) <- MyModel.options) {
#if(key == GETValuePassedToTemplate) {
<option value="#key" selected>#value</option>
} else {
<option value="#key">#value</option>
}
}
</select>
Still wondering if there is a better option / way to do it.
Actually, there is a nicer solution to it. If you call the template having the form partially bound you will achieve your goal. Here's the code for your controller:
Ok(views.html.myForm(myForm.bind(
Map("fieldName1" -> "value1",
"fieldName2" -> "value2"))))
Make sure you map fieldnames to the values of the options you want pre-selected.
Still wondering if there is a better option / way to do it.
Well, if your not hell-bent on using play to solve this particular problem, you could always solve it using JavaScript and jQuery:
$(function () {
$('#yourSelect_id').val(5);
}
Where your select options each has values and the one option you whish to pre select has value 5.

django admin list_filter too long

I have a list_filter with loads of sectors. This list, on the right side of the page, is too long.
Can I use an input select field instead since I can't choose more than one sector?
I have seen this before, screenshots, but I can not find the way to do this.
edit:
I have a custom FilterSpec not a list_filter
You can write your own custom FilterSpec (custom admin list filter).
This feature is not part of the Django code yet; it is planned for version 1.2. You'll need to apply this patch to the Django code: http://code.djangoproject.com/ticket/5833.
There are many examples on stackoverflow on how to do that, e.g: https://stackoverflow.com/a/1294952/342473.
http://lincolnloop.com/blog/2011/jan/11/custom-filters-django-admin/
The long list that you said comes from the default template 'admin/filter.html', in django/contrib/admin/templates/admin/filter.html, of builtin ListFilters.
There are several ways to customize it:
Globally override 'admin/filter.html'. Render select tag instead of ul tag if the count of choices hit certain limit. This affects all list filters in admin. The select tag should have onchange event handler like
<select ... onchange="location.href=this.options[this.selectedIndex].value">
Set template attribute in your specific ListFilter instance, to the name of the customized filter template. The content of the template is like #1. Django 1.4+ is required for this.
Add javascript in the ModelAdmin instance to convert HTML content inside the ul tag to select tag as soon as DOM has been fully loaded.
This is how i resolved it (jQuery):
$('#changelist-filter ul').each(function(){
var maxlength = 10;
if ($(this).children().length > maxlength )
{
var list=$(this),
select=$(document.createElement('select')).insertBefore($(this).hide());
$('>li a', this).each(function(){
console.log($(this).parent().attr('class'));
var target=$(this).attr('target'),
option=$(document.createElement('option'))
.appendTo(select)
.val(this.href)
.attr('selected', $(this).parent().attr('class'))
.html($(this).html())
.click(function(){
if (target==='_blank'){
window.open($(this).val());
}
else{
window.location.href=$(this).val();
}
});
});
list.remove();
}
});

django - insert a custom option in a select statement that is auto-generated from database table

I have a drop down (select) form that pulls the select options form a database table. The options change almost all the time depending on certain variable.
I need to add one more option all the way to the bottom of the drop down that will always be the same. Something that will say "more options". Any ideas? Thanks!
This is easy enough to do by overriding __init__ on the Form sub-class you're using. It should work equally well on a ModelForm as well. I'm not sure how you're populating the choices based on the question though.
class ChoiceForm(Form):
choice = ModelChoiceField(queryset=MyModel.objects.all())
def __init__(self, *args, **kw):
super(ChoiceForm, self).__init__(*args, **kw)
# Add to choices iterator
choice_field = self.fields['choice']
choice_field.choices = list(choice_field.choices) + [(0, 'More Options')]
This gives the following when rendered with <p> tags:
<p>
<label for="id_choice">Choice:</label>
<select name="choice" id="id_choice">
<option value="" selected="selected">---------</option>
<option value="0">More Options</option>
</select>
</p>
Be warned though, this fields choices will be fixed after you create it. A normal ModelChoiceField will auto-update its choices if the results of the queryset you passed it would be changed.
I would solve in this way:
1- render the select box as you currently do
2- create two hidden select boxes, 1 with limited choices and the other with the full list
3- when the user clicks on the "more options" button all options are flushed and the it will be repopulated with the ones from the full select box.
4- as an option you may want the user to go back to "less options", in this case you just have to flush again the options and to load from the hidden select box with limited choices.
In order to to that you just need the template to render the 2 select boxes (less opts and more opts) with style="display:none" css property and then to write the js button(s) click event (I would normally to that in jQuery) to do the switching.
Hope it helps, just ask if you need some code samples