JQuery Validation on dynamic controls MVC - javascript

I have a problem validating dynamic addes inputs on GridView. I have partial views and each partial view has its own GridView. On my _Layout I have all links to scripts like jquery.validation.min.s etc. GridView is wrapped in a form so I have form id. Function for appending new row to GridView:
<script type="text/javascript">
$(function () {
$(document).on('click', '.addCostObject', function () {
var existRowSave = $('.saveCostObject').length;
var existRowEdit = $('.updateCostObject').length;
if (existRowSave == 0 && existRowEdit == 0) {
$('#gridCostObject tbody').append('<tr>' +
'<td><img src="#Url.Content("~/Images/save_.png")" /> <img src="#Url.Content("~/Images/save_cancel.png")" /></td>' +
'<td></td>' +
'<td><input type="text" name=\'costObject\' id=\'costObjectName\' class=\'costObjectNameClass\' placeholder=\'Cost Object Type\' data-val="true" data-val-required="This field is required"/></td>' +
'<td><input type="text" name=\'objectIdName\' id=\'objectId\' class=\'objectIdClass\' placeholder=\'Object ID\' data-val="true" data-val-required="This field is required"/></td>' +
'</tr>');
}
else {
alert('Save/Update or Cancel your previous record!');
}
})
event.stopImmediatePropagation();
})
At the end of my view I have a script for vaildating and appending rules:
<script type="text/javascript">
$(function() {
$("#gridCostObject").validate("add", {
rules: {
costObject: {
required: true
},
objectIdName: {
required: true,
digits: true
}
},
messages: {
objectIdName: {
digits: "Object id contains only digits"
}
}
})
})
At the save click, debugger always says that object form does not have 'valid'. I've tried putting my script everywhere in my view and trying all possible combination so far. What am I doing wrong?

$.validator.unobtrusive.parse('#yourFormSelector')
should help :)
It reinitializes the validation for your form - after that, the method will be available for your newly loaded elements

Related

JQuery Validate Filesize in Multidimensional Array Dynamically

I tried using jquery validate but i've spent more than 4 hours to search how to solve my problem but couldn't find it. The problem is when I tried using jquery validate for filesize in multidimensional array, it doesn't work. It can still submit the form and not showing the error message.
Here is it my field
var numberIncr = 1;
$('#add-berkas').click(function () {
var box_html = $('<div class="text-box form-group row">\n' +
' <div class="col-sm-8">\n' +
' <input type="text" name="berkas['+numberIncr+'][nama]" placeholder="Nama File" class="form-control" required>\n' +
' </div>\n' +
' <div class="col-sm-4">\n' +
' <input type="file" name="berkas['+numberIncr+'][file]" id="berkasfile'+numberIncr+'" accept="application/pdf" required/>\n' +
' <button id="remove-berkas" class="btn btn-sm btn-danger remove-box" type="button"><i class="fa fa-trash"></i></button>\n' +
' </div>\n' +
' </div>');
$('.text-box:last').after(box_html);
box_html.fadeIn('slow');
numberIncr++;
});
And this is the validate
$.validator.addMethod('filesize', function (value, element, param) {
return this.optional(element) || (element.files[0].size <= param)
}, 'File size must be less than {0}');
var berkas = $('input[name^="berkas"]');
berkas.filter('input[name$="[file]"]').each(function() {
$(this).rules("add", {
extension: "pdf", filesize:1048576,
messages: "Berkas must be PDF and less than 1MB"
});
});
$("#form").validate({
rules: {
surat: {extension: "pdf", filesize: 1048576, },
},
messages: {
surat: "Surat must be PDF and less than 1MB",
},
errorPlacement: function(error,element){
showErrorMessage(error.text());
},
submitHandler: function(form) {
form.submit();
},
highlight: function(element, errorClass) {
return false;
}
});
Your problem is caused by presumably only calling this code once on page load, when the fields don't yet exist...
berkas.filter('input[name$="[file]"]').each(function() {
$(this).rules("add", {
extension: "pdf", filesize:1048576,
messages: "Berkas must be PDF and less than 1MB"
});
});
There are no matching fields at the time you call this code. The whole point of this method is for you to dynamically add the rules after you create each field.
You must call it immediately after adding a new field. Put it inside the click handler near the bottom.
var numberIncr = 1;
$('#add-berkas').click(function () {
var box_html = $('<div class="text-box form-group row">\n' +
.....
' </div>');
$('.text-box:last').after(box_html);
box_html.fadeIn('slow');
// add rules to new field here
$('[name="berkas[' + numberIncr + '][file]"]').rules("add", {
extension: "pdf", filesize:1048576,
messages: "Berkas must be PDF and less than 1MB"
});
numberIncr++;
});
You wouldn't need an .each() since you only create one field on each click. Just target the new field and add the rule.

