SvelteSuperForm - Checkbox value instead of boolean - Stack Overflow

I try to use checkboxs with SuperForm (and formFieldProxy).And i have some problems:i don't under

I try to use checkboxs with SuperForm (and formFieldProxy).

And i have some problems:

  • i don't understand why i have no way (or don't find the one) to retrieve checkbox value instead of the checked boolean (native html checkbox send input value, the value is just conditioned by the checked state)
  • when i try to use bind:group i retrieve checkboxs values but all are stored as array

My reservation Zod schema

const ReservationObject = z.object({
    id: z.string().uuid(),
    reservation_id: z.string(),
    denomination: z.string(),
    price: z.coerce.number(),
    options: z.array(
        z.object({
            id: z.string().uuid(),
            optionDenomination: z.string(),
            price: z.coerce.number()
        })
    ),
    total: z.number().optional(),
    isBooked: z.boolean()
});

const ReservationsObject = z.object({
    reservation_id: z.string(),
    isSuspended: z.boolean(),
    booking: z.array(ReservationObject)
});

The schema used for form values

export const BuyingReservation = z.object({
    buying: z.array(
        z.object({
            buyReservation: z.string().uuid(),
            buyReservationOption: z.array(z.string().uuid())
        })
    )
});

SuperForm object

const defaultBuyingEntry = [{ buyReservation: '', buyReservationOption: [] }];
const buying: BuyingReservation = { buying: defaultBuyingEntry };
const superform = superForm(buying, {
    dataType: 'json',
    resetForm: false,
    invalidateAll: false
});
const { form, submitting, enhance } = superform;

The form

