i am trying to use parsely.js on my html page to validate input box. currently this html page contains one input box and one submit button. the structure is created using bootstrap 3 and this page does not contain Form tag.
<div role='form'>
<div class="row form-group">
<div class="col-xs-3">
<label title="fullname">Full Name</label>
</div>
<div class="col-xs-4">
<input type="text" class='form-control' id="name" name="fullName" data-parsley-required="true" data-parsley-required-message="Please insert your name"/>
</div>
</div>
<input type="submit" class= "btn btn-danger"/> </div>
i am calling parsley.js like
function validateInput()
{
var handle = $("input[name='fullName']").parsley({
successClass: "has-success",
errorClass: "has-error",
classHandler: function (el) {
return $(el).closest('.form-group');//not working
},
errorsWrapper: "<span class='help-block'></span>",
errorTemplate: "<span></span>",
});
return handle.isValid();
}
on click of Submit button. it returns true/false correctly and create span tag also. but error classes are not applied. even data-parsley-required-message'Please insert your name' is not working.
when i put alert($(el)) or alert(el) it gives [object Object]. i think el should be the input object on which i am calling parsley function. but i am not able to get el.attr('id') or any other attribute. it returns undefined. i have also tried
//return el.closest('.form-group');//not working
//return el.$element.closest('.form-group)//not working
//return $(el).$element.closest('.form-group')//not working
I can not use Form tag as i am using this html structure in sharepoint content edtior web part.
A few things first:
Parsley allows you to bind it to a field, so you won't have a problem without the form element (see docs);
The classHandler function recieves an object of the type ParsleyField. With this object, you can access the input element with el.$element (for example: alert(el.$element.attr('id'));
I have made the following changes to your validateInput function:
<script type="text/javascript">
function validateInput() {
$("input[name='fullName']").parsley({
successClass: "has-success",
errorClass: "has-error",
classHandler: function (el) {
return el.$element.closest('.form-group'); //working
},
errorsWrapper: "<span class='help-block'></span>",
errorTemplate: "<span></span>",
});
// Returns true / false if the field has been validated. Does not affect UI.
//$("input[name='fullName']").parsley().isValid());
// validate field and affects UI
$("input[name='fullName']").parsley().validate();
}
</script>
With this code, the message is presented correctly, and the successClass and errorClass are appended to the div form-group.
See the following working jsfiddle
Related
Using jQuery Validation plugin, I defined the following for my Bootstrap form:
$(".form-with-validation").validate({
errorClass: "help-block",
errorElement: "span",
highlight: function(element) {
$(element).closest('.form-group').addClass('has-error');
},
unhighlight: function(element) {
$(element).closest('.form-group').removeClass('has-error');
}
});
It works well for a simple form. However, the part with highlight and unhighlight doesn't work when a .form-group contains multiple inputs (inline) that need to be validated:
<div class="form-group">
<label class="col-md-4 control-label">State & Zip</label>
<div class="col-md-3">
<select class="form-control required" name="state">
...
</select>
</div>
<div class="col-md-3">
<input type="text" class="form-control required" name="zip">
</div>
</div>
The problem is that once you select a state for example, the input becomes valid, and its .form-group parent loses .has-error class, even though the sibling input (i.e. zip) is still invalid (i.e. has a .help-block span below it):
So, I changed the unhighlight part to the following:
unhighlight: function(element) {
var formGroup = $(element).closest('.form-group');
var formGroupIsValid = true;
formGroup.find('input').each(function(){
if (! $(this).valid())
formGroupIsValid = false;
});
if (formGroupIsValid)
formGroup.removeClass('has-error');
}
Yet I get the following error:
Uncaught RangeError: Maximum call stack size exceeded
Any ideas why? I tried many approaches, but each time I get the same error.
EDIT
I'd prefer to stick with div.form-group having .has-error class if possible (because of styling).
EDIT 2
Jsfiddle to demonstrate the issue.
Here is the solution I ended up with. It was simpler than I thought. As people have indicated before, any form-group should contain only one form-control at a time. The easiest solution is thus to put a second form-group inside the first one and then place the second form-control in there:
<div class="form-group">
<label class="col-md-4 control-label">State & Zip</label>
<div class="col-md-6">
<div class="row">
<div class="col-sm-6">
<select class="form-control required" name="state">
...
</select>
</div>
<div class="col-sm-6 form-group" style="margin-bottom:0;padding-right:0">
<input type="text" class="form-control required" name="zip">
</div>
</div>
</div>
</div>
With just a few CSS styles, this works perfectly and looks just fine. Here's a jsfiddle.
You are calling a function which calls another function and so on, until you hit the call stack limit. I am going to assume the problem is in your .each loop when you call .valid().
You shouldn't have to do any of that though. Instead of targeting form-group you should target something around the input specifically so you don't have to change that unhightlight function. For example something like:
<div class="form-group">
<label class="col-md-4 control-label">State & Zip</label>
<div class="col-md-3 inputToValidate">
<select class="form-control required" name="state">
...
</select>
</div>
<div class="col-md-3 inputToValidate">
<input type="text" class="form-control required" name="zip">
</div>
</div>
And then update the JavaScript code to something like:
$(".form-with-validation").validate({
errorClass: "help-block",
errorElement: "span",
highlight: function(element) {
$(element).closest('.inputToValidate').addClass('has-error');
},
unhighlight: function(element) {
$(element).closest('.inputToValidate').removeClass('has-error');
}
});
I'd prefer to stick with div.form-group having .has-error class if possible
It's not possible with the options provided by the plugin. The valid/invalid classes are toggled on the element being validated. The highlight and unhighlight functions can be modified to toggle classes on other elements using jQuery DOM traversal, etc.
However, you want logic that makes a parent container "invalid" when any of its children are invalid... the plugin is not equipped for that. As soon as an invalid child element triggers the error class on the parent, any valid child element will apply the valid class to the same parent.
A workaround would be an external keyup and change handler that looks at the classes on all sibling input elements and toggles its parent class accordingly. Based on your own code and untested...
$('input, select').on('keyup change', function() {
var formGroup = $(this).closest('.form-group');
var formGroupIsValid = true;
formGroup.find('input, select').each(function(){
if (! $(this).valid()) {
formGroupIsValid = false;
}
});
if (formGroupIsValid) {
formGroup.removeClass('has-error');
} else {
formGroup.addClass('has-error');
}
});
I get the following error: Uncaught RangeError: Maximum call stack size exceeded .... Any ideas why?
Yes, you are calling the .valid() method from within the .validate() method (via unhighlight). So calling $(this).valid() from within this method only causes unhighlight to be called again... and so on indefinitely.
You don't have to use the form-with-validation class you can target all the form field that you are wanting to validate by selecting the inputToValidate class. It also much simpler. Also you probably want to use the toggleClass.
$(".inputToValidaten").validate({
errorClass: "help-block",
errorElement: "span",
highlight: function(element) {
$(this).toggleClass('has-error');
},
unhighlight: function(element) {
$(this).toggleClass('has-error');
}
});
Updates and Edites
OK. So here is code that will work on any nested form field with the form-control class. It will go up and grab the closest element with the form-group class and then add you validation code to it.
$(".form-control").validate({
errorClass: "help-block",
errorElement: "span",
highlight: function(e) {
$(e.target).closest('.form-group').toggleClass('has-error');
},
unhighlight: function(e) {
$(e.target).closest('.form-group').toggleClass('has-error');
}
});
I have a little problem:
I have a modal that opens after some result search with ajax: it opens and show all requested results correctly.
On close, I need to empty another div with ID "results", empty an input with ID "search" and focus on it:
empty "results" is working
changing value of "search" to "" is also working
focus on "search" is not working
Here's my HTML:
<div class="col-sm-3">
<form action="" method="post" id="searchit">
<div class="input-group mar-btm">
<span class="input-group-addon"><i class="fa fa-search fa-lg"></i> Ricerca:</span>
<input type="text" id="search" tabindex="1" class="form-control" name="search" placeholder="Codice, EAN o Testo" />
</div>
</form>
</div>
<div class="col-sm-4" id="results"></div>
UPDATE:
jQuery:
$(".modal").on('hidden.bs.modal', function () {
$("#results").empty();
$("#search").val('');
$("#search").focus();
});
I also tried:
$(".modal").on('hidden.bs.modal', function () {
$("#results").empty();
$("#search").val('').focus();
});
and (is the only text input on this page):
$(".modal").on('hidden.bs.modal', function () {
$("#results").empty();
$("#search").val('');
$('input[type="text"]').focus();
});
In every case, empty() and val() are working properly but nothing is working with focus()! No error thrown in console...
I can't figure out what I'm missing/doing wrong!
Some help? Thanks in advance!
Problems with trying to use .focus() in an event handler usually stem from the event being handled also having an affect on focus. To get around that, I usually just wrap the .focus() call in a timeout:
$(".modal").on('hidden.bs.modal', function () {
$("#results").empty();
$("#searc").val('');
setTimeout(function() {
$("#searc").focus();
}, 10);
});
The timeout handler will run basically immediately after whatever triggered the event handler is all finished.
I have a form that I insert dynamically. When a link is clicked I execute this jQuery:
var newhtml = ' <div class="nav-wrapper"> <form id="target"> <div class="input-field"><input id="search" type="search" required> <label for="search"><i class="material-icons">search</i></label><i class="material-icons">close</i></div></form></div> ';
//replace nav bar with search bar
$("#replaceBar").replaceWith(newhtml);
I also have this in my javascript file:
$("#target").submit(function (event) {
alert("search submitted");
});
My issue is that I think the jquery for the submit is not being attached since the form is being submitted after the JS loads.
I eventually want the form to go to a new html page with the data that was in the form.
I think the issue is you don't have a submit button. Using your demo code, if I hit enter from the input field, I see the alert.
Try this:
$(document).ready(function() {
var newhtml = '<div class="nav-wrapper"> <form id="target"> <div class="input-field"><input id="search" type="search" required><input type="submit" value="search"></div></form></div>';
//replace nav bar with search bar
$("#replaceBar").replaceWith(newhtml);
$("#target").on('submit', function (event) {
alert("search submitted");
});
});
My codes was correct I just had the on submit event binded in a different function. I needed it to be right after the insert.
Now it works perfectly.
dynamically inserted elements need to use $().on();
if you don't know what is, search it in Jquery API.
your submit event bind before the event-target elements id inserted,
then the script can't work as you expected.
Try the event handler with document:
$(function(){
$(document).on('submit',function(e) {
e.stopPropagation();
if('target' === e.target.id) {
//to do here
}
});
});
I have a popover with a form inside. And It is already out and ready for submission, here is the code for the popover
<div id="popover-head" class="hide">Add new subject</div>
<div id="popover-content" class="hide">
<form class="form-inline" id="pop-form" method="POST" action="../admin/module_add_subject.do">
<div class="form-group">
<!-- This input is what i'm talking about -->
<input type="text" name="subjectName" id="subject-name" required="required" pattern="^[\S\s]{3,25}[A-z]+$" title="Only accept alphabet characters and length is minimum of 3 and max of 25 " placeholder="Subject name.."/>
<button class="btn btn-primary" type="button" id="add-subject" ><i class="icon-white icon-ok"></i></button>
</div>
<p></p>
<p style="color:red" id="error-message"></p>
</form>
</div>
The input above I'm sure the regex is working. When I change the button to submitthe required is working perfectly fine but when I change it back to button then it is not working again.
The reason why my submit button is a type="button" because of this code:
$(document).on('click', '#add-subject', function(e) {
$.post('../admin/module_check_subject.do', { subjectName: $('#subject-name').val() },
function( data ) {
// if data from the database is empty string
if( $.trim( data ).length != 0 ) {
// hide pop-over
$('#popover').popover('hide');
// submit form
$('#pop-form').submit();
} else {
$('#error-message').text('Subject already exist.' );
}
}
})
.fail( function () {
bootbox.alert('Failed to check, please try again later.');
});
});
What I'm doing is on submit i'll check out first in my database if the input text in the textbox exist in the database, then if the text exist the database stop the submission of the form and display error at the p tag
By the form submission algorithm, validation is not performed when a form is submitted using the submit() method. The idea is, more or less, that when you submit a form with a script, your script should also carry out any checks deemed necessary.
Within your script, you can call the checkValidity() method to carry out the normal validation that would be performed if the form were submitted with a submit button. Note that it performs static validation only.
I want to add "i" to a input field when the red div is clicked, but the "i" that is added to the input field should not be viewable. If the green button is clicked the hidden "i" should be removed.
Here is my HTML live: http://jsfiddle.net/mtYtW/60/
My HTML:
<div class="input string optional">
<label for="company_navn" class="string optional">Name</label>
<input type="text" size="50" name="company[navn]" maxlength="255" id="webhost_navn" class="string optional">
</div>
<div style="width:30px;height:30px;margin-top:10px;display:block;background:green;">
</div>
<div style="width:30px;height:30px;margin-top:10px;display:block;background:red;">
</div>
How to create this functionality?
If you would like to associate data with a specific element, I suggest the .data() method of jQuery. Take a look at the jQuery docs. It's a much cleaner way of accomplishing your goal.
Here's a working Fiddle to get you started.
EDIT
Per the new requirement spelled out in the comments to your question, you can attach to the form submit event like this:
$('#yourForm').submit(function() {
if($('#webhost_navn').data('myData') == 'i')
{
var val = $('#webhost_navn').val();
$('#webhost_navn').val('i' + val);
}
});
NOTE: This code relys on the orginal code in my Fiddle.
It sounds like you want to associate some data with the input field, but not alter the input field's value. For that, you can use the data method:
$(document).ready(function() {
$('#redDiv').click(function() {
$('#webhost_navn').data('myData', 'i');
});
$('#greenDiv').click(function() {
$('#webhost_navn').data('myData', null);
});
});
You'll need to add id's to the red and green divs for the above example to work as is, respectively, redDiv and greenDiv. To retrieve the data you associate with the input, do this:
var myData = $('#webhost_navn').data('myData'); // Will equal 'i' or null
API Ref: http://api.jquery.com/data
EDIT: To append the "i" value to the input's value:
var myData = $('#webhost_navn').data('myData'),
val = $('#webhost_navn').val();
if (myData) {
$('#webhost_navn').val(myData + val);
}
Working example: http://jsfiddle.net/FishBasketGordo/e3yKu/
My update to your code here: http://jsfiddle.net/mtYtW/61/
Basically I gave your red/green button's id's and created a click event to add/remove the content. I also created a css definition for the color of the input box to be white so you don't see the text.
<div class="input string optional"><label for="company_navn" class="string optional"> Name</label><input type="text" size="50" name="company[navn]" maxlength="255" id="webhost_navn" class="string optional"></div>
<div id='green' style="width:30px;height:30px;margin-top:10px;display:block;background:green;"></div>
<div id='red' style="width:30px;height:30px;margin-top:10px;display:block;background:red;"></div>
css:
label {display:block;}
#webhost_navn{color:white};
js:
$("#red").live("click",function()
{
$("#webhost_navn").val("i");
});
$("#green").live("click",function()
{
$("#webhost_navn").val("");
});
Note if the goal is to post an "i" and have nothing else as a value (ie no user input) use <input type='hidden' id=webhost_navn > and use the same jquery code as above without the need for the css.