diff --git a/css/fmxj.css b/css/fmxj.css index 6649f50..261f4ab 100755 --- a/css/fmxj.css +++ b/css/fmxj.css @@ -1,116 +1,143 @@ -* { - font-family:Cabin,Arial,Verdana,sans-serif; -} body { - min-width:700px; - width:90%; + width:94%; + min-width:800px; background-color: rgb(88,93,118); } - -footer { - height:36px; -} div { - padding:6px; - color:white; - margin:5px; + font-family:Cabin,Arial,Verdana,sans-serif; + font-weight:lighter; } -pre { - padding:16px; - margin:5px; +footer { + height:36px; } + button { - padding-top:6px; - padding-right:18px; - padding-bottom:6px; - padding-left:18px; - font-size:16px; + margin-top:12px; + padding-top:7px; + padding-bottom:7px; + font-size:100%; color:white; border-radius:5px; outline:0px; cursor:pointer; - background:rgba(167, 215, 255, 0.0980392); - + width:100%; + -webkit-box-shadow: 1px 1px 1px rgba(240,240,240,0.8); + -moz-box-shadow: 1px 1px 1px rgba(240,240,240,0.8); + box-shadow: 1px 1px 1px rgba(240,240,240,0.8); + border-top-color: rgba(255, 255, 255, 0.898039); + border-top-style: solid; + border-top-width: 1px; + border-right-color: rgba(255, 255, 255, 0.898039); + border-right-style: solid; + border-right-width: 1px; + border-bottom-color: rgba(255, 255, 255, 0.898039); + border-bottom-style: solid; + border-bottom-width: 1px; + border-left-color: rgba(255, 255, 255, 0.898039); + border-left-style: solid; + border-left-width: 1px; + background:rgba(88,93,118,0.94); } button:hover{ - background:rgba(167, 215, 255, 0.14); + color:#a7d7ff; + //color:rgba(240, 240, 240, .85); + background:rgba(88,93,118, 0.98); } -code { - overflow-x:scroll; - font-size:90%; - border-right: 1px solid #999; - +li > a { + text-decoration:none; + color:white; } +li > a:hover { + //color:rgba(240, 240, 240, .85); + color:#a7d7ff; + cursor:pointer; + text-decoration:underline; +} -.title { - font-size:50px; - margin-left:9%; +h3{ + font-weight:lighter; + margin-top:0px; + margin-bottom:0px; } -.gh { - margin-top:12px; - float:right; - vertical-align:bottom; - display:inline-block; - padding-right:42px; - padding-left:42px; - padding-top:9px; - padding-bottom:9px; +h3 > a { + color:rgb(88,93,118); + text-decoration:none; } -.chapter { - font-weight:lighter; - font-size:28px; - margin-left:10%; +h3 > a:hover { + text-decoration:underline; } -.subchapter { - font-size:22px; - margin-left:10%; +button > a { + text-decoration:none; + color:white; } -.separator { - margin-left:8%; - margin-top:36px; - margin-bottom:36px; - border-bottom-color: rgba(255, 255, 255, 0.298039 ); - border-bottom-style: solid; +pre { + overflow:auto; + padding:0px 12px 12px 12px; } -.functionTitle { - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); - color:#FBFFFB; - margin-left:10%; - font-family:Consolas, "Liberation Mono", Menlo, Courier, monospace; - font-size:140%; +code { + overflow-x:scroll; + font-size:87%; + border-right: 1px solid #999; } -.text { - margin-top:-12px; - margin-left:10%; - font-size:110%; - font-weight:lighter; - display:inline-block; +.title { + color:white; + font-size:54px; + margin-left:54px; + margin-bottom:14px; } -.pad { - margin-top:0px; - margin-bottom:0px; - color:rgb(88,93,118); - background: #f5f2f0; - margin-left:10%; +.sub-title { + color:white; + margin-left:54px; + padding:0px; + font-size:24px; + margin-bottom:-6px; +} + +div.sidebar { + padding:12px 1% 5px 0px; + margin-top:18px; + margin-left:36px; + width:200px; + float:left; + min-height:300px; + border-radius: 4px 0px 0px 4px; + border-top-color: rgba(255, 255, 255, 0.298039); + border-top-style: solid; + border-top-width: 1px; + border-bottom-color: rgba(255, 255, 255, 0.298039); + border-bottom-style: solid; + border-bottom-width: 1px; + border-left-color: rgba(255, 255, 255, 0.298039); + border-left-style: solid; + border-left-width: 1px; + color:white; + background:rgba(167, 215, 255, 0.0980392); + font-weight:lighter; + } -.shadow { - border-radius:5px 5px 5px 5px; +div.content { + background:rgba(248, 248, 248, .9 ); + border-radius: 0px 4px 4px 4px; + padding:20px 20px 12px 20px; + margin-left:248px; + margin-top:18px; + min-height:800px; border-top-color: rgba(255, 255, 255, 0.298039); border-top-style: solid; border-top-width: 1px; @@ -123,124 +150,117 @@ code { border-left-color: rgba(255, 255, 255, 0.298039); border-left-style: solid; border-left-width: 1px; - //-webkit-box-shadow: 1px 1px 1px rgba(0,0,0,0.2); - //-moz-box-shadow: 1px 1px 1px rgba(0,0,0,0.2); - //box-shadow: 1px 1px 1px rgba(0,0,0,0.2); + color:rgb(88,93,118); } -.label { - font-size:90%; - color:rgb(88,93,118); - font-weight:bold; - margin-bottom:-4px; + + +li.largeitem { + font-size:large; + margin-left:2%; } -.type { +li.smallitem { + margin-left:-12px; font-size:90%; - margin-left:-8px; - margin-top:-4px; - font-weight:normal; - margin-bottom:-4px; + padding:8px 0px 8px 0px; + font-weight:lighter; + list-style-type: square; } -.string { - color:#87193E; +li.sidebaritem { + margin-left:1%; + padding:8px 0px 8px 0px; } -.array { - color:#6B008F; +li.smallitem:hover { + color:rgba(240, 240, 240, .85); + cursor:pointer; } -.object { - color:#004700; +.bold { + font-weight:bold; } -.number { - color:#0000CC; +.functionTitle { + margin-top:0px; + margin-bottom:6px; + font-family:Consolas, "Liberation Mono", Menlo, Courier, monospace; } -.func { - color:#338570; +.argument { + margin-top:6px; + font-size:90%; + margin-left:12px; + font-weight:bold; + padding:5px; } -.desc { +.type { + margin-left:-6px; font-size:90%; - margin-top:-4px; - color:rgb(88,93,118); - padding-right:2px; - font-weight:normal; - margin-left:5px; - padding:6px; } -.divSeparator { - margin-top:-16px; - border-bottom:1px; - border-bottom-color: rgba(70, 70, 70, 0.2 ); - border-bottom-style: solid; +.text { + margin-left:12px; + font-size:90%; + color:rgb(88,93,118); + padding:8px; } -.smallList { - margin-left:-22px; - margin-top:4px; +.desc { + margin-left:12px; + font-size:90%; + color:rgb(88,93,118); + padding:8px; + margin-bottom:12px; } -.n { - color:black; - font-style:italic; +.string { + color:#87193E; } -.noBullets { - padding-left:2%; - list-style-type: none; +.array { + color:#6B008F; } - -.largeitem { - font-size:large; +.object { + color:#004700; } - - -.argument { - padding-left:1%; - padding-bottom:1%; +.number { + color:#0000CC; } -.topline { - padding-top:2%; +.func { + color:#338570; } -.bottomline { - padding-bottom:2%; +.divSeparator { + margin-top:-8px; + border-bottom:1px; + border-bottom-color: rgba(200, 200, 200, 0.7 ); + border-bottom-style: solid; } - .result { - color:rgb(88,93,118); - font-size:90%; - min-height:48px; + color:gray; + min-height:100px; max-height:200px; white-space: pre-wrap; margin-top:5px; - margin-bottom:5px; + margin-bottom:10px; + font-size:small; + font-family:Consolas, "Liberation Mono", Menlo, Courier, monospace; } .tall { - max-height:344px; - height:344px; + max-height:none; + height:300px; overflow-y:auto; overflow-x:hidden; } -.bottomMargin { - margin-bottom:-36px; -} - -.textshadow { - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); -} - .resultHeader { color:gray; font-size:small; @@ -257,34 +277,3 @@ code { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/databases/Contacts.fmp12 b/databases/Contacts.fmp12 index 1730d8e..feb0b29 100755 Binary files a/databases/Contacts.fmp12 and b/databases/Contacts.fmp12 differ diff --git a/examples/deleteQuery.html b/examples/deleteQuery.html new file mode 100755 index 0000000..9a0b76f --- /dev/null +++ b/examples/deleteQuery.html @@ -0,0 +1,151 @@ + + + + + +  + + + + + + + + + + +
+ SeedCode Logo +
+

+
+

+
+ fmxj.js +
+
+ a JavaScript approach to FileMaker Custom Web Publishing +
+ + +
+

deleteRecordURL(fileName, layoutName, recid)

+
Create a FileMaker -delete query url by specifying the FileMaker record id. These queries are then passed to the postQueryFMS() function which returns the results as a single object array. The object contains the error code with "0" meaning a succesful delete.
+
+
+
+ fileName +
+ + Type: + + + String + +
+ A String of the name of the hosted FileMaker file. +
+
+
+ layoutName +
+ + Type: + + + String + +
+ A String of the name of the target layout in the specified file. +
+
+
+ recid +
+ + Type: + + + number + +
The FileMaker Record ID (-recid) of the record to be deleted.
+ +
+
example 1
+
Create a -delete query by passing the -recid id to the function. Then POST the query. For this example we'll create a new record to delete (so we don't run out of sample data!) +
+
+
+//create new record query from object
+var newRecord =	{
+				"DateStart" : "02/25/2014" ,
+				"DateEnd" : "02/25/2014" ,
+				"Description" : "delete example" ,
+				"Status" : "Open" ,
+				"Summary" : "test delete example"
+				} ;
+var query = fmxj.editRecordURL("Events", "Events", newRecord);
+fmxj.postQueryFMS(query, writeResult);//POST query
+function writeResult (js) { // define handler for results.
+	var record = js[0];
+	updateElement("example1",JSON.stringify(js, null, 4));//write new record to element as JSON
+	if(record["-recid"]){//this is the result for our new record.
+	var recid = record["-recid"];//retrieve record id so we can delete it
+	var dq = fmxj.deleteRecordURL("Events", "Events", recid );//create query
+	fmxj.postQueryFMS(dq, writeResult);//POST query
+	}
+	else//this is the result of our delete request so write it to element
+	{
+	updateElement("example1", JSON.stringify(js, null, 4), true);
+	}
+};
+ + +

+
+
+ + + + + + \ No newline at end of file diff --git a/examples/editQuery.html b/examples/editQuery.html new file mode 100755 index 0000000..8c0e7a3 --- /dev/null +++ b/examples/editQuery.html @@ -0,0 +1,191 @@ + + + + + +  + + + + + + + + + + +
+ SeedCode Logo +
+

+
+

+
+ fmxj.js +
+
+ a JavaScript approach to FileMaker Custom Web Publishing +
+ + +
+

editRecordURL(fileName, layoutName, editObj)

+
Create a FileMaker -edit or -new query url from a javascript object. These queries are then passed to the postQueryFMS() function which returns the results as a single object array.
+
+
+
+ fileName +
+ + Type: + + + String + +
+ A String of the name of the hosted FileMaker file. +
+
+
+ layoutName +
+ + Type: + + + String + +
+ A String of the name of the target layout in the specified file. +
+
+
+ editObj +
+ + Type: + + + Object + +
An Object that specifies the changes to be made to the FileMaker record. Property names represent the FileMaker field names. Specifying a -recid property will edit the specified record with an -edit query. Not specifying the -recid will create a new FileMaker record with a -new query. The -modid property can be optionally specified to ensure you are editing the most current version of that record. See more about using the -mod id in FileMaker's XML CWP Guide +
+ + +
+
example 1
+
Create a new FileMaker record by not specifying the -recid in the edit object. If the record creation is succesful on the server, then the record will be returned and converted into an object. +
+
+
+var newRecord =	{
+				"DateStart" : "02/25/2014" ,
+				"DateEnd" : "02/25/2014" ,
+				"Description" : "test" ,
+				"Status" : "Open" ,
+				"Summary" : "test summary ubi"
+				} ;
+var query = fmxj.editRecordURL("Events", "Events", newRecord) ;
+fmxj.postQueryFMS(query, callBackFunction) ;
+ +

+		
+		
+		
+
example 2
+
Specifying a -recid property in an object will create a edit query to edit the fields specified in the object. Retrieve the first record on the Events layout and toggle its status. If the status is open, set it to closed and vice-versa. +
+
+
+// query to find all records, unsorted and return the first one.
+var query = fmxj.findRecordsURL("Events", "Events", null, null, 1);
+fmxj.postQueryFMS(query,createEdit,null,relay); // Perform request
+function createEdit(js){ //define handler for returned record
+	var recid = js[0]["-recid"]; //retrieve record/object's -recid
+	var modid = js[0]["-modid"]; //retrieve record/object's -modid
+	var recordStatus = js[0]["Status"]; //retrieve record/object's status
+	if ( recordStatus == "Open" ){ //toggle status
+		 recordStatus = "Closed" 
+	} 
+	else {
+		 recordStatus = "Open" 
+	} ;
+	var editObj = { //create new object to edit the record
+		"-recid":recid,
+		"-modid":modid,
+		"Status":recordStatus,
+				  };
+	//create query from object
+	var query = fmxj.editRecordURL("Events", "Events", editObj);
+	fmxj.postQueryFMS(query,writeResult,null,relay); //POST edit query
+	function writeResult(js){ //define handler for writing edited object.
+		updateElement("example2", message, true);
+	};
+};
+ +

+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/examples/filterObjects.html b/examples/filterObjects.html new file mode 100755 index 0000000..f3ce405 --- /dev/null +++ b/examples/filterObjects.html @@ -0,0 +1,181 @@ + + + + + +  + + + + + + + + + +
+ SeedCode Logo +
+

+
+

+
+ fmxj.js +
+
+ a JavaScript approach to FileMaker Custom Web Publishing +
+ + +
+

filterObjects(filters, searchTypes, source)

+
Apply complex property filters to an array of objects in JSON format using the request syntax.
+
+
+
+ filters +
+ + Type: + + + Array of Objects + +
+ An Array of Objects where each object represents a FileMaker type Find Request, i.e. each property specified within an object represents an AND clause and each object on the array represents an OR clause. +
+
+
+ searchTypes +
+ + Type: + + + Object + +
+ An Object specifying the standard search types to apply when filtering by the specified property. Supported search types are: + +
+
+
+ source +
+ + Type: + + + Array of Objects + +
+ The Array of Objects to be filtered. +
+ +
+
example 1
+
Get an array of objects from the server and then apply and revert filters to it.
+ +
+
+var source = [];
+var requests =	[
+	{ "DateStart" : "<=2/28/2014" , "DateEnd" : ">=2/1/2014" } ,
+	{ "DateStart" : "2/1/2014...2/28/2014" }
+				] ;
+var query = fmxj.findRecordsURL("Events", "Events", requests) ;
+fmxj.postQueryFMS(query, writeResults);
+function writeResults(js){
+	source=js;
+	var display = source.splice(0,500);
+	document.getElementById("example1").innerHTML=JSON.stringify(display, null, 4);
+};
+ + +
Apply filters
+
+
+var requests = [
+	{ "id" : "E4B04F12-E006-4928-A1E0-0E86EDF5641C" } , 
+	{ "id" : "463BBEA9-404B-4979-8CC0-6F8F60EB0154" } ,
+	{ "id" : "8CDA64C4-643D-4A64-9336-83BEF07F0CF4" } ,
+			   ];
+var types = {"id" : "equals"};
+filter = fmxj.filterObjects(requests, types, source);
+document.getElementById("example1").innerHTML=JSON.stringify(display, null, 4);
+ + + + + +
+		
+
+
+
+ + + + + + \ No newline at end of file diff --git a/examples/findQuery.html b/examples/findQuery.html new file mode 100755 index 0000000..1f6b40e --- /dev/null +++ b/examples/findQuery.html @@ -0,0 +1,331 @@ + + + + + +  + + + + + + + + + + +
+ SeedCode Logo +
+

+
+

+
+ fmxj.js +
+
+ a JavaScript approach to FileMaker Custom Web Publishing +
+ + +
+

findQueryURL(fileName, layoutName,[ requests, sort, max, skip])

+
Create a complex xml -findquery string from an array of javascript objects. These queries are then passed to the postQueryFMS() function which returns the results as an array of JavaScript Objects (JSON).
+
+
+
+ fileName +
+ + Type: + + + String + +
+ A String of the name of the hosted FileMaker file. +
+
+
+ layoutName +
+ + Type: + + + String + +
+ A String of the name of the target layout in the specified file. +
+
+
+ requests +
+ + Type: + + + Array of Objects + +
+ (Optional) An Array of Objects where each object represents a FileMaker Find Request. If this arguement is not passed then a -findall query will be generated. +
+
+
+
+ sort +
+ + Type: + + + Object + +
+ (Optional) An Object of name value pairs specifying a sort order for the query. Supported properties are field1-fieldn and order1-ordern (see example 3 below). +
+
+
+ max +
+ + Type: + + + Number + +
+ (Optional) A Number specifying the maximimum number of parent records to be returned from FileMaker Server. Simmilar to Fetch First in FileMaker's SQL syntax. +
+
+
+ skip +
+ + Type: + + + Number + +
+ (Optional) A Number specifying the number of records to skip in the found set before starting to return them. Simmilar yo Offset in FileMaker's SQL Syntax. +
+ + +
+
example 1
+
Two request find query for the layout "Events" in the file "Events". +
+
+
+var requests =	[
+	{ "DateStart" : "<=2/28/2014" , "DateEnd" : ">=2/1/2014" } ,
+	{ "DateStart" : "2/1/2014...2/28/2014" }
+				];	
+var query = fmxj.findRecordsURL("Events", "Events", requests) ;
+ +

+
+		
+
example 2
+
Add additional criteria to requests object, so both requests have the Resource field equal to "Example C". +
+
+
+var requests =	[
+	{ "DateStart" : "<=2/28/2014" , "DateEnd" : ">=2/1/2014" },
+	{ "DateStart" : "2/1/2014...2/28/2014" }
+			   	];
+requests[0]["Resource"] = "Example C";
+requests[1]["Resource"] = "Example C";
+var query = fmxj.findRecordsURL("Events", "Events", requests);
+ +

+
+		
+
example 3
+
Specify a sort order for the request by passing an object to the optional sort argument. Supprted order values are: ascend, descend and valuelist. +
+
+
+var requests =	[
+	{ "DateStart" : "<=2/28/2014" , "DateEnd" : ">=2/1/2014" } ,
+	{ "DateStart" : "2/1/2014...2/28/2014" }
+				] ;
+var sort =	{ 
+			"field1" : "DateStart" ,
+			"order1" : "descend" ,
+			"field2" : "id" ,
+			"order2" : "ascend"
+			} ;
+var query = fmxj.findRecordsURL("Events", "Events", requests, sort) ;
+ +

+
+		
+
example 4
+
Specify an Omit Request by setting the -omit property to 1. +
+
+
+var requests =	[
+	{ "DateStart" : "<=2/28/2014" , "DateEnd" : ">=2/1/2014" } ,
+	{ "DateStart" : "2/1/2014...2/28/2014" } ,
+	{ "Resource" : "Example B" , "-omit" : "1" }
+				] ;
+var query = fmxj.findRecordsURL("Events" ,"Events" ,requests) ;
+ +

+
+
+
+
+
+

+
+
+
+
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/examples/nestObjects.html b/examples/nestObjects.html new file mode 100755 index 0000000..41f21f9 --- /dev/null +++ b/examples/nestObjects.html @@ -0,0 +1,171 @@ + + + + + +  + + + + + + + + + +
+ SeedCode Logo +
+

+
+

+
+ fmxj.js +
+
+ a JavaScript approach to FileMaker Custom Web Publishing +
+ + +
+

nestObjects(parentArray, childArray, childName, predicates)

+
Nest one array of objects into another as a property an using SQL like Join.
+
+
+
+ parentArray +
+ + Type: + + + Array of Objects + +
+ An Array of Objects that will be the parent objects and have the child array nested in them. +
+
+
+ childArray +
+ + Type: + + + Array of Objects + +
+ An Array of Objects to be nested into the above parent objects. +
+
+
+ childName +
+ + Type: + + + String + +
+ The name of the property of the child array in the parent object. +
+
+
+ predicates +
+ + Type: + + + Object + +
+ An object specifying the match keys to join parent and child objects. Only equijoin matches supported. + +
+ +
+
example 1
+
Call Contacts and Contact Info in separate calls with no portals on the layouts, then stitch together in JS. Compare to example 2.4 where Contact Info is gathered via Portal. This operation (7.1) tests a little bit slower overall, but the footprint on the server is smaller, so should scale better with multiple users. You also may not need nest them all at once and right away like in this example.
+ +
+
+var contacts = [];
+var q1 = fmxj.findRecordsURL("Contacts", "ContactsNoPortal");
+var q2 = fmxj.findRecordsURL("Contacts", "ContactInfo");
+function writeDownload(n){
+	document.getElementById("nestResult").innerHTML +=  n + " bytes downloaded" ;
+} ;
+function updateContacts(js){
+	function updateContactInfo(js){
+		fmxj.nestObjects(contacts, js, "Contacts", {"parentKey1": "id", "childKey1": "id_Contact"});
+		document.getElementById("nestResult").innerHTML += JSON.stringify(contacts,null, 4 );
+	};
+	fmxj.postQueryFMS(q2, updateContactInfo, null, relay);
+	contacts = js;
+};
+fmxj.postQueryFMS(q1, updateContacts, writeDownload, relay);
+}
+};
+ + + + + +
+		
+
+
+
+ + + + + + \ No newline at end of file diff --git a/examples/postQuery.html b/examples/postQuery.html new file mode 100755 index 0000000..0df836f --- /dev/null +++ b/examples/postQuery.html @@ -0,0 +1,306 @@ + + + + + +  + + + + + + + + + +
+ SeedCode Logo +
+

