I'm trying to use the jQuery Validation plugin to make a multistep form with tabs, but I keep getting an "element is undefined" error when I attempt to loop through all the inputs. Any suggestions? I don't understand what's wrong. I've tried placing the checkbox in multiple places, and it seems to happen everywhere (i.e. not just at the 2nd last tab).
var tabs = $("#tabs").tabs({
disabled: [1,2,3,4,5],
select: function(event, ui) {
var valid = true;
var current = $(this).tabs("option", "selected");
var panelId = $("#tabs ul a").eq(current).attr("href");
$(panelId).find("input").each(function(index, element) {
if (!validator.element(this) && valid) {
if(ui.index > current) {
valid = false;
}
else
{
//re-disable the next tab
}
}
});
return valid;
}
});
$(".nexttab").click(function() {
var selected = $("#tabs").tabs("option", "selected");
$("#tabs").tabs("enable", selected+1);
$("#tabs").tabs("option", "selected", selected + 1);
});
HTML Part:
<div id="general">
</div>
<div id="problemtab">
<p>
<input type="checkbox" name"response" id="response" value="agree" class="required"><label for="response">I Agree</label>
</p>
<p>
<a class="prevtab navbutton"><span>Prev</span></a>
<a class="nexttab navbutton"><span>Next</span></a>
</p
</div>
<div id="lasttab">
</div>
Thanks for any help!
Edit:
It's giving me an error in jquery-validate.js:787
staticRules: function(element) {
var rules = {};
var validator = $.data(element.form, 'validator'); // <---- Error here
if (validator.settings.rules) {
rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
}
return rules;
},
Edit#2: element/this is defined as [object HTMLInputElement]
Here is my validator:
var validator = $("#myForm").validate({
ignore : ['#tabs .inactive input'], // tells the validator to only validate elements on your current tab
errorElement: "div",
wrapper: "div", // a wrapper around the error message
errorPlacement: function(error, element) {
if (element.parent().hasClass('group')){
element = element.parent();
}
offset = element.position();
error.insertBefore(element)
error.addClass('message'); // add a class to the wrapper
error.css('position', 'absolute');
error.css('left', offset.left + element.outerWidth());
error.css('top', offset.top);
}
});
You forgot an equal sign for the name attribute of your checkbox, so the name attribute is not set.
name"response" should be name="response"
I noticed yesterday that jquery.validate needs a name on elements to work, or it will throw this error.
Make sure you have just one form in your page. I used to have two forms in the same page and that was causing the problem you mention.
This error also might be related to this issue of JQuery with hidden chekcboxes (or radioboxes). This issue hasn't been addressed but it could be solved by setting (temporarily) validatorInstance.settings.ignore =''.
I faced that issue with checkboxes & hidden inputs on the form in MVC 5 Jquery 3.3.1, nothing worked so I had to disable the default validation and do some custom validation.
<button type="submit" id="btnSubmit" formnovalidate="formnovalidate" class="btn">Submit</button>
It started coming when I added
$.validator.methods.date = function (value, element) { .....
Related
This is the html:
<div class="btn btn-stock-report" id="superman">
Superman <input type="checkbox" name="superman" />
</div>
this is the JQuery:
$('#superman').on('click', function () {
if ($(this).children('input:checkbox:first').is(':checked')) {
superman = true;
$(this).children('input:checkbox:first').removeAttr('checked');
}
else {
superman = false;
$(this).children('input:checkbox:first').attr('checked', 'checked');
}
console.log("superman: " + superman);
});
What I'm trying to achieve it simply change the state of the child checkbox and change the value of a superman variable, but for some reason it always prints out superman: false in the console log. Even when I manually check the checkbox and click the div, even though the checkbox is now checked, it reports superman: false
What could be causing this?
You could just change the <div> to <label> and get rid of all the jQuery code and it will just work.
You should use .prop() instead of attr as checked is property of checkboxes. also you can narrow down your code to:
$('#superman').on('click', function () {
var chk = $(this).find('input:checkbox:first')
chk.prop("checked", !chk.prop("checked"));
});
Working Demo
$('#superman').on('click', function () {
superman = !$(this).children('input:checkbox:first').is(':checked');
$(this).children('input:checkbox:first').prop('checked',superman);
console.log("superman: " + superman);
});
Imagine a table (actually constructed of divs) with rows and in the final cell in each row, I have an input text and a link that look like this:
<input type="text" name="message" id="message_#Model.IncidentId" value="">
Send a Comment
After each row (the parent div), I have a chunk of code like the following to ajaxify the link and text input:
$('#send_#Model.IncidentId').click(function () {
var msg = $('#message_#Model.IncidentId').val();
if (msg != '') { $(this).attr('href', this.href + '?msg=' + msg) }
$.post(this.href, function (json) {
if (json.jsonResult === null) {
$("#msg_#Model.IncidentId").html("Sent...");
} else {
window.location.href = json.jsonResult;
}
});
return false;
});
It works. However, there are at least 10 of these on each page. What I'm trying to do is consolidate the jquery into one function to handle all the links. Can I use jquery "this" or pass the IncidentId to the jquery function or something? It seems like "this" would not work because the input text is outside of the link? How can I do this to have one function for the entire page?
Keep in mind it's not imperative that I splash everything with the IncidentId. So, if I need to make one or more of the ids or names generic, that would be ok. It just needs to not get confused about what pair it's handling. I've seen some comments that a form might help, but 10+ forms on a page is ok? Plus, as it stands, there will never be any other input fields than what is shown above.
I appreciate your help. Thanks.
Update: So, I basically used Søren's recommended html5 data-* (data-id) attribute in my link, gave it a class name, and then moved my url down to the function as well...and then simply replaced all my #Model.IncidentIds. The one catch is that I had to use the following to register my click event:
$(document).on('click', ".ajax-link", function () {
I guess because I'm using handlebars to dynamically generate the page? I hadn't tested the original function since I moved it to my infinite scroll layout mentioned in the comments. Thanks all for replying.
Try this:
<input type="text" name="message" data-input-id="1" value="">
<a class="ajax-link" href="#" data-link-id="1">Send a Comment</a>
$('.ajax-link').click(function () {
var id = $(this).attr('data-link-id');
var msg = $('[data-link-id='+id+']').val();
if (msg != '') { $(this).attr('href', this.href + '?msg=' + msg) }
$.post(this.href, function (json) {
if (json.jsonResult === null) {
$("[data-link-id='+id+']").html("Sent...");
} else {
console.debug(json.jsonResult);
}
});
return false;
});
Make sure the link and field have the same id
First, make sure you have some useful class name's in place. E.g.,
<input type="text" class="incident-message" name="message" id="message_#Model.IncidentId" value="">
Send a Comment
That should allow you to create a nice, row-generic script like this:
$('.incident-link').click(function(e) {
e.preventDefault();
var $this = $(this),
$row = $this.closest('div'),
$msg = $row.find('.incident-message');
var msg = $msg.val();
if (msg != '') {
$this.attr('href', $this.attr('href') + '?msg=' + msg);
}
$.post($this.attr('href'), function (json) {
if (json.jsonResult === null) {
// I didn't see any markup for your #msg element, but assuming
// that you give it a useful classname, you can do something
// similar to this:
$row.find('.some-msg-className').html('Sent...');
} else {
window.location.href = json.jsonResult;
}
});
});
As far as grouping the events to a single handler, just use a class instead of id's.
$('.thisKind').click(function () {
or if the content is dynamic, use a single event for the parent with a selector in the on() method
$('#parentId').on("click", ".thisKind", function() {
As far as the this usage, you should familiarize yourself with jquery's DOM traversal using closest() to go up the tree and find() to go down
Summernote gives you the option of giving focus to the editor when you create it, passing this options:
$('#summernote').summernote({
focus: true
});
But after initialization, it seems you can't give focus to the textarea by clicking a button or similar. I've tried several ways, without success.
Anyone did that?
$('.summernote').summernote('focus')
ps. i want to find an angular way out .. and it works
After coming back to this problem and trying a lot of solutions, I came to one that works:
$('.note-editable').trigger('focus');
Triggering the event through jQuery works, but using the focus() function doesn't.
$(document).ready(function () {
$.fn.extend({
placeCursorAtEnd: function () {
// Places the cursor at the end of a contenteditable container (should also work for textarea / input)
if (this.length === 0) {
throw new Error("Cannot manipulate an element if there is no element!");
}
var el = this[0];
var range = document.createRange();
var sel = window.getSelection();
var childLength = el.childNodes.length;
if (childLength > 0) {
var lastNode = el.childNodes[childLength - 1];
var lastNodeChildren = lastNode.childNodes.length;
range.setStart(lastNode, lastNodeChildren);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
return this;
}
});
});
then:
$('.note-editable').click(function(){
//$('#summernote').summernote('focus');
$(this).placeCursorAtEnd();
});
①focus on click or tap
②focus at the end of content
it works on mobile device too
please refer codepen
for this problem
/* Summernote Validation */
$(function () {
var summernoteForm = $('.form-validate-summernote');
var summernoteElement = $('.summernote');
var summernoteValidator = summernoteForm.validate({
errorElement: "div",
errorClass: 'is-invalid',
validClass: 'is-valid',
ignore: ':hidden:not(.summernote),.note-editable.card-block',
errorPlacement: function (error, element) {
// Add the `help-block` class to the error element
error.addClass("invalid-feedback");
console.log(element);
if (element.prop("type") === "checkbox") {
error.insertAfter(element.siblings("label"));
} else if (element.hasClass("summernote")) {
error.insertAfter(element.siblings(".note-editor"));
} else {
error.insertAfter(element);
}
}
});
summernoteElement.summernote({
height: 300,
callbacks: {
onChange: function (contents, $editable) {
// Note that at this point, the value of the `textarea` is not the same as the one
// you entered into the summernote editor, so you have to set it yourself to make
// the validation consistent and in sync with the value.
summernoteElement.val(summernoteElement.summernote('isEmpty') ? "" : contents);
// You should re-validate your element after change, because the plugin will have
// no way to know that the value of your `textarea` has been changed if the change
// was done programmatically.
summernoteValidator.element(summernoteElement);
}
}
});
});
This works for Summernote v0.8.18:
$(`div.note-editing-area div.note-editable`).focus();
You can set the focus by putting the focus on the editable div used by Summernote:
document.querySelectorAll(".note-editable").focus();
or using JQuery
$('#summernote').find('.note-editable').focus();
<div class="col-lg-12 col-md-6 col-xs-12">
<div class="form-group">
<label> Skills</label>
<span ng-messages="EditForm.Skills.$error" ng-if="EditForm.Skills.$dirty || isEditFormSubmitted ">
<span class="text-danger" ng-message="required" ng-bind="error msg"></span>
</span>
<text-angular id="Skills" name="Skills" ng-model="EditVacancyModel.Skills" ta-toolbar="[['bold','underline','italics','ul','ol']]"ng-required="true"></text-angular>
</div>
</div>
Within my form there are 2 SELECT Options. I'm looking to check the values of both, to check that they match.
This below is my jquery, when the code runs, I deliberatly have different values in the SELECT options and the form will just carry onto the next page without flagging up the error that they don't match.
<script type="text/javascript">
$(document).ready(function () {
jquery(function(){
$("leadgenform2").click(function(){
$(".error").hide();
var hasError = false;
var exppagesval = $("#exppages").val();
var pagesseenval = $("#pagesseen").val();
if (exppagesval != pagesseenval) {
$("#pagesseen").after('<div class="alert alert-success display-hide"><button class="close" data-close="alert"></button>Pages Seen & Expected Pages do not match!</div>');
hasError = true;
}
if(hasError == true) {return false;}
});
});
});
</script>
What have I missed?
Not sure why formatting has gone a miss. sorry!
hey $("leadgenform2") is invalid selector either make it a class or id(preferred) and use like
$(".leadgenform2") for class.
$("#leadgenform2") for id.
$("leadgenform2") is not a valid selector. assuming it is an ID, so you should use $("#leadgenform2").
Just from a first glance... you seem to have an error on line1:
jquey(function(){
should be
jquery(function(){
And you are missing $(document).ready(function(){ .... );
Without this, click event will not fire.
(I am not using Jquery Validation)
I'm trying to return custom errors if the field is incorrect or empty. For instance, if the #id_first_name field is null. Append the string, " first name" to p#error to result in :
Please fill in your first name
I've made a fiddle here to show what I mean. So in the list of required fields... How would I be able to grab / check each individual required id and assign the corrosponding error?
Thank you for your help in advance!
You're fiddle should be as basic as possible, removing all other information, but you could try something like this,
$('form').on('submit',function(){
$('input').each(function(){
$this = $(this);
if($this.val() == 'null')
{
$('p#error').append('Please enter your ' + $this.attr('placeholder'));
}
}
});
You could do something like below
$('form input').on('blur', function() {
var id = $(this).attr('id');
var val = $(this).val();
if(id == 'myInput') {
if(!val.length) {
$('#error').append('Please enter a value into the input');
}
}
});
This is a simple way of doing form validation, just tailor the example to your needs.
EDIT
If you want it to work in your example it would be better to have a div with the id of error and append p tags with the corresponding error values.
Happy coding :)