1 (function($, _
, undefined) {
8 fieldTpl
= _
.template($('#api-param-tpl').html()),
9 chainTpl
= _
.template($('#api-chain-tpl').html());
11 function addField(name
) {
12 $('#api-params').append($(fieldTpl({name
: name
|| ''})));
13 var $row
= $('tr:last-child', '#api-params');
14 $('.api-param-name', $row
).crmSelect2({data
: fields
}).change();
17 function addChainField() {
18 $('#api-params').append($(chainTpl({})));
19 var $row
= $('tr:last-child', '#api-params');
20 $('.api-chain-entity', $row
).crmSelect2({
21 formatSelection: function(item
) {
22 return '<span class="icon ui-icon-link"></span> API ' + item
.text
;
27 function getFields() {
31 // Special case for getfields
32 if (action
=== 'getfields') {
37 options
.api_action
= [];
38 $('option', '#api-action').each(function() {
40 options
.api_action
.push({key
: this.value
, value
: $(this).text()});
43 showFields(['api_action']);
46 CRM
.api3(entity
, 'getFields', {'api_action': action
, sequential
: 1, options
: {get_options
: 'all'}}).done(function(data
) {
47 _
.each(data
.values
, function(field
) {
51 text
: field
.title
|| field
.name
,
52 required
: field
['api.required'] || false
54 if (field
['api.required']) {
55 required
.push(field
.name
);
58 options
[field
.name
] = field
.options
;
66 function showFields(required
) {
69 text
: ts('Other') + '...'
71 $('#api-params').empty();
72 $('#api-param-buttons').show();
73 if (required
.length
) {
74 _
.each(required
, addField
);
80 function toggleOptions() {
81 var name
= $(this).val(),
82 $valField
= $(this).closest('tr').find('.api-param-value');
84 $valField
.val('').select2({
86 data
: _
.transform(options
[name
], function(result
, option
) {
87 result
.push({id
: option
.key
, text
: option
.value
});
91 else if ($valField
.data('select2')) {
92 $valField
.select2('destroy');
95 $(this).select2('destroy');
96 $(this).val('').focus();
101 * Attempt to parse a string into a value of the intended type
104 function evaluate(val
, makeArray
) {
109 var first
= val
.charAt(0),
110 last
= val
.slice(-1);
112 if (val
=== 'true' || val
=== 'false' || val
=== 'null' || !isNaN(val
)) {
116 if ((first
=== '"' || first
=== "'") && last
=== first
) {
117 return val
.slice(1, -1);
120 if ((first
=== '[' && last
=== ']') || (first
=== '{' && last
=== '}')) {
121 return eval('(' + val
+ ')');
123 // Transform csv to array
124 if (makeArray
&& val
.indexOf(',') > 0) {
125 return val
.split(',');
127 // Ok ok it's really a string
130 // If eval crashed return undefined
136 * Format value to look like php code
139 function phpFormat(val
) {
141 if ($.isPlainObject(val
)) {
142 $.each(val
, function(k
, v
) {
143 ret
+= (ret
? ',' : '') + "'" + k
+ "' => " + phpFormat(v
);
145 return 'array(' + ret
+ ')';
147 if ($.isArray(val
)) {
148 $.each(val
, function(k
, v
) {
149 ret
+= (ret
? ', ' : '') + phpFormat(v
);
151 return 'array(' + ret
+ ')';
153 return JSON
.stringify(val
);
157 * Smarty doesn't support array literals so we provide a stub
160 function smartyFormat(js
, key
) {
161 if (js
.indexOf('[') > -1 || js
.indexOf('{') > -1) {
162 return '$' + key
.replace(/[. -]/g, '_');
167 function buildParams(e
) {
169 $('.api-param-checkbox:checked').each(function() {
170 params
[this.name
] = 1;
172 $('input.api-param-value').each(function() {
173 var $row
= $(this).closest('tr'),
174 val
= evaluate($(this).val(), $(this).is('.select2-offscreen')),
175 name
= $('input.api-param-name', $row
).val(),
176 op
= $('select.api-param-op', $row
).val() || '=';
177 // Special syntax for api chaining
178 if (!name
&& $('select.api-chain-entity', $row
).val()) {
179 name
= 'api.' + $('select.api-chain-entity', $row
).val() + '.' + $('select.api-chain-action', $row
).val();
181 if (name
&& val
!== undefined) {
182 params
[name
] = op
=== '=' ? val
: {};
184 params
[name
][op
] = val
;
188 else if (name
&& (!e
|| e
.type
!== 'keyup')) {
192 if (entity
&& action
) {
197 function setError(el
) {
198 if (!$(el
).hasClass('crm-error')) {
200 .addClass('crm-error')
201 .attr('title', ts('Syntax error'))
202 .before('<div class="icon red-icon ui-icon-alert"/>');
206 function clearError(el
) {
208 .removeClass('crm-error')
210 .siblings('.ui-icon-alert').remove();
213 function formatQuery() {
215 smarty
: "{crmAPI var='result' entity='" + entity
+ "' action='" + action
+ "'",
216 php
: "$result = civicrm_api3('" + entity
+ "', '" + action
+ "'",
217 json
: "CRM.api3('" + entity
+ "', '" + action
+ "'",
218 rest
: CRM
.config
.resourceBase
+ "extern/rest.php?entity=" + entity
+ "&action=" + action
+ "&json=" + JSON
.stringify(params
) + "&api_key=yoursitekey&key=yourkey"
220 $.each(params
, function(key
, value
) {
221 var js
= JSON
.stringify(value
);
223 q
.php
+= ", array(\n";
228 q
.php
+= " '" + key
+ "' => " + phpFormat(value
) + ",\n";
229 q
.json
+= " \"" + key
+ '": ' + js
;
230 // FIXME: How to deal with complex values in smarty?
231 q
.smarty
+= ' ' + key
+ '=' + smartyFormat(js
, key
);
238 q
.json
+= ").done(function(result) {\n // do something\n});";
239 q
.smarty
+= "}\n{foreach from=$result.values item=" + entity
.toLowerCase() + "}\n {$" + entity
.toLowerCase() + ".some_field}\n{/foreach}";
240 if (action
.indexOf('get') < 0) {
241 q
.smarty
= '{* Smarty API only works with get actions *}';
243 $.each(q
, function(type
, val
) {
244 $('#api-' + type
).text(val
);
250 if (!entity
|| !action
) {
251 alert(ts('Select an entity & action.'));
254 if (action
.indexOf('get') < 0) {
255 var msg
= action
=== 'delete' ? ts('This will delete data from CiviCRM. Are you sure?') : ts('This will write to the database. Continue?');
256 CRM
.confirm({title
: ts('Confirm %1', {1: action
}), message
: msg
}).on('crmConfirm:yes', execute
);
263 $('#api-result').html('<div class="crm-loading-element"></div>');
265 url
: CRM
.url('civicrm/ajax/rest'),
270 json
: JSON
.stringify(params
)
272 type
: action
.indexOf('get') < 0 ? 'POST' : 'GET',
274 }).done(function(text
) {
275 $('#api-result').text(text
);
279 $(document
).ready(function() {
280 $('form#api-explorer')
281 .on('change', '#api-entity, #api-action', function() {
282 entity
= $('#api-entity').val();
283 action
= $('#api-action').val();
284 if (entity
&& action
) {
285 $('#api-params').html('<tr><td colspan="4" class="crm-loading-element"></td></tr>');
286 $('#api-params-table thead').show();
290 $('#api-params, #api-generated pre').empty();
291 $('#api-param-buttons, #api-params-table thead').hide();
294 .on('change keyup', 'input.api-param-checkbox, input.api-param-value, input.api-param-name, #api-params select', buildParams
)
295 .on('submit', submit
);
297 .on('change', '.api-param-name', toggleOptions
)
298 .on('click', '.api-param-remove', function(e
) {
300 $(this).closest('tr').remove();
303 $('#api-params-add').on('click', function(e
) {
307 $('#api-chain-add').on('click', function(e
) {
311 $('#api-entity').change();