I am trying to add a class in bootstrap form for validation purpose. It is my form
<form id= "regForm" method="post" class="form-horizontal">
<div class="form-group has-feedback">
<label for="FirstName" class="col-sm-2 control-label">First Name</label>
<div class="col-sm-10">
<input type="text" name="firstName" class="form-control" id="FirstName" placeholder="First Name">
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
</div>
</div>
</form>
and here is my jquery
$(document).ready(function() {
$("#FirstName").focusin(function(){
var is_name = $("input").val();
if(is_name ==='' && is_name === null){
$('div').addClass('has-error');
$('span').addClass('glyphicon-remove');
}
});
});
I want that if name is null or empty it should add bootstrap class glyphicon-remove in existing class, exactly in same way i want to do it in further form inputs. can some one please help i dont want to use jquery plugin i want to learn it. I am using bootstrap 3.3.7 cdn.
Thanks
This will do it.
$(document).ready(function() {
$("#FirstName").focusin(function(){
var is_name = $("input").val();
if(is_name ==='' || is_name === null){
var $this = $(this);
$this.addClass('has-error');
$this.next('span').addClass('glyphicon-remove');
}
});
});
You had the conditional operator wrong. This:
if(is_name ==='' && is_name === null)
Needed to be this:
if(is_name ==='' || is_name === null)
Becuase 'is_name' can never be both an empty string and null at the same time, they're 2 different things.
Next, where you had this line:
$('div').addClass('has-error');
You're telling jQuery to add the 'has-error' class to EVERY div on the page.
Instead, you can get a reference to the input you just clicked in using $(this), so now you can add the class to the input itself.
You could just use:
$(this).addClass('has-error');
But because you need to find the 'span' tag, you still need the reference to the input, so a best practice is to cache it using this line:
var $this = $(this);
Now jQuery has a saved variable for the input which is better for performance.
Finally, use jQuery's 'next' method to find the span tag and add the 'glyphicon-remove' class to it:
$this.next('span').addClass('glyphicon-remove');
Hope that helps.
Related
I was able to create a script to validate my Bootstrap 4 form but somehow the error message is REPLACING the input field. Is there an elegant way to validate a BS4 with Vanilla JS or I should just go down the road of using Bootstrap validation? What's the best practice in the industry? It's my first time dealing with form validation.
Here's the fiddle:
https://jsfiddle.net/wunrsjdy/
HTML:
<div class="container">
<div id="form">
<h1 class="page-title">Quer Ser Nosso Cliente? Preencha o QuestionĂ¡rio Abaixo</h1>
<form id="form-user" action ="#" method="POST">
<div class="form-group" id='errorTeste'>
<label for="name">Empresa</label>
<input type="text" class="form-control" id="name" name= "name" placeholder="">
</div>
<button type="submit" class="btn btn-primary" id="button-send">Enviar</button>
</form>
</div>
JS
const name = document.getElementById('name')
const form = document.getElementById('form-user')
const errorElement = document.getElementById('errorTeste')
form.addEventListener('submit', (e) => {
let messages = []
if (name.value === '' || name.value == null) {
messages.push('Preencha o nome')
}
if (messages.length > 0) {
e.preventDefault()
errorElement.innerText = messages.join(', ')
}
})
In your fiddle, you are changing the innerText attribute of errorElement. But errorElement is also (equal to) your .form-group element:
const errorElement = document.getElementById('errorTeste')
// A little further down your html...
<div class="form-group" id='errorTeste'>
I believe that this causes your input and label elements in .form-group to be replaced by the inner text.
I feel you are on the right track, though. Try showing another element that contains a styled error/warning message when a user input is invalid using the element's style.display attribute. Maybe you tried giving the #errorTeste id to a separate error message element, but assigned it to the .form-group element by accident? Just a hunch.
Here's a decent example of how you could make it look:
I'm trying to add a class to my element based on whether it's required and empty field. Not sure what I'm doing wrong. My console.log is getting printed but the class is not assigned.
This is my html
<div ng-repeat="supplier in vm.exportSuppliers" class="row">
<div class="col-xs-5">
<label ng-show="vm.exportSuppliers[$index].exportSupplier" class="control-label" for="es{{$index}}+Ref">Agreement Reference *</label>
<label ng-hide="vm.exportSuppliers[$index].exportSupplier" class="control-label" for="es{{$index}}+Ref">Agreement Reference</label>
<input class="form-control" id="es{{$index}}+Ref" type="text"
ng-model="supplier.agreementReference" ng-change="vm.addExportSupplier()"
ng-blur="vm.requiredField('es'+$index+'+Ref')"
ng-required="vm.exportSuppliers[$index].exportSupplier">
</div>
</div>
and my function to make sure field is required and not filled in
vm.requiredField = requiredField;
function requiredField (id) {
if($scope.vm.exportSupplier.form.$error.required) {
for (var i = 0; i < $scope.vm.exportSupplier.form.$error.required.length; i++) {
if ($scope.vm.exportSupplier.form.$error.required[i].$$attr.id == id) {
console.log('invalid required field');
var myEl = angular.element( document.querySelector( id ) );
myEl.addClass('top40');
}
}
}
}
What's wrong with my addClass?
Have a look at the below question. I think you could improve your approach by making use of the ternary operators in ng-class.
angular ng-class if-else expression
You can add conditional classes by using ng-class and form properties provided by angularjs
You need to add "name" attribute on form and specify novalidate on it
<input class="form-control" id="es{{$index}}+Ref" type="text"
name="inputName"
ng-class="{'error-class': formName.inputName.$invalid && formName.inputName.$touched}"
ng-model="supplier.agreementReference" ng-change="vm.addExportSupplier()"
ng-required="vm.exportSuppliers[$index].exportSupplier">
I think this will solve your purpose. No need to write blur function in controller.
There are two ways to handle this situation.
Option 1:
<div ng-class="{'class1': obj.success, 'classB': obj.error}"></div>
Option 2:
<div class="{{obj.classes}}"></div>
The only problem with this approach is that updating the template could become an issue. Sometimes the controller may not update the template. If that is the case, use $scope.$apply(); after the change has been made.
I have a component on my page which looks like this:
<div id="componentList">
<div class="componentPair">
<div class="left">
<input type="text" class="part" placeholder="PART NUMBER">
</div>
<div class="right">
<input type="text" class="serial" placeholder="SERIAL NUMBER">
</div>
</div>
</div>
A component list can have multiple component pairs nested within it. When performing a search a query cannot be made for a serial number if a part number is not present, therefore when performing a keyup event on the .serial field I need to get the text from the part number field. I would store this in a data model, but by referencing the current serial field I should be able to traverse to the part number field.
Here is what I have tried, when my page loads I bind a keyup event on the serial field, I pass this as the selector so I have reference to the (sender) current field in getData():
$(document).on("keyup", '.serial', function() { getData(this, "SERIAL") });
Then in getData I want to be able to traverse up my DOM structure to the current componentPair group and then traverse into the left div and get the value from Part Number input field.
Here is what I tried:
function getData(elem, type) {
var code = ""
var serial = ""
if(type === "SERIAL") {
console.log(elem.closest('input[class^="part"]'))
serial = elem.value
}
... Other erroneous code to perform the search
}
As you can see, here I use console.log(elem.closest('input[class^="part"]')) to find the closest component with the class of part, after reading jQuery documentation I believe this should work, but I get an undefined function error. I then tried to use the parent() selector and parentsUntil() selector but each of them threw an undefined function error.
If I console log, elem I get:
<input type="text" class="serial" placeholder="SERIAL NUMBER">
Which is what I would expect, so I don't see why I can't use elem.parent().parent() to traverse to componentPair and then dive into the tree structure to pull the information out.
I am using jQuery 1.11.3, any help would be greatly appreciated.
The issue is because .part is not a parent of .serial. You need to use closest() to find a common parent, then find() to get the element you require. Try this:
var serial = $(elem).closest('.componentPair').find('.part').val();
The reason you get undefined function error is that elem is not a jQuery object, it's a HTMLElement, so wrap it in $().
Then .closest() won't work the way you think, it will only search through itself and its parents.
Try this:
function getData(elem, type) {
var code = ""
var serial = ""
if(type === "SERIAL") {
console.log($(elem).parent().siblings().find('input[class^="part"]'));
serial = elem.value
}
}
$(document).on("keyup", '.serial', function() {getData(this, "SERIAL") });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="componentList">
<div class="componentPair">
<div class="left">
<input type="text" class="part" placeholder="PART NUMBER">
</div>
<div class="right">
<input type="text" class="serial" placeholder="SERIAL NUMBER">
</div>
</div>
</div>
You have issue with elem.closest('input[class^="part"]'), this should be $(elem).closest('input[class^="part"]') . Because elem is the input's object itself. so you can not directly call closest()
Here is the working code :
$(document).on("keyup", '.serial', function() { getData(this, "SERIAL") });
function getData(elem, type) {
var code = ""
var serial = ""
if(type === "SERIAL") {
console.log($(elem).parent().parent().find('.part'));
serial = $(elem).parent().parent().find('.part').val();
alert(serial);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="componentList">
<div class="componentPair">
<div class="left">
<input type="text" class="part" placeholder="PART NUMBER">
</div>
<div class="right">
<input type="text" class="serial" placeholder="SERIAL NUMBER">
</div>
</div>
</div>
I have a html fragment similar to this
<div class="form-row">
<input type="text" id="foo1">
</div>
<div class="form-row">
<input type="text" id="foo2">
</div>
<div class="form-row">
<input type="text" id="foo3">
</div>
and I wanted to use cheerio to change the id tag to foobar[1,2,3]
my code is
var cheerio = require("cheerio");
var $ = cheerio.load("html as above");
var inputs = $('input[id]');
Object.keys(inputs).forEach(function(key,index) {
if (key == index) {
console.log(key,inputs[key])
//#1
});
at this point (//#1), I wanted to get the value of the id attribute, and according to the docs at https://github.com/cheeriojs/cheerio I can use the .data method to get and change the attribute in the element, but
inputs[key].data("id")
gives me a "TypeError: undefined is not a function" error
I know that I'm missing something simple, but can't see the wood for the trees and would appreciate some pointers.
thanks
update #1
just when I think I've got a grip on this, it slips from my fingers ..
now, I want to move an element :
I have
<label>xyz<i class="fa fa-list"></i></label>
and I want
<label>xyz</label><i class="fa fa-list"></i>
the code - that doesn't work ;) - is this
var icons = $('label i');
icons.each(function(index,icon) {
// #2 now that I've got an element what now ?
}
I know that icons.remove() will delete the element(s) but struggling to get them added to the right place.
The problem is inputs[key]) will be a dom element reference, which will not have methods like data()
Try to set the attribute value like
var cheerio = require("cheerio");
var $ = cheerio.load('<div class="form-row">\
<input type="text" id="foo1">\
</div>\
<div class="form-row">\
<input type="text" id="foo2">\
</div>\
<div class="form-row">\
<input type="text" id="foo3">\
</div>');
var inputs = $('input[id]');
inputs.attr('id', function(i, id){
return id.replace('foo', 'foobar')
});
console.log($.html())
Hello guys i have the below html for a number of products on my website,
it displays a line with product title, price, qty wanted and a checkbox called buy.
qty input is disabled at the moment.
So what i want to do is,
if the checkbox is clicked i want the input qty to set to 1 and i want it to become enabled.
I seem to be having some trouble doing this. Could any one help
Now i can have multiple product i.e there will be multiple table-products divs within my html page.
i have tried using jQuery to change the details but i dont seem to be able to get access to certain elements.
so basically for each table-product i would like to put a click listener on the check box that will set the value of the input-text i.e qty text field.
so of the below there could be 20 on a page.
<div class="table-products">
<div class="table-top-title">
My Spelling Workbook F
</div>
<div class="table-top-price">
<div class="price-box">
<span class="regular-price" id="product-price-1"><span class="price">€6.95</span></span>
</div>
</div>
<div class="table-top-qty">
<fieldset class="add-to-cart-box">
<input type="hidden" name="products[]" value="1"> <legend>Add Items to Cart</legend> <span class="qty-box"><label for="qty1">Qty:</label> <input name="qty1" disabled="disabled" value="0" type="text" class="input-text qty" id="qty1" maxlength="12"></span>
</fieldset>
</div>
<div class="table-top-details">
<input type="checkbox" name="buyMe" value="buy" class="add-checkbox">
</div>
<div style="clear:both;"></div>
</div>
here is the javascript i have tried
jQuery(document).ready(function() {
console.log('hello');
var thischeck;
jQuery(".table-products").ready(function(e) {
//var catTable = jQuery(this);
var qtyInput = jQuery(this).children('.input-text');
jQuery('.add-checkbox').click(function() {
console.log(jQuery(this).html());
thischeck = jQuery(this);
if (thischeck.is(':checked'))
{
jQuery(qtyInput).first().val('1');
jQuery(qtyInput).first().prop('disabled', false);
} else {
}
});
});
// Handler for .ready() called.
});
Not the most direct method, but this should work.
jQuery(document).ready(function() {
jQuery('.add-checkbox').on('click', function() {
jQuery(this)
.parents('.table-products')
.find('input.input-text')
.val('1')
.removeAttr('disabled');
});
});
use
jQuery('.add-checkbox').change(function() {
the problem is one the one hand that you observe click and not change, so use change rather as it really triggers after the state change
var qtyInput = jQuery(this).children('.input-text');
another thing is that the input is no direct child of .table-products
see this fiddle
jQuery('input:checkbox.add-checkbox').on('change', function() {
jQuery(this)
.parent()
.prev('div.table-top-qty')
.find('fieldset input:disabled.qty')
.val(this.checked | 0)
.attr('disabled', !this.checked);
});
This should get you started in the right direction. Based on jQuery 1.7.2 (I saw your prop call and am guessing that's what you're using).
$(document).ready(function() {
var thischeck;
$('.table-products').on('click', '.add-checkbox', function() {
var qtyInput = $(this).parents('.table-products').find('.input-text');
thischeck = $(this);
if (thischeck.prop('checked')) {
$(qtyInput).val('1').prop('disabled', false);
} else {
$(qtyInput).val('0').prop('disabled', true);
}
});
});
Removing the property for some reason tends to prevent it from being re-added. This works with multiple tables. For your conflict, just replace the $'s with jQuery.
Here's the fiddle: http://jsfiddle.net/KqtS7/5/