Thanks to the help from StackOverflow I have got as far as creating a single line entry with fields and then this adds each field to an array but the Hours SQL statement isn't working e.g. it will have blank sql entries for the first 2 records and then work correctly on another but I cannot see what I am doing wrong. Any help would be very appreciated.
<td colspan="3" align="left"><div id="hoursrow">
<p> <span class="text">Hours Labour :</span></span></p>
<p> <span class="headings"><span class="text"><span class="hours">Start Time:
<input type="time" name="add_start" size="4" />
Finish Time:
<input type="time" name="add_finish" size="4" />
Date:
<input type="date" name="add_date" size="4" />
OVT:
<input type="checkbox" name="add_overtime_hours" id="add_overtime_hours" size="1" maxlength="1" />
</span></span><span class="text"><span class="hours">
<input onclick="addhours(this, event);" type="button" value="Add Labour" />
</span></span></p>
<p class="headings"><span class="text"><span class="hours">
<span class="info">(This row will not be saved unless you click on "Add Labour" first) </span></span></span></p>
</div></td>
<td width="7"></td>
</tr>
<tr>
var rownumhours = 1;
function addhours(obj, e) {
rownumhours++;
var hoursrow = '<p id="rownumhours' + rownumhours + '">Start Time: <input type="time" name="add_start[' + rownumhours + ']" size="4" value="' +
$(obj).closest('span.headings').find('[name="add_start"]').val() + '"> Finish Time: <input type="time" name="add_finish[' + rownumhours + ']" value="' +
$(obj).closest('span.headings').find('[name="add_finish"]').val() + '"> Date: <input type="date" name="add_date[' + rownumhours + ']" value="' +
$(obj).closest('span.headings').find('[name="add_date"]').val() + '"> Show_Overtime: <input type="text" name="show_overtime_hours[' + rownumhours + ']" size="1" value="' +
(($(obj).closest('span.headings').find('[name="add_overtime_hours"]').is(':checked')) ? '1' : '0' ) + '"> Overtime: <input type="checkbox" name="add_overtime_hours[' + rownumhours + ']" size="1" value="' +
$(obj).closest('span.headings').find('[name="add_overtime_hours"]').val() + '"' +
(($(obj).closest('span.headings').find('[name="add_overtime_hours"]').is(':checked')) ? 'checked' : '') +
' "> <input type="button" value="Remove" onclick="removeRow(' +
rownumhours + ');"></p>';
jQuery('#hoursrow').append(hoursrow);
$(obj).closest('span.headings').find('[name="add_start"]').val("");
$(obj).closest('span.headings').find('[name="add_finish"]').val("");
$(obj).closest('span.headings').find('[name="add_date"]').val("");
$(obj).closest('span.headings').find('[name="show_overtime_hours"]').val("");
$(obj).closest('span.headings').find('[name="add_overtime_hours"]').removeAttr('checked');
}
function removeRow(rnum) {
jQuery('#rownumhours' + rnum).remove();
}
So it is showing on the page properly as I want it to but then the major problem is is won't add properly to the database.
I have echo'd the sql that is to be inserted into the database and it shows the following.
INSERT INTO hours(job_number,start_time,finish_time,date,overtime)
VALUES('904','','','','')
INSERT INTO hours(job_number,start_time,finish_time,date,overtime)
VALUES('904','','','','')
INSERT INTO hours(job_number,start_time,finish_time,date,overtime)
VALUES('904','10:10','11:11','2017-01-03','') //
The Sql part is as follows
if (
!empty($_POST['add_start']) && !empty($_POST['add_finish']) && !empty($_POST['add_date']) && !empty($_POST['show_overtime_hours'])&&
is_array($_POST['add_start']) && is_array($_POST['add_finish']) && is_array($_POST['add_date']) && is_array($_POST['show_overtime_hours'])&&
count($_POST['show_overtime_hours']) && count($_POST['add_finish']) && count($_POST['add_date']) === count($_POST['add_start'])
) {
$add_start_array = $_POST['add_start'];
$add_finish_array = $_POST['add_finish'];
$add_overtime_hours_array = $_POST['show_overtime_hours'];
$add_date_array =$_POST['add_date'];
for ($i = 0; $i < count($add_start_array); $i++) {
$add_start_values = $mysqli->real_escape_string($add_start_array[$i]);
$add_finish_values = $mysqli->real_escape_string($add_finish_array[$i]);
$add_date_values = $mysqli-> real_escape_string($add_date_array[$i]);
$add_overtime_hours_boolean = $mysqli-> real_escape_string($add_overtime_hours_array[$i]);
$sql_add_hours = "INSERT INTO hours(job_number,start_time,finish_time,date,overtime) VALUES('$increment_job_number','$add_start_values','$add_finish_values','$add_date_values','$add_overtime_hours_boolean')";
$mysqli-> query($sql_add_hours);
// This next section is for debugging only
//echo ($add_date_values);
//echo ($add_start_values);
//echo ($add_finish_values);
echo ($sql_add_hours);
//echo ($add_overtime_hours_values);
}
Ok, after doing some inspections, actually the first group of the html components produced from the JQuery is :
"Start Time:"
<input type="time" name="add_start[2]" size="4" value="23:57">
"Finish Time:"
<input type="time" name="add_finish[2]" size="4" value="22:57">
"Date:"
<input type="date" name="add_date[2]" value="2017-01-13">
"Show_overtime:"
<input type="text" name="show_overtime_hours[2]" size="1" value="0">
"Overtime:"
<input type="checkbox" name="add_overtime_hours[2]" size="1" value="on">
<input type="button" value="Remove" onclick="removeRow(2)">
You see there...,the counter (rownumhours) starts from 2.
Thus in your php part, the first entries for these array :
$add_start_array = $_POST['add_start'];
$add_finish_array = $_POST['add_finish'];
$add_overtime_hours_array = $_POST['show_overtime_hours'];
$add_date_array =$_POST['add_date'];
Also at 2nd-index, but as your loop starts from zero , hence the entry for the location is empty.
So start the rownumhours in javascript part from -1:
var rownumhours = -1;
Quick Fix
You increment the rownumhours before dynamically adding a new row of fields.
The quickest fix is change the rownumhours value to 0
var rownumhours = 0;
So the newly added row of fields will have the index of 1 and up.
Also add [] to the name tag to the first/default row:
<input type="time" name="add_start[]" size="4"> <!-- this will have an index of 0 -->
<!-- DO THE SAME WITH FIRST/DEFAULT SET OF FIELDS -->
Recommendation
But what you can actually do is do not bother with the assigning of index.
Just put [] to the given row of fields:
<td colspan="3" align="left">
<div id="hoursrow">
<p>
<span class="text">Hours Labour :</span>
</p>
<p>
<span class="headings">
<span class="text">
<span class="hours">
Start Time: <input type="time" name="add_start[]" size="4" />
Finish Time: <input type="time" name="add_finish[]" size="4" />
Date: <input type="date" name="add_date[]" size="4" />
OVT: <input type="checkbox" name="add_overtime_hours[]" id="add_overtime_hours" size="1" maxlength="1" />
</span>
</span>
<span class="text">
<span class="hours">
<input onclick="addhours(this, event);" type="button" value="Add Labour" />
</span>
</span>
</span>
</p>
<p class="headings">
<span class="text">
<span class="hours">
<span class="info">(This row will not be saved unless you click on "Add Labour" first)</span>
</span>
</span>
</p>
</div>
</td>
Then remove the rownumhours and do not assign index for dynamically added input fields:
var hoursrow = '<p id="rownumhours' + rownumhours + '">Start Time: <input type="time" name="add_start[]" size="4" value="' + $(obj).closest('span.headings').find('[name="add_start"]').val() + '"> /*** JUST CONTINUE THE REST OF THE INPUT FIELDS ***/
Thank you all so very much for the help. I am sorry It took a few days to reply. I have made the changes by taking the rownumhours ++ off and using the [] for the naming to be taken care of itself which I had no idea it was clever enough to do it on its own.
The Mysql Section worked well and I also left the html section because I only wanted to have different names for the multiple hours into the entries
var rownumhours = 0;
function addhours(obj, e) {
var hoursrow = '<p id="rownumhours' + rownumhours + '">Start Time: <input type="time" name="add_start[]" size="4" value="' +
$(obj).closest('span.headings').find('[name="add_start"]').val() + '"> Finish Time: <input type="time" name="add_finish[]" value="' +
$(obj).closest('span.headings').find('[name="add_finish"]').val() + '"> Date: <input type="date" name="add_date[]" value="' +
$(obj).closest('span.headings').find('[name="add_date"]').val() + '"> <input type="hidden" name="show_overtime_hours[]" size="1" value="' +
(($(obj).closest('span.headings').find('[name="add_overtime_hours"]').is(':checked')) ? '1' : '0' ) + '"> Overtime: <input type="checkbox" name="add_overtime_hours[]" size="1" value="' +
$(obj).closest('span.headings').find('[name="add_overtime_hours"]').val() + '"' +
(($(obj).closest('span.headings').find('[name="add_overtime_hours"]').is(':checked')) ? 'checked' : '') +
' "> <input type="button" value="Remove" onclick="removeRow(' +
rownumhours + ');"></p>';
jQuery('#hoursrow').append(hoursrow);
rownumhours++;
$(obj).closest('span.headings').find('[name="add_start"]').val("");
$(obj).closest('span.headings').find('[name="add_finish"]').val("");
$(obj).closest('span.headings').find('[name="add_date"]').val("");
$(obj).closest('span.headings').find('[name="show_overtime_hours"]').val("");
$(obj).closest('span.headings').find('[name="add_overtime_hours"]').removeAttr('checked');
}
function removeRow(rnum) {
jQuery('#rownumhours' + rnum).remove();
}
</script>
Related
The following code will get the lowest value entered in first 3 columns, it is running fine. But after adding the row (Add Row) i am unable to get the lowest value from next 3 columns. Also i want to get the sum of all 3 lowest values from as much columns as user will add. Your kind help is required in this regard.
$(document).ready(function() {
var i = 1;
$("#Add_BDSP").click(function() {
$('#BDSP' + i).html("<td><input type='text' name='QuotedAmount1[" + i + "]' placeholder='Quoted Amount' class='form-control' /><input type='text' name='QuotedAmount2[" + i + "]'placeholder='Quoted Amount' class='form-control' /><input type='text' name='QuotedAmount3[" + i + "]' placeholder='Quoted Amount' class='form-control'/></td>");
$('#Tab_BDSP').append('<tr id="BDSP' + (i + 1) + '"></tr>');
i++;
});
$("#Delete_BDSP").click(function() {
if (i > 1) {
$("#BDSP" + (i - 1)).html('');
i--;
}
});
});
var input = $('[name="QuotedAmount1[0]"],[name="QuotedAmount2[0]"],[name="QuotedAmount3[0]"]'),
QuotedAmount1 = $('[name="QuotedAmount1[0]"]'),
QuotedAmount2 = $('[name="QuotedAmount2[0]"]'),
QuotedAmount3 = $('[name="QuotedAmount3[0]"]'),
MulRes = $('[name="ServiceTotalCost"]');
input.change(function() {
var Qoute1 = (isNaN(parseInt(QuotedAmount1.val()))) ? 0 : parseInt(QuotedAmount1.val());
var Qoute2 = (isNaN(parseInt(QuotedAmount2.val()))) ? 0 : parseInt(QuotedAmount2.val());
var Qoute3 = (isNaN(parseInt(QuotedAmount3.val()))) ? 0 : parseInt(QuotedAmount3.val());
MulRes.val(Math.min(Qoute1, Qoute2, Qoute3));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group form-float">
<table class="table table-bordered table-hover" id="Tab_BDSP">
<thead>
<tr>
<td>Amount</td>
</tr>
</thead>
<tbody>
<tr id='BDSP0'>
<td>
<input type="text" name='QuotedAmount1[0]' placeholder='Quoted Amount' class="form-control" required />
<input type="text" name='QuotedAmount2[0]' placeholder='Quoted Amount' class="form-control" required />
<input type="text" name='QuotedAmount3[0]' placeholder='Quoted Amount' class="form-control" required />
</td>
</tr>
<tr id='BDSP1'></tr>
</tbody>
</table>
</div>
<a id="Add_BDSP" class="btn btn-default pull-left">Add Row</a><a id='Delete_BDSP' class="pull-right btn btn-default">Delete Row</a>
</div>
<div class="col-md-4">
<div class="input-group form-group">
<span class="input-group-addon">
<i class="material-icons">business_center</i>
</span>
<div class="form-line">
<input type="number" class="form-control" name="ServiceTotalCost" id="ServiceTotalCost" required>
</div>
</div>
</div>
But after adding the row (Add Row) i am unable to get the lowest value
from next 3 columns
Your main problem is:
QuotedAmount1 = $('[name="QuotedAmount1[0]"]'),
QuotedAmount2 = $('[name="QuotedAmount2[0]"]'),
QuotedAmount3 = $('[name="QuotedAmount3[0]"]'),
Because you just select QuotedAmount1[0] to QuotedAmount3[0], after you append row new input has QuotedAmount1[1] .. , also you used change and for new row you need to use change with document selector, to get live change. And you should move your variable inside of change event. Important things is, you should select your input without name, here is working snippet:
$(document).ready(function() {
var i = 1;
$("#Add_BDSP").click(function() {
$('#BDSP' + i).html("<td><input type='text' name='QuotedAmount1[" + i + "]' placeholder='Quoted Amount' class='form-control' /><input type='text' name='QuotedAmount2[" + i + "]'placeholder='Quoted Amount' class='form-control' /><input type='text' name='QuotedAmount3[" + i + "]' placeholder='Quoted Amount' class='form-control'/></td>");
$('#Tab_BDSP').append('<tr id="BDSP' + (i + 1) + '"></tr>');
i++;
});
$("#Delete_BDSP").click(function() {
if (i > 1) {
$("#BDSP" + (i - 1)).html('');
i--;
}
});
});
$(document).on('change', '#Tab_BDSP tbody tr td input[type="text"]', function() {
let result = 0;
var MulRes = $('input#ServiceTotalCost');
var QuotedAmount1 = $(this).parent().find('input[type="text"]').eq(0),
QuotedAmount2 = $(this).parent().find('input[type="text"]').eq(1),
QuotedAmount3 = $(this).parent().find('input[type="text"]').eq(2);
var Qoute1 = (isNaN(parseInt(QuotedAmount1.val()))) ? 0 : parseInt(QuotedAmount1.val()),
Qoute2 = (isNaN(parseInt(QuotedAmount2.val()))) ? 0 : parseInt(QuotedAmount2.val()),
Qoute3 = (isNaN(parseInt(QuotedAmount3.val()))) ? 0 : parseInt(QuotedAmount3.val());
var min = Math.min(Qoute1, Qoute2, Qoute3);
$(this).parent().attr('data-lowest', min)
$('#Tab_BDSP tbody tr td').each(function() {
result += +$(this).attr('data-lowest')
});
MulRes.val(result)
});
Thank you for kind response,
the code is running perfect,
but the issue is if i change the value in additional rows,
it adds the lowest into the sum,
e.g. 1st row have 300000 400000 500000 and second row have 600000 700000 800000 The total sum will be 900000 which is perfect. but if i change the value from 600000 to 200000 it should shows 700000 but it gives value of 1100000. Your kind help is needed to rectify this issue in the given code. – ADIL I.T 8 mins ago
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group form-float">
<table class="table table-bordered table-hover" id="Tab_BDSP">
<thead>
<tr>
<td>Amount</td>
</tr>
</thead>
<tbody>
<tr id='BDSP0'>
<td>
<input type="text" name='QuotedAmount1[0]' placeholder='Quoted Amount' class="form-control" required />
<input type="text" name='QuotedAmount2[0]' placeholder='Quoted Amount' class="form-control" required />
<input type="text" name='QuotedAmount3[0]' placeholder='Quoted Amount' class="form-control" required />
</td>
</tr>
<tr id='BDSP1'></tr>
</tbody>
</table>
</div>
<a id="Add_BDSP" class="btn btn-default pull-left">Add Row</a><a id='Delete_BDSP' class="pull-right btn btn-default">Delete Row</a>
</div>
<div class="col-md-4">
<div class="input-group form-group">
<span class="input-group-addon">
<i class="material-icons">business_center</i>
</span>
<div class="form-line">
<input type="number" class="form-control" name="ServiceTotalCost" id="ServiceTotalCost" required>
</div>
</div>
</div>
Also i want to get the sum of all 3 lowest values from as much columns
as user will add
For get sum you need to get min and also old lowest value
This code works. I just made all of the script run separately so it worked.
$(".input0").keyup(function() {
var val10 = $("[name='a1[0]']").val();
var val20 = $("[name='a2[0]']").val();
var val30 = $("[name='a3[0]']").val();
var lowestValue0 = Math.min(val10, val20, val30);
$("[name='answer[0]']").val(lowestValue0);
$("[name='total']").val(lowestValue0);
});
$(document).keyup(function() {
var sum = "";
$('.inputClass').each(function() {
sum += this.value;
});
$("[name='total']").val(sum);
});
$(document).ready(function() {
var a = "1";
$(".add").click(function() {
$('<div class="valueDiv' + a + '"><input name="a1[' + a + ']" class="input' + a + '" placeholder="Value 1"><input name="a2[' + a + ']" class="input' + a + '" placeholder="Value 2"><input name="a3[' + a + ']" class="input' + a + '" placeholder="Value 3"><br><h5>Lowest Value = <\/h5><input name="answer[' + a + ']" class="inputClass" readonly placeholder="Lowest Value"><hr><\/div>').appendTo("#mainDiv");
$('#scripts').append('<script type="text/javascript" id="script' + a + '">$(".input' + a + '").keyup(function() { var val1' + a + ' = $("[name=\'a1[' + a + ']\']").val(); var val2' + a + ' = $("[name=\'a2[' + a + ']\']").val(); var val3' + a + ' = $("[name=\'a3[' + a + ']\']").val(); var lowestValue' + a + ' = Math.min(val1' + a + ', val2' + a + ', val3' + a + '); $("[name=\'answer[' + a + ']\']").val(lowestValue' + a + '); });<\/script>');
a++;
});
$(".delete").click(function() {
if (a > 1) {
$(".valueDiv" + (a - 1)).remove();
$("script" + (a - 1)).remove();
a--;
}
var sum = "";
$('.inputClass').each(function() {
sum += this.value;
});
$("[name='total']").val(sum);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<div id="mainDiv" style="width: 100%; height: 100%; padding: 50px;">
<div class="valueDiv0">
<hr>
<input name="a1[0]" class="input0" placeholder="Value 1">
<input name="a2[0]" class="input0" placeholder="Value 2">
<input name="a3[0]" class="input0" placeholder="Value 3">
<br>
<h5>Lowest Value = </h5>
<input name="answer[0]" class="inputClass" readonly placeholder="Lowest Value">
<hr>
</div>
</div>
<div style="width: 100%; height: 100%; padding: 0px 50px;">
<h5>Sum of All Lowest Values</h5>
<input style="width: 230px;" name="total" readonly placeholder="Total Value of All Lowest Values">
</div>
<div id="scripts">
</div>
<br>
<div>
<button class="btn btn-primary add">Add Row</button>
<button class="btn btn-danger delete">Delete Row</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
I have a form that is generated dynamically using PHP with a foreach loop.
The input fields of this form are inturn returning the data in a 3-D array which makes it easy to back-track where to submit these fields and how to store them. so here is is the form:
<?php
$i = 0;
foreach ($shop->fetch()->showResults() as $sr){
$j = 0;
if($i == 0){
echo '<div id="ser'.$sr->id.'" location = "'.$sr->id.'" class="tab-pane fade active in">';
$i++;
} else{
echo '<div id="ser'.$sr->id.'" location = "'.$sr->id.'" class="tab-pane fade">';
$i++;
}
$ser = new Service(Input::get('cd'));
$ser->fetchPriceInShop($sr->id, $ser->fetchData()->id);
foreach ($ser->fetchData() as $price){
echo '<input type="text" value="'.$price->duration.'" name="price['.$sr->id.']['.$j.'][duration]" placeholder="duration (in Minutes)">
<input type="text" value="'.$price->price.'" name="price['.$sr->id.']['.$j.'][price]" placeholder="Price ($ 100)">
<br>';
$j++;
}
echo '
<button style="float: right;" class="addPrice" type="button">+</button>
</div>';
}
?>
so the resulting form is something like this:
<input type="text" value="10.00" name="price[1][0][price]" placeholder="Price ($ 100)">
<br><input type="text" value="20" name="price[1][1][duration]" placeholder="duration (in Minutes)">
<input type="text" value="20.00" name="price[1][1][price]" placeholder="Price ($ 100)">
<br><input type="text" value="30" name="price[1][2][duration]" placeholder="duration (in Minutes)">
<input type="text" value="30.00" name="price[1][2][price]" placeholder="Price ($ 100)">
<br>
now, I am trying to make this form flexible where I can add more fields to it and submit value using them. using the following js for that:
$(".addPrice").on("click", function(){
var location = $(this).parent().attr('location');
var element = '<input type="text" placeholder="duration (minutes)" name="prices['+location+'][index][duration]">';
element += '<input type="text" placeholder="price (aud)" name="prices['+location+'][index][price]"><br>';
$(this).parent().append(element);
});
I somehow managed to fetch the first index (location) and the last index are static, but I have no clue how can I find the second index of the array generated. Please help me figuring out the solution.
PS: I am a noob at stack overflow so please don't be harsh. I am learning to use this platform.
I'm recommending a re-structuring of your multi-dim array to avoid unnecessary counting / incrementing.
The form generating php code:
$i=0;
foreach($shop->fetch()->showResults() as $sr){
echo "<div id=\"ser{$sr->id}\" location=\"{$sr->id}\" class=\"tab-pane fade",(!$i++?" active in":""),"\">";
$ser=new Service(Input::get('cd'));
$ser->fetchPriceInShop($sr->id, $ser->fetchData()->id);
foreach($ser->fetchData() as $price){
echo "<input type=\"text\" value=\"{$price->duration}\" name=\"price[{$sr->id}][duration][]\" placeholder=\"duration (in Minutes)\">
<input type=\"text\" value=\"{$price->price}\" name=\"price[{$sr->id}][price][]\" placeholder=\"Price ($ 100)\">
<br>";
}
echo "<button style=\"float:right;\" class=\"addPrice\" type=\"button\">+</button>";
echo "</div>";
}
*note the $i++ condition first checks if it is zero, then increments. This maintains your intended use. Demo of this technique
The jquery code:
$(".addPrice").on("click", function(){
var location = $(this).parent().attr('location');
var element = '<input type="text" placeholder="duration (minutes)" name="price['+location+'][duration][]">';
element += '<input type="text" placeholder="price (aud)" name="price['+location+'][price][]"><br>';
$(this).parent().append(element);
});
I might also like to recommend the use of data-location instead of location as an attribute name.
You can add a class to your price element and count the elements with that class.
var idx = parent.find('.price').length;
function parsePrice(el) {
var parent = $(el).parent();
var location = parent.attr("location");
var idx = parent.find('.price').length;
var element = '<input type="text" placeholder="duration (minutes)" name="price[' + location + '][' + idx + '][duration]">';
element += '<input type="text" placeholder="price (aud)" name="price[' + location + ']['+idx+'][price]"><br>';
$(element).insertBefore(el);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="1" location="1" class="tab-pane fade active in">
<input type="text" value="10" name="price[1][0][duration]" placeholder="duration (in Minutes)">
<input class="price" type="text" value="10.00" name="price[1][0][price]" placeholder="Price ($ 100)">
<br><input type="text" value="20" name="price[1][1][duration]" placeholder="duration (in Minutes)">
<input class="price" type="text" value="20.00" name="price[1][1][price]" placeholder="Price ($ 100)">
<br><input type="text" value="30" name="price[1][2][duration]" placeholder="duration (in Minutes)">
<input class="price" type="text" value="30.00" name="price[1][2][price]" placeholder="Price ($ 100)">
<br>
<input type="button" onclick="parsePrice(this);" value="go" />
</div>
Alternately you can group your elements inside of parent container, such as a div in your PHP loop:
foreach ($ser->fetchData() as $price){
echo '<div class="pricediv price-'.$sr->id.'"><input type="text" value="'.$price->duration.'" name="price['.$sr->id.']['.$j.'][duration]" placeholder="duration (in Minutes)">
<input type="text" value="'.$price->price.'" name="price['.$sr->id.']['.$j.'][price]" placeholder="Price ($ 100)">
</div>';
$j++;
}
And then select a count of those elements:
function parsePrice(el) {
var parent = $(el).parent();
var location = parent.attr("location");
var idx = parent.find('div').length;
var element = '<input type="text" placeholder="duration (minutes)" name="price[' + location + '][' + idx + '][duration]">';
element += '<input type="text" placeholder="price (aud)" name="price[' + location + '][' + idx + '][price]"><br>';
$(element).insertBefore(el);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="1" location="1" class="tab-pane fade active in">
<div class="pricediv price-1"><input type="text" value="10" name="price[1][0][duration]" placeholder="duration (in Minutes)">
<input class="price" type="text" value="10.00" name="price[1][0][price]" placeholder="Price ($ 100)">
</div>
<div class="pricediv price-2"><input type="text" value="20" name="price[1][1][duration]" placeholder="duration (in Minutes)">
<input class="price" type="text" value="20.00" name="price[1][1][price]" placeholder="Price ($ 100)">
</div>
<div class="pricediv price-3"><input type="text" value="30" name="price[1][2][duration]" placeholder="duration (in Minutes)">
<input class="price" type="text" value="30.00" name="price[1][2][price]" placeholder="Price ($ 100)">
<br>
<input type="button" onclick="parsePrice(this);" value="go" />
</div>
You could use get elements by Tag name to find the index.
$(".addPrice").on("click", function(){
var location = $(this).parent().attr('location');
var index=$(this).parent().getElementsByTagName("input").length/2;
var element = '<input type="text" placeholder="duration (minutes)" name="prices['+location+']['+index+'][duration]">';
element += '<input type="text" placeholder="price (aud)" name="prices['+location+']['+index+'][price]"><br>';
$(this).parent().append(element);
});
I have a section in my system that allows users to enter ingredients and then when they click 'live preview' each ingredient is printed out in plain text so they can check spelling using jQuery. However it will only print out the first element and not the ones after. Can anyone see why? Here is the fiddle http://jsfiddle.net/X94At/
HTML
<div class="recipe-ingredients pure-u-1 pad8bottom clearfix">
<span class="heading">Ingredients</span>
<div class="ingredients pure-u-1 clearfix">
<div class="ingredient pure-u-1 clearfix">
<p>
<input type="text" id="ingredient_1" name="ingredient[]" placeholder="Ingredient" class="element pure-u-6-24" />
<input type="text" id="quantity_1" name="quantity[]" value="" placeholder="Quantity" class="element pure-u-4-24" />
<select id="selectQuantity_1" name="quantityType[]" class="element pure-u-3-24">
<option value="grams">Grams</option>
<option value="ounces">Ounces</option>
<option value="Pounds">Pounds</option>
</select>
<input type="text" id="alternative_1" name="alternative[]" value="" placeholder="Alternative Ingredient" class="element pure-u-6-24" />
<input type="text" id="addedQuantiy_1" name="addedQuantity[]" value="" placeholder="Quantity per extra person" class="element pure-u-4-24" />
</p>
</div>
</div>
Add Ingredient
</div>
HTML For the Live Preview
<div id="toPopup">
<div class="close">×</div> <span class="ecs_tooltip">End Preview<span class="arrow"></span></span>
<div id="live-preview-display">
<div id="lp-name"></div>
<div id="lp-ingredientslist">
<h3>Ingredients</h3>
</div>
<div id="lp-step">
<h3>Method</h3>
</div>
</div>
</div>
<div class="loader"></div>
<div id="backgroundPopup"></div>
jQuery
$(".ingredient").on('blur change focus', function () {
$('.ingredient p').each(function () {
var i = $('.ingredient p').size(),
el = $(this);
if ($('#lp-ingredientslist .ingredient_' + i).length == 0) {
$("#lp-ingredientslist").append('<span class="ingredient_' + i + '"></span>');
}
var ingredient = el.find('input[name="ingredient[]"]').val(),
quantity = el.find('input[name="quantity[]"]').val(),
quantityType = el.find('select[name="quantityType[]"]').val(),
alternative = el.find('input[name="alternative[]"]').val();
if (!quantity || !ingredient)
return;
var alt = '';
if (alternative.length >= 0) {
alt = ' (you can also use ' + alternative + ')';
}
$('#lp-ingredientslist .ingredient_' + i).html(i + '. ' + quantity + ' ' + quantityType + ' of ' + ingredient + alt + '</br></br> ');
});
});
jQuery to add an ingredient
$('.recipe-ingredients #addNewIngredient').on('click', function () {
var i = $('.recipe-ingredients .ingredient').size() + 1;
$('<div class="ingredient pure-u-1 clearfix"><input type="text" id="ingredient_' + i + '" name="ingredient[]" placeholder="Chocolate" class="element pure-u-6-24" /><input type="text" id="quantity_' + i + '" name="quantity[]" value="" placeholder="Quantity" class="element pure-u-4-24" /><select id="selectQuantity_1" name="quantityType[]" class="element pure-u-3-24"><option value="grams">Grams</option><option value="ounces">Ounces</option><option value="Pounds">Pounds</option></select><input type="text" id="alternative_' + i + '" name="alternative[]" value="" placeholder="Alternative Ingredient" class="element pure-u-6-24" /><input type="text" id="addedQuantiy_' + i + '" name="addedQuantity[]" value="" placeholder="Quantity per extra person" class="element pure-u-4-24" />×</div>').appendTo($('.recipe-ingredients .ingredients'));
Thanks!
Not perfect needs improvement
Working Fiddle
$(".ingredient").on('blur change focus', function () {
this line needs to be replaced by
$('.ingredients').on('blur change focus', function () {
as you dynamically are adding the .ingredient class so the changes would appear at .ingredients....
Update
Fiddle with a new look Credit goes to #WASasquatch for pointing it out...
Hope it helps....!!
I am have a dynamic HTML form (jQuery) that a user can add in an ingredient and its quantity, After the user puts in the data I need to save the data as XML. I was thinking of having the quantity as an attribute of the ingredient tag, so for example
<ingredient quantity="250g"> spaghetti </ingredient>
However at the moment I'm not sure how to pass the information in through my array as only a string is allowed as an attribute. I was wondering if anyone had an idea how to do this?
Here are some snippets of my code.
HTML form:
<div id="addIngredient">
<p>
<input type="text" id="ingredient_1" name="ingredient[]" value="" placeholder="Ingredient"/>
<input type="text" id="quantity_1" name="quantity[]" value="" placeholder="quantity"/>
Add
</p>
</div>
<br />
jQuery:
$('#addNewIngredient').on('click', function () {
$('<p> <input id="ingredient_' + i + '" size="40" name="ingredient[]' + '" type=text" value="" placeholder="Ingredient" /><input id="quantity_' + i + '" size="40" name="quantity[]' + '" type=text" value="" placeholder="Quantity" /> Remove </p> ').appendTo(addDiv2);
i++;
return false;
});
PHP:
$ingredients = $xml->createElement('ingredients');
for ($i = 0; $i < 2; $i++) {
$element = $ingredientName[$i];
$ingredient = $xml->createElement('ingredient_name', $element);
$ingredient->setAttribute("quantity", $quantity);
$ingredients->appendChild($ingredient);
}
$recipe->appendChild($ingredients);
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.