Dynamic HTML form array only submitting last value to PHP - javascript

I'm trying to create a system for my organization that keeps track of points for our members. Part of that system is a page where the officers can create events for the members to sign up for in a form. Part of the event creation form is the "shift(s)" for that event, which looks like this:
<div id="shifts-div">
<div class="form-inline">
<div class="form-group">
<label for="start">Start Time: </label>
<input type="time" class="form-control" name="start[]" value="12:00:00">
</div>
<div class="form-group">
<label for="end">End Time: </label>
<input type="time" class="form-control" name="end[]" value="12:00:00">
</div>
<div class="form-group">
<label for="end">Spots Available: </label>
<input type="number" class="form-control" name="spots[]">
</div>
</div>
<br>
</div>
Since there can be any number of shifts for a given event I allow the officers to dynamically add or remove shifts using the following buttons:
<button type="button" class="btn btn-default" onclick="addShift()">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add Shift
</button>
<button type="button" class="btn btn-default" onclick="removeShift()">
<span class="glyphicon glyphicon-minus" aria-hidden="true"></span> Remove Shift
</button>
Which run these two javascript functions:
function addShift(){
var shift =
`<div class="form-inline">
<div class="form-group">
<label for="start">Start Time: </label>
<input type="time" class="form-control" name="start[]" value="12:00:00">
</div>
<div class="form-group">
<label for="end">End Time: </label>
<input type="time" class="form-control" name="end[]" value="12:00:00">
</div>
<div class="form-group">
<label for="end">Spots Available: </label>
<input type="number" class="form-control" name="spots[]">
</div>
</div>
<br>`;
document.getElementById("shifts-div").innerHTML += shift;
}
and
function removeShift() {
$('#shifts-div').children().last().remove();
$('#shifts-div').children().last().remove();
}
This works well as far as adding and removing shifts to the page, but when I submit the form to a php file start, end, and spots are not an array and only hold the values for the last shift. I check this by running this in the php:
foreach($_POST as $key => $value){
echo $key.' -> '.$value . ' ';
}
So, say I add 3 shifts with different values for each input and click submit, I would get this as the result (I took out the parts I don't think are relevant as they are just other non-array values for the event, like name and date, and are working properly):
start -> 14:00 end -> 17:00 spots -> 3
Where the start, end, and spots values are what I entered for the third shift that was added.
After some research I found that using innerHTML can cause some weird problems since it rewrites every node in the div, so I changed the addShift function to the following just to see if this was the problem (Not the prettiest way to do it, I know)
function addShift(){
$("#shifts-div").append("<div class='form-inline'><div class='form-group'><label for='start'>Start Time: </label><input type='time' class='form-control' name='start[]' value='12:00:00'></div><div class='form-group'><label for='end'>End Time: </label><input type='time' class='form-control' name='end[]' value='12:00:00'></div><div class='form-group'><label for='end'>Spots Available: </label><input type='number' class='form-control' name='spots[]'></div></div><br>");
}
The same problem persists with the same results. This is my first time doing this kind of web development and this is how I came up with to tackle this problem, but I recognize that there are probably better ways to do this that I am unaware of, so there are two parts to my question:
Why isn't my code running how I intend, and how do I fix that?
How would an experienced web developer implement the functionality I am after (assuming he was also just using basic javascript, html, and php)?
Like I said I am new, so feel free to critique any parts of my code, even if it doesn't directly solve the problem. There are so many different ways to do anything, it is hard to know which is the "correct" way for any given situation. Thanks in advance and let me know if more of the code needs to be given.
EDIT:
I submit the form with this button:
<button type="submit" class="btn btn-default btn-lg">Submit</button>
and this is what the form looks like:
<form action="../php/create-event.php" method="POST" name="event">

So, it turns out I had just messed up with uploading my changes to the server. Once I changed the innerHTML to jquery as described in the question and properly uploaded it the problem was fixed.
I'm going to leave this question up because even finding that solution took me a long time and I never found anyone directly addressing this problem. If you are having the problem I described above do the change from innerHTML to another DOM manipulation method. The problem has something to do with innerHTML rewriting the entire element and losing references to the elements that were already there.
I'll gladly accept a different answer if someone can come along and explain it better than I can.

Related

google apps script sidebar form Send button not working

I'm creating a google add on for sheets. The sidebar I'm working on is intended to be sort of help ticket submission, but way before I can develop that part of things, I'm not getting the submit button in the form to call the javascript function I want to build.
I've removed all of the form data from the html button call to activate a Logger.log. No dice.
I created a completely separate (and very simple) button to call a different function to call Logger.log. This also did not work.
I've double checked the form data, the send call, and the function.
I made sure the name of the function (sendMsg) is unique.
I think that the issue may not be in my code but in some other way the html and javascript (.gs) are connected.
here is the html form:
<div class="block form-group">
<form>
<label for="reason">Purpose of Contact</label>
<select id="reason">
<option selected>Help Request</option>
<option>Feature Request</option>
<option>Error Report</option>
<option>Other</option>
</select>
<label for="email">Email</label>
<input type="text" id="email" style="width: 200px;">
<label for="phone">Phone</label>
<input type="text" id="phone" style="width: 120px;" value = "optional">
<br>
<label for="translated-text">
<b>Message</b></label>
<textarea id="userMsg" rows="15" cols="35">
</textarea>
<br>
<input id="app" name="appSrc" type="hidden" value="COE">
<input type="button" class="action" name="helpRequest" value="SEND" onClick="google.script.run.sendMsg(
document.getElementById('reason').value,
document.getElementById('email').value,
document.getElementById('phone').value,
document.getElementById('userMsg').value,
document.getElementById('appSrc').value
)" />
</form>
</div>
and here is the function called:
function sendMsg(appSrc,reason,email,phone,userMsg) {
appV = appSrc;
reasonV = reason;
emailV = email;
phoneV = phone;
userMsgV = userMsg;
Logger.log('cheese');
}
Right now the form should simply result in a Logger.log message. At this point nothing happens.
In your situation, when "SEND" button is clicked, the script of sendMsg() at Google Apps Script side doesn't work.
You want to run sendMsg().
If my understanding is correct, how about this modification?
Modification point:
When I saw <input id="app" name="appSrc" type="hidden" value="COE">, appSrc is not id. By this, an error occurs at document.getElementById('appSrc').value, and sendMsg() didn't work. So if your script is modified, for example, please use app.
From:
document.getElementById('appSrc').value
To:
document.getElementById('app').value
Or
From:
<input id="app" name="appSrc" type="hidden" value="COE">
To:
<input id="appSrc" name="appSrc" type="hidden" value="COE">
If I misunderstood your question and this was not the result you want, I apologize.
In case anyone has the same issue as I had... onpress doesn't seem to work here. I had to change it to onclick.

