I have a table where I am showing some data in first three columns but in last column user enters his feedback/comments. On submit, data is posted and sent via email.
Problem is values in textarea are not posted upon submit. I have 6 rows in my table.
Sample TR
<tr>
<td>1</td>
<td>TEST 123</td>
<td>TEST</td>
<td><input type="text" value="" id="prbt-rev" ></td>
</tr>
AJAX CALL
$(document).on('click','#email',function(e){
e.preventDefault();
var reportData = $("#report-data").html();
var request = $.ajax({
url : '<?=base_url();?>healthcheck/sendEmail',
type : 'POST',
data : {report:reportData}
});
request.done(function(response){
$('#result').html(response);
}); });
Your selector #report-data doesn't match any element in the HTML you've shared. Either some HTML is missing or you are using the wrong selector.
The jQuery html() method gets the child nodes of the selected element. A text input doesn't have any child nodes. A textarea's child nodes describe its default value, not its current value.
Use val() to read the current value of a form control.
Your HTML code has missing the fields that you getting in the jquery!.
Its more helpful and easy to give tips if you put here your full code here that you are using.
Related
I have a button, when I click I want it to get all data from the row. My .php file (i also have php code not included here) looks like so (I trimmed out the table for stackoverflow)
<tr class='rowdata'>
<td>Bob</thd>
</tr>
<input type='submit' class='getRow' value='ClickMe'>
<script>
$(".getRow").click(function() {
var rowOfData = $(this).closest(".rowdata");
alert(rowOfData.text());
});
</script>
Right now I click and nothing happens. Any ideas? The . prefix means it is searching for class.
Well first, have you checked your developer's console (F12) to see if you have any errors. Are you sure you've referenced the JQuery library.
Next, even with JQuery referenced, .closest() is going to search the ancestor elements of the element you call it on. If your button is not a descendant of the element you wish to find, you won't find it.
Now, assuming that .closest() does find your row, you are then asking for the .text() in the entire row. This may be what you want, but it's seems more likely that you'd want data cell by cell.
Also, your button is a submit button which is used for submitting form data, but it doesn't appear that that's what you're doing here. If that's the case, use a regular button.
And, your HTML isn't valid as you have a bad closing tag for your cell.
So, correcting all that:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr class='rowdata'>
<td>Bob</td>
<td>Smith</td>
<td><input type='button' class='getRow' value='ClickMe'></td>
</tr>
</table>
<script>
$(".getRow").click(function() {
var rowOfData = $(this).closest(".rowdata");
alert(rowOfData.text()); // Gets all the text in the row
alert($("td:first-child", rowOfData).text()); // Gets just first cell
});
</script>
I am trying to convert a normal field to autocomplete and making a ajax call to get the data in JSON and then set it to that autocomplete.
I do not know much on JQUERY, I spent around 5-6 hours just to know I have to initialize before using any function on the auto complete field.
What I have done so far
I managed to initialize and convert my text field to autocomplete and checked that using the inspect option it shows autocomplete , and also am able to make the ajax call which is pulling the data verified that using f12 network option.But it does not show up as a type ahead in my autocomplete option.
HTML
<div id ="myName">
<table class="some_class">
<tbody>
<tr>
<td >
<label>NAMES</label>
</td>
</tr>
<tr>
<td >
<input type="text" id="nameText" />
</td>
</tr>
</tbody>
</table>
</div>
initialization part
myName.on('valueChange',function (value){
$("#nameText").autocomplete({
appendTo:"#nameText",
source:function(event,ui){
var name=myName.value();
$.ajax({
url: "www.getmeSomeData.com/query/name:"+name,
type:"GET".
dataType:"json",
success:function(result){
//set this result in autocomplete which I am not sure how to do
}
});
},minLength:1});
});
$("#nameText").focus(function(even,ui){
$((this).data("uiAutocomplete").search$(this).val());
});
PROBLEM
1.The autocomplete does not show any result even though from ajax call i see json data coming.
2.The value change starts only after i type abc and then move the cursor somewhere else and then click it back,before that nothing invokes.Where as what is expected is as soon as I type a or ab or abc it should make ajax call and pull the data show in autocomplete dropdown.
Can someone please help? I did not come here without researched but I think i tried a lot of things and nothing worked so am totally confused.Kindly help me, i have spent around 2 days on this.
Thanks in advance.
I finally figured out what was the problem in my code.I actually was not able to add option to my input autocomplete.To make it work I needed to update my html with
HTML
just replace <input class="nameClass" type="text" id="nameText" />
And the jquery part needed updates, the above was just a very novice attempt.
1. I should have used $.each($(".nameClass"), function(index, item) {
2. and then $(item).autocomplete
3. Also in source should have used source:function(request,response)
4. In the ajax call request.term (which will take whatever you input in the autocomplete field where as my method was invoking the ajax call only after tab out.
5. Map the data of response response($.map(data.data, function(item){
6. Write a select callback function to make anything happen after i click on any entry in the typeahead
7.data("ui-autocomplete")._renderItem = function (ul, item) { >To show the data in a formatted way after the ajax call.
INITIALIZATION
$.each($(".nameClass"), function(index, item) {
$(item).autocomplete({
source:function(request,response){
$.ajax({
url: "www.getmeSomeData.com/query/name:"+request.term,
type:"GET".
dataType:"json",
success:function(result){
//set this result in autocomplete which I am not sure how to do
response($.map(data.data, function(item){
return{
value:item.somethigncomingfromJson //will set into the field
data:item
}}))}}
});
} ,minLength :2,
select:function(event,ui){
//do something on select of a row in the autocomplete dropdown
}}).data("ui-autocomplete")._renderItem=function(ul,item){
return $("format in which you want to see the data").appendTo(ul);
});
}
No other event is required.
I have a FORM on a PHP web page that accepts a table of data (editable-grid) which the end-user is in control of in that they can add as many rows as they like. One of the fields is also a TEXTAREA which means each row has a variable size.
If the post is too large however, it will be rejected by the server and all the target page will see is an empty $_POST. Worse, if the user navigates back to the input page, it will show its initial empty state, losing all data entered and annoying the end-user to say the least.
I could increase the POST_max_size setting in PHP, but all that will do is push the boundary at which it will fail.
I could also check in JavaScript what the size of the post will be, PRIOR to them submitting the form, ideally as they add each row or change the textarea content, but I'm not sure how accurate or slow that will be. It also means they would have to remove some data or rows.
The only other option I can think of is to submit each row individually in a hidden FORM, through AJAX, once they click the Submit button. I'm not sure it is a good idea to replace one post with hundreds of posts to the server.
Any other ideas?
Instead of sending the entire datagrid you can just send the edited row as if it were a single form using javascript. If you send each row in a loop with ajax even if it is not edited you can choke the server in the same way as if you were sending the entire datagrid. Instead of sending 20k rows of data with just one column modified, just send one row when the user leaves the textarea.
I don't know how you manage the editing events but with jQuery (for the sake of simplicity) could be something like this.
$(document).ready(function() {
$('textarea, input').on('blur', function(e) {
var $row = $(this).closest('tr')
var data = {
id: $row.data('id'),
input: $row.find('td input').val(),
textarea: $row.find('td textarea').val()
};
// e.g. foo.php/1
$.post("foo.php/" + data.id, data)
.success(function() { /* silent success */ })
.fail(function() { alert('Error') })
});
});
with html
<table>
<tbody>
<tr data-id="1">
<td><input /></td>
<td><textarea></textarea></td>
</tr>
<tr data-id="2">
<td><input /></td>
<td><textarea></textarea></td>
</tr>
<tr data-id="3">
<td><input /></td>
<td><textarea></textarea></td>
</tr>
</tbody>
</table>
example jsfiddle https://jsfiddle.net/vt0a0udx
ps: sorry for the bad english.
try to change this value in php.ini
max_input_vars = 1000 to 10000
I have a simple HTML page where I will be having few rows, each row specifies a record in database, I have some input fields on each to collect and a link at the end, when I click that I need to collect the input field values on the same row.
The HTML goes like this:
<tr>
<td>Name</td>
<td><input name="mode_sort"/></td>
<td><input name="mode_selected" type="checkbox"/></td>
<td>Add</td>
</tr>
So I will be writing my code to collect input fields on the row when I click the "Add" link, I'm not sure how to pass the current clicked selector and get the field values with that in add_this_mode() function.
Within the function you can use jQuery traverse methods to isolate the parent row and then to find elements within that row
function add_this_mode( elem){
/* get parent row */
var $row = $(elem).closest('tr');
/* use find() to get other elements in row */
alert( $row.find('[name=mode_sort]').val() );
}
I am developing a webapp using Spring, jsp, javascript, jquery.
I display a table using datatables.
When I click on a table row I want it to change all fields to an inline edit inputs, selects etc. In addition I want to show some extra input fields in the next row and a save button.
Now I see several ways of doing this. I am not sure which one to take.
I can get a handle to selected row and then iterate over the td and transform them to input/select fields. I can then insert an extra row for the new fields and the save button.
I don't see this as a clean solution. I will have to issue a Post manually instead of using the Spring ModelAttribute binding for the form. (Can I still use ModelAttribute here?)
I can create an edit form in a jsp file which looks like:
<form:form action="" commandName="">
<td> <input ... > </td>
<td> <select ... > </td>
</tr>
<tr>
<td> <label> <input new field> </td>
<td> <button> </td>
</tr>
Note I do not have a beginning in a jsp file as I plan to reuse the tr from the existing row in the table.
This way I would be able to have a clean form and also use the update method I have already written which binds the form to a Java class. Also I do not have to bother about the alignment of input fields with the column names.
The generated html looks like
...
The problem with this approach is the placement of form element in the html causes the entire form to be cramped into one cell of the table which does not look good and messes up the whole layout. Is there a way out? Should I just replace the contents of the table with a having a colspan and then put divs inside this element and fine tune the css to ensure that the input fields align with the column names in the table?
Is there a better solution you can suggest?
In case the question is not very clear I can fill in more details.
This is what I would do (coming from a server-side development background, as I know developers love easy solutions)
Wrap the table with a single form
on Edit row (clicking row) open an ajax request that returns pure html that looks like the exact tr, only with whatever extra you want to include:
<tr><td><input type="text" name="text1" ... /></td><td>second row... </td></tr>
<tr><td colspan="2">And hey, here is more, and the save button ... </td></tr>
in jQuery replace tr with content retrieved (myTr.replace($(ajaxResponse))) or something similar
now Save button is a regular submit for the form
if you want to submit via ajax, once done, return the old html in your ajax response and replace the two trs with the old tr (you just need to hook it by giving new trs an attribute that you can find easily in jquery)
don't forget to switch off a global key to prevent double editing, users can edit one row at a time
Update: adding a second solution to dump load on client instead of server
To avoid overloading the server (though I wouldn't be worried about it until it becomes a regular habit), you can make your form fields as a template inside your HTML and use string replacement (or jQuery Templates), so instead of ajaxing to get response in step 2, you call the template, and replace the strings with attributes you save in every row... like this:
<div id="myTemplate"> // or you can use jQuery script templates
<tr><td><input type="text" name="${Name}" ... /> id is ${Id}</td><td>${SecondRow}... </td></tr>
<tr><td colspan="2">Save button here.... and may be more text ${MoreText}</td></tr>
</div>
in every row in your code add sufficient attributes or ids to know what you want to replace with, like this:
<tr data-itemid="34"><td ><input type="text" name="text1" id="findme" ... /></td><td data-moretext="here is more text">second column </td></tr>...etc
so now in your replacement script:
$("#myTemplate").html().replace("${Name}", $(thisrow).find("#findme").attr("name"))
.replace("${Id}",$(thisrow).attr("data-itemid"));
etc...
Of course after submission it has to be a to server, but in case user "cancels" you can have another readonly template
By the way, that is the way I usually go with, I use jQuery templates, and create edit and view templates, but I also repeat edit forms and I use jQuery ajax submit manually... but that... my friend, is not a simple clean and maintainable solution I'm afraid
I've been into an issue like this a year before. This is a messy problem. Either way if you traverse each td of row and convert it into text field or You can create a separate jsp file for this.
But the best in this case is to change the content of td to input field and post the data manually. because in this case you cannot wrap form tag around tr. You have to manually post the values of each input field.
P.S The very best solution is to create an edit dialog.
There is another solution, but I'm under the impression you won't like it very much... you can use a single form for the whole datatable (wrapping the whole table in a form is permitted) generate input fields for the current row and if it's updated submit the form asyncronously with javascript and restore td contents to the original html, if you name your fields such as name="field[]" you can also submit multiple rows at a time (I don't know if you'd want that though).
You can write html code such as
<form action="">
<table>
<tr><td><input type="hidden" name="row[]" value="1"/><input name="field[]"/></td></tr>
<tr><td>field value for row2</td></tr>
<tr><td><input type="hidden" name="row[]" value="3"/><input name="field[]"/></td></tr>
</table>
</form>
you can just grab the form with jquery and submit it via xmlhttprequest as I suspect you would if each row was a separate form (which is illegal), if you don't want multiple rows, just remove the [] and submit each row
and upon submitting the values you get them numbered correctly, don't know exactly how it would behave in java but in php I'd get the following:
$_GET[row][0] = 1;
$_GET[field][0] = 'value typed in row1';
$_GET[row][1] = 3;
$_GET[field][1] = 'value typed in row3';
Alternative table definition to avoid having the same name again
<form action="">
<table>
<tr><td><input name="field[1]"/></td></tr>
<tr><td>field value for row2</td></tr>
<tr><td><input name="field[3]"/></td></tr>
</table>
</form>
It's the same table as above only you set explicit indexes for each entry thus avoiding duplicate names in the response, preferrably use a unique identifier which can describe the row from the table that you're modifying in there (when possible I use the primary key) instead of the row number, just in case that wasn't clear enough.
Have you tried:
Wrap whole table in the form
have the data entries as disabled inputs with their borders hidden via CSS
when user clicks edit, enable the inputs and show the borders
You'll probably need hidden elements for each field
When user submits the form, post via ajax and set the inputs back to disabled with hidden borders
What about contenteditable?
Demo: http://jsfiddle.net/SO_AMK/XQekC/
jQuery:
var ctrlDown = false;
$(document).keydown(function(e) {
if (e.which = "ctrlKey") {
ctrlDown = true;
}
}).keyup(function(e) {
if (e.which = "ctrlKey") {
ctrlDown = false;
}
});
$('#example').dataTable();
$("#example tr").click(function() {
if ($(this).hasClass("row_selected") && ctrlDown) {
submitRow($(this));
return false; // Break out so the next if doesn't run
}
else if ($(this).hasClass("row_selected") && ctrlDown == false) {
return false; // Break out so the next if doesn't run
}
if ($(this).siblings(".row_selected").length && ctrlDown == false) {
$(this).siblings(".row_selected").each(function() {
submitRow($(this));
});
}
$(this).addClass("row_selected");
$(this).children("td").each(function() {
$(this).attr("contenteditable", true);
});
});
function submitRow(elm) {
var data = [];
$(elm).removeClass("row_selected").children("td").each(function() {
data.push($(this).text());
});
alert(data); // This will stop the keyup from firing, but you won't (I hope) really be using alerts
}
This has everything but a submit-to-server function, it's also completely inline and has support for selecting multiple rows.
The only bug is, when it shows the data alert the focus goes off of the main window so the keyup event never fires, since you probably won't be using alerts this shouldn't be an issue. To fix it in the fiddle, press and release ctrl after the alert closes before clicking a row.
I see couple of problems
Your no. Of columns in the table & the edit columns you show are different
You might not be having complete data to edit the row so you might need to do an Ajax call and get it
If you have complete data on then you don't need point 2, let's assume you have a function f called with the clicked tr as the parameter
function f(row)
{
var newRow = yourTable.insertRow(parseInt(row.rowIndex,10)+1);
//you can place the above or below the clicked row , or you can even make the row visible false And then show the new row
Var newCell = newRow.insertCell(0);
newCell.colspan = 6;//the count if columns in your table row
NewCell.innerHTML = " put your HTML content here";
}