|
14 | 14 | {%endif%} |
15 | 15 | {%for field in form%} |
16 | 16 | {%if not field.is_hidden%} |
| 17 | + {%if field.name == 'tags' and form.checkbox_tags %} |
| 18 | + {# Render the tags field with checkbox shortcuts #} |
| 19 | + <div class="form-group"> |
| 20 | + <label class="control-label">Tags</label> |
| 21 | + <div class="col-lg-12 controls"> |
| 22 | + {# Checkbox shortcuts for common tags #} |
| 23 | + <div class="btn-group flex-wrap tag-checkbox-group mb-2" role="group" aria-label="Quick tag selection"> |
| 24 | + <button type="button" class="btn btn-sm btn-outline-secondary" disabled>Shortcuts:</button> |
| 25 | + {%for tag in form.checkbox_tags%} |
| 26 | + <input type="checkbox" class="btn-check tag-shortcut-checkbox" data-tag-id="{{tag.id}}" data-tag-name="{{tag.name}}" id="tag_shortcut_{{tag.id}}" autocomplete="off"> |
| 27 | + <label class="btn btn-sm btn-outline-primary d-inline-flex align-items-center" for="tag_shortcut_{{tag.id}}"><span class="tag-color" style="background-color: {{tag.color}}; width: 10px; height: 10px; border-radius: 2px; margin-right: 4px; margin-top: 1px;"></span>{{tag.name}}</label> |
| 28 | + {%endfor%} |
| 29 | + </div> |
| 30 | + {# The actual selectize field for all tags #} |
| 31 | + {{field}} |
| 32 | + {%if field.help_text%}<br/>{{field.help_text|safe}}{%endif%} |
| 33 | + {# "No tags apply" checkbox below the selectize (only for new patches) #} |
| 34 | + {%if form.no_tags_apply %} |
| 35 | + <div class="form-check mt-2"> |
| 36 | + <input type="checkbox" class="form-check-input" name="no_tags_apply" id="id_no_tags_apply" {% if form.no_tags_apply.value %}checked{% endif %}> |
| 37 | + <label class="form-check-label" for="id_no_tags_apply">{{form.no_tags_apply.label}}</label> |
| 38 | + {%if form.no_tags_apply.help_text%}<small class="form-text text-muted d-block">{{form.no_tags_apply.help_text}}</small>{%endif%} |
| 39 | + </div> |
| 40 | + {%endif%} |
| 41 | + </div> |
| 42 | + </div> |
| 43 | + {%elif field.name == 'no_tags_apply' %} |
| 44 | + {# Skip - rendered as part of the tags group above #} |
| 45 | + {%else%} |
17 | 46 | <div class="form-group"> |
18 | 47 | {{field|label_class:"control-label"}} |
19 | 48 | <div class="col-lg-12 controls"> |
|
32 | 61 | {%elif not field.name in form.selectize_fields%}{{field|field_class:"form-control"}}{%else%}{{field}}{%endif%} |
33 | 62 | {%if field.help_text%}<br/>{{field.help_text|safe}}{%endif%}</div> |
34 | 63 | </div> |
| 64 | + {%endif%} |
35 | 65 | {%else%} |
36 | 66 | {{field}} |
37 | 67 | {%endif%} |
@@ -92,5 +122,63 @@ <h3 class="modal-title">Search user</h3> |
92 | 122 | $('#searchUserSearchField').focus(); |
93 | 123 | }); |
94 | 124 | {%endif%} |
| 125 | + |
| 126 | + // Tag shortcut checkbox synchronization with selectize |
| 127 | + (function() { |
| 128 | + var $tagsSelect = $('#id_tags'); |
| 129 | + if (!$tagsSelect.length || !$tagsSelect[0].selectize) return; |
| 130 | + |
| 131 | + var selectize = $tagsSelect[0].selectize; |
| 132 | + var $checkboxes = $('.tag-shortcut-checkbox'); |
| 133 | + var $noTagsCheckbox = $('#id_no_tags_apply'); |
| 134 | + |
| 135 | + // Initialize checkbox state from current selectize values |
| 136 | + function syncCheckboxesFromSelectize() { |
| 137 | + var selectedIds = selectize.getValue(); |
| 138 | + if (typeof selectedIds === 'string') { |
| 139 | + selectedIds = selectedIds ? selectedIds.split(',') : []; |
| 140 | + } |
| 141 | + selectedIds = selectedIds.map(function(id) { return String(id); }); |
| 142 | + |
| 143 | + $checkboxes.each(function() { |
| 144 | + var tagId = String($(this).data('tag-id')); |
| 145 | + $(this).prop('checked', selectedIds.indexOf(tagId) !== -1); |
| 146 | + }); |
| 147 | + |
| 148 | + // Uncheck "no tags apply" if any tags are selected |
| 149 | + if ($noTagsCheckbox.length && selectedIds.length > 0) { |
| 150 | + $noTagsCheckbox.prop('checked', false); |
| 151 | + } |
| 152 | + } |
| 153 | + |
| 154 | + // Sync on selectize change |
| 155 | + selectize.on('change', syncCheckboxesFromSelectize); |
| 156 | + |
| 157 | + // Handle checkbox clicks |
| 158 | + $checkboxes.on('change', function() { |
| 159 | + var tagId = String($(this).data('tag-id')); |
| 160 | + if ($(this).is(':checked')) { |
| 161 | + selectize.addItem(tagId, true); |
| 162 | + if ($noTagsCheckbox.length) { |
| 163 | + $noTagsCheckbox.prop('checked', false); |
| 164 | + } |
| 165 | + } else { |
| 166 | + selectize.removeItem(tagId, true); |
| 167 | + } |
| 168 | + }); |
| 169 | + |
| 170 | + // Handle "no tags apply" checkbox (only exists for new patches) |
| 171 | + if ($noTagsCheckbox.length) { |
| 172 | + $noTagsCheckbox.on('change', function() { |
| 173 | + if ($(this).is(':checked')) { |
| 174 | + selectize.clear(true); |
| 175 | + $checkboxes.prop('checked', false); |
| 176 | + } |
| 177 | + }); |
| 178 | + } |
| 179 | + |
| 180 | + // Initial sync |
| 181 | + syncCheckboxesFromSelectize(); |
| 182 | + })(); |
95 | 183 | </script> |
96 | 184 | {%endblock%} |
0 commit comments