HTML required fields are not showing a message when it's not filled out

I have a big form for a website, with multiple required fields, and all of them are working perfectly, when i click submit on the form, the web page scroll to the field's location with an error message, except on two parts, the "Number of travelers" and the "Date of the trip".
This is the HTML for both of them:
<div class="sect-txt" style="margin-top:100px;" id="op">
<h1> Date of the trip </h1>
<div class="al">
<h1 style="font-family:Montserrat;font-size:14px;color:#161616;margin-bottom:5px;"> Check In </h1>
<input type="date" class="hide-replaced" data-date-size="1" placeholder="Check-in" name="checkin" required />
</div>
<div class="al">
<h1 style="font-family:Montserrat;font-size:14px;color:#161616;margin-bottom:5px;"> Check Out </h1>
<input type="date" class="hide-replaced" data-date-size="1" placeholder="Check-out" name="checkout" required />
</div>
<a href="#four">
<div class="btn-nxt" style="position:relative;top:137px;">
NEXT
</div>
</a>
</div>
<div class="sect-txt">
<h1> Number of travelers </h1>
<input type="number" class="f-2" placeholder="Adults" name="adults" required/>
<input type="number" class="f-3" placeholder="Children" name="childrens" required/>
<a href="#fif">
<div class="btn-nxt-b">
NEXT
</div>
</a>
</div>
And this is a link to the page in action: http://www.eliteware.co/92/form/
Your button is not focusable because you are trying to hide it when it has to receive focus again. Check the following link for more information about why this happens. Basically, you are hiding the object that is supposed to receive focus when validation is needed. If you don't want this to happen, you can probably do validation before hiding, or unhide the object if validation fails.
https://stackoverflow.com/a/28340579/616813
Also, do remember, if an error log exists, that is the first point to check if you receive an error. That is the whole point of error log, to give you a starting point to debug.
Or as Andreas said, "Fix the damn errors in the console... :)".
Edit:
Because it was killing me, I tried to reverse engineer your application. All it took was comparing the textbox that was working, and the one that was failing to find the problem. Really, that easy.
aria-required="true"
Your "Adults" and "Children" input fields have this property. You need required="true" instead.
Check your css and update that. And no, I have no idea why "aria=required" and "required" property behave differently. It is something new to learn for sure.

