メッセージバー

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>

場所

メッセージバーの位置は非常に重要です。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)メッセージバーインスタンスを破棄します。
  • el - HTMLElement または 文字列(CSSセレクター付き)または オブジェクト。破棄するメッセージバー要素またはメッセージバーインスタンス。
app.messagebar.get(el)HTML要素からメッセージバーインスタンスを取得します。
  • el - HTMLElement または 文字列(CSSセレクター付き)。メッセージバー要素。
  • メソッドはメッセージバーのインスタンスを返します。

メッセージバーパラメーター

利用可能なすべてのパラメーターのリストを見てみましょう。

パラメーターデフォルト説明
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オブジェクト

イベントハンドラーを含むオブジェクト。たとえば

var messagebar = app.messagebar.create({
  el: '.messagebar',
  on: {
    change: function () {
      console.log('Textarea value changed')
    }
  }
})
レンダリング関数
renderAttachmentsfunction(attachments)添付ファイルブロックをレンダリングする関数。完全な添付ファイルHTML文字列を返す必要があります。
renderAttachmentfunction(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というプレフィックスが付いた同じ名前を持ちます。

イベントターゲット引数説明
changemessagebar(messagebar)メッセージバーテキストエリアの値が変更された後にトリガーされます。引数として、イベントハンドラーはメッセージバーインスタンスを受け取ります。
messagebarChangeapp
focusmessagebar(messagebar)メッセージバーテキストエリアがフォーカスを取得したときにトリガーされます。引数として、イベントハンドラーはメッセージバーインスタンスを受け取ります。
messagebarFocusapp
blurmessagebar(messagebar)メッセージバーテキストエリアがフォーカスを失ったときにトリガーされます。引数として、イベントハンドラーはメッセージバーインスタンスを受け取ります。
messagebarBlurapp
resizePagemessagebar(messagebar)メッセージバーがメッセージページのサイズを変更したときにトリガーされます。引数として、イベントハンドラーはメッセージバーインスタンスを受け取ります。
messagebarResizePageapp
attachmentDeletemessagebar(messagebar, attachmentEl, attachmentIndex)メッセージバー添付ファイルの削除ボタンをクリックした後にトリガーされます。引数として、イベントハンドラーはメッセージバーインスタンス、クリックされた添付ファイルHTML要素、および添付ファイルのインデックス番号を受け取ります。
messagebarAttachmentDeleteapp
attachmentClickmessagebar(messagebar, attachmentEl, attachmentIndex)メッセージバー添付ファイルをクリックしたときにトリガーされます。引数として、イベントハンドラーはメッセージバーインスタンス、クリックされた添付ファイルHTML要素、および添付ファイルのインデックス番号を受け取ります。
messagebarAttachmentClickapp
beforeDestroymessagebar(messagebar)メッセージバーインスタンスが破棄される直前にトリガーされます。
messagebarBeforeDestroyapp

メッセージバーの自動初期化

メッセージバー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);
}

messages.html
<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>