can any one let me know
how can i add the delete button on each row pls
from the below code
[Jsfiddle][1]
var counter = 1;
jQuery('a.add-author').click(function(event){
event.preventDefault();
counter++;
var newRow = jQuery('<div class="row"><div class="col-lg-6"><input type="text" name="first_name' +
counter + '"/></div><div class="row"><div class="col-lg-6"><input type="text" name="last_name' +
counter + '"/></div></div>');
jQuery('div.row').append(newRow);
});
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="col-lg-6"><input type="text" name="first_name" /></div><div class="col-lg-6"><input type="text" name="last_name" /></div>
</div>
Add Author
To "delete" an element you can use the jQuery('element').remove() function.
By using the jQuery('element').on() you can listen to events even if the element is created later on.
Please read the documentation about .on() carefully!
var counter = 1;
jQuery('a.add-author').click(function(event){
event.preventDefault();
counter++;
var newRow = jQuery('<div class="row"><div class="col-lg-6"><input type="text" name="first_name' +
counter + '"/></div><div class="col-lg-6"><input type="text" name="last_name' +
counter + '"/></div><div>delete</div></div>');
jQuery('.add-author').before(newRow);
});
//Bound to 'body' for this sample, bind to you own wrapper element when using this!
jQuery('body').on('click', '.delete', function(event)
{
event.preventDefault();
$(this).closest('.row').remove();
});
.row { position: relative; width: 500px; height: auto; margin: 5px 0; overflow: hidden; }
.row div { position: relative; float: left; width: 150px; height: auto; overflow: hidden; }
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="col-lg-6"><input type="text" name="first_name" /></div><div class="col-lg-6"><input type="text" name="last_name" /></div>
</div>
Add Author
Related
I'm having a problem with an error: jQuery input val() is undefiend.
I have 3 inputs which are referring to one item.
On add Row i can add an new Item ( 3 rows ).
All those rows have to be prepared in array to be sent to a PHP file.
I believe that my id="item[0]['name']" is wrong.
$(document).ready(function() {
var counter = 1;
$("#addRow").click(function() {
$("#ItemContainer").append(`
<div class="item">
<div><input type="text" id="item[${counter}]['name']" placeholder="Name" ></div>
<div><input type="text" id="item[${counter}]['amount']" placeholder="Amount" ></div>
<div><input type="text" id="item[${counter}]['count']" placeholder="Count" ></div>
<div></div>
</div>
`);
counter = counter + 1;
});
$("#setKasse").click(function() {
for (let i = 0; i <= (counter - 1); i++) {
console.log($(`#item[${i}]`));
console.log($(`#item[${i}]["name"]`).val());
};
});
});
*{
padding: 0;
margin: 0;
}
body{
background-color: #E6E6FA;
color : #191970;
padding-left : 5%;
padding-top : 70px
}
#Container, #ItemContainer, .item {
width: 20%;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto;
row-gap : 18px;
}
#ItemContainer, .item{
width: 100%;
row-gap : 2px;
}
input{
height: 30px;
width: 100%;
border: none;
box-sizing: border-box;
padding-left: 4px;
font-size: 14px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="Container">
<div><button id="addRow"> Add Row </button></div>
<div id="ItemContainer">
<div class="item">
<div><input type="text" id="item[0]['name']" placeholder="Name" ></div>
<div><input type="text" id="item[0]['amount']" placeholder="Amount" ></div>
<div><input type="text" id="item[0]['count']" placeholder="Count" ></div>
<div></div>
</div>
</div>
<div><button id="setKasse"> Set Kasse </button></div>
</div>
So, I want a way to be able to cycle and loop into objects|Arrays
My main goal is to send the data via Ajax Post request, and for that I want to refactor the Array in another Format.
In selectors, [ is used to indicate an attribute selector. If you want to use it as a literal character in the ID, you need to escape it with backslash. You also need to escape the ' characters.
You also need to include the ['name'] part of the ID (or ['amount'] or ['count'] if you want to get those inputs).
$(document).ready(function() {
var counter = 1;
$("#addRow").click(function() {
$("#ItemContainer").append(`
<div class="item">
<div><input type="text" id="item[${counter}]['name']" placeholder="Name" ></div>
<div><input type="text" id="item[${counter}]['amount']" placeholder="Amount" ></div>
<div><input type="text" id="item[${counter}]['count']" placeholder="Count" ></div>
<div></div>
</div>
`);
counter = counter + 1;
}); // end of $("#addRow").click
$("#setKasse").click(function() {
for (let i = 0; i <= (counter - 1); i++) {
console.log($(`#item\\[${i}\\]\\[\\'name\\'\\]`).val());
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="Container">
<div><button id="addRow"> Add Row </button></div>
<div id="ItemContainer">
<div class="item">
<div><input type="text" id="item[0]['name']" placeholder="Name"></div>
<div><input type="text" id="item[0]['amount']" placeholder="Amount"></div>
<div><input type="text" id="item[0]['count']" placeholder="Count"></div>
<div></div>
</div>
</div>
<div><button id="setKasse"> Set Kasse </button></div>
</div>
In my opinion, it's best to avoid using characters that have special meaning in CSS selectors in your IDs, it complicates the code unnecessarily. You could use id="item-${counter}-name". Or don't use IDs for dynamically created elements at all. Use a class like class="name", and then use dynamic indexing. $(".item").eq(i).find("input.name").
$(document).ready(function() {
var counter = 1;
$("#addRow").click(function() {
$("#ItemContainer").append(`
<div class="item">
<div><input type="text" class="name" placeholder="Name" ></div>
<div><input type="text" class="amount" placeholder="Amount" ></div>
<div><input type="text" class="count" placeholder="Count" ></div>
<div></div>
</div>
`);
counter = counter + 1;
}); // end of $("#addRow").click
$("#setKasse").click(function() {
for (let i = 0; i < counter; i++) {
console.log($(".item").eq(i).find(".name").val());
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="Container">
<div><button id="addRow"> Add Row </button></div>
<div id="ItemContainer">
<div class="item">
<div><input type="text" class="name" placeholder="Name"></div>
<div><input type="text" class="amount" placeholder="Amount"></div>
<div><input type="text" class="count" placeholder="Count"></div>
<div></div>
</div>
</div>
<div><button id="setKasse"> Set Kasse </button></div>
</div>
I'm trying to add an input field when clicking on add, and it should be removed when clicking on delete click.
Here is JS Bin link:
JS issue with deletion
var newTextBoxDiv;
var rowCount = 0;
var counter = 1;
var delCounter = 1;
$(document).ready(function() {
$(document).on('focus', '.txtFocus', function() {
$(this).next('.clearContent').hide()
});
$(document).on('focusout', '.txtFocus', function() {
$('.clearContent').show()
})
});
function addTags(obj) {
var newTextBoxDiv = '<div class="col-md-4 TextBoxMainDiv"><div style=""><div class="input-group" id="" style="width: 40%;margin: 0;padding: 0;padding: 2px;float:left;width:80%;"><input type="text" name="textbox' + counter + '" id="textbox' + counter + '" value="" class="txtFocus" required placeholder="Add Tag" autocomplete="false" style="width: 100%" ><span class="clearContent"><i class="fas fa-times"></i></span> </div><div style="width: 15%;display: inline-block;text-align:right;"><span id="addMore" onClick="addTags(this);"><i class="fas fa-plus-square"></i></span></div></div></div>';
$(obj).hide();
$("#tagElement").append(newTextBoxDiv);
$('.txtFocus').focus();
counter++;
if (counter == 1) {
$(obj).show()
}
}
function deleteTag(obj) {
$(obj).closest('.TextBoxMainDiv').last().find('#addMore').show();
$(obj).closest('.TextBoxMainDiv').last().find('#addMore').css('display', 'block');
$(obj).closest('.TextBoxMainDiv').remove();
counter--;
if (counter == 1) {
$('#addMore').show()
}
}
<div class="row">
<div id="tagElement">
<div> </div>
<div class="col-md-4 TextBoxMainDiv">
<div style="">
<div class="input-group" id="" style="width: 40%;margin: 0;padding: 0;padding: 2px;float:left;width:80%;">
<input type="text" class="txtFocus" required placeholder="Add Tag" id="textBox" autocomplete="false" autofocus="autofocus" style="width: 100%">
<span class="clearContent">
Add
</span>
</div>
<div style="width: 15%;display: inline-block;text-align:right;">
<span id="addMore" onClick="addTags(this);">
cancel
</span>
</div>
</div>
</div>
</div>
</div>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
I manage to add the input fields properly, but have issues deleting them. They seem to be deleted randomly.
I think the add and delete button are mixed up, but I couldn't spend time on analysing the code because it's too much code for something that does very little. The following demo:
has a single button that adds a row of form controls:
a checkbox
a text input
a button that deletes it's own row as well as itself.
Demo
var index = 0;
var template = `
<figure class='frame'><input class='status' type='checkbox'><label class='tag'></label><input class='text' type='text' placeholder='Enter New Task'><button class='del' type='button'>➖</button></figure>`;
$('.set').on('click', 'button', function(e) {
if ($(this).hasClass('add')) {
index++;
$('.set').prepend(template);
$('.status:eq(0)').attr('id', 'chx' + index);
$('.tag:eq(0)').attr('for', 'chx' + index);
} else {
$(this).prevUntil('.del, .add').add(this).remove();
}
});
.set {
position: relative;
padding: 2px 0 1px 2px;
min-height: 28px;
border-radius:7px;
}
.frame {
padding: 0;
margin: 0;
min-width:90vw;
}
.add {
position: absolute;
right: 6px;
top: 3px;
display:block;
}
.status {
display: none
}
.tag {
display: inline-table;
font-size: 28px;
line-height: 1;
vertical-align: middle
}
.tag::before {
content: '\2610';
}
.status:checked+.tag::before {
content: '\2611'
}
.text {
display:inline-table;
width: 75%;
margin: 2px 5px 0
}
<form id='ui'>
<fieldset class='set'>
<figure class='frame'>
<input id='chx0' class='status' type='checkbox'>
<label for='chx0' class='tag'></label>
<input class='text' type='text' placeholder='Enter New Task' style='margin:2.5px 2px 0 0' autofocus>
<button class='del' type='button'>➖</button>
</figure>
<button class='add' type='button'>➕</button>
</fieldset>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I think your code's logic is working, however, the icon for addition and deletion of inputs is not being rendered.
You can replace your newTextBoxDiv with this:
var newTextBoxDiv = `
<div class="col-md-4 TextBoxMainDiv">
<div style="">
<div class="input-group" id="" style="width: 40%;margin: 0;padding: 0;padding: 2px; float:left; width:80%;">
<input type="text" name="textbox${counter}" id="textbox${counter}" value="" class="txtFocus" required placeholder="Add Tag" autocomplete="false" style="width: 100%" >
<span class="clearContent">
Delete<i class="fas fa-times"></i>
</span>
</div>
<div style="width: 15%;display: inline-block;text-align:right;">
<span id="addMore" onClick="addTags(this);">
Add
</span>
</div>
</div>`;
Notice that I added the word "Add" and "Delete" between the tags, so that you have something to click on
Also, I think you need to swap the word "Add" and "Cancel" in the initial HTML to convey a clearer message, as they are now doing the opposite thing.
Another fix that's needed is to replace the id="addMore" with class="addMore"
<span class="addMore" onClick="addTags(this);">
Since id is meant to be unique. In your code, however, when you append new element, you added new elements with duplicate id, making jquery's selector not selecting the element you want.
After replacing id with class, you also need to change the deleteTag function to select the last "addMore" span and show it.
function deleteTag(obj) {
$(obj).closest('.TextBoxMainDiv').last().find('.addMore').show();
$(obj).closest('.TextBoxMainDiv').last().find('.addMore').css('display', 'block');
$(obj).closest('.TextBoxMainDiv').remove();
counter--;
$('.addMore').last().show();
}
For the layout, you need to do it with css, removing float and setting the div tag with appropriate width and display: inline-block. I suggest you use a separate css file to style the elements instead of doing it inline.
function deleteTodo() {
$(this).parent().remove();
}
function addTodo() {
var inputTemplate =
'<div class="todo-input-wrapper">' +
'<input class="todo-input" type="text" placeholder="Add Tag" />' +
'<button class="delete-button">Delete</button>' +
'</div>';
$('.todo-wrapper').append(inputTemplate);
$('.delete-button').last().on('click', deleteTodo);
$('.todo-input').last().focus();
}
$(document).ready(function () {
$('.delete-button').on('click', deleteTodo);
$('.add-button').on('click', addTodo);
});
.todo-wrapper {
display: inline-block;
width: max-content;
font-size: 0;
}
.todo-input-wrapper {
margin: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="todo-wrapper">
<div class="todo-input-wrapper">
<input class="todo-input" type="text" placeholder="Add Tag" />
<button class="delete-button">Delete</button>
</div>
</div>
<button class="add-button">Add</button>
I've played around with a number of options, but I can't keep the table height from growing as I add lines dynamically.
This is a small section, part of a more complex page. Basically I have several div tags within the larger container div.
As more lines are added the table pushes the button below outside the boundaries of the div. Run the code snippet to observe the problem.
function onBodyLoader(obj) {
g.c.assignEventListners();
}
var g = {};
g.formClass = function() {
/*
----------------------------------
Properties for formClass
----------------------------------
*/
this.tr;
this.td;
this.elist = [];
/*
----------------------------------
Methods for formClass
----------------------------------
*/
this.assignEventListners = function() {
this.tbody = document.getElementById('emailDist');
g.sbAddELine = document.getElementById('sbAddELine');
g.sbAddELine.addEventListener("click", function(evt) {
g.c.addBlank();
}, false);
/*event listener for all links on the email list body*/
g.dataUpdate = document.querySelector("#emailDist");
g.dataUpdate.addEventListener("click", g.c.tableBodyRouter, false);
};
this.tableBodyRouter = function(e) {
/*
called from clicks on keyTable or task links
*/
if (e.target !== e.currentTarget)
if (e.target.id.indexOf('eRemove') > -1)
g.c.removeEmail(e);
e.stopPropagation();
};
this.redrawElist = function() {
/*delete current table*/
while (this.tbody.rows.length > 1)
this.tbody.deleteRow(1);
/*redraw table*/
for (var i = 0; i < this.elist.length; i++) {
this.rowLayout();
}
};
this.addBlank = function() {
/*add blank to this.elist array*/
this.elist.push({
eEmail: '',
eFirst: '',
eLast: '',
});
this.rowLayout();
}
this.removeEmail = function(e) {
var x = e.target.id.substr(7);
this.elist.splice(x, 1);
this.redrawElist();
};
this.rowLayout = function() {
var rowCnt = this.tbody.rows.length - 1;
this.tr = this.tbody.insertRow(this.tbody.rows.length);
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eFirst' + rowCnt + '" maxlength="20" size="20" value=""/>';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eLast' + rowCnt + '" maxlength="20" size="20" value="" />';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eEmail' + rowCnt + '" maxlength="50" size="50" value="" />';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="button" id="eRemove' + rowCnt + '" value="Remove" ">';
document.getElementById("eFirst" + rowCnt).focus();
document.getElementById("eFirst" + rowCnt).select();
}
}
g.c = new g.formClass;
table {
height: 60%;
max-height: 60%;
width: 100%;
display: inline-table;
border-style: none;
}
tbody {
font-size: 10pt;
display: block;
height: 90%;
overflow-y: scroll;
}
#container {
position: absolute;
width: 98%;
top: 40px;
height: 90%;
}
#dataEntryDiv {
border: medium groove;
position: absolute;
top: 0.5em;
height: 95%;
padding-left: 1em;
padding-right: 1em;
}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Email List</title>
</head>
<body id="intactRolesBody" onLoad="onBodyLoader(this);">
<form id='intactRolesForm' method="post" action="" onSubmit="return false;">
<div id="container">
<div id="dataEntryDiv">
<input type="button" id='sbAddELine' value="Add non-company contact"><br>
<p>Email Distribution List</p>
<table>
<tbody id='emailDist'>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>email</th>
<th>remove from list</th>
</tr>
</tbody>
</table>
<input type="button" id='SaveEmailList' value="Save email List">
</div>
</div>
</form>
</body>
</html>
This is the basic behavior of a table. it shrinks and expand acording to its content.
What you can do to manage height is to reset the display.
it can be anything but table/inline-table/table-cell/table-row/.. . nor inline.
You used inline-table, inline-block might be fine:
function onBodyLoader(obj) {
g.c.assignEventListners();
}
var g = {};
g.formClass = function() {
/*
----------------------------------
Properties for formClass
----------------------------------
*/
this.tr;
this.td;
this.elist = [];
/*
----------------------------------
Methods for formClass
----------------------------------
*/
this.assignEventListners = function() {
this.tbody = document.getElementById('emailDist');
g.sbAddELine = document.getElementById('sbAddELine');
g.sbAddELine.addEventListener("click", function(evt) {
g.c.addBlank();
}, false);
/*event listener for all links on the email list body*/
g.dataUpdate = document.querySelector("#emailDist");
g.dataUpdate.addEventListener("click", g.c.tableBodyRouter, false);
};
this.tableBodyRouter = function(e) {
/*
called from clicks on keyTable or task links
*/
if (e.target !== e.currentTarget)
if (e.target.id.indexOf('eRemove') > -1)
g.c.removeEmail(e);
e.stopPropagation();
};
this.redrawElist = function() {
/*delete current table*/
while (this.tbody.rows.length > 1)
this.tbody.deleteRow(1);
/*redraw table*/
for (var i = 0; i < this.elist.length; i++) {
this.rowLayout();
}
};
this.addBlank = function() {
/*add blank to this.elist array*/
this.elist.push({
eEmail: '',
eFirst: '',
eLast: '',
});
this.rowLayout();
}
this.removeEmail = function(e) {
var x = e.target.id.substr(7);
this.elist.splice(x, 1);
this.redrawElist();
};
this.rowLayout = function() {
var rowCnt = this.tbody.rows.length - 1;
this.tr = this.tbody.insertRow(this.tbody.rows.length);
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eFirst' + rowCnt + '" maxlength="20" size="20" value=""/>';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eLast' + rowCnt + '" maxlength="20" size="20" value="" />';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="text" id="eEmail' + rowCnt + '" maxlength="50" size="50" value="" />';
this.td = this.tr.insertCell(this.tr.cells.length);
this.td.innerHTML = '<input type="button" id="eRemove' + rowCnt + '" value="Remove" ">';
document.getElementById("eFirst" + rowCnt).focus();
document.getElementById("eFirst" + rowCnt).select();
}
}
g.c = new g.formClass;
table {
height: 60%;
max-height: 60%;
width: 100%;
display: inline-block;/*... or block : do not use table display if you need to constrain height */
border-style: none;
}
tbody {/* this CSS could have been set to table directly :) */
font-size: 10pt;
display: block;
height: 90%;
overflow-y: scroll;
}
#container {
position: absolute;
width: 98%;
top: 40px;
height: 90%;
}
#dataEntryDiv {
border: medium groove;
position: absolute;
top: 0.5em;
/*left: 37em; removed for demo */
height: 95%;
padding-left: 1em;
padding-right: 1em;
}
<body id="intactRolesBody" onLoad="onBodyLoader(this);">
<form id='intactRolesForm' method="post" action="" onSubmit="return false;">
<div id="container">
<div id="dataEntryDiv">
<input type="button" id='sbAddELine' value="Add non-company contact"><br>
<p>Email Distribution List</p>
<table>
<tbody id='emailDist'>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>email</th>
<th>remove from list</th>
</tr>
</tbody>
</table>
<input type="button" id='SaveEmailList' value="Save email List">
</div>
</div>
</form>
</body>
Note: You did use display:block on tbody, you could have apply this directly to the table element and reset tbody to display:table :) (defaut is table-row-group )
Add
#dataEntryDiv {
overflow: auto;
}
To get a simplified version of the situation, I would suggest writing something like this - instead of putting in the code from your actual project. This way, you can get away from trying to 'fix' something - and possibly see a better way to build the layout - or at least make the use-case more specific.
https://stackoverflow.com/help/how-to-ask
markup
<section class="table-wrapper">
<header>
I'm a table wrapper thing
</header>
<main>
<table>
<!-- populate this -->
</table>
</main>
<footer>
<button>button (add row)</button>
</footer>
</section>
styles
.table-wrapper {
height: 300px; /* arbitrary */
border: 2px solid red;
}
.table-wrapper main {
height: 260px; /* likely you'd use flexbox or percentages or JS */
border: 2px solid blue;
overflow: auto;
}
js
var $table = $('.table-wrapper').find('table');
var $moreButton = $('.table-wrapper').find('button');
var counter = 0;
function addRow() {
counter = counter + 1;
$table.prepend('<tr><td>row and data ' + counter + '</td></tr>');
}
addRow();
// populate some things to start
$moreButton.on('click', function() {
addRow();
});
https://jsfiddle.net/sheriffderek/b6z4ep46/
I want to send form data using ajax done by serialize method but input type text and email is serialized in array but input type file not serialize in array
<form role="form" action="javascript:;" id="myform" enctype = "multipart/form-data" method = "post">
<div class="form-group">
<label for="name">Name:</label>
<input type="text" class="form-control" id="name" name="name" placeholder="Enter Name">
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" class="form-control" id="email" name="email" placeholder="Enter email">
</div>
<div class="form-group">
<label for="email">Photo:</label>
<input type="file" name="userPhoto" id="userPhoto" class="form-control" />
</div>
<button type="submit" class="btn btn-default submit_add" id="enter">Submit</button>
</form>
And Ajax Code
$('.submit_add').click(function(e){
e.preventDefault();
var data = $('#myform').serialize();
console.log(data); return false;
$.ajax({
url: '/ajax',
type: 'POST',
cache: false,
data: data,
dataType: 'json',
success: function(data) {
if (data.success == true ) {
window.location.href = '/';
} else {
alert('Error : There is something wrong.');
}
},
error: function(jqXHR, textStatus, err){
alert('text status '+textStatus+', err '+err);
}
})
});
Console response
name=manish+prajapati&email=kumar%40manish.com
You should try this:
var data = new FormData($("#myform")[0]);
and set:
processData: false,
contentType: false,
See more here: http://portfolio.planetjon.ca/2014/01/26/submit-file-input-via-ajax-jquery-easy-way/
I use jquery (but this can be easily done via vanilla javascript too) to create a hidden text input after the file input. I then set the name of the new text input as the id of the file input it's associated with and set it's value (when a file is selected) to the filename. You can then use $('form').serializeArray(); and return the name:value pairs of the hidden inputs that correspond to the file inputs.
/* The javascript/jquery */
$(document).ready(function(){
// Dynamically create hidden text inputs for the file inputs' data
// (create dynamically to avoid having re-write your entire html file)
$('input:file').each( function(){
$(this).after('<input type="text" readonly name="' + $(this).attr("id").replace("_", " ") + '" hidden value=""/>');
});
// When the user selects a file to be uploaded...
$('input:file').change( function(){
// If a file is selected set the text input value as the filename
if($(this).get(0).files.length !== 0){
$(this).next('input:text').val($(this).get(0).files[0].name);
}
});
$("form").submit( function(e){
e.preventDefault();
//Clear previous data from results div
$('#results').text("");
// Serialize the form data
var x = $('form').serializeArray();
// Iterate through the array results and append
// the data to the results div
$.each(x, function(i, field) {
var result = '<span class="left">' + field.name + ' : </span>';
result += '<span class="right">' + field.value + '</span><br>';
$('#results').append(result);
});
});
});
/* The .css */
form {
display: inline-block;
left: 0;
width: auto;
max-width: 40%;
margin-left: 0;
padding: 0;
}
div.left, div.right, span.left, span.right {
display:block;
position: relative;
width: 40%;
}
.rad { font-size: 14px; }
.left { float: left; }
.right { float: right; }
#results {
display: inline-block;
position: relative;
width: auto;
min-width: 40%;
line-height: 23px;
}
#results .left {
color: green;
text-align: right;
}
#results .right {
color: blue;
text-align: left;
margin-right: 20px;
}
.clearfix { clear: both; }
<!-- The HTML -->
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<form id="myForm">
<div class="left">
<label class="right" for="name">Name:</label><br>
<label class="right" for="gender">Gender:</label><br>
<label class="right" for="file1">1st Pic:</label><br>
<label class="right" for="file2">2nd Pic:</label><br>
<label class="right" for="file3">3rd Pic:</label><br>
<label class="right" for="file4">4th Pic:</label><br>
</div>
<div class="right">
<input class="left" type="text" name="Name" ><br>
<select class="left" name="Gender">
<option selected></option>
<option>Unspecified</option>
<option>Female</option>
<option>Male</option>
</select><br>
<input class="left" type="file" accept="image/*" id="File_1"><br>
<input class="left" type="file" accept="image/*" id="File_2"><br>
<input class="left" type="file" accept="image/*" id="File_3"><br>
<input class="left" type="file" accept="image/*" id="File_4"><br>
</div>
</form>
<div id="results" class="right"></div>
<div class="clearfix"></div>
<input form="myForm" type="submit" id="submit" value="Serialize Form" />
<input form="myForm" type="reset" value="Reset Form" onClick="this.form.reset()" />
</body>
I am trying to create two columns of text boxes which should look like something like the following image:
But it looks something like this:
I used the following code:
HTML
<!DOCTYPE html>
<html>
<head>
<title>DHTML with jQuery</title>
<link rel="stylesheet" href="../css/styles.css">
</head>
<body>
<button id="btnStart">start</button>
<div id="container"></div>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="../js/script.js"></script>
</body>
</html>
HTML from the DOM inspector
<html><head>
<script src="/iScorecard/resources/js/jquery.1.10.2.min.js"></script><style type="text/css"></style>
</head>
<body>
<button id="btnStart" style="display: none;">start</button>
<div id="container">
<input type="text" id="txtPlayerId1" placeholder="player 1">
<input type="text" id="txtPlayerId11" placeholder="0">
<input type="text" id="txtPlayerId2" placeholder="player 2">
<input type="text" id="txtPlayerId12" placeholder="0">
<input type="text" id="txtPlayerId3" placeholder="player 3">
<input type="text" id="txtPlayerId13" placeholder="0">
<input type="text" id="txtPlayerId4" placeholder="player 4">
<input type="text" id="txtPlayerId14" placeholder="0">
<input type="text" id="txtPlayerId5" placeholder="player 5">
<input type="text" id="txtPlayerId15" placeholder="0">
<input type="text" id="txtPlayerId6" placeholder="player 6">
<input type="text" id="txtPlayerId16" placeholder="0">
<input type="text" id="txtPlayerId7" placeholder="player 7">
<input type="text" id="txtPlayerId17" placeholder="0">
<input type="text" id="txtPlayerId8" placeholder="player 8">
<input type="text" id="txtPlayerId18" placeholder="0">
<input type="text" id="txtPlayerId9" placeholder="player 9">
<input type="text" id="txtPlayerId19" placeholder="0">
<input type="text" id="txtPlayerId10" placeholder="player 10">
<input type="text" id="txtPlayerId110" placeholder="0">
<input type="text" id="txtPlayerId11" placeholder="player 11">
<input type="text" id="txtPlayerId111" placeholder="0"></div>
<script type="text/javascript" src="/iScorecard/resources/js/dataTextBoxes.js"></script>
<link rel="stylesheet" href="/iScorecard/resources/css/style.css">
</body></html>
JS
function createTextBoxes(event, txtBoxCount) {
var iCounter = 0,
playerText = null,
scoreText = null;
for (iCounter = 0; iCounter < txtBoxCount; iCounter++) {
playerText = document.createElement('input');
scoreText = document.createElement('input');
$(playerText).attr('type', 'text');
$(scoreText).attr('type', 'text');
$(playerText).attr('id', 'txtPlayerId' + (iCounter + 1));
$(scoreText).attr('id', 'txtPlayerId1' + (iCounter + 1));
$(playerText).attr('placeholder', 'player ' + (iCounter + 1));
$(scoreText).attr('placeholder', '0');
$('#container').append(playerText);
$('#container').append(scoreText);
}
}
$("#btnStart").on('click', function(event) {
createTextBoxes(event, 11);
$("#btnStart").hide();
});
How should I modify the code to create the list of text boxes as shown in the mockup screen.
Yo can accomplish this using css. I can will give you 3 options.
Option 1 - Using only css (with inline-block)
<style type="text/css">
#container{
width:500px;
}
#container input[type="text"]{
display:inline-block;
width:40%;
margin-left:5%;
}
</style>
Above css will make all the input type=text elements as inline-block and take the input width as 40% from parent container. Even you change the main container width. inner elements won't affect. it will always show as two columns
Option 2 - Using only css (with float)
<style type="text/css">
#container{
width:500px;
border:1px solid red;
}
#container input[type="text"]{
display:block;
float:left;
width:40%;
margin-left:5%;
}
.clearfix{
clear: both;
}
.clearfix:before,
.clearfix:after{
display: table;
content: "";
}
.clearfix:after{
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
</style>
In HTML I am adding extra class for the container DIV
<div id="container" class="clearfix">
This option is using float instead of inline-block. Here I have added an extra class .clearfix whenever we do a float we need to clear it after the floating elements. otherwise it will affect for below elements as well
Option 3 - Adding specific class to the player input box and score input box
<style type="text/css">
#container{
width:500px;
}
#container .player,
#container .score{
display:inline-block;
width:40%;
margin-left:5%;
}
</style>
<script type="text/javascript">
function createTextBoxes(event, txtBoxCount) {
var iCounter = 0,
playerText = null,
scoreText = null;
for (iCounter = 0; iCounter < txtBoxCount; iCounter++) {
playerText = document.createElement('input');
scoreText = document.createElement('input');
$(playerText).attr('type', 'text');
$(scoreText).attr('type', 'text');
$(playerText).attr('id', 'txtPlayerId' + (iCounter + 1));
$(scoreText).attr('id', 'txtPlayerId1' + (iCounter + 1));
$(playerText).attr('placeholder', 'player ' + (iCounter + 1));
$(scoreText).attr('placeholder', '0');
$(playerText).attr('class', 'player');
$(scoreText).attr('class', 'score');
$('#container').append(playerText);
$('#container').append(scoreText);
}
}
</script>