質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

Q&A

解決済

1回答

1626閲覧

Laravel、Vueにて画像アップロード更新

o0039

総合スコア3

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

0グッド

0クリップ

投稿2023/01/09 08:10

編集2023/01/09 08:17

前提

Laravel、Vueにてプロフィール更新ページを作成しております。
新規作成は成功し、プロフィールをDBに保存する機能は完成しております。

登録したプロフィールを更新したいのですが、画像を選択せず更新をしますと更新機能が上手く機能するのですが、プロフィール画像を選択後、更新をしますとなぜかバリデーションのrules(required)に引っかかりエラーとなってしまいます。
※ユーザー画像選択すると、ユーザー名など全て入力していますが「必ず指定してください。」と未入力エラーが発生致します。rulesでは「required」を設定しております。

新規登録では、エラーは発生せず上手く登録されます。

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • プロフィールの更新にて画像選択してもバリデーションのエラーが発生しないようにしたいです。

発生している問題・エラーメッセージ

ユーザーの画像を選択すると、格input項目でのバリデーションエラー

該当のソースコード

// ======================================= //更新用ファイル //Edit.vue // ======================================= <script setup> import AdminAuthenticatedLayout from '@/Layouts/AdminAuthenticatedLayout.vue'; import { Inertia } from '@inertiajs/inertia'; import { Head, Link, useForm } from '@inertiajs/inertia-vue3'; import { reactive, toRef, onMounted } from 'vue'; import FlashMessage from "@/Components/FlashMessage.vue" const props = defineProps({ 'user': Array, 'plans': Array, 'errors': Object }); const form = reactive({ id: props.user.id, user_image: null, user_name: props.user.user_name, plan: props.user.plan, address: props.user.address, tel: props.user.tel, email: props.user.email, remarks: props.user.remarks, }); onMounted(() => { const planNum = props.user.plan; document.getElementById('plan').options[planNum].selected = true; }) const userData = id => { Inertia.put(route('admin.user.update', {user: id}), form); } const onImageUpLoad = (e) => { const file = e.target.files[0]; const blobUrl = window.URL.createObjectURL(file); const deleteTarget = document.getElementById('c-user-img__image'); const addTarget = document.querySelector('.c-user-img label'); const addHtml = `<img src="${blobUrl}" class="u-fit" id="c-user-img__image">`; form.user_image = file deleteTarget.remove(); addTarget.insertAdjacentHTML('afterbegin', addHtml); } </script> <template> <Head title="ユーザー登録フォーム" /> <AdminAuthenticatedLayout> <template #header> <h2 class="font-semibold text-xl text-gray-800 leading-tight">ユーザー</h2> </template> <div class="py-12"> <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> <h2 class="my-5 font-bold text-xl">ユーザー登録フォーム</h2> <div class="p-content py-20"> <div class="mb-10"> <FlashMessage /> </div> <form @submit.prevent="userData(form.id)"> <div class="p-user-show"> <div> <div class="c-user-img"> <label class="cursor-pointer"> <img :src="'/storage/images/users/' + user.user_image" class="u-fit" id="c-user-img__image"> <input type="file" id="user_image" name="user_image" accept="image/png,image/jpeg,image/jpg" class="p-form__camera" v-on:change="onImageUpLoad"> </label> <div class="text-red-600" v-if="errors.user_image">{{ errors.user_image }}</div> </div> </div> <div class="p-user-show__data"> <dl class="p-user-show__data__def p-user-show__data__def--form items-center"> <dt class="p-user-show__data__def-tit p-user-show__data__def-tit--form">ユーザー名</dt> <dd class="p-user-show__data__def-data p-user-show__data__def-data--form"> <input type="text" id="user_name" name="user_name" v-model="form.user_name" class="w-full bg-opacity-50 rounded border border-gray-300 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 px-3 leading-8 transition-colors duration-200 ease-in-out" required> <div class="text-red-600" v-if="errors.user_name">{{ errors.user_name }}</div> </dd> </dl> <dl class="p-user-show__data__def p-user-show__data__def--form items-center"> <dt class="p-user-show__data__def-tit p-user-show__data__def-tit--form">プラン</dt> <dd class="p-user-show__data__def-data p-user-show__data__def-data--form"> <select v-if="plans" id="plan" name="plan" v-model="form.plan" class="bg-opacity-50 rounded border border-gray-300 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 px-3 leading-8 transition-colors duration-200 ease-in-out" required> <option value="">選択する</option> <option v-for="plan in plans" :key="plan.id" :value="plan.id">{{plan.name}}</option> </select> <div class="text-red-600" v-if="errors.plan">{{ errors.plan }}</div> </dd> </dl> <dl class="p-user-show__data__def p-user-show__data__def--form items-center"> <dt class="p-user-show__data__def-tit p-user-show__data__def-tit--form">住所</dt> <dd class="p-user-show__data__def-data p-user-show__data__def-data--form"> <input type="text" id="address" name="address" v-model="form.address" class="w-full bg-opacity-50 rounded border border-gray-300 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 px-3 leading-8 transition-colors duration-200 ease-in-out" required> <div class="text-red-600" v-if="errors.address">{{ errors.address }}</div> </dd> </dl> <dl class="p-user-show__data__def p-user-show__data__def--form items-center"> <dt class="p-user-show__data__def-tit p-user-show__data__def-tit--form">TEL</dt> <dd class="p-user-show__data__def-data p-user-show__data__def-data--form"> <input type="tel" id="tel" name="tel" v-model="form.tel" class="w-full bg-opacity-50 rounded border focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 px-3 leading-8 transition-colors duration-200 ease-in-out" required> <div class="text-red-600" v-if="errors.tel">{{ errors.tel }}</div> </dd> </dl> <dl class="p-user-show__data__def p-user-show__data__def--form items-center"> <dt class="p-user-show__data__def-tit p-user-show__data__def-tit--form">メールアドレス</dt> <dd class="p-user-show__data__def-data p-user-show__data__def-data--form"> <input type="email" id="email" name="email" v-model="form.email" class="w-full bg-opacity-50 rounded border focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 px-3 leading-8 transition-colors duration-200 ease-in-out" required> <div class="text-red-600" v-if="errors.email">{{ errors.email }}</div> </dd> </dl> <dl class="p-user-show__data__def p-user-show__data__def--form"> <dt class="p-user-show__data__def-tit p-user-show__data__def-tit--form">備考</dt> <dd class="p-user-show__data__def-data p-user-show__data__def-data--form"> <textarea name="remarks" id="remarks" v-model="form.remarks" cols="30" rows="10" class="border border-gray-300"></textarea> <div class="text-red-600" v-if="errors.remarks">{{ errors.remarks }}</div> </dd> </dl> <!-- <button type="submit" :onclick="formSubmit" class="c-button c-button--brown m-auto u-mt60">登録する</button> --> <button class="c-button c-button--brown m-auto u-mt60">編集する</button> </div> </div> </form> </div> </div> </div> <template #footer /> </AdminAuthenticatedLayout> </template> // ======================================= //バリデーションファイル内容 //UpdateUserInfoRequest.php // ======================================= 'user_image' => 'nullable|image|mimes:jpg,jpeg,png|max:2048', 'user_name' => ['required', 'string', 'max:255'], 'plan' => ['required', 'integer'], 'address' => ['required', 'string'], 'tel' => ['required', 'string'], 'email' => 'required|string|email|max:255', 'remarks' => ['string'],

