settings.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. (function($){
  2. $.validator.addMethod( "alphanumeric", function( value, element ) {
  3. return this.optional( element ) || /^\w+$/i.test( value );
  4. }, "Letters, numbers, and underscores only please" );
  5. FLBuilder.registerModuleHelper('contact-form', {
  6. rules: {
  7. recaptcha_action: {
  8. alphanumeric: true
  9. }
  10. },
  11. init: function()
  12. {
  13. var form = $( '.fl-builder-settings' ),
  14. icon = form.find( 'input[name=btn_icon]' );
  15. icon.on( 'change', this._flipSettings );
  16. this._flipSettings();
  17. // Toggle reCAPTCHA display
  18. this._toggleReCaptcha();
  19. this._toggleAction();
  20. $( 'select[name=recaptcha_toggle]' ).on( 'change', $.proxy( this._toggleReCaptcha, this ) );
  21. $( 'select[name=recaptcha_toggle]' ).on( 'change', $.proxy( this._toggleAction, this ) );
  22. $( 'input[name=recaptcha_site_key]' ).on( 'change', $.proxy( this._toggleReCaptcha, this ) );
  23. $( 'select[name=recaptcha_validate_type]' ).on( 'change', $.proxy( this._toggleReCaptcha, this ) );
  24. $( 'select[name=recaptcha_theme]' ).on( 'change', $.proxy( this._toggleReCaptcha, this ) );
  25. $( 'input[name=btn_bg_color]' ).on( 'change', this._previewButtonBackground );
  26. // Render reCAPTCHA after layout rendered via AJAX
  27. if ( window.onLoadFLReCaptcha ) {
  28. $( FLBuilder._contentClass ).on( 'fl-builder.layout-rendered', onLoadFLReCaptcha );
  29. }
  30. },
  31. _flipSettings: function() {
  32. var form = $( '.fl-builder-settings' ),
  33. icon = form.find( 'input[name=btn_icon]' );
  34. if ( -1 !== icon.val().indexOf( 'fad fa') ) {
  35. $('#fl-field-btn_duo_color1').show();
  36. $('#fl-field-btn_duo_color2').show();
  37. } else {
  38. $('#fl-field-btn_duo_color1').hide();
  39. $('#fl-field-btn_duo_color2').hide();
  40. }
  41. },
  42. /**
  43. * Custom preview method for reCAPTCHA settings
  44. *
  45. * @param object event The event type of where this method been called
  46. * @since 1.9.5
  47. */
  48. _toggleReCaptcha: function(event)
  49. {
  50. var form = $( '.fl-builder-settings' ),
  51. nodeId = form.attr( 'data-node' ),
  52. toggle = form.find( 'select[name=recaptcha_toggle]' ),
  53. captchaKey = form.find( 'input[name=recaptcha_site_key]' ).val(),
  54. captType = form.find( 'select[name=recaptcha_validate_type]' ).val(),
  55. theme = form.find( 'select[name=recaptcha_theme]' ).val(),
  56. reCaptcha = $( '.fl-node-'+ nodeId ).find( '.fl-grecaptcha' ),
  57. reCaptchaId = nodeId +'-fl-grecaptcha',
  58. target = typeof event !== 'undefined' ? $(event.currentTarget) : null,
  59. inputEvent = target != null && typeof target.attr('name') !== typeof undefined && target.attr('name') === 'recaptcha_site_key',
  60. selectEvent = target != null && typeof target.attr('name') !== typeof undefined && target.attr('name') === 'recaptcha_toggle',
  61. typeEvent = target != null && typeof target.attr('name') !== typeof undefined && target.attr('name') === 'recaptcha_validate_type',
  62. themeEvent = target != null && typeof target.attr('name') !== typeof undefined && target.attr('name') === 'recaptcha_theme',
  63. scriptTag = $('<script>'),
  64. isRender = false;
  65. // Add library if not exists
  66. if ( 0 === $( 'script#g-recaptcha-api' ).length ) {
  67. scriptTag
  68. .attr('src', 'https://www.google.com/recaptcha/api.js?onload=onLoadFLReCaptcha&render=explicit')
  69. .attr('type', 'text/javascript')
  70. .attr('id', 'g-recaptcha-api')
  71. .attr('async', 'async')
  72. .attr('defer', 'defer')
  73. .appendTo('body');
  74. }
  75. if ( 'show' === toggle.val() && captchaKey.length ) {
  76. // reCAPTCHA is not yet exists
  77. if ( 0 === reCaptcha.length ) {
  78. isRender = true;
  79. }
  80. // If reCAPTCHA element exists, then reset reCAPTCHA if existing key does not matched with the input value
  81. else if ( ( inputEvent || selectEvent || typeEvent || themeEvent ) && ( reCaptcha.data('sitekey') != captchaKey || reCaptcha.data('validate') != captType || reCaptcha.data('theme') != theme )
  82. ) {
  83. reCaptcha.parent().remove();
  84. isRender = true;
  85. }
  86. else {
  87. reCaptcha.parent().show();
  88. }
  89. if ( isRender ) {
  90. this._renderReCaptcha( nodeId, reCaptchaId, captchaKey, captType, theme );
  91. }
  92. }
  93. else if ( 'show' === toggle.val() && captchaKey.length === 0 && reCaptcha.length > 0 ) {
  94. reCaptcha.parent().remove();
  95. }
  96. else if ( 'hide' === toggle.val() && reCaptcha.length > 0 ) {
  97. reCaptcha.parent().hide();
  98. }
  99. },
  100. /**
  101. * Render Google reCAPTCHA
  102. *
  103. * @param string nodeId The current node ID
  104. * @param string reCaptchaId The element ID to render reCAPTCHA
  105. * @param string reCaptchaKey The reCAPTCHA Key
  106. * @param string reCaptType Checkbox or invisible
  107. * @param string theme Light or dark
  108. * @since 1.9.5
  109. */
  110. _renderReCaptcha: function( nodeId, reCaptchaId, reCaptchaKey, reCaptType, theme )
  111. {
  112. var captchaField = $( '<div class="fl-input-group fl-recaptcha">' ),
  113. captchaElement = $( '<div id="'+ reCaptchaId +'" class="fl-grecaptcha">' ),
  114. widgetID;
  115. if ( 'invisible_v3' == reCaptType ) {
  116. reCaptType = 'invisible';
  117. }
  118. captchaElement.attr( 'data-sitekey', reCaptchaKey );
  119. captchaElement.attr( 'data-validate', reCaptType );
  120. captchaElement.attr( 'data-theme', theme );
  121. // Append recaptcha element to an appended element
  122. captchaField
  123. .html(captchaElement)
  124. .insertAfter( $('.fl-node-'+ nodeId ).find('.fl-contact-form > .fl-message') );
  125. widgetID = grecaptcha.render( reCaptchaId, {
  126. sitekey : reCaptchaKey,
  127. size : reCaptType,
  128. theme : theme
  129. });
  130. captchaElement.attr('data-widgetid', widgetID);
  131. },
  132. _toggleAction: function()
  133. {
  134. var form = $( '.fl-builder-settings' ),
  135. toggle = form.find( 'select[name=recaptcha_toggle]' ).val(),
  136. captType = form.find( 'select[name=recaptcha_validate_type]' ).val(),
  137. action = form.find('input[name=recaptcha_action]');
  138. if ( 'show' == toggle && 'invisible_v3' == captType ) {
  139. action.closest( 'tr' ).show();
  140. }
  141. else {
  142. action.closest( 'tr' ).hide();
  143. }
  144. },
  145. _previewButtonBackground: function( e ) {
  146. var preview = FLBuilder.preview,
  147. selector = preview.classes.node + ' a.fl-button, ' + preview.classes.node + ' a.fl-button:visited',
  148. form = $( '.fl-builder-settings:visible' ),
  149. style = form.find( 'select[name=btn_style]' ).val(),
  150. bgColor = form.find( 'input[name=btn_bg_color]' ).val();
  151. if ( 'flat' === style ) {
  152. if ( '' !== bgColor && bgColor.indexOf( 'rgb' ) < 0 ) {
  153. bgColor = '#' + bgColor;
  154. }
  155. preview.updateCSSRule( selector, 'background-color', bgColor );
  156. preview.updateCSSRule( selector, 'border-color', bgColor );
  157. } else {
  158. preview.delayPreview( e );
  159. }
  160. },
  161. });
  162. })(jQuery);