+
+

+
+ fmxj.js +
+
+ a JavaScript approach to FileMaker Custom Web Publishing +
+ + +
+

postQueryFMS(query, callBackOnReady[, callBackOnDownload, phpRelay])

+
Performs an Ajax call to FileMaker Server. Results are converted to an Array of Objects(JSON) and passed to the callBackOnReady handler function. Query arguments can created from JavaScript Objects using the Query Functions. All fields on the target layout will be returned as object properties. Properties for -recid and -modid will be added automatically to each object in the array.
+
+
+
+ query +
+ + Type: + + + String + +
+ A String of the query to be POSTed to FileMaker Server. These Strings will typically be created by the fmxj URL finctions. +
+
+
+ callBackOnReady +
+ + Type: + + + Function(js, utc) + +
+ A Function for handling the returned Array of Objects when ready. Supported callback arguments are: + +
+
+
+ callBackOnDownload +
+ + Type: + + + Function(n) + +
+ (Optional) A Function for handling the on progress feedback for the POST. e.loaded is the only feedback property available from FileMaker Server and will be passed to the function as the argument n if specified. +
+
+
+ phpRelay +
+ + Type: + + + Object + +
+ (Optional) An object of name value pairs specifying the location of the FileMaker Server and the php relay file to use (fmxjRelay.php). Supported properties are: + +

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.

