settings.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. (function($){
  2. FLBuilder.registerModuleHelper('pp-contact-form', {
  3. rules: {
  4. 'form_border_width': {
  5. number: true
  6. },
  7. 'form_border_radius': {
  8. number: true,
  9. },
  10. 'form_shadow_h': {
  11. number: true
  12. },
  13. 'form_shadow_v': {
  14. number: true
  15. },
  16. 'form_shadow_blur': {
  17. number: true
  18. },
  19. 'form_shadow_spread': {
  20. number: true
  21. },
  22. 'form_shadow_opacity': {
  23. number: true
  24. },
  25. 'form_padding': {
  26. number: true
  27. },
  28. 'title_margin': {
  29. number: true
  30. },
  31. 'description_margin': {
  32. number: true
  33. },
  34. 'input_field_height': {
  35. number: true
  36. },
  37. 'input_textarea_height': {
  38. number: true
  39. },
  40. 'input_field_background_opacity': {
  41. number: true
  42. },
  43. 'input_field_border_width': {
  44. number: true
  45. },
  46. 'input_field_border_radius': {
  47. number: true
  48. },
  49. 'input_field_padding': {
  50. number: true
  51. },
  52. 'input_field_margin': {
  53. number: true
  54. },
  55. 'button_width_size': {
  56. number: true
  57. },
  58. 'button_background_opacity': {
  59. number: true
  60. },
  61. 'button_border_width': {
  62. number: true
  63. },
  64. 'button_border_radius': {
  65. number: true
  66. },
  67. 'title_font_size': {
  68. number: true
  69. },
  70. 'title_line_height': {
  71. number: true
  72. },
  73. 'description_font_size': {
  74. number: true
  75. },
  76. 'description_line_height': {
  77. number: true
  78. },
  79. 'label_font_size': {
  80. number: true
  81. },
  82. 'input_font_size': {
  83. number: true
  84. },
  85. 'button_font_size': {
  86. number: true
  87. },
  88. 'validation_error_font_size': {
  89. number: true
  90. },
  91. 'success_message_font_size': {
  92. number: true
  93. }
  94. },
  95. init: function()
  96. {
  97. var form = $( '.fl-builder-settings' ),
  98. action = form.find( 'select[name=success_action]' ),
  99. self = this;
  100. this._actionChanged();
  101. action.on( 'change', this._actionChanged );
  102. this._keySourceChanged();
  103. $('input[name=recaptcha_key_source]').on( 'change', this._keySourceChanged );
  104. $('input[name=recaptcha_toggle]').on( 'change', function() {
  105. setTimeout( function() {
  106. self._keySourceChanged();
  107. }, 500 );
  108. } );
  109. // Toggle reCAPTCHA display
  110. this._toggleReCaptcha();
  111. // Toggle hCaptcha display
  112. this._toggleHCaptcha();
  113. $('input[name=recaptcha_toggle]').on( 'change', this._toggleReCaptcha.bind( this ) );
  114. $('input[name=hcaptcha_toggle]').on( 'change', this._toggleHCaptcha.bind( this ) );
  115. $('input[name=recaptcha_key_source]').on( 'change', this._toggleReCaptcha.bind( this ) );
  116. $('input[name=recaptcha_site_key]').on( 'change', this._toggleReCaptcha.bind( this ) );
  117. $('select[name=recaptcha_validate_type]').on( 'change', this._toggleReCaptcha.bind( this ) );
  118. $('input[name=recaptcha_theme]').on( 'change', this._toggleReCaptcha.bind( this ) );
  119. // Render reCAPTCHA after layout rendered via AJAX
  120. if (window.onLoadPPReCaptcha) {
  121. $(FLBuilder._contentClass).on('fl-builder.layout-rendered', onLoadPPReCaptcha);
  122. }
  123. // Render hCaptcha after layout rendered via AJAX
  124. if (window.onLoadPPHCaptcha) {
  125. $(FLBuilder._contentClass).on('fl-builder.layout-rendered', onLoadPPHCaptcha);
  126. }
  127. },
  128. _actionChanged: function()
  129. {
  130. var form = $( '.fl-builder-settings' ),
  131. action = form.find( 'select[name=success_action]' ).val(),
  132. url = form.find( 'input[name=success_url]' );
  133. url.rules('remove');
  134. if ( 'redirect' == action ) {
  135. url.rules( 'add', { required: true } );
  136. }
  137. },
  138. _keySourceChanged: function() {
  139. var form = $( '.fl-builder-settings' );
  140. if ( 'hide' === form.find('input[name=recaptcha_toggle]').val() ) {
  141. $('#fl-field-recaptcha_site_key').hide();
  142. $('#fl-field-recaptcha_secret_key').hide();
  143. return;
  144. }
  145. if ( 'default' === form.find('input[name=recaptcha_key_source]').val() ) {
  146. $('#fl-field-recaptcha_site_key').hide();
  147. $('#fl-field-recaptcha_secret_key').hide();
  148. } else {
  149. $('#fl-field-recaptcha_site_key').show();
  150. $('#fl-field-recaptcha_secret_key').show();
  151. }
  152. },
  153. /**
  154. * Custom preview method for reCAPTCHA settings
  155. *
  156. * @param object event The event type of where this method been called
  157. * @since 1.9.5
  158. */
  159. _toggleReCaptcha: function (event) {
  160. var form = $('.fl-builder-settings'),
  161. nodeId = form.attr('data-node'),
  162. toggle = form.find('input[name=recaptcha_toggle]'),
  163. captchaKey = form.find('input[name=recaptcha_site_key]').val(),
  164. captType = form.find('select[name=recaptcha_validate_type]').val(),
  165. theme = form.find('input[name=recaptcha_theme]').val(),
  166. reCaptcha = $('.fl-node-' + nodeId).find('.pp-grecaptcha'),
  167. reCaptchaId = nodeId + '-pp-grecaptcha',
  168. target = typeof event !== 'undefined' ? $(event.currentTarget) : null,
  169. inputEvent = target != null && typeof target.attr('name') !== typeof undefined && target.attr('name') === 'recaptcha_site_key',
  170. selectEvent = target != null && typeof target.attr('name') !== typeof undefined && target.attr('name') === 'recaptcha_toggle',
  171. typeEvent = target != null && typeof target.attr('name') !== typeof undefined && target.attr('name') === 'recaptcha_validate_type',
  172. themeEvent = target != null && typeof target.attr('name') !== typeof undefined && target.attr('name') === 'recaptcha_theme',
  173. scriptTag = $('<script>'),
  174. isRender = false;
  175. if ( 'undefined' !== typeof pp_recaptcha ) {
  176. if ( 'default' === form.find( 'input[name=recaptcha_key_source]' ).val() ) {
  177. captchaKey = pp_recaptcha.site_key;
  178. }
  179. }
  180. // Add library if not exists
  181. if (0 === $('script#g-recaptcha-api').length) {
  182. scriptTag
  183. .attr('src', 'https://www.google.com/recaptcha/api.js?onload=onLoadPPReCaptcha&render=explicit')
  184. .attr('type', 'text/javascript')
  185. .attr('id', 'g-recaptcha-api')
  186. .attr('async', 'async')
  187. .attr('defer', 'defer')
  188. .appendTo('body');
  189. }
  190. if ('show' === toggle.val() && captchaKey.length) {
  191. // reCAPTCHA is not yet exists
  192. if (0 === reCaptcha.length) {
  193. isRender = true;
  194. }
  195. // If reCAPTCHA element exists, then reset reCAPTCHA if existing key does not matched with the input value
  196. else if ((inputEvent || selectEvent || typeEvent || themeEvent) && (reCaptcha.data('sitekey') != captchaKey || reCaptcha.data('validate') != captType || reCaptcha.data('theme') != theme)
  197. ) {
  198. reCaptcha.parent().remove();
  199. isRender = true;
  200. }
  201. else {
  202. reCaptcha.parent().show();
  203. }
  204. if (isRender) {
  205. this._renderReCaptcha(nodeId, reCaptchaId, captchaKey, captType, theme);
  206. }
  207. }
  208. else if ('show' === toggle.val() && captchaKey.length === 0 && reCaptcha.length > 0) {
  209. reCaptcha.parent().remove();
  210. }
  211. else if ('hide' === toggle.val() && reCaptcha.length > 0) {
  212. reCaptcha.parent().hide();
  213. }
  214. },
  215. _toggleHCaptcha: function(event) {
  216. var form = $('.fl-builder-settings'),
  217. nodeId = form.attr('data-node'),
  218. toggle = form.find('input[name=hcaptcha_toggle]'),
  219. captchaKey = '',
  220. hCaptcha = $('.fl-node-' + nodeId).find('.h-captcha'),
  221. hCaptchaId = nodeId + '-pp-hcaptcha',
  222. target = typeof event !== 'undefined' ? $(event.currentTarget) : null,
  223. selectEvent = target != null && typeof target.attr('name') !== typeof undefined && target.attr('name') === 'hcaptcha_toggle',
  224. scriptTag = $('<script>'),
  225. isRender = false;
  226. if ( 'undefined' !== typeof pp_hcaptcha ) {
  227. captchaKey = pp_hcaptcha.site_key;
  228. }
  229. // Add API script if not exists
  230. if (0 === $('script#h-captcha-api').length) {
  231. scriptTag
  232. .attr('src', 'https://hcaptcha.com/1/api.js?onload=onLoadPPHCaptcha&render=explicit&recaptchacompat=off')
  233. .attr('type', 'text/javascript')
  234. .attr('id', 'h-captcha-api')
  235. .attr('async', 'async')
  236. .attr('defer', 'defer')
  237. .appendTo('body');
  238. }
  239. if ('show' === toggle.val() && captchaKey.length) {
  240. // hCaptcha is not yet exists
  241. if (0 === hCaptcha.length) {
  242. isRender = true;
  243. }
  244. // If hCaptcha element exists, then reset hCaptcha if existing key does not matched with the input value
  245. else if (selectEvent && hCaptcha.data('sitekey') != captchaKey ) {
  246. hCaptcha.parent().remove();
  247. isRender = true;
  248. }
  249. else {
  250. hCaptcha.parent().show();
  251. }
  252. if (isRender) {
  253. this._renderHCaptcha(nodeId, hCaptchaId, captchaKey);
  254. }
  255. }
  256. else if ('show' === toggle.val() && captchaKey.length === 0 && hCaptcha.length > 0) {
  257. hCaptcha.parent().remove();
  258. }
  259. else if ('hide' === toggle.val() && hCaptcha.length > 0) {
  260. hCaptcha.parent().hide();
  261. }
  262. },
  263. /**
  264. * Render Google reCAPTCHA
  265. *
  266. * @param string nodeId The current node ID
  267. * @param string reCaptchaId The element ID to render reCAPTCHA
  268. * @param string reCaptchaKey The reCAPTCHA Key
  269. * @param string reCaptType Checkbox or invisible
  270. * @param string theme Light or dark
  271. * @since 1.9.5
  272. */
  273. _renderReCaptcha: function (nodeId, reCaptchaId, reCaptchaKey, reCaptType, theme) {
  274. var captchaField = $('<div class="pp-input-group pp-recaptcha">'),
  275. captchaElement = $('<div id="' + reCaptchaId + '" class="pp-grecaptcha">'),
  276. widgetID;
  277. captchaElement.attr('data-sitekey', reCaptchaKey);
  278. captchaElement.attr('data-validate', reCaptType);
  279. captchaElement.attr('data-theme', theme);
  280. // Append recaptcha element to an appended element
  281. captchaField
  282. .html(captchaElement)
  283. .appendTo($('.fl-node-' + nodeId).find('.pp-contact-form-inner'));
  284. widgetID = grecaptcha.render(reCaptchaId, {
  285. sitekey: reCaptchaKey,
  286. size: reCaptType,
  287. theme: theme
  288. });
  289. captchaElement.attr('data-widgetid', widgetID);
  290. },
  291. /**
  292. * Render hCaptcha
  293. *
  294. * @param string nodeId The current node ID
  295. * @param string hCaptchaId The element ID to render hCaptcha
  296. * @param string hCaptchaKey The hCaptcha Key
  297. * @since 2.x
  298. */
  299. _renderHCaptcha: function (nodeId, hCaptchaId, hCaptchaKey) {
  300. var captchaField = $('<div class="pp-input-group pp-hcaptcha">'),
  301. captchaElement = $('<div id="' + hCaptchaId + '" class="h-captcha">'),
  302. widgetID;
  303. captchaElement.attr('data-sitekey', hCaptchaKey);
  304. // Append hCaptcha element to an appended element
  305. captchaField
  306. .html(captchaElement)
  307. .appendTo($('.fl-node-' + nodeId).find('.pp-contact-form-inner'));
  308. widgetID = hcaptcha.render(hCaptchaId, {
  309. sitekey: hCaptchaKey
  310. });
  311. captchaElement.attr('data-hcaptcha-widget-id', widgetID);
  312. }
  313. });
  314. })(jQuery);