レコード詳細画面のボタン押下でダイアログを表示し、レコードに紐づけてファイル登録を行う方法を2つ検証したので書いていきます。
①標準コンポーネントの File Upload を使用する
②標準コンポーネントの Input(タイプ "file")を使用する
①はアップロードから登録までを一括してくれるコンポーネントです。とりあえずファイルをしたいときはこれを使えば簡単です。
②はファイルアップロードのためのコンポーネントです。(Input自体はテキストや日時などの入力に使われます。)
読込・登録は別で処理を書く必要がありますが、ファイル名チェックなどの中間処理を入れることが可能です。
仕様
・商談のレコード詳細ページにファイル登録ボタンを配置する
・ボタン押下でファイル登録ダイアログを表示する
・ファイルをアップロードすると商談に紐づく形で登録し、ダイアログを閉じる
というような仕様は統一で
①はアップロードから登録まで連続。.txtと.xlsxの拡張子を許容し、ファイルの複数選択が可能。
②はアップロードと登録を分割。.pdfを許容し、複数選択が不可。ファイル名に「請求書」が含まれるかチェックする。
というようにしました。
下準備 AuraコンポーネントとApexクラスの新規作成
開発者コンソールでAuraコンポーネントを新規作成します。
File → New → Lightning Component
FileUploadAction1とFileUploadAction2を作成しました。
ついでにカスタムコントローラーも作成します。
File → New → Apex Class
FileUploadActionContollerを作成しました。
下準備 アクション作成と配置
Salesforce設定画面で商談レコード詳細ページにボタンを作成します。
オブジェクトマネージャー → 商談 → ボタン、リンク、およびアクション → 新規アクション
ファイル登録1とファイル登録2を作成しました。
Lightning コンポーネントには先ほど作成したFileUploadAction1とFileUploadAction2をそれぞれ設定します。
これだけでは画面に表示されないので注意です。
ページレイアウトに作成したアクションを配置して保存します。
これで下準備完了です。
レコード詳細ページにボタンが表示されました。
この状態ではまだ何も書いていない状態なので、ボタンを押しても空のダイアログが表示されるだけです。
それではコードを書いていきましょう!
①File Upload を使用する
ここで必要なのはAuraコンポーネントのコンポーネント部分とJavaScriptで書かれるコントローラ部分のみです。
<aura:component implements="force:lightningQuickActionWithoutHeader,force:hasRecordId">
<aura:attribute name="recordId" type="String"/>
<article class="slds-card">
<div class="slds-page-header" role="banner">
<h1 class="slds-page-header__title">ファイル登録1</h1>
</div>
<br/>
<lightning:fileUpload
label="請求書添付"
name="fileUploader"
multiple="true"
accept=".txt,.xlsx"
recordId="{!v.recordId}"
onuploadfinished="{!c.handleUploadFinished}" />
</article>
</aura:component>
lightning:fileUpload がアップロードも登録もしてくれる便利なやつです。
multipleでファイルの複数選択が可能か否かを定義します。
acceptは許容するファイルの拡張子を設定します。複数指定したいときはカンマ区切りで書きます。
({
handleUploadFinished: function (cmp, event) {
var uploadedFiles = event.getParam("files");
alert(uploadedFiles.length + "個のファイルを登録しました。");
$A.get("e.force:closeQuickAction").fire();
$A.get('e.force:refreshView').fire();
}
})
handleUploadFinishedはとりあえず入れとけなので入れています。
今回は登録件数を表示するようにしました。
【実際の動作】ダイアログ表示
【実際の動作】アップロード
【実際の動作】登録完了
②Input を使用する
これはちょっと増えます。
<aura:component implements="force:lightningQuickActionWithoutHeader,force:hasRecordId" controller="FileUploadActionContoller">
<aura:attribute name="recordId" type="String"/>
<aura:attribute name="hasFile" type="Boolean" default="false"/>
<aura:attribute name="fileMessage" type="String"/>
<aura:attribute name="file" type="Object"/>
<article class="slds-card">
<div class="slds-page-header" role="banner">
<h1 class="slds-page-header__title">ファイル登録2</h1>
</div>
<br/>
<aura:if isTrue="{!v.hasFile}">
<h2 class="slds-card__file-title name">{!v.fileMessage}</h2>
<ui:button class="slds-button slds-button--neutral" press="{!c.saveFile}" label="登録" />
<aura:set attribute="else">
<lightning:input name="file1" type="file" label="請求書添付" multiple="fales" accept=".pdf" onchange="{! c.handleFilesChange }"/>
<h2 class="slds-card__file-title error">{!v.fileMessage}</h2>
</aura:set>
</aura:if>
<br/>
<ui:button class="slds-button slds-button--neutral" press="{!c.cancel}" label="キャンセル" />
</article>
</aura:component>
controller="FileUploadActionContoller"でApexのコントローラを設定します。
fileはtype="Object"です。ここにアップロードしたファイルの情報が入ります。
({
saveFile : function(component, event, helper) {
helper.saveFile(component);
},
cancel : function(component, event, helper) {
$A.get("e.force:closeQuickAction").fire();
},
handleFilesChange : function (component, event, helper) {
helper.checkFileName(component,event);
}
})
ボタン・操作で呼ばれるファイル登録、キャンセル、ファイル変更のアクションです。
({
checkFileName: function(component, event) {
var files = event.getSource().get("v.files");
if(files[0].name.includes("請求書")) {
component.set("v.hasFile", true);
component.set("v.fileMessage", files[0].name);
component.set("v.file", files[0]);
}else{
component.set("v.hasFile", false);
component.set("v.fileMessage", "ファイル名が不正です: " + files[0].name );
}
},
saveFile: function(component) {
var recordId = component.get("v.recordId");
var file = component.get("v.file");
var reader = new FileReader();
reader.onload = function() {
var fileContent = reader.result;
var base64 = 'base64,';
var dataStart = fileContent.indexOf(base64) + base64.length;
fileContent = fileContent.substring(dataStart);
var action = component.get("c.insertContentVersion");
action.setParams({
recordId : recordId,
base64Data : encodeURIComponent(fileContent),
fileName : file.name
});
$A.enqueueAction(action);
}
reader.readAsDataURL(file);
$A.get("e.force:closeQuickAction").fire();
$A.get('e.force:refreshView').fire();
}
})
ヘルパーにより詳しい処理を書きます。
checkFileNameではファイル名に「請求書」が含まれるかチェックしています。
saveFileではファイル読み込みを行い、ApexのFileUploadActionContollerに処理を渡します。
.THIS .slds-card__file-title.name {
font-weight: normal;
font-size: x-large;
}
.THIS .slds-card__file-title.error {
font-weight: bold;
font-size: medium;
color: red;
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
いい感じに表示を整えます。
詳しくないので間違っていたら教えてください、、、
public class FileUploadActionContoller {
/**
* ファイルを登録する
*/
@AuraEnabled
public static void insertContentVersion(String recordId, String base64Data, String fileName){
base64Data = EncodingUtil.urlDecode(base64Data, 'UTF-8');
ContentVersion cv = new ContentVersion(
Title = fileName,
VersionData = EncodingUtil.base64Decode(base64Data),
PathOnClient = '/' + fileName,
FirstPublishLocationId = recordId
);
insert cv;
}
}
Auraコンポーネントで使用するメソッドには @AuraEnabled をつける必要があります。
【実際の動作】ダイアログ表示
【実際の動作】アップロードNG
【実際の動作】アップロードOK
参考