How to clone form fields without their values?

How to clone following html without persisting the field values?
<form method=POST action="/url">
<div class="form-group" data-answer>
<div class="pull-left"><label><input type="checkbox" name="answer[1][is_correct]" value="true"> Correct Answer</label></div>
<div class="pull-right">
</span>
</div>
<input type="text" class="form-control" name="answer[1][body]" placeholder="Possible answer">
</div>
<div class="form-group" data-answer>
<div class="pull-left"><label><input type="checkbox" name="answer[2][is_correct]" value="true"> Correct Answer</label></div>
<div class="pull-right">
</span>
</div>
<input type="text" class="form-control" name="answer[2][body]" placeholder="Possible answer">
</div>
. . .
<button type="submit">Submit</button>
</form>
I can see only 3 possible choices here. However, all of them come with major flaws:
.clone() the .form-field normally and reset the field values.
Problem: resetting all the values one by one is cumbersome and is not a future-proof solution. For example, if more fields are added into the .form-group, their values will need to be cleared separately.
Include a hidden .form-group as a template on the page.
Problem: as you see, the input fields contain enumerated names like: answer[1][body]. It is convenient to clone the last .form-group and just increment the value by 1. Cloning the templated .form-group will be lacking this flexibility.
Read the fields as raw html and transform them into JQuery object
Problem: this seems to be a clear solution to me, however I couldn't get it working. The code $.parseHTML($('.form-group').html()) does not return a valid JQuery object, which I need to use .find() and other methods on.
What will be an effective and elegant solution to this problem?
Try this code:
$("button").click(function(){
var t = $("form").clone().appendTo("#clonedForm");
$(t).find("input[type=checkbox],input[type=text], textarea").removeAttr("checked").val('');
});

Dynamically add and remove form fields

