I have a number of inputs like this:
<div class="fg-line">
<input type="text" class="form-control fg-input place-edit placeInformation" id="place_name">
<label class="fg-label">Place Name</label>
</div>
<div class="fg-line">
<input type="text" class="form-control fg-input place-edit placeInformation" id="place_address">
<label class="fg-label">Place Address</label>
</div>
I get some data from an API and then append to these inputs (so the user can edit).
This works fine. The issue is that I want to add a class to this:
<div class="fg-line">
This is simple enough if I only have one of these and one input, but since I have multiple, I need some way to check each input and if not empty add the class fg-toggled such that the line becomes:
<div class="fg-line fg-toggled">
If I had just one input, I'd do this:
if (('#place_name').value != '' || ('#place_name').value != ('#place_name').defaultValue) {
$('.fg-line').addClass('fg-toggle')
}
But I don't know how to do this without writing this out for every class (there are 30+). Is there a way to iterate this somehow? I tried checking .place-edit but since it's a class, if any of the inputs with the class are not empty then they all get the new class added.
Simply loop through each input and find the parent using .closest().
$('.placeInformation').each(function() {
var $input = $(this);
if ($input.val()) {
var $parent = $input.closest('.fg-line');
$parent.addClass('fg-toggled')
}
});
Sample plunkr
Can use filter()
$('.fg-line').has('.placeInformation').filter(function(){
return !$(this).find('.placeInformation').val()
}).addClass('fg-toggled')
Not sure what "default" should be or how it is declared. Could be set in a data attribute and add an || to above filter condition
Use each() and closest()
Try this :
$(".fg-input").each(function() {
if ($(this).val() != '') {
$(this).closest(".fg-line").addClass('fg-toggle');
}
})
.fg-toggle
{
color:green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="fg-line">
<input type="text" class="form-control fg-input place-edit placeInformation" id="place_name">
<label class="fg-label">Place Name</label>
</div>
<div class="fg-line">
<input type="text" class="form-control fg-input place-edit placeInformation" id="place_address">
<label class="fg-label">Place Address</label>
</div>
You could just loop through the .place-edit class and then check the values and add the class to the parents, like this:
$('.place-edit').each(function(){
if($(this).val() != '' || $(this).val() != $(this).defaultValue) {
$(this).parent().addClass('fg-toggle');
}
})
Try this.. I'm assuming they all have the same class
if (('#place_name').value != '' || ('#place_name').value != ('#place_name').defaultValue) {
$('.fg-line').each(function(){
$(this).addClass('fg-toggle')
});
}
Related
I have a form field:
<div class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" ng-model="abc.user.name" ng-focus="abc.setFocus('name')" required>
</div>
What I need to do is set add a class to the parent element, here <div class="form-group">, when the input has focus and remove it when the field loses focus.
I know how to do this in jQuery, but not in an Angular way. I have many form fields that need to behave like this, so I'm trying to avoid setting a variable and looking for that with an ng-class. I'd rather have some way for the field to simple act on its parent, which I can use the same method in every form field.
A directive is possibly the simplest generic approach if all you need to do is manipulate the dom.
<div class="form-group" focus-class="focused">
<label>Name</label>
<input name="name" class="form-control" ng-model="abc.user.name" required>
</div>
JS
angular.module('myApp').directive('focusClass', function(){
return {
link:function(scope, elem, attrs){
elem.find('input').on('focus', function(){
elem.toggleClass(attrs.focusClass);
}).on('blur', function(){
elem.toggleClass(attrs.focusClass);
});
}
}
});
You can perform this
<div class="form-group {{focusIsSet ? 'is-focused': ''}}">
<label>Name</label>
<input type="text" name="name" class="form-control" ng-model="abc.user.name" ng-focus="focusIsSet = true" ng-blur="focusIsSet = false" required>
</div>
Where $scope.focusIsSet a boolean property. So depends of its state you can manage classes in <div class="form-group"> with that expression {{focusIsSet ? 'is-focused': ''}}
You change it with ng-focus and ng-blur directives
UPDATE
I think you can hold states for each input with that way
<div class="form-group {{checkFocusState('abc.user.name') ? 'is-focused': ''}}">
<label>Name</label>
<input type="text" name="name" class="form-control" ng-model="abc.user.name" ng-focus="setFocus('abc.user.name')" ng-blur="setBlur('abc.user.name')" required>
</div>
</div>
JS code
var inputsFocusState = {};
$scope.checkFocusState = function(propertyPathName) {
if(inputsFocusState[propertyPathName] == true) {
return true;
}
return false
}
$scope.setBlur = function(propertyPathName) {
inputsFocusState[propertyPathName] = false;
}
$scope.setFocus = function(propertyPathName) {
inputsFocusState[propertyPathName] = true;
}
Otherwise, you can create each focus property for each input in html template
P.S. ng-class is good option too
P.S.S I had similar case, but forms were completely dynamic.
So I split each property in object like user.name = {value: 'john', buttons: [...], label: 'Name', //and much more}.
Also better to change 'user.name.path' to something like 'user-name-path'.
In my app I have multiple divs which look like (The divs are created dynamically):
<div class="form-group clearfix">
<div class="form-group first-name">
<input type="text" id="firstName0" class="signup-input firstName required" name="first[0]" placeholder="">
</div>
<div class="form-group last-name">
<input type="text" id="lastName0" class="signup-input lastName" name="last[0]" placeholder="optional">
</div>
<div class="form-group email">
<input type="text" data-index="0" id="inputMail0" class="signup-input mail" name="email[0]" placeholder="e.g. example#url.com" aria-invalid="true">
<span class="common-sprite sign-up-cross first"></span>
</div>
</div>
The names are dynamically generated according to the index (For example the are email[1], email[2].....).
I have a button which should be disabled in case the field of the first name is not empty and the field of the email is empty and the span hasn't a class of disNone.
How should I disable the button according to above condition?
If I understand you correctly, you want to disable the button if all of the following conditions are met:-
First name field is NOT empty - $('#firstName0').val() != ''
Email field IS empty - $('#inputMail0').val() == ''
Span does NOT have class of disNone - !$('span').hasClass('disNone')
So I would check that condition this way by wrapping it in a listener on the keyup event upon the form:
$('.form-group').on('keyup', function () {
console.log('keyup');
if ($('#firstName0').val() !== '' && $('#inputMail0').val() === '' && !$('.email span').hasClass('disNone')) {
//Now do whatever with your button.
$('.mybutton').prop('disabled', true);
} else {
$('.mybutton').prop('disabled', false);
}
});
Demo: http://jsfiddle.net/ajj87Lg3/
Hope this condition works out for you.
Store the jQuery objects in variables and use that variables instead, which is a much better way to do it.
$(function(){
var firstName = $('#firstName0').val();
var inputMail = $('#inputMail0').val();
var checkClass = $('span').hasClass('disNone');
if( firstName!=='' && inputMail==='' && !checkClass ) {
$('button').attr('disabled','disabled'); //in the fiddle you would see an alert, you just have to replace that code with this one
}
});
EDIT: If your DIVS are being generated dynamically you can use the each() jquery function to loop through them.
$(function(){
$('#mainDiv').children('div').each(function(index,element){
var nameDiv = $(element).find(":nth-child(1)");
var firstName = $(nameDiv).find('input').val();
var emailDiv = $(element).find(":nth-child(3)");
var inputMail = $(emailDiv).find('input').val();
var spanElem = $(emailDiv).find("span");
var checkClass = $(spanElem).hasClass('disNone');
if(firstName!=='' && inputMail==='' && !checkClass){
$('button').attr('disabled','disabled');
//in the fiddle you would see a console.log('hi'), you just have to replace that code with this one for whatever button you want to disable
}
});
});
Checkout the FIDDLE LINK
In the fiddle I have left out one SPAN tag with class disNone and other SPAN tag without class disNone. So only once the condition executes
it wont submit even though the fields are not empty
here's the form:
<form id="form" role="form" method='POST' action="user_add-post.php">
<div class="form-group">
<p><label class="control-label">Title</label><br />
<input style="width: 40%" class="form-control" type="text" name="postTitle"/>
</div>
<div class="form-group">
<p><label lass="control-label">Description</label><br />
<textarea name="postDesc" cols="60" rows="10"></textarea>
</div>
<div class="form-group">
<p><label>Content</label></p>
<textarea name="postCont" cols="60" rows="10"></textarea>
</div>
<input type='submit' name="submit" class='btn btn-primary' value='Submit'></form>
and here's my jquery to check if the input fields are empty:
$('#form').submit(function() {
if ($.trim($("#postTitle").val()) === "" || $.trim($("#postDesc").val()) === "" || $.trim($("#postCont").val()) === "") {
alert('All fields required');
return false;
} });
now why won't it submit? it keeps on saying that all fields are required even though I already fill up the fields.
You have missed to add id in input boxes,
<input style="width: 40%" class="form-control" type="text" name="postTitle"/>
Change it to
<input style="width: 40%" class="form-control" type="text" id="postTitle" name="postTitle"/>
for next text box aswell ,Please Refer
you do not have define the ids so change the condition to
if ($.trim($('[name="postTitle"]').val()) === "" || $.trim($('[name="postDesc"]').val()) === "" || $.trim($('[name="postCont"]').val()) === "")
You have not given the ids to any of your form field, use global selector with condition
here is the working fiddle of your task
`$("input[name=postTitle]").val()` //name selector instead of id
If condition should be like this:
if ($("#postTitle").val().trim() == "" || $("#postDesc").val().trim() == "" || $("#postCont").val().trim() == "") {
See for any JS errors if you are getting. Also , try it on various browsers. You are not using ID attribute, but Name attritute, so it may not work on Firefox,Chrome and may work on IE7 and below. Hope this helps you
Provide Id to input element in html code.
Jquery code is fine
here is the correct code of html
<input style="width: 40%" class="form-control" type="text" name="postTitle" id="postTitle"/>
Yes like everyone else is saying if you are going to use selectors then you need those id's on the form fields. Or you can use the names like this:
$("[name=postTitle]").val()
$("[name=postDesc]").val()
$("[name=postCont]").val()
Here is your jquery with the above:
$('#form').submit(function() {
if ($("[name=postTitle]").val().trim() == "" || $("[name=postDesc]").val().trim() == "" || $("[name=postCont]").val().trim() == "") {
alert('All fields required');
return false;
} });
As others have said, the selectors are based on ID but using name attribute values. So you can add ID attributes, change the selector or use a different strategy.
Since the listener is on the form, this within the function references the form and all form controls with a name are available as named properties of the form. So you can easily test the value contains something other than whitespace with a regular expression, so consider:
var form = this;
var re = /^\s*$/;
if (re.test(form.postTitle.value) || re.test(form.postDesc.value) || re.test(form.postCont.value) {
/* form is not valid */
}
which is a lot more efficient than the OP.
Given the above, a form control with a name of submit will mask the form's submit method so you can't call form.submit() or $('#formID').submit().
I have a form that I want to validate using JQuery.
When the user leaves the form field without entering anything the class of that input changes to show an error by becoming red.
I have created a jsfiddle file
http://jsfiddle.net/mTCvk/
The problem I am having is that the it will only work on the first text input and the other text inputs will adjust according to the state of the first input.
The JQuery
$(document).ready(function(){
$('.text-input').focusout(function () {
if ($(":text").val().length == 0) {
$(this).removeClass("text-input").addClass("text-input-error");
} else {
$(this).removeClass("text-input-error").addClass("text-input");
}
});
});
Here is the HTML for the form
<form method="post" action="">
<div class="text-input">
<img src="images/name.png">
<input type="text" name="name" placeholder="*Name:">
</div>
<div class="text-input">
<img src="images/mail.png">
<input type="text" name="email" placeholder="*Email:">
</div>
<div class="text-input">
<img src="images/pencil.png">
<input type="text" name="subject" placeholder="*Subject:">
</div>
<div class="text-input">
<img src="images/phone.png">
<input type="text" name="phone" placeholder="Phone Number:">
</div>
<textarea name="message" placeholder="*Message:"></textarea>
<input type="submit" value="Send" class="submit">
It's a DOM issue. It needs to check the :text child for that specific element
$(document).ready(function(){
$('.text-input').focusout(function () {
if ($(this).find(":text").val().length == 0) {
$(this).removeClass("text-input").addClass("text-input-error");
} else {
$(this).removeClass("text-input-error").addClass("text-input");
}
});
});
Updated Fiddle http://jsfiddle.net/mTCvk/2/
It's easy, you have selected the first input type text found : $(":text").val().. You must select the input type type on the .text-input blured :
$(":text", $(this)).val()... // First :text, on $(this) parent
http://jsfiddle.net/mTCvk/1/
PS : for your class management, don't delete .text-input juste add and remove an other class .text-input-error when you have an error
You can use this:
$(":text").focusout(function () {
if ($(this).val().length == 0) {
$(this).parent().removeClass("text-input").addClass("text-input-error");
} else {
$(this).parent().removeClass("text-input-error").addClass("text-input");
}
});
Use following code....
$('.text-input, .text-input-error').focusout(function () {
if ($(this).find(':text').val().length == 0) {
$(this).removeClass("text-input").addClass("text-input-error");
} else {
$(this).removeClass("text-input-error").addClass("text-input");
}
});
I changed your code to use the .on method, and gave it the event blur. Then we create a variable for the closest text-input class (which would be its parent text-input div). Rather than checking the .length, we just check to see if it is an empty string. You would also need to wrap your textarea in the save text-input div for this to work properly.
http://jsfiddle.net/43e2Q/
$('input, textarea').on('blur', function () {
var $closestParent = $(this).parent();
if ($(this).val() == '') {
$closestParent.removeClass("text-input").addClass("text-input-error");
console.log('error');
} else {
$closestParent.removeClass("text-input-error").addClass("text-input");
console.log('valid');
}
});
Javascript:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("#first").keyup(function(event){
event.preventDefault();
ajax_check("#first");
});
$("#last").keyup(function(event){
event.preventDefault();
ajax_check("#last");
});
});
function ajax_check(current)
{
var check=$(current).val();
$.post("validate.php", {tocheck : check}, function(filled) {
if(filled == '1')
{
$(".check").html("");
$(".ajax_check").removeClass("error");
$(".ajax_check").addClass("success");
}
else
{
$(".check").html("");
$(".ajax_check").removeClass("error");
$(".ajax_check").removeClass("success");
}
})
}
HTML
<div class="control-group ajax_check">
<label class="control-label" for="first">First Name</label>
<div class="controls">
<input type="text" id="first" class="validate" placeholder="First" required>
<span class="help-inline check" ></span>
</div>
</div>
<div class="control-group ajax_check">
<label class="control-label" for="last">Last Name</label>
<div class="controls">
<input type="text" id="last" class="validate" placeholder="Last" required>
<span class="help-inline check" ></span>
</div>
</div>
The issue I'm having is when I enter in info for one of the input, the other one gets highlighted too, which isn't suppose to happen. And I think my code is kind of sloppy, but I'm trying to reuse the ajax_check function instead of making a function for each input field.
Is there a way I could reuse the function for both of the inputs? I'm new to Javascript, so I'm kind of lost. Thank you!
http://i.imgur.com/BiLObRF.png
it has to do with the scope you're requesting .check within in the ajax call. You're going back to document-level (instead of just within the current node). A simple change makes this work as intended:
var $this = $(current), // store reference to jquery object
$scope = $this.closest('.ajax_check'), // set scope to .ajax_check
check = $this.val();
$.post("validate.php", {tocheck : check}, function(filled) {
if(filled == '1')
{
// use .find() to search _within_ $scope and not across
// the entire document.
$scope.find(".check").html("");
$scope.removeClass("error").addClass("success");
}
else
{
// same thing, search within $scope
$scope.find(".check").html("");
$scope.removeClass("error success");
}
})
You can also refactor your bindings a bit to make this a little more brief as well:
$("#first,#last").keyup(function(event){
event.preventDefault();
ajax_check(this); // this is automatically going to be #first or #last
// just by the selector above
});
You can use comma to add items in selector, you can use this to get current element,
$("#first, #last").keyup(function(event){
event.preventDefault();
ajax_check('#'+this.id);
});
OR, pass object instead of id.
$("#first, #last").keyup(function(event){
event.preventDefault();
ajax_check($(this));
});
function ajax_check(current)
{
var check=current.val();
You need to save the this reference and search the closest form :
function ajax_check(e)
{
e.preventDefault()
var $this = $(this)
var check=$this.val();
$.post("validate.php", {tocheck : check}, function(filled) {
$this.siblings(".check").html("");
$this.closest(".ajax_check").removeClass("error").toggleClass("success", filled == '1');
})
}
$("#first, #last").keyup(ajax_check);
siblings
closest