Hello everyone I'm still new to JS, so I want to ask about calling a function when form is submitted.
[update] Form
<div id="dashboard-side">
<form id="report" class="form-horizontal" method="post" action="<?= site_url('api/load_report') ?>"> <!-- onsubmit="location.reload()" -->
<fieldset>
<div class="control-group center_div">
<label class="control-label">Sales Name</label>
<div class="controls">
<input type="text" name="sales_name" class="form-control input-xlarge txt-up" value="<?php echo set_value('cust_name'); ?>" placeholder="Enter Customer Name" style="height: 30px;"/>
</div>
</div>
<div class="control-group center_div">
<div class="controls form-inline">
<input id="get_report" type="submit" class="btn btn-success btn-inline " value="Get Report" style="width:110px; margin-left: -155px;"/>
</div>
</div>
<table border="1" width="100%" style="background-color: #dfe8f6;">
<tr>
<td width="154px"><strong>Customer Name</strong></td><td width="128px"><strong>Activity</strong></td>
<td width="244px"><strong>Detail</strong></td><td width="141px"><strong>Start Time</strong></td>
<td width="142px"><strong>Finish Time</strong></td><td width="39px" style="text-align:center"><strong>Note</strong></td>
<td style="margin-left: 50px"><strong>Action</strong></td>
</tr>
</table>
<!------------------------------------------------------------------------------------->
<div id="xreport" class="table-hover" style="background-color: #EAF2F5"></div>
</fieldset>
</form>
</div>
Controller
public function load_report() {
$this->db->where('user_id', $this->input->post('sales_name'));
$query = $this->db->get('activity');
$result = $query->result_array();
$this->output->set_output(json_encode($result)); }
JS
var load_report = function() {
$.get('api/load_report', function(o){
var output = '';
for (var i = 0; i < o.length; i++){
output += Template.dodo(o[i]);
}
$("#xreport").html(output);
}, 'json');
};
If I call the function on form load it works fine, but I want to call it on form submit, how to do that?
Here is what I tried
var load_report = function () {
$("#report").submit(function(){
$.get('api/load_report', function(o){
var output = '';
for (var i = 0; i < o.length; i++){
output += Template.dodo(o[i]);
}
$("#xreport").html(output);
}, 'json');
});
};
Instead of assigning the array into my #div, it shows the array data in the new blank tab like this:
my current result so far
any help would be appreciated, thanks.
Update: New calling function
var load_report = function () {
$("#report").submit(function (evt) {
evt.preventDefault();
var url = $(this).attr('action');
var postData = $(this).serialize();
$.post(url, postData, function (o) {
if (o.result == 1) {
var output = '';
Result.success('Clocked-in');
for (var i = 0; i < o.length; i++) {
output += Template.dodo(o[i]); //this data[0] taken from array in api/load_report
console.log(output);
$("#xreport").html(output);
}
} else {
Result.error(o.error);
console.log(o.error);
}
}, 'json');
});
};
with this new calling function I'm able to retrieve data from api/load_report without getting stuck on e.preventDefault or even open a new tab, I console.log and the result show correctly in the console, but it doesn't show on the div somehow.
my template.js (if needed)
this.dodo = function(obj){
var output ='';
output +='<table border=1, width=100%, style="margin-left: 0%"';
output += '<tr>';
output += '<td width=120px>' + obj.user_id + '</td>';
output += '<td width=120px>' + obj.cust_name + '</td>';
output += '<td width=100px>' + obj.act_type + '</td>';
output += '<td width=190px>' + obj.act_detail + '</td>';
output += '<td width=110px>' + obj.date_added + '</td>';
output += '<td width=110px>' + obj.date_modified + '</td>';
output += '<td style="text-align:center" width=30px>' + obj.act_notes + '</td>';
output += '</tr>';
output +='</table>';
output += '</div>';
return output;
};
Result (note, user_id = form.sales_name)
result preview
First off, I would advise against using onclick or onsubmit directly on the dom like so.
<form onsubmit="myFunction();"></form>
The biggest reason for me is that it negatively impacts readability and sometimes even future maintenance of the project . It is nice to keep html and javascript separate unless you are using a framework that provides templating features/functionality such as angularjs.
Another big one is that you can only have one in-line event present and it is easy to accidentally overwrite, which can lead to confusing bugs.
The reason it is going to a new tab is because of the .submit(). This will call your function, but then proceed with internal jQuery event handling which includes refreshing the page. There are two solutions I see most viable here.
1st Solution:
Add a event.preventDefault(); at the start of your function to stop jQuery from refreshing your page.
$("#report").submit(function(e) {
e.preventDefault();
});
2nd Solution (Likely better):
You are making an ajax call with $.get(...). You could add an event listener on a button (probably on the button used to submit the form) that fires your ajax call. Here is an example that assumes the submit button has the id of loadData.
$("#loadData").click(function(){
$.get('api/load_report', function(o){
var output = '';
for (var i = 0; i < o.length; i++){
output += Template.dodo(o[i]);
}
$("#xreport").html(output);
}, 'json');
}
You could alway do the following:
function myFunction() {
alert("Hello! I am an alert box! in a function");
}
<form>
<input type="text" />
<input type="submit" value="submit" onclick="return myFunction();"/>
</form>
P.S. This question might be answered in this question already, add onclick function to a submit button
Try to prevent form to get submit by using preventDefault()
$("#report").submit(function(e){ //add param "e"
e.preventDefault(); //to prevent form to submit
//further code....
});
Ok just try
function mysubmit(){
$.get('api/load_report', function(o){
var output = '';
for (var i = 0; i < o.length; i++){
output += Template.dodo(o[i]);
}
$("#xreport").html(output);
}, 'json');
}
as your script and
<form id="report" class="form-horizontal" onsubmit="event.preventDefault(); mysubmit();" method="post" action="<?= site_url('api/load_report') ?>">
as your form
I have a table that I get from my MySQL base using ajax. The answer from ajax makes the table in a DIV wrapper.
Now I need to edit this table and if it is needed to save it, but I've got several problems.
My plan was to make a $('td').click() append an input and after pressing enter or clicking anywhere the input should be hidden and the clear TD with new value should appear. After that I presss the UPDATE button and save my row to DB.
But my JavaScript skills are not so good and I failed even with 100 of examples.
Here is my code:
$('#load').click(function() {
//the load button - gets the table from DB
//here I get some data from the website filter.
var data = new webmaster(pid, name, email, skype, web, current_offer, lookingfor_offer, anwsered, comment);
data = JSON.stringify(data);
$('#aw-wrapper').empty();
$.ajax({
type: "POST",
data: {
"data": data
},
url: "inc/load-web.php",
success: function(anwser) {
$('#aw-wrapper').html(anwser);
TableEdit();
}
});
});
function TableEdit() {
if (i) {
$('td').click(function() {
this.onclick = null;
var td_value = $(this).html();
var input_field = '<input type="text" id="edit" value="' + td_value + '" />'
$(this).empty().append(input_field);
$('input').focus();
i = 0;
});
}
}
But it doesnot work at all. I got many clicks on td instead of one. Maybe I am doing it wrong and it can be realized easier?
I dont see where i is defined. I changed your function to look like this:
function TableEdit() {
var i = 1;
$('td').click(function() {
if (i) {
this.onclick = null;
var td_value = $(this).html();
var input_field = '<input type="text" id="edit" value="' + td_value + '" />'
$(this).empty().append(input_field);
$('input').focus();
i = 0;
}
});
}
if I understand what you want i believe it gives the desired result, however, this is how i would implement this
function TableEdit() {
$('td').click(function() {
var td_value = $(this).html();
var input_field = '<input type="text" id="edit" value="' + td_value + '" />'
$(this).empty().append(input_field);
$('input').focus();
$('td').off('click');
$(this).find('input').blur(function(){
var new_text = $(this).val();
$(this).parent().html(new_text);
TableEdit();
})
});
}
updated fiddle https://jsfiddle.net/vf2L78p8/2/
Created a basic input textbox and a button dynamically via javascript using some bootstrap css. On pressing the button I need to retrieve the value of the textbox. But its coming out to be empty (not undefined).
The doSearch function is where I need to pick up the value.
Here is the jsFiddle: http://jsfiddle.net/9u3kb6rk/3
Here is the code:
(function ($) {
function doSearch() {
alert($('#name').val());//this is empty?
}
$(document.body).on('click', '#go', function () {
alert('doing search');
doSearch();
});
$.fn.searchName = function () {
var caller = $(this);
var output = '';
output += '<div class="input-group ">';
output += '<span class="input-group-addon area" id="name" name="name">Name</span>';
output += '<input type="text" class="form-control" />';
output += '</div>';
output += '<div class="input-group">';
output += '<span class="input-group-btn">';
output += '<button class="btn btn-primary" type="button" id="go">Search</button>';
output += '</span>';
output += '</div>';
output += '</div>';
$(caller).html(output);
return this;
}
}(jQuery));
$(document).ready(function () {
$('#searchName').searchName();
});
The id must be in the input instead of in the span.
output += '<span class="input-group-addon area">Name</span>';
output += '<input type="text" id="name" name="name" class="form-control"
Your code updated.
I have a MySQL database of orders that each have various activities associated with them. My PHP/HTML page pulls down the activities when you click an order and allows the user to change attributes of the activities with a form. On submit another PHP file loops through activities in the table and runs an update query on the database. Works great!
I have recently added a JavaScript function that will add activities to the list (appendChild, createElement...). I then added to my PHP file an INSERT query for the new activities.
The problem is that when I run the update PHP file it is not looping through the newly added records that were added with JavaScript. I checked it by using <?php print $size = count($_POST['FcastID']) ?> and the value doesn't change when records have been added.
The records look fine when added to the table and the id and name convention match the other records. It seems like the page needs to be refreshed before the PHP file runs.
PHP file with dynamically created html form
<div id="submit"><form method="post" action="Up_Forecast.php"><input type="submit" value="Submit"></div>
....
<table id="fcast">
<?
$i=0;
while($row = mysqli_fetch_array($res_fcast))
{
echo "<tr id='fcastRow[$i]'>";
echo "<td class='medium'><input type='text' id='qtyJan[$i]' name='qtyJan[$i]' value='".$row[Jan]."'/></td>";
echo "<td class='medium'><input type='text' id='qtyFeb[$i]' name='qtyFeb[$i]' value='".$row[Feb]."'/></td>";
echo "<td class='medium'><input type='text' id='qtyMar[$i]' name='qtyMar[$i]' value='".$row[Mar]."'/></td>";
echo "<td class='medium'><input type='text' id='qtyApr[$i]' name='qtyApr[$i]' value='".$row[Apr]."'/></td>";
echo "<td class='medium'><input type='text' id='qtyMay[$i]' name='qtyMay[$i]' value='".$row[May]."'/></td>";
echo "<td class='medium'><input type='text' id='qtyJun[$i]' name='qtyJun[$i]' value='".$row[Jun]."'/></td>";
echo "<td class='medium'><input type='text' id='qtyJul[$i]' name='qtyJul[$i]' value='".$row[Jul]."'/></td>";
echo "<td class='medium'><input type='text' id='qtyAug[$i]' name='qtyAug[$i]' value='".$row[Aug]."'/></td>";
echo "<td class='medium'><input type='text' id='qtySep[$i]' name='qtySep[$i]' value='".$row[Sep]."'/></td>";
echo "<td class='medium'><input type='text' id='qtyOct[$i]' name='qtyOct[$i]' value='".$row[Oct]."'/></td>";
echo "<td class='medium'><input type='text' id='qtyNov[$i]' name='qtyNov[$i]' value='".$row[Nov]."'/></td>";
echo "<td class='medium'><input type='text' id='qtyDec[$i]' name='qtyDec[$i]' value='".$row[Dec]."'/></td>";
echo "<td class='medium'><input type='text' id='Totalqty[$i]' name='Totalqty[$i]' value='".$row[Total]."' disabled/></td>";
echo "</tr>";
++$i;
}
?>
<tr><td class="blank"></td><td class="mini"><input type="button" onclick="addRowYear(this)" value="Add"/></td></tr>
</table>
</form>
</div>
Javascript function to add row
function addRowYear(lastRow){
var rowNo = lastRow.parentNode.parentNode.rowIndex;
var newRow = document.getElementById("fcast").insertRow(rowNo);
newRow.setAttribute("id","fcastRow["+rowNo+"]");
var cell0 = newRow.insertCell(0);
cell0.setAttribute("class","mini");
var input0 = document.createElement("input");
input0.setAttribute("type","text");
input0.setAttribute("name","FcastID["+rowNo+"]");
input0.setAttribute("value","new");
cell0.appendChild(input0);
var cell1 = newRow.insertCell(1);
cell1.setAttribute("class","mini");
var input1 = document.createElement("input");
input1.setAttribute("type","text");
input1.setAttribute("name","Fcast_ActID["+rowNo+"]");
input1.setAttribute("id","Fcast_ActID["+rowNo+"]");
cell1.appendChild(input1);
var curAct = document.getElementById("selAct").innerHTML;
document.getElementById("Fcast_ActID["+rowNo+"]").value = curAct;
var cell2 = newRow.insertCell(2);
cell2.setAttribute("class","mini");
var input2 = document.createElement("input");
input2.setAttribute("type","text");
input2.setAttribute("name","Year["+rowNo+"]");
cell2.appendChild(input2);
var month = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
for (var i = 0; i < month.length; i++) {
//alert(month[i]);
x=3;
var cell = newRow.insertCell(x);
cell.setAttribute("class","medium");
var input = document.createElement("input");
input.setAttribute("type","text");
input.setAttribute("class","numbers");
input.setAttribute("name","qty"+month[i]+"["+rowNo+"]");
input.setAttribute("id","qty"+month[i]+"["+rowNo+"]");
input.setAttribute("onkeyup","findTotal()");
cell.appendChild(input);
x=x+1;
}
var cell15 = newRow.insertCell(15);
cell15.setAttribute("class","medium");
var input15 = document.createElement("input");
input15.setAttribute("type","text");
input15.setAttribute("class","numbers");
input15.setAttribute("name","Totalqty["+rowNo+"]");
input15.setAttribute("id","Totalqty["+rowNo+"]");
cell15.appendChild(input15);
PHP Update - Called on Submit of form
$size = count($_POST['FcastID']);
$i = 0
while ($i < $size) {
$FcastID = $_POST['FcastID'][$i];
$ActID = $_POST['Fcast_ActID'][$i];
$Year = $_POST['Year'][$i];
$Jan = $_POST['qtyJan'][$i];
$Feb = $_POST['qtyFeb'][$i];
$Mar = $_POST['qtyMar'][$i];
$Apr = $_POST['qtyApr'][$i];
$May = $_POST['qtyMay'][$i];
$Jun = $_POST['qtyJun'][$i];
$Jul = $_POST['qtyJul'][$i];
$Aug = $_POST['qtyAug'][$i];
$Sep = $_POST['qtySep'][$i];
$Oct = $_POST['qtyOct'][$i];
$Nov = $_POST['qtyNov'][$i];
$Dec = $_POST['qtyDec'][$i];
$Total = $_POST['Totalqty'][$i];
$update = "UPDATE FCAST SET
Year='$Year',
Jan=replace('$Jan',',',''),
Feb=replace('$Feb',',',''),
Mar=replace('$Mar',',',''),
Apr=replace('$Apr',',',''),
May=replace('$May',',',''),
Jun=replace('$Jun',',',''),
Jul=replace('$Jul',',',''),
Aug=replace('$Aug',',',''),
Sep=replace('$Sep',',',''),
Oct=replace('$Oct',',',''),
Nov=replace('$Nov',',',''),
`Dec`=replace('$Dec',',',''),
Total=replace('$Total',',','')
WHERE
FcastID='$FcastID'";
mysqli_query($link, $update);
Without seeing your code, it is difficult to say. Something I have used in the past that works well is the following:
PHP:
foreach($_POST as $key => $value) {
//... $key is name of field, $value is the value
}
This goes through each individual field in the submitted form and reads the value in each. I've used this exact script for dynamically-created forms, and it works great. You have to be careful, though, if you use the same name for different fields, the values will be stored as arrays.
EDIT
HTML:
<form method="post" action="index.php">
<div>
<div>
<p>
<label class="reg_label" for="field_name">Item:</label>
<input class="text_area" name="field_name[]" type="text" id="testing" tabindex="98" style="width: 150px;"/>
</p>
</div>
</div>
<input type="button" id="btnAdd" value="Add" class="someClass1"/>
<input type="button" id="btnDel" value="Remove" class="someClass2" disabled/><br><br>
<input type="submit" id="submit" name="submit" value="Submit">
</form>
JavaScript:
var j = 0;
$(document).ready(function () {
$('.someClass1').click(function (e) {
var num = $(this).prev().children().length;
var newNum = new Number(num + 1);
var newElem = $(this).prev().children(':last').clone().attr('id', 'input' + newNum);
if(newElem.children().children().last().hasClass('otherOption')){
newElem.children().children().last().remove();
}
newElem.children().children().each(function(){
var curName = $(this).attr('name');
var newName = '';
$(this).attr('id', 'name' + num + '_' + j);
j++;
});
newElem.children().children().each(function(){
$(this).removeAttr('value');
});
$(this).prev().children(':last').after(newElem);
$(this).next().removeAttr('disabled');
});
$('.someClass2').click(function (e) {
var num = $(this).prev().prev().children().length;
$(this).prev().prev().children(':last').remove();
if (num - 1 == 1) $(this).attr('disabled', 'disabled');
});
});
It isn't all that important to know how the JavaScript code works. All you need to know is that clicking on the "Add" button will duplicate the field and clicking on "Remove" will remove the most recently added field. Try it out at the link provided.
PHP:
This is where the magic happens…
<?php
if(isset($_POST['submit'])){
foreach($_POST as $name => $item){
if($name != 'submit'){
for($m=0; $m < sizeof($item); $m++){
echo ($name.' '.$item[$m].'<br>');
}
}
}
}
?>
Looks easy enough, right?
This PHP code is within the same file as the form, so first we check to see if the form has been submitted by checking for the name of the submit button if(isset($_POST['submit'])){…}.
If the form has been submitted, go through each submitted item foreach($_POST as $name => $item){…}.
The submit button counts as one of the fields submitted, but we aren't interested in storing that value, so check to make sure the value you are reading in is not from the submit button if($name != 'submit'){…}.
Finally, all the fields within this form have the same name field_name[]. The square brackets are used for multiple items that share the same name. They are then stored in an array. Read through each item within that array for the length of the array for($m=0; $m < sizeof($item); $m++){…} and then do what you'd like with each value. In this case, I've just printed them to the screen echo ($name.' '.$item[$m].'<br>');
Below are a couple screen-shots of the page…
Before submitting the form:
After submitting the form:
You can go to the page and view the code (right click -> View Source), but the PHP will not show up in the source. I assure you that all the PHP used for this is shown above - just the few lines.
If each item has a completely unique name (which you can achieve via JavaScript when adding fields), then you will not need to loop through the array of values (i.e. will not need for($m=0; $m < sizeof($item); $m++){…} block). Instead, you'll likely read the value using simply $item. If you name your fields with the square brackets (i.e. field_name[]), but only have one of that field, then reading a singular value may require $item or $item[0]. In that case you'll just have to test it and see. Some field types behave differently than others (i.e. input, text area, radio buttons, etc).
The Whole Thing
Here is the entire code for index.php - you can just copy and paste it and run it on your own server. Just make sure to change the name of the file in the action attribute <form> tag…
<?php
if(isset($_POST['submit'])){
foreach($_POST as $name => $item){
if($name != 'submit'){
for($m=0; $m < sizeof($item); $m++){
echo ($name.' '.$item[$m].'<br>');
}
}
}
}
?>
<html>
<head>
<script type="text/javascript" src="../scripts/jquery-1.8.2.min.js"></script>
</head>
<body>
<form method="post" action="index.php">
<div>
<div>
<p>
<label class="reg_label" for="field_name">Item:</label>
<input class="text_area" name="field_name[]" type="text" id="testing" tabindex="98" style="width: 150px;"/>
</p>
</div>
</div>
<input type="button" id="btnAdd" value="Add" class="someClass1"/>
<input type="button" id="btnDel" value="Remove" class="someClass2" disabled/><br><br>
<input type="submit" id="submit" name="submit" value="Submit">
</form>
</body>
<script>
var j = 0;
$(document).ready(function () {
$('.someClass1').click(function (e) {
var num = $(this).prev().children().length;
var newNum = new Number(num + 1);
var newElem = $(this).prev().children(':last').clone().attr('id', 'input' + newNum);
if(newElem.children().children().last().hasClass('otherOption')){
newElem.children().children().last().remove();
}
newElem.children().children().each(function(){
var curName = $(this).attr('name');
var newName = '';
$(this).attr('id', 'name' + num + '_' + j);
j++;
});
newElem.children().children().each(function(){
$(this).removeAttr('value');
});
$(this).prev().children(':last').after(newElem);
$(this).next().removeAttr('disabled');
});
$('.someClass2').click(function (e) {
var num = $(this).prev().prev().children().length;
$(this).prev().prev().children(':last').remove();
if (num - 1 == 1) $(this).attr('disabled', 'disabled');
});
});
</script>
</html>
I'm currently working on some input forms in JavaScript, and I've edited by script so that once the user enters the number of forces for a problem, new input text fields show up per number, also there is a button which is added at the end of that. The issue is when I try and click this button, I try and use the .map function to start all text field values into it and nothing is happening.
function forceRecording(numofforces,$this){
var addRows='<tr id=newRows>';
for(var i =1; i<=numofforces;i++)
{
var nearTr=$this.closest('tr');
addRows=addRows + "<td>Force " +i+": </td><td><form><input type='text' name='forceItem' id='newR'/></form></td>";
}
addRows=addRows+"<td><div class='button' id='forceButton'> Add! </div></td></tr>";
nearTr.after(addRows);
};
$('#forceButton').click(function(){
forces=$("input[id='newR']").map(function(){
return $(this).val()
});
function forceRecording(numofforces,$this){
var addRows='<tr id=newRows>';
for(var i =1; i<=numofforces;i++)
{
var nearTr=$this.closest('tr');
addRows=addRows + "<td>Force " +i+": </td><td><form><input type='text' name='forceItem' id='newR'/></form></td>";
}
addRows=addRows+"<td><div class='button' id='forceButton'> Add! </div></td></tr>";
nearTr.after(addRows);
};
$('#forceButton').click(function(){
forces=$("input[id='newR']").map(function(){
return $(this).val()
});
prompt("forces");
});
As you can see my forceRecording function is working and creates a new row with new text input fields per the numofforces but once I try clicking the forceButton to enter the values into my forces array nothing happens. Any idea what could be causing this?
You are missing the closing paranthesis around your code here
$('#forceButton').click(function(){
forces=$("input[id='newR']").map(function(){return $(this).val()
});
It should be like this
$('#forceButton').click(function(){
forces=$("input[id='newR']").map(function(){
return $(this).val();
});
});
And don't use the id instead use a class name
$('#forceButton').click(function(){
forces=$(".newR").map(function(){
return $(this).val();
});
});
Apply the class to input field like this
<input type="text" name="forceItem" class="newR"/>
I have absolutely no idea what you're trying to achieve, but maybe this will help:
function forceRecording(numofforces, $this) {
var addRows = '<tr id="newRows">';
for (var i = 1; i <= numofforces; i++)
addRows += '<td>Force ' + i + ': </td><td><input type="text" name="forceItem" /></td>';
addRows += '<td><input type="button" class="button" id="forceButton" value="Add!" /></td></tr>';
$this.closest('tr').after(addRows);
}
$('#forceButton').click(function() {
forces = $(this).parent().parent().filter('input[name="forceItem"]').map(function() { return $(this).val(); });
});