// swad_form.c: forms to go to actions
/*
SWAD (Shared Workspace At a Distance),
is a web platform developed at the University of Granada (Spain),
and used to support university teaching.
This file is part of SWAD core.
Copyright (C) 1999-2024 Antonio Caņas Vargas
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
/*****************************************************************************/
/*********************************** Headers *********************************/
/*****************************************************************************/
#define _GNU_SOURCE // For asprintf
#include // For asprintf
#include // For free
#include "swad_action_list.h"
#include "swad_alert.h"
#include "swad_error.h"
#include "swad_form.h"
#include "swad_global.h"
#include "swad_hierarchy_type.h"
#include "swad_HTML.h"
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
/************************* Private global variables **************************/
/*****************************************************************************/
static bool Frm_Inside = false;
/*****************************************************************************/
/**************************** Private prototypes *****************************/
/*****************************************************************************/
static inline void Frm_SetInside (bool Inside);
static void Frm_BeginFormInternal (Act_Action_t NextAction,bool PutParLocationIfNoSesion,
const char *Id,const char *Anchor,const char *OnSubmit);
/*****************************************************************************/
/************** Set to true inside a form to avoid nested forms **************/
/*****************************************************************************/
static inline void Frm_SetInside (bool Inside)
{
Frm_Inside = Inside;
}
bool Frm_CheckIfInside (void)
{
return Frm_Inside;
}
/*****************************************************************************/
/******************************** Begin a form *******************************/
/*****************************************************************************/
void Frm_BeginFormGoTo (Act_Action_t NextAction)
{
Frm_BeginFormInternal (NextAction,false,NULL,NULL,NULL); // Do not put now parameter location
}
void Frm_BeginForm (Act_Action_t NextAction)
{
Frm_BeginFormInternal (NextAction,true,NULL,NULL,NULL); // Do put now parameter location (if no open session)
}
void Frm_BeginFormAnchor (Act_Action_t NextAction,const char *Anchor)
{
Frm_BeginFormInternal (NextAction,true,NULL,Anchor,NULL); // Do put now parameter location (if no open session)
}
void Frm_BeginFormOnSubmit (Act_Action_t NextAction,const char *OnSubmit)
{
Frm_BeginFormInternal (NextAction,true,NULL,NULL,OnSubmit); // Do put now parameter location (if no open session)
}
void Frm_BeginFormAnchorOnSubmit (Act_Action_t NextAction,const char *Anchor,const char *OnSubmit)
{
Frm_BeginFormInternal (NextAction,true,NULL,Anchor,OnSubmit);// Do put now parameter location (if no open session)
}
void Frm_BeginFormId (Act_Action_t NextAction,const char *Id)
{
Frm_BeginFormInternal (NextAction,true,Id,NULL,NULL); // Do put now parameter location (if no open session)
}
static void Frm_BeginFormInternal (Act_Action_t NextAction,bool PutParLocationIfNoSesion,
const char *Id,const char *Anchor,const char *OnSubmit)
{
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
char ParsStr[Frm_MAX_BYTES_PARAMS_STR + 1];
if (!Frm_CheckIfInside ())
{
/* Begin form */
HTM_TxtF ("");
Frm_SetInside (false);
}
}
/*****************************************************************************/
/********************** Put a form and a table to create *********************/
/*****************************************************************************/
void Frm_BeginFormTable (Act_Action_t NextAction,const char *Anchor,
void (*FuncPars) (void *Args),void *Args,
const char *ClassTable)
{
extern const char *Txt_Actions[ActLst_NUM_ACTIONS];
/***** Begin fieldset *****/
HTM_FIELDSET_Begin (NULL);
HTM_LEGEND (Txt_Actions[NextAction]);
/***** Begin form *****/
Frm_BeginFormAnchor (NextAction,Anchor);
if (FuncPars)
FuncPars (Args);
/***** Begin table *****/
HTM_TABLE_Begin (ClassTable);
}
void Frm_EndFormTable (Btn_Button_t Button)
{
extern const char *Txt_Create;
extern const char *Txt_Save_changes;
extern const char *Txt_Remove;
static const char **TxtButton[Btn_NUM_BUTTON_TYPES] =
{
[Btn_CREATE_BUTTON ] = &Txt_Create,
[Btn_CONFIRM_BUTTON] = &Txt_Save_changes,
[Btn_REMOVE_BUTTON ] = &Txt_Remove,
};
/***** End table *****/
HTM_TABLE_End ();
/***** Send button *****/
if (Button != Btn_NO_BUTTON)
Btn_PutButton (Button,*TxtButton[Button]);
/***** End form *****/
Frm_EndForm ();
/***** End fieldset *****/
HTM_FIELDSET_End ();
}
/*****************************************************************************/
/***************************** Get unique Id *********************************/
/*****************************************************************************/
void Frm_SetUniqueId (char UniqueId[Frm_MAX_BYTES_ID + 1])
{
static unsigned CountForThisExecution = 0;
/***** Create Id. The id must be unique,
the page content may be updated via AJAX.
So, Id uses:
- a name for this execution
- a number for each element in this execution *****/
snprintf (UniqueId,Frm_MAX_BYTES_ID + 1,"id_%s_%u",
Cry_GetUniqueNameEncrypted (),
++CountForThisExecution);
}
/*****************************************************************************/
/****************** Build/free anchor string given a code ********************/
/*****************************************************************************/
void Frm_SetAnchorStr (long Cod,char **Anchor)
{
if (Cod > 0)
{
if (asprintf (Anchor,"cod_%ld",
Cod) < 0)
Err_NotEnoughMemoryExit ();
}
else
*Anchor = NULL;
}
void Frm_FreeAnchorStr (char **Anchor)
{
if (*Anchor)
{
free (*Anchor);
*Anchor = NULL;
}
}
/*****************************************************************************/
/************************* Show label column in form *************************/
/*****************************************************************************/
// Id == NULL ==> label class = data
// Id[0] == '\0' ==> label class = form, no label for
// Id[0] != '\0' ==> label class = form, label for
void Frm_LabelColumn (const char *TDClass,const char *Id,const char *Label)
{
/***** Column/cell begin *****/
if (TDClass)
HTM_TD_Begin ("class=\"%s\"",TDClass);
else
HTM_TD_Begin (NULL);
/***** Label *****/
if (Id)
{
if (Id[0])
HTM_LABEL_Begin ("for=\"%s\" class=\"FORM_IN_%s\"",
Id,The_GetSuffix ());
else
HTM_LABEL_Begin ("class=\"FORM_IN_%s\"",
The_GetSuffix ());
}
else
HTM_LABEL_Begin ("class=\"DAT_%s\"",The_GetSuffix ());
HTM_TxtColon (Label);
HTM_LABEL_End ();
/***** Column/cell end *****/
HTM_TD_End ();
}