Messagebar Vue Component
- Messagebar Components
- Messagebar Properties
- Messagebar Methods
- Messagebar Events
- Messagebar Slots
- Access To Messagebar Instance
- Examples
Messagebar Vue component represents Framework7's Messagebar component.
Messagebar Components
There are following components included:
f7-messagebar
- main messagebar elementf7-messagebar-sheet
- messagebar sheet elementf7-messagebar-sheet-image
- messagebar sheet image itemf7-messagebar-sheet-item
- messagebar sheet itemf7-messagebar-attachments
- messagebar attachments elementf7-messagebar-attachment
- single messagebar attachment element
Messagebar Properties
Prop | Type | Default | Description |
---|---|---|---|
<f7-messagebar> properties | |||
init | boolean | true | Initializes Messagebar |
name | string | Textarea "name" attribute | |
textarea-id | string number | Textarea "id" attribute | |
placeholder | string | Message | Textarea placeholder text |
value | string number | Textarea value | |
readonly | boolean | false | Sets "readonly" textarea attribute |
disabled | boolean | false | Sets "disbled" textarea attribute |
send-link | string | Enables Send link and specifies its text. This property will be ignored in case you use send-link slot | |
max-height | number | Defines resizable textarea max height | |
resizable | boolean | true | Enables resizable textarea |
sheet-visible | boolean | false | Makes messagebar sheet visible/active |
attachments-visible | boolean | false | Makes messagebar attachments visible/active |
resize-page | boolean | true | When enabled, it will resize messages page when messagebar textarea size changed |
<f7-messagebar-sheet-image> properties | |||
image | string | Sheet image URL | |
checked | boolean | false | Indicates whether this sheet image-item is checked or not |
<f7-messagebar-attachment> properties | |||
image | string | Attachment image URL | |
deletable | boolean | true | Defines whether the attachment is deletable or not. In case of deletable the additional delete button will be rendered |
Messagebar Methods
<f7-messagebar> methods | |
---|---|
.clear() | Clear textarea and update/reset its size |
.setValue(newValue) | Set messagebar textarea value/text |
.getValue() | Return messagebar textarea value |
.resize() | Force Messagebar to resize messages page depending on messagebar height/size |
.focus() | Focus messagebar textarea |
.blur() | Remove focus from messagebar textarea |
Messagebar Events
Event | Arguments | Description |
---|---|---|
<f7-messagebar> events | ||
change | (event) | Event will be triggered when "change" event occurs on messagebar textarea element |
input | (event) | Event will be triggered when "input" event occurs on messagebar textarea element |
focus | (event) | Event will be triggered when "focus" event occurs on messagebar textarea element |
blur | (event) | Event will be triggered when "blur" event occurs on messagebar textarea element |
submit send | (value, clear) | Event will be triggered when user clicks on messagebar "send link" |
<f7-messagebar-sheet-image> events | ||
change | (event) | Event will be triggered on sheet item checkbox change |
<f7-messagebar-attachment> events | ||
attachment:click | (event) | Event will be triggered on attachment click |
attachment:delete | (event) | Event will be triggered on attachment delete button click |
Messagebar Slots
Messagebar Vue component has additional slots for custom elements:
default
- element will be inserted in the end of<div class="toolbar-inner">
. elementbefore-area
- element will be inserted right before textarea. Messagebar attachments go hereafter-area
- element will be inserted right after textareasend-link
- element will be inserted inside of send linkbefore-inner
- element will be inserted right before<div class="toolbar-inner">
. elementafter-inner
- element will be inserted right after<div class="toolbar-inner">
. element. Messagebar sheet goes hereinner-start
- element will be inserted in the beginning of<div class="toolbar-inner">
. elementinner-end
- element will be inserted in the end of<div class="toolbar-inner">
. element. Same asdefault
slot
<f7-messagebar placeholder="Message" @submit="onSubmit">
<div slot="before-inner">Before inner</div>
<div slot="after-inner">After inner</div>
<div slot="before-area">Before textarea</div>
<div slot="after-area">After textarea</div>
<f7-icon ios="f7:arrow_up_fill" aurora="f7:arrow_up_fill" md="material:send" slot="send-link"></f7-icon>
<div>Default slot</div>
</f7-messagebar>
Renders to:
<div class="toolbar messagebar">
<div>Before inner</div>
<div class="toolbar-inner">
<div class="messagebar-area">
<div>Before textarea</div>
<textarea placeholder="Message"></textarea>
<div>After textarea</div>
</div>
<a href="#" class="link"><i class="icon f7-icons">arrow_up_fill</i></a>
<div>Default slot</div>
</div>
<div>After inner</div>
</div>
Access To Messagebar Instance
If you use automatic initalization to init Messagebar (with init:true
prop) and need to use its Methods and Properties you can access its initialized instance by accessing .f7Messagebar
component's property.
Examples
Here is how the full example of Messages page where it can be used together with Messages:
<template>
<f7-page>
<f7-navbar title="Messages"></f7-navbar>
<f7-messagebar
:placeholder="placeholder"
ref="messagebar"
:attachments-visible="attachmentsVisible"
:sheet-visible="sheetVisible"
>
<f7-link
icon-ios="f7:camera_fill"
icon-aurora="f7:camera_fill"
icon-md="material:camera_alt"
slot="inner-start"
@click="sheetVisible = !sheetVisible"
></f7-link>
<f7-link
icon-ios="f7:arrow_up_fill"
icon-aurora="f7:arrow_up_fill"
icon-md="material:send"
slot="inner-end"
@click="sendMessage"
></f7-link>
<f7-messagebar-attachments>
<f7-messagebar-attachment
v-for="(image, index) in attachments"
:key="index"
:image="image"
@attachment:delete="deleteAttachment(image)"
></f7-messagebar-attachment>
</f7-messagebar-attachments>
<f7-messagebar-sheet>
<f7-messagebar-sheet-image
v-for="(image, index) in images"
:key="index"
:image="image"
:checked="attachments.indexOf(image) >= 0"
@change="handleAttachment"
></f7-messagebar-sheet-image>
</f7-messagebar-sheet>
</f7-messagebar>
<f7-messages ref="messages">
<f7-messages-title><b>Sunday, Feb 9,</b> 12:58</f7-messages-title>
<f7-message
v-for="(message, index) in messagesData"
:key="index"
:type="message.type"
:image="message.image"
:name="message.name"
:avatar="message.avatar"
:first="isFirstMessage(message, index)"
:last="isLastMessage(message, index)"
:tail="isTailMessage(message, index)"
>
<span slot="text" v-if="message.text" v-html="message.text"></span>
</f7-message>
<f7-message v-if="typingMessage"
type="received"
:typing="true"
:first="true"
:last="true"
:tail="true"
:header="`${typingMessage.name} is typing`"
:avatar="typingMessage.avatar"
></f7-message>
</f7-messages>
</f7-page>
</template>
<script>
export default {
data() {
return {
attachments: [],
sheetVisible: false,
typingMessage: null,
messagesData: [
{
type: 'sent',
text: 'Hi, Kate',
},
{
type: 'sent',
text: 'How are you?',
},
{
name: 'Kate',
type: 'received',
text: 'Hi, I am good!',
avatar: 'https://cdn.framework7.io/placeholder/people-100x100-9.jpg',
},
{
name: 'Blue Ninja',
type: 'received',
text: 'Hi there, I am also fine, thanks! And how are you?',
avatar: 'https://cdn.framework7.io/placeholder/people-100x100-7.jpg',
},
{
type: 'sent',
text: 'Hey, Blue Ninja! Glad to see you ;)',
},
{
type: 'sent',
text: 'Hey, look, cutest kitten ever!',
},
{
type: 'sent',
image: 'https://cdn.framework7.io/placeholder/cats-200x260-4.jpg',
},
{
name: 'Kate',
type: 'received',
text: 'Nice!',
avatar: 'https://cdn.framework7.io/placeholder/people-100x100-9.jpg',
},
{
name: 'Kate',
type: 'received',
text: 'Like it very much!',
avatar: 'https://cdn.framework7.io/placeholder/people-100x100-9.jpg',
},
{
name: 'Blue Ninja',
type: 'received',
text: 'Awesome!',
avatar: 'https://cdn.framework7.io/placeholder/people-100x100-7.jpg',
},
],
images: [
'https://cdn.framework7.io/placeholder/cats-300x300-1.jpg',
'https://cdn.framework7.io/placeholder/cats-200x300-2.jpg',
'https://cdn.framework7.io/placeholder/cats-400x300-3.jpg',
'https://cdn.framework7.io/placeholder/cats-300x150-4.jpg',
'https://cdn.framework7.io/placeholder/cats-150x300-5.jpg',
'https://cdn.framework7.io/placeholder/cats-300x300-6.jpg',
'https://cdn.framework7.io/placeholder/cats-300x300-7.jpg',
'https://cdn.framework7.io/placeholder/cats-200x300-8.jpg',
'https://cdn.framework7.io/placeholder/cats-400x300-9.jpg',
'https://cdn.framework7.io/placeholder/cats-300x150-10.jpg',
],
people: [
{
name: 'Kate Johnson',
avatar: 'https://cdn.framework7.io/placeholder/people-100x100-9.jpg',
},
{
name: 'Blue Ninja',
avatar: 'https://cdn.framework7.io/placeholder/people-100x100-7.jpg',
},
],
answers: [
'Yes!',
'No',
'Hm...',
'I am not sure',
'And what about you?',
'May be ;)',
'Lorem ipsum dolor sit amet, consectetur',
'What?',
'Are you sure?',
'Of course',
'Need to think about it',
'Amazing!!!',
],
responseInProgress: false,
};
},
computed: {
attachmentsVisible() {
const self = this;
return self.attachments.length > 0;
},
placeholder() {
const self = this;
return self.attachments.length > 0 ? 'Add comment or Send' : 'Message';
},
},
mounted() {
const self = this;
self.$f7ready(() => {
self.messagebar = self.$refs.messagebar.f7Messagebar;
self.messages = self.$refs.messages.f7Messages;
});
},
methods: {
isFirstMessage(message, index) {
const self = this;
const previousMessage = self.messagesData[index - 1];
if (message.isTitle) return false;
if (!previousMessage || previousMessage.type !== message.type || previousMessage.name !== message.name) return true;
return false;
},
isLastMessage(message, index) {
const self = this;
const nextMessage = self.messagesData[index + 1];
if (message.isTitle) return false;
if (!nextMessage || nextMessage.type !== message.type || nextMessage.name !== message.name) return true;
return false;
},
isTailMessage(message, index) {
const self = this;
const nextMessage = self.messagesData[index + 1];
if (message.isTitle) return false;
if (!nextMessage || nextMessage.type !== message.type || nextMessage.name !== message.name) return true;
return false;
},
deleteAttachment(image) {
const self = this;
const index = self.attachments.indexOf(image);
self.attachments.splice(index, 1)[0]; // eslint-disable-line
},
handleAttachment(e) {
const self = this;
const index = self.$$(e.target).parents('label.checkbox').index();
const image = self.images[index];
if (e.target.checked) {
// Add to attachments
self.attachments.unshift(image);
} else {
// Remove from attachments
self.attachments.splice(self.attachments.indexOf(image), 1);
}
},
sendMessage() {
const self = this;
const text = self.messagebar.getValue().replace(/\n/g, '<br>').trim();
const messagesToSend = [];
self.attachments.forEach((attachment) => {
messagesToSend.push({
image: attachment,
});
});
if (text.trim().length) {
messagesToSend.push({
text,
});
}
if (messagesToSend.length === 0) {
return;
}
// Reset attachments
self.attachments = [];
// Hide sheet
self.sheetVisible = false;
// Clear area
self.messagebar.clear();
// Focus area
if (text.length) self.messagebar.focus();
// Send message
self.messagesData.push(...messagesToSend);
// Mock response
if (self.responseInProgress) return;
self.responseInProgress = true;
setTimeout(() => {
const answer = self.answers[Math.floor(Math.random() * self.answers.length)];
const person = self.people[Math.floor(Math.random() * self.people.length)];
self.typingMessage = {
name: person.name,
avatar: person.avatar,
};
setTimeout(() => {
self.messagesData.push({
text: answer,
type: 'received',
name: person.name,
avatar: person.avatar,
});
self.typingMessage = null;
self.responseInProgress = false;
}, 4000);
}, 1000);
},
},
};
</script>