Skip to content

Added option to hide folder checkbox #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
79 changes: 56 additions & 23 deletions fancytree/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from django.utils.safestring import mark_safe
from django.utils.datastructures import MultiValueDict, MergeDict
from mptt.templatetags.mptt_tags import cache_tree_children
from mptt.forms import TreeNodeChoiceField

try:
import simplejson as json
Expand All @@ -28,27 +29,30 @@ def get_doc(node, values):
doc['expand'] = True
return doc

def recursive_node_to_dict(node, values):
def recursive_node_to_dict(node, values, hide_folder_checkbox):
result = get_doc(node, values)
children = [recursive_node_to_dict(c, values) for c in node.get_children()]
children = [recursive_node_to_dict(c, values, hide_folder_checkbox) for c in node.get_children()]
if children:
expand = [c for c in children if c.get('selected', False)]
if expand:
result["expand"] = True
result["folder"] = True
if hide_folder_checkbox:
result['hideCheckbox'] = True
result['children'] = children
return result

def get_tree(nodes, values):
def get_tree(nodes, values, hide_folder_checkbox):
root_nodes = cache_tree_children(nodes)
return [recursive_node_to_dict(n, values) for n in root_nodes]
return [recursive_node_to_dict(n, values, hide_folder_checkbox) for n in root_nodes]

class FancyTreeWidget(Widget):
def __init__(self, attrs=None, choices=(), queryset=None, select_mode=2):
def __init__(self, attrs=None, choices=(), queryset=None, select_mode=2, hide_folder_checkbox=False):
super(FancyTreeWidget, self).__init__(attrs)
self.queryset = queryset
self.select_mode = select_mode
self.choices = list(choices)
self.hide_folder_checkbox = hide_folder_checkbox

def value_from_datadict(self, data, files, name):
if isinstance(data, (MultiValueDict, MergeDict)):
Expand All @@ -63,12 +67,17 @@ def render(self, name, value, attrs=None, choices=()):
has_id = attrs and 'id' in attrs
final_attrs = self.build_attrs(attrs, name=name)
if has_id:
output = [u'<div id="%s"></div>' % attrs['id']]
output = [u'<div id="f%s"></div>' % attrs['id']]
id_attr = u' id="%s_checkboxes"' % (attrs['id'])
else:
output = [u'<div></div>']
id_attr = u''
output.append(u'<ul class="fancytree_checkboxes"%s>' % id_attr)
# output.append(u'<ul class="fancytree_checkboxes"%s>' % id_attr)
if self.select_mode == 3:
multiple_tag = u'multiple'
else:
multiple_tag = u''
output.append(u'<select id="%s" name="%s" class="fancytree_checkboxes"%s %s>' % (attrs['id'], name, id_attr, multiple_tag))
str_values = set([force_unicode(v) for v in value])
for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
if has_id:
Expand All @@ -77,35 +86,58 @@ def render(self, name, value, attrs=None, choices=()):
else:
label_for = ''

cb = forms.CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
# cb = forms.CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
option_value = force_unicode(option_value)
rendered_cb = cb.render(name, option_value)
# rendered_cb = cb.render(name, option_value)
option_label = conditional_escape(force_unicode(option_label))
output.append(
u'<li><label%s>%s %s</label></li>' % (label_for, rendered_cb, option_label)
)
output.append(u'</ul>')
# output.append(
# u'<label%s>%s %s</label>' % (label_for, rendered_cb, option_label)
# )
sel = u''
try:
if option_value == force_unicode(value[0]) and self.select_mode != 3:
sel = u' selected '
elif option_value in force_unicode(value) and self.select_mode == 3:
sel = u' selected '
except IndexError:
pass
output.append(u'<option value="%s" name="%s" id="id_%s_%s" %s> '
u'%s</option>' % (option_value, name, name, option_value, sel, option_label))

output.append(u'</select>')
output.append(u'<script type="text/javascript">')
js_data_var = 'fancytree_data_%s' % (attrs['id'].replace('-', '_'))
if has_id:
output.append(u'var %s = %s;' % (
js_data_var,
json.dumps(get_tree(self.queryset, str_values))
json.dumps(get_tree(self.queryset, str_values, self.hide_folder_checkbox))
))
output.append(
"""
$(".fancytree_checkboxes").hide();
$(function() {
$("#%(id)s").fancytree({
$("#f%(id)s").fancytree({

checkbox: true,
clickFolderMode: 2,
activeVisible: true,
selectMode: %(select_mode)d,
source: %(js_var)s,
debugLevel: %(debug)d,
beforeSelect: function(event, data){
// A node is about to be selected: prevent this, to limit node selections:
if( $('#%(id)s option:selected').length == 5 &! data.node.isSelected() ){
alert('You can only choose 5!');
return false;
}
},
select: function(event, data) {
$('#%(id)s_checkboxes').find('input[type=checkbox]').prop('checked', false);
// $('#%(id)s').prop('selectedIndex',0);
$("#%(id)s option:selected").prop("selected", false);
var selNodes = data.tree.getSelectedNodes();
var selKeys = $.map(selNodes, function(node){
$('#%(id)s_' + (node.key)).prop('checked', true);
$('#%(id)s_' + (node.key)).prop('selected', true);
$( "#%(id)s" ).change();
return node.key;
});
},
Expand Down Expand Up @@ -134,9 +166,10 @@ def render(self, name, value, attrs=None, choices=()):
return mark_safe(u'\n'.join(output))

class Media:
css = {
'all': ('fancytree/skin-vista/ui.fancytree.css',)
}
js = (
'fancytree/jquery.fancytree.min.js',
)
pass
# css = {
# 'all': ('css/fancytree/skin-vista/ui.fancytree.css',)
# }
# js = (
# 'js/fancytree/jquery.fancytree.min.js',
# )