Using bassistance jquery-validator with formtowizard plugin - javascript

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();
});

Related

How to change the label of a checkbox in JavaScript?

Note: Willing to use jQuery, whatever is easier.
I have a form which when submitted, creates a checkbox input. The text of the checkbox should be equal to that of another text input when the form is submitted.
The checkbox is created as expected when I submit the form but it is blank and doesn't contain the text from the corresponding text area.
For a checkbox i'm not sure if I should be using .text, .innerhtml, .val etc and the previous questions I saw on here seemed unnecessarily complicated.
HTML:
<div id="listContainer">
<form id="listForm">
<input type="submit" value="Add">
<input id="listInput" class="textarea" placeholder="Add your list item here, then click submit.">
<div id="checkboxContainer">
</div>
</form>
</div>
JS:
//ADD LIST ITEM
$("#listForm").submit(function(ev) {
ev.preventDefault();
if ($("#listInput").val() == "") {
alert("Please enter the item name, then click 'Add'.");
} else {
listCount++;
var input = $("#listInput").val();
console.log("List Count: " + listCount);
console.log(input);
var cb = document.createElement('input');
cb.id = 'input' + listCount;
cb.type = 'checkbox';
document.getElementById("checkboxContainer").appendChild(cb);
var label = document.createElement('label');
label.id = 'label' + listCount;
$("#label" + listCount).attr("for", "input" + listCount).html(input);
document.getElementById("checkboxContainer").appendChild(label);
//Store the list count
localStorage.setItem("listCount", listCount);
//Store the list title
localStorage.setItem("input" + listCount, input); //"Note " + noteCount + ": " +
this.submit();
}
});
var label = document.createElement('label');
label.id = 'label' + listCount;
$("#label" + listCount).attr("for", "input" + listCount).html(input);
document.getElementById("checkboxContainer").appendChild(label);
These four lines can be cleaned up and fixed. The issue here is quite simple, however your constant back-and-forth between jQuery and plain JS makes things very difficult to read. I would suggest writing DOM manipulation in one or the other, but never both.
The error here is on the third line, which uses the selector $("label" + listCount). This selector will look for this element on the page, however you've only created the element - you haven't added it to the page yet.
Let's correct this and rewrite it in jQuery:
$("<label />") //create new label
.attr("id", "label" + listCount) //set ID
.attr("for", "input" + listCount) //set For
.html(input) //set contents
.appendTo("#checkboxContainer"); //add to checkbox container
Consider using the example above to rewrite your checkbox creation as well, that way you can avoid the mixture of jQuery/plain JS.

How to bring Radio Buttons inside an html link using Javascript

