LightningコンポーネントのondragstartイベントがFirefoxでなぜ動かないの?

簡単なグリッド内DragAndDropLightningコンポーネントを作ってみましたが すべてのブラウザーで検証してみましたがなぜFirefoxだけ動かないか原因&対策方法 を見つけた。

  1. コンポーネントのイメージ

  1. ソースコード
  • コンポーネントのソース
<aura:component>
    <aura:attribute name="values"
    type="String[]"
    access="private" />
<aura:attribute name="dragid"
    type="Integer"
    access="private" />
<aura:handler name="init"
  value="{!this}"
  action="{!c.doInit}" />
<div class="droparea" 
ondragover="{!c.cancel}" 
ondragenter="{!c.cancel}"
ondrop="{!c.drop}">
<aura:iteration items="{!v.values}"
        indexVar="index"
        var="value">
<div class="row" 
 draggable="true"
 ondragstart="{!c.dragstart}"
 data-drag-id="{!index}">
{!value}
</div>
</aura:iteration>
</div>
</aura:component>
  • コントローラーのソース
({
    doInit: function(component, event, helper) {
        var values = "f u r u C R M".split(' ');
        component.set("v.values", values);
    },
    dragstart: function(component, event, helper) {
        component.set("v.dragid", event.target.dataset.dragId);

    },
    drop: function(component, event, helper) {
        var dragId = component.get("v.dragid"),
            values = component.get("v.values"),
            temp;
        temp = values[dragId];
        values[dragId] = values[event.target.dataset.dragId];
        values[event.target.dataset.dragId] = temp;
        component.set("v.values", values);
        event.preventDefault();
    },
    cancel: function(component, event, helper) {
        event.preventDefault();
    }
})
  • CSS
.THIS.droparea{
    border: 1px solid black;
    position: relative;
    margin: 3px;
}
.THIS.droparea .row {
    position: relative;
    border: 1px solid red;
    padding: 3px;
    margin: 3px;
}
  • コンポーネントを呼び出すアプリ
<aura:application>
    <c:cmpDragDropRowSample />
</aura:application>

Firefoxで確認してみるとドラグイベントが起こらないみたいです。 javascriptをデバッグしたところで確かにコントローラーにあるdragstart関数に ジャンプインされていないようです。 事象を解決するために以下の記事を参考しました。

http://mereskin.github.io/dnd/

主に以下の文書をごらんください。

Making element draggable

To make an element draggable set draggable attribute to "true". However this is not enough to make elements draggable in Firefox. You need to locate the dragstart event and set some data on the DataTransfer object:

draggableElement.addEventListener('dragstart', function(e){ e.dataTransfer.setData('text', 'foo'); });

ということはdragstart関数に以下のコードラインを入れないと解決できないみたい

event.dataTransfer.setData('Text', component.id);

最終的にdragstart関数の中身は以下となります。

dragstart: function(component, event, helper) {
        component.set("v.dragid", event.target.dataset.dragId);
        event.dataTransfer.setData('Text', component.id);
    }

Firefoxで再度確認するとうまく動けるようになるぞう。

Happy coding

Posted in Apex, Lightning Components, Salesforce on Apr 16, 2019