Multiple form fields with same 'name' attribute not posting - javascript

I'm dealing with some legacy HTML/JavaScript. Some of which I have control over, some of which is generated from a place over which I have no control.
There is a dynamically generated form with hidden fields. The form itself is generated via a Velocity template (Percussion Rhythmyx CMS) and JavaScript inserts additional hidden form fields. The end result is hidden form fields generated with the same 'name' attribute. The data is being POSTed to Java/JSP server-side code about which I know very little.
I know that form fields sharing the same 'name' attribute is valid. For some reason the POSTed data is not being recognized the back end. When I examine the POST string, the same-name-keys all contain no data.
If I manipulate the code in my dev environment such that only a single input field exists for a given name, the data IS POSTed to the back end correctly. The problem is not consistent, sometimes, it works just fine.
Is there something I can do to guarantee that the data will be POSTed? Can anyone think of a reason why it would not be?
I should really update my answer and post code here, because POST requests without
variable strings indicates the problem is on the client side.

How about this:
<script type="text/JavaScript">
function disableBlankValues()
{
var elements = document.getElementById("form1").elements;
for (var i = 0; i < elements.length; i++)
{
if (elements[i].value == "")
elements[i].disabled = true;
}
}
</script>
<form action="page.php" method="POST" onsubmit="disableBlankValues()" id="form1">
<input type="hidden" name="field1" value="This is field 1."/>
<input type="hidden" name="field1" value=""/>
</form>
EDIT
I now realize the actual problem (multiple variables with the same name should be passed to JSP as an array) and my solution is probably not what the OP is looking for, but I'm leaving it here just in case it happens to help someone else who stumbles upon this post.

you could use something like:
var form = document.getElementById('yourformid');
var elements = form.getElementsByName('repeatedName');
var count = 0;
for(var item in elements){
elements[item].name += count++;
}
this way you will get each hiddenfield with the names:
name0
name1
name2
...

I've worked out a brute-force solution. Note that I'm pretty aware this is a hack. But I'm stuck in the position of having to work around other code that I have no control over.
Basically, I've created an ONSUBMIT handler which examines the form for the repeated hidden fields and makes sure they are all populated with the correct data. This seems to guarantee that the POST string contains data regardless of how the form gets rendered and the Java back end appears to be happy with it as well.
I've tested this in the following situations:
Code generates single instances of the hidden fields (which does happen sometimes)
Code generates multiple instances of the hidden fields
Code generates no instances of the hidden fields (which should never happen, but hey...)
My 'else' condition contains a tiny bit of MooTools magic, but it's otherwise straight-forward stuff.
Maybe someone else will find this useful one day...
Thanks for the help!
<form method="post" name="loginform" id="loginform" action="/login" onsubmit="buildDeviceFP(this);">
<script type="text/javascript">
function insertFieldValues( fields, sValue )
{
if ( 'length' in fields )
{
// We got a collection of form fields
for ( var x = 0; x < fields.length; x++ ) {
fields[x].value = sValue;
}
}
else
{
// We got a single form field
fields.value = sValue;
}
}
function buildDeviceFP( oForm )
{
// Get the element collections for Device Fingerprint & Language input fields from the form.
var devicePrintElmts = oForm.elements.deviceprint;
var languageElmts = oForm.elements.language;
// 'devicePrintElmts' & 'languageElmts' *should* always exist. But just in case they don't...
if ( devicePrintElmts) {
insertFieldValues( devicePrintElmts, getFingerprint() );
} else if ( oForm.deviceprint ) {
oForm.deviceprint.value = getFingerprint();
} else {
$('logonbox').adopt(
new Element( 'input', {'type':'hidden', 'name':'deviceprint', 'value':getFingerprint()} )
);
}
if ( languageElmts) {
insertFieldValues( languageElmts, getLanguage() );
} else if ( oForm.language ) {
oForm.language.value = getLanguage();
} else {
$('logonbox').adopt(
new Element( 'input', {'type':'hidden', 'name':'language', 'value':getLanguage()} )
);
}
}
</script>

Related

javascript validation of the elements

I am running a code for my validatio where i am facing some issues
I have created a function to validate but based upon my html a little bit help is needed
Here it is:
My HTML code look alike
<div class="el-form-item">
<label for="streetAddress" class="el-form-item__label">Street Address</label>
<div class="el-form-item__content">
<div class="el-input">
<input type="text" autocomplete="off" class="el-input__inner validate">
</div>
</div>
</div>
here is the validation Function
function validate(){
var validateElements = document.getElementsByClassName("validate");
var inputs = Array.prototype.filter.call(validateElements,function(element){
return element.nodeName === 'INPUT';
});
for(var i=0; i < inputs.length; i ++ ){
var input = inputs[i];
if(input.value.length == 0){
// generic placeholder
input.placeholder = "kindly enter value";
// error class
input.classList.add("err");
// focus on the input [ optional ]
console.log(input.closest('.el-form-item__label'));
input.closest('.el-form-item__label').classList.add('err'); // error happening here
input.focus();
// break the loop [ optional ]
break;
}
}
}
two things i am trying to do here
i want to cover the label also to red which is defined in the .err class
and also want to place the error just underneath the input element instead of inside the placeholder.
i posted my code code above, please guide
i hope the making this validation function as mixin so i can use in my vueJS app, if anyone can guide with that, would be much much appreciated
i am trying to include inputs first and then plan to bring other form elements with this.

How do you return data from javascript into a html form?

I was wondering if anyone can help? What I am trying to do is retrieve the word count from javascript code into a form and then pass it into php along with the rest of the form which will check that the word count is a certain length or else it won't be submitted.
The javascript is as follows.
counter = function() {
var value = $('#msg').val();
if (value.length == 0) {
$('#wordCount').html(0);
$('#totalChars').html(0);
$('#charCount').html(0);
$('#charCountNoSpace').html(0);
return;
}
var regex = /\s+/gi;
var wordCount = value.trim().replace(regex, ' ').split(' ').length;
var totalChars = value.length;
var charCount = value.trim().length;
var charCountNoSpace = value.replace(regex, '').length;
$('#wordCount').html(wordCount);
$('#totalChars').html(totalChars);
$('#charCount').html(charCount);
$('#charCountNoSpace').html(charCountNoSpace);
};
$(document).ready(function() {
$('#count').click(counter);
$('#msg').change(counter);
$('#msg').keydown(counter);
$('#msg').keypress(counter);
$('#msg').keyup(counter);
$('#msg').blur(counter);
$('#msg').focus(counter);
});
My problem is returning wordCount into a hidden field in a form. I am not too good with javascript and am not sure how to modify this code to make it work. The rest I can figure out but am stuck here. Thank you for your help, it is greatly appreciated.
$('#wordCount').val(wordCount);
$('#totalChars').val(totalChars);
$('#charCount').val(charCount);
$('#charCountNoSpace').val(charCountNoSpace);
Use .val() instead of .html(), because .val() refers to the value of an input field.
Your HTML inside the form should include a hidden input field:
<input type="hidden" id="word_count" name="word_count" value="0" />
Then inside your JS:
$('#word_count').val(wordCount);
All together embedded inside your function:
counter = function() {
var value = $('#msg').val();
if (value.length == 0) {
$('#wordCount').html(0);
$('#totalChars').html(0);
$('#charCount').html(0);
$('#charCountNoSpace').html(0);
return;
}
var regex = /\s+/gi;
var wordCount = value.trim().replace(regex, ' ').split(' ').length;
var totalChars = value.length;
var charCount = value.trim().length;
var charCountNoSpace = value.replace(regex, '').length;
$('#wordCount').html(wordCount);
$('#word_count').val(wordCount);
$('#totalChars').html(totalChars);
$('#charCount').html(charCount);
$('#charCountNoSpace').html(charCountNoSpace);
};
$(document).ready(function() {
$('#count').click(counter);
$('#msg').change(counter);
$('#msg').keydown(counter);
$('#msg').keypress(counter);
$('#msg').keyup(counter);
$('#msg').blur(counter);
$('#msg').focus(counter);
});
If you have INPUT fields in your form, use val()
$('#wordCount').val(wordCount)
That would work for a field like this:
Be aware that there's a difference between "id" and "class". jQuery allows you to select elements based on their properties. The "id" property gets selected with "#", just like you'd do it in CSS. So make sure you have that "id='wordCount'" defined in your hidden field.
Have a look at this http://www.hscripts.com/scripts/JavaScript/word-count.php
There are plenty of examples online, just google "javascript count words in textbox"
Some imporntant notes:
A very long string with no spaces is still 1 word so don't forget to set the max length for fields
If you are doing this as a sort of validation be aware of the fact that you can not trust a form field because it can be easily manipulated, so don't forget to check the word count on the server side after the form is submitted.
The Code that you are showing is not just javascript it also includes jquery, please make sure you included jquery
<script src = "http://code.jquery.com/jquery-1.11.1.min.js"></script>
$('#field').val('asdf'); //Sets Value of a input type="text"
$('#field').html('sadf'); //Sets the html of a div
Using javascript you use either value for a input or innerHtml for a div or other text based element
document.getElementById('field').value = 'asdfsadf';
document.getElementById('field').innerHtml= 'asdfsadf';
Also instead of using a form submit consider using jquery $.ajax(there is nothing wrong with form submits but there are benefits to knowing jquery as well such as you came make async requests
http://api.jquery.com/jquery.ajax/
You will want to use a hidden field such as the following and have it in the form
<form id="myform" action='posttome.php'>
<input type="hidden" id="wordCount"/>
<input type="submit" value="sbumit"> //Submits Form
</form>
Then set its value by using of of three methods, a an elements html, an elements value, or a javascript variable $('#wordCount').val()
$('#wordCount').val($('#wordCountSoruceDiv').html()); // Sets the value to another divs html
$('#wordCount').val($('#wordCountSourceInput').val()); // Sets the value to another inputs value
$('#wordCount').val(wordCountVariable); // Sets the value to a variable

Form validation with jQuery Validate plugin

after a long research on internet i'm about to give up, let's say you are my last hope. My problem: I'm implementing a timesheet form for my company. This form is dynamic because in a day you can do several activities. The fields (included in a PHP page) are:
Day (text field)
Hours (drop down)
Notes (a text field where the employee can write notes for the day)
All the fields listed are in a row enclosed in a fieldset. On the top of field set i've put a button, clicking it I will add another row with the data listed before. Now, before submitting to backend, I want, of course, put some validation rules which are the following:
Field DAY must be required (it's my key in DB and i've added a DatePicker plugin)
The sum of hours in an entire day can't exceed the 8 hours
I've tried to use Jquery Validate but seems I have two problems:
It can't handle in somehow the arrays of data going to the script php that will write down on DB (for example the days submitted will arrive to backend in an array, I've decided this way because the number of days that can be recorded is not known before submission)
It adds the controls only on first row
I've tried (as I've read in other posts) to add rules after the creation of new row, but, in that case, it works on other fields only if i put the cursor inside, I leave the field blank and then I click outside that field.
I attach my code, any help would be appreciated!!
greetings from Italy.
<script type="text/javascript">
$(document).ready(function() {
var i = 0;
//fadeout selected item and remove
$('.remove').live('click', function() {
$(this).parent().fadeOut(300, function(){
$(this).empty();
return false;
});
});
$('a#add').click(function() {
i++;
var options = '<p>Day <input type="text" id = "Day'+i+'" class = "Day" name="day[]"> </select> hours<select id = "hours'+i+'" class = "hours" name="hours[]"><option value="1">1</option><option value="2">2</option><option value="3">3</option><option value="4">4</option><option value="5">5</option><option value="6">6</option><option value="7">7</option><option value="8">8</option></select> Notes <input type="text" id="Note'+i+'" class = "Note" name="note[]"><img src="images\\remove.png" height="20" width="20"></img></p>';
$(options).fadeIn("slow").appendTo('#extender');
});
$('.Day').live('click', function() {
$(this).datepicker('destroy').datepicker({
changeMonth: false,
changeYear: false,
stepMonths: false,
dateFormat: "dd-mm-yy",
showOn:'focus'}).focus();
});
});
</script>
this is where the dynamic fields are appended
<form name="rec_abs" method="post" action = "rec_on_db.php">
<fieldset>
<legend>Timesheet</legend>
<div id="extender"></div>
<p><img src="images\add.png" alt="" border=3 height=20 width=20></img> </p>
</fieldset>
</form>
<input type="submit" value="Send your timesheet"></input><br>
Regarding the fact that your elements are only validated when you change them, you can try using the plugin's onsubmit option:
$("form[name='rec_abs']").validate({
onsubmit:true
});
When it comes to validating multiple fields, I'd suggest adding a class rule to your validation using the addClassRule method.
Define your rule the following way:
$.validator.addClassRules("my-day", {
required: true
});
Then add the my-day class to your day elements.
Regarding the sum of the hours, look into the addMethod method. It enables you to define custom validation rules. Here's an example that checks if a phone number is in the +XXXXXX format (X is a number, + is optional):
$.validator.addMethod("phone", function(value, element) {
// no phone number is a good phone number (the field is optional)
if (value.length == 0) { return true; }
// use a regexp to test the if the value is in the '+XXXXXX..' form
return /^\+?(\d){5}\d+/i.test(value);
}, 'Invalid phone number');
I've managed to get my validation to work on ajax loaded content before, while retaining my script in a separate file using class rules and custom methods.
Thanks for reply Sir Celsius. Now with the first modification you suggested I can validate my form at submit. There is more than this by the way. I modified the code generating the dynamic form as follows:
$('a#add').click(function() {
i++;
var options = ' .... html of the row as before ...';
$(options).fadeIn("slow").appendTo('#extender');
$('#Day'+i).rules('add', {
required: true,
messages: {
required: ""
}
});
$('#Hours'+i).rules('add', {
required: true,
messages: {
required: ""
}
});
});
With these lines I add rules at newly created parts of document. I've put a counter just to make every cell have its own ID, class name remains the same. For my purpose I have to put data in arrays, every type of data has its own vector. Here is the problem. If all the fields have different IDs (OK for HTML), same CLASS (OK for HTML), BUT SAME NAME (ok for HTML but not for Jquery validation), the validation is operated only on the first row! To accomplish the aim I've made a modification to query.validate.js putting this code:
checkForm: function() {
this.prepareForm();
for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
if (this.findByName( elements[i].name ).length != undefined && this.findByName( elements[i].name ).length > 1) {
for (var cnt = 0; cnt < this.findByName( elements[i].name ).length; cnt++) {
this.check( this.findByName( elements[i].name )[cnt] );
}
} else {
this.check( elements[i] );
}
}
return this.valid();
}
replacing the "standard" form
checkForm: function() {
this.prepareForm();
for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {
this.check( elements[ i ] );
}
return this.valid();
}
as suggested at link Jquery Validation validate form-array. Now the validation works perfectly. I will work at second part of validation (sum of hours) and I'll let you know! Thank you so much for the moment!

Unable to remove form elements while using element.parentNode.removeChild(element)

I have a form that will submit to a Google search appliance, forming a query string "q".
In the form I have radio buttons and a hidden element; the radio buttons contain options for sites to select; the hidden element contains multiple sites that will allow the user to select multiple site searches.
<input type="radio" id="site_search" name="as_sitesearch" value="www.mycompany.com" checked>Current site<br />
<input type="radio" id="site_search" name="as_sitesearch" value="archive.mycompany.com">Archive site<br />
<input type="radio" id="site_search" name="as_sitesearch" value="">Both sites<br />
<input type="hidden" id="as_oqOption" name="as_oq" value="www.mycompany.com archive.mycompany.com">
This is the Javascript I wrote that will remove the radio element or the hidden element exclusively (one of them can exist in the form submittal):
// IF THE USER CHECKED "BOTH SITES", YOU WILL HAVE TO WIPE OUT THE VALUE OF as_sitesearch TO ALLOW FOR PASSING OF as_oq FOR GOOGLE ENGINE
if (form.elements['as_sitesearch'][0].value.length == 0) {
var goodbyeElement = document.getElementById('site_search');
goodbyeElement.parentNode.removeChild(goodbyeElement);
} else {
var goodbyeElement = document.getElementById('as_oqOption');
goodbyeElement.parentNode.removeChild(goodbyeElement);
}
However, when the form is submitted, "q" winds up obtaining both radio and hidden elements no matter what radio option I click.
Not sure why this is happening as I followed the guides in the DOM tutorial sites I have read on how to remove a form element prior to submittal. Any ideas?
Thanks
Following code may help you:
(form.as_sitesearch[2].checked){
for(var k=0; k<form.as_sitesearch.length;k++){
form.as_sitesearch[k].parentNode.removeChild(form.as_sitesearch[k])
}
}
else{
var goodbyeElement = document.getElementById('as_oqOption');
goodbyeElement.parentNode.removeChild(goodbyeElement);
}
You should call it on form submit. here form is document.form[index];
Got it! Apparently form.elements will always fail because of the grouping, so don't use it..
// IF THE USER CHECKED "BOTH SITES", YOU WILL HAVE TO WIPE OUT THE VALUE OF as_sitesearch TO ALLOW FOR PASSING OF as_oq FOR GOOGLE ENGINE
if (document.getElementById('site_search3').checked) {
for (var i = 1; i <= 3; i++) {
eval('var goodbyeElement = document.getElementById("site_search' + i + '");');
goodbyeElement.parentNode.removeChild(goodbyeElement);
}
} else {
var goodbyeElement = document.getElementById('as_oqOption');
goodbyeElement.parentNode.removeChild(goodbyeElement);
}

JavaScript accessing form elements using document.forms[].elements[]

var loc_name = document.forms['create_<?php echo(htmlspecialchars($window_ID)); ?>'].elements['location_name'];
alert(loc_name);
This just gives me the message 'undefined'
where as...
var loc_name = document.forms['create_<?php echo(htmlspecialchars($window_ID)); ?>'];
alert(loc_name);
Gives me the object form business.
Have I just got this all wrong? What is the 'proper' way to access this form element. The form element has the correct name and it has an id, the id is similar but not the same.
HTML
<input type="button" name="create_location" value="Create" onclick="
var pre_row_was = $('#pre_form_row_1').innerHTML;
$('#pre_form_row_1').innerHTML = '<td colspan=\'3\'>Validating...</td>';
var loc_name = document.forms['create_1'].elements['location_name'];
alert(loc_name);
if(loc_name.value == '') {
alert('You can\'t leave the room name blank');
loc_name.focus(); loc_name.value = 'Enter a name';
$('#pre_form_row_1').innerHTML = pre_row_was; return false;
}
if(loc_name.value == 'Enter a name') {
alert('You must enter a room name first'); loc_name.focus();
$('#pre_form_row_1').innerHTML = pre_row_was;
return false;
}
$('#pre_form_row_1').innerHTML = pre_row_was;
Window_manager.new_window().load_xml('location/create.php?location_name=' + loc_name.value).display();">
tried formatting it so it is easier to read.
Your HTML is invalid.
A tr element cannot have a form child, and a form cannot have a td child.
Browsers recover from this error in different ways, including (if I remember correctly) moving the form element to after the table while leaving everything else where it is.
Start with a valid document before you try to access the DOM with JS.
When mixing forms and tables you can entire put the entire table in a form, or an entire form in a cell.
A further problem you have is an attempt to modify the innerHTML of a table row. This will break in many versions of Internet Explorer. Never modify bits of a table with innerHTML.

Categories

Resources