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

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.

Classe do componente

TsgcHTMLComponent_NotificationPreferences (unit sgcHTML_Component_NotificationPreferences)

Renderiza

Uma tabela: uma linha por categoria, um checkbox por canal e um botão de salvar

Linguagens

Delphi, C++ Builder, .NET

Ofereça as categorias, carregue e salve os valores

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);

Principais propriedades & métodos

Os membros que você usa com mais frequência.

Categorias

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.

Canais

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

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.

Carregamento

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.

Salvando

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.

Formulários forjados

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.

Lendo um checkbox

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.

Aparência e ação

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.

Edições

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.

Componentes relacionados

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.

Continue explorando

Ajuda onlineReferência completa da API e guia de uso para este componente.
Todos os Componentes sgcHTMLExplore a matriz completa de recursos com mais de 80 componentes.
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.
PreçosLicenças Single, Team e Site com código-fonte completo.
Melhor custo-benefício: All-AccessTodos os produtos da eSeGeCe, com Suporte Premium incluído, a partir de €1,059/ano.
Ver preços do All-Access

Pronto para Começar?

Baixe a versão de avaliação gratuita e comece a construir UIs web em Delphi, C++ Builder e .NET.