JQuery validation works only on debug modus

I have an empty form and a dropdown list, where on each click, different elements will be attached to the form. I called JQuery validate() once to initialize the validator and defined the validation rules everytime the form is filled up using rules.add().
The required validation worked if I type something in the form, erase it, and click submit. But if I don't give any inputs and immediately click submit, the form don't give an error message saying the inputs are required. It worked only when I set a breakpoint in Chrome.
Did I miss something?
ASPX page
<div id="divMenuQuery">
<div id="divQueryDDL"></div>
<div id="divQueryControls">
<form id="formQuery" />
</div>
<input type="button" id="btnExecuteQuery" runat="server" value="Execute" />
</div>
JS - The example below is only for textbox, but it happens for all HTML controls (DDL, Listbox, ...)
function _init() {
$form = $("#formQuery");
_createDDL(); // creates DDL and registers event handler below
}
function _onChangeDDL() {
var selectedTheme = $(this).val;
$form.validate();
$.each(selectedTheme.Controls, function (index, control) {
_buildControl(index, control);
}
}
function _buildControl(control) {
switch (control.Type) {
case Gon.Control.textBox:
_createTextBox(control);
break;
default:
break;
}
}
function _createTextBox(control) {
var $textBox = $("<input>");
$textBox.attr({
id: control.UniqueID,
name: control.UniqueID,
value: ""
}).appendTo($form);
$textBox.rules("add", {
required: true,
messages: {
required: "This field is required"
}
});
}
function _onClickExecute() {
var numErrors = $form.validate().numberOfInvalids(); // always gives 0
var formNodes = $form.serializeArray();
if (numErrors == 0 && $form.valid()) { // .valid() always gives true
_showQueryResults(formNodes);
}
}
Here is the rendered HTML page:

Adding validation to auto complete .each

I am trying to add validation check on this auto complete, however for some reason because its in an each() block it's causing me so many problems.
Full code:
<input type="text" class="productOptionSerialNumber" value="#opt.SerialNumber" data-part-num="#opt.PartNumber" />
$(".productOptionSerialNumber").each(function () {
var partNum = $(this).attr("data-part-num");
$(this).autocomplete({
source: "#Url.Action("SerialPartNumStockSiteAutoComplete", "Ajax")?stocksitenum=LW&model=" + $("#Form_Prod_Num").val() + "&partnum=" + partNum + "&callnum=" + $("#Form_Call_Num").val(),
minlength: 2,
delay: 300,
})
});
For this .productOptionSerialNumber function i cannot do a validation.
i have a working example which has worked before (look below) but with this particular function it doesn't validate, i have tried to add it the same way i did before, but no luck.
Working:
$(document).ready(function () {
//$('input[name="Form.InstallType"]').on('change', function() {
var val = $('input[name="Form.InstallType"]:checked').val();
if (val == '1') {
var validOptions = "#Url.Action("SerialProdNumStockSiteAutoComplete", "Ajax")?stocksitenum=LW&model=" + $("#Form_Prod_Num").val();
previousValue = "";
$('#abc').autocomplete({
autoFocus: true,
source: validOptions,
}).change(function(){
var source = validOptions;
var found = $('.ui-autocomplete li').text().search(source);
console.debug('found:' + found);
var val = $('input[name="Form.InstallType"]:checked').val();
if (found < 0 && val === '1') {
$(this).val('');
alert("You must select a value from the auto complete list!");
}
});
}
});
So if I don't choose from auto complete I get an alert. I am trying to implement this to the first part of code but because its in a .each and .attr it's not liking it this way.
Any ideas
Without additional information I don't know what kind of problems you are experiencing with the each() loop, however what you are trying to accomplish is certainly do-able.
Here is an example, hopefully it will help you fill in anything you are missing on your end.
HTML
<label>productOption aaa:</label>
<input type="text" class="productOptionSerialNumber" value="" data-part-num="aaa" />
<br />
<br />
<label>productOption bbb:</label>
<input type="text" class="productOptionSerialNumber" value="" data-part-num="bbb" />
<br />
<br />
<label>productOption ccc:</label>
<input type="text" class="productOptionSerialNumber" value="" data-part-num="ccc" />
Jquery
var dataFromURL = {
'aaa':['What','Is','Up'],
'bbb':['Nothing','Much','Bro man'],
'ccc':['Clown','Question','Bro schmoe']
}
$(document).ready(function(){
$(".productOptionSerialNumber").each(function () {
var partNum = $(this).attr("data-part-num");
$(this).autocomplete({
source: dataFromURL[partNum],
minlength: 2,
delay: 300,
}).change(function(){
var data = $(this).autocomplete( "option" ).source;
var found = data.indexOf($(this).val());
if (found < 0) {
alert("You must select a value from the auto complete list!");
$(this).val('');
}
});
});
});
Fiddle Example
If there isn't specifically a reason it needs to only execute after autocomplete (i.e. validation can occur whenever there is a change -- which, from my understanding is what occurs in the old, working code), you can still bind your validation to $(this).
Also,is there a reason you removed .change() from the new code?
If the reason is because you can't apply the validation to everything in the each statement, you need to check for a unique selector before binding the validation (typically an ID, but I see that there isn't one).
This code code does what I described. It uses ID as a unique selector. If adding an ID to the input tag is not an option, you'll need to find a different one.
$(".productOptionSerialNumber").each(function () {
$(this).autocomplete({
source: "#Url.Action("SerialPartNumStockSiteAutoComplete", "Ajax")?stocksitenum=LW&model=" + $("#Form_Prod_Num").val() + "&partnum=" + partNum + "&callnum=" + $("#Form_Call_Num").val(),
minlength: 2,
delay: 300,
});
if ($(this).attr('id') == "thisid")
{
$(this).bind('input propertychange',function(){
alert('this code executed because the input box changed');
});
}
});

