The XML file is rather simple so I just tried a little hack to parse it and extract the data you are looking for:
function getText(str, tag){
return str.substring(str.indexOf('<'+tag+'>')+tag.length+2, str.indexOf('</'+tag+'>'))
}
function parseIsbnRecord(url){
var xml = Utils.getTextFromUrl(url);
// cleanup xml
xml = xml.replace(/dc:/g,'').replace(/</g,'<').replace(/>/g,'>');
// extract recordData section
xml = xml.substring(xml.indexOf('<recordData>')+12, xml.indexOf('</recordData>'))
var data = [];
data['title'] = getText(xml, 'title');
data['creator'] = getText(xml, 'creator');
data['language'] = getText(xml, 'language');
data['publisher'] = getText(xml, 'publisher');
data['description'] = xml.match(/<description>([^<]+?)<\/description>/g);
for (n=0; n<data['description'].length; n++){
data['description'][n] = data['description'][n].replace(/<description>/g, '').replace(/<\/description>/g, '');
}
return data;
}
var url = 'https://iss.ndl.go.jp/api/sru?operation=searchRetrieve&query=isbn=9784334779146';
isbn_record = parseIsbnRecord(url);
console.log("Title: " + isbn_record['title']);
console.log("Creator: " + isbn_record['creator']);
console.log("Publisher: " + isbn_record['publisher']);
console.log("Language: " + isbn_record['language']);
console.log("Description: " + isbn_record['description']);
This generates following output:
Title: まよい道 : 新・吉原裏同心抄(一)
Creator: 佐伯泰英 著・文・その他
Publisher: 光文社
Language: jpn
Description: 判型 : 文庫,販売対象 : 一般,発行形態 : 文庫,内容 : 日本文学小説・物語,Cコード : 0193,ジャンル : 文庫
This code is very specific to this example ISBN number you provided. Most likey, other entries are very similar.
Cheers, Daniel
---
See https://lab.danielleu.com/tapformspro/ for scripts and tips&tricks
XML is hard because inherently the structure doesn’t easily map to a JavaScript object unlike JSON which is technically JavaScript. I looked for a JS native XML option but most seemed to suggest using the browser based DOM handlers which doesn’t work for Tap Forms and Apple’s JavaScriptCore.
What makes XML a challenge is that a single node in XML can have attributes as well as a value on top of being a nested structure as well which may have child values whose ordering is important but whose values is duplicated. Part of the heritage coming from SGML similar to the challenge with HTML.
For myself I have a set of PHP scripts that I use to bridge and give Tap Forms a JSON interface to work with. I use these for scraping web sites and converting values so that Tap Forms can work with a relatively clean JSON interface and the PHP scripts do the heavy lifting. This does mean you need to run a web server or similar service somewhere to make it work but it could help convert the XML into domain specific JSON for Tap Forms to consume.
No worries, happy to help! The Calculation field is pretty powerful, it has a bunch of built in functions for simple operations from the fx menu item.
The script field is a bit tricky however you can press the “play” button in the editor above the keyboard and it’ll run the script for you and you can see it’s output. There is also an option for a console log as well to see any debugging output. That enables you to do some iteration and testing as you go.

Attachments:
You must be
logged in to view attached files.
I was (not yet) aware about the fx in a calculation field, using version 5 since some days.
Refresh the recordset to get a value from a script field is tricky.
Thanks, Sam.
Calculation field exists on iOS, all of the field types are supported on both Mac and iOS. There’s a slight difference that on iOS it wraps the field name in square brackets so it’d look like `DAYS(
[Bought];TODAY())` or similar.



To your question:
1. That should return Hello
2. Script is triggered when a dependent field is changed or you refresh the field. On iOS, pull the record down to refresh the calculation manually.

