Skip to content
This repository has been archived by the owner on Oct 5, 2022. It is now read-only.

Label/header customisation and better defaults #16

Merged
merged 8 commits into from
Sep 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions condensedinlinepanel/edit_handlers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from __future__ import absolute_import, unicode_literals
import six

import json
import django
from django import forms
from django.utils.translation import ugettext_lazy as _

from modelcluster.forms import BaseChildFormSet

Expand Down Expand Up @@ -108,6 +110,7 @@ def get_form_extra_data(form):
'forms': [
{
'id': i,
'instanceAsStr': six.text_type(form.instance),
'fields': {
field_name: form[field_name].value()
for field_name in form.fields.keys()
Expand Down Expand Up @@ -154,29 +157,42 @@ def required_formsets(cls):


class CondensedInlinePanel(object):
def __init__(self, relation_name, panels=None, label='', help_text='', min_num=None, max_num=None, card_header_from_field=None, card_header_from_js=None, card_header_from_js_safe=None):
def __init__(self, relation_name, panels=None, heading='', label='', help_text='', min_num=None, max_num=None, card_header_from_field=None, card_header_from_js=None, card_header_from_js_safe=None, new_card_header_text=""):
self.relation_name = relation_name
self.panels = panels
# TODO: label is used below for backwards compatibility. We may want to rethink this later.
self.heading = heading or label
self.label = label
self.help_text = help_text
self.min_num = min_num
self.max_num = max_num
self.card_header_from_field = card_header_from_field
self.card_header_from_js = card_header_from_js
self.card_header_from_js_safe = card_header_from_js_safe
self.new_card_header_text = new_card_header_text

def bind_to_model(self, model):
if django.VERSION >= (1, 9):
related = getattr(model, self.relation_name).rel
else:
related = getattr(model, self.relation_name).related

related_name = {
'related_verbose_name': related.related_model._meta.verbose_name,
'related_verbose_name_plural': related.related_model._meta.verbose_name_plural
}
heading = self.heading or _('%(related_verbose_name_plural)s') % related_name
new_card_header = self.new_card_header_text or _('New %(related_verbose_name)s') % related_name
label = self.label or _('Add %(related_verbose_name)s') % related_name

return type(str('_CondensedInlinePanel'), (BaseCondensedInlinePanel,), {
'model': model,
'relation_name': self.relation_name,
'related': related,
'panels': self.panels,
'heading': self.label,
Copy link
Collaborator

@kaedroho kaedroho Aug 18, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should leave the heading field called label so it's the same as Wagtail's builtin InlinePanel.

EDIT: Scratch that. What you suggested in your last comment sounds good to me

'heading': heading,
'new_card_header': new_card_header,
'label': label,
'help_text': self.help_text,
# TODO: can we pick this out of the foreign key definition as an alternative?
# (with a bit of help from the inlineformset object, as we do for label/heading)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ var CondensedInlinePanel =
var canDelete = options['canDelete'] || canEdit;
var canOrder = options['canOrder'] || false;
var renderCardHeader = options['renderCardHeader'] || renderCardHeaderDefault;
var panelLabel = options['panelLabel'] || "Add";
var element = document.getElementById(id);
if (element === null) {
console.error("CondensedInlinePanel.init(): Element with id '" + id + "' does not exist.");
Expand Down Expand Up @@ -93,7 +94,7 @@ var CondensedInlinePanel =
return;
}
var state = store.getState() || state_1.emptyState();
ReactDOM.render(React.createElement(CardSet_1.DNDCardSet, { forms: state.forms, renderCardHeader: renderCardHeader, canEdit: canEdit, canDelete: canDelete, canOrder: canOrder, store: store, emptyForm: state.emptyForm, formTemplate: element.dataset['formTemplate'], formsetPrefix: id, sortCompareFunc: sortCompareFunc }), uiContainer);
ReactDOM.render(React.createElement(CardSet_1.DNDCardSet, { forms: state.forms, panelLabel: panelLabel, renderCardHeader: renderCardHeader, canEdit: canEdit, canDelete: canDelete, canOrder: canOrder, store: store, emptyForm: state.emptyForm, formTemplate: element.dataset['formTemplate'], formsetPrefix: id, sortCompareFunc: sortCompareFunc }), uiContainer);
});
// Keep sort order field up to date
if (canOrder) {
Expand Down Expand Up @@ -28787,7 +28788,7 @@ var CondensedInlinePanel =
e.preventDefault();
return false;
};
addButton = React.createElement("button", { className: "condensed-inline-panel__top-add-button button bicolor icon icon-plus", type: "button", onClick: onClickAddButton }, "Add");
addButton = React.createElement("button", { className: "condensed-inline-panel__top-add-button button bicolor icon icon-plus", type: "button", onClick: onClickAddButton }, this.props.panelLabel);
}
return React.createElement("div", null,
addButton,
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface CardSetProps {
store: Store<State | null | undefined>,
dndKey?: string,
formsetPrefix: string,
panelLabel: string,
renderCardHeader: renderCardHeaderFn,
canEdit: boolean,
canDelete: boolean,
Expand Down Expand Up @@ -178,7 +179,7 @@ export class CardSet extends React.Component<CardSetProps, {}> {
e.preventDefault();
return false;
};
addButton = <button className="condensed-inline-panel__top-add-button button bicolor icon icon-plus" type="button" onClick={onClickAddButton}>Add</button>;
addButton = <button className="condensed-inline-panel__top-add-button button bicolor icon icon-plus" type="button" onClick={onClickAddButton}>{this.props.panelLabel}</button>;
}

return <div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface Options {
canDelete?: boolean,
canOrder?: boolean,
renderCardHeader?: renderCardHeaderFn,
panelLabel?: string,
}


Expand All @@ -31,6 +32,7 @@ export function init(id: string, options: Options = {}) {
const canDelete = options['canDelete'] || canEdit;
const canOrder = options['canOrder'] || false;
const renderCardHeader = options['renderCardHeader'] || renderCardHeaderDefault;
const panelLabel = options['panelLabel'] || "Add";

let element = document.getElementById(id);
if (element === null) {
Expand Down Expand Up @@ -63,6 +65,7 @@ export function init(id: string, options: Options = {}) {

let state = store.getState() || emptyState();
ReactDOM.render(<DNDCardSet forms={state.forms}
panelLabel={panelLabel}
renderCardHeader={renderCardHeader}
canEdit={canEdit}
canDelete={canDelete}
Expand Down
3 changes: 3 additions & 0 deletions condensedinlinepanel/static/condensedinlinepanel/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export interface Form {
// Note: Not the same as the primary key of the object
id: number,

// The in python string representation of the object
instanceAsStr?: string,

// Is the form being edited (aka. is it expanded?)
isEditing?: boolean,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
CondensedInlinePanel.init('id_{{ self.formset.prefix }}', {
summaryTextField: '{{ self.formset.summary_text_field|escapejs }}',
canOrder: {{ self.formset.can_order|lower }},
panelLabel: "{{ self.label }}",
renderCardHeader: function(form) {
{% if self.card_header_from_field %}
{# Get the card header value from a field and escape it #}
var value = form.fields['{{ self.card_header_from_field|escapejs }}'];
if (form.isNew){
value = "{{ self.new_card_header }}";
}
var needsEscaping = true;
{% elif self.card_header_from_js %}
{# The card_header_from_js field is set by a developer so we can assume it's safe #}
Expand All @@ -17,12 +21,17 @@
var needsEscaping = false;
{% else %}
{# Developer forgot to set this #}
var value = "";
var needsEscaping = false;
if (form.instanceAsStr===undefined){
var value = "{{ self.new_card_header }}";
} else {
var value = form.instanceAsStr;
}
var needsEscaping = true;
{% endif %}

if (value==null){
var value = "";
value = "";
needsEscaping = false;
}

value = value.toString();
Expand Down
4 changes: 3 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
'Framework :: Django :: 1.9',
'Topic :: Internet :: WWW/HTTP :: Site Management',
],
install_requires=[],
install_requires=[
'six>=1.10.0',
],
zip_safe=False,
)