I have a form where you can generate automatically additional form boxes and send them to be handeled at PHP-script. How ever as I am quite lousy with Javascript and I am running in the following problem.
When the form is filled out I can see everything is filled out on the URL, except the the boxes created with JS (every box has unique name!). My guess is that the JS generated field drop out of the form tags, but can not figure out how to fix this. I would appreciate if someone could give me pointers or tell me how to fix this. I shortened the code for clarity (if something got left out please tell me). If someone is wondering why I am not using the form action. It´s because drupal tries to forward the site to wrong place if I do (surprise, not too good with drupal either :D)
<?php
require_once('customer.php');
?>
<script type="text/javascript">
var intTextBox=0;
//FUNCTION TO ADD TEXT BOX ELEMENT
function addElement()
{
intTextBox = intTextBox + 1;
var contentID = document.getElementById('content');
var newTBDiv = document.createElement('div');
newTBDiv.setAttribute('id','strText'+intTextBox);
newTBDiv.innerHTML = "<div class='product'><tr><td>Sku/ID: "+intTextBox+": <input type='text' name='sku_" + intTextBox + "'/></div>";
contentID.appendChild(newTBDiv);
}
function removeElement()
{
if(intTextBox != 0)
{
var contentID = document.getElementById('content');
contentID.removeChild(document.getElementById('strText'+intTextBox));
intTextBox = intTextBox-1;
}
}
</script>
<table>
<form name="activate">
<div class='cu'>
<tr><td>Sku/ID (oma): <input type="text" name="sku"></td>
<td><p><a href="javascript:addElement();" >Add product</a>
<a href="javascript:removeElement();" >Remove product</a></p></td></tr>
<div id="content"></div>
</div>
<tr> <td><input type="submit" value="Submit"></td> </tr>
</form>
Customer.php
<?php
if(isset($_GET["sku_1"]))
{
echo "found it";
}
else
echo "did not find it";
?>
Any help would be much appreciated!
You could dynamically change the url of the form tag to include textbox values:
var textboxes = document.getElementsByTagName("input");
for (var i = 0; i < textboxes.length; i++){
var data = "?";
if (textboxes[i].type == "text") {
data += (data == "?" ? "" : "&") + textboxes[i].name + "=" + textboxes[i].value;
}
}
form.action += data;
I haven't tested this, you might have to dynamically add all elements
[UPDATE]
If you have trouble with the form you can try using an absolute path, if you aren't already.
Related
I have some google script that generates an initial form then gathers a number does a lookup and then is supposed to return a second form (getfamily function). The second form which is dynamically generated returns blank. I can see the formHTML variable with data in the logger, but it comes up blank in the browser. Any suggestions would be appreciated.
var ssID="xxx";
var rows = SpreadsheetApp.openById(ssID).getSheetByName("studentinfo").getDataRange().getValues();
function doGet() {
var html = HtmlService.createTemplateFromFile('index2').evaluate()
.setTitle('Lookup').setSandboxMode(HtmlService.SandboxMode.NATIVE);
return html;
};
function getfamily(form){
Logger.log(form.familyid);
var ssID="xxxx";
var rows = SpreadsheetApp.openById(ssID).getSheetByName("studentinfo").getDataRange().getValues();
var formHTML = "<!DOCTYPE html>";
formHTML +="Hello!";
formHTML += '<form id="students">';
var filteredRows = rows.filter(function(row){
var message="made it";
if (row[0] === form.familyid) {
Logger.log(row[2]);
formHTML+= '<input type="checkbox" name ="students value='+ row[1] + '">'+ row[2] + '<br>';
return row[2];
}
});
formHTML+='<input type="submit" value="CheckIn">';
formHTML+='</form>';
Logger.log(formHTML);
var output = HtmlService.createHtmlOutput(formHTML).setSandboxMode(HtmlService.SandboxMode.NATIVE);
return output;
};
Your input type="checkbox" line is hard to figure out what you want. I presume that you plan in insert this form into an already exist DOM so no need the worrying about other tags just stick it in whatever div you have prepared for it.
function getfamily(form){
var ssID="xxxx";
var rows = SpreadsheetApp.openById(ssID).getSheetByName("studentinfo").getDataRange().getValues();
var formHTML='<form id="students">';
var message="made it";
rows.forEach(function(row){
if (row[0]==form.familyid) {
formHTTML=Utilities.formatString('<input type="checkbox" name="students" value="%s" /><br />',row[2]);//I presume that you want to change the name but I cant tell how you planned to do it.
}
});
formHTML+='<input type="button" value="CheckIn" onClick="proceesForm(this.parentNode);" />';
formHTML+='</form>';
return HtmlService.createHtmlOutput(formHTML);
};
You can use submit if you really must but I find using google.script.run to be a lot easier. We need to see more of what you're doing to provide a complete answer.
How I create a do...while loop (or if there is a better way to go about this - please advise) for a form with potentially additional information?
Background - I've got a form that will accept a users assessment of a particular location (such as a basement). Using only 1 location per form, this works nicely and submits to my db without a problem.
Now I want to enhance this form with a "add new location" button. I don't (obviously) want to create new pages but rather a loop that can store the first location, save it (which I know could be done with be a session variable) and then clear the fields for locations 2, 3, 4, etc.
My confusion is around the functionality of the button. What type of button is this? Reset with a unique id such as new_loc[]?
And then when I write this as a do...while loop should I do it like this:
<?php
do {
all my form fields
} while (some condition that looks for the button submit);
?>
ok so I have a created a simple JS that can "handle" this.
var counter = 1;
var limit = 5;
function addInput(locInformation){
if (counter == limit) {
alert("You have reached the limit of adding " + counter + " locations");
}
else {
var newdiv = document.createElement('div');
newdiv.innerHTML = "Entry " + (counter + 1) + " <br><br><input type='text' name='location[]'>";
document.getElementById(locInformation).appendChild(newdiv);
counter++;
}
}
Now the problem is that JS will add 1 new field - any suggestions on how to add a massive block of HTML to the JS? I tried adding all my fields to the JS and I get a whole bunch of unclosed string errors.
So first of all your form must have action="" method="post"
then add this php to your page:
session_start();
if (isset ($_POST['NameOfSubmitButtonInsideForm'])) {
if (!isset ($_SESSION['sessionName'])) {
$_SESSION['sessionName'] = 1
}
for ($i = 0; $i <= $_SESSION['sessionName']; $i++) {
echo 'some html code like a form with a input that has
<input type="submit" name="submit- . $i .'EndInputTag>';
};
}
So this will loop the number of times the user clicked the button and you can echo out html code based on that number, or what ever it is you need to do in the loop.
Ok I've figured this out. Thanks to Marc B for suggesting JS.
HTML for the button
<input style="margin-left:5px;" class="btn btn-primary" type="button" value="Add Additional Location" onClick="addInput('locInformation');">
JS
var counter = 1;
var limit = 5;
function addInput(locInformation){
if (counter == limit) {
alert("You have reached the limit of adding " + counter + " inputs");
}
else {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<h3>Location " + (counter + 1) + "</h3>" + document.getElementById('additionalLoc').innerHTML;
document.getElementById(locInformation).appendChild(newdiv);
counter++;
}
}
And then lastly is the new locInformation stuff:
<div id="additionalLoc" language="text">
huge block of HTML with additional fields
</div>
I have been trying to figure out how to get all the input elements inside a div including select and textarea and pass them to editor, so far i figured out with input but i am just stuck with the rest.
Here is the code so far
function InsertShortcode(elem) {
var shortcodeName = elem.parentElement.id;
var inputs = document.getElementById(shortcodeName).getElementsByTagName('input'), i=0, e;
var inputs_val = '[' + shortcodeName;
while(e=inputs[i++]){
if(e.id){
inputs_val += ' ' + e.id + '="' + e.value + '"';
}
}
inputs_val += ']';
window.send_to_editor(inputs_val);
}
By this i am able to grab all the inputs inside a div where submit button is but still i am not sure how to grab textarea or select inputs.
The problem is that i have to make it dynamic. I will have many "shortcodes" and each will be in it's own div where the button is. But each will have it's own inputs which i can't control so i need to grab them all and send values to editor. Here's example of the code.
<div class="output-shortcodes">
<?php foreach( $theme_shortcodes as $key => $name ) { ?>
<div id="<?php echo $key ?>">
<p>
<h2><?php echo $name ?></h2>
</p>
<?php $form = $key . '_form';
if(function_exists($form)) {
$form(); // this is where the input fields are dynamically created on each shortcode.
}
?>
<button class="button-primary" onclick="InsertShortcode(this)">Insert shortcode</button>
</div>
<?php } ?>
</div>
Use jQuery and the :input pseudo selector:
$('.output-shortcodes').find(':input');
That simple.
https://api.jquery.com/input-selector/
Or wrap it in a <form>, then you can use:
document.getElementById("outputForm").elements...
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/elements
You can target your wrapper element and locate thru .find() all inputs within:
var inputs = $("#" + shortcodeName).find("select, textarea, input");
If you can use jQuery here is a fiddle: https://jsfiddle.net/q33hg0ar/
<div id="form">
<input type="text" name="input1" />
<select name="cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<textarea name="notes"></textarea>
<button class="button-primary" onclick="InsertShortcode(this)">Insert shortcode</button>
</div>
<script>
$(document).ready(function() {
$('#form').find('input, select, textarea').each(function() {
console.log($(this).attr('name'));
});
});
</script>
And here it is w/o jQuery: https://jsfiddle.net/67pp3ggu/
window.onload = runIt();
function runIt() {
var elements = document.getElementById('form').childNodes;
var inputTypes = ['text', 'select-one', 'textarea'];
for (var i = 0; i < elements.length; i++) {
var elm = elements[i];
if (typeof elm.type !== 'undefined' && inputTypes.indexOf(elm.type)) {
console.log(elm);
console.log(elm.type);
}
}
}
At the end i switched to jQuery code completely and using :input helped me to resolve the problem.
Here is the complete code that i use now.
$('.vivid-framework-submit-shortcode').click(function(event) {
event.preventDefault();
var shortcodeName = $(this).closest('div').attr('id');
var inputs = $('#' + shortcodeName).find(':input');
var inputsVal = '[' + shortcodeName;
inputs.each(function() {
if($(this).attr('id') != 'content') {
inputsVal += ' ' + $(this).attr('id') + '="' + $(this).val() + '"';
console.log(inputsVal);
}
});
inputs.each(function() {
if($(this).attr('id') == 'content' ) {
inputsVal += ']' + $(this).val() + '[/' + shortcodeName;
}
});
inputsVal += ']';
window.send_to_editor(inputsVal);
});
What does it do? So now when i click on a button within shortcode div first using preventDefault to prevent page to scroll to top, next i grab the id of that div using it as shortcode name, and lastly i grab all the inputs and check if one of the inputs have id content because that will decide if shortcode is enclosed or selfclosed and loop through all inputs outputting their id's and values. and at the end return that to the editor.
Some of the terms may be unfamiliar but those who are familiar to WordPress will recognize terms like shortcode...
At the end final output is:
[bartag foo="value" bar="value"]content from textarea[/bartag]
If you downvote my questions or answers please explain why because i always tend to explain or ask as detailed as i can.
I have an app for making questionnaires. Users have index.php page where they create the questions and choose minimum number of answers, then they have process.php page where they can enter their answers or add more answers.
PROBLEM: When user clicks add more button, it creates textarea of the particular question but with the wrong name. The add more button should add a textarea and change its name according to the minimum of the defined textareas. So if you for ex. have 4 defined textareas in question2, the next textareas should be like odg25, odg26, odg27, odg28 etc...
The problem is in variable $k (process.php) - because it is not defined in addmore function, but I don't know how to pass somehow in this part of code to make it happen.
THIS IS THE TESTING LINK
INDEX.PHP
<input id="btntxt" type="submit" value="TEXT" onclick="addtxt();" /><br/><br/>
<form action="process.php" method="post">
Title: <br/><input type="text" name="naslov" size="64" required ><br/>
Maximum characters: <br/><input type="text" name="chars" size="64"><br/><br/>
<div id="brain1"></div><br/>
<input type="submit" name="submit" value="CONFIRM"><br/>
</form>
PROCESS.PHP
<script type="text/javascript">
<?php $chars = $_POST['chars']; ?>
function addmore(index) {
var textarea = document.createElement("textarea");
textarea.name = "odg" + index + //WHAT SHOULD I ADD HERE???;
textarea.rows = 3;
textarea.setAttribute('maxlength',<?php echo $chars ?>);
var div = document.createElement("div");
div.innerHTML = textarea.outerHTML;
document.getElementById("inner"+index).appendChild(div);
}
</script>
<body>
<?php
$bla = "";
$pitanje = $_POST['question'];
$length = count($_POST['question']);
$req = $_POST['req'];
$requiem = '';
$min = $_POST['min'];
$area = array("","","","","","","","","","","","","","","");
for($j=1; $j<$length+1; $j++) {
if($_POST['question'][$j] != "") {
if(($min[$j])!="") {
for($k=1;$k<=$min[$j];$k++) {
$area[$j] .= '<textarea name="odg'.$j.$k.'" rows="3"'.$requiem.' maxlength="'.$chars.'" ></textarea><br/>';}}
if(($min[$j])=="") {
$area[$j] = '<textarea name="odg'.$j.$k.'" rows="3"'.$requiem.' maxlength="'.$chars.'" ></textarea>';}
$addmore = '<input type="button" name="more" value="Add more" onClick="addmore('.$j.');">';
$bla .= $j.') '.$pitanje[$j].'<br/>'.$area[$j].'<div id="inner'.$j.'"></div>'.$addmore.'<br/>';}}
echo $bla;
?>
FNCS.JS
var n = 1;
function addtxt() {
var textarea = document.createElement("textarea");
textarea.name = "question[" + n + "]";
var required = document.createElement("input");
required.type = "checkbox";
required.name = "req[" + n + "]";
var minimum = document.createElement("input");
minimum.type = "text";
minimum.name = "min[" + n + "]";
var div = document.createElement("div");
div.innerHTML = n + ". Question: " + "<br />" + textarea.outerHTML + "<br />" + "Required: " + required.outerHTML + "<br />" + "Min: " + minimum.outerHTML + "<br /><hr/><br/>";
document.getElementById("brain1").appendChild(div);
n++;
}
I did the same kind of dev.
I had a globalized counter (cpt) in the javascript is incremented by 1 each duplication
My variables were duplicated like this id = "foo_" + cpt.
I added a hidden field for the counter <input type="hidden" id = "cpt"> and its value was changed for each replication.
Php side, I recovered the counter and then a loop to iterate through all the duplicate fields.
// For example
$cpt = $_POST['cpt'];
for ($i = 1; $i <= $cpt; $i++) {
$foo[$i] = $_POST['foo_' . $i];
}
I hope it will help.
You're mixing JavaScript and PHP. PHP is doing some part of the question generation and then JavaScript has to pick up where it left off.
The problem with that approach is that you'll find you end up duplicating a lot of functionality.
The answer the quesiton WHAT SHOULD I ADD HERE??? is "odg" + $j + $k
If instead you start by doing:
var questions = <?php echo json_encode($_POST["question"]);?>;
You now have all your question data available in JavaScript. You can move the for loop from PHP to JavaScript and have j and k there.
What you're going to have to do is make $k able to be passed into process.php.
That is accomplished with something like this:
<form action="process.php" method="post">
Title: <br/><input type="text" name="naslov" size="64" required ><br/>
Maximum characters: <br/><input type="text" name="chars" size="64"><br/><br/>
<div id="brain1"></div><br/>
<input id="numRows" type="hidden" name="numRows" value="1"/>
<input type="submit" name="submit" value="CONFIRM"><br/>
</form>
notice I've added a new <input> element with the name "numRows" which will be passed via POST to process.php. I've given it an arbitrary default value of 1, you can set this however you wish.
Now, when a user clicks the "add more" button, within fncs.js do this:
document.getElementById("numRows").value++;
and finally, in your process.php you need to read in the value of this, as $k:
<?php $k = isset($_POST['numRows']) ? urldecode($_POST['numRows']) : 1; ?>
within process.php you may do as you wish, then, with that value $k.
You need to store last text area value in hidden variable and always increment that
first step: At start set value of hidden variable and your counter
'n' same
second step : at each step where you are adding new text area ,
overwrite the hidden value by new counter value of text area
Remember Textarea counter should be always fetched from hidden value
I think this may help you to solve your problem
I have a application which you can access here. If you open the application please click on the "Add" button a couple of times. This will add a new row into a table below. In each table row there is an AJAX file uploader.
Now the problem is that if I click on the "Upload" button in any row except the first row, then the uploading only happens in the first row so it is only uploading the first file input only.
Why is it doing this and how can I get it so that when then the user clicks the "Upload" button, the file input within that row of the "Upload" button is uploaded and not the first row being uploaded?
Below is the full code where it appends the file AJAX file uploaded in each table row:
function insertQuestion(form) {
var $tbody = $('#qandatbl > tbody');
var $tr = $("<tr class='optionAndAnswer' align='center'></tr>");
var $image = $("<td class='image'></td>");
var $fileImage = $("<form action='upload.php' method='post' enctype='multipart/form-data' target='upload_target' onsubmit='startUpload();' >" +
"<p id='f1_upload_process' align='center'>Loading...<br/><img src='Images/loader.gif' /><br/></p><p id='f1_upload_form' align='center'><br/><label>" +
"File: <input name='fileImage' type='file' class='fileImage' /></label><br/><label><input type='submit' name='submitBtn' class='sbtn' value='Upload' /></label>" +
"</p> <iframe id='upload_target' name='upload_target' src='#' style='width:0;height:0;border:0px solid #fff;'></iframe></form>");
$image.append($fileImage);
$tr.append($image);
$tbody.append($tr);
}
function startUpload(){
document.getElementById('f1_upload_process').style.visibility = 'visible';
document.getElementById('f1_upload_form').style.visibility = 'hidden';
return true;
}
function stopUpload(success){
var result = '';
if (success == 1){
result = '<span class="msg">The file was uploaded successfully!<\/span><br/><br/>';
}
else {
result = '<span class="emsg">There was an error during file upload!<\/span><br/><br/>';
}
document.getElementById('f1_upload_process').style.visibility = 'hidden';
document.getElementById('f1_upload_form').innerHTML = result + '<label>File: <input name="fileImage" type="file"/><\/label><label><input type="submit" name="submitBtn" class="sbtn" value="Upload" /><\/label>';
document.getElementById('f1_upload_form').style.visibility = 'visible';
return true;
}
UPDATE:
Current Code:
var $fileImage = $("<form action='upload.php' method='post' enctype='multipart/form-data' target='upload_target' onsubmit='startUpload(this);' >" +
"<p class='f1_upload_process' align='center'>Loading...<br/><img src='Images/loader.gif' /><br/></p><p class='f1_upload_form' align='center'><br/><label>" +
"File: <input name='fileImage' type='file' class='fileImage' /></label><br/><label><input type='submit' name='submitBtn' class='sbtn' value='Upload' /></label>" +
"</p> <iframe class='upload_target' name='upload_target' src='#' style='wclassth:0;height:0;border:0px solclass #fff;'></iframe></form>");
function stopUpload(success, source_form){
var result = '';
if (success == 1){
result = '<span class="msg">The file was uploaded successfully!<\/span><br/><br/>';
}
else {
result = '<span class="emsg">There was an error during file upload!<\/span><br/><br/>';
}
$(source_form).find('.f1_upload_process').style.visibility = 'hidden';
$(source_form).find('.f1_upload_form').innerHTML = result + '<label>File: <input name="fileImage" type="file"/><\/label><label><input type="submit" name="submitBtn" class="sbtn" value="Upload" /><\/label>';
$(source_form).find('.f1_upload_form').style.visibility = 'visible';
return true;
}
Why am I getting an error on this line below:
$(source_form).find('.f1_upload_form').style.visibility = 'visible';
Without seeing the full cose, your problem seems to be that you are working with ID's, which must be unique within one document. If several elements are using the same ID, in the best case a browser will use the first one (which it does here), in the worst case nothing will work.
When adding a new upload form, you have to give the elements in it unique ID's. You could do that simply by attaching a counting variable to window, e.g.
$(document).ready( function(){ window.formCount=0; } );
You could then add that number to the ID of the newly added form.
Apart from this, by using the this variable, you can carry a reference to the correct form through, e.g. like onsubmit='startUpload(this);' as well as function startUpload(f){...
You should then be able to access things within the form using $(f).find(...).
There are many ways to make this work and solve the issue of multiple ID's. What I would do: var $fileImage = $("<form action... In this form where it says id I would instead use class. Then as above, change the onsubmit (in the same line) by adding "this" to its brackets. Then change the function startUpload as here:
function startUpload(source_form){
$(source_form).find('.f1_upload_process').css('visibility','visible');
$(source_form).find('.f1_upload_form').css('visibility','hidden');
return true;
}
You have to do the same thing for other functions where you want to access something inside the form that is sending a file. Pass a reference to the form to the function using this in the function call's brackets, then access things inside the form as I showed above.