Looking at your screenshot, you’re still missing the return statement at the end. You can do return days; as the last line of the method similar to the return 'Hello'; and it should work properly.
Attachments:
You must be
logged in to view attached files.
Hello, I’m a elder Tap Forms beginner.
Basically, I am using Tap Forms for manage of books.
Now, I am trying to write scripts for get books information from National Diet Library, Japan. Its output is XML format.
So, I need XML parsing, But I have no ideas to parse it. If Tap Forms Utils has utils.getXMLFromUrl() like a utils.getJSONUrl() or utils.getTextUrl(), it is useful.
Now, I am getting data using utils.getTextUrl() from site. and trying to parse XML data. I know there is XML parser in DOM. But I don’t know how to use it . The pioneers of Tap Forms Scripts, Would you please advice me good solution.
Regards. Kenji.
This was so long ago I can’t remember. I was still using OS9 it was that long ago. I don’t know why Apple ditched the database function when the introduced their iWorks suite, but they did. I bought Tap Forms at the beginning of the year to create a database (and did so, a very, very simple one) and I really haven’t spent a great deal of time getting to know it and its features. So, no, I have no screenshots.
I mentioned that I wanted to get a rough idea of how a general election would turn out given a certain likely swing and that is what I want to do again. Brendan has mentioned javascript (with which I am not at all familiar but I will check it out) so I shall see how I get on.
I would be surprised if Tap Forms didn’t have a ‘visual’ feature because when I was looking up an alternative to Appleworks database (and not wanting to spend a million on Filemaker) Tap Forms seemed to be getting most of the thumbs-up.
Hi Guys,
thanks so far, but I‘m not sure if we‘re talking about the same.
@Sam: This Built-In calculation field is not available on an iPhone !
I do not have this TypeError like you.
My screenshot shows a working method,
but I‘ve to use a script field and additional a „days“ field. What I‘d like to know if only a script field would be necessary to return the value ?
However, independent of the calculation of days,
that‘s a general question:
Assuming I have a simple script field:
function Script() {
return 'Hello';
}
Script();
1. shouldn’t the field value „Hello“ ?
2. when a script is triggered ?
Attachments:
You must be
logged in to view attached files.
Hi Patrick,
It sounds to me like what you would need is a Script field to do your if/then function. How’s your JavaScript? :)
You can create custom layouts in Tap Forms for Mac and colour your fields and values as you like.
The online user manual will have all that you need to know to get started with scripting in Tap Forms and for customizing layouts. You can access the manual from the Help menu.
Or click here for Scripting: https://www.tapforms.com/help-mac/5.3/en/topic/scripts
and here for layouts: https://www.tapforms.com/help-mac/5.3/en/topic/layouts
Thanks!
Brendan
var date_id = 'fld-db4e94e8bb1a46e7b886afba72a6f2df';
var bought = record.getFieldValue(date_id);
the above code should still trigger the script to execute when the date field changes values.
@sam, shouldn’t your example formula and script return a Number value?
The DAYS() function returns a Number. Your sample is returning Text.
The built in calculation field has a DAYS function that will give you the number of days between two dates and put it in the field.

The field ID detection code I think is triggered by getFieldValue('fld-etc') and using the var date_id syntax is tripping it up. It’s a little bit magical, I made my piece with it once I figured it out.
In the script editor when I run the code (though changing the field ID), I also get an error reporting TypeError: bought.getTime is not a function. (In 'bought.getTime()', 'bought.getTime' is undefined), column:46, line:4. Take out the getTime()
You don’t need the document.saveAllChanges() in this context, however in your example what you’re missing is a return days; at the end. Something like this I think would work better for you:
function calcdays() {
var today = new Date();
var bought = record.getFieldValue('fld-018ce5f02f7a4655be3e8f4377592f8b');
var days = today - bought;
var days = days / (1000*3600*24);
return days;
}
calcdays();
Here’s what that script looks like:

And in the default layout it looks like this:

