Serenity: is there a CheckBoxGroupEditor or how to do?

Created on 28 Sep 2019  路  8Comments  路  Source: serenity-is/Serenity

public class xxForm { public String Day{ get; set; } }

how to show as checkbox group?
cb

Thanks!

Most helpful comment

Hi,
image

image

this is my Editor:
create checkboxEditor

namespace Serenity {

    function Editor(name: string, intf?: any[]) {
        return Decorators.registerEditor('Serenity.' + name + 'Editor', intf)
    }
    import Element = Decorators.element

    export interface CheckboxButtonEditorOptions {
        enumKey?: string;
        enumType?: any;
        lookupKey?: string;
    }

    @Serenity.Decorators.editor()
    @Editor('CheckboxButton', [IStringValue])
    @Element('<div/>')
    export class CheckboxButtonEditor extends Widget<CheckboxButtonEditorOptions> {
        constructor(input: JQuery, opt: CheckboxButtonEditorOptions) {
            super(input, opt);

            if (Q.isEmptyOrNull(this.options.enumKey) &&
                this.options.enumType == null &&
                Q.isEmptyOrNull(this.options.lookupKey)) {
                return;
            }

            if (!Q.isEmptyOrNull(this.options.lookupKey)) {
                var lookup = Q.getLookup(this.options.lookupKey);
                for (var item of lookup.items) {
                    var textValue = item[lookup.textField];
                    var text = (textValue == null ? '' : textValue.toString());
                    var idValue = item[lookup.idField];
                    var id = (idValue == null ? '' : idValue.toString());
                    this.addChecbox(id, text);
                }
            }
            else {
                var enumType = this.options.enumType || Serenity.EnumTypeRegistry.get(this.options.enumKey);
                var enumKey = this.options.enumKey;
                if (enumKey == null && enumType != null) {
                    var enumKeyAttr = (ss as any).getAttributes(enumType, Serenity.EnumKeyAttribute, false);
                    if (enumKeyAttr.length > 0) {
                        enumKey = enumKeyAttr[0].value;
                    }
                }

                var values = (ss as any).Enum.getValues(enumType);
                for (var x of values) {
                    var name = (ss as any).Enum.toString(enumType, x);
                    this.addChecbox(x.toString(), Q.coalesce(Q.tryGetText(
                        'Enums.' + enumKey + '.' + name), name));
                }
            }
        }

        protected addChecbox(value: string, text: string) {
            var label = $('<label/>').text(text);
            $('<input type="checkbox"/>').attr('name', this.uniqueName)
                .attr('id', this.uniqueName + '_' + value)
                .attr('value', value).prependTo(label);
            label.appendTo(this.element);
        }

        get_value(): string {
            let val: number[] = new Array();
            this.element.find('input:checked').each((i, e) => {
                val.push(Q.toId($(e).val()));
            });
            return val.join(',');
        }

        get value(): string {
            return this.get_value();
        }

        set_value(value: string): void {
            if (value !== this.get_value()) {
                let values: number[] = [];
                if (!Q.isEmptyOrNull(value))
                    values = value.split(',').map(p => Number(p));
                var inputs = this.element.find('input');
                inputs.each((i, e) => {
                    (e as HTMLInputElement).checked = false;
                });

                if (Q.isArray(values)) {
                    values.forEach((v, i) => {
                        let checks = inputs.filter('[value=' + v + ']');
                        if (checks.length > 0) {
                            (checks[0] as HTMLInputElement).checked = true;
                        }
                    })
                } else {
                    let checks = inputs.filter('[value=' + values + ']');
                    if (checks.length > 0) {
                        (checks[0] as HTMLInputElement).checked = true;
                    } 
                }
            }
        }

        set value(v: string) {
            this.set_value(v);
        }
    }
}

In xyzForm.cs or xyzRow.cs
with Enum:

        [CheckboxButtonEditor(EnumKey = "PattisonSand.TblInvoices.Status") ]
        public String TestCheckBox { get; set; }

or
with Lookup

        [CheckboxButtonEditor(LookupKey = "Default.TblRailcarTypeLookup") ]
        public String TestCheckBox { get; set; }

Use to filter on grid:
In xyzRow.cs or xyzColumn.cs

        [CheckboxButtonEditor, QuickFilter]
        public String TestCheckBox  { get; set; }

In zxyGrid.ts

 protected getQuickFilters(): Serenity.QuickFilter<Serenity.Widget<any>, any>[] {

            // get quick filter list from base class, e.g. columns
            let filters = super.getQuickFilters();

            let statusfilter = Q.first(filters, x => x.field == fld.TestCheckBox  );
            statusfilter.element = e => {
                this.statusFilter = e;
                this.statusFilter.parent().find('span.quick-filter-label').remove();
            };
            statusfilter.handler = h => {
                // if filter is active, e.g. editor has some value
                if (h.active) {
                        h.request.Criteria = Serenity.Criteria.and(h.request.Criteria, [[fld.Status], '=', h.value]);
                }
            };

            return filters;
        }

Hope help you

All 8 comments

Hi,
image

image

this is my Editor:
create checkboxEditor

namespace Serenity {

    function Editor(name: string, intf?: any[]) {
        return Decorators.registerEditor('Serenity.' + name + 'Editor', intf)
    }
    import Element = Decorators.element

    export interface CheckboxButtonEditorOptions {
        enumKey?: string;
        enumType?: any;
        lookupKey?: string;
    }

