FSN#38299 Flexkenmerken via de API kunnen bewerken, savepoint bestanden upload/downloaden
Ook: fields parameter om de opgeleverde velden te beperken Ook: .tables format om de data in een prettig leesbaar formaat te tonen svn path=/Website/trunk/; revision=33260
This commit is contained in:
@@ -847,7 +847,7 @@ api2 = {
|
||||
else if (inckey in existing_includes)
|
||||
{
|
||||
__Log("Nu ga ik '{0}' {1} updaten".format(incname, inckey));
|
||||
incmodel.REST_PUT(params, incdata[j], inckey);
|
||||
incmodel.REST_PUT(params, incdata[j], inckey, the_key);
|
||||
existing_includes[inckey].found = true;
|
||||
}
|
||||
}
|
||||
@@ -1007,6 +1007,7 @@ api2 = {
|
||||
return timetable.join(";");
|
||||
},
|
||||
// Geef alle velden van een record terug
|
||||
// ?? Alleen bij includes in gebruik ??
|
||||
sql2jsonfields: function _sql2jsonfields(params, oRs, model)
|
||||
{
|
||||
var record = {};
|
||||
@@ -1114,6 +1115,8 @@ api2 = {
|
||||
var field = model.fields[fld];
|
||||
if (field.hidden)
|
||||
continue;
|
||||
if ("fields" in params.filter && !inArray(fld, params.filter.fields.split(",")))
|
||||
continue;
|
||||
|
||||
var val = api2.sql2jsonval(oRs, fld, model)
|
||||
//waarom was dit aanwezig?
|
||||
|
||||
@@ -264,7 +264,7 @@ api2_rest = {
|
||||
var result = model["REST_" + method]( requestparams, key );
|
||||
}
|
||||
else if (filter.mode == "attachment" && "custom_fields" in model.includes)
|
||||
{ // https://xxxx.facilitor.nl/trunk/api2/visitors/99685/attachments/1040/testfile.jpg"
|
||||
{ // GET/PUT/POST https://xxxx.facilitor.nl/trunk/api2/visitors/99685/attachments/1040/testfile.jpg"
|
||||
if (wasCodePage != 65001)
|
||||
{
|
||||
// Door de IIS rewriter is de filenaam in de url utf-8 encoded
|
||||
@@ -385,7 +385,7 @@ api2_rest = {
|
||||
Response.End;
|
||||
}
|
||||
|
||||
if (format == "html" || format == "json")
|
||||
if (format == "html" || format == "json" || format == "table")
|
||||
{
|
||||
var result = { };
|
||||
if (single)
|
||||
@@ -500,6 +500,20 @@ api2_rest = {
|
||||
+ Server.HTMLEncode(antwoord)
|
||||
+ "</pre></body></html>";
|
||||
break;
|
||||
case "table":
|
||||
Response.ContentType = "text/html";
|
||||
var antwoord = api2_rest.json2htmltable(resultdata[model.records_name], model);
|
||||
var str_antwoord = "<!DOCTYPE html>"
|
||||
+ "<html>"
|
||||
+ "<head>"
|
||||
+ " <title>{0}</title>".format(single?model.record_name:model.records_name)
|
||||
+ " <link rel=stylesheet type='text/css' href='../appl/api2/table.css'>"
|
||||
+ "</head>"
|
||||
+ "<body>"
|
||||
+ antwoord
|
||||
+ "</body>"
|
||||
+ "</html>";
|
||||
break;
|
||||
case "xml":
|
||||
Response.ContentType = "text/xml";
|
||||
var xml_antwoord = api2_rest.json2xml(data, model, single);
|
||||
@@ -551,6 +565,46 @@ api2_rest = {
|
||||
Response.write(str_antwoord);
|
||||
},
|
||||
|
||||
json2htmltable: function _json2htmltable(data, model, single)
|
||||
{
|
||||
var trs = [];
|
||||
if (data.length) // Header maken
|
||||
{
|
||||
var tds = [];
|
||||
for (var fld in data[0])
|
||||
tds.push(fld);
|
||||
trs.push("<th>" + tds.join("</th><th>") + "</th>");
|
||||
}
|
||||
for (var i = 0; i < data.length; i++)
|
||||
{
|
||||
var rec = data[i];
|
||||
var tds = [];
|
||||
for (var fld in rec)
|
||||
{
|
||||
var val = rec[fld];
|
||||
var safeval = Server.HTMLEncode(String(val));
|
||||
if (val === null)
|
||||
safeval = ' ';
|
||||
if (typeof val == 'object' && val instanceof Date)
|
||||
safeval = toISODateTimeString(val);
|
||||
if (val && typeof val == "object" && "id" in val)
|
||||
{ // dereference
|
||||
var naam = val.name||"???";
|
||||
if (typeof naam == 'object' && naam instanceof Date) // Bij appointment
|
||||
naam = toISODateTimeString(naam);
|
||||
safeval = val.id + " (" + Server.HTMLEncode(naam) + ")";
|
||||
}
|
||||
else if (val && typeof val == "object" && model.includes && fld in model.includes)
|
||||
{ // dereference
|
||||
safeval = api2_rest.json2htmltable(val, model.includes[fld].model, single)
|
||||
}
|
||||
tds.push(safeval);
|
||||
}
|
||||
trs.push("<td>" + tds.join("</td><td>") + "</td>");
|
||||
}
|
||||
return "\n<table border='1'>\n<tr>" + trs.join("</tr>\n<tr>") + "</tr></table>";
|
||||
},
|
||||
|
||||
// TODO: Wanneer attributes gebruiken en wanneer (sub)-elements?
|
||||
// Streven: data == xml2json(json2xml(data))
|
||||
json2xml: function _json2xml(data, model, single)
|
||||
|
||||
@@ -71,7 +71,7 @@ function model_appointments()
|
||||
|
||||
this.list = { columns: ["id", "from", "to"] },
|
||||
this.includes =
|
||||
{"visitors": { model: model_visitors,
|
||||
{"visitors": { model: new model_visitors(),
|
||||
joinfield: "appointment",
|
||||
enable_update: true
|
||||
},
|
||||
|
||||
@@ -48,6 +48,7 @@ function model_custom_fields(formodel, flexModule, flexParams)
|
||||
|
||||
this.fields = {
|
||||
// De echte unieke waarde "id" is bez_kenmerkwaarde_key.
|
||||
// We doen echter alles op basis van de samengestelde kenmerk_key + parent_key
|
||||
// De naam van dat veld weten we hier even niet echter
|
||||
// en hebben we ook niet nodig
|
||||
"propertyid": {
|
||||
@@ -118,6 +119,11 @@ function model_custom_fields(formodel, flexModule, flexParams)
|
||||
}
|
||||
delete record["xflexparentkey"]; // nu niet meer nodig
|
||||
}
|
||||
// Voor flexbijlagen kennen we een duale interface
|
||||
// Enerzijds zitten ze gewoon als attachements-object in de JSON
|
||||
// die een GET van custom_fields oplevert
|
||||
// Anderzijds zijn ze met GET/PUT/POST/DELETE rechtstreeks te benaderen onder
|
||||
// /api2/visitors/1234/attachments/1000/test.jpg
|
||||
this.streamattachment = function(filter, flexfields)
|
||||
{
|
||||
for (var fid in flexfields)
|
||||
@@ -150,26 +156,15 @@ function model_custom_fields(formodel, flexModule, flexParams)
|
||||
Response.Status = "404 Not Found";
|
||||
}
|
||||
|
||||
this.REST_PUT = function (params, jsondata, the_key) /* update custom_field */
|
||||
{debugger;
|
||||
var sql = "BEGIN flx.setflex({0}".format(safe.quoted_sql(this.module))
|
||||
+ " , {0}".format(jsondata.propertyid)
|
||||
+ " , {0}".format(params.filter.id)
|
||||
+ " , {0}".format(safe.quoted_sql(flexParams.niveau))
|
||||
+ " , {0});".format(safe.quoted_sql(jsondata.value))
|
||||
+ "END;"
|
||||
Oracle.Execute(sql);
|
||||
}
|
||||
|
||||
this.REST_POST = function (params, jsondata, parent_key) /* add custom_field */
|
||||
{
|
||||
this.REST_PUT = function (params, jsondata, the_key, parent_key) /* update custom_field */
|
||||
{ // Let op: parameter the_key is de kenmerk_key, niet een een kenmerkwaarde_key
|
||||
// Merk op dat flexProps ook wel het type oplevert. Ik wil echter migreren naar modellen
|
||||
var kenmerkdata = api2.GET(flexModel, jsondata.propertyid);
|
||||
// TODO: if (!kenmerkdata) en rechtencontrole
|
||||
var typ = kenmerkdata.attributetype.id;
|
||||
if (typ == 'F' || typ == 'M')
|
||||
{debugger;
|
||||
var flexparams = flexProps(this.module, params.filter.id, params.filter.subfolder, flexParams.pNiveau);
|
||||
{
|
||||
var flexparams = flexProps(this.module, params.filter.id, the_key, flexParams.pNiveau);
|
||||
// TODO: bij type F zorgen dat er <20><>n file overblijft
|
||||
for (var i = 0; i < jsondata.attachments.length; i++)
|
||||
{
|
||||
@@ -178,9 +173,17 @@ function model_custom_fields(formodel, flexModule, flexParams)
|
||||
if (flexparams.isAllowedName(safefilename))
|
||||
{
|
||||
CreateFullPath(flexparams.AttachPath);
|
||||
if ("datastream" in attachment)
|
||||
if ("datastream" in attachment) // PUT op /api2/visitors/1234/attachments/1000/test.jpg
|
||||
{
|
||||
attachment.datastream.SaveToFile(flexparams.AttachPath + safefilename, 2); // adSaveCreateOverWrite
|
||||
// TODO: content_base64 en content_hex encoding ondersteunen
|
||||
}
|
||||
else if ("content_base64" in attachment || "content_hex" in attachment)
|
||||
{
|
||||
var fileencoding = "content_base64" in attachment?"bin.base64":"bin.hex";
|
||||
encodedString2File(flexparams.AttachPath + safefilename,
|
||||
attachment.content_base64 || attachment.content_hex,
|
||||
fileencoding);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -190,20 +193,30 @@ function model_custom_fields(formodel, flexModule, flexParams)
|
||||
}
|
||||
}
|
||||
|
||||
var sql = "BEGIN flx.setflex({0}".format(safe.quoted_sql(this.module))
|
||||
+ " , {0}".format(jsondata.propertyid)
|
||||
+ " , {0}".format(parent_key)
|
||||
+ " , {0}".format(safe.quoted_sql(flexParams.niveau))
|
||||
+ " , {0});".format(safe.quoted_sql(jsondata.value))
|
||||
+ "END;"
|
||||
Oracle.Execute(sql);
|
||||
if (typ != "M")
|
||||
{
|
||||
var sql = "BEGIN flx.setflex({0}".format(safe.quoted_sql(this.module))
|
||||
+ " , {0}".format(the_key) // == jsondata.propertyid
|
||||
+ " , {0}".format(params.filter.id)
|
||||
+ " , {0}".format(safe.quoted_sql(flexParams.niveau))
|
||||
+ " , {0});".format(safe.quoted_sql(jsondata.value))
|
||||
+ "END;"
|
||||
Oracle.Execute(sql);
|
||||
}
|
||||
}
|
||||
|
||||
this.REST_POST = function (params, jsondata, parent_key) /* add custom_field */
|
||||
{ // Voor flexvelden is er geen verschil tusen 'toevoegen' en 'bijwerken'
|
||||
this.REST_PUT(params, jsondata, jsondata.propertyid, parent_key);
|
||||
}
|
||||
|
||||
this.REST_DELETE = function (params, the_key) /* remove custom_field */
|
||||
{
|
||||
// custom_fields zijn ietwat afwijkend
|
||||
// 'verwijderen' doe je door de waarde op NULL te zetten (net zoals met vaste velden)
|
||||
// Anders loop je risico dat bij een update velden die niet in de include=custom_fields
|
||||
// zitten (omdat je er gewoon geen rechten op had) zo maar verwijderd worden
|
||||
// TODO: flexfiles wel deleten
|
||||
}
|
||||
|
||||
this.list = { columns: ["id", "label", "value"] }
|
||||
|
||||
@@ -100,7 +100,9 @@ function model_visitors()
|
||||
var sql = "SELECT " + query.selects.join(", ")
|
||||
+ " FROM " + query.tables.join(", ")
|
||||
+ " WHERE " + query.wheres.join(" AND " )
|
||||
+ " ORDER BY bez_afspraak_datum, bez_afspraak.bez_afspraak_key";
|
||||
+ " ORDER BY bez_afspraak.bez_afspraak_key, bez_bezoekers.bez_bezoekers_key";
|
||||
if (query.orderbys.length)
|
||||
sql += ", " + query.orderbys.join(", ");
|
||||
|
||||
var json = api2.sql2json (params, sql, this );
|
||||
|
||||
|
||||
19
APPL/API2/table.css
Normal file
19
APPL/API2/table.css
Normal file
@@ -0,0 +1,19 @@
|
||||
table {
|
||||
color: #333; /* Lighten up font color */
|
||||
font-family: Verdana; /* Nicer font */
|
||||
font-size: smaller;
|
||||
border-collapse:
|
||||
collapse; border-spacing: 0;
|
||||
}
|
||||
|
||||
td, th { border: 1px solid #CCC; height: 1.3em; } /* Make cells a bit taller */
|
||||
|
||||
th {
|
||||
background: #F3F3F3; /* Light grey background */
|
||||
font-weight: bold; /* Make sure they're bold */
|
||||
}
|
||||
|
||||
td {
|
||||
background: #FAFAFA; /* Lighter grey background */
|
||||
text-align: center; /* Center our text */
|
||||
}
|
||||
@@ -21,12 +21,12 @@
|
||||
</rule>
|
||||
<!-- /api2/buildings/1234.xml?... /default.asp?api2=buildings&format=xml&id=1234&... -->
|
||||
<rule name="api2SingleRecord" stopProcessing="true">
|
||||
<match url="^api2/([a-z0-9_]+)/(\d+)\.(xml|json|html|api|doc)/?" />
|
||||
<match url="^api2/([a-z0-9_]+)/(\d+)\.(xml|json|html|api|doc|table)/?" />
|
||||
<action type="Rewrite" url="default.asp?api2={R:1}&format={R:3}&id={R:2}" appendQueryString="true" />
|
||||
</rule>
|
||||
<!-- /api2/buildings.xml?... /default.asp?api2=buildings&format=xml&... -->
|
||||
<rule name="api2List" stopProcessing="true">
|
||||
<match url="^api2/([a-z0-9_]+)\.(xml|json|html|api|doc)/?" />
|
||||
<match url="^api2/([a-z0-9_]+)\.(xml|json|html|api|doc|table)/?" />
|
||||
<action type="Rewrite" url="default.asp?api2={R:1}&format={R:2}" appendQueryString="true" />
|
||||
</rule>
|
||||
<!-- 2015.1 experimenteel: -->
|
||||
|
||||
@@ -385,6 +385,8 @@ function oneFileInfo(fsoFile, result, pModule, pKey, pSubpath, pNiveau, params)
|
||||
}
|
||||
if (params.getFileEncoded == "base64" || params.getFileEncoded == "hex")
|
||||
{
|
||||
// Verleidelijk om new ActiveXObject("SLNKDWF.Crypto").base64 in te zetten
|
||||
// Die kan echter alleen text-input aan, niet binary data
|
||||
var oStream = Server.CreateObject("ADODB.Stream");
|
||||
oStream.Open;
|
||||
oStream.Type = 1; // adTypeBinary
|
||||
@@ -394,7 +396,7 @@ function oneFileInfo(fsoFile, result, pModule, pKey, pSubpath, pNiveau, params)
|
||||
var oNode = oXML.createElement("encodeddata");
|
||||
oNode.dataType = params.getFileEncoded == "base64"?"bin.base64":"bin.hex"; // Zeer snelle oplossing
|
||||
oNode.nodeTypedValue = oStream.read(oStream.Size);
|
||||
filedata.data = oNode.text;
|
||||
filedata.data = oNode.text.replace(/\n/g, ""); // Ik wil de newlines er niet in hebben
|
||||
oStream.Close();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user