I’m looking for some help bringing Radio buttons that we have on a page inside a link. At the moment we have a Quiz with various questions with 4 possible choices for the respondent to choose. The text links work fine and advance the user to the next page, but the radio buttons don’t work. They are clickable, but they don’t advance you to the next page.
How would I bring the Radio buttons inside the link? I want the Radio buttons to send you forward, just like the text links.
Here is the test page for the Quiz (need to press Start Quiz to see the Radio buttons):
http://stephanieshipper.com/test/
Here is the piece of code from the .js file:
function updates(questions) {
for (i = 0; i < 20; i++) {
$("body").append("<article><p>" + questions[i] + "</p><input id='question-" + (i*10) + "-1' type='radio' order='1' name='question-" + i + "-0'><label for='question-" + (i*10) + "-1'>exactly like me</label><br><input id='question-" + (i*100) + "-2' type='radio' order='2' name='question-" + i + "-0'><label for='question-" + (i*100) + "-2'>sort of like me</label><br><input id='question-" + (i*1000) + "-3' type='radio' order='3' name='question-" + i + "-0'><label for='question-" + (i*1000) + "-3'>not really like me</label><br><input id='question-" + (i*10000) + "-4' type='radio' order='4' name='question-" + i + "-0'><label for='question-" + (i*1000) + "-4'>not at all like me</label><br></article>");
}
motions();
}
function motions() {
var step = 1;
results = [];
var order;
$("body > article > label").on("click", function() {
$(this).parent().hide(250);
if (step < 20) {
$(this).parent().next().show(250);
order = parseInt($(this).prev().attr("order"));
results[step-1] = order;
step++;
} else {
As I see, your are calling the next page just if the user click on the label tag :
$("body > article > label").on("click", function() {}
What you gonna need to do it's adding the radio button(your input tag), into this jquery
eg.:
$("input[type='radio']")
So maybe would work :
$("body > article >input[type='radio'] > label").on("click", function() {}

append() in jquery does'nt append file second time

I have defined an input of type file and a hidden form below it,
<input type="file" name="attachment0" id="attachment0" custom-on-change="uploadfile" ng-show="attachFile" multiple/>
<form class="hidden" id="myForm" method="post" enctype="multipart/form-data" action="SupportRequest">
</form>
"custom-on-change" is an angular directive that calls the function uploadfile() after choosing files. My javascript looks as shown below
var form = $('#myForm');
var n=0;
$scope.attachFile = true;
$scope.uploadfile = function() {
if(n == 0){
var filein = $('#attachment0');
form.append(filein);
$('#attachment0').test();
}
else
{
if(n==1){
var temp = "attachment0" + '_' + n;
var file_in = $('#'+temp);
form.append(file_in);
$('#'+temp).test();}
}
};
$.fn.test = function() {
return this.each(function(){
n++;
$(this).attr('id', this.id + '_' + n);
$(this).attr('name', this.name + '_' + n);
});
};
Am trying to append files twice to the form myForm. When i choose files second time, even after appending, i see that the previously appended input with id="attachment0" is not present in myForm and the input of id="attachment0_1" is present in the form.
Here am trying to upload multiple files multiple times, that is why am dynamically changing the id of the input in test().
I want both input with id attachment0 and attachment0_1 in myForm.
Does anyone know how this can be fixed? And explain this behavior too.
Change your code from form.append(filein) to form.append($('#attachment0').clone()).
It work then. You should use .clone() method to copy elements .
.append() just moves the element from one place to another but for copying first create the copy of the element using .clone() and then append it to your form
looks like in test function you are replacing id,
$(this).attr('id', this.id + '_' + n);
Would is not be better to use ng-repeat? Something like this:
Controller:
$scope.files = [...] // list of files
$scope.uploadfile = function() {
// So stuff to get the file
$scope.files.push(filein);
};
Html:
<!-- Inside the form -->
<div ng-repeat="file in files">{{file}}</div>

Dynamically building a button with an onClick

I am dynamically building a button in JavaScript, this will include an onClick event. The onClick event needs to focus a field which is stored in a variable.
I couldn't find a way of using the field variable itself, so instead decided to try using the field.selector property from the JQuery object, this WILL contain " ".
Here is a code snippet of the construction as it stands.
InvalidField.prototype.getMessageStructure = function(){
var structure = '<div class="invalidMessage"><span>' + this._message + '</span>
<button class="inputButton"
Value="Go To Field"
onclick=\'goToFieldFromAlert($(\'' + this._field.selector + '\'))\'
/>
</div>';
return structure;
};
This is outputting:
<button class="inputButton"
value="Go To Field"
onclick="goToFieldFromAlert($(" input[name="applicant.email" ]'))'="">
</button>
As you can see, the quotations will not be out put correctly and so break on click.
Can anyone foresee a better way of performing this function, or correcting the quotations? I see from this SO Answer that the DOM doesn't respect the quotations which is what is currently causing me the issue.
Kind Regards.
As I mentioned in comment, avoid using onclick at all. jQuery event handlers are far more flexible (and support multiple event handlers).
1) Inject the fieldname (only, not the jQuery selector) into a data- attribute:
InvalidField.prototype.getMessageStructure = function(){
var structure = '<div class="invalidMessage"><span>' + this._message + '</span>
<button class="inputButton"
value="Go To Field" data-field="' + this._field.name + '"/>
</div>';
return structure;
};
2) Use a delegated event handler to get all clicks on inputButtons with less overhead. Extract the field name and do the jQuery where it belongs:
$(document).on('click', '.inputButton', function() {
var $button = $(this);
var field = $button.data('field');
goToFieldFromAlert('input[name="' + field + '"]');
});
You should create element using jQuery. This is much cleaner and error free approach
An example with your code
InvalidField.prototype.getMessageStructure = function(){
var structure =
$('<div></div>').append(
$('<span></span>').text(this._message)
);
structure.append(
$('<button></button>')
.addClass('inputButton')
.text("Go To Field")
.click(function(){
goToFieldFromAlert($(this._field.selector));
})
);
return structure;
};
The following example will dynamically add buttons:
hello.forEach( function(result) {
var card = document.createElement("input");
card.type = "button";
card.onclick = function() {
newcard( result );
}
card.value = value; // some value
card.style.backgroundColor="#5ABC7B";
document.body.appendChild(card);
});

Getting ALL children from all levels

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.

Categories

Resources