Recaptcha is ignored by ajax action - ajax

I'm using Primefaces, however I can't use their p:captcha component, because it can't be rendered/updated by Ajax.
So, I'm trying to use reCaptcha's Ajax Api to create it on the form dynamically, by using Recaptcha.create. Here's the code:
Recaptcha.create(/*public_code*/,
'captchadiv', {
tabindex : 1,
theme : "red",
callback : Recaptcha.focus_response_field
});
Captcha has been created, but it doesn't validate actions from ajax buttons, like p:commandButton. What am I doing wrong?

I'm using Primefaces, however I can't use their p:captcha component, because it can't be rendered/updated by Ajax.
False. The p:captcha element has an id attribute so it can be updated using AJAX. It also has a rendered attribute which can be set to true or false, yes even at runtime.
Captcha has been created, but it doesn't validate actions from ajax buttons, like p:commandButton. What am I doing wrong?
I'm guessing the captcha element you're rendering has no integration with JSF/PrimeFaces. ;-)
Why not use the PrimeFaces captcha element like this:
<div id="captchaWrapper">
<p:captcha rendered="captchaBean.rendered"/>
</div>
<p:commandButton value="render" action="#{captchaBean.render}"
update="captchaWrapper"/>
And have a backing bean like this:
public class CaptchaBean
{
//Getter/setter omitted
private boolean rendered;
public void render()
{
rendered = true;
}
}

Related

Update the data in View with AJAX not working

I have diffrent <a> tags that normally pass a parameter to an action using asp-route="". Now i want to use AJAX t do this. each tag is supposed to pass an ID that comes from the model chats when the page loads up. (asp-route-ChatID="#Model.ID").
How can I achieve this in AJAX and pass that parameter? I tried using Data-ajax-update and Data-ajax-url but these option arent even available in Intellisense. Here is the method that i want to call
public IActionResult Chat(string ChatID)
{
Chats userchats=new Chats(); // a class that holds chats
//selecting data from the database......
return View(userchats);//returns view with the model
}
here is the <a> tag that gets clicked and it needs to pass a specific ID that comes from the model
<a > View Chat </a>
here is the <div> that needs to be updated depending on what <a> is clicked
<div id="UpdateThis"> <!--show data that comes from the method ajax calls--> </div>
How can I implement ajax here with tag helpers or any other way?
Use PartialView instead of view if you want to update div.
public IActionResult Chat(string ChatID)
{
Chats userchats=new Chats(); // a class that holds chats
//selecting data from the database......
return PartialView(userchats);//returns view with the model
}
View
<a id="btnView" data-id="1">View Chat</a>
<div id="UpdateThis"></div>
<script>
$("#btnView").click(function () {
$.post('#Url.Action("Chat")', { ChatID: $(this).data("id") }).done(function (e) {
$("#UpdateThis").html(e);
})
});
</script>

How to only update JSF/Primefaces component value upon Ajax sucess, but do nothing on Ajax failure

I have a JSF front end using Primefaces 5.3 which updates fields dynamically using Ajax. The problem that I am having is that sometimes my Ajax calls fail (ex: server responds with a 500), but my front end is still changing. Essentially, I'm looking to prevent the change of the input field if my ajax fails. Stated differently, I only want the input field to change upon a successful Ajax response.
I'm fairly new to JSF, so I'm not sure how to handle this. In regular HTML/JS, I would have been able to store the value onclick and in my ajax error handler restored the value, but I don't know how to do this using the PF framework.
<div class="Container25">
<p:selectOneRadio id="grid" value="#{cc.attrs.answer.singleAnswer.codeValue}" layout="grid" columns="1" >
<f:selectItems value="#{cc.attrs.menuItems}"
var="item" itemLabel="#{msg[item.code]}" itemValue="#{item.code}" itemLabelEscaped="false"/>
<p:ajax event="change" listener="#{cc.attrs.onChange}" update="#{cc.attrs.update}" disabled="#{cc.attrs.onChange == null }" global="false" />
</p:selectOneRadio>
</div>
I've tried adding the resetValues attribute to the ajax component, but that hasn't helped. Additionally, I've tried adding some custom JS in my onstart handler, but it is undefined.
I figured there must be a simple JSF/PF way of doing this, but can't seem to find it.
How can I either prevent the input value to change until the Ajax call returns successfully (ie: only change the value in the onsuccess handler) or reset my original radio button selection in the event that my Ajax call fails? What do I need to put in my onerror handler to restore the pre-ajax state?
You can use Primefaces RemoteCommand component for an easy solution, just embed it in your form:
<p:remoteCommand name="revertSomeValues"
actionListener="#{relatedBean.revertValuesToDefaults}"
update="componentId" />
And at the bean side you can manipulate the model:
#Named
#ViewScoped
public class relatedBean implements Serializable {
Integer codeValue;
//other model attributes and methods...
public void revertValuesToDefaults() {
setCodeValue(0); //supposing 0 is the default value
//handle other model attributes if needed
}
}
Now you can set the onerror callback alike -> onerror="revertSomeValues()"
You can also update the components wtih Primefaces RequestContext programatically from your bean if needed:
RequestContext context = RequestContext.getCurrentInstance();
context.update("componentId");

