get previous td element to manipulate in Ajax call - ajax

How would I go about grabbing the previous td element in a table in order to change it's text value inside an Ajax call?
This is what i have so far. I think I am grabbing the td element properly and placing it into the variable, however I cannot get an alert to pop up with the text on the td element I'm trying to alter and I can't actually change the text like I'm trying to do.
function ChangeStatus(id) {
var td = $(this).parent('td').prev();
$.ajax({
type: 'GET',
url: '#Url.Action("changeStatus","AgentTransmission")',
data: { id: id },
dataType: 'json',
success: function (data) {
td.empty();
td.html("Hold");
}
});
}
Edit
Here are the two td elements I'm working with. When the user clicks the Hold link w/the ChangeStatus() onclick event, I want to be able to change the text of the previous element from Waiting to Hold.
<td>
Waiting
</td>
<td>
Details
<span> | </span>
<a href="javascript:void(0)" onclick="ChangeStatus(17)" >Hold</a>
</td>
<td align=center id=17>
</td>

First, parent() only get the first parent, if the caller is deeper in the dom, you won't get it. You should use parents(), but i'd recommend using classes instead of tag names, something like this:
$(this).parents('td.myClass').prev();
You can also use:
console.log(myString);
instead of alerts, you can see the result in the console, using chrome or firebug in firefox
Hope it helps

Try getting the td like this:
var td = $(this).closest('td');

Related

Thymeleaf: Form submit on click of table row

I have a table with orders and order ids. I would like to click on a row to view the order details in another page. My code:
<form id="orderDetalsForm" th:action="#{/restaurant/orderdetails}"
method="POST" th:object="${order}">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th scope="col">Order Id</th>
<th scope="col">Order Details</th>
<th scope="col">Date</th>
<th scope="col">Amount</th>
</tr>
</thead>
<tbody>
<tr id="orderRow" th:each="order : ${orders}"
style="cursor: pointer"
th:onclick="'getOrderItems(\''+${order.orderId}+ '\');'">
<td scope="row" th:text="${order.orderId}"></td>
<td th:text="${order.orderDetais}"></td>
<td th:text="${order.orderDate}"></td>
<td th:text="${order.amount}"></td>
</tr>
<tr>
<td colspan="3">Total</td>
<td th:text="${grandTotal}"></td>
</tr>
</tbody>
</table>
</form>
I tried an ajax form submit:
<script>
function getOrderItems(orderId) {
var url = "/restaurant/orderdetails";
$.ajax({
url : url,
type : "post",
data : {
"orderId" : orderId
},
success : function(data) {
console.log(data);
},
error : function() {
console.log("There was an error");
}
});
}
</script>
In my controller I have this:
#PostMapping(value="/restaurant/orderdetails")
public ModelAndView orderDetails(#RequestParam String orderId){
List<Product> orderDetails = userService.getOrderDetails(orderId);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("orderDetails", orderDetails);
modelAndView.setViewName("restaurant/orderdetails");
return modelAndView;
}
While the ajax works, the page is not getting redirected to my orderdetails page.
You can't use AJAX to redirect to a page. AJAX is for getting data from the server that is then processed/displayed using JavaScript. You however basically want clicking on the row to behave like clicking a link or (since you are using a POST mapping) submitting a form.
First off, using POST makes this a bit more complicated. You should consider using a GET mapping, not only because it makes this problem easier, but also because a POST mapping isn't really appropriate here. POST is used to send data to the server, which you are not doing.
Another thing you should consider it that using a (pure) JavaScript solution to link the table row hinders accessibility. For example, users that can't/don't use a mouse (such as disabled people or search engines) won't be able to see or even use such a link. To solve this it is a good idea to add a proper link to the row. Then that link can used by "clicking" on it with the JavaScript of the click handler.
<tr th:each="order : ${orders}" onclick="orderRowClick(this)">
<td scope="row"><a th:href="#{/restaurant/orderdetails(orderId=${order.orderId})}" th:text="${order.orderId}"></a></td>
<td th:text="${order.orderDetais}"></td>
<td th:text="${order.orderDate}"></td>
<td th:text="${order.amount}"></td>
</tr>
<script>
// Look for a link in the row and click on it
function orderRowClick(row) {
row.querySelector("a").click();
}
</script>
Several more points:
IDs must be unique in HTML. By putting id="orderRow" on such a repeated row will result in invalid HTML.
You shouldn't be using on... attributes to assign event handlers. I'm just using it here or otherwise this answer will go too far.
Remove the <form> from around the table. It doesn't do anything.
If you do want to/have to use a POST mapping, then replace the link in the table row with a form with a hidden field containing the order ID and a submit button and in the JavaScript look for the form instead of the link and submit it: row.querySelector("form").submit();.
BTW there are several (possibly better) ways to do what you are trying. For example:
Forget the JavaScript and just put a link into every cell. With the right CSS the row/cells can be changed so that it looks like you are clicking on the row.
It seems like you are using Bootstrap, which has the "stretched link" feature. Unfortunately it's a bit tricky to get to work with table rows, but it's worth looking at.
What I've understand so far is that you want to redirect user to a new page when the user clicks on the button on the table, for that there're different approaches -
Issue with your approach -
Since you're using ajax it wont be redirecting user to a new page ( because thats exactly how a AJAX works, for more info on AJAX us this link - https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX ), unless you explicitly tells your ajax-code to redirect the user on a new page.
For that you can simply put your page redirection code to a on your ajax success, something like this -
<script>
//your code
$.ajax({
// your code
success : function(data) {
//page redirection code here
window.location.href = "your-base-URL/restaurant/orderdetails/orderId="+orderId;
},
error : function() {
console.log("There was an error");
}
});
}
</script>
PS - This is not efficient programming practice since you're technically making an extra call to your server un-necessarily.
Approach 2nd
Simply make your html table buttin a-href link , like this -
<html>
// your code
<a th:href="#{'/restaurant/orderdetails/orderId=' + ${order.orderId}}">Order details button </a>
//your rest of the code
</html>
Approach-3rd , You can alternatively use java-script function for page redirection as well, simply modify you ajax function , something like this -
function getOrderItems(orderId) {
//page redirection code here
window.location.href = "your-base-URL/restaurant/orderdetails/orderId="+orderId;
}