dynamically add, validate and remove sets of form fields

I'd like to create a webpage where the user can add and remove sets of form fields by means of one add button and remove buttons related to the set to be removed. Entered values will be checked by means jquery validate, for which rules are added dynamically as well. pls see an an simplified example below of my targeted form:
What is a good structure of javascript code for adding, removing and validate sets of forms fields? I googled -also on this site- and there are many javascript examples for adding sets of formfields. I like the example I found at view-source:http://www.coldfusionjedi.com/demos/jqueryvalidation/testadd.cfm, which uses a form template. But I struggle in particular with the javascript coding for the removing buttons..(which are not in the example)
my targeted (simplified) form (template with 1 set of 3 formfields):
<form name="myForm" id="myForm" method="post" action="">
<input id="name1" name="name1" />
<input id="email1" name="email1" />
<input id="phone1" name="phone1" />
<input type="submit" value="Save">
</form>
I think that you should template the form. I.e. wrap it in a function, so you can create it again and again. Here is a jsfiddle http://jsfiddle.net/krasimir/2sZsx/4/
HTML
<div id="wrapper"></div>
add form
JS
var wrapper = $("#wrapper");
var addForm = $("#add-form");
var index = 0;
var getForm = function(index, action) {
return $('\
<form name="myForm" id="myForm" method="post" action="' + action + '">\
<input id="name' + index + '" name="name' + index + '" />\
<input id="email' + index + '" name="email' + index + '" />\
<input id="phone' + index + '" name="phone' + index + '" />\
<input type="submit" value="Save">\
remove form\
</form>\
');
}
addForm.on("click", function() {
var form = getForm(++index);
form.find(".remove").on("click", function() {
$(this).parent().remove();
});
wrapper.append(form);
});
Simple validation can be done when your form is submitted, thus:
$('#myForm').submit({
var n1 = $('#name1').val();
var e1 = $('#email1').val();
var p1 = $('#phone1').val();
if (n1=='' || e1=='' || p1=='') {
alert('Please complete all fields');
return false;
}
});
Note that the return false will abort the submit and return user to the document.
Great code for adding/removing form fields can be found in this question: https://stackoverflow.com/questions/18520384/removing-dynamically-generated-textboxes-in-jquery
jsFiddle here
If you are using KeenThemes (maybe Metronic theme)
https://preview.keenthemes.com/good/documentation/forms/formvalidation/advanced.html
You can do like this.
var form = document.getElementById('form_id');
var validator = FormValidation.formValidation(
form,
{
fields: {
name: {
validators: {
notEmpty: {
message: 'Please enter template name'
},
stringLength: {
min: 3,
trim: true,
message: 'Please enter a longer name.'
},
}
},
...
more fields here
...
},
plugins: {
trigger: new FormValidation.plugins.Trigger(),
bootstrap: new FormValidation.plugins.Bootstrap(),
},
});
function addNewFieldDynamically() {
// add new field here
...
validator.addField('field_name', {
validators : {...}
})
}
function removeFieldDynamically() {
// remove a field here
...
validator.removeField('field_name')
}

