How to allow user to enter elements in an HTML table - javascript

I want to allow a user to enter a list of persons in a web application, and then submit them as one batch. Each row looks roughly like this:
<TR>
<TD> <INPUT name="person.fname"> </TD>
<TD> <INPUT name="person.lname"> </TD>
<TD> <INPUT name="person.birthdate"> </TD>
</TR>
The form starts out with a single row of blank inputs, and I want a fresh row added to the list whenever the user fills in any of the fields -- i.e. the list grows on demand. Likewise, I want a row to disappear whenever the user clears all fields in it.
What is the easiest, most robust and most maintainable way to implement this?
Finally, how do I submit this table of values back to the server? What is the preferred way to name each field so that the server can create a list of Person entities based on the entered values?

If you are familiar with jQuery, you can use the .change handler to catch them changing the field. Test to see if it's the last row and if there is data in it. If they have taken everything out of the row, remove it. jQuery has some great ways to do this, but it's all dependent on how you want to write it. If so, append the new row using jQuery's .append function. If you're using Python and cgi_app and you use the same name attribute for each type of cell, you can use form.getlist('fname[]') and it will return an array of the names.

What is the preferred way to name each field so that the server can create a list of Person entities based on the entered values?
You can do:
<TR>
<TD> <INPUT name="person[fname]"> </TD>
<TD> <INPUT name="person[lname]"> </TD>
<TD> <INPUT name="person[birthdate]"> </TD>
</TR>
Which generates array 'person'

JQuery is a good suggestion, but if you don't want to use it, you can try generating input name by appending an index. For example:
<TR>
<TD> <INPUT name="person_0.fname"> </TD>
<TD> <INPUT name="person_0.lname"> </TD>
<TD> <INPUT name="person_0.birthdate"> </TD>
</TR>
...
<TR>
<TD> <INPUT name="person_N.fname"> </TD>
<TD> <INPUT name="person_N.lname"> </TD>
<TD> <INPUT name="person_N.birthdate"> </TD>
</TR>
where "N" is the row index. This way may help you to easily get the entire whole row values by using (i.e.) $GET['person'.$i.'fname'], $GET['person'.$i.'lname']... and so on.

CSS:
input:not(:first-of-type){
display:none}
jQuery:
$('input').click(function(){
$(this).val('');
}).blur(function(){
if($(this).val().length>1){
$(this)
.toggleClass('processed')
.hide('slow')
.parents('#person').find('input:not(.processed):first').show('slow');
}
});
$('#person').prepend('Click on blank space to proceed<br/>');
HTML:
<tr>
<form id=person method=post action='/your_page_on_server'>
<td><input name="fname" value='Enter the first name'/></td>
<td><input name="lname" value='Enter the last name'/></td>
<td><input name="birthdate" value='Enter the birth date'/></td>
<td><input type=submit value='Submit'/></td>
</form>
</tr>
I'm not familiar with server-side scripting, so my answer in only partial. Here's an example.
Also, I recommend to add input validation by JS.

Related

JavaScript mask money doesn't work after adding another input in table

I am new in JavaScript and jQuery, and I have a problem when I use the mask money plugin. It worked well, but when I make some JavaScript to add another input in table, the new row doesn't work with the maskmoney even though it had the same class
Here's my table:
<thead>
<tr>
<td width="100"><center>Waqaf</center></td>
<td width="100"><center>Operasional Sekolah</center></td>
<td width="100"><center>Seragam</center></td>
</tr>
</thead>
<tbody>
<tr>
<td width="100"><input type="text" class="form-control price" name="waqaf" id=""></td>
<td width="100"><input type="text" class="form-control price" name="operasional_sekolah" id=""></td>
<td width="100"><input type="text" class="form-control price" name="seragam" id=""></td>
</tr>
</tbody>
The JS for adding new field was running well, when I've checked the inspect element outputing input with same class. And the problem is in the plugin JS mask money
<script type="text/javascript">
$('input.price').number( true, 2 );
</script>
(see picture below)
BUT when I manually make another text input it worked well
Why doesn't it work even though I make another field with js event with same input and class?
You should do $('input.price').number( true, 2 ); each time a new row is created, the method currently only applies to the first row.
If you mean this plugin, then it's important to know it uses $.bind to handle events. It means that new inputs won't be handled in any way by this plugin. Today we should use $.on for this kind of bindings (and '$.live' in early versions of jQuery).

