I am using inertiajs and vue3 on my laravel project.
Problem:
When I try to login with an invalid credential toast message appears and disappears with animation as intended.
But after correct login toast message appear without animation, and doesn't disappear after a certain interval. Also same happens on logout
Toast Component
<template>
<transition
enter-active-class="transition-all ease-out duration-200"
enter-from-class="transform opacity-0 top-32 scale-95"
enter-to-class="transform opacity-100 top-22 scale-100"
leave-active-class="transition-all top-22 ease-in duration-200"
leave-from-class="transform opacity-100 scale-100"
leave-to-class="transform top-12 opacity-0 scale-95">
<div v-if="toast && show == true" class="absolute flex flex-col max-w-lg top-20 right-2 shadow-lg rounded pl-4 pr-2 pt-0 pb-2
bg-white/95 dark:bg-gray-800/95"
:class="{
'bg-green-600 dark:bg-green-600 shadow-green-600/40': toast.type == 'success',
'bg-red-600 dark:bg-red-600 shadow-red-600/40': toast.type == 'error'
}">
<div class="flex mb-2">
<div class="font-semibold"
:class="{
'text-white dark:text-white': toast.type == 'success',
'text-red-200 dark:text-red-200 hover:text-red-50 dark:hover:text-red-50': toast.type == 'error'
}">
{{toast.header}}
</div>
<button #click.prevent="show = false" class="focus:outline-none ml-auto"
:class="{
'text-green-200 dark:text-green-200 hover:text-green-50 dark:hover:text-green-50': toast.type == 'success',
'text-red-200 dark:text-red-200 hover:text-red-50 dark:hover:text-red-50': toast.type == 'error'
}" >
<XCircleIcon class="w-6 h-6" />
</button>
</div>
<div class="flex mr-6 items-center">
<div class="mr-2">
<CheckCircleIcon v-if="toast.type == 'success'" class="w-6 h-6"
:class="{
'text-green-50 dark:text-green-50': toast.type == 'success',
}" />
<XCircleNoFillIcon v-if="toast.type == 'error'" class="w-6 h-6"
:class="{
'text-red-50 dark:text-red-50': toast.type == 'error'
}" />
</div>
<div class="flex-1"
:class="{
'text-green-50 dark:text-green-50': toast.type == 'success',
'text-red-50 dark:text-red-50': toast.type == 'error'
}">
{{toast.message}}
</div>
</div>
</div>
</transition>
</template>
<script>
import { defineComponent, computed, reactive, watch, ref } from 'vue'
import { usePage } from '#inertiajs/inertia-vue3'
import CheckCircleIcon from '#/Icons/CheckCircle.vue'
import XCircleIcon from '#/Icons/XCircle.vue'
import XCircleNoFillIcon from '#/Icons/XCircleNoFill.vue'
export default defineComponent({
components: {
CheckCircleIcon, XCircleIcon, XCircleNoFillIcon,
},
setup() {
const toast = ref(computed(() => usePage().props.value.toast))
const show = ref(true)
watch(toast, () => {
setTimeout(() => {
show.value = true
}, 10);
hideToast()
})
function hideToast() {
setTimeout(() => {
console.log( toast.value.duration)
show.value = false
}, toast.value.duration);
}
return { toast, show }
},
})
</script>
AuthController
// Sign in
public function store(Request $request)
{
$credentials = Validator::make($request->all(), [
'email' => ['required', 'string', 'email', 'max:255'],
'password' => ['required', Rules\Password::defaults()],
]);
if($credentials->fails()) {
return back()
->withInput()
->withErrors($credentials)
->with([
'toast' => [
'duration' => '6000',
'type' => 'error',
'header' => 'Validation Error.',
'message' => 'Please resolve the issues.',
]
]);
}
if (!Auth::attempt($credentials->validated(), $request->remember ? true : false)) {
return back()
->withInput()
->withErrors(['email' => 'Invalid credentials'])
->with([
'toast' => [
'duration' => '1000',
'type' => 'error',
'header' => 'Failed!',
'message' => 'Invalid credentials.',
]
]);
}
$request->session()->regenerate();
return redirect()
->intended(RouteServiceProvider::HOME)
->with([
'toast' => [
'duration' => '5000',
'type' => 'success',
'header' => 'Signed in.',
'message' => 'Welcome back, ' . Auth::user()->name,
]
]);
}
Related
I have created a form which has two ajax callbacks but neither of them seems to work as expected the form_state do not get rebuild after callback
namespace Drupal\dashboard\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\Entity\User;
use Drupal\commerce_price\Price;
use Drupal\commerce_order\Entity\OrderItem;
use Drupal\commerce_order\Entity\Order;
use Drupal\taxonomy\Entity\Term;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
use CommerceGuys\Addressing\AddressFormat\AddressField;
use Drupal\dashboard\DashboardRepository;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* UI to update a record.
*
* #ingroup scorecards
*/
class AcfDataUpdateForm extends FormBase {
/**
* Our database repository service.
*
* #var \Drupal\scorecards\ScorecardsRepository
*/
protected $repository;
/**
* {#inheritdoc}
*/
public function getFormId() {
return 'acf_data_update_form';
}
/**
* {#inheritdoc}
*/
public static function create(ContainerInterface $container) {
$form = new static($container->get('dashboard.repository'));
$form->setStringTranslation($container->get('string_translation'));
$form->setMessenger($container->get('messenger'));
return $form;
}
/**
* Construct the new form object.
*/
public function __construct(DashboardRepository $repository) {
$this->repository = $repository;
}
/**
* Sample UI to update a record.
*/
public function buildForm(array $form, FormStateInterface $form_state, $order_id = NULL) {
$items = $this->repository->get_order_items($order_id);
$mark_pack = 6;
$uid = \Drupal::currentUser()->id();
$config = \Drupal::config('dashboard.settings');
foreach($items as $item){
if($item->purchased_entity == 6 || $item->purchased_entity == 7 || $item->purchased_entity == 8){
$mark_pack = $item->purchased_entity;
}
}
$form['#prefix'] = '<div id="package_design_wrapper-container">';
$form['#suffix'] = '</div>';
$form['order_id'] = array(
'#type' => 'hidden',
'#default_value' => $order_id,
);
$form['package'] = array(
'#type' => 'container',
'#prefix' => '<div class="message" id="message"></div>',
'#attributes' => array('id' => 'marketing-package-wrapper'),
);
$form['package']['marketing_package'] = array(
'#type' => 'radios',
'#default_value' => $mark_pack,
'#options' => array(
6 => $this
->t('Standard <span>'.$this->getPrice(6).'</span>'),
7 => $this
->t('Premium <span>'.$this->getPrice(7).'</span>'),
8 => $this
->t('Premium + <span>'.$this->getPrice(8).'</span>'),
),
'#disabled' => true,
);
$form['package']['designation'] = array(
'#type' => 'textfield',
'#prefix' => $this->t('<h3>your designation</h3><p>Lorem Ipsum is simply dummy text of the printing and typesetting industry</p>'),
'#attributes' => array('placeholder' => 'Type Here'),
);
$form['package']['photograph'] = array(
'#type' => 'managed_file',
'#upload_location' => 'public://acf_profile_photos',
'#multiple' => FALSE,
'#upload_validators' => [
'file_validate_is_image' => [],
'file_validate_extensions' => array('png jpg jpeg'),
'file_validate_size' => array(25600000)
],
'#required' => true,
'#title' => $this->t('<h3>your photograph</h3><p>Lorem Ipsum is simply dummy text of the printing and typesetting industry</p>'),
);
$form['package']['date'] = array(
'#type' => 'radios',
'#default_value' => 1,
'#options' => $this->getDates(),
'#required' => true,
'#prefix' => $this->t('<h3>Award Slot</h3><p>Lorem Ipsum is simply dummy text of the printing and typesetting industry</p>'),
'#ajax' => [
'wrapper' => 'wrapper-dropdown',
'callback' => '::getAwardSlots',
'method' => 'replace',
'effect' => 'fade',
'event' => 'change',
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
],
);
$form['package']['award_slot'] = array(
'#type' => 'radios',
'#default_value' => 1,
'#options' => $form_state->getValue('date') ? $this->getAwardSlotOptions($form_state->getValue('date')) : $this->getAwardSlotOptions('2021-04-21'),
'#prefix' => '<div id="wrapper-dropdown">',
'#suffix' => '</div>',
'#required' => true,
);
$form['package']['bio'] = array(
'#type' => 'textarea',
'#prefix' => $this->t('<h3>Individual Bio</h3><p>Lorem Ipsum is simply dummy text of the printing and typesetting industry</p>'),
'#attributes' => array('placeholder' => 'Type Here'),
);
$form['package']['plaque_type'] = array(
'#type' => 'radios',
'#default_value' => 'remote',
'#options' => array(
'remote' => $this
->t('remote'),
'event' => $this
->t('event'),
),
'#required' => true,
'#prefix' => $this->t('<h3>Plaque Type</h3>'),
);
$form['package']['shipping_address'] = array(
'#type' => 'container',
'#states' => array(
'visible' => array(
':input[name="plaque_type"]' => array(
'value' => 'remote',
),
),
),
);
$form['package']['shipping_address']['markup'] = array(
'#markup' => ' <h3>shipping address</h3><p>Lorem Ipsum is simply dummy text of the printing and typesetting industry</p>',
);
$form['package']['shipping_address']['address'] = array(
'#type' => 'address',
'#default_value' => ['country_code' => 'US'],
'#used_fields' => [
AddressField::GIVEN_NAME,
AddressField::FAMILY_NAME,
AddressField::ORGANIZATION,
AddressField::ADDRESS_LINE1,
AddressField::ADDRESS_LINE2,
AddressField::LOCALITY,
AddressField::POSTAL_CODE,
],
'#available_countries' => ['US'],
'#attributes' => array('class' => array('edit-address')),
);
$form['package']['save'] = array(
'#type' => 'submit',
'#submit' => ['::submitPackageDetails'],
'#name' => 'mark-save',
'#value' => t('Save'),
'#validate' => ['::validatePackageDetails'],
'#prefix' => '<div class="row"><div class="col-md-6">',
'#suffix' => '</div>',
'#ajax' => [
'wrapper' => 'package_design_wrapper-container',
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
],
);
$form['package']['submit'] = array(
'#type' => 'submit',
'#submit' => ['::submitPackageDetails'],
'#validate' => ['::validatePackageDetails'],
'#name' => 'mark-submit',
'#value' => t('Submit'),
'#prefix' => '<div class="col-md-6">',
'#suffix' => '</div></div>',
'#ajax' => [
'wrapper' => 'package_design_wrapper-container',
'progress' => [
'type' => 'throbber',
'message' => NULL,
],
],
);
$form['terms'] = array(
'#type' => 'checkbox',
'#title' => t('I have read the terms & conditions and agree to comply with them. '),
'#prefix' => '<div class="row mb-3"><div class="col-12 col-sm-12 col-md-12 col-lg-12">',
'#suffix' => '</div></div>',
);
$form['#theme'] = 'acf_data_update_form';
return $form;
}
/**
* {#inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
echo "<pre>";
print_r($form_state->getValues());
die;
$old = $this->repository->save_old_data($old_data, $order_id, $user_id);
$this->messenger()->addMessage($this->t('Saved old data #entry (#count row updated)', [
'#count' => $old,
'#entry' => print_r($old_data, TRUE),
]));
if(!empty($old)){
$count = $this->repository->update_nominee($entry, $order_id, $user_id);
$this->messenger()->addMessage($this->t('Updated entry #entry (#count row updated)', [
'#count' => $count,
'#entry' => print_r($entry, TRUE),
]));
}
$form_state->setRedirect('scorecards.scorecard_entry_list');
}
public function validatePackageDetails(array &$form, FormStateInterface $form_state){
$fields = array('designation','date','award_slot','plaque_type','bio','photograph');
$add_fields = array('given_name','family_name','organization','address_line1','locality','postal_code');
$valid = true;
if($form_state->getValue('plaque_type') == 'remote'){
$add = $form_state->getValue('address');
foreach($add_fields as $field){
if(empty($add[$field])){
$form_state->setErrorByName($add[$field], 'Please enter a valid detail');
}
}
}
foreach($fields as $field){
if(empty($form_state->getValue($field))){
$form_state->setErrorByName($field, 'Please enter a valid detail');
}
}
}
public function submitPackageDetails(array &$form, FormStateInterface $form_state){
$fields = array('designation','date','award_slot','plaque_type','bio','photograph');
$add_fields = array('given_name','family_name','organization','address_line1','locality','postal_code');
if($form_state->getValue('plaque_type') == 'remote'){
$add = $form_state->getValue('address');
}
$data = array();
$pid = $form_state->getValue('marketing_package');
foreach($fields as $field){
$data[$field] = $form_state->getValue($field);
}
$data['status'] = 0;
$triggering_element = $form_state->getTriggeringElement();
$button_name = $triggering_element['#name'];
if($button_name == 'mark-submit'){
$data['status'] = 1;
}
$order_id = $form_state->getValue('order_id');
$pid = $form_state->getValue('marketing_package');
$entry = $this->repository->saveAcfDetails($order_id,$pid,$data);
$entry_add = $this->repository->saveShippingDetails($order_id,$add);
$this->setFilePermanent($form_state->getValue('photograph'));
if($entry && $entry_add){
$form_state->setRebuild(TRUE);
$this->messenger->addMessage(t('Your data has been saved successfully!'));
}
else{
$this->messenger->addMessage(t('Your data cannot be Saved'));
}
}
function getPrice($id){
$variation = \Drupal\commerce_product\Entity\ProductVariation::load($id);
return str_replace('USD','$',$variation->getPrice());
}
function setFilePermanent($image_id){
if(!empty($image_id)) {
$file = \Drupal\file\Entity\File::load($image_id[0]);
if (isset($file) and is_object($file)) {
$file->setPermanent(); // FILE_STATUS_PERMANENT;
$file->save();
}
}
}
function getDates(){
$config = $this->config('dashboard.settings');
$start_date = $config->get('conference_start_date');
$no_days = $config->get('no_days');
$dates = array();
for($i = 1; $i <= $no_days; $i++){
$j = $i-1;
$date = strtotime("{$j} day", strtotime($start_date));
$new_date = date("d-M-Y", $date);
$dates[date("Y-m-d", $date)] = 'DAY '.$i.'<span>('.$new_date.')</span>';
}
return $dates;
}
function getAwardSlots(array &$form, FormStateInterface $form_state){
$form_state->setValue('date', $form_state->getValue('date'));
$form_state->setRebuild(TRUE);
return $form['package']['award_slot'];
}
function getAwardSlotOptions($date){
$terms = \Drupal::entityManager()->getStorage('taxonomy_term')->loadByProperties(array('name' => $date));
$term = reset($terms);
$award_slots = $term->get('field_award_slot');
$slots = array();
foreach($award_slots as $award_slot){
$slots[$award_slot->value] = $award_slot->value;
}
return $slots;
}
}
I have also created a template for this form
<div class="row">
<div class="col-12 col-sm-12 col-md-9 col-lg-9">
<div class="package_border">
<div class="wellcome_back">
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-12">
<h3>Awardee Deliverables</h3>
</div>
</div>
</div>
<div class="package_header">
<div class="row">
<div class="col-12 col-sm-12 col-md-5 col-lg-5">
<div class="package_header_batch">
<img src="/modules/custom/dashboard/images/package.jpg">
<div>
<h2>Marketing package</h2>
<p>Lorem Ipsum is simply</p>
</div>
</div>
</div>
{% if form.package.marketing_package %}
<div class="col-12 col-sm-12 col-md-7 col-lg-7">
{{ form.package.marketing_package }}
</div>
{% endif %}
</div>
</div>
<div class="designation_content_wrapper">
<div class="designation_content">
{{ form.package|without('marketing_package','plaque_type','shipping_address','submit','save') }}
{% if form.package.plaque_type %}
<h3>plaque</h3>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry</p>
<div class="row mb-5">
<div class="col-12 col-sm-12 col-md-6 col-lg-6">
<figure class="plaque_figure">
{% set images = getPlaqueBadge() %}
<img src="{{ images.plaque }}" width="100%">
</figure>
</div>
<div class="col-12 col-sm-12 col-md-6 col-lg-6">
<div class="plaque_type_wrapper">
{{ form.package.plaque_type }}
</div>
</div>
</div>
{% endif %}
{% if form.package.shipping_address %}
{{ form.package.shipping_address }}
{% endif %}
{{ form.package.save }}
{{ form.package.submit }}
</div>
</div>
</div>
{{ form|without('package') }}
</div>
<div class="col-12 col-sm-12 col-md-3 col-lg-3">
<aside class="package_aside">
<div class="package_aside_wrapper">
<h5>jump to</h5>
<ul class="package_aside_list">
<li>
designation
</li>
<li>
photograph
</li>
<li>
award slot
</li>
<li>
individual boi
</li>
<li>
plaque
</li>
<li>
plaque type
</li>
<li>
shipping address
</li>
</ul>
</div>
</aside>
</div>
</div>
what is actually happening is that after the ajax callback is executed the the form_state still has user submitted values which it should not. please help if anyone knows what m I doing wrong here.
That's kinda old but maybe can help someone :).
First of all - you cannot modify $form_state from within the ajax callback - so the $form_state->setRebuid() will not have an effect.
As stated in AJAX form docs you should only return a markup, a renderable array or an AjaxCommand.
What you need to do here is to modify the value of the element in the ajax callback, more like this:
function getAwardSlots(array &$form, FormStateInterface $form_state){
$date = $form_state->getValue('date')
$form['package']['award_slot']['#options'] = $this->getAwardSlotOptions($date);
return $form['package']['award_slot'];
}
I can't understand what the problem may be:
I state that the code without the part of the attachment works
function submit(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'file' => 'mimes:pdf,doc,docx'
]);
$data = array(
'name_data' => $request->name,
'cognome_data' => $request->cognome,
'luogo_data' => $request->luogo,
'date_data' => $request->date,
'telefono_data' => $request->telefono,
'email_data' => $request->email,
'citta_data' => $request->citta,
'provincia_data' => $request->provincia,
'studio_data' => $request->studio,
'lingua_data' => $request->lingua,
'livello_data' => $request->livello,
'lingua2_data' => $request->lingua2,
'livello2_data' => $request->livello2,
'file_data' => $request->file,
'agree_data' => $request->agree
);
Mail::send('mail', $data, function($message) use ($request,$data){
$message->to('pipo#gmail.com', 'piooi')->subject('Send mail ' . $request->name);
$message->from($request->email, $request->name);
if ( isset($data['file_data']))
{
$message->attach($data['file_data']->getRealPath(), array(
'as' => $data['file_data']->getClientOriginalName(),
'mime' => $data['file_data']->getMimeType()));
}
});
Session::flash('success', 'Mail spedita con sucesso');
}
}
I put the piece of the form in question:
<form class="text-left form-email"action="#" enctype="multipart/form-data" method="POST">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroupFileAddon01">Curriculum Vitae:</span>
</div>
<div class="custom-file">
<input type="file" class="custom-file-input" id="file" name="file"
aria-describedby="inputGroupFileAddon01">
<label class="custom-file-label" for="inputGroupFile01">Seleziona il file</label>
</div>
</div>
the error that gives the summit is the following:
local.ERROR: Call to a member function getRealPath() on null {"exception":"[object] (Error(code: 0):
Change your mail part to this and see if it works
Mail::send('mail', $data, function($message) use ($request,$data){
$message->to('pipo#gmail.com', 'piooi')->subject('Send mail ' . $request->name);
$message->from($request->email, $request->name);
if($request->hasFile('file')){
$message->attach($request->file->getRealPath(), array(
'as' => $request->file->getClientOriginalName(),
'mime' => $request->file->getMimeType())
);
}
});
I'm trying to upload an image with another field to like the patreon image post.
I use Laravel as a backend and have been tested WORK using postman.
But for the frontend part using the q-uploader Quasar Framework - vue js, it seems I need some advice.
this is my laravel controller:
public function createImagePost(Request $request) {
$validator = Validator::make($request->all(),[
'title' => 'required',
'permission' => 'required',
'images' => 'required',
]);
if ($validator->fails()) {
return response()->json([
'status' => 'failed',
'errors' => $validator->errors()
], 500);
} else {
if ($request->hasfile('images'))
{
$images = $request->file('images');
$names = array();
foreach($images as $image) {
$imageName = Auth::user()->id.'_image_'.time().'.'.$image->getClientOriginalExtension();
$image->storeAs('user_post_images', $imageName);
$names[] = $imageName;
}
UserPost::create([
'images' => json_encode($names),
'title' => $request->title,
'tags' => $request->tags,
'description' => $request->description,
'permission' => $request->permission,
'post_user_id' => Auth::user()->id
]);
return response()->json([
'status' => 'success',
'message' => 'Post has been created successfully!'
], 200);
} else {
return response()->json([
'status' => 'ERROR VRO',
'message' => 'ERROR'
], 500);
}
}
}
and this is the quasar frontend:
<q-form #submit="createImagePost">
<q-card-section class="q-pt-none">
<!-- Fields -->
<q-uploader
label="Pick Some Images Here!"
multiple
color="teal"
accept="image/*"
style="max-width: 1200px; width: 100%"
flat
bordered
:factory="createImagePost"
url=""
ref="imageUploader"
/>
<br>
<q-input
type="text"
hint="Required"
label="Post Title"
v-model.trim="post_title"
#input="$v.post_title.$touch()"
:rules="[
val => $v.post_title.required || 'Post Title is required',
]"
:dense="dense"
/>
<br>
<q-input
type="textarea"
v-model="post_description"
hint="Tell a story"
label="Post Description"
:dense="dense"
/>
<br>
<div class="row">
<div class="col q-mr-md">
<q-select
outlined
:options="post_permission_options"
label="Permission"
hint="Required"
v-model.trim="post_permission"
#input="$v.post_permission.$touch()"
:rules="[
val => $v.post_permission.required || 'Post permission is required',
]"
/>
</div>
<div class="col">
<q-select
label="Tags"
outlined
v-model="post_tags"
use-input
use-chips
multiple
hide-dropdown-icon
input-debounce="0"
new-value-mode="add"
/>
</div>
</div>
</q-card-section>
<q-card-actions align="right" class="text-primary">
<q-btn flat label="Cancel" v-close-popup />
<q-btn flat label="Create" type="submit"/>
</q-card-actions>
</q-form>
createImagePost(files) {
let currentObj = this
currentObj.createImagePostLoading = true
const config = {
headers: { 'Content-Type': undefined }
}
const fd = new FormData()
fd.append('images', files)
fd.append('title', currentObj.title)
fd.append('tags', currentObj.tags)
fd.append('description', currentObj.description)
fd.append('permission', currentObj.permission)
axios.get('/sanctum/csrf-cookie').then(response => {
axios.post('/api/create-image-post', fd, config)
.then(function (response) {
currentObj.serverSuccess = response.data.message
currentObj.showCreatePostSuccess()
currentObj.createImagePostLoading = false
currentObj.create_image_post = false
currentObj.selected_file = []
})
.catch(function (error) {
if(error.response.data) {
currentObj.serverError = error.response.data.errors
}
currentObj.showCreatePostError()
currentObj.createImagePostLoading = false
currentObj.create_image_post = false
currentObj.errorModal = true
currentObj.selected_file = []
})
})
},
and the error message is the same as the error message that is made if the file is not found. but for this controller it works if I use postman, am I missing something with q-uploader?
Error Message :
{status: "ERROR VRO", message: "ERROR"}
status: "ERROR VRO"
message: "ERROR"
How will I validate the current entries from here , this is the json response inside the Chrome Devtools after submitting the form thru axios ?
And this is in my UpdateProfileRequest.php
public function rules()
{
return [
'username' => 'required|unique:users|min:3',
'password' => 'required|min:8|confirmed',
'confirm_password' => 'required|',
'current_password' => 'required|u',
'country_id' => 'required|integer',
'display_name' => 'required|min:5',
'email' => 'required|unique:users,email_address',
'phone_number' => 'required|alpha_num',
'image' => 'mimes:jpg,png,gif'
];
This is the whole response from the request
This is inside my UpdateProfile.vue
<div>
<div v-if="user != null">
<form class="bg-white m-auto h-full p-4 w-full" id="setup-billing-form" #submit.prevent="submitProfile()" method="POST">
<div class="flex inline-block">
<div id="input-group" class="w-3/5">
<label for="name" class="block uppercase tracking-wide text-black-v2 text-xs font-bold mb-2">Username
</label>
<input v-model="form.username" type="text" class="hover:bg-grey-lightest bg-grey-lighter w-full mb-2 p-2 leading-normal" id="pin" name="pin" autocomplete="name" placeholder="Your Username" required>
</div>
<div id="input-group" class="ml-2 w-3/5">
<label for="name" class="block uppercase tracking-wide text-black-v2 text-xs font-bold mb-2">Email
</label>
this is is inside my axios request
submitProfile(){
let data = new FormData();
axios.put(this.endpoint, {
form : this.form ,
image : this.image
}).then(response => {
console.log(response.data);
}).catch(error => {
console.log(error);
});
},
Now, I want to ask if how do I validate those requests inside my UpdateProfileRequest, should I add the form. to each of those requests ?
Two Methods:
1. just use form.username to validate
$rule = [
'form.username' => 'required|unique:users|min:3',
'form.password' => 'required|min:8|confirmed',
'form.confirm_password' => 'required|',
'form.current_password' => 'required|u',
'form.country_id' => 'required|integer',
'form.display_name' => 'required|min:5',
'form.email' => 'required|unique:users,email_address',
'form.phone_number' => 'required|alpha_num',
'image' => 'mimes:jpg,png,gif'
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
}
2. Flatten the object to request:
It seems that you new a formdata without using it.
And pass the data with keys form and image.
You need to flatten your object before put it:
submitProfile(){
// if you use formdata
// let form = new FormData(this.form);
// let form = form.append('image', this.image);
let form = Object.assign({}, this.form); // clone this.form
form['image'] = this.image;
axios.put(this.endpoint, form).then(response => {
console.log(response.data);
}).catch(error => {
console.log(error);
});
},
This request that you can directly validate by
'username', 'password', ... without prefix form.
and if you want to insert the datas, you can just use $request->except('image').
I'm a novice when it comes to PHP and Laravel and am embarrassed that I haven't figured this out yet. I'm trying to provide an option for my user to import their database into the application. However, I need to attach a user id to each row so it can be saved with that user. I've tried multiple attempts to grab that user id and pass it into the foreach loop so it can be saved. Any guidance I can receive, I'd be most grateful. I am using Maatwebsite/Laravel-Excel facade.
Here is my Controller:
class ImportController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function importExcel()
{
if(Input::hasFile('import_file')){
$path = Input::file('import_file')->getRealPath();
$data = Excel::load($path, function($reader) {
})->get();
if(!empty($data) && $data->count()){
foreach ($data as $key => $value) {
$user = Auth::user();
$data['user_id'] = $user->id;
$insert[] = [
'user_id' => $value->user_id,
'first_name' => $value->first_name,
'last_name' => $value->last_name,
'title' => $value->title,
'level' => $value->level,
'company' => $value->company,
'email' => $value->email,
'address_1' => $value->address_1,
'address_2' => $value->address_2,
'city' => $value->city,
'state' => $value->state,
'zip_code' => $value->zip_code,
'office_tel' => $value->office_tel,
'mobile_tel' => $value->mobile_tel,
'member_since'=> $value->member_since
];
}
if(!empty($insert)){
DB::table('members')->insert($insert);
Session::flash('flash_message', 'Database successfully imported!');
}
}
}
return back();
}
}
Here is my route:
Route::post('importExcel', 'ImportController#importExcel');
Here is my view:
<button type="button" class="btn btn-danger btn-lg" data-toggle="modal" data-target="#importExcel">Import</button>
<div class="modal fade" id="importExcel" tabindex="-1" aria-labelledby="importExcelLabel">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">Import Your Database</h4>
</div>
<div class="modal-body">
<p>Click browse to import your database. Only Microsoft Excel extensions are acceptable. Please label your columns as follows:</p>
<ul>
<li>user_id (leave this column empty)</li>
<li>first_name</li>
<li>last_name</li>
<li>title</li>
<li>level</li>
<li>company</li>
<li>address_1</li>
<li>address_2</li>
<li>city</li>
<li>state</li>
<li>zip_code</li>
<li>office_tel</li>
<li>mobile_tel</li>
<li>member_since</li>
</ul>
<form action="{{ URL::to('importExcel') }}" class="form-horizontal" method="post" enctype="multipart/form-data">
<input type="file" name="import_file" />
<input type="hidden" name="_token" value="{{csrf_token()}}">
<button type="submit" class="btn btn-primary">Import File</button>
</form>
</div><!-- /.modal-body-->
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal">Close</button>
</div><!-- /.modal-footer-->
</div><!-- /.modal-content-->
</div><!-- /.modal-dialog-->
</div><!-- /.modal-->
Here is my model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Member extends Model
{
protected $fillable = [
'user_id',
'first_name',
'last_name',
'title',
'level',
'company',
'email',
'address_1',
'address_2',
'city',
'state',
'zip_code',
'office_tel',
'mobile_tel',
'member_since' ];
}
First of all: Where do you set $insert? You have to set this variable with the data you like to import. Despite of that you can try the following:
If I understand you right, the database-field user_id should contain the ID of the logged in user - if so, try in your controller the following in importExcel (see comment):
public function importExcel(Request $request)
{
if(Input::hasFile('import_file')){
$path = Input::file('import_file')->getRealPath();
$data = Excel::load($path, function($reader) {
})->get();
if(!empty($data) && $data->count()){
foreach ($data as $key => $value) {
$user = Auth::user();
$data['user_id'] = $user->id;
[
'user_id' => $user->id, // Access here the userId of the logged in user
'first_name' => $value->first_name,
'last_name' => $value->last_name,
'title' => $value->title,
'level' => $value->level,
'company' => $value->company,
'email' => $value->email,
'address_1' => $value->address_1,
'address_2' => $value->address_2,
'city' => $value->city,
'state' => $value->state,
'zip_code' => $value->zip_code,
'office_tel' => $value->office_tel,
'mobile_tel' => $value->mobile_tel,
'member_since'=> $value->member_since
];
}
if(!empty($insert)){
DB::table('members')->insert($insert);
Session::flash('flash_message', 'Database successfully imported!');
}
}
}
return back();
}
Hope that helps :)