NotificationPreferences
TsgcHTMLComponent_NotificationPreferences: カテゴリごとに 1 行、チャネル(アプリ内、プッシュ、メール)ごとに 1 つのチェックボックスを持つテーブルを、Delphi、C++ Builder、.NET で提供します。値の読み込みと保存はアプリケーションが行います。
TsgcHTMLComponent_NotificationPreferences: カテゴリごとに 1 行、チャネル(アプリ内、プッシュ、メール)ごとに 1 つのチェックボックスを持つテーブルを、Delphi、C++ Builder、.NET で提供します。値の読み込みと保存はアプリケーションが行います。
ライブラリは何も保存しません。OnLoadPreferences は 1 人のユーザーの値をアプリケーションに問い合わせ、OnSavePreferences はユーザーがチェックした内容を返し、それを永続化するのはアプリケーションの役割です。値は name=value のペアで、値には 1 または 0 を使い、提示されるペアは常にすべて存在します。すべてのエディションで動作します。
TsgcHTMLComponent_NotificationPreferences(ユニット sgcHTML_Component_NotificationPreferences)
テーブル: カテゴリごとに 1 行、チャネルごとに 1 つのチェックボックス、保存ボタン
Delphi, C++ Builder, .NET
ユーザーに通知しうる項目ごとに Categories に 1 つ項目を追加し、OnLoadPreferences に独自のストレージから応答し、OnSavePreferences に届いた内容を永続化し、ポストされたフォームはセッションから取得したユーザーとともに ProcessAction に振り分けます。
uses
sgcHTML_Session, sgcHTML_Component_NotificationPreferences;
var
oPrefs: TsgcHTMLComponent_NotificationPreferences;
begin
oPrefs := TsgcHTMLComponent_NotificationPreferences.Create(nil);
try
oPrefs.PreferencesID := 'prefs';
oPrefs.Title := 'How you want to hear about it';
oPrefs.SaveCaption := 'Save preferences';
with oPrefs.Categories.Add do
begin
Name := 'orders';
Caption := 'A new order arrives';
end;
with oPrefs.Categories.Add do
begin
Name := 'billing';
Caption := 'A payment fails';
end;
oPrefs.OnLoadPreferences := PrefsLoad;
oPrefs.OnSavePreferences := PrefsSave;
// the user comes from the session, never from the form
oPrefs.LoadPreferences(sgcHTMLRequestSession.UserID);
Response := oPrefs.HTML; // one row per category, one checkbox per channel
finally
oPrefs.Free;
end;
end;
// the application owns the values: one category.channel=1 or =0 per pair
procedure TMain.PrefsLoad(Sender: TObject; const aUserID: string;
aValues: TStrings);
begin
aValues.Add('orders.inapp=1');
aValues.Add('orders.push=0');
aValues.Add('orders.email=1');
end;
procedure TMain.PrefsSave(Sender: TObject; const aUserID: string;
aValues: TStrings);
var
i: Integer;
begin
// every offered pair is here, with 1 or 0
for i := 0 to aValues.Count - 1 do
MyStore.Save(aUserID, aValues.Names[i], aValues.Values[aValues.Names[i]] = '1');
end;
// in the message handler that receives the form the table posts
if oPrefs.ProcessAction(vUser, vAction, vPostedFields) then
oHTMX.PushFragment(vGuid, oPrefs.HTML);
// includes: sgcHTML_Session.hpp, sgcHTML_Component_NotificationPreferences.hpp
TsgcHTMLComponent_NotificationPreferences *oPrefs = new TsgcHTMLComponent_NotificationPreferences(NULL);
try
{
oPrefs->PreferencesID = "prefs";
oPrefs->Title = "How you want to hear about it";
oPrefs->SaveCaption = "Save preferences";
TsgcHTMLPreferenceCategory *orders = oPrefs->Categories->Add();
orders->Name = "orders";
orders->Caption = "A new order arrives";
TsgcHTMLPreferenceCategory *billing = oPrefs->Categories->Add();
billing->Name = "billing";
billing->Caption = "A payment fails";
oPrefs->OnLoadPreferences = PrefsLoad;
oPrefs->OnSavePreferences = PrefsSave;
// the user comes from the session, never from the form
oPrefs->LoadPreferences(sgcHTMLRequestSession()->UserID);
String html = oPrefs->HTML; // one row per category, one checkbox per channel
}
__finally
{
delete oPrefs;
}
// the application owns the values: one category.channel=1 or =0 per pair
void __fastcall TMain::PrefsLoad(TObject *Sender, const String aUserID,
TStrings *aValues)
{
aValues->Add("orders.inapp=1");
aValues->Add("orders.push=0");
aValues->Add("orders.email=1");
}
void __fastcall TMain::PrefsSave(TObject *Sender, const String aUserID,
TStrings *aValues)
{
// every offered pair is here, with 1 or 0
for (int i = 0; i < aValues->Count; i++)
MyStore->Save(aUserID, aValues->Names[i], aValues->Values[aValues->Names[i]] == "1");
}
// in the message handler that receives the form the table posts
if (oPrefs->ProcessAction(vUser, vAction, vPostedFields))
oHTMX->PushFragment(vGuid, oPrefs->HTML);
using esegece.sgcWebSockets;
var prefs = new TsgcHTMLComponent_NotificationPreferences();
prefs.PreferencesID = "prefs";
prefs.Title = "How you want to hear about it";
prefs.SaveCaption = "Save preferences";
var orders = prefs.Categories.Add();
orders.Name = "orders";
orders.Caption = "A new order arrives";
var billing = prefs.Categories.Add();
billing.Name = "billing";
billing.Caption = "A payment fails";
prefs.OnLoadPreferences += PrefsLoad;
prefs.OnSavePreferences += PrefsSave;
// the user comes from the session, never from the form
string user = sgcHTMLSessionHelpers.sgcHTMLRequestSession()?.UserID ?? "";
prefs.LoadPreferences(user);
string html = prefs.HTML; // one row per category, one checkbox per channel
// the application owns the values: one category.channel=1 or =0 per pair
void PrefsLoad(object sender, string userID, List<string> values)
{
values.Add("orders.inapp=1");
values.Add("orders.push=0");
values.Add("orders.email=1");
}
void PrefsSave(object sender, string userID, List<string> values)
{
// every offered pair is here, with 1 or 0
foreach (var line in values)
{
int eq = line.IndexOf('=');
myStore.Save(userID, line.Substring(0, eq), line.Substring(eq + 1) == "1");
}
}
// in the message handler that receives the form the table posts
if (prefs.ProcessAction(user, action, postedFields))
htmx.PushFragment(guid, prefs.HTML);
最もよく使うメンバーです。
Categories は TsgcHTMLPreferenceCategories コレクションで、各 TsgcHTMLPreferenceCategory は、値の中で、またチェックボックスの名前として使われる安定したキーである Name と、ユーザーが読む文字列でレンダリング時にエスケープされる Caption を持ちます。Caption が空の場合は Name が使われ、Name が空のカテゴリはスキップされます。IndexOfName で 1 つを検索できます。
Channels は、ncInApp、ncPush、ncEmail のどれに列を設けるかを選択し、既定では 3 つすべてです。チャネル名は TsgcHTMLComponent_Notification と共有されており、こちらは通知を配信する前に OnGetChannel でアプリケーションに問い合わせます。
値は name=value のペアで、提示されるカテゴリとチャネルごとに 1 つあります: orders.inapp=1、orders.push=0、orders.email=1。キーは、カテゴリの Name、ドット、チャネルのキー inapp、push、email のいずれかです。値は、チャネルがオンなら 1、オフなら 0 です。ValueKey(aCategory, aChannel) がキーを組み立てます。
LoadPreferences(aUserID) は Values をクリアし、OnLoadPreferences(aUserID, aValues) を発生させます。aValues にそのユーザーの category.channel=1 の行を埋めてください。Values は、レンダリングされている内容、または最後に保存された内容の読み取り専用ビューです。省略したペアはチェックなしで表示されます。
OnSavePreferences(aUserID, aValues) は、提示されたすべてのペアを新しい値とともに受け取るため、キーがない場合の意味をアプリケーションが推測する必要はありません。SavePreferences(aUserID, aPosted) は届いたままのフォームを受け取り、チェックされたボックスだけが含まれます。ProcessAction(aUserID, aAction, aPosted) がこれを振り分けます。False を返すのは、アクションが prefsSave でない場合です。
保存されるフォームはクライアントから送られるデータとして届くため、マークアップにはユーザー ID を書き込みません。また、コンポーネントが提示していないカテゴリやチャネルを指定するものはすべて無視されます。偽造されたフォームでは、設定の範囲を広げることはできません。コンポーネントは認可を行いません。操作しているユーザーは、フォームではなくリクエストのセッション(sgcHTMLRequestSession)から取得してください。
IsChecked(aCategory, aChannel) はペアがオンかどうかを返し、SetChecked(aCategory, aChannel, aValue) は 1 または 0 を Values に書き込み、IsOffered(aCategory, aChannel) はカテゴリが存在し、チャネルに列がある場合に True です。
PreferencesID はルート要素の ID で、prefs フィールドにポストされる値でもあるため、複数のテーブルがあるページでもどのテーブルが応答したかが分かります。Title、SaveCaption、EmptyText でテキストを設定し、ShowSave(既定でオン)でボタンを表示します。フォームは prefsSave を data-sgc-ws-send フォームとしてポストし、チェックされたボックスごとに 1 つの category.channel フィールドを含み、その値は 1 です。
ユニットは SGC_HTML が定義されている場合にコンパイルされ、sgcVer.inc は Android と iOS についてはそれを定義しません。すべてのエディションで動作し、sgcHTML はスタンドアロンのパックで、sgcWebSockets とは別に販売されています。プッシュのチェックボックスは選択を記録するだけです。プッシュを配信するには WebPush が必要で、Enterprise および All-Access エディションでのみ利用できます。
通知そのものは NotificationInbox が表示し、ユーザーへの通知をページ内で行うかプッシュで行うかは Notification が決めます。