{"id":2495,"date":"2023-05-24T16:23:34","date_gmt":"2023-05-24T16:23:34","guid":{"rendered":"https:\/\/obo.zoj.mybluehost.me\/uncategorized\/scriptlet-call-server-scriptlet-in-page-level-script\/"},"modified":"2025-01-08T12:47:14","modified_gmt":"2025-01-08T12:47:14","slug":"scriptlet-call-server-scriptlet-in-page-level-script","status":"publish","type":"post","link":"https:\/\/ioninteractive.com\/ionacademy\/scriptlet-call-server-scriptlet-in-page-level-script\/","title":{"rendered":"Scriptlet: Call server scriptlet in page-level script"},"content":{"rendered":"<p>You can call a server scriptlet in page-level JavaScript by using the liveBallScriptlet function. Here\u2019s an example of what this line of code would look like in your page-level script:<\/p>\n<pre data-aura-rendered-by=\"75:426;a\">var result = liveballScriptlet(1, \"json\", 'data1=' + val1 + '&amp;data2=' + val2);<\/pre>\n<p>There are three parameters in this function:<\/p>\n<ol>\n<li>\u201c1\u201d represents the scriptlet id. To obtain the scriptlet id, navigate into the scriptlet editor in ion and view the URL in your browser window. The sscID parameter value is what you\u2019ll use as the first parameter in the liveBallScriptlet function.<\/li>\n<li>The second parameter defines the scriptlet response content type. For example,\u00a0you&#8217;d specify &#8220;json&#8221; as the content type if that is format the scriptlet will return.<\/li>\n<li>The third parameter is optional and\u00a0can\u00a0be leveraged to save data to the respondent prior to invoking the scriptlet.<\/li>\n<\/ol>\n<p>Let&#8217;s say you have a server scriptlet that calculates the sum of x and y that you seek to invoke from page-level script. For example:<\/p>\n<pre data-aura-rendered-by=\"75:426;a\">return respondent.x + respondent.y;<\/pre>\n<p>If this scriptlet&#8217;s id is 10, below is an example that passes x and y into the scriptlet to return the sum:<\/p>\n<pre data-aura-rendered-by=\"75:426;a\">var x = 1;\n\nvar y = 2;\n\nvar sum\u00a0= liveballScriptlet(10, \"text\/plain\", 'x=' + x + '&amp;y=' + y);<\/pre>\n<h2><\/h2>\n<h2>Server scriptlets for global sets of page rules &amp; advanced functionality<\/h2>\n<p>The power behind scriptlets is that you can write code for advanced, custom logic on your pages, store it centrally then plug it into creatives as needed!<\/p>\n<h4><strong>1. Add Scriptlet(s) to your Ion console<\/strong><\/h4>\n<p>You&#8217;ll create your scriptlet outside of Ion and then add it to the library.<\/p>\n<ol>\n<li>Navigate to Libraries &gt; Server Scriptlets<\/li>\n<li>Click green \u201cNew scriptlet category\u201d and give it a label<\/li>\n<li>Click green \u201cNew scriptlet\u201d button and label the scriptlet<\/li>\n<li>Paste or write custom Javascript into the scriptlet field\n<ul>\n<li>Note, use server-side Javascript (ECMAScript Version 3) to process data. The script should return a string or null.<\/li>\n<\/ul>\n<\/li>\n<li>Save<\/li>\n<\/ol>\n<h4><strong>2. Use rules to run your scriptlet(s) on your Ion pages<\/strong><\/h4>\n<p>Now that your custom Javascript has been added to your console, you can use rules to trigger the script and base actions off of its response.<\/p>\n<ol>\n<li>Navigate to the page you want your script to run on<\/li>\n<li>Click on the \u201crules\u201d button in the Page tab of your creative studio if you want the scriptlet to run on page load. If you would like the scriptlet to run on form submission, click the form\u2019s submit button and then open the rules editor from within the Edit tab of your creative studio.<\/li>\n<li>Add a rule condition to trigger the scriptlet. If you want the scriptlet to run unconditionally upon page load or form submission, select \u201cNo conditions required\u201d.<\/li>\n<li>Add the action labeled \u201cRun server scriptlet\u201d and select the scriptlet from the dropdown to the right.<\/li>\n<li>To base action(s) from the scriptlet\u2019s result(s), add a new rule with the condition being \u201cServer scriptlet result\u201d, select the scriptlet, and input the result value.<\/li>\n<li>Add an action to trigger based on the scriptlet\u2019s result value.<\/li>\n<\/ol>\n<p>Let\u2019s say you added a scriptlet to your console that calculates the respondent\u2019s age based on a birth date value they input on an ion form. You would run the scriptlet using form-level rules. You could drive respondents under eighteen, for example, to a page explaining they are not qualified to register.\u00a0Here\u2019s an example of what your rules might look like to accomplish this:<\/p>\n<div class=\"hs-callout-type-tip\" data-hs-callout-type=\"tip\">\n<p><strong>Condition<\/strong>: No conditions required<\/p>\n<p><strong>Action<\/strong>: Run server scriptlet &#8211; Age Calculation<\/p>\n<\/div>\n<div class=\"hs-callout-type-tip\" data-hs-callout-type=\"tip\">\n<p><strong>Condition<\/strong>: Server scriptlet result &#8211; Age Calculation &#8211; less than \u2013 19<\/p>\n<p><strong>Action<\/strong>: Go to next page \u2013 \u201cNot qualified to register\u201d<\/p>\n<\/div>\n<p><strong>Mobile detection Scriptlet<\/strong><\/p>\n<p>We&#8217;ve attached a server scriptlet to this post. This scriptlet identifies if the respondent is on a smartphone and assigns a true\/false value accordingly. Using rules, you can run the scriptlet and redirect respondents with a &#8220;true&#8221; value to a <a href=\"https:\/\/obo.zoj.mybluehost.me\/?p=3204\" target=\"_blank\" rel=\"noopener\">mobile-optimized page<\/a>. The scriptlet also saves the smartphone type into a data collection field and <a href=\"https:\/\/obo.zoj.mybluehost.me\/tag-tips-tagging-best-practices\/\" target=\"_blank\" rel=\"noopener\">tags<\/a> the respondent, giving you heightened visibility into the devices your smartphone audience uses.<\/p>\n<ul>\n<li><a href=\"https:\/\/f.hubspotusercontent30.net\/hubfs\/355484\/Mobile_Detection.rtf\" target=\"_blank\" rel=\"noopener\">Mobile_Detection.rtf<\/a><\/li>\n<\/ul>\n<div class=\"attachment-meta meta-group\"><\/div>\n<h2>External URL Map<\/h2>\n<p>Use a look-up table combined with a scriptlet to create an &#8220;External URL Map.&#8221; The sample below correlates respondent data to an external URL managed in the look-up table. An advanced rule would run on form submission, a link or a button that drives the respondent to the external site. The benefit of using an External URL map is that the links are managed in one place, so updates can roll-out globally. It also helps eliminate human error in appending dynamic URL parameters, since the links are managed in a single data source.<\/p>\n<div>\n<pre>\/\/ look-up URL based on respondent data and drive user to location<\/pre>\n<pre>var url = actionLookupValue(\"URL Map\", respondent.dataname);<\/pre>\n<pre>if(url != null){<\/pre>\n<pre>actionGoExternalUrl(url);<\/pre>\n<pre>}<\/pre>\n<pre>else {<\/pre>\n<pre>actionGoExternalURL(\"http:\/\/defaulturl.com\");<\/pre>\n<pre>}<\/pre>\n<\/div>\n<h2 data-pm-slice=\"1 1 [&quot;bullet_list&quot;,{},&quot;list_item&quot;,{}]\"><\/h2>\n<h2 data-pm-slice=\"1 1 [&quot;bullet_list&quot;,{},&quot;list_item&quot;,{}]\">Split data field values<\/h2>\n<p>Let&#8217;s say you collect phone number as a single field on your ion form but need to export this as three separate values. This scriptlet splits phone and saves it into three ion data collection fields.<\/p>\n<div>\n<pre>\/\/ splits and saves respondent.phone into three LiveBall data collection fields<\/pre>\n<pre>\/\/ respondent.phone must be collected in xxx-xxx-xxxx format for this example<\/pre>\n<pre>var phone = respondent.phone;<\/pre>\n<pre>var phoneParts = newArray();<\/pre>\n<pre>phoneParts = phone.split(\"-\");<\/pre>\n<pre>actionSaveData(\"area code\", phoneParts[0]); \/\/ \"areacode\" represents the data name to save value into<\/pre>\n<pre>actionSaveData(\"prefix\", phoneParts[1]); \/\/ \"prefix\" represents the data name to save value into<\/pre>\n<pre>actionSaveData(\"suffix\", phoneParts[2]); \/\/ \"suffix\" represents the data name to save value into<\/pre>\n<\/div>\n<h2 data-pm-slice=\"1 1 [&quot;bullet_list&quot;,{},&quot;list_item&quot;,{}]\"><\/h2>\n<h2 data-pm-slice=\"1 1 [&quot;bullet_list&quot;,{},&quot;list_item&quot;,{}]\">Format Phone Value<\/h2>\n<pre>\/\/returns xxx-xxx-xxxx format\nfunction ConvertPhone(phone) { \nvar formatted = phone.replace(\/[^0-9]+\/g, ''); \nif (formatted.length == 10){\nformatted = formatted.replace(\/^[2-9]d{2}-d{3}-d{4}$, '$1-$2-$3'\/); \n} \nelse {\nformatted = respondent.phone;\n}\nreturn formatted; \n}<\/pre>\n<p data-pm-slice=\"1 1 [&quot;bullet_list&quot;,{},&quot;list_item&quot;,{}]\">\n<h2 data-pm-slice=\"1 1 [&quot;bullet_list&quot;,{},&quot;list_item&quot;,{}]\">Calculate Lead&#8217;s Age<\/h2>\n<p>If &#8220;birthdate&#8221; is collected on your Ion form, calculate a lead&#8217;s age by running a scriptlet with advanced rules, behind the form. If leads need to meet an age requirement to be eligible for an offer, the scriptlet can return a true\/false value to confirm if the age requirement is met. Based on the scriptlet result, advanced rules can be used to control the user experience.<\/p>\n<pre>\/\/ Calculates age based on birthdate. \n\/\/ Returns true if lead is 18 or older.\n\/\/ Optionally save age into LiveBall data collection field. \n\nfunction Age(monthDob,dayDob,yearDob) {\n\u00a0 var now = new Date();\n\u00a0 var yearNow = now.getFullYear();\n\u00a0 var monthNow = now.getMonth() + 1;\n\u00a0 var dayNow = now.getDate();\n\n\u00a0 yearAge = yearNow - yearDob;\n\n\u00a0 if (monthNow &lt;= monthDob) {\n\u00a0\u00a0\u00a0 if (monthNow &lt; monthDob) {\n\u00a0\u00a0\u00a0\u00a0\u00a0 yearAge--;\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\n\u00a0\u00a0\u00a0 } \n\u00a0\u00a0\u00a0 else {\n\u00a0\u00a0\u00a0\u00a0\u00a0 if (dayNow &lt; dayDob) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 yearAge--;\n\u00a0\u00a0\u00a0\u00a0\u00a0 }\n\u00a0\u00a0\u00a0 }\n\u00a0 }\n\u00a0 \n\u00a0 return yearAge;\n}\n\n\/\/ form field birthday is formatted as mm\/dd\/yyyy\nvar date = respondent.reg_month + '\/' + respondent.reg_day + '\/' + respondent.reg_year;\nvar myDate = new Date(date);\nvar myAge = Age(myDate.getMonth() + 1, myDate.getDate(), myDate.getFullYear());\n\/\/actionSaveData(\"age\",yearAge.toString());\nif (myAge &gt; 17) {\n\u00a0\u00a0\u00a0 actionSaveData(\"ageRequirement\",\"true\");\n}\nelse {\n\u00a0\u00a0\u00a0 actionSaveData(\"ageRequirement\",\"false\");\n}<\/pre>\n<p data-pm-slice=\"1 1 [&quot;bullet_list&quot;,{},&quot;list_item&quot;,{}]\">\n<h2 data-pm-slice=\"1 1 [&quot;bullet_list&quot;,{},&quot;list_item&quot;,{}]\">Smartphone Sensing<\/h2>\n<p>This script may be copied into your Ion Server Scriptlet library and then used as a custom Ion advanced rule condition.<\/p>\n<pre>\/\/ return \"true\" if respondent is on a mobile device\n\/\/ save name of mobile device in \"MobileDevice\" data field\n\/\/ reference: http:\/\/www.zytrax.com\/tech\/web\/mobile%5Fids.html\n\nif (!respondent.useragent) {\n  return \"false\";  \/\/ if no user agent string, return \"false\"\n}\nvar ua = respondent.useragent;  \/\/ shortcut\n\nif (ua.indexOf(\"iPhone\") != -1) {\n  actionAssignTag(\"mobile\");\n  actionSaveData(\"MobileDevice\", \"iPhone\");\n  return \"true\";\n}\nif (ua.indexOf(\"BlackBerry\") != -1) {\n  actionAssignTag(\"mobile\");\n  actionSaveData(\"MobileDevice\", \"Blackberry\");\n  return \"true\";\n}\nif (ua.indexOf(\"Android\") != -1) {\n  actionAssignTag(\"mobile\");\n  actionSaveData(\"MobileDevice\", \"Android\");\n  return \"true\";\n}\nif (ua.indexOf(\"Windows Phone\") != -1) {\n  actionAssignTag(\"mobile\");\n  actionSaveData(\"MobileDevice\", \"Windows Phone\");\n  return \"true\";\n}\nif (ua.indexOf(\"Windows CE\") != -1 || ua.indexOf(\"Symbian\") != -1\n || ua.indexOf(\"Nokia\") != -1 || ua.indexOf(\"PDA\") != -1) {\n  assignTag(\"mobile\");\n  actionSaveData(\"MobileDevice\", \"Other\");\n  return \"true\";\n}\nreturn \"false\";  \/\/ if mobile device not detected<\/pre>\n<div>\n<p data-pm-slice=\"1 1 [&quot;bullet_list&quot;,{},&quot;list_item&quot;,{}]\">\n<\/div>\n<h2 data-pm-slice=\"1 1 [&quot;bullet_list&quot;,{},&quot;list_item&quot;,{}]\">Trim Spaces<\/h2>\n<p>Prior to data export, you can trim any leading or trailing spaces from a field by saving a scriptlet result with advanced rules or by leveraging a JavaScript field in the export format.<\/p>\n<pre>\/\/ return data collection value after trimming leading\/trailing spaces<\/pre>\n<pre>var trimField = respondent.dataname.replace(\/^s+|s+$\/g, \"\");<\/pre>\n<pre>return trimField;<\/pre>\n<p data-pm-slice=\"1 1 [&quot;bullet_list&quot;,{},&quot;list_item&quot;,{}]\">\n<p>To read more about server scriptlets, please check out the post &#8220;<a href=\"https:\/\/obo.zoj.mybluehost.me\/scriptlet-server-scriptlets-for-global-sets-of-page-rules-advanced-functionality\/\" target=\"_blank\" rel=\"noopener\">Scriptlet: Server scriptlets for global sets of page rules &amp; advanced functionality&#8221;.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>You can call a server scriptlet in page-level JavaScript by using the liveBallScriptlet function. Here\u2019s an example of what this line of code would look like in your page-level script: var result = liveballScriptlet(1, [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":5510,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","footnotes":""},"categories":[2082,2078],"tags":[2173,2190],"class_list":["post-2495","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scriptlets","category-the-advanced-capabilites","tag-advanced","tag-scriptlets"],"_links":{"self":[{"href":"https:\/\/ioninteractive.com\/ionacademy\/wp-json\/wp\/v2\/posts\/2495","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ioninteractive.com\/ionacademy\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ioninteractive.com\/ionacademy\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ioninteractive.com\/ionacademy\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/ioninteractive.com\/ionacademy\/wp-json\/wp\/v2\/comments?post=2495"}],"version-history":[{"count":4,"href":"https:\/\/ioninteractive.com\/ionacademy\/wp-json\/wp\/v2\/posts\/2495\/revisions"}],"predecessor-version":[{"id":7061,"href":"https:\/\/ioninteractive.com\/ionacademy\/wp-json\/wp\/v2\/posts\/2495\/revisions\/7061"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ioninteractive.com\/ionacademy\/wp-json\/wp\/v2\/media\/5510"}],"wp:attachment":[{"href":"https:\/\/ioninteractive.com\/ionacademy\/wp-json\/wp\/v2\/media?parent=2495"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ioninteractive.com\/ionacademy\/wp-json\/wp\/v2\/categories?post=2495"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ioninteractive.com\/ionacademy\/wp-json\/wp\/v2\/tags?post=2495"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}