how to refresh only data in ajax?

here, when i m going to replace my div i want to refresh only data not whole html design at 7 line
function func_name(id_1,id_2)
{
$.ajax({
type :"GET",
url:''<?php echo site_url('controller/function');?>/'+id_1+'/'+id_2,<br />
success: function(data){
$('#right').html(data); // id where do you want to replace div
}
});
}
If you want to refresh data, you'll need to define some HTML document element identifiers and set them one by one.
For example, in the $.ajax success callback, instead of calling $('#right').html(data);, if your right container has 2 spans to show first and second name of some user, you would do this:
$("#right #name").text(data.name);
$("#right #secondName").text(data.name);
...and your HTML should look as follows:
<div id="right">
<span id="name"></span>
<span id="secondName"></span>
</div>

save ajax response to a element that was not on the DOM

I have some results on the page (firts 10), then with a "load more result" button, I send the "id" of the last report to a PHP page.
I'v read here that I have to use .on (because .live is depreciated) so click event on new elements added to the DOM (through AJAX) can work.
My question is ... can I display somehow the content that came through AJAX on a div that was not on the initial DOM ?
$("#jokesWrap").on('click', 'a.share', function(event) {
var joke_id = $(this).attr('name');
var msgbox = $("#success[name='" + joke_id + "']");
$("#post-to-wall[name='" + joke_id + "']").hide();
msgbox.html('<img src="includes/images/load.gif"> Loading...');
$.ajax(
{
type: "POST",
url: "includes/php/ajax.php",
data: "joke_id=" + joke_id,
success: function(msg)
{
if(msg == 'OK')
{
msgbox.html('<img src="includes/images/success.png" /> DONE!');
}
} // function(msg)
}); // ajax
event.preventDefault(); });
This is the HTML part:
<div id="jokesWrap">
<div class="joke" id="1">
<p class="txt">
some text
</p>
<div class="joke-options-bar">
Post to wall
<span id="success" name="1" class="share floatL"></span>
<br class="floatClear" />
</div>
</div>
// the above area comes through loop from the ajax call
PS: Everything is ok: the ajax call (The tetxt is posted to the wall) the #post-to-wall is hidden. The "loding..." and the success message it's not shown.
PS2: the "Loading..." text and success message it's shown when I click on link that was on the DOM before the AJAX call ( because the #success was there)
Any help it's apprecied!
As long as the element exists in the DOM when the success callback of the AJAX is executed, you can use jQuery to select and manipulate it in the same way as you would an element that did exist in the DOM when the page was initially loaded. Or you can use jQuery to create the element as part of the success callback, manipulate it using the response from the AJAX request, then append your newly created element to the DOM in the required position. Something like so:
var div = $('<div/>').attr('id', 'new-div-id').html(data);
$('body').append(div);
That creates a new div, gives it an id of new-div-id, then sets its innerHTML to be whatever data was (assuming data is the name of the variable that contains the response text from the AJAX), then finally appends it as a new child of the <body> tag of the page.
Looking at what seem to be edits to the question: Element IDs (specified with the id attribute) have to be unique throughout the entire document; that includes elements added later as part of an AJAX callback. You can't have multiple elements with an id of success - make them unique by doing away with the name attribute, and adding the value to the end of the id instead, so you'd have success1, success2, etc as your IDs.
Add it to the DOM before writing to it?

