NotificationPreferences

TsgcHTMLComponent_NotificationPreferences: una tabla con una fila por categoría y una casilla por canal (en la app, push, correo electrónico), en Delphi, C++ Builder y .NET. Tu aplicación carga y guarda los valores.

TsgcHTMLComponent_NotificationPreferences

La biblioteca no almacena nada. OnLoadPreferences pide a tu aplicación los valores de un usuario, OnSavePreferences le devuelve lo que el usuario marcó, y guardarlo es cosa tuya. Los valores son pares name=value con 1 o 0, y todos los pares ofrecidos están siempre presentes. Funciona en todas las ediciones.

Clase del componente

TsgcHTMLComponent_NotificationPreferences (unidad sgcHTML_Component_NotificationPreferences)

Genera

Una tabla: una fila por categoría, una casilla por canal y un botón de guardar

Lenguajes

Delphi, C++ Builder, .NET

Ofrece las categorías, carga y guarda los valores

Añade un elemento a Categories por cada cosa de la que se pueda avisar a un usuario, responde a OnLoadPreferences desde tu propio almacenamiento, guarda lo que llegue en OnSavePreferences, y enruta el formulario recibido a ProcessAction con el usuario tomado de la sesión.

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

Propiedades y métodos clave

Los miembros que usarás con más frecuencia.

Categorías

Categories es una colección TsgcHTMLPreferenceCategories; cada TsgcHTMLPreferenceCategory tiene un Name, la clave estable que se usa en los valores y como nombre de la casilla, y un Caption, que es lo que lee el usuario y se escapa al renderizarse. Un Caption vacío toma el valor de Name, y una categoría con un Name vacío se omite. IndexOfName localiza una.

Canales

Channels elige cuáles de ncInApp, ncPush y ncEmail tienen una columna, los tres por defecto. Los nombres de los canales se comparten con TsgcHTMLComponent_Notification, que los pide a tu aplicación en OnGetChannel antes de entregar nada.

Los valores

Los valores son pares name=value, uno por cada categoría y canal ofrecidos: orders.inapp=1, orders.push=0, orders.email=1. La clave es el Name de la categoría, un punto y la clave del canal inapp, push o email. Un valor es 1 cuando el canal está activado y 0 cuando está desactivado. ValueKey(aCategory, aChannel) construye la clave.

Carga

LoadPreferences(aUserID) vacía Values y dispara OnLoadPreferences(aUserID, aValues): rellena aValues con las líneas category.channel=1 de ese usuario. Values es una vista de solo lectura de lo que se renderiza, o de lo que se guardó por última vez. Un par que omitas se muestra sin marcar.

Guardado

OnSavePreferences(aUserID, aValues) recibe todos los pares ofrecidos con su nuevo valor, así que tu aplicación nunca tiene que adivinar qué significaba una clave ausente. SavePreferences(aUserID, aPosted) toma el formulario tal como llegó, donde solo están presentes las casillas marcadas, y ProcessAction(aUserID, aAction, aPosted) lo enruta, devolviendo False cuando la acción no es prefsSave.

Formularios falsificados

El formulario guardado viaja como datos enviados por el cliente, así que no se escribe ningún id de usuario en el marcado, y se ignora todo lo que nombre una categoría o un canal que el componente no ofrece. Un formulario falsificado no puede ampliar el conjunto de preferencias. El componente no aplica ninguna autorización: toma el usuario que actúa de la sesión de la petición (sgcHTMLRequestSession), nunca del formulario.

Leer una casilla

IsChecked(aCategory, aChannel) indica si un par está activado, SetChecked(aCategory, aChannel, aValue) escribe 1 o 0 en Values, y IsOffered(aCategory, aChannel) es True cuando la categoría existe y el canal tiene una columna.

Aspecto y acción

PreferencesID es el id del elemento raíz y el valor enviado en el campo prefs, de modo que una página con varias tablas sabe cuál respondió. Title, SaveCaption y EmptyText establecen los textos, y ShowSave (activado por defecto) muestra el botón. El formulario envía prefsSave como un formulario data-sgc-ws-send, con un campo category.channel establecido a 1 por cada casilla marcada.

Ediciones

La unidad se compila cuando SGC_HTML está definido, algo que sgcVer.inc no hace para Android e iOS. Funciona en todas las ediciones, y sgcHTML es un pack autónomo, que se vende de forma independiente de sgcWebSockets. La casilla de push solo registra una elección: entregar un push necesita WebPush, que está disponible solo en las ediciones Enterprise y All-Access.

Componentes relacionados

Las notificaciones en sí las muestra NotificationInbox, y Notification decide si se avisa a un usuario en la página o mediante un push.

Sigue explorando

Ayuda en líneaReferencia completa de la API y guía de uso para este componente.
Todos los componentes de sgcHTMLExplora la matriz completa de más de 80 componentes.
Descargar prueba gratuitaLa prueba de 30 días incluye los proyectos de demostración 60.HTML, entre ellos 17.FieldService, que usa la tabla de preferencias.
PreciosLicencias Single, Team y Site con código fuente completo.
La mejor opción: All-AccessTodos los productos de eSeGeCe, con Premium Support incluido, desde €1,059 al año.
Ver precios de All-Access

¿Listo para empezar?

Descarga la prueba gratuita y empieza a crear interfaces web en Delphi, C++ Builder y .NET.