Why unobtrusive MVC validations are not working in IE7 and IE8?

I have an application in ASP.NET MVC 3 using Razor. I have setup some data annotations on text boxes along with jQuery validation and unobtrusive validation.
The thing is, some fields have custom validation logic using plain old vanilla JavaScript like the following functions.
function Validation() {
var signUp = SignUpValidation();
var book = BookingValidation();
if (signUp && book) {
return true;
}
else
{
ShowErrorMessage();
return false;
}
}
function ShowErrorMessage()
{
$('span#ErrorMessage').html('These fields are required');
}
where SignUpValidation(), BookingValidation() are functions which
returns either true or false on basis of some other validation
logic.
This is my code for submit button.
#using (Html.BeginForm(MVC.Booking.Actions.AtWork(model: null), FormMethod.Post,
new {#onsubmit = "return Validation()" }))
{
#Html.Partial("_BookingView")
}
This approach is working in all browsers except IE-7/8.
I faced the same issue lately .. and worked out the following solution:
instead of giving your additional form validation (apart from the unobtrusive mvc 3 validation) as a separate/second submit handler in form "onsubmit" event, you should "inject" your additional validation function in the main unobtrusive validation process of mvc3.. let it take care of the rest.
Create a custom validation adaptor somewhere in your common javascript code/file:
(function ($) {
if($.validator && $.validator.unobtrusive) {
$.validator.unobtrusive.adapters.addBool("AdditionalFormValidation");
}
} (jQuery));
In your view file, where you have the form, add this code to create a new jquery validator method for the custom validator adaptor that you defined in your common file above:
(function ($) {
if ($.validator) {
$.validator.addMethod("AdditionalFormValidation", function (value, element) {
return Validation();
});
}
} (jQuery));
Here
- "AdditionalFormValidation" is the validator method name same as your custom validation adaptor.
- "Validation" is the name of your javascript function that takes care of your additional validation and returns a boolean result for validation successs or failure.
In your form, remove the "onsubmit" handler that you had supplied, add a invisible dummy text field to your form and apply the custom unobtrusive validation adaptor/rule that you created, as given below:
#using (Html.BeginForm(MVC.Booking.Actions.AtWork(model: null), FormMethod.Post))
{
#Html.Partial(MVC.Booking.Views._BookForAtWork)
<input type="text" style="visibility:hidden; width: 1px; height: 1px;" name="hiddenValidation" id="hiddenValidation" data-val="true" data-val-AdditionalFormValidation />
}
This solution worked like a charm for me. To me appears a cleaner solution as it injects the additional validation in the same unobtrusive validation flow of mvc3 rather than creating a second validation flow. Also it is inline to future improvement for creating custom data annotation (validations) for all the custom client side validation work.
You may try updating both your jQuery.Validate.min.js and jquery.validate.unobtrusive.min.js files to latest version...it could be that these files are old...I had the same issue some time back and fixed it by doing this update.

Lost: Getting a fully rendered view via Ajax in ASP.NET MVC3 / jQuery

All,
I am very new to MVC3 / jQuery combo and have been reading tutorials. While I kind of get the concept, razor syntax etc. I'm still a bit confused on how to implement a basic concept that I'm trying to.
I have a textarea and when someone enters some text into it and hits enter, I want to trigger a ajax call to the server with the content of the text area, and get back a fully formed HTML blurb that I can put in a div. Now as I understand in MVC3 this would be a view, so in a sense I'm rendering a view on the server and sending it back so I can put it in HTML.
Is this possible? Any examples that I can look up to see how this done? I know how to capture keystrokes, get the value etc., it's this partial rendering of a fully formed HTML via ajax that I'm struggling to understand.
Thanks,
You can do with jQuery. This is how it works. you listen for the keydown event of the text area and when there is a keydown, check what key it is.if it is enter key, then make a jQuery ajax post call to a server page (action method in your controller with the data).Save the data there to your tables and return the markup of what you want and return that. in your script load it to your relevant div.
HTML
//Load jQuery library in your page
<textarea id="txtComment" > </textarea>
<div id="divComment"></div>
Javascript
$(function(){
$("#txtComment").keydown(function (event) {
if (event.keyCode == 10 || event.keyCode == 13) {
var comment=$("#txtComment").val();
comment=encodeURIComponent(comment);
$.post("yourcontroller/actionmethod?data="+comment,function(response){
$("#divComment").html(response);
});
}
});
});
and your controller action method
public ActionResult actionmethod(string data)
{
//Do some sanitization on the data before saving.
// Call your method to save the data to your tables.
CommentViewModel objCommentVM=new CommentViewModel();
objCommentVM.Comment=data;
return View("PartialCommentView",objCommentVM);
}
You should have a ViewMolde class called "CommentViewModel" like this
public class CommentViewModel
{
public string Comment{ set; get; }
}
and you should have a View called PartialCommentView which is strongly typed to CommentViewModel
#model FlashRack.ViewModel.RackViewModel
#{
Layout = null;
}
<div>
#Model.Comment
</div>
If you are simply returning a string, instead of returning a View, you can simply return the string using Return Content("your string here") method as well. But i prefer returning the ViewModel via View because it is more scalable and clean approach to me.
Your action method will return the markup you have in your PartialCommentView with the data.
Keep in mind that you have to take care of the special characters and escaping them properly.

