Download on GitHub
postQueryFMS(query, callBackOnReady[, callBackOnDownload, phpRelay, resultClass, max, nestPortals])
- js - the results as an array of objects
- utc - (optional) the utc timestamp when the download was completed.
- "server" : server location
- "php" : [optional: default fmxjRelay.php]
- "protocol" : [optional: default http]
- "port" : [optional: default 80]
- "user" : [optional: FM Account]
- "pass" : [optional: FM Account Password]
You can use fmxj without any PHP providing all the JavaScript is hosted on the FileMaker Server. In this case, the JavaScript will do the httpXMLRequest POST directly to FileMaker Server's XML API. If the Guest account is not enabled then you will be prompted for FileMaker authentication from the browser. This is simple Basic Authentication, so may not be suitable for your deployment. If you're using this deployment, you can simply not pass the optional phpRelay argument or pass null, to it.
You will need to use the php Relay if your web server and Filemaker server are located remotely from each other. FileMaker server does not allow cross domain httpXMLRequests directly to the XML API, and changing this involves modifying the Web Server settings. This is actually pretty easy in Windows/IIS, but not so in Mac/FileMaker Server/Apache. In either case, dropping a single PHP relay file into the FileMaker Server's root directory is much easier.
fmxj comes with a simple PHP file (fmxjRelay.PHP) that you can use for this. You'll then do your POST to the PHP file which will then do the identical POST locally to the FileMaker server using cURL and then relay the XML results back. When doing this you'll need to have the fmxjRelay.php file in your FileMaker WPE's root directory. You'll then need to define an object in JavaScript and pass it as the phpRelay argument.
User name and password can be passed as part of the object. They are sent via POST, so can potentially be secured if both the web server and Filemaker Server are using SSL, otherwise passing the credentials like this is equivalent to Basic Authentication. You also have the option of hardcoding the FileMaker credentials in the PHP file so they're not passed via JavaScript at all.
{
"id" : {
"idFieldName":"id", // filemaker field name is "id"
"getValue" : function(f){ // method name must be getValue.
var field = this["idFieldName"]; //retrieve our field name
return f(field); //retrieve the filemaker field value
}, // end method
}, // end property
}
In addition to straight field mapping, you can also define the getValue() method to transform/combine the source data.
{
"allDay" : {
"timeStartFieldName" : "TimeStart", //field for start time,
"getValue" : function(f){
var field = this["timeStartFieldName"];
if(f(field).length){ //we have a start time so this is false
return false;
}
else{ //if empty, event is all day
return true;
};
}, // end getValue method
}, // end property
}
See example 5 below for more details on this argument usage.
var requests = [ //create requests for query
{ "DateStart" : "<=2/28/2014" , "DateEnd" : ">=2/1/2014" },
{ "DateStart" : "2/1/2014...2/28/2014" }
];
var query = fmxj.findRecordsURL("Events", "Events", requests) ; // create query
function onReadyFuntion(js){ //define handler for onready
document.getElementById("example1") = JSON.stringify(js, null, 4);
} ;
function onProgressFuntion(n){ //define handler for onprogress
document.getElementById("example1") += n + " bytes downloaded\n";
} ;
fmxj.postQueryFMS(query, onReadyFunction, onProgressFunction); //make call
var sourceLoop = [];
var requests = [ //create requests for query
{ "DateStart" : "<=2/28/2014" , "DateEnd" : ">=2/1/2014" },
{ "DateStart" : "2/1/2014...2/28/2014" }
];
var sortObject = {
"field1" : "DateStart" ,
"order1" : "ascend" ,
} ;
var query = fmxj.findRecordsURL("Events", "Events", requests) ; // create query
function onReadyFuntion(js){ //define handler for onready
//callBack will return pages recursively, so concat to our array.
sourceLoop = sourceLoop.concat(js);
document.getElementById("example1") = JSON.stringify(sourceLoop, null, 4);
};
// for 375 results per page (max) we don't need an onProgress handler, so we'll set to null.
fmxj.postQueryFMS(query, onReadyFunction, null, relay, null, 375); //make call
var query = fmxj.findRecordsURL("Events", "ShmEvents", requests) ;
fmxj.postQueryFMS(query, onReadyFunction) ;
var query = fmxj.findRecordsURL("Contacts", "Contacts");
fmxj.postQueryFMS(q, writeResults, writeDownload, relay, null, 1000, true);
var fcObject = {
"id" : {
"idField":"id",
"getValue" : function(f){
var field = this["idField"];
return f(field);
},
},
"title" : {
"titleField":"Summary",
"getValue" : function(f){
var field = this["titleField"];
return f(field);
},
},
"allDay" : {
"timeStartField" : "TimeStart",
"getValue" : function(f){
var field = this["timeStartField"];
if(f(field).length){//we have a start time so this is false
return false;
}
else{
return true;
}
},
},
"start" : {
"timeStartField" : "TimeStart",
"dateStartField" : "DateStart",
"yearFormat" : "MM-DD-YYYY",
"timeFormat" : "HH:mm",
"timezone" : "America/Los_Angeles",
"getValue" : function(f){
var time = this["timeStartField"];
var date = this["dateStartField"];
var zone = this["timezone"];
var yearFormat = this["yearFormat"];
var timeFormat = this["timeFormat"];
var date = moment( f(date) + " " + f(time) , yearFormat + " " + timeFormat );
return date.tz(zone).format();
},
},
"end" : {
"timeEndField" : "TimeEnd",
"dateEndField" : "DateEnd",
"dateStartField" : "DateStart", //if no end date is specified we'll need to use the start date.
"yearFormat" : "MM-DD-YYYY",
"timeFormat" : "HH:mm",
"timezone" : "America/Los_Angeles",
"getValue" : function(f){
var time = this["timeEndField"];
var date = this["dateEndField"];
var sdate = this["dateStartField"];
var zone = this["timezone"];
var yearFormat = this["yearFormat"];
var timeFormat = this["timeFormat"];
//use start date if no end date
if(!f(date)){ var d = f(sdate) } else { var d = f(date)};
if(f(time).length){
d = moment( d + " " + f(time) , yearFormat + " " + timeFormat );
}
else
{
d = moment( d , yearFormat + " " + timeFormat ).add( 1, "days");
};
return d.tz(zone).format();
},
},
"description" : {
"descriptionField":"Description",
"getValue" : function(f){
var field = this["descriptionField"];
return f(field);
},
},
"resource" : {
"resourceField":"Resource",
"getValue" : function(f){
var field = this["resourceField"];
return f(field);
},
},
"status" : {
"statusField":"Status",
"getValue" : function(f){
var field = this["statusField"];
return f(field);
},
},
"contactId" : {
"contactIdFieldName":"id_contact",
"getValue" : function(f){
var field = this["contactIdFieldName"];
return f(field);
},
},
"projectId" : {
"projectIdField":"id_project",
"getValue" : function(f){
var field = this["projectIdField"];
return f(field);
},
},
"fmRecordId" : {
"fmRecordIdField":"-recid",
"getValue" : function(f){
var field = this["fmRecordIdField"];
return f(field);
},
},
"fmModId" : {
"fmModIdField":"-modid",
"getValue" : function(f){
var field = this["fmModIdField"];
return f(field);
},
},
};
//build query and make call passing are fcObject as the resultClass argument
var query = fmxj.findRecordsURL("Events", "Events", requests);
fmxj.postQueryFMS(query, writeResults, writeDownload, relay, fcObject);