NotificationPreferences
TsgcHTMLComponent_NotificationPreferences: uma tabela com uma linha por categoria e um checkbox por canal (no app, push, e-mail), em Delphi, C++ Builder e .NET. A sua aplicação carrega e salva os valores.
TsgcHTMLComponent_NotificationPreferences: uma tabela com uma linha por categoria e um checkbox por canal (no app, push, e-mail), em Delphi, C++ Builder e .NET. A sua aplicação carrega e salva os valores.
A biblioteca não guarda nada. OnLoadPreferences pede à sua aplicação os valores de um usuário, OnSavePreferences devolve o que o usuário marcou, e persistir isso é trabalho seu. Os valores são pares name=value com 1 ou 0, e todo par oferecido está sempre presente. Funciona em todas as edições.
TsgcHTMLComponent_NotificationPreferences (unit sgcHTML_Component_NotificationPreferences)
Uma tabela: uma linha por categoria, um checkbox por canal e um botão de salvar
Delphi, C++ Builder, .NET
Adicione um item a Categories para cada assunto sobre o qual um usuário pode ser avisado, responda OnLoadPreferences a partir do seu próprio armazenamento, persista o que chegar em OnSavePreferences e encaminhe o formulário enviado para ProcessAction com o usuário tirado da sessão.
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);
Os membros que você usa com mais frequência.
Categories é uma coleção TsgcHTMLPreferenceCategories; cada TsgcHTMLPreferenceCategory tem um Name, a chave estável usada nos valores e como nome do checkbox, e uma Caption, que é o que o usuário lê e é escapada ao ser renderizada. Uma Caption vazia recorre ao Name, e uma categoria com Name vazio é ignorada. IndexOfName encontra uma.
Channels escolhe quais entre ncInApp, ncPush e ncEmail ganham uma coluna, os três por padrão. Os nomes dos canais são compartilhados com TsgcHTMLComponent_Notification, que os pede à sua aplicação em OnGetChannel antes de entregar qualquer coisa.
Os valores são pares name=value, um por categoria e canal oferecidos: orders.inapp=1, orders.push=0, orders.email=1. A chave é o Name da categoria, um ponto e a chave do canal inapp, push ou email. Um valor é 1 quando o canal está ligado e 0 quando está desligado. ValueKey(aCategory, aChannel) monta a chave.
LoadPreferences(aUserID) limpa Values e dispara OnLoadPreferences(aUserID, aValues): preencha aValues com as linhas category.channel=1 desse usuário. Values é uma visão somente leitura do que está renderizado, ou do que foi salvo por último. Um par que você deixar de fora é exibido desmarcado.
OnSavePreferences(aUserID, aValues) recebe todo par oferecido com o seu novo valor, de modo que a sua aplicação nunca precisa adivinhar o que uma chave ausente significava. SavePreferences(aUserID, aPosted) recebe o formulário como chegou, onde só as caixas marcadas estão presentes, e ProcessAction(aUserID, aAction, aPosted) o encaminha, devolvendo False quando a ação não é prefsSave.
O formulário salvo viaja como dado enviado pelo cliente, então nenhum id de usuário é escrito no markup, e tudo o que nomeia uma categoria ou um canal que o componente não oferece é ignorado. Um formulário forjado não consegue ampliar o conjunto de preferências. O componente não impõe nenhuma autorização: obtenha o usuário que age a partir da sessão da requisição (sgcHTMLRequestSession), nunca do formulário.
IsChecked(aCategory, aChannel) informa se um par está ligado, SetChecked(aCategory, aChannel, aValue) grava 1 ou 0 em Values, e IsOffered(aCategory, aChannel) é True quando a categoria existe e o canal tem uma coluna.
PreferencesID é o id do elemento raiz e o valor enviado no campo prefs, de modo que uma página com várias tabelas sabe qual delas respondeu. Title, SaveCaption e EmptyText definem os textos, e ShowSave (ativado por padrão) mostra o botão. O formulário envia prefsSave como um formulário data-sgc-ws-send, com um campo category.channel definido como 1 por checkbox marcado.
A unit compila quando SGC_HTML está definido, o que o sgcVer.inc não faz para Android e iOS. Funciona em todas as edições, e o sgcHTML é um pacote autônomo, vendido de forma independente do sgcWebSockets. O checkbox de push apenas registra uma escolha: entregar um push exige o WebPush, que está disponível somente nas edições Enterprise e All-Access.
As notificações em si são exibidas pelo NotificationInbox, e o Notification decide se um usuário é avisado na página ou por um push.
| Ajuda onlineReferência completa da API e guia de uso para este componente. | Abrir | |
| Todos os Componentes sgcHTMLExplore a matriz completa de recursos com mais de 80 componentes. | Abrir | |
| Baixar Versão de Avaliação GratuitaA avaliação de 30 dias inclui os projetos de demonstração 60.HTML, entre eles o 17.FieldService, que usa a tabela de preferências. | Abrir | |
| PreçosLicenças Single, Team e Site com código-fonte completo. | Abrir |