メッセージバー
Framework7には、メッセージで使用するための特別なサイズ変更可能なツールバーが付属しています。
メッセージバーレイアウト
メッセージバーのレイアウトは非常にシンプルです。
<div class="toolbar messagebar">
<div class="toolbar-inner">
<div class="messagebar-area">
<!-- messagebar attachments -->
<div class="messagebar-attachments">...</div>
<!-- messagebar resizable textarea -->
<textarea class="resizable" placeholder="Message"></textarea>
</div>
<a href="#" class="link">Send</a>
</div>
<!-- messagebar sheet -->
<div class="messagebar-sheet">...</div>
</div>
場所
messagebar-attachments
- メッセージバーの添付ファイルを含むブロック。オプションです。messagebar-sheet
- メッセージバーシートを含むブロック。オプションです。
メッセージバーの位置は非常に重要です。page
の内側に、page-content
の直前に配置する必要があります。
<div class="page">
<!-- navbar -->
<div class="navbar">...</div>
<!-- messagebar -->
<div class="toolbar messagebar">...</div>
<!-- page-content/messages-content -->
<div class="page-content messages-content">
... messages
</div>
</div>
メッセージバーシートレイアウト
たとえば、メッセージに添付できる画像などの追加のシートが必要な場合は、このために設計された追加のブロックを使用します。
<div class="messagebar-sheet">
<!-- selectable sheet image -->
<label class="checkbox messagebar-sheet-image" style="background-image:url(path/to/image1.png)">
<input type="checkbox" />
<i class="icon icon-checkbox"></i>
</label>
<!-- another selectable sheet image -->
<label class="checkbox messagebar-sheet-image" style="background-image:url(path/to/image2.png)">
<input type="checkbox" />
<i class="icon icon-checkbox"></i>
</label>
<!-- some custom sheet item -->
<div class="messagebar-sheet-item">
<!-- any custom content here -->
</div>
</div>
メッセージバー添付ファイルレイアウト
メッセージの添付ファイルブロックは、現在添付されているメッセージアイテム/画像を表示するために設計されています。
<div class="messagebar-attachments">
<!-- image attachment -->
<div class="messagebar-attachment">
<img src="path/to/image1.png" />
</div>
<!-- deletable image attachment -->
<div class="messagebar-attachment">
<img src="path/to/image2.png" />
<!-- attachment delete button -->
<span class="messagebar-attachment-delete"></span>
</div>
</div>
メッセージバーアプリメソッド
メッセージバーのHTMLができたので、初期化する必要があります。関連するアプリのメソッドを使用する必要があります。
app.messagebar.create(パラメーター) | パラメーターを使用してメッセージバーを初期化します。
|
app.messagebar.destroy(el) | メッセージバーインスタンスを破棄します。
|
app.messagebar.get(el) | HTML要素からメッセージバーインスタンスを取得します。
|
メッセージバーパラメーター
利用可能なすべてのパラメーターのリストを見てみましょう。
パラメーター | 型 | デフォルト | 説明 |
---|---|---|---|
el | 文字列 HTMLElement | メッセージバー要素のCSSセレクターまたはHTML要素(div class="messagebar" ) | |
textareaEl | 文字列 HTMLElement | メッセージバーテキストエリア要素のCSSセレクターまたはHTML要素。デフォルトでは(渡されていない場合)、メッセージバー内のtextarea を探します。 | |
maxHeight | 数値 | null | テキストの量に応じてサイズ変更されたときのテキストエリアの最大高さ。 |
attachments | 配列 | [] | 添付ファイルを含む配列。たとえば、['path/to/image1.png', 'path/to/image2.png'] |
resizePage | ブール値 | true | メッセージバーテキストエリアのサイズが変更されたときにメッセージページのサイズを変更したくない場合は、無効にします。 |
on | オブジェクト | イベントハンドラーを含むオブジェクト。たとえば
| |
レンダリング関数 | |||
renderAttachments | function(attachments) | 添付ファイルブロックをレンダリングする関数。完全な添付ファイルHTML文字列を返す必要があります。 | |
renderAttachment | function(attachment) | 単一の添付ファイルをレンダリングする関数。完全な添付ファイルHTML文字列を返す必要があります。 |
メッセージバーメソッドとプロパティ
メッセージバーを作成するには、以下を呼び出します。
var messagebar = app.messagebar.create({ /* parameters */ })
メッセージバーを初期化すると、便利なメソッドとプロパティを持つ初期化されたインスタンスが変数(上記の例ではmessagebar
変数など)に格納されます。
プロパティ | |
---|---|
messagebar.el | メッセージバーHTML要素。 |
messagebar.$el | メッセージバーHTML要素を含むDom7要素。 |
messagebar.textareaEl | メッセージバーテキストエリアHTML要素。 |
messagebar.$textareaEl | メッセージバーテキストエリアHTML要素を含むDom7要素。 |
messagebar.params | 渡された初期化パラメーターを含むオブジェクト。 |
messagebar.attachments | メッセージバー添付ファイルを含む配列。 |
メソッド | |
messagebar.getValue(); | メッセージバーテキストエリアの値を取得します。 |
messagebar.setValue(value); | メッセージバーテキストエリアの値/テキストを設定します。 |
messagebar.clear(); | テキストエリアをクリアし、サイズを更新/リセットします。 |
messagebar.focus(); | メッセージバーテキストエリアにフォーカスします。 |
messagebar.blur(); | メッセージバーテキストエリアからフォーカスを削除します。 |
messagebar.setPlaceholder(placeholder) | メッセージバーのプレースホルダーテキストを設定/変更します。 |
messagebar.resizePage() | メッセージバーの高さ/サイズに応じてメッセージページのサイズ変更を強制します。 |
messagebar.attachmentsCreate() | 添付ファイルブロックHTML要素を動的に作成します。 |
messagebar.attachmentsShow() | 添付ファイルブロックを表示します。 |
messagebar.attachmentsHide() | 添付ファイルブロックを非表示にします。 |
messagebar.attachmentsToggle() | 添付ファイルブロックを切り替えます。 |
messagebar.renderAttachments() | 添付データに基づいて添付ファイルブロックをレンダリングします。 |
messagebar.sheetCreate() | メッセージバーシートブロックHTML要素を動的に作成します。 |
messagebar.sheetShow() | メッセージバーシートを表示します。 |
messagebar.sheetHide() | メッセージバーシートを非表示にします。 |
messagebar.sheetToggle() | メッセージバーシートを切り替えます。 |
messagebar.destroy(); | メッセージバーインスタンスを破棄します。 |
メッセージバーイベント
メッセージバーは、メッセージバー要素で次のDOMイベントを、アプリとメッセージバーインスタンスでイベントを発生させます。
DOMイベント
イベント | ターゲット | 説明 |
---|---|---|
messagebar:change | メッセージバー要素<div class="messagebar"> | メッセージバーテキストエリアの値が変更された後にトリガーされます。 |
messagebar:focus | メッセージバー要素<div class="messagebar"> | メッセージバーテキストエリアがフォーカスを取得したときにトリガーされます。 |
messagebar:blur | メッセージバー要素<div class="messagebar"> | メッセージバーテキストエリアがフォーカスを失ったときにトリガーされます。 |
messagebar:resizepage | メッセージバー要素<div class="messagebar"> | メッセージバーがメッセージページのサイズを変更したときにトリガーされます。 |
messagebar:attachmentdelete | メッセージバー添付ファイル要素<div class="messagebar-attachment"> | メッセージバー添付ファイルの削除ボタンをクリックした後にトリガーされます。 |
messagebar:attachmentclick | メッセージバー添付ファイル要素<div class="messagebar-attachment"> | メッセージバー添付ファイルをクリックしたときにトリガーされます。 |
messagebar:beforedestroy | メッセージバー要素<div class="messagebar"> | メッセージバーインスタンスが破棄される直前にトリガーされます。 |
アプリとメッセージバーインスタンスイベント
メッセージバーインスタンスは、自分自身とアプリの両方のインスタンスでイベントを発生させます。アプリインスタンスイベントは、messagebar
というプレフィックスが付いた同じ名前を持ちます。
イベント | ターゲット | 引数 | 説明 |
---|---|---|---|
change | messagebar | (messagebar) | メッセージバーテキストエリアの値が変更された後にトリガーされます。引数として、イベントハンドラーはメッセージバーインスタンスを受け取ります。 |
messagebarChange | app | ||
focus | messagebar | (messagebar) | メッセージバーテキストエリアがフォーカスを取得したときにトリガーされます。引数として、イベントハンドラーはメッセージバーインスタンスを受け取ります。 |
messagebarFocus | app | ||
blur | messagebar | (messagebar) | メッセージバーテキストエリアがフォーカスを失ったときにトリガーされます。引数として、イベントハンドラーはメッセージバーインスタンスを受け取ります。 |
messagebarBlur | app | ||
resizePage | messagebar | (messagebar) | メッセージバーがメッセージページのサイズを変更したときにトリガーされます。引数として、イベントハンドラーはメッセージバーインスタンスを受け取ります。 |
messagebarResizePage | app | ||
attachmentDelete | messagebar | (messagebar, attachmentEl, attachmentIndex) | メッセージバー添付ファイルの削除ボタンをクリックした後にトリガーされます。引数として、イベントハンドラーはメッセージバーインスタンス、クリックされた添付ファイルHTML要素、および添付ファイルのインデックス番号を受け取ります。 |
messagebarAttachmentDelete | app | ||
attachmentClick | messagebar | (messagebar, attachmentEl, attachmentIndex) | メッセージバー添付ファイルをクリックしたときにトリガーされます。引数として、イベントハンドラーはメッセージバーインスタンス、クリックされた添付ファイルHTML要素、および添付ファイルのインデックス番号を受け取ります。 |
messagebarAttachmentClick | app | ||
beforeDestroy | messagebar | (messagebar) | メッセージバーインスタンスが破棄される直前にトリガーされます。 |
messagebarBeforeDestroy | app |
メッセージバーの自動初期化
メッセージバーAPIを使用する必要がなく、ページ内にあり、ページの初期化時にDOMに表示されている場合は、メッセージバー要素に追加のmessagebar-init
クラスを追加するだけで自動的に初期化でき、必要なパラメーターはすべてdata-
属性を使用して渡すことができます。
<div class="toolbar messagebar messagebar-init" data-max-height="200">
<div class="toolbar-inner">
<div class="messagebar-area">
<textarea placeholder="Message"></textarea>
</div>
<a href="#" class="link">Send</a>
</div>
</div>
キャメルケースで使用されるパラメーター(たとえばmaxHeight)は、data-
属性ではケバブケース(data-max-height)として使用する必要があります。
CSS変数
関連するCSS変数(CSSカスタムプロパティ)のリストを以下に示します。
コメント付きの変数はデフォルトでは指定されておらず、その値はこの場合のフォールバックです。
:root {
--f7-messagebar-attachments-height: 155px;
--f7-messagebar-sheet-height: 252px;
--f7-messagebar-sheet-landscape-height: 192px;
/*
--f7-messagebar-inner-padding-left: var(--f7-toolbar-inner-padding-left);
--f7-messagebar-inner-padding-right: var(--f7-toolbar-inner-padding-right);
*/
}
.ios {
--f7-messagebar-height: 44px;
--f7-messagebar-font-size: 17px;
--f7-messagebar-textarea-bg-color: transparent;
/*
--f7-messagebar-link-color: var(--f7-theme-color);
*/
--f7-messagebar-border-color: transparent;
--f7-messagebar-textarea-border-radius: 17px;
--f7-messagebar-textarea-padding: 6px 16px;
--f7-messagebar-textarea-height: 34px;
--f7-messagebar-textarea-font-size: 17px;
--f7-messagebar-textarea-line-height: 20px;
--f7-messagebar-sheet-bg-color: #d1d5da;
--f7-messagebar-sheet-border-color: transparent;
--f7-messagebar-attachment-border-radius: 12px;
--f7-messagebar-attachment-height: 155px;
--f7-messagebar-attachment-landscape-height: 120px;
--f7-messagebar-textarea-placeholder-color: rgba(0, 0, 0, 0.4);
--f7-messagebar-textarea-text-color: #000;
--f7-messagebar-textarea-border: 1px solid #c8c8cd;
--f7-messagebar-attachments-border-color: #c8c8cd;
--f7-messagebar-bg-color: #fff;
--f7-messagebar-bg-color-rgb: 255, 255, 255;
}
.ios .dark,
.ios.dark {
--f7-messagebar-textarea-placeholder-color: rgba(255, 255, 255, 0.4);
--f7-messagebar-textarea-text-color: #fff;
--f7-messagebar-textarea-border: 1px solid var(--f7-bars-border-color);
--f7-messagebar-attachments-border-color: var(--f7-bars-border-color);
--f7-messagebar-bg-color: var(--f7-bars-bg-color);
--f7-messagebar-bg-color-rgb: var(--f7-bars-bg-color-rgb);
}
.md {
--f7-messagebar-height: 64px;
--f7-messagebar-font-size: 16px;
--f7-messagebar-textarea-border-radius: 24px;
--f7-messagebar-textarea-padding: 12px 16px;
--f7-messagebar-textarea-height: 48px;
--f7-messagebar-textarea-font-size: 16px;
--f7-messagebar-textarea-line-height: 22px;
--f7-messagebar-textarea-border: 1px solid transparent;
--f7-messagebar-attachment-border-radius: 12px;
--f7-messagebar-attachment-height: 72px;
--f7-messagebar-attachment-landscape-height: 72px;
--f7-messagebar-border-color: transparent;
--f7-messagebar-attachments-border-color: transparent;
}
.md,
.md .dark,
.md [class*='color-'] {
--f7-messagebar-textarea-placeholder-color: var(--f7-md-on-surface-variant);
--f7-messagebar-textarea-bg-color: var(--f7-md-surface-variant);
--f7-messagebar-bg-color: var(--f7-md-surface);
--f7-messagebar-textarea-text-color: var(--f7-md-on-surface);
--f7-messagebar-sheet-bg-color: var(--f7-md-surface);
--f7-messagebar-sheet-border-color: var(--f7-md-outline-variant);
--f7-messagebar-link-color: var(--f7-md-on-surface);
}
例
<template>
<div class="page">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner sliding">
<div class="title">Messages</div>
</div>
</div>
<div class="toolbar messagebar" @messagebar:attachmentdelete=${deleteAttachment}>
<div class="toolbar-inner">
<a class="link icon-only" @click=${sheetToggle}>
<i class="icon f7-icons if-not-md">camera_fill</i>
<i class="icon material-icons md-only">camera_alt</i>
</a>
<div class="messagebar-area">
<textarea class="resizable" placeholder="Message"></textarea>
</div>
<a class="link icon-only demo-send-message-link" @click=${sendMessage}>
<i class="icon f7-icons if-not-md">arrow_up_circle_fill</i>
<i class="icon material-icons md-only">send</i>
</a>
</div>
<div class="messagebar-sheet">
${images.map((image) => $h`
<label class="checkbox messagebar-sheet-image" @change=${handleAttachment}>
<input type="checkbox" />
<i class="icon icon-checkbox"></i>
<img src=${image} />
</label>
`)}
</div>
</div>
<div class="page-content messages-content">
<div class="messages">
<div class="messages-title"><b>Sunday, Feb 9,</b> 12:58</div>
<div class="message message-sent">
<div class="message-content">
<div class="message-bubble">
<div class="message-text">Hi, Kate</div>
</div>
</div>
</div>
<div class="message message-sent">
<div class="message-content">
<div class="message-bubble">
<div class="message-text">How are you?</div>
</div>
</div>
</div>
<div class="message message-received">
<div class="message-avatar"
style="background-image:url(https://cdn.framework7.io/placeholder/people-100x100-9.jpg)"></div>
<div class="message-content">
<div class="message-name">Kate</div>
<div class="message-bubble">
<div class="message-text">Hi, I am good!</div>
</div>
</div>
</div>
<div class="message message-received">
<div class="message-avatar"
style="background-image:url(https://cdn.framework7.io/placeholder/people-100x100-7.jpg)"></div>
<div class="message-content">
<div class="message-name">Blue Ninja</div>
<div class="message-bubble">
<div class="message-text">Hi there, I am also fine, thanks! And how are you?</div>
</div>
</div>
</div>
<div class="message message-sent">
<div class="message-content">
<div class="message-bubble">
<div class="message-text">Hey, Blue Ninja! Glad to see you ;)</div>
</div>
</div>
</div>
<div class="message message-sent">
<div class="message-content">
<div class="message-bubble">
<div class="message-text">Hey, look, cutest kitten ever!</div>
</div>
</div>
</div>
<div class="message message-sent">
<div class="message-content">
<div class="message-bubble">
<div class="message-image">
<img src="https://cdn.framework7.io/placeholder/cats-200x260-4.jpg"
style="width:200px; height: 260px" />
</div>
</div>
</div>
</div>
<div class="message message-received">
<div class="message-avatar"
style="background-image:url(https://cdn.framework7.io/placeholder/people-100x100-9.jpg)"></div>
<div class="message-content">
<div class="message-name">Kate</div>
<div class="message-bubble">
<div class="message-text">Nice!</div>
</div>
</div>
</div>
<div class="message message-received">
<div class="message-avatar"
style="background-image:url(https://cdn.framework7.io/placeholder/people-100x100-9.jpg)"></div>
<div class="message-content">
<div class="message-name">Kate</div>
<div class="message-bubble">
<div class="message-text">Like it very much!</div>
</div>
</div>
</div>
<div class="message message-received">
<div class="message-avatar"
style="background-image:url(https://cdn.framework7.io/placeholder/people-100x100-7.jpg)"></div>
<div class="message-content">
<div class="message-name">Blue Ninja</div>
<div class="message-bubble">
<div class="message-text">Awesome!</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default (props, { $f7, $el, $on, $ }) => {
const 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'
];
const 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'
},
];
const 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!!!',
];
let responseInProgress = false;
let messagebar;
let messages;
const sheetToggle = () => {
messagebar.sheetToggle();
}
const deleteAttachment = (e, index) => {
var image = messagebar.attachments.splice(index, 1)[0];
messagebar.renderAttachments();
checkAttachments();
// Uncheck in sheet
var imageIndex = images.indexOf(image);
$el.value.find('.messagebar-sheet .checkbox').eq(imageIndex).find('input').prop('checked', false);
}
const handleAttachment = (e) => {
var index = $(e.target).parents('label.checkbox').index();
var image = images[index];
if (e.target.checked) {
// Add to attachments
messagebar.attachments.unshift(image)
} else {
// Remove from attachments
messagebar.attachments.splice(messagebar.attachments.indexOf(image), 1);
}
messagebar.renderAttachments();
checkAttachments();
}
const checkAttachments = () => {
if (messagebar.attachments.length > 0) {
messagebar.attachmentsShow();
messagebar.setPlaceholder('Add comment or Send');
} else {
messagebar.attachmentsHide();
messagebar.setPlaceholder('Message');
}
}
const sendMessage = () => {
var text = messagebar.getValue().replace(/\n/g, '<br />').trim();
var messagesToSend = [];
messagebar.attachments.forEach(function (attachment) {
var size = attachment.split('placeholder/cats-')[1].split('-')[0].split('x');
messagesToSend.push({
image: '<img src="' + attachment + '" style="width: ' + (size[0] / 2) + 'px; height: ' + (size[1] / 2) + 'px">'
});
});
if (text.trim().length) {
messagesToSend.push({
text: text
});
}
// Reset attachments
messagebar.attachments = [];
checkAttachments();
// Hide sheet
messagebar.sheetHide();
// Uncheck selected images in sheet
messagebar.$sheetEl.find('input').prop('checked', false);
// Clear area
messagebar.clear();
// Focus area
if (text.length) messagebar.focus();
// Exit when nothing to send
if (!messagesToSend.length) return;
// Send message
messages.addMessages(messagesToSend);
// Mock response
if (responseInProgress) return;
responseInProgress = true;
setTimeout(function () {
var answer = answers[Math.floor(Math.random() * answers.length)];
var person = people[Math.floor(Math.random() * people.length)];
messages.showTyping({
header: person.name + ' is typing',
avatar: person.avatar
});
setTimeout(function () {
messages.addMessage({
text: answer,
type: 'received',
name: person.name,
avatar: person.avatar
});
messages.hideTyping();
responseInProgress = false;
}, 4000);
}, 1000);
}
$on('pageInit', () => {
messagebar = $f7.messagebar.create({
el: $el.value.find('.messagebar'),
attachments: []
});
messages = $f7.messages.create({
el: $el.value.find('.messages'),
firstMessageRule: function (message, previousMessage, nextMessage) {
if (message.isTitle) return false;
if (!previousMessage || previousMessage.type !== message.type || previousMessage.name !== message.name) return true;
return false;
},
lastMessageRule: function (message, previousMessage, nextMessage) {
if (message.isTitle) return false;
if (!nextMessage || nextMessage.type !== message.type || nextMessage.name !== message.name) return true;
return false;
},
tailMessageRule: function (message, previousMessage, nextMessage) {
if (message.isTitle) return false;
if (!nextMessage || nextMessage.type !== message.type || nextMessage.name !== message.name) return true;
return false;
}
});
})
$on('pageBeforeRemove', () => {
messagebar.destroy()
messages.destroy()
})
return $render;
};
</script>