Laravel Nova - Display text area content without option show content - laravel

I would like to display text area resource field content always without showing option "Show Content" or display it by default.
Is it possible?

As of v1.1.4
There is now an option to always show.
Textarea::make('Title')->alwaysShow()
As of v1.0.19
You cannot. If you take a look at the TextareaField.vue (nova/resources/js/components/Detail/TextareaField.vue):
<template>
<panel-item :field="field">
<template slot="value">
<excerpt :content="field.value" />
</template>
</panel-item>
</template>
Then if you take a look at Excerpt.vue (nova/resources/js/components/Excerpt.vue):
<div v-if="hasContent">
<div v-if="expanded" class="markdown leading-normal" v-html="content" />
<a
#click="toggle"
class="cursor-pointer dim inline-block text-primary font-bold"
:class="{ 'mt-6': expanded }"
aria-role="button"
>
{{ showHideLabel }}
</a>
</div>
And the props of the vue:
props: {
content: {
type: String,
},
},
data: () => ({ expanded: false }),
There's no option to pass the expanded attribute.

Related

Vue Component text only partially passes to slot, the rest appears in outer div

I have a wrapping formatting vue component with a slot, and two components that use it. When passing a list structure it works fine, as it does when using the wrapping div directly, but it fails when trying to pass a simple string. The first word of the string renders as expected, but the rest appears in the opening div. I've tried wrapping the mustached prop in additional html tags, but the content still doesn't render correctly.
Display Text component
<template>
<two-col-row-display
:field="field"
:fieldcss="fieldcss"
:valuecss="valuecss"
>
{{ value }}
</two-col-row-display>
</template>
<script>
export default {
props: {
field: {
type: String,
required: true,
},
fieldcss: {
type: String,
},
value: {
type: String,
default: '',
},
valuecss: {
type: String,
},
},
}
</script>
Two column row display wrapper component
<template>
<div class="gridwrap">
<div class="row field" :class="fieldcss">
{{ field + ':' }}
</div>
<div class="row value" :class="valuecss">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
props: {
field: {
type: String,
},
fieldcss: {
type: String,
},
valuecss: {
type: String,
},
},
}
</script>
Display Text used
<display-text
field="Description"
value={{ $recipe->description }}
></display-text>
But it outputs only the first part of the description "All" where it should. The rest of the description "of the recipe" gets output as an attribute of the wrapping div.
Output html
<div class="gridwrap" of the recipe>
<div class="row field"> Description: </div>
<div class="row value"> All </div>
</div>
Using the wrapping component directly works as expected, but I don't want to use that component directly.
<two-col-row-display
field="Description???"
>{{ $recipe->description }}
</two-col-row-display>
outputs the desired result for the display-text component
<div class="gridwrap">
<div class="row field"> Description???: </div>
<div class="row value">All of the recipe </div>
</div>
How can I modify the display-text component to render the text in the slot correctly?
I neglected to wrap the data passed to the value prop in quotes. The display text component should be filled out like:
<display-text
field="Description"
value="{{ $recipe->description }}"
></display-text>

Vue.js 3 - Add list items from component dynamically

I am new to vue, I found some examples but I could not reproduce in my situation.
I have some inputs user will fill out and once it clicks the button, the information will populate a list of items. I am trying to crete < li > with a OrderListItem component. But I am getting this error:
runtime-core.esm-bundler.js?5c40:217 Uncaught ReferenceError: machines is not defined
at eval (OrderListItem.vue?fb66:14)
Here is the form
<template>
<div>
<div class="flex flex-col mb-4 md:w-full m-1">
<label for="planter_model_id">Planter</label>
<select v-model="registration.planter_model_id" name="planter_model_id">
<option disabled selected>Planter</option>
<option v-for="planter in planters" :key="planter" :value="planter.id">{{planter.brand.name}} {{planter.name }}</option>
</select>
</div>
<div class="flex flex-col mb-4 md:w-full m-1">
<label class=" for="lines">Lines</label>
<Input v-model="registration.lines" type="number" name="lines" />
</div>
<Button type="button" #click="addItemOrder">Add</Button>
</div>
<div>
<ul>
<OrderListItem :machines="machines" />
</ul>
<div>
</template>
Here is my code
export default {
components: {
OrderListItem,
Button,
},
props: {
planters:{
type:Array,
required: true
},
},
data() {
return {
machines: [], //this what I wish to be passed to OrderListItem component
registration:{
lines:null,
planter_model_id:null,
},
}
},
methods:{
addItemOrder(){
let item = {}
item.planter_model_id = this.registration.planter_model_id
item.lines = this.registration.lines
this.machines.push(item)
}
}
};
And here is my OrderListItem component that I created on another file:
<template>
<li v-for="machine in machines" :key="machine">
<div class="flex-initial w-3/5">
<p>Planter: {{machine.planter_model_id}}</p>
<p>Lines: {{machine.lines}}</p>
</div>
</li>
</template>
<script>
export default {
name: 'OrderListItem',
props:{
machines,
}
}
</script>
I don’t know if it is relevant but I am using vue3 and laravel.
I am very newbie here and from what I learned I think if machines array was a prop I would be able to access it on my component. But I will dynamically add a and remove itens from machines array and I think props receive data from server so It should not be declared there, that why I declared inside data().
Thanks =)
You should define the prop by adding its type and default value :
export default {
name: 'OrderListItem',
props:{
machines:{type:Array,default:()=>[]},
}
}

vuetify and laravel display of validation error