jQuery unobtrusive validation to validate part of a form

We have a ASP.NET MVC 3 application that uses unobtrusive jQuery validation. The page allows to add children objects to the model in the same go. The <form> contains a grid for the children, and some input fields for adding new children.
Simplified example with Issue as the Model and Subtasks as the children:
Issue.cshtml -> Defines the form and includes fields for the issue as well as its subtasks.
#model Issue
#using (Html.BeginForm("Create", "Issues", FormMethod.Post, new { id = "mainForm" })
{
#Html.TextBoxFor(model => model.Summary)
#Html.Partial("SubtaskFields", new Subtask())
#Html.Partial("SubtasksGrid", model.Subtasks)
}
SubtaskFields.cshtml:
#model Subtask
#Html.TextBoxFor(model => model.Summary)
<button id="add">Add</button>
SubtasksGrid.cshtml:
#model IEnumerable<Subtask>
<table>
#foreach (var subtask in Model)
{
<tr>
<td>
#subtask.Name
<input type="hidden" name="Subtasks[#subtask.Index].Name" value="#subtask.Name"/>
</td>
</tr>
}
</table>
The point is, when submitting the form, only the properties of the issue (Issue.Name, e.g.), plus the hidden fields for the children (Subtask.Name, e.g.) should be validated and submitted.
We have some javascript code that hooks on the "add" button, and adds a new subtask based on the values in the SubtaskFields.cshtml partial view. That script validates the input fields first. In order for this to work, we use the TextBoxFor etc. html helpers for the SubtaskFields.cshtml, too, rendering a dummy/default Subtask object (new Subtask()). Our javascript the uses $("#mainForm").validate().element(...) to validate the SubtaskFields before adding a new subtask.
The big problem with this approach is that the jQuery unobtrusive validation framework automatically hooks on the submit button and validates all fields within the form before submitting the form. I.e., even the subtask fields are validated. This does not make any sense. Say that the subtask name is mandatory (which means the user can only click on "add" if he has filled in a subtask name). But if the user does not click on "add", the values in the Subtask Fields don't have any meaning and can in particular be left blank. In this case, in our current setting, jQuery validation fails because a mandatory field was left blank.
How can this be solved?
This is what we've come up with:
Add an attribute to all subtask fields (which should not be validated when submitting the form), e.g. "data-val-ignore".
Set the ignore setting on the form's validator to "[data-val-ignore]"
For the add button, in order to validate the subtask fields (which are normally ignored), iterate over them, and for each field, remove the attribute, re-parse to genereate the rules, execute validation, add the attribute, parse one more time.
Ad 2:
$(document).ready(function () {
$.data($('form')[0], 'validator').settings.ignore = "[data-val-ignore]";
});
Ad 3:
$(allSubtaskFields).each(function() {
$(this).removeAttr("data-val-ignore");
$.validator.unobtrusive.parseElement(this, false);
if (!$("mainForm").validate().element($(this))) { result = false; }
$(this).attr("data-val-ignore", "true");
$.validator.unobtrusive.parseElement(this, false);
});
I would suggest moving #Html.Partial("SubtasksGrid", model.Subtasks) outside of your form, and either having it in a single separate form, or have the partial generate a form for each grid row.
This will address your validation problems with your main form, and should also permit you to simplify validation of each row in SubTasksGrid.
To validate part of the form, wrap the section or the controls you want to validate into a div with an #id or .class and do the following:
var validator = $("#myForm").validate();
var isValid = true;
$("myDivToBeValidated").find("*[data-val]").each(function (indx, elem) {
if (!validator.element(elem)) {
isValid = false;
}
});
//this part of form is valid however there might be some other invalid parts
if (isValid)
//do your action, like go to next step in a wizard or any other action
goToNextStep();
I hope it is clear, if not please leave a comment. For more info about jQuery validation plugin and element() function, check this
Looks like you are working against the MVC egine here.
I would use Editor templates and Display templates, EditorFor template for the stuff you wanna validate and post, and Display template for the stuff you dont wanna post and validate.. If you have a TextBoxFor in the display template make sure its binding property has no Required attribute, and if its a value type make it nullable.

Resources