Submitting a dynamically generated form

I'm creating a website, and I have a form that gets created by Django. Once the page is loaded, the user can add text inputs to the form by clicking a button. The problem is that when the submit button is clicked, only the text inputs that were originally created by Django get submitted. In other words, the extra text inputs that were added dynamically don't get submitted.
I'm guessing that this is due to the fact that the submit button is only "aware" of form elements that were present when the page was loaded, and not dynamically loaded elements. With that in mind, I'm guessing I need to use some kind of Javascript in order to submit all of the form elements, including the dynamically added ones, but I can't figure out how to do it.
I've tried the jQuery submit function, but I don't really know what I'm supposed to do with it. Any tips would be appreciated!
EDIT: Here's a code snippet, which shows what the HTML looks like after 2 more text inputs have been added dynamically to the "origin"
<table>
<form class="dataInput" action="/foner/116" method="post">
<input type='hidden' name='csrfmiddlewaretoken' value='YYuqTzXUVosu1s2HD3zS00DpoPwQ7N0k' />
<tbody class="origin">
<tr>
<th>
<label>Origin:</label>
</th>
<td>
<input id="id_Origin-0" maxlength="200" name="Origin-0" type="text" value="A native of Georgia" /> // PRESENT AT PAGE LOAD
</td>
<td>
<button class="adder origin">+</button> // USER CLICKS THIS TO APPEND MORE TEXT INPUTS TO THE FORM
</td>
</tr>
<tr>
<th>
</th>
<td>
<input type="text" value="" maxlength="200" name="origin[]"></input> // DYNAMICALLY ADDED
</td>
</tr>
<tr>
<th>
</th>
<td>
<input type="text" value="" maxlength="200" name="origin[]"></input> // DYNAMICALLY ADDED
</td>
</tr>
</tbody>
<tr>
<th>
<label>Notes:</label>
</th>
<td>
<input class="submitButton" type="submit" value="S" />
</td>
</tr>
</form>
</table>
Ok, I was able to solve the problem. I had a table that was arranging all of the text inputs for the form, and the table also enclosed the form itself. It turns out that by inverting this, and enclosing the table inside of the form, all of the dynamically generated inputs get POSTed successfully. Thanks again to those who gave input in the comments above -- it's always helpful to get other opinions & perspectives.
So my question is (I know you're not supposed to ask questions in answers, but in case anyone feels like responding...): How was I supposed to know this? If you're using a compiled language, this is something that a compiler would probably catch for you. Is it just the kind of thing that you get the hang of with experience? Are there any books that would help me to get a handle on elementary problems like this? I find web development to be very tedious and frustrating because I often get hung up for long periods of time on trivial errors like this, and I'm assuming it doesn't have to be this way; I just don't quite know how to improve.

How to structure/control the data that was submitted by a Form?

Let's assume I have a Form like this:
<form>
<table>
<thead>
<th>
Submit?
</th>
<th>
Data
</th>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox" name="c1">
</td>
<td>
<input name="t1">
</td>
</tr>
<tr>
<td>
<input type="checkbox" name="c2">
</td>
<td>
<input name="t2">
</td>
</tr>
</tbody>
</table>
</form>
If I submit that form. An Array will be submitted that contains the checkboxes (if checked) and the regular input.
Now I want it to either:
Submit each row as a row in the array
Only submit the content of the row if the checkbox is checked.
Is there a way to accomplish that?
Edit:
Right now I am submitting the Data like this:
$.post(url, { attributes: $(form).serializeArray() })
I'd love to do it with HTML-Markup, if possible. As this would be the right way in my opinion.
I actually don't want to do some JS/PHP Array juggling. Unless there is a nice way to do it. Right now I can only think of some quite ugly foreach stacking.
Alright here is how I solved it:
Leave the form as it is.
Just do some JS Magic. Instead submitting the Form I do the following:
var submitData = {};
$("input:checked.attributCheckbox").each(function() {
var id = $(this).attr('name');
// This is how I get the input for the checkbox.
var val = $("input[type=number][name="+ id +"]").val();
submitData[id] = val;
});
$.post(url, {attributes : submitData});
Well it's not the perfect solution I hoped for. But it works quite nice. Maybe somebody can come up with a better way to solve it?

unable to hide and show a particular table row with the same id names inside a div using jquery

I am creating a website and there are some pages containing the <div> tags as the wrapper of <table>. A <tr> of each table contains a <form> and another <tr> contains some <a> tags. I am using these anchor tags to make buttons just to add hide and show functionality. Whenever some new data is fetched from database, the set of said html structure is created dynamically. Every <div> contains the same id and every <tr> also containing the <form> assigned the same id. Below is my example htmlfor the better explanation.
HTML
<div class='static_archive'> // First Wrapper
<table>
<tr>
<td>Some data</td>
<td>Some data</td>
<td>
<a id='show_hide_details' href='#'>Show/Hide Button</a>
</td>
</tr>
<tr id='form_container'>
<td colspan='3'>
<form>
<input type='text' name'first' />
<input type='text' name'second' />
<input type='text' name'third' />
</form>
</td>
</tr>
</table>
</div>
<div class='static_archive'> // Second Wrapper
<table>
<tr>
<td>Some data</td>
<td>Some data</td>
<td>
<a id='show_hide_details' href='#'>Show/Hide Button</a>
</td>
</tr>
<tr id='form_container'>
<td colspan='3'>
<form>
<input type='text' name'first' />
<input type='text' name'second' />
<input type='text' name'third' />
</form>
</td>
</tr>
</table>
</div>
jQuery
$(document).ready(function(){
$("#form_container").hide();
$("#show_hide_details").click(function(){
$("#form_container").toggle();
});
});
As soon as the page loads, $("#form_container").hide(); hides all the <tr> containing the <form>. By clicking hide/show button with the toggle effect, hides and shows the every content with the same id.
I want to show only one form at a time when a particular button is hide/show button is pressed. How can i control such behavior?
With a new record fetched, a new DIV is created with only one table inside it. And the table contains only one form. The table row containing the form needs to be hide/show.
Here is the jsfiddle with my code structure jsfiddle
Every clicked hide/show should effects the respective form.
I have edited my post. Please have a look now.
You can use $(this) to do the toggle with particular block.
$(this).closest('tr').next("#form_container").toggle();
You should not use same id for multiple elements, assign class and use that
$(this).closest('tr').next(".form_container").toggle();
I think u want this or may this help u.
You can not have same id's for different controls.So u can have id's staring with same string
You can use ^ here:
$(document).ready(function(){
$("[id^='form_container']").hide();
$("#show_hide_details").click(function(){
$(this).parents().next("tr").toggle();
});
});
jsfiddle
I assume you want to show all of them hidden first. Obviously, you have to replace the id's with class.
$(document).ready(function(){
$(".form_container").hide();
$(".show_hide_details").click(function(){
$(this).parents("tr").next().toggle();
});
});

Hiding empty inputs by parent row in jquery

I have the following HTML:
<table>
<tr class="row">
<td class="field">
<input type="text" />
</td>
<td class="field">
<input type="text" />
</td>
<td class="field">
<input type="text" />
</td>
</tr>
<tr>
...
...
</tr>
</table>
I want to be able to hide the <tr> with the class="row" but only when the input within the <td> with the class="field" is empty when the page loads.
I've tried this, but it doesn't work:
$('td.field:text[value=""]').parents('tr.row').hide();
However, for some reason, this DOES work:
$('td.field).parents('tr.row').hide();
(ie: it hides all of the rows with class="row")
Also, the following DOES work:
$('td.field:text[value=""]').val('test');
(ie: all empty inputs are populated with 'test' on page load)
I'm new to JQuery so I'm suspecting that I may have just misunderstood the way chaining works. can anyone give me any pointers? It semms like the two parts of what I am trying to do are correct when attempted separately, but don't work together as one.
I think it should be in this way:
$('td.field :text[value=""]').parents('tr.row').hide();
The reason: :text (input) is child from td.field. If you put td.field:text it's wrong because they are diferente selectors.
and why dont you go the oposite way - select the INPUT with empty value, and than go to its
parents().parents().hide()
first parents to get TD, the second one to get TR

Categories

Resources