<form method="POST" use:enhance action="/" class={styles['form']}>
    {#each booking.booking as item, index}
        <div class={styles['booking__row']}>
            <p class={styles['booking__row-denomination']}>
                {item.denomination} : <span>{item.price}€</span>
                <Input
                    {superform}
                    id={`${index}-buyReservation`}
                    field="buying[{index}].buyReservation"
                    type="checkbox"
                    label={'Réserver'}
                    value={item.id}
                    grouped={true}
                />
            </p>
            <div class={styles['booking__row-options']}>
                {#each item.options as option, optionIndex}
                    <div class={styles['booking__row-option']}>
                        <p class={styles['booking__row-options-denomination']}>
                            {option.optionDenomination} : <span>{option.price}€</span>
                        </p>
                        <Input
                            {superform}
                            id={`${index}-${optionIndex}-buyReservationOption`}
                            field="buying[{index}].buyReservationOption[{optionIndex}]"
                            type="checkbox"
                            label={'Ajouter'}
                            value={option.id}
                            grouped={true}
                        />
                    </div>
                {/each}
            </div>
        </div>
    {/each}
    <input
        type="submit"
        class={styles['form__field-static']}
        value="Reserver et payer"
        disabled={$submitting}
    />
</form>

My reusable input

let { label, className, field, superform, grouped, ...others }: Props = $props();
const { value, errors, constraints } =
    !!field && !!superform ? formFieldProxy(superform, field) : {};

<input
    {...others}
    name={field}
    data-invalid={$errors}
    aria-invalid={$errors ? 'true' : undefined}
    class={[styles['input'], className].join(' ')}
    {...$constraints}
    type="checkbox"
    bind:group={$value} // or bind:checked={$value}
/>

The results: if bind:checked

{
    "buying": [
        {
            "buyReservation": true,
            "buyReservationOption": [
                true,
                false
            ]
        },
    ]
}

if bind:group

{
    "buying": [
        {
            "buyReservation": [
                "61ee077d-9db9-4286-bd57-25d5ab0fe27e"
            ],
            "buyReservationOption": [
                [
                    "6b2fe441-96eb-46fe-aa2b-fe78319d27fc"
                ],
                [
                    "0fa3b2ab-e2bc-4407-8827-7de6a8f7fb06"
                ]
            ]
        }
    ]
}

I try to use checkboxs with SuperForm (and formFieldProxy).

And i have some problems:

  • i don't understand why i have no way (or don't find the one) to retrieve checkbox value instead of the checked boolean (native html checkbox send input value, the value is just conditioned by the checked state)
  • when i try to use bind:group i retrieve checkboxs values but all are stored as array

My reservation Zod schema

const ReservationObject = z.object({
    id: z.string().uuid(),
    reservation_id: z.string(),
    denomination: z.string(),
    price: z.coerce.number(),
    options: z.array(
        z.object({
            id: z.string().uuid(),
            optionDenomination: z.string(),
            price: z.coerce.number()
        })
    ),
    total: z.number().optional(),
    isBooked: z.boolean()
});

const ReservationsObject = z.object({
    reservation_id: z.string(),
    isSuspended: z.boolean(),
    booking: z.array(ReservationObject)
});

The schema used for form values

export const BuyingReservation = z.object({
    buying: z.array(
        z.object({
            buyReservation: z.string().uuid(),
            buyReservationOption: z.array(z.string().uuid())
        })
    )
});

SuperForm object

const defaultBuyingEntry = [{ buyReservation: '', buyReservationOption: [] }];
const buying: BuyingReservation = { buying: defaultBuyingEntry };
const superform = superForm(buying, {
    dataType: 'json',
    resetForm: false,
    invalidateAll: false
});
const { form, submitting, enhance } = superform;

The form

<form method="POST" use:enhance action="/" class={styles['form']}>
    {#each booking.booking as item, index}
        <div class={styles['booking__row']}>
            <p class={styles['booking__row-denomination']}>
                {item.denomination} : <span>{item.price}€</span>
                <Input
                    {superform}
                    id={`${index}-buyReservation`}
                    field="buying[{index}].buyReservation"
                    type="checkbox"
                    label={'Réserver'}
                    value={item.id}
                    grouped={true}
                />
            </p>
            <div class={styles['booking__row-options']}>
                {#each item.options as option, optionIndex}
                    <div class={styles['booking__row-option']}>
                        <p class={styles['booking__row-options-denomination']}>
                            {option.optionDenomination} : <span>{option.price}€</span>
                        </p>
                        <Input
                            {superform}
                            id={`${index}-${optionIndex}-buyReservationOption`}
                            field="buying[{index}].buyReservationOption[{optionIndex}]"
                            type="checkbox"
                            label={'Ajouter'}
                            value={option.id}
                            grouped={true}
                        />
                    </div>
                {/each}
            </div>
        </div>
    {/each}
    <input
        type="submit"
        class={styles['form__field-static']}
        value="Reserver et payer"
        disabled={$submitting}
    />
</form>

My reusable input

let { label, className, field, superform, grouped, ...others }: Props = $props();
const { value, errors, constraints } =
    !!field && !!superform ? formFieldProxy(superform, field) : {};

<input
    {...others}
    name={field}
    data-invalid={$errors}
    aria-invalid={$errors ? 'true' : undefined}
    class={[styles['input'], className].join(' ')}
    {...$constraints}
    type="checkbox"
    bind:group={$value} // or bind:checked={$value}
/>

The results: if bind:checked

{
    "buying": [
        {
            "buyReservation": true,
            "buyReservationOption": [
                true,
                false
            ]
        },
    ]
}

if bind:group

{
    "buying": [
        {
            "buyReservation": [
                "61ee077d-9db9-4286-bd57-25d5ab0fe27e"
            ],
            "buyReservationOption": [
                [
                    "6b2fe441-96eb-46fe-aa2b-fe78319d27fc"
                ],
                [
                    "0fa3b2ab-e2bc-4407-8827-7de6a8f7fb06"
                ]
            ]
        }
    ]
}
Share Improve this question asked Mar 2 at 22:49 GeioGeio 9719 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

i don't understand why i have no way (or don't find the one) to retrieve checkbox value instead of the checked boolean (native html checkbox send input value, the value is just conditioned by the checked state)

The browser does that when submitting a form:

value The value attribute is one which all <input>s share; however, it serves a special purpose for inputs of type checkbox: when a form is submitted, only checkboxes which are currently checked are submitted to the server, and the reported value is the value of the value attribute. If the value is not otherwise specified, it is the string on by default

However when you're on the client side, no form submission happens, and the value attribute is just an attribute, that's present regardless of the checked state, see the "Clicky" button:

function doThing() {
  for (const cb of document.querySelectorAll("input[type=checkbox]"))
    console.log(cb.value, cb.checked);
}

function doFilter() {
  console.log(JSON.stringify(
    [...document.querySelectorAll("input[type=checkbox]")]
    .filter(cb => cb.checked)
    .map(cb => cb.value)));
}
<input type="checkbox" value="hello">hello <input type="checkbox" value="world" checked>world<br>
<button onclick="doThing()">Clicky</button><br><button onclick="doFilter()">Filter</button>

While there's a chance that svelte supports what you want, with vanilla JS you have to combine the two attributes yourself, as the "Filter" button shows.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745115350a4612094.html

相关推荐

  • SvelteSuperForm - Checkbox value instead of boolean - Stack Overflow

    I try to use checkboxs with SuperForm (and formFieldProxy).And i have some problems:i don't under

    9小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信