Skip to content

Commit 8ff565e

Browse files
committed
Add multiple instance on one page support - fixed #11 request
1 parent bdfe4a3 commit 8ff565e

File tree

5 files changed

+180
-27
lines changed

5 files changed

+180
-27
lines changed

README.md

+68
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public class AccountsController : Controller
6767
```
6868

6969
### 4) Add client-side integration to your front-end
70+
if you need multiple instance on one page please skip to next header
7071

7172
Add the following code to your ``Views/Merchants/Register.cshtml``:
7273

@@ -79,6 +80,21 @@ Add the following code to your ``Views/Merchants/Register.cshtml``:
7980
}
8081
```
8182

83+
#### Add client-side integration to your front-end for explicit use or multiple instance
84+
introduced in `1.2.3` requested in #11
85+
```c#
86+
@ReCaptcha.GetExplictHtml("example1", @ViewBag.publicKey)
87+
88+
@ReCaptcha.GetExplictHtml("example2", @ViewBag.publicKey)
89+
90+
@ReCaptcha.GetExplictScript()
91+
92+
@if (ViewBag.RecaptchaLastErrors != null)
93+
{
94+
<div>Oops! Invalid reCAPTCHA =(</div>
95+
}
96+
```
97+
8298
## Done!
8399

84100

@@ -110,6 +126,58 @@ key | value | default | description
110126
`callback` | | | Optional. Your callback function that's executed when the user submits a successful CAPTCHA response. The user's response, g-recaptcha-response, will be the input for your callback function.
111127
`lang` | See [language codes](https://developers.google.com/recaptcha/docs/language) | | Optional. Forces the widget to render in a specific language. Auto-detects the user's language if unspecified.
112128
129+
### `@ReCaptcha.GetExplictHtml(...)`
130+
131+
For enabling multi captcha in one page. please check the example for [Explicit rendering for multiple widgets](https://developers.google.com/recaptcha/docs/display?hl=en#example)
132+
133+
simple use
134+
135+
``` razor
136+
@ReCaptcha.GetExplictHtml("id","site-key")
137+
```
138+
139+
#### Arguments
140+
141+
The synopsis for the `@ReCaptcha.GetExplictHtml` function is:
142+
143+
``` razor
144+
@ReCaptcha.GetExplictHtml(id, publicKey, [widgetRenderCallsArr], [theme], [type], [callback])
145+
```
146+
147+
##### ReCaptcha Parameter [reCaptcha doc](https://developers.google.com/recaptcha/docs/display)
148+
149+
key | value | default | description
150+
----|-------|---------|------------
151+
`id` | | | the recaptcha widget id. __required__ uniquely identifies the recaptcha widget
152+
`publicKey` | | | Your sitekey.
153+
`widgetRenderCallsArr` | | __recaptcha_widgetRenderCallsArr | js variable name for recaptcha render calls.
154+
`theme` | dark/light | light | Optional. The color theme of the widget.
155+
`type` | audio/image | image | Optional. The type of CAPTCHA to serve.
156+
`callback` | | | Optional. Your callback function that's executed when the user submits a successful CAPTCHA response. The user's response, g-recaptcha-response, will be the input for your callback function.
157+
158+
### `@ReCaptcha. GetExplictScript([lang], [load], [widgetRenderCallsArr])`
159+
160+
``` razor
161+
@ReCaptcha.GetExplictScript()
162+
```
163+
164+
#### Arguments
165+
166+
The synopsis for the `@ReCaptcha.GetExplictScript` function is:
167+
168+
``` razor
169+
@ReCaptcha.GetExplictScript([lang], [load], [widgetRenderCallsArr])
170+
```
171+
172+
##### ReCaptcha Parameter
173+
174+
key | value | default | description
175+
----|-------|---------|------------
176+
`lang` | See [language codes](https://developers.google.com/recaptcha/docs/language) | | Optional. Forces the widget to render in a specific language. Auto-detects the user's language if unspecified.
177+
`load` | | __recaptcha_onloadCallback | js variable name for recaptcha on load explicit call.
178+
`widgetRenderCallsArr` | | __recaptcha_widgetRenderCallsArr | js variable name for recaptcha render calls.
179+
180+
113181
### `@ReCaptcha.Validate(privateKey)`
114182

115183
see [recaptcha doc](https://developers.google.com/recaptcha/docs/verify)

reCaptcha.sln

+22-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio 2013
4-
VisualStudioVersion = 12.0.31101.0
3+
# Visual Studio 14
4+
VisualStudioVersion = 14.0.23107.0
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "reCaptcha", "reCaptcha\reCaptcha.csproj", "{E8178D2F-838E-450D-8CAA-7CF1DF483BC6}"
77
EndProject
@@ -14,6 +14,22 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{DA745D
1414
EndProject
1515
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "reCaptcha.test", "reCaptcha.test\reCaptcha.test.csproj", "{B2E1EEF7-F3BF-4711-BB96-C96238229339}"
1616
EndProject
17+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ProjectFiles", "ProjectFiles", "{E7144273-0C2D-496D-A1C0-79F53CB54680}"
18+
ProjectSection(SolutionItems) = preProject
19+
.gitignore = .gitignore
20+
.travis.yml = .travis.yml
21+
README.md = README.md
22+
EndProjectSection
23+
EndProject
24+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "reCaptcha.NuGet", "reCaptcha.NuGet\reCaptcha.NuGet.csproj", "{0451BAEF-DF2E-4B98-8644-94EE9415E389}"
25+
EndProject
26+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4C57DFA6-50EB-4229-B2AB-1B3A29590F29}"
27+
ProjectSection(SolutionItems) = preProject
28+
.gitignore = .gitignore
29+
.travis.yml = .travis.yml
30+
README.md = README.md
31+
EndProjectSection
32+
EndProject
1733
Global
1834
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1935
Debug|Any CPU = Debug|Any CPU
@@ -28,6 +44,10 @@ Global
2844
{B2E1EEF7-F3BF-4711-BB96-C96238229339}.Debug|Any CPU.Build.0 = Debug|Any CPU
2945
{B2E1EEF7-F3BF-4711-BB96-C96238229339}.Release|Any CPU.ActiveCfg = Release|Any CPU
3046
{B2E1EEF7-F3BF-4711-BB96-C96238229339}.Release|Any CPU.Build.0 = Release|Any CPU
47+
{0451BAEF-DF2E-4B98-8644-94EE9415E389}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
48+
{0451BAEF-DF2E-4B98-8644-94EE9415E389}.Debug|Any CPU.Build.0 = Debug|Any CPU
49+
{0451BAEF-DF2E-4B98-8644-94EE9415E389}.Release|Any CPU.ActiveCfg = Release|Any CPU
50+
{0451BAEF-DF2E-4B98-8644-94EE9415E389}.Release|Any CPU.Build.0 = Release|Any CPU
3151
EndGlobalSection
3252
GlobalSection(SolutionProperties) = preSolution
3353
HideSolutionNode = FALSE

reCaptcha/Properties/AssemblyInfo.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("1.1.3")]
36-
[assembly: AssemblyFileVersion("1.1.3")]
35+
[assembly: AssemblyVersion("1.2.3")]
36+
[assembly: AssemblyFileVersion("1.2.3")]

reCaptcha/ReCaptcha.cshtml

+86-22
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
@functions
1818
{
19+
private const string defaultOnloadCallback = "__recaptcha_onloadCallback";
20+
21+
private const string defaultWidgetRenderCallsArr = "__recaptcha_widgetRenderCallsArr";
22+
1923
private const string reCaptchaVerifyUrl = "https://www.google.com/recaptcha/api/siteverify";
2024

2125
private static readonly object ErrorCodesCacheKey = new object();
@@ -139,34 +143,94 @@
139143
*@
140144
@helper GetHtml(string publicKey = null, string theme = null, string type = null, string callback = null, string lang = null)
141145
{
142-
// Ms helper - old
143-
//ReCaptcha.GetHtml(Context, @publicKey)
144-
145-
// explicit call to recaptcha
146-
@*<script type="text/javascript">
147-
var onloadCallback = function() {
148-
grecaptcha.render('recaptcha_placeholder', {
149-
'sitekey': '@publicKey'
150-
});
151-
};
146+
if (String.IsNullOrEmpty(publicKey))
147+
{
148+
throw new ArgumentException("can't be null", "publicKey");
149+
}
152150

153-
</script>
151+
<script src="https://www.google.com/recaptcha/api.js?hl=@lang" async defer></script>
152+
<div class="g-recaptcha" data-sitekey="@publicKey" data-theme="@theme" data-type="@type" data-callback="@callback"></div>
153+
}
154154

155-
<div id="recaptcha_placeholder"></div>
155+
@**
156+
* return recaptcha explicit html
157+
* @see {@link https://developers.google.com/recaptcha/docs/display}
158+
* @param {string} id - the recaptcha widget id.
159+
* @param {string} publicKey - Your sitekey.
160+
* @param {string} widgetRenderCallsArr - js variable name for recaptcha render calls
161+
* @param {string} theme - dark/light light Optional. The color theme of the widget.
162+
* @param {string} type - audio/image image Optional. The type of CAPTCHA to serve.
163+
* @param {string} callback - Optional. Your callback function that's executed when the user submits a successful CAPTCHA response. The user's response, g-recaptcha-response, will be the input for your callback function.
164+
*@
165+
@helper GetExplictHtml(string id, string publicKey = null, string widgetRenderCallsArr = defaultWidgetRenderCallsArr, string theme = null, string type = null, string callback = null)
166+
{
156167

157-
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit&hl=@lang" async defer></script>
158-
*@
168+
if (String.IsNullOrEmpty(publicKey))
169+
{
170+
throw new ArgumentException("can't be null", "publicKey");
171+
}
159172

160-
if (String.IsNullOrEmpty(publicKey))
161-
{
162-
throw new ArgumentException("can't be null", "publicKey");
163-
}
173+
// build options
174+
var options = new
175+
{
176+
sitekey = publicKey,
177+
theme = theme,
178+
callback = callback,
179+
type = type
180+
};
164181

165-
<script src="https://www.google.com/recaptcha/api.js?hl=@lang" async defer></script>
166-
<div class="g-recaptcha" data-sitekey="@publicKey" data-theme="@theme" data-type="@type" data-callback="@callback"></div>
182+
var optionsJson = JsonConvert.SerializeObject(options);
183+
184+
var noEscapeOptionsJson = new HtmlString(optionsJson);
185+
186+
// add render call
187+
<script type="text/javascript">
188+
// create calls arr
189+
var @widgetRenderCallsArr = @widgetRenderCallsArr || [];
190+
191+
var arr = @widgetRenderCallsArr;
192+
193+
arr.push(function(){
194+
grecaptcha.render('@id', @noEscapeOptionsJson);
195+
});
196+
</script>
197+
198+
// recaptcha widget
199+
<div id="@id"></div>
167200
}
168201

169-
@helper GetJsRefresh()
202+
@**
203+
* return recaptcha explicit script html
204+
* @see {@link https://developers.google.com/recaptcha/docs/display}
205+
* @param {string} lang - {@link https://developers.google.com/recaptcha/docs/language}
206+
* @param {string} load - js variable name for recaptcha on load explicit call
207+
* @param {string} widgetRenderCallsArr - js variable name for recaptcha render calls
208+
*@
209+
@helper GetExplictScript(string lang = null, string load = defaultOnloadCallback, string widgetRenderCallsArr = defaultWidgetRenderCallsArr)
170210
{
171-
<text>grecaptcha.reset();</text>
211+
// define explicit callback
212+
<script type="text/javascript">
213+
var @load = function() {
214+
215+
var arr = @widgetRenderCallsArr || [];
216+
for (var i = 0; i < arr.length; i++) {
217+
arr[i]();
218+
}
219+
};
220+
</script>
221+
222+
// explicit call to recaptcha
223+
<script src="https://www.google.com/recaptcha/api.js?onload=@load&render=explicit&hl=@lang" async defer></script>
224+
}
225+
226+
@helper GetJsRefresh(string id = null)
227+
{
228+
if (string.IsNullOrEmpty(id))
229+
{
230+
<text>grecaptcha.reset();</text>
231+
}
232+
else
233+
{
234+
<text>grecaptcha.reset('@id');</text>
235+
}
172236
}

reCaptcha/reCaptcha.nuspec

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
<description>$description$</description>
1313
<tags>captcha google recaptcha asp.net mvc</tags>
1414
<releaseNotes>
15-
* Removed redundant dependency on Razor Generator - #9
15+
* Updated major version - but didn't broke the current interface - safe to update
16+
* Add multiple instance on one page support - #11
1617
</releaseNotes>
1718
</metadata>
1819

0 commit comments

Comments
 (0)