Create google suggest effect with asp.net mvc and jquery

What I want to achieve, is not the autocomplete effect. What I want to achieve is that when you type on google the search results come up almost inmediately without cliking on a search button.
I already did the ajax example with a search button, but I would like it to make it work while you type it shows the results in a table.
The problem is I have no idea where to start.
EDIT: To ask it in another way.
Lets suppose I have a grid with 1000 names. The grid is already present on the page.
I have a textbox, that when typing must filter that grid using AJAX, no search button needed.
Thanks
Use a PartialView and jQuery.ajax.
$(document).ready(function () {
$("#INPUTID").bind("keypress", function () {
if($(this).val().length > 2) {
$.ajax({
url: "URL TO CONTROLLER ACTION",
type: "POST|GET",
data: {query: $("#INPUTID").val(),
success: function (data, responseStatus, jQXHR)
{
$("#WRAPPERDIVID").html(data);
}
});
}
});
});
Then in your view:
<div>
<input type="text" id="INPUTID" />
</div>
<div id="WRAPPERDIVID"></div>
Edit
Also, you could build in some sort of timer solution that submits the request after say 1 second of no typing, so you don't get a request on every key press event.
Theres a good example you can check here try to type 's' in the search
if thats what you want
then the code and the tutorial is here
another good example here
If you are working on "filtering" a set already located on the page, then you seem to want to set the visibility of the items in the list, based upon the search criteria.
If so, then first, you need to first establish your HTML for each item. You can use the following for each item:
<div class="grid">
<div class="item"><input type="text" value="{name goes here}" readonly="readonly" /></div>
{ 999 other rows }
</div>
Then, you must use some jquery to set each row visible/invisible based on the search criteria:
$("#searchBox").live("change", function () {
$("div[class='grid'] input").each(function () {
var search = $("#searchBox").val();
if ($(this).val().toString().indexOf(search) != -1)
$(this).parent().show();
else
$(this).parent().hide();
});
});
This will cause the visibility of each item to change, depending on whether or not the text in the search box matches any text in the item.

html() does not retrieve the whole content

I am getting the following response
<div id="weblogs">
<tr>
<td nowrap class="bl">1</td>
</tr>
<tr>
<td nowrap class="bl">2</td>
</tr>
</div>
Now I am trying to attach the rows like the following:
function _ajax(postData)
{
loadUrl = "getweblogs.asp";
$.ajax( {
url : loadUrl, // your ajax file
type : 'post',
data : postData,
success : function( resp ) {
alert($("#weblogs" , resp).html());
$('#weblogs > tbody:last').append($("#weblogs" , resp).html());
}
});
return false;
}
The replace is working fine. My problem is, that the htmls elements from the response are removed. I'm getting only 1 and 2. instead of
<tr>
<td nowrap class="bl">1</td>
</tr>
<tr>
<td nowrap class="bl">2</td>
</tr>
I don't know what am I doing wrong. Could someone give me any clue?
Thank you!
Greetings
Magda
What you're trying to do is not so clear. Is there already an element with id="weblogs" in the page? If so, why does your response have an element with the same id (not a good idea), and if not, why are you trying to append an element's contents to itself like that (also, not a good idea)?
Why not just change the server-side to send the html required, without a wrapping div tag (which makes it invalid html anyway, another bad idea), and then use it as-is?
Another problem is that you're trying to select .html() of something that will always be an empty jquery object: $(selector, string) will never match anything. You'll need to make the string a jquery object if you want to search its substructure: string = $(string).
And I think you're misunderstanding the use of $(selector, $obj). The selector must be in the $obj's sub-structure:
$('#foo', $('<div id="foo"><span/></div>')); // returns empty jquery object
So looking for #weblogs in the substructure of an element with id weblogs will also never find anything.
Your question isn't entirely clear, but I'll try and answer: are you working with Internet Explorer? If so, consider this paragraph from the docs:
For example, Internet Explorer sometimes leaves off the quotes around attribute values if they contain only alphanumeric characters.
API docs: html()

Resources