    @Serenity.Decorators.editor()
    @Editor('CheckboxButton', [IStringValue])
    @Element('<div/>')
    export class CheckboxButtonEditor extends Widget<CheckboxButtonEditorOptions> {
        constructor(input: JQuery, opt: CheckboxButtonEditorOptions) {
            super(input, opt);

            if (Q.isEmptyOrNull(this.options.enumKey) &&
                this.options.enumType == null &&
                Q.isEmptyOrNull(this.options.lookupKey)) {
                return;
            }

            if (!Q.isEmptyOrNull(this.options.lookupKey)) {
                var lookup = Q.getLookup(this.options.lookupKey);
                for (var item of lookup.items) {
                    var textValue = item[lookup.textField];
                    var text = (textValue == null ? '' : textValue.toString());
                    var idValue = item[lookup.idField];
                    var id = (idValue == null ? '' : idValue.toString());
                    this.addChecbox(id, text);
                }
            }
            else {
                var enumType = this.options.enumType || Serenity.EnumTypeRegistry.get(this.options.enumKey);
                var enumKey = this.options.enumKey;
                if (enumKey == null && enumType != null) {
                    var enumKeyAttr = (ss as any).getAttributes(enumType, Serenity.EnumKeyAttribute, false);
                    if (enumKeyAttr.length > 0) {
                        enumKey = enumKeyAttr[0].value;
                    }
                }

                var values = (ss as any).Enum.getValues(enumType);
                for (var x of values) {
                    var name = (ss as any).Enum.toString(enumType, x);
                    this.addChecbox(x.toString(), Q.coalesce(Q.tryGetText(
                        'Enums.' + enumKey + '.' + name), name));
                }
            }
        }

        protected addChecbox(value: string, text: string) {
            var label = $('<label/>').text(text);
            $('<input type="checkbox"/>').attr('name', this.uniqueName)
                .attr('id', this.uniqueName + '_' + value)
                .attr('value', value).prependTo(label);
            label.appendTo(this.element);
        }

        get_value(): string {
            let val: number[] = new Array();
            this.element.find('input:checked').each((i, e) => {
                val.push(Q.toId($(e).val()));
            });
            return val.join(',');
        }

        get value(): string {
            return this.get_value();
        }

        set_value(value: string): void {
            if (value !== this.get_value()) {
                let values: number[] = [];
                if (!Q.isEmptyOrNull(value))
                    values = value.split(',').map(p => Number(p));
                var inputs = this.element.find('input');
                inputs.each((i, e) => {
                    (e as HTMLInputElement).checked = false;
                });

                if (Q.isArray(values)) {
                    values.forEach((v, i) => {
                        let checks = inputs.filter('[value=' + v + ']');
                        if (checks.length > 0) {
                            (checks[0] as HTMLInputElement).checked = true;
                        }
                    })
                } else {
                    let checks = inputs.filter('[value=' + values + ']');
                    if (checks.length > 0) {
                        (checks[0] as HTMLInputElement).checked = true;
                    } 
                }
            }
        }

        set value(v: string) {
            this.set_value(v);
        }
    }
}

In xyzForm.cs or xyzRow.cs
with Enum:

        [CheckboxButtonEditor(EnumKey = "PattisonSand.TblInvoices.Status") ]
        public String TestCheckBox { get; set; }

or
with Lookup

        [CheckboxButtonEditor(LookupKey = "Default.TblRailcarTypeLookup") ]
        public String TestCheckBox { get; set; }

Use to filter on grid:
In xyzRow.cs or xyzColumn.cs

        [CheckboxButtonEditor, QuickFilter]
        public String TestCheckBox  { get; set; }

In zxyGrid.ts

 protected getQuickFilters(): Serenity.QuickFilter<Serenity.Widget<any>, any>[] {

            // get quick filter list from base class, e.g. columns
            let filters = super.getQuickFilters();

            let statusfilter = Q.first(filters, x => x.field == fld.TestCheckBox  );
            statusfilter.element = e => {
                this.statusFilter = e;
                this.statusFilter.parent().find('span.quick-filter-label').remove();
            };
            statusfilter.handler = h => {
                // if filter is active, e.g. editor has some value
                if (h.active) {
                        h.request.Criteria = Serenity.Criteria.and(h.request.Criteria, [[fld.Status], '=', h.value]);
                }
            };

            return filters;
        }

Hope help you

@luongnv6 ,

really very good!

Regards,

John

@JohnRanger thank a lot

@luongnv6 ,

this would make a great wiki entry. Would you mind to put your code above into a new wiki page? :-)

(just more or less Copy & paste from here - and if necessary some little additional explanations.)

Regards,

John

Thank you very much !

        let cardDiv = $('<div class="card" style="width:18rem;" />');
        let cardImg = $('<img class="card-img-top" src="..." alt="Card image cap">');
        let cardBody = $('<div class="card-body">');
        let cardTitle = $('<h5 class="card-title">Card Title</h5>');

        var label = $('<label/>').text(text);
        $('<input type="checkbox"/>').attr('name', this.uniqueName)
            .attr('id', this.uniqueName + '_' + value)
            .attr('value', value).prependTo(label);`

       ` cardTitle.appendTo(cardBody);
        label.appendTo(cardBody);

        cardImg.appendTo(cardDiv);
        cardBody.appendTo(cardDiv);

        cardDiv.appendTo(this.element);`

but bootstrap css style "card" doesn't work . @luongnv6

Thanks for sharing, closing.

@luongnv6 your property here this.statusFilter = e; what is the type of object for property identifier for the statusFilter ?
I tried Serenity.QuickFilter(,); and it does not like that ..

Was this page helpful?
0 / 5 - 0 ratings