試したこと

console.logなどで値を確認しながら作業しましたが、さっぱり分からないため皆様のお力をお借りしたいと思いました。

補足情報(FW/ツールのバージョンなど)

以下画像のように、ユーザーの画像を選択後編集ボタンを押すと、未入力ではないのですが、「必ず指定してください。」とエラーが発生致します。
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

onImageUpLoad内がVueの使い方ではないので途中でformが壊れてるのでは。
reactiveだと意図せず壊れやすい。

Inertia vueならuseFormの使い方を見てから
https://inertiajs.com/forms
Jetstreamでのプロフィール画像の変更を参考にすればいい。
https://github.com/laravel/jetstream/blob/2.x/stubs/inertia/resources/js/Pages/Profile/Partials/UpdateProfileInformationForm.vue
これを見てもvue内でdocument.getElementByIdは出て来ない。

投稿2023/01/09 09:59

kawax

総合スコア10377

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

o0039

2023/01/09 13:48

ご教示ありがとうございます! Jetstreamでのプロフィール画像の変更を参考させていただきました。 reactiveをuseFormに変更し「_method: 'PUT',」を追記。 Inertia.put → form.postに変更したところ上手くいきました。 他onImageUpLoadなど変更いたしました。 <script setup> import AdminAuthenticatedLayout from '@/Layouts/AdminAuthenticatedLayout.vue'; import { Head, useForm } from '@inertiajs/inertia-vue3'; import { ref, onMounted } from 'vue'; import FlashMessage from "@/Components/FlashMessage.vue" const props = defineProps({ 'user': Object, 'plans': Array, 'errors': Object }); const form = useForm({ _method: 'PUT', id: props.user.id, user_image: null, user_name: props.user.user_name, plan: props.user.plan, address: props.user.address, tel: props.user.tel, email: props.user.email, remarks: props.user.remarks, }); const photoInput = ref(null); const photoImage = ref(null); onMounted(() => { const planNum = props.user.plan; document.getElementById('plan').options[planNum].selected = true; }) const userData = id => { if (photoInput.value) { form.user_image = photoInput.value.files[0]; } form.post(route('admin.user.update', {user: id})); } const onImageUpLoad = () => { const photo = photoInput.value.files[0]; if (! photo) return; const reader = new FileReader(); reader.onload = (e) => { photoImage.value = e.target.result; }; reader.readAsDataURL(photo); } </script>
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問