はじめに
Power Apps
ではNotify 関数という、バナーメッセージを表示する関数があります。
コチラを使うことで、メッセージの種類に応じて、色とアイコンが使用されたメッセージの表示ができます。
これ小さすぎない?
Notify 関数の弱点として、メッセージが小さいです。
実際の画面を見てみると、ほとんど見えない。特にPCでアプリケーションを使っている際には、ユーザーはポップアップに慣れている感覚があるためか、私の実体験として不評です。
画面上部に表示されているバナーがNotify 関数による表示です。
タイムアウトを指定し、フェードアウトをさせられる便利な機能です。
ブラウザで起動させたパターンですが、黄色警告のバナーのサイズもかなり小さい。
表示されているんだから見てください、というストロングスタイルもありますが、決してユーザー満足度が高くなるとは言い難いのではないでしょうか。
HTML文字列でNotifyを作る
対処方法として、HTML文字列で代替となる通知を自作する方法があります。
画面の最前面にHTML 文字列
を用意し、下記の要素を入れてみるとしましょう。
ℹ️ information
ボタンコントロールで、HTML文字列を定義し、表示させます。
下記はinforomation
のバージョンです。
アイコンは絵文字で代用しています。
UpdateContext(
{
ShowNotification: {
type: "information",
message: "Thanks for trying this!",
html: "<div style='
background-color: #ebf5ff;
color: #1e429f;
padding: 12px;
border-radius: 6px;
border: 1px solid #c3dafe;
text-align: center;
position: relative;
font-size: 18px;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
animation: fadeOut 3s linear forwards;
'>
ℹ️ Thanks for trying this!
</div>"
}
}
);
UpdateContext({locNotifyVisible: true});
⚠️ warning
共通化する箇所はApp.Formulas
で定義することが可能です。
UpdateContext(
{
ShowNotification: {
type: "warning",
message: "Please check your input!",
html: "<div style='
background-color: #fff3cd;
color: #856404;
padding: 12px;
border-radius: 6px;
border: 1px solid #ffeeba;
text-align: center;
position: relative;
font-size: 18px;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
animation: fadeOut 3s linear forwards;
'>
⚠️ Please check your input!
</div>"
}
}
);
UpdateContext({locNotifyVisible: true});
✅ success
locNotifyVisible
によって、パーツの表示・非表示をコントロールします。
UpdateContext(
{
ShowNotification: {
type: "success",
message: "Operation completed successfully!",
html: "<div style='
background-color: #d4edda;
color: #155724;
padding: 12px;
border-radius: 6px;
border: 1px solid #c3e6cb;
text-align: center;
position: relative;
font-size: 18px;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
animation: fadeOut 3s linear forwards;
'>
✅ Operation completed successfully!
</div>"
}
}
);
UpdateContext({locNotifyVisible: true});
❌ error
info
・warning
・success
・error
ほぼ共通です。
プレビュー段階のため避けていますが、再利用できる関数で作成できることが理想的ですね。
UpdateContext(
{
ShowNotification: {
type: "error",
message: "An error has occurred!",
html: "<div style='
background-color: #f8d7da;
color: #721c24;
padding: 12px;
border-radius: 6px;
border: 1px solid #f5c6cb;
text-align: center;
position: relative;
font-size: 18px;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
animation: fadeOut 3s linear forwards;
'>
❌ An error has occurred!
</div>"
}
}
);
UpdateContext({locNotifyVisible: true});
ポップアップを自作する
次にPopUp
をHTML
文字列で再現してみましょう。
Yes
・No
のハンドリングは発生しないあくまで一時的な通知として使う想定で作成します。
関連する要素が多くなるため、定型的な文字列は、App.Formulas
で設定してしまいます。
変動しない要素は、コチラで設定してしまうことがおススメです。
popupColors = {
info: {
primary: "#4A90E2",
icon: "ℹ️"
},
success: {
primary: "#28a745",
icon: "✅"
},
warning: {
primary: "#ffc107",
icon: "⚠️"
},
error: {
primary: "#dc3545",
icon: "❌"
},
overlay: "rgba(0, 0, 0, 0.5)",
white: "white",
text: "#333",
close: "#666"
};
popupSizes = {
width: "50vw",
maxWidth: "500px",
minWidth: "300px",
height: "200px",
accentWidth: "6px",
padding: "1.5rem",
borderRadius: "8px"
};
popupIcon = {
size: "18px",
fontSize: "12px"
};
ℹ️ information
ポップアップのイメージです。あくまでなんちゃってポップアップです。
UpdateContext(
{
currentPopup: Switch(
Self.Text,
"Info",
{
primary: popupColors.info.primary,
icon: popupColors.info.icon,
title: "確認",
content: "このアクションを実行してもよろしいですか?"
},
"Success",
{
primary: popupColors.success.primary,
icon: popupColors.success.icon,
title: "完了",
content: "アクションは正常に完了しました。"
},
"Warn",
{
primary: popupColors.warning.primary,
icon: popupColors.warning.icon,
title: "警告",
content: "このアクションは取り消せません。続行しますか?"
},
"Error",
{
primary: popupColors.error.primary,
icon: popupColors.error.icon,
title: "エラー",
content: "エラーが発生しました。もう一度お試しください。"
}
)
}
);
UpdateContext(
{
popupStyles: {
overlay:
$"position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: {popupColors.overlay}; display: flex; justify-content: center; align-items: center;",
container:
$"background-color: {popupColors.white}; padding: {popupSizes.padding}; border-radius: {popupSizes.borderRadius}; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); width: {popupSizes.width}; max-width: {popupSizes.maxWidth}; min-width: {popupSizes.minWidth}; height: {popupSizes.height}; position: relative; display: flex;",
accentLine:
$"position: absolute; left: 0; top: 0; width: {popupSizes.accentWidth}; height: 100%; background-color: {currentPopup.primary}; border-top-left-radius: {popupSizes.borderRadius}; border-bottom-left-radius: {popupSizes.borderRadius};",
contentWrapper:
$"flex-grow: 1; padding-left: 1rem; display: flex; flex-direction: column;",
header: $"margin-bottom: 1rem;",
title: $"font-size: 1.125rem; font-weight: 600; margin: 0; color: {popupColors.text}; display: flex; align-items: center; gap: 0.5rem;",
infoIcon: $"display: flex; align-items: center; justify-content: center; width: {popupIcon.size}; height: {popupIcon.size}; solid {currentPopup.primary}; border-radius: 50%; color: {currentPopup.primary}; font-size: {popupIcon.fontSize}; font-weight: bold; flex-shrink: 0;",
content: $"flex-grow: 1; display: flex; align-items: center; font-size: 0.975rem;",
buttonArea: $"display: flex; justify-content: flex-end; padding-top: 1rem;",
button:
$"padding: 0.5rem 2rem; border-radius: 4px; border: none; cursor: pointer; font-weight: 500; background-color: {currentPopup.primary}; color: {popupColors.white}; min-width: 100px;",
closeButton:
$"position: absolute; top: 1rem; right: 1rem; width: 24px; height: 24px; border: none; background: none; cursor: pointer; padding: 0; display: flex; align-items: center; justify-content: center;",
closeLine: $"position: absolute; width: 2px; height: 16px; background-color: {popupColors.close};"
},
popupTexts: {
title: currentPopup.title,
content: currentPopup.content,
button: "Yes",
close: "閉じる",
info: currentPopup.icon
}
}
);
UpdateContext({locPopupVisible: true});
ポップアップ
のOnSelect
にUpdateContext({locPopupVisible: true});
を設定して通知を消します。
つまりボタンでもどこでもクリックすれば通知が消えるという仕様です。
クリックされたコントロールによって操作をわけるためには、コンポーネントで自作する方法が挙げられます。
⚠️ warning
Switch(Self.Text・・・
は、ボタンコントロールのテキストInfo
・Success
・Warning
・Error
から設定する値を定義を分けています。
UpdateContext(
{
currentPopup: Switch(
Self.Text,
"Info",
{
primary: popupColors.info.primary,
icon: popupColors.info.icon,
title: "確認",
content: "このアクションを実行してもよろしいですか?"
},
"Success",
{
primary: popupColors.success.primary,
icon: popupColors.success.icon,
title: "完了",
content: "アクションは正常に完了しました。"
},
"Warning",
{
primary: popupColors.warning.primary,
icon: popupColors.warning.icon,
title: "警告",
content: "このアクションは取り消せません。続行しますか?"
},
"Error",
{
primary: popupColors.error.primary,
icon: popupColors.error.icon,
title: "エラー",
content: "エラーが発生しました。もう一度お試しください。"
}
)
}
);
UpdateContext(
{
popupStyles: {
overlay:
$"position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: {popupColors.overlay}; display: flex; justify-content: center; align-items: center;",
container:
$"background-color: {popupColors.white}; padding: {popupSizes.padding}; border-radius: {popupSizes.borderRadius}; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); width: {popupSizes.width}; max-width: {popupSizes.maxWidth}; min-width: {popupSizes.minWidth}; height: {popupSizes.height}; position: relative; display: flex;",
accentLine:
$"position: absolute; left: 0; top: 0; width: {popupSizes.accentWidth}; height: 100%; background-color: {currentPopup.primary}; border-top-left-radius: {popupSizes.borderRadius}; border-bottom-left-radius: {popupSizes.borderRadius};",
contentWrapper:
$"flex-grow: 1; padding-left: 1rem; display: flex; flex-direction: column;",
header: $"margin-bottom: 1rem;",
title: $"font-size: 1.125rem; font-weight: 600; margin: 0; color: {popupColors.text}; display: flex; align-items: center; gap: 0.5rem;",
infoIcon: $"display: flex; align-items: center; justify-content: center; width: {popupIcon.size}; height: {popupIcon.size}; solid {currentPopup.primary}; border-radius: 50%; color: {currentPopup.primary}; font-size: {popupIcon.fontSize}; font-weight: bold; flex-shrink: 0;",
content: $"flex-grow: 1; display: flex; align-items: center; font-size: 0.975rem;",
buttonArea: $"display: flex; justify-content: flex-end; padding-top: 1rem;",
button:
$"padding: 0.5rem 2rem; border-radius: 4px; border: none; cursor: pointer; font-weight: 500; background-color: {currentPopup.primary}; color: {popupColors.white}; min-width: 100px;",
closeButton:
$"position: absolute; top: 1rem; right: 1rem; width: 24px; height: 24px; border: none; background: none; cursor: pointer; padding: 0; display: flex; align-items: center; justify-content: center;",
closeLine: $"position: absolute; width: 2px; height: 16px; background-color: {popupColors.close};"
},
popupTexts: {
title: currentPopup.title,
content: currentPopup.content,
button: "Yes",
close: "閉じる",
info: currentPopup.icon
}
}
);
UpdateContext({locPopupVisible: true});
✅ success
UpdateContext(
{
currentPopup: Switch(
Self.Text,
"Info",
{
primary: popupColors.info.primary,
icon: popupColors.info.icon,
title: "確認",
content: "このアクションを実行してもよろしいですか?"
},
"Success",
{
primary: popupColors.success.primary,
icon: popupColors.success.icon,
title: "完了",
content: "アクションは正常に完了しました。"
},
"Warn",
{
primary: popupColors.warning.primary,
icon: popupColors.warning.icon,
title: "警告",
content: "このアクションは取り消せません。続行しますか?"
},
"Error",
{
primary: popupColors.error.primary,
icon: popupColors.error.icon,
title: "エラー",
content: "エラーが発生しました。もう一度お試しください。"
}
)
}
);
UpdateContext(
{
popupStyles: {
overlay:
$"position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: {popupColors.overlay}; display: flex; justify-content: center; align-items: center;",
container:
$"background-color: {popupColors.white}; padding: {popupSizes.padding}; border-radius: {popupSizes.borderRadius}; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); width: {popupSizes.width}; max-width: {popupSizes.maxWidth}; min-width: {popupSizes.minWidth}; height: {popupSizes.height}; position: relative; display: flex;",
accentLine:
$"position: absolute; left: 0; top: 0; width: {popupSizes.accentWidth}; height: 100%; background-color: {currentPopup.primary}; border-top-left-radius: {popupSizes.borderRadius}; border-bottom-left-radius: {popupSizes.borderRadius};",
contentWrapper:
$"flex-grow: 1; padding-left: 1rem; display: flex; flex-direction: column;",
header: $"margin-bottom: 1rem;",
title: $"font-size: 1.125rem; font-weight: 600; margin: 0; color: {popupColors.text}; display: flex; align-items: center; gap: 0.5rem;",
infoIcon: $"display: flex; align-items: center; justify-content: center; width: {popupIcon.size}; height: {popupIcon.size}; solid {currentPopup.primary}; border-radius: 50%; color: {currentPopup.primary}; font-size: {popupIcon.fontSize}; font-weight: bold; flex-shrink: 0;",
content: $"flex-grow: 1; display: flex; align-items: center; font-size: 0.975rem;",
buttonArea: $"display: flex; justify-content: flex-end; padding-top: 1rem;",
button:
$"padding: 0.5rem 2rem; border-radius: 4px; border: none; cursor: pointer; font-weight: 500; background-color: {currentPopup.primary}; color: {popupColors.white}; min-width: 100px;",
closeButton:
$"position: absolute; top: 1rem; right: 1rem; width: 24px; height: 24px; border: none; background: none; cursor: pointer; padding: 0; display: flex; align-items: center; justify-content: center;",
closeLine: $"position: absolute; width: 2px; height: 16px; background-color: {popupColors.close};"
},
popupTexts: {
title: currentPopup.title,
content: currentPopup.content,
button: "Yes",
close: "閉じる",
info: currentPopup.icon
}
}
);
UpdateContext({locPopupVisible: true});
❌ error
UpdateContext(
{
currentPopup: Switch(
Self.Text,
"Info",
{
primary: popupColors.info.primary,
icon: popupColors.info.icon,
title: "確認",
content: "このアクションを実行してもよろしいですか?"
},
"Success",
{
primary: popupColors.success.primary,
icon: popupColors.success.icon,
title: "完了",
content: "アクションは正常に完了しました。"
},
"Warn",
{
primary: popupColors.warning.primary,
icon: popupColors.warning.icon,
title: "警告",
content: "このアクションは取り消せません。続行しますか?"
},
"Error",
{
primary: popupColors.error.primary,
icon: popupColors.error.icon,
title: "エラー",
content: "エラーが発生しました。もう一度お試しください。"
}
)
}
);
UpdateContext(
{
popupStyles: {
overlay:
$"position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: {popupColors.overlay}; display: flex; justify-content: center; align-items: center;",
container:
$"background-color: {popupColors.white}; padding: {popupSizes.padding}; border-radius: {popupSizes.borderRadius}; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); width: {popupSizes.width}; max-width: {popupSizes.maxWidth}; min-width: {popupSizes.minWidth}; height: {popupSizes.height}; position: relative; display: flex;",
accentLine:
$"position: absolute; left: 0; top: 0; width: {popupSizes.accentWidth}; height: 100%; background-color: {currentPopup.primary}; border-top-left-radius: {popupSizes.borderRadius}; border-bottom-left-radius: {popupSizes.borderRadius};",
contentWrapper:
$"flex-grow: 1; padding-left: 1rem; display: flex; flex-direction: column;",
header: $"margin-bottom: 1rem;",
title: $"font-size: 1.125rem; font-weight: 600; margin: 0; color: {popupColors.text}; display: flex; align-items: center; gap: 0.5rem;",
infoIcon: $"display: flex; align-items: center; justify-content: center; width: {popupIcon.size}; height: {popupIcon.size}; solid {currentPopup.primary}; border-radius: 50%; color: {currentPopup.primary}; font-size: {popupIcon.fontSize}; font-weight: bold; flex-shrink: 0;",
content: $"flex-grow: 1; display: flex; align-items: center; font-size: 0.975rem;",
buttonArea: $"display: flex; justify-content: flex-end; padding-top: 1rem;",
button:
$"padding: 0.5rem 2rem; border-radius: 4px; border: none; cursor: pointer; font-weight: 500; background-color: {currentPopup.primary}; color: {popupColors.white}; min-width: 100px;",
closeButton:
$"position: absolute; top: 1rem; right: 1rem; width: 24px; height: 24px; border: none; background: none; cursor: pointer; padding: 0; display: flex; align-items: center; justify-content: center;",
closeLine: $"position: absolute; width: 2px; height: 16px; background-color: {popupColors.close};"
},
popupTexts: {
title: currentPopup.title,
content: currentPopup.content,
button: "Yes",
close: "閉じる",
info: currentPopup.icon
}
}
);
UpdateContext({locPopupVisible: true});
おわりに
より本格的なものを参照したい場合は下記のサイトがおススメです。
Power AppsのYAML ソースコードが参照できます。