That said once that script runs once, unless the “bought” field changes or your refresh the record then the script field value won’t change. There isn’t a way to automatically recalculate the value. This makes sense because Tap Forms is generating the value and saving it so that it doesn’t have to recalculate it every time. I suspect it also helps the search system by not having to regenerate the value when you search or sort too.
Another thread on age calculations is here: https://www.tapforms.com/forums/topic/age-calculations/
Attachments:
You must be
logged in to view attached files.
By using an additional number field that works:
function calcdays() {
var today = new Date();
var date_id = 'fld-db4e94e8bb1a46e7b886afba72a6f2df';
var bought = record.getFieldValue(date_id);
var days=today.getTime() - bought.getTime();
var days=days / (1000*3600*24);
var res = record.setFieldValue('fld-1737a7de921041b3a2d6d90340537480',days);
document.saveAllChanges();
}
calcdays();
But is the right way to use a script field ?
The general question I have:
Is such a script field able to have a output (value) directly ?
I believe script fields are only executed when a referenced field is changed. Because the default snippet doesn’t reference any fields, by default it doesn’t execute. Perhaps it could be considered a bug it doesn’t run on a new record creation, calculation fields run after creation.
What you could do is get the value of every field in the form, then a change will trigger the script every time those fields change. Alternatively you can manually refresh the record after creation and it’ll force the execution of every script and calculation field. The manual refresh is done by clicking the “Recalculate formulas” button at the bottom of your record, by selected “Record” > “Refresh Selected Record” when the record is selected in the layout or you can refresh your entire form by clicking “Refresh record list” under the list view area.
When running in the script editor, not everything is persisted. If you’re working with just a single record you’ll need to manually refresh it per the above but if you want the new script field code to apply to all of your existing records you should tick “Update records when saving” next to “Done”/”Save” buttons at the bottom right of the script editor.
I’ve not found this too problematic in practice, generally you’re picking up field values to work with and when those are populated the script should execute. What is your use case for running a script at form creation?
Hi Script Guys,
It’s more or less not a scripting question but how to use it in TapForms.
I do have a form with a script field, the script behind, just as simple example:
function Script() {
var hello_world = "Hello World";
return hello_world;
}
Script();
I assumed TapForms will set this field value to “Hello World” when a recordset is added or changed ?
But it’s empty, independant of which type of value (text, number, …)
The console log shows the value, but the field stays empty.
I additional added document.saveAllChanges; without any change.
Or is such a script field to be used only to set another field value by using recordset.setFieldValue(ID,value) ?
A long time ago, I created one checkbox to mark a particular state transition. A while later I ended up realising I need another checkbox because I messed up the first one and it could be ambiguous. So I decided to create a sort of flip flop where if you check one check box, it unchecks the other one.
To solve this I created a new script field that watched the two fields and then used itself to store the historic state of these fields as a serialised JSON value. When it runs, it checks the values and then sees if the field changing is different to what it’s seen previously. It then decides if it wants to toggle the checkbox and returns a JSON string with the current field states to be stored for next time.
To work this uses the Logger module and it also includes a reference to the Form Logger that I used to find the field ID of the script fields. The script is listed below:
// Import the logger and output the header.
document.getFormNamed('Script Manager').runScriptNamed('Logger');
logger.consoleHeader('Checkbox Flip Flop', 'Shipments');
// Get the current values of the check boxes.
var confirmed = record.getFieldValue('fld-2adb9ba8cdd048bbbb614d46b415ada5');
var unverified = record.getFieldValue('fld-abdb319b7db74fc39812a94778c433cc');
// Get the current value for this script field.
var oldState = record.getFieldValue('fld-2cd0296ea0884c8cba3640d8e33f010b');
// Create a copy of the new state for later.
var newState = {'confirmed': confirmed, 'unverified': unverified};
// This logs all of the script fields in the form using the form logger.
document.getFormNamed('Script Manager').runScriptNamed('Form Logger');
formLogger.dump({'type': ['script']});
// For debugging, log the various states.
logger.logMessage(<code>Current State: ${oldState}</code>);
logger.logMessage('New State: ' + JSON.stringify(newState));
// If we have an old state, we parse it out (otherwise it'd be null).
if (oldState)
{
oldState = JSON.parse(oldState);
}
else
{
oldState = { 'unverified': false, 'confirmed': false };
}
// If the old state was unverified and not confirmed and this is confirmed...
if (oldState['unverified'] && !oldState['confirmed'] && confirmed)
{
// Update the unverified field to not be set.
logger.logMessage('Unsetting unverified flag since confirmed flag toggled');
record.setFieldValue('fld-abdb319b7db74fc39812a94778c433cc', false, false);
}
// If the old state was confirmed and not verified and this is now unverified...
if (oldState['confirmed'] && !oldState['unverified'] && unverified)
{
// Update the confirmed field to not be set.
logger.logMessage('Unsetting confirmed flag since verified flag toggled');
record.setFieldValue('fld-2adb9ba8cdd048bbbb614d46b415ada5', false, false);
}
// Save the changes to the database.
document.saveAllChanges();
// Turn the newState into a JSON string.
var result = JSON.stringify(newState);
logger.consoleFooter('Checkbox Flip Flop', 'Shipments');
// Return the JSON string for the next execution run.
result;
There’s one issue with this in that the UI doesn’t seem to update properly when the checkbox state is changed. At some point I’ll turn it into a combobox and fix my fields but until then, I have some automation to keep my state consistent.