
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 element**f7-messagebar-sheet**- messagebar sheet element**f7-messagebar-sheet-image**- messagebar sheet image item**f7-messagebar-sheet-item**- messagebar sheet item**f7-messagebar-attachments**- messagebar attachments element**f7-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 resizeable textarea max height | |
| resizable | bolean | true | Enables resizeable 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">. element**before-area**- element will be inserted right before textarea. Messagebar attachments go here**after-area**- element will be inserted right after textarea**send-link**- element will be inserted inside of send link**before-inner**- element will be inserted right before<div class="toolbar-inner">. element**after-inner**- element will be inserted right after<div class="toolbar-inner">. element. Messagebar sheet goes here**inner-start**- element will be inserted in the beginning of<div class="toolbar-inner">. element**inner-end**- element will be inserted in the end of<div class="toolbar-inner">. element. Same asdefaultslot
1. <f7-messagebar placeholder="Message" @submit="onSubmit">
2. <div slot="before-inner">Before inner</div>
3. <div slot="after-inner">After inner</div>
4. <div slot="before-area">Before textarea</div>
5. <div slot="after-area">After textarea</div>
6. <f7-icon ios="f7:arrow_up_fill" md="material:send" slot="send-link"></f7-icon>
7. <div>Default slot</div>
8. </f7-messagebar>
Renders to:
1. <div class="toolbar messagebar">
2. <div>Before inner</div>
3. <div class="toolbar-inner">
4. <div class="messagebar-area">
5. <div>Before textarea</div>
6. <textarea placeholder="Message"></textarea>
7. <div>After textarea</div>
8. </div>
9. <a href="#" class="link"><i class="icon f7-icons">arrow_up_fill</i></a>
10. <div>Default slot</div>
11. </div>
12. <div>After inner</div>
13. </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:
1. <template>
2. <f7-page>
3. <f7-navbar title="Messsages"></f7-navbar>
5. <f7-messagebar
6. :placeholder="placeholder"
7. ref="messagebar"
8. :attachments-visible="attachmentsVisible"
9. :sheet-visible="sheetVisible"
10. >
11. <f7-link
12. icon-ios="f7:camera_fill"
13. icon-md="material:camera_alt"
14. slot="inner-start"
15. @click="sheetVisible = !sheetVisible"
16. ></f7-link>
17. <f7-link
18. icon-ios="f7:arrow_up_fill"
19. icon-md="material:send"
20. slot="inner-end"
21. @click="sendMessage"
22. ></f7-link>
23. <f7-messagebar-attachments>
24. <f7-messagebar-attachment
25. v-for="(image, index) in attachments"
26. :key="index"
27. :image="image"
28. @attachment:delete="deleteAttachment(image)"
29. ></f7-messagebar-attachment>
30. </f7-messagebar-attachments>
31. <f7-messagebar-sheet>
32. <f7-messagebar-sheet-image
33. v-for="(image, index) in images"
34. :key="index"
35. :image="image"
36. :checked="attachments.indexOf(image) >= 0"
37. @change="handleAttachment"
38. ></f7-messagebar-sheet-image>
39. </f7-messagebar-sheet>
40. </f7-messagebar>
42. <f7-messages ref="messages">
43. <f7-messages-title><b>Sunday, Feb 9,</b> 12:58</f7-messages-title>
44. <f7-message
45. v-for="(message, index) in messagesData"
46. :key="index"
47. :type="message.type"
48. :image="message.image"
49. :name="message.name"
50. :avatar="message.avatar"
51. :first="isFirstMessage(message, index)"
52. :last="isLastMessage(message, index)"
53. :tail="isTailMessage(message, index)"
54. >
55. <span slot="text" v-if="message.text" v-html="message.text"></span>
56. </f7-message>
57. <f7-message v-if="typingMessage"
58. type="received"
59. :typing="true"
60. :first="true"
61. :last="true"
62. :tail="true"
63. :header="`${typingMessage.name} is typing`"
64. :avatar="typingMessage.avatar"
65. ></f7-message>
66. </f7-messages>
67. </f7-page>
68. </template>
69. <script>
70. export default {
71. data() {
72. return {
73. attachments: [],
74. sheetVisible: false,
75. typingMessage: null,
76. messagesData: [
77. {
78. type: 'sent',
79. text: 'Hi, Kate',
80. },
81. {
82. type: 'sent',
83. text: 'How are you?',
84. },
85. {
86. name: 'Kate',
87. type: 'received',
88. text: 'Hi, I am good!',
89. avatar: 'http://lorempixel.com/100/100/people/9',
90. },
91. {
92. name: 'Blue Ninja',
93. type: 'received',
94. text: 'Hi there, I am also fine, thanks! And how are you?',
95. avatar: 'http://lorempixel.com/100/100/people/7',
96. },
97. {
98. type: 'sent',
99. text: 'Hey, Blue Ninja! Glad to see you ;)',
100. },
101. {
102. type: 'sent',
103. text: 'Hey, look, cutest kitten ever!',
104. },
105. {
106. type: 'sent',
107. image: 'http://lorempixel.com/200/260/cats/4/',
109. },
110. {
111. name: 'Kate',
112. type: 'received',
113. text: 'Nice!',
114. avatar: 'http://lorempixel.com/100/100/people/9',
115. },
116. {
117. name: 'Kate',
118. type: 'received',
119. text: 'Like it very much!',
120. avatar: 'http://lorempixel.com/100/100/people/9',
121. },
122. {
123. name: 'Blue Ninja',
124. type: 'received',
125. text: 'Awesome!',
126. avatar: 'http://lorempixel.com/100/100/people/7',
127. },
128. ],
129. images: [
130. 'http://lorempixel.com/300/300/cats/1/',
131. 'http://lorempixel.com/200/300/cats/2/',
132. 'http://lorempixel.com/400/300/cats/3/',
133. 'http://lorempixel.com/300/150/cats/4/',
134. 'http://lorempixel.com/150/300/cats/5/',
135. 'http://lorempixel.com/300/300/cats/6/',
136. 'http://lorempixel.com/300/300/cats/7/',
137. 'http://lorempixel.com/200/300/cats/8/',
138. 'http://lorempixel.com/400/300/cats/9/',
139. 'http://lorempixel.com/300/150/cats/10/',
140. ],
141. people: [
142. {
143. name: 'Kate Johnson',
144. avatar: 'http://lorempixel.com/100/100/people/9',
145. },
146. {
147. name: 'Blue Ninja',
148. avatar: 'http://lorempixel.com/100/100/people/7',
149. },
150. ],
151. answers: [
152. 'Yes!',
153. 'No',
154. 'Hm...',
155. 'I am not sure',
156. 'And what about you?',
157. 'May be ;)',
158. 'Lorem ipsum dolor sit amet, consectetur',
159. 'What?',
160. 'Are you sure?',
161. 'Of course',
162. 'Need to think about it',
163. 'Amazing!!!',
164. ],
165. responseInProgress: false,
166. };
167. },
168. computed: {
169. attachmentsVisible() {
170. const self = this;
171. return self.attachments.length > 0;
172. },
173. placeholder() {
174. const self = this;
175. return self.attachments.length > 0 ? 'Add comment or Send' : 'Message';
176. },
177. },
178. mounted() {
179. const self = this;
180. self.$f7ready(() => {
181. self.messagebar = self.$refs.messagebar.f7Messagebar;
182. self.messages = self.$refs.messages.f7Messages;
183. });
184. },
185. methods: {
186. isFirstMessage(message, index) {
187. const self = this;
188. const previousMessage = self.messagesData[index - 1];
189. if (message.isTitle) return false;
190. if (!previousMessage || previousMessage.type !== message.type || previousMessage.name !== message.name) return true;
191. return false;
192. },
193. isLastMessage(message, index) {
194. const self = this;
195. const nextMessage = self.messagesData[index + 1];
196. if (message.isTitle) return false;
197. if (!nextMessage || nextMessage.type !== message.type || nextMessage.name !== message.name) return true;
198. return false;
199. },
200. isTailMessage(message, index) {
201. const self = this;
202. const nextMessage = self.messagesData[index + 1];
203. if (message.isTitle) return false;
204. if (!nextMessage || nextMessage.type !== message.type || nextMessage.name !== message.name) return true;
205. return false;
206. },
207. deleteAttachment(image) {
208. const self = this;
209. const index = self.attachments.indexOf(image);
210. self.attachments.splice(index, 1)[0]; // eslint-disable-line
211. },
212. handleAttachment(e) {
213. const self = this;
214. const index = self.$$(e.target).parents('label.checkbox').index();
215. const image = self.images[index];
216. if (e.target.checked) {
217. // Add to attachments
218. self.attachments.unshift(image);
219. } else {
220. // Remove from attachments
221. self.attachments.splice(self.attachments.indexOf(image), 1);
222. }
223. },
224. sendMessage() {
225. const self = this;
226. const text = self.messagebar.getValue().replace(/\n/g, '<br>').trim();
227. const messagesToSend = [];
228. self.attachments.forEach((attachment) => {
229. messagesToSend.push({
230. image: attachment,
231. });
232. });
233. if (text.trim().length) {
234. messagesToSend.push({
235. text,
236. });
237. }
238. if (messagesToSend.length === 0) {
239. return;
240. }
242. // Reset attachments
243. self.attachments = [];
244. // Hide sheet
245. self.sheetVisible = false;
246. // Clear area
247. self.messagebar.clear();
248. // Focus area
249. if (text.length) self.messagebar.focus();
250. // Send message
251. self.messagesData.push(...messagesToSend);
253. // Mock response
254. if (self.responseInProgress) return;
255. self.responseInProgress = true;
256. setTimeout(() => {
257. const answer = self.answers[Math.floor(Math.random() * self.answers.length)];
258. const person = self.people[Math.floor(Math.random() * self.people.length)];
259. self.typingMessage = {
260. name: person.name,
261. avatar: person.avatar,
262. };
263. setTimeout(() => {
264. self.messagesData.push({
265. text: answer,
266. type: 'received',
267. name: person.name,
268. avatar: person.avatar,
269. });
270. self.typingMessage = null;
271. self.responseInProgress = false;
272. }, 4000);
273. }, 1000);
274. },
275. },
276. };
277. </script>
