如何在sveltekit中添加值到表单?



所以,我使用的默认行为在sveltekit,其中我们使用html表单提交数据到后端,但也有一个文件上传,使用ajax(获取api)上传图像到服务器,并获得它的文件名,现在我想把这些名称附加到html表单状态在某种程度上,这是可能的还是我应该移动到完整的状态管理表单?

下面是我的代码:
<script lang="ts">
import { enhance } from '$app/forms';
import type { ActionData } from './$types';
let input: HTMLInputElement;
let container;
let images: string[] = [];
let placeholder;
let showImage = false;
let files: Blob[] = [];
let form: ActionData;
const uploadImage = async (file: Blob) => {
let formdata = new FormData();
formdata.append('image', file);
const res = await fetch('/api/upload', {
method: 'POST',
body: formdata
});
const resp = await res.json();
console.log({ resp });
};
const onChange = async () => {
const imgFiles = input.files;
if (imgFiles) {
for (let i = 0; i < imgFiles.length; i++) {
const reader = new FileReader();
reader.addEventListener('load', () => {
if (typeof reader.result == 'string') {
images = [...images, reader.result];
// upload the reader result to backend
}
});
reader.readAsDataURL(imgFiles[i]);
files = [...files, imgFiles[i]];
await uploadImage(imgFiles[i]);
}
}
};
</script>
<form
use:enhance
class="flex rounded-lg shadow-lg my-10 sm:w-1/2 md:w-2/4 flex-col mx-auto p-2 sm:p-6"
method="post"
action="/products/add"
>
{#if form && form.success}
<p class="">Product Added Sucessfully</p>
{/if}
<h2 class="text-2xl font-bold">Add a product / service</h2>
<div class="my-4">
<label for="prodSer">Is this a product or a service?</label>
<select name="type">
<option value="product">Product</option>
<option value="service">Service</option>
</select>
</div>
<input class="basicInput" name="name" placeholder="Name of your product" />
<textarea
class="textArea"
rows={5}
name="description"
placeholder="Write a description about it"
/>
<div class="h-full">
<h4>Images</h4>
<label for="imagePicker">Choose images</label>
<input
multiple
bind:this={input}
on:change={onChange}
id="imagePicker"
name="productImages"
type="file"
placeholder="Upload media"
/>
<div class="flex h-full flex-row my-4 mx-2">
{#if images.length > 0}
{#each images as image}
<div class="h-64 mx-2">
<img class="h-64" src={image} />
<button class="">Remove</button>
</div>
{/each}
{/if}
</div>
</div>
<div>
<label for="currency">Currency</label>
<select id="currency" name="currency">
<option value="Rs.">Rupees</option>
</select>
</div>
<div class="flex flex-row justify-between">
<input class="basicInput halfInput" min={0} name="mrp" placeholder="MRP" type="number" />
<input class="basicInput halfInput" min={0} name="price" placeholder="Price" type="price" />
</div>
<div class="flex flex-row justify-between">
<input class="basicInput halfInput" min={0} name="gst" placeholder="GST %" type="number" />
<input class="basicInput halfInput" min={0} name="cess" placeholder="Cess %" type="price" />
</div>
<div class="p-2">
<label class="text-sm text-gray-600" for="taxIncl">Price is Inclusive of tax?</label>
<input id="taxIncl" type="checkbox" name="includeTax" />
</div>
<div>
<input class="basicInput" name="unit" placeholder="Unit" />
</div>
<div>
<input class="basicInput" name="hsn" placeholder="HSN/SAC" />
</div>
<div>
<input class="basicInput" name="stock" placeholder="Opening Stock" type="number" />
</div>
<input
class="my-2 sm:my-4 sm:w-1/2 hover:cursor-pointer text-white bg-blue-700 hover:bg-blue-800 focus:outline-none focus:ring-4 focus:ring-blue-300 font-medium rounded-full text-sm px-5 py-2.5 text-center mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
type="submit"
value="Add"
/>
</form>
<style>
.basicInput {
height: 60px;
width: 100%;
border-radius: 5px;
border: 1px solid #3e3e3e;
margin-top: 10px;
padding: 10px;
}
.textArea {
width: 100%;
border-radius: 5px;
border: 1px solid #3e3e3e;
margin-top: 10px;
padding: 10px;
}
.halfInput {
width: 49%;
}
select {
padding: 8px;
border-radius: 4px;
}
</style>

我最近遇到了这个问题,可能有一个解决方案。

我使用一个名为Form的组件,它看起来像这样(使用带有JSDoc符号的香草JS):

<script>
import { createEventDispatcher } from 'svelte';
import { enhance } from '$app/forms';
const dispatch = createEventDispatcher();
/** @type {string} */
export let name;
/** @type {string} */
export let method = 'POST';
/** @type {string | null} */
export let action = null;
/** @type {Object} */
export let attributes = {};
/** @type {string | null} */
export let _class = null;
/** @type {string | null} */
export let autocomplete = 'off';
/** @type {boolean} */
export let do_update = true;
/** @type {function | null} */
export let manipulation = null;
/** @param {any} event */
function handleResult(event) {
dispatch('post_result', event);
}
</script>
<form
{name}
{method}
{action}
id={name}
class={_class}
{autocomplete}
{...attributes}
use:enhance={({ data }) => {
if (manipulation) manipulation(data);
return async ({ result, update }) => {
if (do_update) update();
handleResult(result);
};
}}
>
<slot />
</form>

您将注意到在use:enhance回调期间使用的变量manipulation。它引用了一个直接访问和操作表单数据的函数。我想这要归功于JavaScript引用/改变对象的方式。在组件或页面中,我可以像这样操作表单数据:

<script>
/** @param {FormData} data */
function manipulateForm(data) {
value = 'myvalue' // Provide your values here
data.set('set_field', value);
data.delete('delete_field');
// ...and so on
}
</script>
<Form {name} manipulation={manipulateForm}>

request.formData()被调用时,它返回被操作过的表单数据。

相关内容

  • 没有找到相关文章

最新更新