Tailwindcss file input display issue - laravel

I'm running a fresh Laravel project with Jetstream installed.
I copied an example file input code snippet from tailwincss examples page and it is not displaying correctly.
This is what the example on tailwind page looks like:
And this is what it looks like on my page:
Both screenshots were taken in Brave browser.
I tried re-running npm run dev but that didn't change anything.
I'm not great with frontend so perhaps I'm missing something obvious here, but I spent some time looking for answers on similar issues and couldn't to find any.
Here's the html of the element:
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-xl sm:rounded-lg">
<div class="block p-6 rounded-lg shadow-lg bg-white max-w-sm">
<form>
<div class="flex justify-center">
<div class="mb-3 w-96">
<label for="formFile" class="form-label inline-block mb-2 text-gray-700">Default file input example</label>
<input class="form-control
block
w-full
px-3
py-1.5
text-base
font-normal
text-gray-700
bg-white bg-clip-padding
border border-solid border-gray-300
rounded
transition
ease-in-out
m-0
focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none" type="file" id="formFile">
</div>
</div>
</form>
</div>
</div>
</div>
</div>
This is what my app.css looks like:
#import 'tailwindcss/base';
#import 'tailwindcss/components';
#import 'tailwindcss/utilities';
And tailwind.config.js:
const defaultTheme = require('tailwindcss/defaultTheme');
module.exports = {
content: [
'./vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
'./vendor/laravel/jetstream/**/*.blade.php',
'./storage/framework/views/*.php',
'./resources/views/**/*.blade.php',
],
theme: {
extend: {
fontFamily: {
sans: ['Nunito', ...defaultTheme.fontFamily.sans],
},
},
},
plugins: [require('#tailwindcss/forms'), require('#tailwindcss/typography')],
};

My bad, I forgot to install and import tw-elements.

Related

Why is TinyMCE throwing "b is not a constructor", and "({default{}) is not a constructor" when attempting to upload images on Laravel Forge, not dev?

