I have a view model with remote validation enabled. In my view I also disabled OnKeyUp
$(function() {
$.validator.setDefaults({ onkeyup: false });
})
But if I focus on the text box, and move the focus to another control the remote validation is not fired at all.
Is there a way I can ask remote validation to fire when I configured it to onBlur and empty string?
In order to do this you would need to modify the jquery-validate.js file.
The code associated with remote validation:
remote: function(value, element, param) {
if ( this.optional(element) )
return "dependency-mismatch";
var previous = this.previousValue(element);
....
// ajax call
....
}
The first if block tests if the element is optional, which it will be unless a [Required] attribute has been applied to the property, or the property is a value type (I assume you property is typeof string) so the function returns and the code to make the ajax call is never reached. Note that even if you added the [Required] attribute, this code block would never called because required: is validated first and you would just get the "The XXX filed is required" message.
If you comment out the first if block, and focus out with an empty string, the remote validation will be fired.
Related
I am write a form with some fields, when all have valid then i am enable the submit button, do a service call on onSubmit() method.My issue is when i click on the submit button twice it do service call twice. Is there any directive for check form submit.
When you click on the submit button twice it will call the service two times just use one variable 'submit' boolean by default false.
reference: https://angular.io/guide/forms#submit-the-form-with-ngsubmit
onSubmit() {
if(this.submit) {
return;
}
this.submit = true;
this.serviceCall(); // got error set submit to false.
}
Consider the following ko bindings on a select element:
<select data-bind="value: valueObservable, options: optionsObservableArray,
optionsCaption: '[None] - this is an optional field'">
... given a viewmodel like the following:
function MyViewModel()
{
var self = this;
self.valueObservable = ko.observable();
self.optionsObservableArray = ko.observableArray();
// ajax call to load options
ko.computed(function() {
$.ajax(...)
.success(function(optionsResponse) {
self.optionsObservableArray(optionsResponse)
});
});
// ajax call to load data value
ko.computed(function() {
$.ajax(...)
.success(function(valueResponse) {
self.valueObservable(valueResponse)
});
});
}
What's weird about this is when the second (data) ajax call returns before the first (options) ajax call. Since the select element has an optionsCaption binding, here is what I believe is happening:
The data ajax call completes, setting the valueObservable to some value (like 6, abc, or some other non-falsy value).
Because there is only 1 option in the select element (due to the optionsCaption), and because the valueObservable is bound to it (via the value binding), this causes the valueObservable to be changed to undefined.
Finally, the optionsObservableArray completes and adds new option elements to the select, but by this time it is too late: The valueObservable is now wrapping an undefined value rather than the real data value returned from the first ajax call.
Question: What is the best way to work around this? Here is what I can think of:
Make the first ajax call run with async: false. This may slow page rendering.
Create a separate observable for binding to the select value (such as value: selectedValueObservable). Then subscribe to the optionsObservableArray and use the subscription to do something like self.selectedValueObservable(self.valueObservable()). This seems like a bandaid fix.
Render the select & options to the page before any javascript executes by sending the options data from the server (using MVC viewmodel). This makes it a little more difficult to deal with the options as an observableArray.
Update
There is another concern which I omitted from this question to simplify the example code. In actuality, this viewmodel is used to create an editable list of data items. So there is actually more than 1 dropdown list that gets rendered to the page. The data ajax call really returns an array, and its success function really sets an observableArray of complex items. Since the dropdown list options are reused in every inline form, it is placed on the $parent viewmodel and only loaded once. It is also difficult to pass the select options in a single ajax call because the data items are retrieved via WebAPI (which returns an IEnumerable, no room to send additional dropdown options).
I would suggest you to have one ajax call if it is possible. Make your controller to return complex object with array of objects and selected value:
// ajax call to load options and data value
ko.computed(function() {
$.ajax(...)
.success(function(response) {
self.optionsObservableArray(response.options);
self.valueObservable(response.value);
});
});
If it is impossible to merge two ajax call you can put calling of the second ajax to success callback of the first ajax:
// ajax call to load options
ko.computed(function() {
$.ajax(...)
.success(function(optionsResponse) {
self.optionsObservableArray(optionsResponse)
// ajax call to load data value
$.ajax(...)
.success(function(valueResponse) {
self.valueObservable(valueResponse)
});
});
});
Is there any reason not to make ajax call first and applyBinding on done ?
$.when(getOptions(), getData()).done(bind)
function getOptions() {
return $.ajax(...).success(vm.optionsObservableArray)
}
function getData() {
return $.ajax(...).success(vm.valueObservable)
}
function bind() {
ko.applyBindings(vm, document.getElementById('elem'))
}
In Javascript when I provide an onSubmit function, and I return 'false' from the function, it prevents the page from changing/reloading.
However in Dart the onSubmit.listen(...) function does not take a return type.
How do I stop the submit from sending the form data and changing/reloading the page?
Within the on.submit.add(...) callback, you will receive the Event as an argument. The Event object provides a preventDefault() method to prevent or cancel the default action.
It can be used as follows:
querySelector('#myForm').onSubmit.listen((Event e) {
// ... your code here
e.preventDefault();
});
I have a page written using .NET MVC. In the model for a Person called PersonModel I have this defined which requires the user to enter some text in the last name field:
<DisplayName("Last Name"), Required()> _
Public Property LastName() As String
Get
Return _LastName
End Get
Set(ByVal value As String)
_LastName = value
End Set
End Property
On the form, there is a checkbox that a user can check to do some other things. Is there a way, using JQuery preferablly, to change that Last Name field to be non-Required? If not using JQuery I am open to other suggestions but since I am doing alot of things when this check box is checked anyways, I was hoping I could add this logic in there. Here is some sample of what I am doing when this box is checked to demonstrate...
function doOwnerBusiness(event) {
if ($(this).is(':checked')) {
$('input[name="People_1__LastName"], label[for="People[1]_LastName"]').hide();
$("#People_1__LastName").hide();
$("#People_1__LastName").val("");
$("#People_1__LastName :input").attr('disabled', true);
$('input[name="People[1]_Suffix"], label[for="People[1]_Suffix"]').hide();
$("#People_1__Suffix").attr('disabled', true);
$('#People_1__Suffix')[0].selectedIndex = 0;
$('#People_1__Suffix').hide();
}
else {
$('input[name="People_1__LastName"], label[for="People[1]_LastName"]').show();
$("#People_1__LastName").show();
$('#People_1__LastName :input').attr('disabled', false);
}
}
Any help with this would be appreciated folks.
Thank you
William
Here is how I am declaring my checkbox and also part of the function where I am trying to check if it is checked or not...
<%=Html.CheckBoxFor(Function(model) model.FirstNameAsBusiness)%>
<%=Html.LabelFor(Function(model) model.FirstNameAsBusiness)%>
Function Nominate(ByVal m As NominationModel, ByVal captchaValid As Boolean) As ActionResult
If Not m.FirstNameAsBusiness.checked AndAlso String.IsNullOrEmpty(m.lastnametext) Then
ModelState.AddModelError("LastName", "Last Name field is required if you don't yada yada...")
Return View()
End If
Short answer: no. You can't bypass the DataAnnotation with a jQuery call.
Technically, the Last Name field isn't required. So, I'd remove the DataAnnotation for Required, and then on the backend, when the user submits the form, verify that a field value exists when the checkbox isn't checked. If the conditional doesn't pass, and an error to ModelState for that field, and redirect to the page. (apologies for the c#):
public ActionResult Index(HomeIndexModel form)
{
if (!form.Checked && string.IsNullOrEmpty(form.LastName))
{
ModelState.AddModelError("LastName", "Last Name field is required if you don't yada yada...");
return View();
}
//conditional requirement passed...
}
If you want to get a little fancier, you can check out this thread, though all of the suggestions here are also server-side:
ASP.NET MVC Conditional validation
I have a page with link http://localhost:8080/Test/Page.faces?id=asdasdasd
The page got 2 text field and one button, after user key in the details and click submit, it works well when you first time click the submit button, the id will return me the exact value, but if the user never enter the value and click submit the validation will be invoked and next click the button again the id return null? How to solve this problem anyone can help?
Yes, when the user clicks on the button, the browser does a new request to the server. That new request doesn't have the ?id=asdasdasd as part of it. The easiest solution I can think of is to store that value into a hidden text field on the page. You can use some javascript to populate the value.
So, if you have a <h:hidden id="idHidden" value="#{mybean.idHidden}"/> on your JSP, maybe some javascript like this:
<script type='text/javascript'>
function gup( name )
{
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null )
return "";
else
return results[1];
}
if(gup('id') != "") {
document.forms[0].idHidden.value = gup('id');
}
</script>
I haven't checked this code for errors, but the idea is the first time the page loads, the value of 'id' is stored in a hidden input field. That field is bound to your managed bean so the value is persisted across page refreshes. Just reference the id value stored on the bean (as idHidden in the example above) instead of the request parameter.
BTW: I stole the GUP function from http://www.netlobo.com/url_query_string_javascript.html
Nick