I would like to create a form field which has an icon in it, let's say a plus-sign. When this icon is clicked, a new identical form field appears, but with a minus-sign in it. And as you guessed, the minus-sign removes the form field again.
I would like to do this using Bootstrap (3.2.0) and jQuery.
What is the best way to do this? I would like to put a limit on the number of fields (let's say 3) and also not have duplicate id fields. Also, I would like the icon to be inside the input.
HTML file:
<div class='container'>
<div class='row marketing'>
<div class='col-lg-15'>
<form class='form-horizontal'>
<div class="form-group has-feedback">
<label id="keywordLabel" for="keyword" class="col-sm-2 control-label">Keywords:</label>
<div id="keywordList" class="col-sm-10">
<input id="keyword" type="text" name="keyword" class="form-control"></input>
<span id="addKeyword" class="glyphicon glyphicon-plus form-control-feedback"></span>
</div>
</div>
</form>
</div>
</div>
</div>
JavaScript file:
$(document).ready( function() {
$('#addKeyword').on('click', function() {
$('#keywordList').append(
"<input id='keyword' class='form-control' type='text' name='keyword'><span id='removeKeyword' class='glyphicon glyphicon-minus form-control-feedback'></span>"
);
});
});
For my code in JSFiddle, click here.
Edit:
I'm still messing around, if I remove the "form-control-feedback"-class in the javascript, it works better.
For now I have:
<div class='container'>
<div class='row marketing'>
<div class='col-lg-15'>
<form class='form-horizontal'>
<div class="form-group has-feedback">
<label id="keywordLabel" for="keyword" class="col-sm-2 control-label">Keywords:</label>
<div id="keywordList" class="col-sm-10">
<div class="form-control">
<input id="keyword" type="text" name="keyword" class=""></input>
<span id="addKeyword" aria-hidden="true" class="glyphicon glyphicon-plus form-control-feedback"></span></div>
</div>
</div>
</form>
</div>
</div>
And JS:
$(document).ready(function () {
$('#addKeyword').on('click', function () {
$('#keywordList').append("<div class='form-control'><input id='x' class='form-control' type='text' name='keyword'></input><span id='removeKeyword' aria-hidden='true' class='glyphicon glyphicon-minus'></span></div>");
});
});
Still not perfect, but closer already.
Original text:
First of all, your jsfiddle doesn't show the icon, because you didn't activate bootstrap on it. if I activate the bootstrap extension, I can see the "+"
I'm not sure what you're asking us, as there is no real question in your post, but if I click the "+", it adds a field. The problem is that the "-" goes in front of the "+" and so you can't see it.
You're also adding duplicate ID's by doing, which is never a good thing.
If you can edit your post, and add the question, I can look to answer what you want to know. :-)
You need to load the appropriate external resources in Jsfiddle
bootstrap.min.js and bootstrap.min.css
see: http://jsfiddle.net/u4e64quc/4/
Alternatively, check bootstrap in the Jsfiddle options and no need to load external resources --this also fixes the issue with the icon outside of the form field pointed out in the comment

Twitter bootstrap set field from dropdown

I'm using twitter bootstrap for front end. I have a text field and a drop down menu next to it:
<div class="input-group">
<input type="text" class="form-control" name="opening_hr" id="opening_hr" required>
<div class="input-group-btn">
<button type="button" class="btn btn-default dropdown-toggle"
data-toggle="dropdown"><span class="caret"></span></button>
<ul class="dropdown-menu pull-right" id="opening_hr_select">
#foreach($hours as $hour)
<li><a>{{$hour}}</a></li>
#endforeach
</ul>
</div>
I've tried created a javaScript function which takes two parameters the text field I want to edit and the drop down menu that has been selected:
$(function(){
$(".dropdown-menu li a").click(function(){
var elem = document.getElementById("opening_hr");
elem.text($(this).text());
elem.val($(this).text());
});
});
the above is simpler function without parameter I tried testing (no luck). what I would like to achieve is to take the selected value and set it as the text field value.
please help, thank you.
The problem is that the variable elem is not a jQuery object so trying to call val will not work. As you are already using jQuery, change the elem assignment to:
var elem = $("#opening_hr");
and to set the input use:
elem.val($(this).text());
or combine them together:
$("#opening_hr").val( $(this).text() )
I recommend to dig deeper into Jquery. One of its Main Features is the Support of selectors, so in you use Jquery you should use it to Access a DOM Element rather than using getelementbyid.
ps: my ipad hates capitals, sorry.
Found a simple way to achieve what I want done, without the use jQuery or JavaScript. The following is my solution:
<!-- Opening times -->
<div class="row">
<div class="col-lg-3">
<label for="opening_time">Opening Time</label>
<div class="input-group">
<span class="input-group-addon">Hour</span>
<input type="number" max="24" min="1" class="form-control" name="opening_hr"
id="opening_hr"
required>
<span class="input-group-addon">Minute</span>
<input type="number" max="60" min="0" class="form-control" name="opening_min"
id="opening_min"
required>
</div>
</div>
</div>

Categories