I have my image upload functionality working in development, for which my environment is Laravel Sail. It is working in development, but not in production Laravel forge where it is throwing 'b is not a constructor," and "({default{}}) is not a constructor", depending on whether you're using chrome or firefox respectively, which should have similar-identical environments. Only thing I can think I did differently between them is that in production I used npm run dev in development and npm run build for production. For the application, I'm using Laravel, InertiaJS, and Vue3 and It looks like this:
Vue Form and Script:
<form enctype="multipart/form-data" class="mb-4 md:flex md:flex-wrap md:justify-between" action="/dashboard/pages/store"
method="post">>
<input type="hidden" name="_token" :value="csrfToken">
<div class="flex flex-col mb-4 md:w-1/2">
<label class="mb-2 uppercase tracking-wide font-bold text-lg text-grey-darkest" for="title">Title </label>
<input class="border py-2 px-3 text-grey-darkest md:mr-2" type="text" name="title" id="title">
</div>
<div class="flex flex-col mb-4 md:w-1/2">
<label class="mb-2 uppercase tracking-wide font-bold text-lg text-grey-darkest"
for="slug">Slug </label>
<input class="border py-2 px-3 text-grey-darkest md:mr-2" type="text" name="slug" id="slug">
</div>
<div class="flex flex-col mb-4 md:w-1/2">
<label class="mb-2 uppercase tracking-wide font-bold text-lg text-grey-darkest"
for="slug">Status </label>
<select class="border py-2 px-3 text-grey-darkest md:mr-2" name="status" id="status">
<option value="published">Published</option>
<option value="draft">Draft</option>
</select>
</div>
<!-- Page Header Image -->
<div class="flex flex-col mb-4 md:w-1/2">
<label class="mb-2 uppercase tracking-wide font-bold text-lg text-grey-darkest"
for="slug">Page Header Image </label>
<input class="border py-2 px-3 text-grey-darkest md:mr-2" type="file" name="header_image" id="header_image">
</div>
<div class="flex flex-col mb-4 md:w-full">
<label class="mb-2 uppercase tracking-wide font-bold text-lg text-grey-darkest" for="content">Content </label>
<editor name="content" id="content" api-key='xxxxxxxxxxxxxxxx'
:init="{
plugins: [
'advlist autolink lists link image charmap print preview anchor',
'searchreplace visualblocks code fullscreen',
'insertdatetime media table contextmenu paste imagetools'
],
toolbar: 'insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image ',
image_title: true,
automatic_uploads: true,
file_picker_types: 'image',
images_upload_handler: function (blobInfo, success, failure) {
let data = new FormData();
data.append('file', blobInfo.blob(), blobInfo.filename());
axios.post('/dashboard/pages/upload-images', data)
.then(function (res) {
success(res.data.location);
})
.catch(function (err) {
failure('HTTP Error: ' + err.message);
});
}
}"/>
</div>
<div class="grid mb-4 md:w-full place-items-center">
<button class="bg-red-500 md:w-36 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
type="submit">
Create
</button>
</div>
</form>
Here's the error I'm getting. I don't even know how to get it into the console so I can debug it further:
This is definitely related to the build script, as I ran npm run build on my local machine and it's doing the same thing locally/in development.
This seems to have been an issue with #rollup/plugin-commonjs.
The vite documentation for migration notes that this is the biggest difference between dev and build, so I tried their alternative strategy for removing commonjs because esbuild converts CJS-only dependencies to ESM.
https://vitejs.dev/guide/migration.html#using-esbuild-deps-optimization-at-build-time
To do this, from my Laravel build, in app.js I had to declare my config as a const, then you can use optimizeDeps.disabled: false (the default in v3 is disabled: 'build'). #rollup/plugin-commonjs can be removed by passing build.commonjsOptions: { include: [] }
For me, that left my app.js looking like this:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
const config = defineConfig({
plugins: [
laravel({
input: 'resources/js/app.js',
ssr: 'resources/js/ssr.js',
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
ssr: {
noExternal: ['#inertiajs/server'],
},
alias: {
src: '/src',
},
});
config.build = { ...config.build, include: [] };
config.optimizeDeps = { disabled: false };
export default config;

How can I create an array of id's from the selected option in vue-multiselect plugin?

I've created an Laravel Vue SPA app. Right now, I can successfully retrieved the data in object format and can display the names in vue-multiselect (https://vue-multiselect.js.org/) when selected. Also, I can already save the selected options to the database in an object format. My question is how can I save only the id's in an array?
This is the results from api:
[
{
"id": 1,
"name": "Shoe Machine Operators",
"description": "Iusto cupiditate quo veniam.",
"created_at": "2022-03-23T10:23:35.000000Z",
"updated_at": "2022-03-23T10:23:35.000000Z"
},
{
"id": 2,
"name": "Librarian",
"description": "Vero eius quidem quo fugiat.",
"created_at": "2022-03-23T10:23:35.000000Z",
"updated_at": "2022-03-23T10:23:35.000000Z"
}
]
Here's my markup code where my vue-multiselect element is:
<form #submit.prevent="addEmployee">
<div class="flex space-x-6 md:w-3/4">
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2" for="name">First Name</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline required" name="name" id="name" type="text" placeholder="First Name" tabindex="1" v-model="employee.first_name" />
</div>
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2" for="name">Last Name</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline required" name="name" id="name" type="text" placeholder="Last Name" tabindex="2" v-model="employee.last_name" />
</div>
</div>
<div class="flex space-x-6 md:w-3/4">
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2" for="designation_id">Designation</label>
<multiselect v-model="employee.designation_id"
:options="designation_options"
:multiple="true"
:close-on-select="false"
:clear-on-select="false"
:preserve-search="true"
placeholder="Pick one or many"
label="name"
track-by="name"
:preselect-first="true"
>
<template slot="selection" slot-scope="{ values, search, isOpen }"><span class="multiselect__single" v-if="values.length && !isOpen">{{ values.length }} options selected</span></template>
</multiselect>
<pre class="language-json"><code>{{ employee.designation_id }}</code></pre>
</div>
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2" for="position_id">Position</label>
<multiselect v-model="employee.position_id"
:options="position_options"
:multiple="true"
:close-on-select="false"
:clear-on-select="false"
:preserve-search="true"
placeholder="Pick one or many"
label="name"
track-by="name"
:preselect-first="true"
>
<template slot="selection" slot-scope="{ values, search, isOpen }"><span class="multiselect__single" v-if="values.length && !isOpen">{{ values.length }} options selected</span></template>
</multiselect>
<pre class="language-json"><code>{{ employee.position_id }}</code></pre>
</div>
</div>
<div class="flex space-x-6 md:w-3/4">
<div class="md:w-3/6 mb-4 flex-1">
<label class="block text-gray-700 text-sm font-bold mb-2" for="basic_pay">Basic Pay</label>
<div class="relative rounded">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<span class="text-gray-700">₱</span>
</div>
<input class="shadow appearance-none border rounded w-full py-2 pl-8 pr-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline required" name="basic_pay" id="basic_pay" type="number" step="any" placeholder="00.00" tabindex="5" v-model="employee.basic_pay" />
<div class="absolute inset-y-0 right-0 flex items-center"><label for="basic_pay" class="sr-only">Basic Pay</label>
</div>
</div>
</div>
<div class="md:w-3/6 mb-4 flex-1"> </div>
</div>
<button type="submit" class="sm:hidden md:flex bg-blue-500 hover:bg-blue-400 text-white font-bold py-2 px-4 border-b-4 border-blue-700 hover:border-blue-500 rounded outline-none focus:outline-none">Create</button>
</form>
Here's my script:
<script>
export default {
data() {
return {
employee: {},
designation_id: [],
designation_options: [],
}
},
methods: {
addEmployee() {
this.axios.post('/api/employees', this.employee).then(response => (this.$router.push({
name: 'employees'
}))).catch(err => console.log(err)).finally(() => this.loading = false)
},
getDesignationNames() {
this.axios.get('/api/designation').then((res) => {
this.designation_options = res.data;
}).catch(err => console.log(err))
},
},
created: function() {
this.getDesignationNames();
},
}
</script>
Any help is much appreciated.
I tried getting only the id using .map() function but it caused the vue-multiselect to not show the names and return only the first clicked result in an id format.
getDesignationNames() {
this.axios.get('/api/designation').then((res) => {
this.designation_options = res.data.map((a) => {
return a.id;
});
}).catch(err => console.log(err))
},
Use v-model.
Define v-model binding as an array.
Check this example
<script setup>
import { ref } from 'vue'
const data = ref([{id:1,name:"first"},{id:2,name:"second"},{id:3,name:"third"},{id:4,name:"forth"},{id:5,name:"fifth"}])
const selected = ref(["2","4"])
</script>
<template>
<select v-model="selected" multiple>
<option v-for="item in data" :value="item.id">{{item.name}}</option>
</select>
<div>Selected: {{selected}}</div>
</template>

make a Grid system like bootstrap in Tailwind

i am using TailWind with blade template in laravel, how can i make those card like in the bootstrap, i mean every three items in the one column :
#section('content')
<div class="flex justify-center">
<div class="w-8/12 bg-white p-6 rounded-lg mt-10 ">
#forelse($products as $product)
<!-- Box -->
<div class="md:flex md:justify-center md:space-x-8 md:px-14">
<!-- box-1 -->
<div class="mt-16 py-4 px-4 bg-whit w-72 bg-white rounded-xl shadow-lg hover:shadow-xl transform hover:scale-110 transition duration-500 mx-auto md:mx-0">
<div class="w-sm">
<img class="w-64" src="{{asset('storage/images/products/'.$product->image)}}" alt="" />
<div class="mt-4 text-green-600 text-center">
<h1 class="text-xl font-bold">{{$product->name}}</h1>
<div class="mt-4 text-gray-600">{{$product->info}}</div>
<div class="mt-4 px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-300 text-green-800">{{$product->category->name}}</div>
<button class="mt-8 mb-4 py-2 px-14 rounded-full bg-green-600 text-white tracking-widest hover:bg-green-500 transition duration-200">MORE</button>
</div>
</div>
</div>
#empty
<h1 class="text-center">There is no Products</h1>
#endforelse
<div> {{$products->links()}}</div>
</div>
</div>
#endsection
Recreate the Bootstrap grid system in Tailwind CSS
<div class="grid grid-cols-12">Your column goes here</div>
You can follow this link for further details. https://shortbuzz.in/blog/shortbuzz.in/how-to-create-tailwind-css-grid-system-like-the-bootstrap-grid-system
Here's Peppermintology's comment in the form of an answer:
It sounds like you're looking for a 3 column grid. To do that in Tailwind CSS, use the grid classes like this:
<div class="grid grid-cols-3">
<!--- Generated cards go here --->
</div>
<div class="container mx-auto">
  <div class="grid grid-cols-12 gap-1">
    <div class="col-span-12 sm:col-span-12 md:col-span-3 lg:col-span-3 xl:col-span-3 2xl:col-span-3">Column</div>
    <div class="col-span-12 sm:col-span-12 md:col-span-3 lg:col-span-3 xl:col-span-3 2xl:col-span-3">Column</div>
    <div class="col-span-12 sm:col-span-12 md:col-span-3 lg:col-span-3 xl:col-span-3 2xl:col-span-3">Column</div>
  </div>
</div>

Laravel live wire accordion collapsing on input change

I am using accordion something like this
https://www.tailwindtoolbox.com/components/accordion and I have a input field inside my accordion
<div class="tab-content overflow-y-scroll border-l-2 bg-gray-100 border-indigo-500 leading-normal">
<div class="border border-black mt-3 p-3 grid grid-cols-4">
<div class="col-span-1">
<label for="about" class="block text-sm leading-5 font-medium text-gray-700">
Title
</label>
<div class="rounded-md shadow-sm">
<textarea wire:model="additional_docs.title" name="additional_docs" id="edit_additional_docs" name="" rows="3" class="form-textarea mt-1 block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5" placeholder="description"></textarea>
</div>
<p class="mt-2 text-sm text-gray-500">
Document Title
</p>
</div>
</div>
The accordion is working fine but as soon as I start typing the accordion closes and I need to open accordion again and start typing, but if I remove wire:model ,it works fine .I am new to live wire and if I use wire:ignore it doesn't help too.
Thanks for any help :)
Add wire:ignore.self on the element which will be hidden/shown.

Can't access component method inside my blade file

I am trying to access a method inside my blade file, with #click but I am getting an error
signup-modal.vue
<template>
<div>
<div v-if="modal" class="animated fadeIn fixed z-50 pin overflow-auto bg-black flex">
<div class="animated fadeInUp fixed shadow-inner max-w-md md:relative pin-b pin-x align-top m-auto justify-end md:justify-center p-8 bg-white md:rounded w-full md:h-auto md:shadow flex flex-col">
<p class="text-xl leading-normal mb-8 text-center">
{{ __("Sign up to name to start socializing") }}
</p>
<div class="justify-center">
<form action="/auth/register" method="post">
<div class="mb-4">
<label class="block text-grey-darker text-sm font-bold mb-2" for="username">
{{ __("Name" )}}
</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker leading-tight" id="username" type="text" placeholder="Username">
</div>
<div class="mb-4">
<label class="block text-grey-darker text-sm font-bold mb-2" for="username">
{{ __("Email" )}}
</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker leading-tight" id="username" type="text" placeholder="Username">
</div>
<div class="mb-4">
<label class="block text-grey-darker text-sm font-bold mb-2" for="username">
{{ __("Password" )}}
</label>
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker leading-tight" id="username" type="text" placeholder="Username">
</div>
<div class="flex items-center justify-end">
<button class="bg-teal hover:bg-teal-dark text-white font-bold py-2 px-4 rounded" type="button">
{{ __("Sign up") }}
</button>
</div>
</form>
</div>
<span #click="toggleModal" class="absolute pin-t pin-r pt-4 px-4">
<svg class="h-6 w-6 text-grey hover:text-grey-darkest" role="button" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><title>Close</title><path d="M14.348 14.849a1.2 1.2 0 0 1-1.697 0L10 11.819l-2.651 3.029a1.2 1.2 0 1 1-1.697-1.697l2.758-3.15-2.759-3.152a1.2 1.2 0 1 1 1.697-1.697L10 8.183l2.651-3.031a1.2 1.2 0 1 1 1.697 1.697l-2.758 3.152 2.758 3.15a1.2 1.2 0 0 1 0 1.698z"/></svg>
</span>
</div>
</div>
</div>
</template>
<script>
export default {
data: function()
{
return {
modal: false
}
},
methods: {
toggleModal: function() {
console.log("djdjd")
//this.modal = !this.modal
}
}
}
</script>
app.js
/**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap');
window.Vue = require('vue');
Vue.component('signup-modal', require('./components/signup-modal.vue'));
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
const app = new Vue({
el: '#app'
});
My blade file:
<div id="app">
<button class="bg-blue w-full rounded-full text-white py-2 mb-2" #click="toggleModal">
{{ __("Sign up") }}
</button>
</div>
<div>
<signup-modal></signup-modal>
</div>
</div>
As you can see in my blade file I am trying to access my components method toggleModal but I am getting an error:
app.js:36520 [Vue warn]: Property or method "toggleModal" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
(found in <Root>)
warn # app.js:36520
warnNonPresent # app.js:37826
has # app.js:37859
(anonymous) # VM374:3
Vue._render # app.js:40471
updateComponent # app.js:38715
get # app.js:39069
Watcher # app.js:39058
mountComponent # app.js:38722
Vue.$mount # app.js:44467
Vue.$mount # app.js:46866
Vue._init # app.js:40567
Vue # app.js:40656
(anonymous) # app.js:13896
__webpack_require__ # app.js:20
(anonymous) # app.js:13869
__webpack_require__ # app.js:20
(anonymous) # app.js:63
(anonymous) # app.js:66
app.js:36520 [Vue warn]: Invalid handler for event "click": got undefined
Why is this and how can I fix it?
To achieve what I wanted to do, I went the event-based way. For example, in my component, I added the method mounted, and added the following:
mounted()
{
eventHub.$on('signup-click', this.toggleModal)
}
And my main Vue method I added a simple event emitter method like so:
const app = new Vue({
el: '#app',
methods: {
generateEvent: (event) => {
eventHub.$emit(event);
}
}
});
And then in my blade file, I simple called that method like so:
<button class="bg-blue w-full rounded-full text-white py-2 mb-2" #click="generateEvent('signup-click')">
{{ __("Sign up") }}
</button>
Which simple emits the event, so my component listens to it, then calls that child method.

Resources