I just wanted to fix the display of errors in the view page. It is being displayed as JSON format. How do I fix this?
Vue.component
<template>
<v-alert
dense
outlined
type="error"
>
{{ allerror }}
</v-alert>
...
...
</template>
<script>
data: () => ({
allerror: ''
}),
axios
.post('/api/section', { name, department_id })
.then(response => {
this.getSections()
this.snackbar.appear = true
this.snackbar.alert = response.data.alert
this.snackbar.icon = response.data.icon
this.$refs.form.reset()
})
.catch(error => this.allerror = error.response.data.errors)
</script>
there are 2 ways to go:
1 - Show specific errors on specific field by:
<v-text-field
label="Name"
v-model="name"
:error-messages="allerror.name"
></v-text-field>
2 - Show all error:
<v-alert
dense
outlined
type="error"
>
<ul>
<li v-for="(errors, field) in allerror">
{{ field }} //name of the field
//run second loop to display all errors for this field
<ul>
<li v-for="error in errors">
{{ error }}
</li>
</ul>
</li>
</ul>
</v-alert>
Add custom css class
.invalid-feedback {
width: 100%;
margin-top: 0.25rem;
font-size: 80%;
color: #e3342f;
}
Then bind invalid-feedback in the text field, if you are using laravel you can find invalid-feedback in app.css file
<v-text-field
v-model="form.email"
:rules="[rules.required, rules.emailRules]"
:class="{ 'is-invalid':
form.errors.has('email') }"
label="E-mail"
required
></v-text-field>

Button that shows modal for each b-table row

Im using laravel, vue, and bootstrap-vue.
I have created a vue component that displays a table of elements (subnets in this example).
For each of them I show a component (modal_edit-subnet) thats should open a modal that allows to edit the data of the element of the related row.
The problem is that it shows modals for all of the table elements. For example, if the table has 3 rows, it shows 3 modals (after closing one it shows the next). Each of the modals with the data of each of the rows.
I've tried to add "key"s but no success.
What am i doing wrong?
Thanks!
Component that shows the table
<template>
<div>
<b-card class="text-center">
<b-table small striped hover :items="data_subnets" :fields="fields" :tbody-tr-class="rowClass">
<template slot="[ip_address]" slot-scope="data_subnets">
<b>{{ long2ip(data_subnets.item.ip_address) }}</b>
</template>
<template slot="[actions]" slot-scope="data_subnets">
v-on:deleteSubnet="deleteSubnet"></modal_delete-subnet>
<modal_edit-subnet :key="'modal_edit_subnet' + data_subnets.item.id" :subnet="data_subnets.item" v-on:editSubnet="editSubnet"></modal_edit-subnet>
</template>
</b-table>
</b-card>
</div>
</template>
Modal modal_edit-subnet
<template>
<div>
<b-button size="sm" v-b-modal.modal-edit-subnet>Edit</b-button>
<b-modal
id="modal-edit-subnet"
ref="modal"
title="Edit subnet"
#ok="handleOk"
>
This is subnet {{data_subnet.id}}
</b-modal>
</div>
</template>
The problem is that:
You're rendering a modal for each row of the table and;
Reading the docs, it seems like the modal is triggered by the id, and your b-modal id is not dynamic depending on the row.
How to fix it:
Use just one modal on the b-table level
Dynamically inject id into your modal_edit-subnet component:
<template>
<div>
<b-button size="sm" v-b-modal[id]>Edit</b-button>
<b-modal
:id="id"
ref="modal"
title="Edit subnet"
#ok="handleOk"
>
This is subnet {{data_subnet.id}}
</b-modal>
</div>
</template>
<script>
export default {
props: {
id: {
type: String | Number
}
}
}
</script>
Use v-model (this is the way I would do it)
<template>
<div>
<b-button size="sm" #click="show = true">Edit</b-button>
<b-modal
v-model="show"
ref="modal"
title="Edit subnet"
#ok="handleOk"
>
This is subnet {{data_subnet.id}}
</b-modal>
</div>
</template>
<script>
export default {
data() {
return {
show: false
}
}
}
</script>

How to properly implement hover effect on icon links in Nuxt.js

I'm trying to implement a hover effect on an icon link for a component in a site built using Nuxt.js with Bootstrap 4. I've attempted using the #mouseover/#mouseenter and #mouseleave events to switch the src attribute from one icon image to another, but it doesn't cause a change unless the icon link is clicked. Does this have something to do with focus? Is there a better way to get the effect I want?
The component is below.
<template>
<b-row class="main-focus px-3 pt-3">
<b-col md="12" class="mb-4">
<h1 class="clr-t mb-4 px-2 pb-1 clr-brdr-btm">resume</h1>
<p class="drk-t pl-2">{{description[0].text}}</p>
<b-link
#mouseover="icon = 'assets/images/icons/resume-icon-clicked.svg'"
#mouseleave="icon = 'assets/images/icons/resume-icon.svg'"
:href="resume.url"
target="_blank"
>
<b-img
class="icon bg-lt"
v-bind="iconProps"
rounded
:src="icon"/>
</b-link>
</b-col>
</b-row>
</template>
<script>
export default {
props: {
description: Array,
resume: Object
},
data () {
return {
icon: 'assets/images/icons/resume-icon.svg',
iconProps: { width: 100 }
}
}
}
</script>
The above behaviour is because b-link supports only #click event as stated in docs.
You can achieve the functionality by wrapping b-link in a div as below.
<div #mouseover="icon = 'assets/images/icons/resume-icon-clicked.svg'"
#mouseleave="icon = 'assets/images/icons/resume-icon.svg'">
<b-link
:href="resume.url"
target="_blank"
>
<b-img
class="icon bg-lt"
v-bind="iconProps"
rounded
:src="icon"/>
</b-link>
</div>

Resources