adjusting default value script to work with multiple rows

I am using a default value script (jquery.defaultvalue.js) to add default text to various input fields on a form:
<script type='text/javascript'>
jQuery(function($) {
$("#name, #email, #organisation, #position").defaultvalue("Name", "Email", "Organisation", "Position");
});
</script>
The form looks like this:
<form method="post" name="booking" action="bookingengine.php">
<p><input type="text" name="name[]" id="name">
<input type="text" name="email[]" id="email">
<input type="text" name="organisation[]" id="organisation">
<input type="text" name="position[]" id="position">
<span class="remove">Remove</span></p>
<p><span class="add">Add person</span><br /><br /><input type="submit" name="submit" id="submit" value="Submit" class="submit-button" /></p>
</form>
I am also using a script so that users can dynamically add (clone) rows to the form:
<script>
$(document).ready(function() {
$(".add").click(function() {
var x = $("form > p:first-child").clone(true).insertBefore("form > p:last-child");
x.find('input').each(function() { this.value = ''; });
return false;
});
$(".remove").click(function() {
$(this).parent().remove();
});
});
</script>
So, when the page loads there is one row with the default values. The user would then start adding information to the inputs. I am wondering if there is a way of having the default values show up in subsequent rows that are added as well.
You can see the form in action here.
Thanks,
Nick
Just call .defaultValue this once the new row is created. The below assumes the format of the columns is precticable/remains the same.
$(".add").click(function() {
var x = $("form > p:first-child");
x.clone(true).insertBefore("form > p:last-child");
x.find('input:not(:submit)').defaultvalue("Name", "Email", "Organisation", "Position");
return false;
});
You should remove ids from the input fields because once these are cloned, the ids, classes, everything about the elements are cloned. So you'll basically end up with multiple elements in the DOM with the same id -- not good.
A better "set defaults"
Personally I would remove the "set defaults plugin" if it's used purely on the site for this purpose. It can easily be re-created with the below and this is more efficient because it doesn't care about ordering of input elements.
var defaults = {
'name[]': 'Name',
'email[]': 'Email',
'organisation[]': 'Organisation',
'position[]': 'Position'
};
var setDefaults = function(inputElements)
{
$(inputElements).each(function() {
var d = defaults[this.name];
if (d && d.length)
{
this.value = d;
$(this).data('isDefault', true);
}
});
};
Then you can simply do (once page is loaded):
setDefaults(jQuery('form[name=booking] input'));
And once a row is added:
$(".add").click(function() {
var x = $("form > p:first-child");
x.clone(true).insertBefore("form > p:last-child");
setDefaults(x.find('input')); // <-- let the magic begin
return false;
});
For the toggling of default values you can simply delegate events and with the help of setDefault
// Toggles
$('form[name=booking]').delegate('input', {
'focus': function() {
if ($(this).data('isDefault'))
$(this).val('').removeData('isDefault');
},
'blur': function() {
if (!this.value.length) setDefaults(this);
}
});
Fiddle: http://jsfiddle.net/garreh/zEmhS/3/ (shows correct toggling of default values)
Okey, first of all; ids must be unique so change your ids to classes if you intend to have more then one of them.
and then in your add function before your "return false":
var
inputs = x.getElementsByTagName('input'),
defaults = ["Name", "Email", "Organisation", "Position"];
for(var i in inputs){
if(typeof inputs[i] == 'object'){
$(inputs[i]).defaultvalue(defaults[i]);
}
}

Categories

Resources