+
+ +
+
These examples are run from seedcode.com to a remote FileMaker Server (hosted at FoxtailTech) using the php relay.
+
+
+
example 1
+
Create a HTTP request to the hosted filemaker file "Events". Target layout in the specified file is "Events". Query is created by the findRecordsURL() function and passed as the query argument. The required handler for onreadystateexchange is defined as well as the optional onprogress handler. +
+
+
+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
+ + +

+
+
+
example 2
+
Looping Ajax Calls. Use Max and Skip in the findRecordsURL() to increment your calls. Takes a little longer overall, but initial results are displayed much more quickly.
+ +
+
+//sample function for updating pre via loop
+function updateJSONLoop(resultElementID, requests, increment, sort){
+	var sourceLoop = [];
+	var max = increment;
+	var skip = 0;
+	var num = 0;
+	var total = 0;
+	var message = "";
+	var indent = 4; //JSON indent
+	var q = "";
+	//callback functions for writing download.
+	function writeDownload(n){
+		document.getElementById(resultElementID).innerHTML += 
+		"" + n + " bytes downloaded\n" ;
+	} ;
+	function writeResult(js){
+		sourceLoop = sourceLoop.concat(js);
+		total = sourceLoop.length;
+		num = js.length;
+		if (num===max) { 
+			//maximum records returned, which meanse we have more to get(probably)
+			//increment skip and run again
+			skip = skip + max;
+			var q = fmxj.findRecordsURL("Events","Events", requests, sort, max, skip);
+			fmxj.postQueryFMS(q,writeResult,null,relay) ;
+		};
+		//Write results to element, first, last and middle ara little different.
+		//displaying collapsed, see fmxjDemo.js for full function code.
+		if (total===max) {*}
+		else if (num!==max) {*}
+		else {*}
+	}; //end writeResult
+	var q = fmxj.findRecordsURL("Events","Events", requests , sort , max , skip  );
+	fmxj.postQueryFMS(q, writeResult, writeDownload, relay);
+};
+var requests =	[
+	{ "DateStart" : "<=2/28/2014" , "DateEnd" : ">=2/1/2014" } ,
+	{ "DateStart" : "2/1/2014...2/28/2014" }
+				] ;
+var sortObject = { 
+	"field1" : "DateStart" ,
+	"sort1" : "ascend" 
+				 } ;
+updateJSONLoop("loopResult", requests, 500, sortObject); //loads 500 records at a time
+ + +

