im about to develop a Formvalidator. I use a global Function which i call before every form-submit, i also give the form ID for accessing the inputs. so the function looks like this:
function FormValidation(formId)
{
var validated = true;
$("#" + formId ).each(function ()
{
var message="";
if ($(this).attr("data-validation-required") == "true" && $(this).val() == "") {
message += "-This field is required<br/>";
validated = false;
if (message != "")
$(this).after('<div class="popover fade bottom validation-error in" style="position:relative;display: block; margin-top:0px;"><div class="arrow" style="left:10% !important;"></div><div class="popover-content" style="color:#c0392b;">' + message + '</div></div>');
}
return validated; //true or false
}
so the problem is, that this each loop i wrote, is not accessing ALL children which are within the given "form" (by formId). Its accessing only the FIRST level children.
Here's some HTML example code:
<form id="myform">
<input type="text" data-validation-required="true"/> <-- will be accessed -->
<div class="SomeDivClass">
<input type="text" data-validation-required="true"/> <-- will NOT be accessed because 2nd level -->
</div>
</form>
<script>
$("#myform").submit(function(){
if(!FormValidation("myform"))
return false;
});
</script>
There are few issues in the given code
function FormValidation(formId) {
var validated = true;
//use descendant selector to find all required fields
$("#" + formId + ' [data-validation-required="true"]').each(function () {
//check whether the value is empty, if so mark as invalid
if ($(this).val() == "") {
var message = "-This field is required<br/>";
validated = false;
$(this).after('<div class="popover fade bottom validation-error in" style="position:relative;display: block; margin-top:0px;"><div class="arrow" style="left:10% !important;"></div><div class="popover-content" style="color:#c0392b;">' + message + '</div></div>');
} else {
//remove the validation of it is again become valid
$(this).next('.validation-error').remove()
}
//don't return the validated from the each loop since returning false here will cause the each loop to stop further iterations
})
return validated; //true or false
}
$("#myform").submit(function () {
if (!FormValidation("myform")) {
return false;
}
});
Demo: Fiddle
You could get all elements with data-validation-required via $('#' + formId +' [data-validation-required!=""]')
The jQuery API for traversing the DOM is incredibly well documented. To get all descendants of an element, you'd use .find(), along with a selector that didn't exclude anything — * — so your code would end up as follows:
$("#" + formId ).find( '*' ).each(function (){
But seeing as you're already creating a CSS selector to select the form, you may as well simply extend that selector:
$("#" + formId + " *").each(function (){
Your current form isn't even iterating the children — it's iterating over each form, and there's only one.
Related
I have a div with an id like: comment-box-5 and I want to see using javascript if there is a form inside of it if so remove it if not add it (so it toggles when I call the function). I wrote this piece of code to try to do this:
function reply(id){
console.log(document.getElementById('comment-id-' + id).innerHTML.indexOf(document.getElementById('form-' + id)));
if (document.getElementById('comment-id-' + id).innerHTML.indexOf(document.getElementById('form-' + id))) {
var form = replyFn(id);
document.getElementById('comment-id-' + id).appendChild(form);
} else {
//for toogle effect
document.getElementById('comment-id-' + id).removeChild(document.getElementById("form-" + id));
}
}
And I tried executing it but console.log(document.getElementById('comment-id-' + id).innerHTML.indexOf(document.getElementById('form-' + id))); prints -1 even if there is a form inside.
What am I doing wrong? how can I actually see if there is a form in the div?
You could change your condition to :
if ( document.querySelector('#comment-id-' + id +'>#form-' + id) ) {
//Your if logic
}else{
//Your else logic
}
Snippet :
var id = 1;
if (document.querySelector('#comment-id-' + id + '>#form-' + id)) {
console.log('Remove form');
} else {
console.log('Add form');
}
<div id="comment-id-1">
<form id="form-1"></form>
</div>
Try using contains on the div without innerHTML like below, I changed the code from yours a bit to do the example but it should work for yours as well.
console.log(document.getElementById('comment-id-1').contains(document.getElementById('form-id-1')));
<div id="comment-id-1"><form id="form-id-1"></form></div>
i have this code that i use, and on click i put email in field, but what i want to accomplish is that on next click on same field it removes email if one already exist in input.
Here is my code:
<p class="email">mail1#gmail.com</p>
<p class="email">something#gmail.com</p>
<p class="email">third#gmail.com</p>
<input type="text" id="contact-email" value="" class="form-control" style="width:500px" />
And js:
var $contact = $('#contact-email');
$('.email').on('click', function () {
if ($contact.val()) {
$contact.val($contact.val() +'; '+ $(this).text());
} else {
$contact.val($(this).text());
}
});
and fiddle https://jsfiddle.net/2dffwew5/2/
I would store selected email addresses to an array. Then push or splice the clicked email.
var $contact = $('#contact-email');
var emails = [];
$('.email').on('click', function () {
var index = emails.indexOf($(this).text());
if (index > -1) {
emails.splice(index, 1);
} else {
emails.push($(this).text());
}
$contact.val(emails.join(";"));
});
https://jsfiddle.net/jdgiotta/ze7zebzq/
I would suggest that you add a check to see if the current text contains the selected email address. If it does, then remove it. Otherwise add it.
You will also need to cater for leading/trailing dividers, which can easily be done with a couple of conditional checks.
Something like this:
var $contact = $('#contact-email');
$('.email').on('click', function () {
var text = $(this).text(); // Get the value to insert/remove.
var current = $contact.val(); // Get the current data.
// Check if the value already exists with leading seperator, if so remove it.
if (current.indexOf('; ' + text) > -1) {
$contact.val(current.replace('; ' + text, ''));
}
// Check if the value already exists with trainling seperator, if so remove it.
else if (current.indexOf(text + '; ') > -1) {
$contact.val(current.replace(text + '; ', ''));
}
// Check if the value already exists with no seperator (on it's own), if so remove it.
else if (current.indexOf(text) > -1) {
$contact.val(current.replace(text, ''));
}
// Otheriwse, it doesn't exist so add it.
else {
if (current) {
$contact.val(current + '; ' + text);
} else {
$contact.val(text);
}
}
});
Here is a working example
I am trying to get all span elements inside the form. The span elements are turning into input text fields and become editable. When you click away they are turning back into span elements. I will attached fiddle live example.
I gave it a go but the problem is that I am getting both ids but only value of the first span element.
Here is my html:
<span name="inputEditableTest" class="pztest" id="inputEditableTest" data-editable="">First Element</span>
<span name="inputEditableTest2" class="pztest" id="inputEditableTest2" data-editable="">Second Element</span>
<input id="test" type="submit" class="btn btn-primary" value="Submit">
And here is JavaScript with jQuery:
$('body').on('click', '[data-editable]', function () {
var $el = $(this);
var name = $($el).attr('name');
var value = $($el).text();
console.log(name);
var $input = $('<input name="' + name + '" id="' + name + '" value="' + value + '"/>').val($el.text());
$el.replaceWith($input);
var save = function () {
var $p = $('<span data-editable class="pztest" name="' + name + '" id="' + name + '" />').text($input.val());
$input.replaceWith($p);
};
$input.one('blur', save).focus();
});
$("#test").on('click', function(){
var ok = $("span")
.map(function () {
return this.id;
})
.get()
.join();
var ok2 = $("#" + ok).text();
alert(ok);
alert(ok2);
//return [ok, ok2];
});
Here is the fiddle https://jsfiddle.net/v427zbo1/3/
I would like to return the results as an array example:
{element id : element value}
How can I read ids and values only inside specific form so something like:
<form id = "editableForm">
<span id="test1">Need these details</span>
<span id="test2">Need these details</span>
<input type="submit">
</form>
<span id="test3">Don't need details of this span</span>
Lets say I have got more than 1 form on the page and I want JavaScript to detect which form has been submitted and grab values of these span elements inside the form
I will be grateful for any help
$("#test").on('click', function(){
var result = {};
$("span").each(function (k, v) {
result[v.id] = v.innerHTML;
});
alert(JSON.stringify(result));
//return [ok, ok2];
});
Here is an example: https://jsfiddle.net/v427zbo1/4/
Container issue:
You should use this selector: #editableForm span if you want to get all the divs inside this container.
$("#editableForm span").each(function (k, v) {
result[v.id] = v.innerHTML;
});
But if you want to get only first-level children elements then you should use this selector: #editableForm > span
Example with getting all the spans inside #editableForm container: https://jsfiddle.net/v427zbo1/9/
If you want to have several forms, then you can do like this:
$('form').on('submit', function(e){
e.preventDefault();
var result = {};
$(this).find('span').each(function (k, v) {
result[v.id] = v.innerHTML;
});
alert(JSON.stringify(result));
//return [ok, ok2];
});
Example with two forms: https://jsfiddle.net/v427zbo1/10/
You can't use .text to return the value of multiple elements. It doesn't matter how many elements are selected, .text will only return the value of the first one.
Virtually all jQuery methods that return a value behave this way.
If you want to get an array of values for an array of matched elements, you need another map. You also need to join the strings with , # as you're producing something along the lines of #id1id2id3 instead of #id1, #id2, #id3:
var ok = $("span").map(function () {
return this.id;
}).join(', #')
var ok2 = $("#" + ok).map(function () {
return $(this).text();
});
That said, you're already selecting the right set of elements in your first map. You pass over each element to get its ID, you already have the element. There is no reason to throw it away and reselect the same thing by its ID.
If I got you right following code will do the job
var ok = $("span")
.map(function () {
return {id: $(this).attr('id') , value: $(this).text()};
}).get();
Check this fiddle.
I'm using the FormToWizard Jquery plugin with this Bassistance validation plugin. I have attached my next button to a click event which validates my form however I only want it to validate the current fieldset not the whole form.
What formtowizard does is show one fieldset at a time and generate next and back buttons in each fieldset to browse around the form.
It goes like this:
<form id="SignupForm" method="POST" action="..................">
<fieldset>
<legend>Step One</legend>
<div>
</div>
</fieldset>
<fieldset>
<legend>Step Two</legend>
<div>
</div>
</fieldset>
</form>
And this is how i declared the bassistance validator
$("a.next").click(function() {
$("#formID").validate();
});
And I found this code from this already answered topic about the very same problem but it doesn't seem to work!
Validate between fieldsets
He basically added a few lines of code in an existing FormToWizard plugin method.
function createNextButton(i) {
var stepName = "step" + i;
$("#" + stepName + "commands").append("<a href='#' id='" + stepName + "Next' class='next'>Next</a>");
$("#" + stepName + "Next").bind("click", function(e) {
/* VALIDATION */
if (options.validationEnabled) {
var stepIsValid = true;
$("#"+stepName+" :input").each(function(index) {
checkMe = element.validate().element($(this));
//stepIsValid = !element.validate().element($(this)) && stepIsValid;
stepIsValid = checkMe && stepIsValid;
});
//alert("stepIsValid === "+stepIsValid);
if (!stepIsValid) {
return false;
};
};
$("#" + stepName).hide();
$("#step" + (i + 1)).show();
if (i + 2 == count)
$(submmitButtonName).show();
selectStep(i + 1,'next');
});
}
Any idea how to get this work? I am not a jquery/javascript pro since I am just starting, I am still trying to learn how the syntax work and why that person made those changes.
I found the error. I forgot to declare the variable validationEnabled. Adding that fixed the problem.
May give the fieldset an id like <fieldset id="validate"></fieldset> an use the id with your function : $("a.next").click(function() {
$("#validate").validate();
});
I have a dropbox that when selected it displays its respective fields
in first image you can see there is A person without an ID so when selected it displays
something like:
if you see I added 12
Now if i change my mind and select the other option (person with ID) one field is displayed like:
I added 9999
That is ok, but now if I change my mind again and return to other selected option the values are still there like:
I would like to clean them... How can I accomplish that?
It does not matter to fill all respective fields again, I want to reset values in that case if select
person without ID, delete the 9999, on the other hand, if i select person with Id, i want to reset the vakue 12
please take a look at my fiddle
some of the jquery code is:
//function available
function validate(id, msg) {
var obj = $('#' + id);
if(obj.val() == '0' || obj.val() == ''){
$("#" + id + "_field_box .form-error").html(msg)
return true;
}
return false;
}
$(function () {
$('#has_id').show();
$('#select_person').change(function () {
$('.persons').hide();
if ($('#select_person').val() == 'typeA') {
$("#has_id").html('');
$("<option/>").val('0').text('--Choose Type A--').appendTo("#has_id");
$("<option/>").val('person-A-withID').text('person-A-withID').appendTo("#has_id");
$("<option/>").val('person-A-withoutID').text('person-A-withoutID').appendTo("#has_id");
}
if ($('#select_person').val() == 'typeB') {
$("#has_id").html('');
$("<option/>").val('0').text('--Choose Type B--').appendTo("#has_id");
$("<option/>").val('person-B-withID').text('person-B-withID').appendTo("#has_id");
$("<option/>").val('person-B-withoutID').text('person-B-withoutID').appendTo("#has_id");
}
});
$('#has_id').change(function () {
$('.persons').hide();
$('#' + $(this).val()).show();
});
});
var validation = function(){
var err = 0;
err += validate('select_person', "select person.");
err += validate('has_id', "Select whether it has an ID or not.");
if(err == 0){
alert('continue');
}else{
alert('error');
}
};
Simply make this change:
$('#has_id').change(function () {
$('.persons input').val('');
$('.persons').hide();
$('#' + $(this).val()).show();
});
New fiddle: http://jsfiddle.net/6m27M/
This simply clears out all the values any time a change is made to the #has_id dropdown.