swad-core/swad_form.c

326 lines
11 KiB
C
Raw Normal View History

2018-11-09 20:48:17 +01:00
// 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.
2020-01-01 14:53:57 +01:00
Copyright (C) 1999-2020 Antonio Ca<EFBFBD>as Vargas
2018-11-09 20:48:17 +01:00
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 <http://www.gnu.org/licenses/>.
*/
/*****************************************************************************/
/*********************************** Headers *********************************/
/*****************************************************************************/
2019-04-20 21:11:44 +02:00
#define _GNU_SOURCE // For asprintf
#include <stdio.h> // For asprintf
2019-05-14 09:03:48 +02:00
#include <stdlib.h> // For free
2019-04-20 21:11:44 +02:00
2018-11-09 20:48:17 +01:00
#include "swad_form.h"
#include "swad_global.h"
2019-11-10 12:36:37 +01:00
#include "swad_HTML.h"
2018-11-09 20:48:17 +01:00
/*****************************************************************************/
/************** External global variables from others modules ****************/
/*****************************************************************************/
extern struct Globals Gbl;
/*****************************************************************************/
2019-11-21 16:47:07 +01:00
/************************* Private global variables **************************/
2018-11-09 20:48:17 +01:00
/*****************************************************************************/
/*****************************************************************************/
/**************************** Private prototypes *****************************/
/*****************************************************************************/
static void Frm_StartFormInternal (Act_Action_t NextAction,bool PutParameterLocationIfNoSesion,
const char *Id,const char *Anchor,const char *OnSubmit);
/*****************************************************************************/
/******************************** Start a form *******************************/
/*****************************************************************************/
void Frm_StartFormGoTo (Act_Action_t NextAction)
{
Gbl.Form.Num++; // Initialized to -1. The first time it is incremented, it will be equal to 0
snprintf (Gbl.Form.Id,sizeof (Gbl.Form.Id),
"form_%d",
Gbl.Form.Num);
Frm_StartFormInternal (NextAction,false,Gbl.Form.Id,NULL,NULL); // Do not put now parameter location
}
void Frm_StartForm (Act_Action_t NextAction)
{
Frm_StartFormAnchorOnSubmit (NextAction,NULL,NULL);
}
void Frm_StartFormAnchor (Act_Action_t NextAction,const char *Anchor)
{
Frm_StartFormAnchorOnSubmit (NextAction,Anchor,NULL);
}
void Frm_StartFormOnSubmit (Act_Action_t NextAction,const char *OnSubmit)
{
Frm_StartFormAnchorOnSubmit (NextAction,NULL,OnSubmit);
}
void Frm_StartFormAnchorOnSubmit (Act_Action_t NextAction,const char *Anchor,const char *OnSubmit)
{
Gbl.Form.Num++; // Initialized to -1. The first time it is incremented, it will be equal to 0
snprintf (Gbl.Form.Id,sizeof (Gbl.Form.Id),
"form_%d",
Gbl.Form.Num);
Frm_StartFormInternal (NextAction,true,Gbl.Form.Id,Anchor,OnSubmit); // Do put now parameter location (if no open session)
}
void Frm_StartFormUnique (Act_Action_t NextAction)
{
Frm_StartFormUniqueAnchor (NextAction,NULL);
}
void Frm_StartFormUniqueAnchor (Act_Action_t NextAction,const char *Anchor)
{
Gbl.Form.Num++; // Initialized to -1. The first time it is incremented, it will be equal to 0
snprintf (Gbl.Form.UniqueId,sizeof (Gbl.Form.UniqueId),
"form_%s_%d",
Gbl.UniqueNameEncrypted,Gbl.Form.Num);
Frm_StartFormInternal (NextAction,true,Gbl.Form.UniqueId,Anchor,NULL); // Do put now parameter location (if no open session)
2019-02-23 13:00:25 +01:00
}
void Frm_StartFormUniqueAnchorOnSubmit (Act_Action_t NextAction,const char *Anchor,const char *OnSubmit)
{
Gbl.Form.Num++; // Initialized to -1. The first time it is incremented, it will be equal to 0
snprintf (Gbl.Form.UniqueId,sizeof (Gbl.Form.UniqueId),
"form_%s_%d",
Gbl.UniqueNameEncrypted,Gbl.Form.Num);
Frm_StartFormInternal (NextAction,true,Gbl.Form.UniqueId,Anchor,OnSubmit); // Do put now parameter location (if no open session)
2018-11-09 20:48:17 +01:00
}
void Frm_StartFormId (Act_Action_t NextAction,const char *Id)
{
Gbl.Form.Num++; // Initialized to -1. The first time it is incremented, it will be equal to 0
Frm_StartFormInternal (NextAction,true,Id,NULL,NULL); // Do put now parameter location (if no open session)
}
// Id can not be NULL
static void Frm_StartFormInternal (Act_Action_t NextAction,bool PutParameterLocationIfNoSesion,
const char *Id,const char *Anchor,const char *OnSubmit)
{
2018-12-08 16:43:13 +01:00
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
2018-11-09 20:48:17 +01:00
char ParamsStr[Frm_MAX_BYTES_PARAMS_STR + 1];
if (!Gbl.Form.Inside)
{
2019-10-20 22:00:28 +02:00
/* Begin form */
2019-11-11 00:15:44 +01:00
HTM_TxtF ("<form method=\"post\" action=\"%s/%s",
Cfg_URL_SWAD_CGI,
Lan_STR_LANG_ID[Gbl.Prefs.Language]);
2018-11-09 20:48:17 +01:00
if (Anchor)
if (Anchor[0])
2019-11-11 00:15:44 +01:00
HTM_TxtF ("#%s",Anchor);
HTM_TxtF ("\" id=\"%s\"",Id);
2018-11-09 20:48:17 +01:00
if (OnSubmit)
if (OnSubmit[0])
2019-11-18 08:38:34 +01:00
HTM_TxtF (" onsubmit=\"%s\"",OnSubmit);
2018-11-09 20:48:17 +01:00
switch (Act_GetBrowserTab (NextAction))
{
case Act_BRW_NEW_TAB:
case Act_DOWNLD_FILE:
2019-11-11 00:15:44 +01:00
HTM_Txt (" target=\"_blank\"");
2018-11-09 20:48:17 +01:00
break;
default:
break;
}
if (Act_GetContentType (NextAction) == Act_CONT_DATA)
2019-11-11 00:15:44 +01:00
HTM_Txt (" enctype=\"multipart/form-data\"");
HTM_Txt (" accept-charset=\"windows-1252\">");
2018-11-09 20:48:17 +01:00
/* Put basic form parameters */
Frm_SetParamsForm (ParamsStr,NextAction,PutParameterLocationIfNoSesion);
2019-11-10 12:36:37 +01:00
HTM_Txt (ParamsStr);
2018-11-09 20:48:17 +01:00
Gbl.Form.Inside = true;
}
}
2020-05-11 02:28:38 +02:00
void Frm_StartFormNoAction (void)
{
if (!Gbl.Form.Inside)
{
/* Begin form */
HTM_Txt ("<form accept-charset=\"windows-1252\""
" onsubmit=\"return false;\">"); // Form that can not be submitted, to avoid enter key to send it
Gbl.Form.Inside = true;
}
}
2018-11-09 20:48:17 +01:00
void Frm_SetParamsForm (char ParamsStr[Frm_MAX_BYTES_PARAMS_STR + 1],Act_Action_t NextAction,
bool PutParameterLocationIfNoSesion)
{
char ParamAction[Frm_MAX_BYTES_PARAM_ACTION + 1];
char ParamSession[Frm_MAX_BYTES_PARAM_SESSION + 1];
char ParamLocation[Frm_MAX_BYTES_PARAM_LOCATION + 1];
ParamAction[0] = '\0';
ParamSession[0] = '\0';
ParamLocation[0] = '\0';
if (NextAction != ActUnk)
2019-02-24 21:45:46 +01:00
{
2018-11-09 20:48:17 +01:00
snprintf (ParamAction,sizeof (ParamAction),
"<input type=\"hidden\" name=\"act\" value=\"%ld\" />",
Act_GetActCod (NextAction));
2019-02-24 21:45:46 +01:00
if (Gbl.Session.Id[0])
snprintf (ParamSession,sizeof (ParamSession),
"<input type=\"hidden\" name=\"ses\" value=\"%s\" />",
Gbl.Session.Id);
else if (PutParameterLocationIfNoSesion)
// Extra parameters necessary when there's no open session
{
/* If session is open, course code will be get from session data,
but if there is not an open session, and next action is known,
it is necessary to send a parameter with course code */
2019-04-03 20:57:04 +02:00
switch (Gbl.Hierarchy.Level)
{
case Hie_CTY: // Country
snprintf (ParamLocation,sizeof (ParamLocation),
"<input type=\"hidden\" name=\"cty\" value=\"%ld\" />",
Gbl.Hierarchy.Cty.CtyCod);
break;
case Hie_INS: // Institution
snprintf (ParamLocation,sizeof (ParamLocation),
"<input type=\"hidden\" name=\"ins\" value=\"%ld\" />",
Gbl.Hierarchy.Ins.InsCod);
break;
case Hie_CTR: // Centre
snprintf (ParamLocation,sizeof (ParamLocation),
"<input type=\"hidden\" name=\"ctr\" value=\"%ld\" />",
Gbl.Hierarchy.Ctr.CtrCod);
break;
case Hie_DEG: // Degree
snprintf (ParamLocation,sizeof (ParamLocation),
"<input type=\"hidden\" name=\"deg\" value=\"%ld\" />",
Gbl.Hierarchy.Deg.DegCod);
break;
case Hie_CRS: // Course
snprintf (ParamLocation,sizeof (ParamLocation),
"<input type=\"hidden\" name=\"crs\" value=\"%ld\" />",
2019-04-04 10:45:15 +02:00
Gbl.Hierarchy.Crs.CrsCod);
2019-04-03 20:57:04 +02:00
break;
default:
break;
}
2019-02-24 21:45:46 +01:00
}
2018-11-09 20:48:17 +01:00
}
snprintf (ParamsStr,Frm_MAX_BYTES_PARAMS_STR + 1,
"%s%s%s",
ParamAction,ParamSession,ParamLocation);
}
void Frm_EndForm (void)
{
if (Gbl.Form.Inside)
{
2019-11-11 00:15:44 +01:00
HTM_Txt ("</form>");
2018-11-09 20:48:17 +01:00
Gbl.Form.Inside = false;
}
}
/*****************************************************************************/
/***************************** 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 (Gbl.UniqueNameEncrypted)
- a number for each element in this execution (CountForThisExecution) *****/
snprintf (UniqueId,Frm_MAX_BYTES_ID + 1,
"id_%s_%u",
Gbl.UniqueNameEncrypted,
++CountForThisExecution);
}
2019-04-20 21:11:44 +02:00
/*****************************************************************************/
/****************** Build/free anchor string given a code ********************/
/*****************************************************************************/
void Frm_SetAnchorStr (long Cod,char **Anchor)
{
if (Cod > 0)
{
if (asprintf (Anchor,"cod_%ld",
Cod) < 0)
Lay_NotEnoughMemoryExit ();
}
else
*Anchor = NULL;
}
void Frm_FreeAnchorStr (char *Anchor)
{
if (Anchor)
{
2019-11-06 19:45:20 +01:00
free (Anchor);
2019-04-20 21:11:44 +02:00
Anchor = NULL;
}
}
2019-12-26 22:29:04 +01:00
/*****************************************************************************/
/************************* Show label column in form *************************/
/*****************************************************************************/
2019-12-27 19:22:48 +01:00
// Id == NULL ==> label class = data
// Id[0] == '\0' ==> label class = form, no label for
// Id[0] != '\0' ==> label class = form, label for
2019-12-27 15:45:19 +01:00
void Frm_LabelColumn (const char *TDClass,const char *Id,const char *Label)
2019-12-26 22:29:04 +01:00
{
extern const char *The_ClassFormInBox[The_NUM_THEMES];
2019-12-27 15:45:19 +01:00
/***** Column/cell begin *****/
if (TDClass)
HTM_TD_Begin ("class=\"%s\"",TDClass);
else
HTM_TD_Begin (NULL);
/***** Label *****/
2019-12-26 22:29:04 +01:00
if (Id)
2019-12-27 19:22:48 +01:00
{
if (Id[0])
HTM_LABEL_Begin ("for=\"%s\" class=\"%s\"",
Id,The_ClassFormInBox[Gbl.Prefs.Theme]);
else
HTM_LABEL_Begin ("class=\"%s\"",
The_ClassFormInBox[Gbl.Prefs.Theme]);
}
2019-12-26 22:29:04 +01:00
else
2019-12-27 15:45:19 +01:00
HTM_LABEL_Begin ("class=\"DAT\"");
2019-12-26 22:29:04 +01:00
HTM_TxtF ("%s:",Label);
HTM_LABEL_End ();
2019-12-27 15:45:19 +01:00
/***** Column/cell end *****/
2019-12-26 22:29:04 +01:00
HTM_TD_End ();
}