+
+
+
example 3
+
Errors returned as a simple one object array with the Filemaker error code and description.
+ +
+
+var query = fmxj.findRecordsURL("Events", "ShmEvents", requests) ;
+fmxj.postQueryFMS(query, onReadyFunction) ;
+ +

+
+
example 4
+
Portals on the target layouts are converted to nested arrays. The TO name of the portal's source will be used as the property name, and will be prefixed by a hyphen to make sure it doesn't collide with a field name in the parent table. This puts a higher load on the server, so use sparingly or consider an alternitive structure using the nestObjects() function.
+
+
+var query = fmxj.findRecordsURL("Contacts", "Contacts");
+fmxj.postQueryFMS(query, onReadyFunction, onProgressFunction);
+ +

+
+
+ + + + + + \ No newline at end of file diff --git a/examples/sortObjects.html b/examples/sortObjects.html new file mode 100755 index 0000000..92f174c --- /dev/null +++ b/examples/sortObjects.html @@ -0,0 +1,182 @@ + + + + + +  + + + + + + + + + +
+ SeedCode Logo +
+

+
+

+
+ fmxj.js +
+
+ a JavaScript approach to FileMaker Custom Web Publishing +
+ + +
+

sortObjects(filters, searchTypes, source)

+
Sort an array of objects in JSON format by multiple properties.
+
+
+
+ sortOrder +
+ + Type: + + + Object + +
+ An object specifying the properties by which to sort the array of objects, the order by which to sort them, and the data type to apply to the properties. + +
+
+ +
+ source +
+ + Type: + + + Array of Objects + +
+ The Array of Objects to be sorted +
+ + + + +
+
example 1
+
Get an array of objects from the server and then sort and unsort it.
+ +
+
+var source = [];
+var requests =	[
+	{ "DateStart" : "<=2/28/2014" , "DateEnd" : ">=2/1/2014" } ,
+	{ "DateStart" : "2/1/2014...2/28/2014" }
+				] ;
+var query = fmxj.findRecordsURL("Events", "Events", requests) ;
+fmxj.postQueryFMS(query, writeResults);
+function writeResults(js){
+	source=js;
+	var display = source.splice(0,500);
+	document.getElementById("example1").innerHTML=JSON.stringify(display, null, 4);
+};
+ + +
Apply Sort
+
+
+var sort = 	{ 
+				"property1" : "DateStart" ,
+				"sort1" : "descend" ,
+				"type1" : "date",
+				"property2" : "Resource" ,
+				"order2" : "ascend",
+				"type2" : "string"
+		 	} ;
+fmxj.sortObjects(sort, source) ;
+var display = filter.splice(0,500);
+document.getElementById("example1").innerHTML=JSON.stringify(display, null, 4);
+ + + + + +
+		
+
+
+
+ + + + + + \ No newline at end of file diff --git a/fmxj.js b/fmxj.js index 214d1ee..eb55e77 100755 --- a/fmxj.js +++ b/fmxj.js @@ -29,6 +29,7 @@ return { errorDescription: errorDescription, filterObjects: filterObjects, sortObjects: sortObjects, + nestObjects: nestObjects, } @@ -799,40 +800,42 @@ function sortObjects( sortOrder, source ) { //additonal predicates ban ce assigned as leftKey2, leftKey3, etc. function nestObjects( parentArray, childArray, childName, predicates) { - var nestTheseObjects = function(p,c){ - - var c = 1; + function nestTheseObjects(p,c){ + var n = 1; var ok = 1; - while ( predicates["parentKey" + c] ) { - var pv = p[predicates["parentKey" + c]]; - var cv = c[predicates["childKey" + c]]; + while ( predicates["parentKey" + n] ) { + var pv = p[predicates["parentKey" + n]]; + var cv = c[predicates["childKey" + n]]; if (pv===cv){ok++} - c++; + n++; }; - - if(c===ok&&c>1){ // all predicates match for this object, so we can nest. + if(n===ok&&n>1){ // all predicates match for this object, so we can nest. //does the childName already exist in this Parent? //if not, create it. if(!p[childName]){ p[childName]=[] }; - //push the child Object to the parent. p[childName].push(c); - }; //end object match + return true; + } }; - var ca = 0; - var pa = 0; + console.log(childArray.slice(0,10)); - for ( pa in parentArray ) { // outer loop for parents - - for ( ca in childArray ) { //inner loop for children - nestTheseObjects(parentArray[pa],childArray[ca]); + for (var pa in parentArray){ + var cc = []; + var i = 0; + var result = []; + for (var ca in childArray){ + result = nestTheseObjects(parentArray[pa],childArray[ca]); + if (result){cc.unshift(ca)} //mark this object for removal from child array. + }; + for (i in cc){ + childArray.splice(cc[i],1); //remove the child records that were nested from the childArray, so next pass a little shorter. }; }; - - + childArray=null; }; diff --git a/fmxjDemo.js b/fmxjDemo.js index 66d2041..5af6d5f 100644 --- a/fmxjDemo.js +++ b/fmxjDemo.js @@ -11,11 +11,12 @@ //They will be sent via POST to your PHP page, which will use them to authenticate to FMS //This is the SeedCode Test Server so be kind to it!! var relay = {"php":"fmxjRelay.php","server":"sc-fms13-fms.fmsdb.com","protocol":"https","port":"443"}; +//var relay = {"php":"fmxjRelay.php","server":"192.168.1.10"}; //***************FUNCTIONS********************* -var updateJSONLoop = function(resultElementID, requests, increment, sort){ +function updateJSONLoop(resultElementID, requests, increment, sort){ var sourceLoop = []; var max = increment; var skip = 0; @@ -24,15 +25,12 @@ var updateJSONLoop = function(resultElementID, requests, increment, sort){ var message = ""; var indent = 4; //JSON indent var q = ""; - var start = new Date().getTime(); var split = new Date().getTime(); - //callback functions for writing download. - var writeDownload = function(n){ + function writeDownload(n){ document.getElementById(resultElementID).innerHTML += "" + n + " bytes downloaded\n" ; } ; - function writeResult(js,utc){ var dlc = utc-split split = new Date().getTime(); @@ -73,19 +71,14 @@ var updateJSONLoop = function(resultElementID, requests, increment, sort){ cc + " milliseconds.\n"; document.getElementById(resultElementID).innerHTML = message + "\n\n" + displayJSON ; } - }; //end writeResult - var q = fmxj.findRecordsURL("Events","Events", requests , sort , max , skip ); - //clear values document.getElementById(resultElementID).innerHTML = "POST: " + q + "\n\n"; - - fmxj.postQueryFMS(q, writeResult, writeDownload, relay) ; - + fmxj.postQueryFMS(q, writeResult, writeDownload, relay); }; -var createMessage = function(js, utc, start, num){ +function createMessage(js, utc, start, num){ var end = new Date().getTime(); var dlc = utc - start; var cc = end - utc; @@ -95,25 +88,26 @@ var createMessage = function(js, utc, start, num){ var message = "" + total + " FileMaker records downloaded in " + dlc + " milliseconds\n" + "" + - "converted to JS objects in " + cc + " milliseconds\n" + + "FMPXMLRESULT converted to JS objects in " + cc + " milliseconds\n" + "Displaying the first " + num + " \"stringified\" objects.\n" + "" + (end - start) + " total milliseconds.\n\n"; return message; -} +}; -var createDisplay = function(js, utc, start, num){ +function createDisplay(js, utc, start, num){ var indent = 4; // JSON indent var display = JSON.stringify(js.slice(0,num), null, indent); var message = createMessage(js,utc,start,num); return message+display ; }; -var updateElement = function(elementID, value){ - document.getElementById(elementID).innerHTML = value; -} +function updateElement(id, value, append){ + if(append){document.getElementById(id).innerHTML += value;} + else{document.getElementById(id).innerHTML = value;} +}; -var editQuery = function(source){ +function editQuery(source){ var firstRecord = source[0]; var recid = firstRecord["-recid"]; var recordStatus = firstRecord["Status"] ; @@ -126,7 +120,11 @@ var editQuery = function(source){ edit["Status"] = newStatus ; edit["-modid"] = recordModId ; return fmxj.editRecordURL( "Events" , "Events" , edit ) ; -} +}; + +//***************Load Sidebar********************* + +updateElement("sb",''); //***************SAMPLE DATA********************* @@ -178,7 +176,7 @@ var sortObjectJs = var sortObject = { "field1" : "DateStart" , - "sort1" : "descend" , + "order1" : "descend" , "field2" : "id" , "order2" : "ascend" } ; diff --git a/gh.png b/gh.png new file mode 100644 index 0000000..aab4993 Binary files /dev/null and b/gh.png differ diff --git a/index.html b/index.html index c0b5479..356c302 100755 --- a/index.html +++ b/index.html @@ -6,1047 +6,109 @@   - - - - - + + + + + -
-
- - SeedCode Logo - -
- -
- fmxj.js - - - -
- -
A JavaScript approach to FileMaker Custom Web Publishing.
-
With fmxj.js and simple JavaScript Objects/JSON, you can... - -
- - - -
-
findRecordsURL(fileName, layoutName, requests [, sort, max, skip])
-
Create a complex xml -findquery from an array of javascript objects. These queries are then passed to the postQueryFMS function which returns the results as an array of JavaScript Objects (JSON).
-
-
- fileName -
- - Type: - - - String - -
- A String of the name of the hosted FileMaker file. -
-
-
- layoutName -
- - Type: - - - String - -
- A String of the name of the target layout in the specified hosted FileMaker file. -
- -
-
- requests -
- - Type: - - - Array of Objects - -
- An Array of Objects where each object represents a FileMaker Find Request -
-
-
-
- sort -
- - Type: - - - Object - -
- (Optional) An Object specifying sort fields and their sort order. Appropriate sort parameters will be appended to the query. Supported properties are field1-fieldn and order1-ordern (see example 1.3). -
-
-
- max -
- - Type: - - - Number - -
- (Optional) A Number specifying the maximimum number of parent records to be returned from FileMaker Server. Simmilar Fetch First in FileMaker's ExecuteSQL function. -
-
-
- skip -
- - Type: - - - Number - -
- (Optional) A Number specifying the number of records to skip in the found set before starting to return them. Simmilar Offset in FileMaker's ExecuteSQL function. -
-
-

- -
example 1.1: Two request find.
- - - -

-var requests =	[
-					{ "DateStart" : "<=2/28/2014" , "DateEnd" : ">=2/1/2014" } ,
-					{ "DateStart" : "2/1/2014...2/28/2014" }
-			   	] ;	
-var query = fmxj.findRecordsURL("Events", "Events", requests) ;
- - - -
- -
- -
-

-	
- -

-
example 1.2: Add additional criteria to requests object, so both requests have the Resource field equal to "Example C".
- - - -

-var requests =	[
-					{ "DateStart" : "<=2/28/2014" , "DateEnd" : ">=2/1/2014" },
-					{ "DateStart" : "2/1/2014...2/28/2014" }
-			   	];
-requests[0]["Resource"] = "Example C";
-requests[1]["Resource"] = "Example C";
-var query = fmxj.findRecordsURL("Events", "Events", requests);
- - - - -
- -
-
-

-	
-

-
example 1.3: Specify a sort order for the request by passing an object to the optional sort argument. Supprted order values are: ascend, descend and valuelist.
- - - -
-
-var requests =	[
-					{ "DateStart" : "<=2/28/2014" , "DateEnd" : ">=2/1/2014" } ,
-					{ "DateStart" : "2/1/2014...2/28/2014" }
-				] ;
-var sort =	{ 
-			"field1" : "DateStart" ,
-			"sort1" : "descend" ,
-			"field2" : "id" ,
-			"order2" : "ascend"
-			} ;
-var query = fmxj.findRecordsURL("Events", "Events", requests, sort) ;
- - - - -
- -
-
-

-	
-

-
example 1.4: Specify an Omit Request by setting the -omit property to 1.
- - - -
-
-var requests =	[
-					{ "DateStart" : "<=2/28/2014" , "DateEnd" : ">=2/1/2014" } ,
-					{ "DateStart" : "2/1/2014...2/28/2014" } ,
-					{ "Resources" : "Example B" , "-omit" : "1" }
-				] ;
-var query = fmxj.findRecordsURL("Events" ,"Events" ,requests) ;
- - - -
- -
-
-

-	
- - - -
-
postQueryFMS(query, callBackOnReady[, callBackOnDownload, phpRelay])
-
POSTS a query to FileMaker Server and returns the results as JavaScript Objects (JSON) for Callback.
-
-
- query -
- - Type: - - - String - -
- A String of the query to be POSTed to FileMaker Server. These Strings will typically be created by the fmxj URL finctions. -
-
-
- callBackOnReady -
- - Type: - - - Function - -
- A Function for handling the returned Array of Objects when ready. -
-
-
-
- callBackOnDownload -
- - Type: - - - Function - -
- (Optional) A Function for handling the on progress feedback for the POST. e.loaded is the only feedback property available from FileMaker Server and will be passed to the function if specified.
-
-
- phpRelay -
- - Type: - - - Object - -
- (Optional) An object specifying information about the FileMaker server and the phpRelay file to target. Use a PHP relay if your FileMaker Server is hosted remotely from your Web Server by adding the included fmxjRelay.php file to your WPE root directory. Then define the Object for this argument. Supported properties for the object: - -
-
- -

-
example 2.1: Create query and POST to FileMaker server, then return results as JavaScript objects. Stringified results are written to the pre via call back function.
- - - -
-
-var query = fmxj.findRecordsURL("Events", "Events", requests) ;
-fmxj.postQueryFMS(query, onReadyFunction, onProgressFunction) ;
- - - -
- -    Uses the currently selected xml query from above so you can try them all. -
-
-

-	
- -

-
example 2.2: Looping Ajax Calls. Use Max and Skip to increment your calls. Takes a little longer overall, but initial results are displayed much more quickly.
- - - -
-	
-	//sample function for updating pre via loop
-	var updateJSONLoop = function(resultElementID, requests, increment, sort){
-		var sourceLoop = [];
-		var max = increment;
-		var skip = 0;
-		var num = 0;
-		var total = 0;
-		var message = "";
-		var indent = 4; //JSON indent
-		//callback functions for writing download.
-		function writeDownload(n){
-			document.getElementById(resultElementID).innerHTML += "downloading results " + n + "\n" ;
-		} ;
-		function writeResult(js,utc){
-			sourceLoop = sourceLoop.concat(js);
-			total = sourceLoop.length;
-			num = js.length;
-			if (num===max) { 
-				//maximum records returned, which meanse we have more to get(probably)
-				//increment skip and run again
-				skip = skip + max;
-				var q = fmxj.findRecordsURL("Events","Events", requests, sort, max, skip);
-				fmxj.postQueryFMS(q,writeResult,null,relay) ;
-			};
-			//displaying these as collapsed, see fmxjDemo.js for full function.
-			//first time through write status and results
-			if (total===max) {*}
-			//last time through update results
-			else if (num!==max) {*}
-			//middle iterations update results
-			else {*}
-		}; //end writeResult
-	
-		var q = fmxj.findRecordsURL("Events","Events", requests , sort , max , skip  );
-		fmxj.postQueryFMS(q, writeResult, writeDownload, relay) ;
-	
-	}; //end updateJSONLoop() definition
-
-	var requests =	[
-						{ "DateStart" : "<=2/28/2014" , "DateEnd" : ">=2/1/2014" } ,
-						{ "DateStart" : "2/1/2014...2/28/2014" }
-					] ;
-		
-	var sortObject = 	{ 
-						  "field1" : "DateStart" ,
-						  "sort1" : "ascend" 
-						} ;
-					
-	updateJSONLoop("loopResult", requests, 500, sort); //loads 500 records at a time
-	
- - - - -
- -   - -
- -
-

-			
- - - - -

-
example 2.3: Errors returned as a simple one object array with the Filemaker error code and description:
- - - -
-
-var query = fmxj.findRecordsURL("Events", "ShmEvents", requests) ;
-fmxj.postQueryFMS(query, onReadyFunction) ;
- - - -
- +
+ SeedCode Logo
-
-
+

+
+

+
+ fmxj.js
- -

-
example 2.4: Portals on the target layout will be returned as nested arrays. Properties that represent related records will be prefixed with a "-" to make sure they don't collide with field names.
- -
-	
-	var requests =	[
-						{ "Status" : "Customer" }
-					] ;
-	var query = fmxj.findRecordsURL("Contacts", "Contacts", requests) ;
-	fmxj.postQueryFMS(query, onReadyFunction, onProgressFunction) ;
- -
- -   - -
- -
-

-	
- - - -

-
example 2.5: Using the phpRelay property. FileMaker Server location is seedcode.com and the name of the phpRelay file is the standard fmxjRelay.php file included with the library.
- - - -
-
-var relay = { "php" : "fmxjRelat.php", "server" : "seedcode.com" } ;
-// not using a call back for onDownload, so pass null for its argument
-fmxj.postQueryFMS ( query , onReadyFunction , null , relay ) ;
- - - - - -
-
editRecordURL(fileName, layoutName, editObj)
-
Create a FileMaker -edit or -new query url from a javascript object.
- -
-
- fileName -
- - Type: - - - String - -
- A String of the name of the hosted FileMaker file. -
-
-
- layoutName -
- - Type: - - - String - -
- A String of the name of the target layout in the specified hosted FileMaker file. -
- -
-
- editObject -
- - Type: - - - Object - -
- An Object that specifies the changes to be made to the FileMaker record. Property names represent the FileMaker field names. Specifying a -recid property will edit the specified record with an -edit query. Not specifying the -recid will create a new FileMaker record with a -new query. The -modid property can be optionally specified to ensure you are editing the most current version of that record. See more about using the -mod id in FileMaker's XML CWP Guide -
-
-

-
example 3.1: Read the first object in the array and update the corresponding FileMaker record. If the Status is Open, set it to Closed, and vice-versa. If server edit is succesful, then the full object/record will be returned and the array displayed above in example 2.1 will be updated.
- - - -
-
-// capture first object in the array so we can get the current values
-var firstRecord = source[0] ;
-var recid = firstRecord["-recid"] ;
-var modid = firstRecord["-modid"] ;
-var recordStatus = firstRecord["Status"] ;
-// create an edit object for this record
-var edit = { "-recid" : recid , "-modid" : modid } ;
-// toggle the value for Status
-if ( recordStatus==="Open" ) {
-	var newStatus = "Closed" ;
-	}
-else {
-	var newStatus = "Open" ;
-	} ;
-// update edit object with new status balue
-edit["Status"] = newStatus ;
-//POST query to edit object
-fmxj.postQueryFMS(edit, callBackFunction) ;
- - - - -
- -   - uses the data in example 2.1, so make sure that's populated first! -
-
-

+
+ a JavaScript approach to FileMaker Custom Web Publishing™
- -

-
example 3.2: Create a new FileMaker record by not specifying the -recid in the edit object. If the record creation is succesful on the server, the full object/record will be returned and added to the bottom of the array displayed above in example 2.1.
- - - -
-
-var newRecord =	{
-					"DateStart" : "02/25/2014" ,
-					"DateEnd" : "02/25/2014" ,
-					"Description" : "test" ,
-					"Status" : "Open" ,
-					"Summary" : "test summary ubi"
-				} ;
-var query = fmxj.editRecordURL("Events", "Events", newRecord) ;
-fmxj.postQueryFMS(query, callBackFunction) ;
- - - -
- -
-
-

-	
- - - -
-
deleteRecordURL(fileName, layoutName, recid)
-
Create a FileMaker -delete query url from record id.
- -
-
- fileName + +
+

+ gh LogoDownload on GitHub +

+

+

+ Do the data interchange work with JavaScript. +

+
    +
  • Build complex queries and perform HTPP POSTs to your FileMaker Server +
  • +
  • Return FileMaker parent and child records as JavaScript Objects/JSON +
  • +
  • Create, edit and delete FileMaker records with JavaScript objects +
  • +
  • Filter and sort Javascript objects locally with complex criteria. +
  • +
+

+ Query strings are created from JavaScript Objects and then sent as an HTTP POST to FileMaker's XML Web Publishing Engine. An XML FMPXMLRESULT is returned and converted into JavaScript Objects/JSON by fmxj.
+
+ HTTP POSTS can be done directly to the FileMaker Server's XML WPE or a simple PHP relay can be used to get around cross-domain issues and provide more authentication options. See more on the PHP relay in the postQueryFMS() function. +

+

+

Example

+
Create a HTTP request to the hosted filemaker file "Events". Target layout in the specified file is "Events". Query is created by the findRecordsURL() function and passed as the query argument to the postQueryFMS() function. The required handler for onreadystateexchange is defined as well as the optional onprogress handler.
- - Type: - - - String - -
- A String of the name of the hosted FileMaker file. -
-
-
- layoutName -
- - Type: - - - String - -
- A String of the name of the target layout in the specified hosted FileMaker file. -
- -
-
- recid -
- - Type: - - - Number - -
- A Number specifying the record id of the FileMaker record to be deleted. -
-
- -

-
example 4.1: Delete a FileMaker record based on the last object of the current array. If succesfully deleted on the server, the object will be removed from the current array. Error codes are always returned for the delete queries, with "0" meaning a succesful delete.
- - -
 
-// get the -recid of the last object in the array
-var recid = source[source.length-1]["-recid"] ;
-var query = fmxj.deleteRecordURL("Events", "Events", recid) ;
-fmxj.postQueryFMS(query, callBackFunction) ;
- - - -
- -   - deletes the last object in example 2.1 so make sure that's populated. -
-
-

-	
- - - -
-
filterObjects(filters, searchTypes, source)
-
Apply complex property filters to an array of objects using the request syntax.
-
-
- filters -
- - Type: - - - Array of Objects - -
- An Array of Objects where each object represents a FileMaker type Find Request, i.e. each property specified within an object represents an AND clause and each object on the array represents an OR clause. -
-
-
- searchTypes -
- - Type: - - - Object - -
- An Object specifying the standard search types to apply when filtering by the specified property. Supported search types are: -
    -
  • startswith
  • -
  • equals
  • -
  • contains
  • -
-
- -
-
- source -
- - Type: - - - Array of Objects - -
- The Array of Objects to be filtered -
-
- -

-
example 5.1: Filter the current array of objects based on a filter object made of FileMaker type find requests.
- - - -
-
-var requests = [
-				 {
-					 "id" : "E4B04F12-E006-4928-A1E0-0E86EDF5641C" , 
-					 "Status" : "Open" 
-				 } , 
-				 { "id" : "463BBEA9-404B-4979-8CC0-6F8F60EB0154" } ,
-				 { "id" : "8CDA64C4-643D-4A64-9336-83BEF07F0CF4" } ,
-			   ] ;
-var types = { "id" : "equals" , "Status" : "equals" } ;
-fmxj.filterObjects(requests, types, source) ;
- - - -
- -   - -   - uses the data from example 2.1 -
- -
-

-	
- - - -
-
sortObjects(sortOrder, source)
-
Sort an array of objects by multiple properties.
- -
-
- sortOrder -
- - Type: - - - Object - -
- An object specifying the properties to sort by, the order by which to sort them, and the data type to apply to the properties sort. -
    -
  • property1 - propertyn: property names to sort by in order, property 1 is sorted first, then property 2, etc.
  • -
  • order1 - ordern: ascend or descend, default is ascend if not specified
  • -
  • type1 - typen: supported type values are -
      -
    • string
    • -
    • number
    • -
    • date (use for timestamps)
    • -
    • time (of day)
    • -
    -
  • -
-
-
-
- source -
- - Type: - - - Array of Objects - -
- The Array of Objects to be sorted -
- +var requests = [ //create find requests for query. each object is request. + { "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 + +

 
-

-
example 6.1: Filter an array of objects by 1-n properties. Specify an object of properties and their sort orders. Also specify an object defining the data type to use to sort the specified properties. Supported data types are: String, Number, Date/Timestamp and Time. Unspecified properties are sorted as Strings.
- - -
-
-var sort = 	{ 
-				"property1" : "DateStart" ,
-				"sort1" : "descend" ,
-				"type1" : "date",
-				"property2" : "Resource" ,
-				"order2" : "ascend",
-				"type2" : "string"
-		 	} ;
-fmxj.sortObjects(sort, source) ;
- -
- -   - -
-
-

-
-
- - \ No newline at end of file diff --git a/libraries/prism.css b/libraries/prism.css index a40d111..ebfa496 100755 --- a/libraries/prism.css +++ b/libraries/prism.css @@ -14,7 +14,7 @@ pre[class*="language-"] { white-space: pre; word-spacing: normal; word-break: normal; - line-height: 1.5; + line-height: 1.4; -moz-tab-size: 4; -o-tab-size: 4; @@ -268,6 +268,6 @@ pre.line-numbers > code { display: block; padding-right: 0.7em; text-align: right; - line-height: 1.65; + line-height: 1.5; }