Skip to content
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

How could I use AutoCrud with a custom Form-Renderer for company #84

Open
smikesmike opened this issue Feb 26, 2024 · 4 comments
Open

Comments

@smikesmike
Copy link

Hi,
I want to use AutoCrud in ContactsView.tsx but I don't know how to implement a custom form-renderer for the field company.
Could you show me an example?

Thanks in advance
Marc

@smikesmike
Copy link
Author

I've tried something like this in ContactsView.tsx:

import {AutoCrud} from '@hilla/react-crud';
import {ContactService, CRMService} from "Frontend/generated/endpoints";
import ContactDtoModel from "Frontend/generated/com/example/application/services/ContactDtoModel";
import ContactDto from "Frontend/generated/com/example/application/services/ContactDto";
import {TextArea} from "@hilla/react-components/TextArea";
import {useEffect, useState} from "react";
import {Select, SelectItem} from "@hilla/react-components/Select";

function CompanyRenderer({ item }: { item: ContactDto }) {
    const { company } = item;
    return <span >{company.name}</span>;
}

export function ContactsView() {
    const [companies, setCompanies] = useState<SelectItem[]>([]);

    useEffect(() => {
        getCompanies();
    }, []);

    async function getCompanies() {
        const companies = await CRMService.findAllCompanies();
        const companyItems = companies.map(company => {
            return {
                label: company.name,
                value: company.id + ""
            };
        });
        setCompanies(companyItems);
    }

    return <AutoCrud service={ContactService}
                     model={ContactDtoModel}
                     gridProps={{
                         visibleColumns: ['firstName', 'lastName', 'email', 'company'],
                         columnOptions: {
                             company: { title: 'Foo', renderer: CompanyRenderer},
                         },
                     }}
                     formProps={{
                         visibleFields: ['firstName', 'lastName', 'email', 'company'],
                         fieldOptions: {
                             firstName: { label: 'Name' },
                             company: {
                                 label: 'Company'
                                 , renderer: ({field}) => <Select label="Company" items={companies}  />

                             },
                             description: {
                                 renderer: ({ field }) => <TextArea {...field} label="Full description" />,
                             },
                         },
                     }}
   />;
}

but I habe no idea how to bind the combobox to the ContactDto.company field.

@sissbruecker
Copy link

The select component only works with string values, while the property you want to bind contains an object. One option would be to add another property companyId to ContactDto and bind that to the select. In the save method of your CrudService you would use companyId to assign the company to the contact.

The AutoCrud configuration would look like this:

<AutoCrud 
  service={ContactService}
  model={ContactDtoModel}
  gridProps={...}
  formProps={{
    visibleFields: ['firstName', 'lastName', 'email', 'companyId'],
    fieldOptions: {
      firstName: { label: 'Name' },
      companyId: {
        renderer: ({field}) => <Select {...field} label="Company" items={companies}  />
      },
      description: {
        renderer: ({ field }) => <TextArea {...field} label="Full description" />,
      },
    },
  }}
/>

@sissbruecker
Copy link

ComboBox makes this a bit easier actually, as it supports binding objects:

// No need to map items when using combo box
const [companies, setCompanies] = useState<CompanyDto[]>([]);

useEffect(() => {
  CRMService.findAllCompanies().then(setCompanies);
}, []);

// In the field renderer, render a combo box and configure it to use name and ID from company
<ComboBox {...field} label="Company" items={companies} itemLabelPath="name" itemValuePath="id" itemIdPath="id"  />

@smikesmike
Copy link
Author

Thank you very much. The solution with ComboBox was exactly what I was searching for.

Now, it works very nice;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants