I'm writing an app using web2py and I'm currently trying to make a form where the user can add/remove additional fields on the fly. I've got this working by using jQuery to add the addition fields to the DOM but the problem is only the hardcoded fields are being submitted (I am dumping form.vars at the top of the page to check). I have made sure the dynamic fields have unique names and I've been scouring the html for errors but have come up with nothing.
Here's my javascript:
$(document).ready(function(){
var wrapper = $("#formwrapper");
var addbutton = $("#addfield");
var removebutton = $('#removefield');
var x = 2;
$(addbutton).click(function(){
$(wrapper).append(
"<div id='extrareward"+ x +"'><h3>Reward " + x + "</h3>" +
"<label>Minimum amount to get reward: </label>" +
"<input name='min"+ x +"' type='text'><br>" +
"<label>Reward Description: </label>" +
"<textarea name='reward"+ x +"' rows='10' cols='40'></textarea></div>"
);
x++;
});
$(removebutton).click(function(){
if (x > 2) {
x--;
var id = '#extrareward' + x;
$(id).remove();
}
});
});
And here's the html form from the page source with one static and one dynamic block:
<form action="#" enctype="multipart/form-data" method="post">
<div id="formwrapper">
<label>Minimum amount to get reward: </label>
<input name="min1" type="text" value=""><br>
<label>Reward description: </label>
<textarea cols="40" name="reward1" rows="10"></textarea><br>
<div id="extrareward2">
<h3>Reward 2</h3>
<label>Minimum amount to get reward: </label>
<input name="min2" type="text"><br>
<label>Reward Description: </label>
<textarea name="reward2"></textarea>
</div>
</div>
<input id="submitbutton" type="submit">
<div style="display:none;">
<input name="_formkey" type="hidden" value="1e315a07-a035-4858-822c-614c962ebb98">
<input name="_formname" type="hidden" value="default">
</div>
</form>
and finally here is the code for the controller:
#auth.requires_login()
def create2():
form = FORM(DIV(LABEL('Minimum amount to get reward: '), INPUT(_name='min1', _type='text'), BR(),
LABEL('Reward description: '), TEXTAREA(_name='reward1'), BR(),
_id='formwrapper'),
INPUT(_id='submitbutton', _type='submit'))
if form.process(keepvalues=True).accepted:
session.flash = 'form accepted'
else:
session.flash = 'form rejected'
return dict(loginform=auth.login(),
rewardtiersform=form)
Might be that I'm just missing a silly error somewhere but I've been scratching my head for too long in this. Help much appreciated!
Related
I'm trying to display a text area depending on what radio button the user clicks. When the "contest" function is commented out, the newsletter part works fine. But when the contest function is included, the newsletter does not work. I've tried debugging but I can't seem to find an issue. I've tried using different forms but it doesn't change the problem.
My HTML:
function newsletter() {
var response = "";
if(document.getElementById("yes").checked) {
response += "<p><b>Enter Your Address:</b></p>";
response += '<input type="text" id="address"><br>';
var output = document.getElementById("isChecked");
output.innerHTML = response;
}
}
function contest() {
var resp = "";
if(document.getElementById("answer").value == "Y") {
resp += "<p><b>Enter your credit card information to verify age ($0.00 charge)</b></p>";
resp += "<br>";
resp += '<input type="text" id="first4" size="4" maxlength="4">';
resp += "-";
resp += '<input type="text" id="second4" size="4" maxlength="4">';
resp += "-";
resp += '<input type="text" id="third4" size="4" maxlength="4">';
resp += "-";
resp += '<input type="text" id="fourth4" size="4" maxlength="4"';
var out = document.getElementById("contestOutput");
out.innerHTML = resp;
}
}
body {background-color: pink; }
<center>
<h1>Magnificant Music!</h1>
</center>
<p>Welcome Blue Note Records visitors! On this site, you can enter your information to recieve a card sent every month informing you about the lastest releases on your favorite record label, and a chance to enter a contest that could win you a brand new instrument of your choice!</p>
<form action="" method="post">
<fieldset>
<p><b>Personal Information</b></p>
<label>First Name:</label>
<input type="text" id="firstName"><br>
<label>Last Name:</label>
<input type="text" id="lastName"><br>
<label>Middle Initial</label>
<input type="text" id="middleInit"><br>
</fieldset>
<br>
<fieldset>
<p><b>Do you want to recieve a newsletter?</b></p>
<input type="radio" name="news" id="yes">Yes<br>
<input type="radio" name="news" id="no">No<br>
<button type="button" onclick="newsletter();">Submit</button>
<div id="isChecked"></div>
</fieldset>
<br>
<fieldset>
<p><b>Would you like to enter the contest for a brand new instrument of your choice (Y / N)? (18 yrs old minimum)</b></p>
<input type="text" size="1" id="answer"><br>
<button type="button" onclick="contest();">Submit</button>
<div id="contestOutput"></div>
</fieldset>
</form>
The answer, provided by #jcubic, was the error. Closing the tag fixed the error encountered.
The code below is a form that generates html codes
I want each field to be on a separate line in the "Post text" field
Current output:
<div>texthere</div><script>texthere</script><style>texthere</style>
Expected output:
<div>texthere</div>
<script>texthere</script>
<style>texthere</style>`
function submitted() {
var formValue0 = '<div>' + document.getElementsByName("content")[0].value + '</div>';
var formValue1 = '<script>' + document.getElementsByName("content")[1].value + '<\/script>';
var formValue2 = '<style>' + document.getElementsByName("content")[2].value + '</style>';
document.getElementsByName("content")[3].value = formValue0 + formValue1 + formValue2;
return false;
}
<form onsubmit="return submitted()">
Field 1:<br><input type="text" name="content"><br>
Field 2:<br><input type="text" name="content"><br>
Field 3:<br><input type="text" name="content"><br>
<input type="submit" value="DONE"><br><br>
Post text:<br><textarea name="content" style="height:200px"></textarea>
</form>
You can use this code for several things and speed up your work with repeated codes like a custom post that would have to edit the html manually
You can use new line character \n like this -
function submitted() {
var formValue0 = '<div>'+ document.getElementsByName("content")[0].value +'</div>\n';
var formValue1 = '<script>'+ document.getElementsByName("content")[1].value +'<\/script>\n';
var formValue2 = '<style>'+ document.getElementsByName("content")[2].value +'</style>\n';
document.getElementsByName("content")[3].value = formValue0+formValue1+formValue2;
return false;
}
<form onsubmit="return submitted()">
Field 1:<br><input type="text" name="content"><br>
Field 2:<br><input type="text" name="content"><br>
Field 3:<br><input type="text" name="content"><br>
<input type="submit" value="DONE"><br><br>
Post text:<br><textarea name="content" style="height:200px"></textarea>
</form>
I am using this code to generate dynamically ADD More input fields and then plan on using Save button to save their values in database. The challenge is that on Save button, I want to keep displaying the User Generated Input fields. However they are being refreshed on Save button clicked.
javascript:
<script type="text/javascript">
var rowNum = 0;
function addRow(frm) {
rowNum++;
var row = '<p id="rowNum' + rowNum + '">Item quantity: <input type="text" name="qty[]" size="4" value="' + frm.add_qty.value + '"> Item name: <input type="text" name="name[]" value="' + frm.add_name.value + '"> <input type="button" value="Remove" onclick="removeRow(' + rowNum + ');"></p>';
jQuery('#itemRows').append(row);
frm.add_qty.value = '';
frm.add_name.value = '';
}
function removeRow(rnum) {
jQuery('#rowNum' + rnum).remove();
}
</script>
HTML:
<form method="post">
<div id="itemRows">Item quantity:
<input type="text" name="add_qty" size="4" />Item name:
<input type="text" name="add_name" />
<input onclick="addRow(this.form);" type="button" value="Add row" />
</div>
<p>
<button id="_save">Save by grabbing html</button>
<br>
</p>
</form>
One approach is to define a template to add it dynamically via jQuery
Template
<script type="text/html" id="form_tpl">
<div class = "control-group" >
<label class = "control-label"for = 'emp_name' > Employer Name </label>
<div class="controls">
<input type="text" name="work_emp_name[<%= element.i %>]" class="work_emp_name"
value="" />
</div>
</div>
Button click event
$("form").on("click", ".add_employer", function (e) {
e.preventDefault();
var tplData = {
i: counter
};
$("#word_exp_area").append(tpl(tplData));
counter += 1;
});
The main thing is to call e.preventDefault(); to prevent the page from reload.
You might want to check this working example
http://jsfiddle.net/hatemalimam/EpM7W/
along with what Hatem Alimam wrote,
have your form call an upate.php file, targeting an iframe of 1px.
I'm new to Stack and this is my first question, but I did search and wasn't able to find anything that was specifically what I am trying to accomplish. I'm all for learning, so any reference material that would help me better understand how to approach this would be appreciated, but if someone wants to provide some example code I wouldn't mind that either :p
OK, so the scenario is this. I am writing a "Note Creator" that will generate automatic client notes based on some fields I enter into a form. I've already scripting getting the values from text fields, but I have one field that I want to be a combination of a radio option OR text field, and the java needs to grab whichever one was used and the proper value. Any help is appreciated, below is my code:
<script type="text/javascript">
function getNotes() {
//Grab Variables
spokeTo = document.thisForm.spokeWith.value;
problemItem = document.thisForm.problemWith.value;
resolvedBy = document.thisForm.resolvedWith.value;
thisTech = document.thisForm.techName.value;
fSpace = "... "
//Read in the location information and prep the output container
outputValue = "";
{
//Test if things are blank
if (spokeTo == "") { alert('Please Enter the Name of the Person.'); }
else if (problemItem == "") { alert('Please Select the Problem.'); }
else if (resolvedBy == "") { alert('Please Type Your Resolution.'); }
else {
//The loop that puts the output together
outputValue += "Spoke With: " + spokeTo + "\n\n" + "Called About: " + problemItem + "\n\n" + "Resolution: " + resolvedBy +fSpace + thisTech;
}
//output to the user
document.thisForm.outputArea.value = outputValue;
}
}
</script>
<form name="thisForm">
<p>
1. Spoke With: <input type="text" id="spokeWith" class="input" name="spokeWith">
</p>
<p>
2. Called About:
Hardware <input type="radio" id="problemWith" class="input" name="problemWith" value="Hardware">
Software <input type="radio" id="problemWith" class="input" name="problemWith" value="Software">
<input type="text" id="problemWith" class="input" name="problemWith"><br>
</p>
<p>
3. Resolved By:<br /><br />
<textarea name="resolvedWith" id="resolvedWith"></textarea>
</p>
<p>
4. Your Name:<br>
<input type="text" id="techName" class="input" name="techName" /><br>
</p>
<p>
<input type="button" class="button" value="Make My Notes!" onClick="javascript:getNotes();" />
<input type="reset" class="button" value="Start Over" />
</p>
<br><br>
<textarea name="outputArea" id="outputArea"></textarea>
<p class="finishMessage" id="finishMessage" name="finishMessage"></p>
</form>
I am referring specifically to The Step 2 section of the form where it has radio options and a text field with the same IDs and names. I know IDs are only supposed to be used once per page so this would probably change but I'm open to any suggestion/assistance. I'm moderate with Javascript, still in the learning phases.
Thanks again!
---------------
ROUND 2
---------------
Here is my revised code after taking the suggestion of the provided answer. I added a bunch of alerts to kind of let me know along the way which parts of the script I'm managing to hit, and I can't get anything past the first alert to trigger, and can't get any output at all anymore. What am I missing?
<script type="text/javascript">
function getNotes() {
alert('You\'ve hit the function. Congratulations - you didn\'t break the whole damn thing.');
//Grab Variables
var spokeTo = document.thisForm.spokeWith.value;
var resolvedBy = document.thisForm.resolvedWith.value;
var thisTech = document.thisForm.techName.value;
var fSpace = "… ";
//Grab if radio else text
var inputVal1 = document.getElementByClass('problemRadio').value;
var inputVal2 = document.getElementByClass('problemWith').value;
alert('You made it! Almost there.');
// If Input Value 1 is not Null, Show Radio Value. Else, show Text Value
var problemOutput;
if (inputVal1.length > 0) {
problemOutput = inputVal1;
alert('I found value 1!');
}
else {
problemOutput = inputVal2;
alert('I found value 2!');
}
//Read in the location information and prep the output container
outputValue = "";
//Test if things are blank
if (spokeTo == "") { alert('Please Enter the Name of the Person.'); }
else {
alert('We Made it to Else to parse outputValue');
//The loop that puts the output together
outputValue += "Spoke With: " + spokeTo + "\n\n" + "Called About: " + problemOutput + "\n\n" + "Resolution: " + resolvedBy +fSpace + thisTech;
}
//output to the user
document.thisForm.outputArea.value = outputValue;
}
</script>
<form name="thisForm">
<p>1. Spoke With: <input type="text" id="spokeWith" class="input" name="spokeWith"></p>
<p>2. Called About:
Hardware <input type="radio" id="problemRadio" class="problemRadio" name="problemRadio" value="Hardware">
Software <input type="radio" id="problemRadio" class="problemRadio" name="problemRadio" value="Software">
<input type="text" id="problemWith" class="problemWith" name="problemWith"><br>
</p>
<p>3. Resolved By:<br /><br />
<textarea name="resolvedWith" id="resolvedWith"></textarea>
</p>
<p>4. Your Name:<br>
<input type="text" id="techName" class="input" name="techName" /><br>
</p>
<p>
<input type="button" class="button" value="Make My Notes!" onClick="javascript:getNotes();" />
<input type="reset" class="button" value="Start Over" />
</p>
<br><br>
<textarea name="outputArea" id="outputArea"></textarea>
<p class="finishMessage" id="finishMessage" name="finishMessage"></p>
</form>
sorry about that, I don't know the best way to get code in here yet. Always ends up messy looking ( till I figure it out )
Few things I spotted in your update;
1) getElementbyId is best ( it wasn't getting past your first lines)
2) duplicate IDs on the radio buttons
3) We Needed to 'check' which of the radio buttons was checked
4) always handy to alert the variables ( I've added some in to show )
I gave this code below a rough test and it looks to be along the lines ..
see comments added in your code below ..
<script type="text/javascript">
function getNotes() {
//Grab Variables
var spokeTo = document.getElementById('spokeWith').value;
var resolvedBy = document.getElementById('resolvedWith').value;
var thisTech = document.getElementById('techName').value;
var fSpace = "… ";
alert("spokeTo:" + spokeTo
+" , resolvedBy: " +resolvedBy+", thisTech: "+thisTech);
//Grab if radio else text
var problemWith = document.getElementById('problemWith').value;
alert("problemWith: "+problemWith);
/* set a default value */
var problemOutput="other";
/* if they added no notes */
if((problemWith=="") || ( problemWith==null)) {
/* check which radio is selected if any */
if(document.getElementById('problemHardware').checked) {
problemOutput = document.getElementById('problemHardware').value;
}
if(document.getElementById('problemSoftware').checked) {
problemOutput = document.getElementById('problemSoftware').value;
}
} else {
problemOutput=problemWith;
}
alert("problem output is: "+problemOutput);
alert('You made it! Almost there.');
//Read in the location information and prep the output container
outputValue = "";
//Test if things are blank
if (spokeTo == "") { alert('Please Enter the Name of the Person.'); }
else {
alert('We Made it to Else to parse outputValue');
/* The loop that puts the output together */
outputValue += "Spoke With: "
+ spokeTo + "\n\n"
+ "Called About: "
+ problemOutput + "\n\n"
+ "Resolution: " + resolvedBy +fSpace + thisTech;
}
//output to the user
document.thisForm.outputArea.value = outputValue;
}
</script>
<form name="thisForm">
<p>1. Spoke With: <input type="text" id="spokeWith" class="input" name="spokeWith"> </p>
<p>2. Called About:
Hardware <input type="radio" id="problemHardware" class="problemRadio" name="problemRadio" value="Hardware">
Software <input type="radio" id="problemSoftware" class="problemRadio" name="problemRadio" value="Software">
<input type="text" id="problemWith" class="problemWith" name="problemWith"><br>
</p>
<p>3. Resolved By:<br /><br />
<textarea name="resolvedWith" id="resolvedWith"></textarea>
</p>
<p>4. Your Name:<br>
<input type="text" id="techName" class="input" name="techName" /><br>
</p>
<p>
<input type="button" class="button" value="Make My Notes!" onClick="javascript:getNotes();" />
<input type="reset" class="button" value="Start Over" />
</p>
<br><br>
<textarea name="outputArea" id="outputArea"></textarea>
<p class="finishMessage" id="finishMessage" name="finishMessage"></p>
</form>
one approach would be to check on the value and if else
var input1val = document.getElementById('input1Id').value;
var input2val = document.getElementById('input2Id').value;
var valfromeitherbox = (input1val.length > 0) ? input1val : input2val;
/* UPDATE : ^ is the same as -
var valfromeitherbox;
if(input1val.length > 0) { valfromeitherbox=input1val;
} else { valfromeitherbox=input2val; }
*/
document.getElementById('input3Id').value = valfromeitherbox;
/* if val is empty in input1 use val from text box 2 */
Sorry if a little scrappy , but hope you get the gist and I haven't missed the point
i am working on a project in which i have to render rows dynamically . but user could also delete that row have a look at my current working
JQuery
var counter = 1;
function addrow() {
var textbox = "<div id='rows" + counter + "'> </br><label> Option : </label><input type='text' name='Answers[" + counter + "]' class='ahsan required' />Remove</div>";
var form = $("#form").valid();
if (form) {
$("#TextBoxesGroup").append(textbox);
counter++;
}
else {
return false;
}
}
html
<div id="TextBoxesGroup" style="margin-left: 100px;">
<div id="rows0">
</br><label>
Option :
</label>
<input type='text' name='Answers[0]' class='ahsan required' />Remove
</div>
</div>
<div>
<input type="button" value="Add another row" onclick="addrow();" class="qa-adbtn" id='addButton' /></div>
Now , if i have 10 rows there names will be Answers[0,1,2,3,4,5] . I want to remove input when i click on remove anchor and also reoder all textbox's name
For Example if i remove input at 4th index then all textbox automatically get re arranged . Can i Do it Please Help me and Thanks in Advance
You can make it without counter. This way your answers will be always ordered in the array starting by zero.
Here's a plausible solution:
$(function(){
$("#form").validate();
this.addrow = function() {
if ($("#form").valid()) {
var textbox = "<div> </br><label> Option : </label><input type='text' name='Answers["+$("#TextBoxesGroup div").length+"]' class='ahsan required' /><a class='remove-me' href='#'>Remove</a></div>";
$("#TextBoxesGroup").append(textbox);
$('.remove-me').click(function(){
$(this).parent().remove();
return false;
});
}
else {
return false;
}
}
this.addrow();
});
and the html is simple like this:
<form id="form">
<div id="TextBoxesGroup" style="margin-left: 100px;"></div>
<div>
<input type="button" value="Add another row" onclick="addrow();" class="qa-adbtn" id='addButton' />
</div>
</form>