I am facing problem to validate select which is beautified using bootstrap-select.js plugin using jquery validate plugin. bootstrap-select.js is expecting class selectpicker and following one line of code:
$('.selectpicker').selectpicker();
for beautifying select of html.
However it is causing problem in validations using jquery validate plugin. The select in not at all validated unless and untill class selectpicker in not removed. Once class is removed then validations are properly performed.
Following is my html for select:
<select class="input-medium required" id="editCategory_sltCategoryName"
name="editCategory_sltCategoryName">
<option value="">
Select Category
</option>
<option>
Reusable Components
</option>
<option>
BU Connects
</option>
</select>
and following is the js:
$('#frm_editCategory').validate({
rules: {
editCategory_sltbuName: {
required: true
},
editCategory_sltCategoryName: {
required: true
},
editCategory_categoryName: {
minlength: 2,
required: true,
buname: true
},
editCategory_categoryDescription: {
minlength: 2,
required: true,
buname: true
}
},
highlight: function(element) {
$(element).closest('.control-group')
.removeClass('success').addClass('error');
},
success: function(element) {
element.text('OK!').addClass('valid')
.closest('.control-group')
.removeClass('error').addClass('success');
},
submitHandler: function(event) {
return true;
}
});
I have tried to do it by writing custom method for it also but it is of no use.
I'll do my best to answer your question based on what you've described, because I believe I have encountered a similar issue and been able to resolve it.
First, I'm assuming that you correctly initialized your select with the selectpicker() method. Above, you wrote
$('.selectpicker').selectpicker();
But you do not have any select elements with class selectpicker, so I think what you meant to write was
$('select').selectpicker();
When you call selectpicker(), Bootstrap will insert additional elements (div, button, span, ul, and li) after your select element. But note that, Bootstrap will then hide() your original select element. Because your select is hidden, JQuery Validate will ignore validation of it when the form is submitted. This is the main issue.
To tell Jquery Validate not to ignore your hidden select inputs, you can do the following...
// Initialize form validation rules, submit handler, etc.
$('#frm_editCategory').validate({
.
.
.
});
// The default value for $('#frm_editCategory').validate().settings.ignore
// is ':hidden'. Log this to the console to verify:
console.log($('#frm_editCategory').validate().settings.ignore);
// Set validator to NOT ignore hidden selects
$('#frm_editCategory').validate().settings.ignore =
':not(select:hidden, input:visible, textarea:visible)';
Why do you also need to include input:visible and textarea:visible? Before, the setting was to ignore all hidden inputs. If you only ignored :not(select:hidden), you would ignore any input which is not a hidden select. This is too permissive, though, because a visible input[type=text] is not a hidden select. So, it also would get ignored. What we want is to ignore any element which:
- is *not* a hidden `select`
- *is* a hidden `input`
- *is* a hidden `textarea`
To fit this all into a :not selector, you want to ignore any element which:
- is *not* a hidden `select`
- is *not* a visible `input`
- is *not* a visible `textarea`
Therefore...
$('#frm_editCategory').validate().settings.ignore =
':not(select:hidden, input:visible, textarea:visible)';
$('#frm_editCategory').validate({
ignore: ":hidden:not(.selectpicker)"
});
Here's what worked flawlessly for me:
jQuery / javascript:
$(document).ready(function() {
$.validator.setDefaults({
/*OBSERVATION: note how the ignore option is placed in here*/
ignore: ':not(select:hidden, input:visible, textarea:visible)',
/*...other options omitted to focus on the OP...*/
errorPlacement: function (error, element) {
if (element.hasClass('bs-select')) {
error.insertAfter('.bootstrap-select');
} else {
error.insertAfter(element);
}
/*Add other (if...else...) conditions depending on your
* validation styling requirements*/
}
});
$('#myform').validate({
rules: {
'year': {
required: true
}
},
messages: {
'year': {
required: 'Please select a year from the dropdown'
}
}
});
});
HTML:
<select class="input-medium bs-select required">
<option value="">Select Category</option>
<option>Innovation</option>
<option>Reusable Components</option>
<option>BU Connects</option>
</select>
Explanation:
OBSERVATION: Based on #Alvin Lee's answer setting the ignore options on the form element as follows was ok, but had its caveats;
$('#myform').validate().settings.ignore =
':not(select:hidden, input:visible, textarea:visible)';
The Problem: The bootstrap select element got validated but showed the default message This field is required on every other input element instead of overriding it with all the custom validation messages that were previously configured.
The fix: move the ignore setting into $.validator.setDefaults({...}) block... That should do it!
Here is simple solution which worked for me:
var validator = $('#frm_editCategory').validate({
.
.
.
});
$('select.input-medium').on('change', function () {
validator.element($(this));
});
That's it
In my case this tric work
*.js
`$("#form_id").validate({
rules: {
field_name: { required: true },
},
submitHandler: function (form) {
form.submit();
}
}).settings.ignore =
':not(select:hidden, input:visible, textarea:visible)'
`
*.html
<select data-style="btn-default" class="selectpicker" name="class_id" id="class_id">
<option value="" selected disabled hidden>Placeholder</option>
<option value="value1">Value 1</option>
</select>
Related
I am working on my project in laravel/vue.js and I decided to use simple vue-multiselect to choose categories from my database. Thing is I want to clear the value from input field (to look for item in list).
My multiselect component:
<multiselect
v-model="value"
placeholder="Find the category"
label="category_name"
:options="categories"
#input="addReceiversFromCategory">
</multiselect>
I try to clear an v-model but it work only on first select after page load (and also it is not a smart way..).
Last thing i try was the :clear-on-select="true" but it works onlu when multiple is true (which I dont want to be true).
I think its simple to do but I didn't find any way in documentation doc
If your v-model is just modeling the value selected, then you need to use that value however you want and reset value to null. I don't really know how your component is set up but it would look something like this:
<template>
<select v-model="value" v-on:change="doSomething()">
<option :value="null">-- Select --</option>
<option value="foo">Foo</option>
<option value="bar">Bar</option>
</select>
</template>
<script>
module.exports = {
data: function(){
return {
value: null
};
},
methods: {
doSomething: function() {
if( this.value ) {
var data = this.value; // now you can work with data
this.value = null; // reset the select to null
}
}
}
}
</script>
I have this in my view:
<div class="already_voted" v-if="already_voted" >
<p>You already voted or your are not allowed to vote</p>
</div>
This is my method :
upvote: function(com_id) {
var comment_id = {
comment_id :com_id
}
this.$http.post('/blog/article/comment/upvote', comment_id).then(function(response){
upvote_total= response.data.upvote_value;
this.already_voted = response.data.already_voted;
this.$dispatch('child-msg', this.already_voted);
$('.upvote_class_' + com_id ).text(upvote_total);
$('.isDisabledUpvote_' + com_id).addClass('disabled');
$('.isDisabledDownvote_' + com_id).removeClass('disabled');
},function(response){
});
},
Im getting value on click and if its true it need to show this div.
Problem is that this div is showed only for first time when already_voted is true and thats it. Next time when its true nothing happend. Any suggestion?
It looks like you are mixing jQuery and Vue, which should be avoided unless you have a specific reason to do so. Instead you should bind attributes to data. As a basic version of what you are doing you could bind both the disabled attribute and the message to a voted flag:
Markup
<div id="app">
<div v-if="voted">
You have already voted!
</div>
<button v-bind:disabled="voted" #click="vote()">
Vote
</button>
<button v-bind:disabled="!voted" #click="removeVote()">
Un-Vote
</button>
</div>
View Model
new Vue({
el: '#app',
methods: {
vote(){
this.voted = true;
},
removeVote(){
this.voted = false;
}
},
data: {
voted: false
}
});
Here I'm simply binding the disabled attribute using v-bind to the voted flag to disabled the buttons and am using v-if to show a message if the voted flag is true.
Here's the JSFiddle: https://jsfiddle.net/05sbjqLL/
Also be aware that this inside an anonymous function refers to the anonymous function itself, so either assign this to something (var self = this) outside the function or use an arrow function if using ES6.
EDIT
I've updated the JSFiddle to show you how you might handle your situation based on you comments:
https://jsfiddle.net/umkvps5g/
Firstly, I've created a directive that will allow you to initiate your variable from your cookie:
Vue.directive('init', {
bind: function(el, binding, vnode) {
vnode.context[binding.arg] = binding.value;
}
})
This can now be used as:
<div v-init:voted="{{ $request->cookie('voted') }}"></div>
I simply disabled the button to show you how to bind attributes to data, there's loads more that can be done, for example showing the message after a user clicks the button, I've just added a click counter and bound thev-if to that instead, so the message doesn't show until a user clicks the button:
<div v-if="vote_attempts">
You have already voted!
</div>
Then in vote() method:
vote() {
this.voted = true;
this.vote_attempts++;
},
Then data:
data: {
voted: false,
vote_attempts: 0
}
I created some input fields using KnockoutJS, and now I want to validate them.
http://jsfiddle.net/sohimohit/43zkoszu/12/
I tried it using validation plugin but it doesn't work.
I added that plugin and used it as mentioned but didn't get the solution. When you click on "add field" a form appears; I want to make the name field required and branch id as numeric. However, when I click on "add fields" it doesn't get added until the form is validated.
How can I achieve this?
You are not doing validation properly. I recommend this method
Set some settings
ko.validation.configure({
insertMessages: false,
decorateElement: true,
errorElementClass: 'error-element',
errorClass: 'error-element',
errorsAsTitle: true,
parseInputAttributes: false,
messagesOnModified: true,
decorateElementOnModified: true,
decorateInputElement: true
});
Make inputs bind with validationElement
<input type="text" placeholder="Name" data-bind="value:name,validationElement:name">
<input type="text" placeholder="Branch" data-bind="value:branch,validationElement:branch">
Extend observables
self.name = ko.observable().extend({required:true})
self.branch = ko.observable().extend({required:true,digit: true})
Now apply the rule. I prefer group
var data = [
self.name,
self.branch
]
self.Errors = ko.validation.group(data);
Now on add button wrap your code
self.Add = function(){
if(self.Errors.length == 0){
.
.
.
//Your code here
}else{
self.Errors.showAllMessages()
}
}
Hope it helps
I am using Model validation and k-state-error css class is not being applied to it in case validation fails. what else i can do to add this class to my datepicker
function onChange(e) {
if (e.date == undefined) {
var item = $(this).find('.k-picker-wrap');
$(item).addClass("k-state-error");
// $(e).css("border-color", "red");
}
}
using this code to add class but it's not working. Perhaps jquery selector is not right
From your code seems that you are trying to implement a validation that checks that the date is required. Why not implementing it as:
HTML:
<input id="date" required/>
JavaScript:
$("#date")
.kendoDatePicker({})
.kendoValidator({
validateOnBlur: true,
messages : {
required : "My custom required message"
}
});
I am using the ajaxform() plugin, which so far is working well. However, my input fields have default values, and if the user just submits the untouched form, I need to blank them out before the form is submitted using the beforeSubmit: callback.
In nutshell, I don't know the syntax to check the forms input fields and stop the submit if necessary. I have an idea its using the each() method and this.defaultValue, and maybe a return false? but I'm not sure of the details.
Could anyone perhaps give me an idea? Thanks. Heres my code so far, its the checkValues() function that I'm stuck with.
$(document).ready(function(){
//========= Functions =========
function styleForm() {
$('.quickcontact label').hide();
$('input[type="text"],textarea').addClass("idleField");
$('input[type="text"],textarea').focus(function() {
$(this).removeClass("idleField").addClass("focusField");
if (this.value == this.defaultValue){
this.value = '';
}
if(this.value != this.defaultValue){
this.select();
}
});
$('input[type="text"],textarea').blur(function() {
$(this).removeClass("focusField").addClass("idleField");
if ($.trim(this.value) == ''){
this.value = (this.defaultValue ? this.defaultValue : '');
}
});
}
//options for ajaxform() function
var options = {
target: '.quickcontactDisplay', // target element(s) to be updated with server response
beforeSubmit: checkValues, // pre-submit callback
success: reBind // post-submit callback
// other available options:
//url: url // override for form's 'action' attribute
//type: type // 'get' or 'post', override for form's 'method' attribute
//dataType: null // 'xml', 'script', or 'json' (expected server response type)
//clearForm: true // clear all form fields after successful submit
//resetForm: true // reset the form after successful submit
// $.ajax options can be used here too, for example:
//timeout: 3000
};
//rebinds the ajax functionality to updated form html
function reBind() {
// re-do the form, as it has just been replaced
$('form.quickcontact').ajaxForm(options);
styleForm();
}
//checks for default values of form on submit to prevent them being submitted
function checkValues(){
}
// ==== logic =====
$('form.quickcontact').ajaxForm(options);
styleForm();
});
And my form html:
<form action="/enquiries/add" method="post" id="EnquiryAddForm" class="quickcontact">
<input type="hidden" value="POST" name="_method"/>
<input type="hidden" id="EnquiryVisitorId" value="276" name="data[Enquiry][visitor_id]"/>
<input type="text" id="EnquiryName" maxlength="200" value="Your name" name="data[Enquiry][name]"/>
<input type="text" id="EnquiryEmailAddress" maxlength="200" value="Your Email" name="data[Enquiry][emailAddress]"/>
<textarea id="EnquiryEnquiry" rows="6" cols="30" name="data[Enquiry][enquiry]">Your Email Address</textarea>
<input type="submit" value="Ok, I'm done"/>
</form>
You are abusing the default value as a label. This is causing you problems. Rather then trying to work around those problems, I suggest fixing the cause instead.
When setting default values — set default values. Don't use the default value as a pseudo-label. Use a <label> element instead.
Haven't you looked at the documentation?
beforeSubmit:
Callback function to be invoked before the form is submitted. The
'beforeSubmit' callback can be
provided as a hook for running
pre-submit logic or for validating the
form data. If the 'beforeSubmit'
callback returns false then the form
will not be submitted. The
'beforeSubmit' callback is invoked
with three arguments: the form data in
array format, the jQuery object for
the form, and the Options Object
passed into ajaxForm/ajaxSubmit. The
array of form data takes the following
form:
[ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
Default value: null
Here the idea, didn't check it yet.
function checkValues(formData, jqForm, options)
{
for( var i in formData)
if ( formData[i].value == "")
return false;
return true;
}
sounds as if you need to:
run through all the inputs / textarea at the start and grab the default values, then stick it into an associative array with the element id as key
within checkValues, iterate through inputs once again and compare the pre-submit value against your array - when finding a match, you can set the value to "".