I have angularjs table added with check boxes to each row and a common remove button outside the table, so that multiple rows can be selected and deleted at a time. When rows are selected and remove is clicked, that particular rows will be deleted. This is fine and till here its working in the below plunker too. Now what I need is when a particular row is selected, its rowid has to be sent as a parameter to another URL. when this URL(URL formed by selected rowIds) with ids is called, automatically the rows will be deleted from first URL data, and now the table has to be updated from first URL. null will be returned from second url with ids as parameters and at the same time that rows will be deleted from JSON data of first URL.
Here is a demo:http://plnkr.co/edit/UzKdIGSubEfHoF7FHoCd?p=preview
Below is the code for the table:
<div ng-controller="SampleController">
<form class="form-horizontal">
<a class="btn btn-info" ng-click="subt_click()">Submit</a>
</form>
<div class="table-responsive" ng-show="tableData.length > 0">
<table class="table table-striped table-bordered table-hover dataTables-example">
<thead>
<tr>
<th><input name="all" type="checkbox" ng-click="selectAllFriends()" /></th>
<th>ID</th>
<th>Body</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in tableData">
<td><input name="all" type="checkbox" ng-model="x.checked" /></td>
<td>{{x.id}}</td>
<td>{{x.body}}</td>
</tr>
</tbody>
</table>
</div>
<input ng-hide="!tableData.length" type="button" class="btn btn-danger pull-left" ng-click="remove()" value="Remove">
app.js:
$scope.remove = function () {
var newDataList = [];
$scope.selectedAll = false;
angular.forEach($scope.tableData, function (checked) {
if (!checked.checked) {
newDataList.push(checked);
}
});
$scope.tableData = newDataList;
};
$scope.isAll = false;
$scope.selectAllFriends = function () {
if ($scope.isAll === false) {
angular.forEach($scope.tableData, function (x) {
x.checked = true;
});
$scope.isAll = true;
} else {
angular.forEach($scope.tableData, function (x) {
x.checked = false;
});
$scope.isAll = false;
}
};
In brief what i need is:
I get table data from first url. (pls check the plunk and the url i used is jsonplaceholder.typicode.com/posts)
When a checkbox is selected from a row in table and remove button is clicked, that rowid has to be sent to second URL(need to call another url, need not post) and this url when called along with selected rowids deletes that particular row details from first url and returns a null.
Finally, the first url data(which will be modified by just calling second url with rowids) has to be updated in the table present already.
How can I change this code to send rowid to second url and call that url to update the table. Thanks in advance!!
$scope.xListNo is never affected in your statements.
May be you wanted to use xListNo which is your function parameter (without $scope) ?
So does index in your second statement, which should be idx.
Double check your variables spelling and it should work !
#Deborah : Went through your Plunker and could not find any code for Posting ids to an URL. Assuming that you are doing that somewhere, Still there can be two cases, whether to remove data as soon as call is made or removing it after response from API call. The better way would be removing after the success of API.
So, what you should do probably is to keep your entire table data in a variable (as you have already done, after your GET call).
//Table Data
$http.get("http://jsonplaceholder.typicode.com/posts")
.success( function(response) {
$scope.tableData = response;
});
Now In remove function you can create an array of rows which are checked and send them to URL..Like:
$scope.remove = function(){
$scope.deletedIds = [];
$scope.tableData.forEach(function(x){
if(x.checked){
$scope.deletedIds.push(x)
}
}
makePostCallFOrDeletion()
}
//use this if POST call
function makePostCallFOrDeletion(){
$http.post("deleteurl", angular.toJson($scope.deleteIds)).then(function(response){
$scope.tableData = response //assuming you get the updated JSON back.
//if you don't get JSON back, delete yourself from JSON, like
$scope.tableData.forEach(function(x,i){
if ($scope.deleteIds.indexOf(x.id) !== -1)
$scope.tableData.splice(i, 1);
}
}
As per my understanding of your question, this should get you going..
EDIT: OP wanted GET call for deleting (which as per my opinion is not a good idea, since number of IDs can be too large)
//use this if GET call
function makePostCallFOrDeletion(){
$http.get("deleteurl" + append IDs here,).then(function(response){
//$scope.tableData = response //assuming you get the updated JSON back.
//if you don't get JSON back, delete yourself from JSON, like
$scope.tableData.forEach(function(x,i){
if ($scope.deleteIds.indexOf(x.id) !== -1)
$scope.tableData.splice(i, 1);
}
}
Related
I have a rest call in my application (spring based) to update the User's Active (boolean) status using Fetch API like below:
async function activateUser(obj) {
var fullURL = obj.getAttribute("href");
let response = await fetch(fullURL, {
method: 'POST'
});
let result = await response.json();
if (response.ok) {
alert(result.username + " Activated Successfully.. !!");
obj.parentElement.parentElement.cells[6].innerHTML = "true";
//getAllUsersApi(endpoint);
} else {
alert(response.status + "Error Occurred.. !!");
}
}
All works well.
Now, I am trying to update just that cell of my html table to true whose Initial value was false. I am updating the html table's cell by hard-coding the column number using (as you can see above too) - obj.parentElement.parentElement.cells[6].innerHTML = "true";. I was wondering if there is some way we can find the false in that row for that particular user and update that cell only. Prior to this I was reloading the entire table (the commented line in the JS code above), which nobody will prefer. I tried to find the solution here and here. But couldn't find the stating point for my situation.
From my rest call I am returning the User object so I was just wondering if I could search the table (on client side) just for that particular user and update that just one corresponding cell. In the table Id, Username and email are unique if that helps to find and replace false to true..
Summarized question: How can I update just one cell of my html table by utilizing the response from my REST call?
Since each ID is unique, you can add that to each row as an id="user id goes here" attribute. Then each cell can be given a class to specify it's purpose.
For example:
<table>
<tr id="user_{{ user ID }}">
<td class="user-name">{{ user name }}</td>
<td class="user-email">{{ user email address }}</td>
<td class="is-user-active">{{ user active status }}</td>
</tr>
</table>
Since the result is returning the username, I am guessing it can also return the ID, in which case your code would look like this:
if (response.ok) {
let isUserActive = document.querySelector(`#user_${result.id} .is-user-active`);
isUserActive.innerHTML = "true"
}
There is not really much magic to do. Instead of targetting cell 6, you would check find out the column number by finding the column header that has the title "Enabled". Replace this:
obj.parentElement.parentElement.cells[6].innerHTML = "true";
With:
let row = obj.closest("tr");
let titles = row.closest("table").querySelectorAll("th");
for (let cellNo = 0; cellNo < titles.length; cellNo++) {
if (titles[cellNo].textContent.includes("Enabled")) {
row.cells[cellNo].textContent = "true";
}
}
This is based on the information you have given in the question (not behind links) and in comments/chat.
My problem is the following:
I have created an array from a table I already have and stored the column I want into an array, and then stored it in the localStorage using JSON.stringify:
function createArray(){
var arrayPlayerName = [];
var count = 1;
while(count<=playerNum){
arrayPlayerName.push(document.getElementById('playertable').rows[count].cells[1].innerHTML);
count++;
}
localStorage.setItem("playerNameArray", JSON.stringify("arrayPlayerName"));
}
(playerNum is a variable with a fixed number used in other methods, and the "getElementById" works).
After that I want to show this data in another table in another HTML doc.
So, the following is my HTML code:
<table class="myTable">
<thead>
<tr class="row">
<th colspan="3">Array List</th>
</tr>
</thead>
</table>
And this is the script:
var storedPlayerArray = JSON.parse(localStorage.getItem("playerNameArray"));
tablegenerate (storedPlayerArray);
function tablegenerate (list) {
for(i=0; i<playerNum;i++){
var $formrow = '<tr><td>'+list[i]+'</td></tr>';
$('.myTable').append($formrow);
}
}
I am not sure what I'm doing wrong.. thanks in advance.
EDIT: I am calling the createArray function with a button, and I'm navigating to the second page with another button. The second page should load directly.
EDIT2: I have revised that the array is being stored and called properly on the second page, so the issue is now on the "tablegenerate" function.
EDIT
I think I found the problem try this:
var storedPlayerArray = JSON.parse(localStorage.getItem("playerNameArray"));
function tablegenerate (list) {
for(var i=0; i<list.length;i++){
var $formrow = $('<tr><td>'+list[i]+'</td></tr>');
$('.myTable').append($formrow);
}
}
$(document).ready(function(){
tablegenerate (storedPlayerArray);
})
You have an issue in your createArray function.. You are running JSON.stringify on a string instead of the array you want to store.
Change this:
localStorage.setItem("playerNameArray", JSON.stringify("arrayPlayerName"));
To this:
localStorage.setItem("playerNameArray", JSON.stringify(arrayPlayerName));
In my Struts2 application, I have a table that is dynamically populated with data, coming from the database (via Eclipselink JPA). Below that table there's a button that became enabled as soon as a row is selected in the table (jQuery). Now, when that button is clicked, I need to know which row is currently selected, so I can access the corresponding object bean, since I need to pass the bean ID (target_id) into the next page (createexperiment2 action). So, in short, the question is: How can I access the Struts2 object bean that is contained in the selected (clicked) table row?
1. Screenshots:
Before row selection -> After row selection
2. JSP code:
<table id="targets" class="ink-table grey tableSection">
<thead>
<tr>
<th colspan="5" class="align-left">Select your target:</th>
</tr>
</thead>
<tbody>
<s:if test="targets.size > 0">
<s:iterator value="targets">
<tr id="row_<s:property value="i"/>">
<td class="all-100"><s:param name="id"><s:property value="target_id"/></s:param></s:url>"><s:property value="name"/></td>
<td class="all-15"><s:param name="id"><s:property value="target_id"/></s:param></s:url>">edit</td>
<td class="all-5">|</td>
<td class="all-15"><s:param name="id"><s:property value="target_id"/></s:param></s:url>">delete</td>
<td class="all-5">?</td>
</tr>
</s:iterator>
</s:if>
</tbody>
</table>
[...]
<a href="createexperiment2" class="ink-button double-vertical-space all-25 buttonSection" id="next" disabled>Next ></a>
3. jQuery code:
$(document).ready(function(){
$('.tableSection tbody tr').click(function()
{
var selected = $(this).hasClass("highlight");
$('.tableSection tbody tr').removeClass("highlight");
$('.buttonSection').attr("disabled", false);
if(!selected)
$(this).addClass("highlight");
});
});
EDIT 1:
With the help of Andrea, I've finally been able to access Struts2 functions with jQuery, the poblem is that I can only access the properties of the last bean on the table (the last one that was accessed when the JSP was rendered, which makes sense). See the updated code below, while I'll try a workaround for this:
JSP:
<s:if test="targets.size > 0">
<s:iterator value="targets">
<tr onclick="<s:set var="tid" value="target_id"/>">
[...]
</tr>
</s:iterator>
</s:if>
[...]
<script type="text/javascript">
$(function () {
$('.tableSection tbody tr').click(function(event) {
alert ('<s:property value="%{#tid}" />');
});
});
</script>
EDIT 2:
Now I know which table row index has been clicked, but after hours of trying to assign it to a variable (using Struts tags) and send it to the action, I'm still not getting what I want. I'm not even being able to send this row index to the Action. This is frustrating. Nevertheless, that's how I got to know which row has been selected:
<tr onclick="getRow(this)">
[...]
<script>
function getRow(x)
{
alert("Selected row: "+x.rowIndex);
//return x.rowIndex;
}
</script>
EDIT 3:
This time, I was finally able to send the row ID (a String), to the action. The only remaining issue is that the action gets call twice, the first one on the click event, and the other one because of the href attribute of the a HTML element, which redirects to the desired Struts2 action. Apart of being obviously inneficient, this naturally makes the variable become null on the second call to the action. Do you know how can I somehwow "merge" this 2 calls to the createxperiment2 action into only one? I've tried with the async option in the AJAX call set to false, with no success.
[first, removed the onclick event from the table tr, since I only need to know which row is highlighted when the "Next" button is pressed]. The code currently goes like this:
<script type="text/javascript">
$('#next').click(function(event)
{
var row = $('.highlight').index();
alert (row);
$.ajax({
method: "POST",
url: "createexperiment2.action",
data: { row : row }
});
});
</script>
Q: I have assigned an ID to each table row. How can I know which one is the selected one?
Obtain the object's id with the this keyword:
$('.tableSection tbody tr').click(function(event) {
alert (this.id);
...
Q: how can I use the selected table row ID to access the corresponding bean object (represented in the row itself)?
This is not clear: just submit your id and retrieve the object serverside, no matter if through AJAX or a standard form submit.
Finally, the solution:
First get the ID of the object (I made it with Struts). Then, with the help of an AJAX call, send the ID to the desired action (url: attribute). Upon success of this action, define with the success: callback option where you want to redirect it.
Struts / JSP:
<s:if test="targets.size > 0">
<s:iterator value="targets">
<tr id="<s:property value="target_id"/>" class="highlight">
[...]
</tr>
</s:iterator>
</s:if>
jQuery:
<script type="text/javascript">
$('#next').click(function(event)
{
var tid = $('.highlight').attr("id");
$.ajax({
method: "POST",
url: "createexperiment2.action",
data: { tid : tid },
success:
function()
{
//alert("TID -> "+tid);
window.location = "loadworkloads.action";
}
});
});
</script>
I've got a table with a load of auto complete boxes in it which look like so...
<richui:autoComplete style="width:500px" name="objSelect[${newRow-1}].id" value= "" action="${createLinkTo('dir': 'object/searchAJAX')}" forceSelection = "true" maxResultsDisplayed="20" minQueryLength ="3" onItemSelect="updateHiddenInput(id,${newRow-1})" />
I've got it to call a function called updateHiddenInput when a user selects a value passing in the id selected as well as the row the autocomplete is on (this function then updates a hidden field in the same row, using the values passed in, with the ID). The function looks like so: -
function updateHiddenInput(id, num){
var objID = "objectID[" + num + "].id";
$(document.getElementById(objID)).val(id);
}
Everything works until I add a new row within my table, this pushes everything down one row and stops the autocomplete from updating the right rows hidden field (as its still referencing the old row).
Currently I have another piece of code that goes through and renames all the fields when a new row is inserted, but I have no idea how to update the autocomplete so that it passes through the right row number, anyone know how I can alter this?
The only other alternative I could think of would be to just pass through the object itself as well as the ID I can then locate the hidden based off the object, but I can't work out how to do this, any suggestions gratefully received! :S
I've tried changing
onItemSelect="updateHiddenInput(id,${newRow-1})"
to
onItemSelect="updateHiddenInput(id,this)"
Theoretically so I can just pass through the autocomplete object and from there just traverse the page to find the hidden field I want to update. However when I then attempt to use that object in my function, for example with something like: -
var mynumber = $(myobject).closest('td').find('input').val();
I always get an "undefined" returned when I try to alert back the value...
If I just put in an alert(myobject) in the function it returns AutoComplete instance0 autoLook[0].id but if I've inserted new lines the id value doesn't change (i.e the objects id is now autoLook[3].id but it still shows [0], which I think could be part of the problem but I've got now idea how I can update this value...
I notice when looking in firebug at the html there is a /script linked to the autocomplete which could be the problem as this doesn't get updated when new lines are added and I can see multiple references to the old/original id value (see below) so maybe the passing through of this isn't passing the current objects values through...?
<script type="text/javascript">
var autoCompleteDataSource = new YAHOO.util.XHRDataSource("/Framework/object/searchAJAX");
autoCompleteDataSource.responseType = YAHOO.util.XHRDataSource.TYPE_XML;
autoCompleteDataSource.responseSchema = {
resultNode : "result",
fields : [
{ key: "name" },
{ key: "id" }
]
};
;
autoComplete = new YAHOO.widget.AutoComplete('autoLook[0].id','ad186a42e45d14d5cde8281514f877e42', autoCompleteDataSource);
autoComplete.queryDelay = 0;
autoComplete.prehighlightClassName = 'yui-ac-prehighlight';
autoComplete.useShadow = false;
autoComplete.minQueryLength = 3;
autoComplete.typeAhead = false;
autoComplete.forceSelection = true;
autoComplete.maxResultsDisplayed = 20;
autoComplete.shadow = false;
var itemSelectHandler = function(sType, args) {
var autoCompleteInstance = args[0];
var selectedItem = args[1];
var data = args[2];
var id = data[1];
updateHiddenInput(id,this) };
autoComplete.itemSelectEvent.subscribe(itemSelectHandler);
</script>
My thanks so far to user1690588 for all his help thus far! :)
On further digging I'm convinced that my issues is down to the line autoComplete = new YAHOO.widget.AutoComplete('autoLook[0].id','a5b57b386a2d1c283068b796834050186', autoCompleteDataSource); specifically the part where its inputting autoLook[].id and if I could change this I'd then be ok, but this line is auto generated and I've got no idea how to update it, anyone have any similar experience?
I have not much idea about your gsp page but I tried it on my side:
My gsp:
<!DOCTYPE html>
<html>
<head>
<resource:autoComplete skin="default"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
var counter = ${list.size()};
function asd() {
jQuery.ajax({
url: " ${createLink(controller: 'oauthCallBack', action: 'testAuto')}",
data: "idx=" + counter++,
success: function (data) {
jQuery("#tableId").append("<tr><td>" + data + "</td></tr>");
}
});
}
function updateHiddenInput(id, tg) {
jQuery(tg).val(id);
}
</script>
</head>
<body>
<g:form>
<table id="tableId">
<g:each in="${list}" var="vr" status="idx">
<tr>
<td>
<richui:autoComplete name="name" id="uniqueId${idx}" action="${createLinkTo('dir': 'oauthCallBack/test')}" onItemSelect="updateHiddenInput(id, someId${idx})"/>
<g:hiddenField name="someName" id="someId${idx}" value=""/>
</td>
</tr>
</g:each>
</table>
</g:form>
<button onclick="asd()">Add</button>
</body>
</html>
My action:
def testAuto() {
render template: 'addNew', model: [idx: params.idx]
}
My template(addNew):
<richui:autoComplete name="name" id="uniqueId${idx}" action="${createLinkTo('dir': 'oauthCallBack/test')}"
onItemSelect="updateHiddenInput(id, someId${idx})"/>
<g:hiddenField name="someName" id="someId${idx}" value=""/>
Try this..,.
EDIT.....................................................................................
I supposed that you have successfully updated all the input field names. Then you can edit hidden field like:
View:
<tr class="dummyClass">
<td>
<richui:autoComplete name="name[${idx}]" id="uniqueId[${idx}]" action="${createLinkTo('dir': 'oauthCallBack/test')}" onItemSelect="updateHiddenInput(id, this)"/>
<g:hiddenField name="someName[${idx}]" id="someId[${idx}]" value=""/>
</td>
</tr>
jQuery:
function updateHiddenInput(id, tg) {
jQuery(tg._elTextbox).closest("tr.dummyClass").find("input[type=hidden]").val(id);
}
EDIT.....................................................................................
Why you need to change the 'id'? Changing name is sufficient to send values in order. And you can update the hidden field without id as above edit.
If you still need to change the id then you can change it by cloning the tr and then use regex. See this answer for full working example.
I have the following table that uses Javascript to calculate the sum of cells. When the inputs are entered Javascript the sums up the total of quantity and displays it in TD id="totalSum".
Ultimately I need to have it where when the totalSum equals 100, then execute php code.
How do I get PHP to read the data in the totalSum and then execute PHP when it equals 100?
HTML-
<table id="mytable" width="394">
<colgroup>
<col style="width: 50px;">
<col>
<col style="width: 60px;">
<col style="width: 110px;">
</colgroup>
<tbody>
<tr>
<th width="130" height="43"></th>
<th width="52">Weight Select</th>
<th width="181">New P</th>
</tr>
<tr>
<td align="center" width="130"> </td>
<td align="center">
<input type="text" size="2" value="1" id="qty_item_1" name="sum" >
</td>
<td align="center" id="total_item_1"></td>
</tr>
<tr>
<td align="center" width="130"></td>
<td align="center" >
<input type="text" size="2" value="1" id="qty_item_2" name="sum" >
</td>
<td align="center" id="total_item_2"></td>
</tr>
<tr class="tr">
<td align="left" colspan="1"><strong>Grand Total:</strong></td>
<td width="11" align="left" id="totalSum"></td>
</tr>
</tbody>
</table>
Javascript-
<script type="text/javascript">
var bIsFirebugReady = (!!window.console && !!window.console.log);
$(document).ready(function (){
// update the plug-in version
$("#idPluginVersion").text($.Calculation.version);
/*
$.Calculation.setDefaults({
onParseError: function(){
this.css("backgroundColor", "#cc0000")
}
, onParseClear: function (){
this.css("backgroundColor", "");
}
});
*/
// bind the recalc function to the quantity fields
$("input[id^=qty_item_]").bind("keyup", recalc);
// run the calculation function now
recalc();
// automatically update the "#totalSum" field every time
// the values are changes via the keyup event
$("input[name^=sum]").sum("keyup", "#totalSum");
// automatically update the "#totalAvg" field every time
// the values are changes via the keyup event
$("input[name^=avg]").avg({
bind:"keyup"
, selector: "#totalAvg"
// if an invalid character is found, change the background color
, onParseError: function(){
this.css("backgroundColor", "#cc0000")
}
// if the error has been cleared, reset the bgcolor
, onParseClear: function (){
this.css("backgroundColor", "");
}
});
// automatically update the "#minNumber" field every time
// the values are changes via the keyup event
$("input[name^=min]").min("keyup", "#numberMin");
// automatically update the "#minNumber" field every time
// the values are changes via the keyup event
$("input[name^=max]").max("keyup", {
selector: "#numberMax"
, oncalc: function (value, options){
// you can use this to format the value
$(options.selector).val(value);
}
});
// this calculates the sum for some text nodes
$("#idTotalTextSum").click(function() {
// get the sum of the elements
var sum = $(".textSum").sum();
// update the total
$("#totalTextSum").text("$" + sum.toString());
});
// this calculates the average for some text nodes
$("#idTotalTextAvg").click(function() {
// get the average of the elements
var avg = $(".textAvg").avg();
// update the total
$("#totalTextAvg").text(avg.toString());
});
});
function recalc(){
$("[id^=total_item]").calc(
// the equation to use for the calculation
"qty * price / 100",
// define the variables used in the equation, these can be a jQuery object
{
qty: $("input[id^=qty_item_]"),
price: $("[id^=price_item_]")
},
// define the formatting callback, the results of the calculation are passed to this function
function (s){
// return the number as a dollar amount
return "" + s.toFixed(2);
},
// define the finish callback, this runs after the calculation has been complete
function ($this){
// sum the total of the $("[id^=total_item]") selector
var sum = $this.sum();
$("#grandTotal").text(
// round the results to 2 digits
"" + sum.toFixed(2)
);
}
);
}
</script>
Your question does not show how you trigger summing up the values, or checking the value of cell id="totalSum", so in my solution I added a button id="mybutt" to do that.
Working jsFiddle here
All you need to know is in the above jsFiddle, and in the section below discussing the some_php_file.php. What follows now is a description of how the code works, if you need that.
First, we get the collection of all table cells where the id starts with qty_item:
$('[id^=qty_item_]')
Next, we iterate through this collection using the .each method:
var ttl = 0;
$('[id^=qty_item_]').each(function() {
str = $(this).val();
ttl += Number(str);
});
Then, inject the total into the cell with id="totalSum"
$('#totalSum').text(ttl).trigger('change');
Note that we trigger a change event on that same element (table cell). That immediately fires this code:
$('#totalSum').change(function() {
var sum = $(this).text();
alert('Value: ' + sum);
if (Number(sum) > 99) {
alert('Value > 100. AJAX will begin, but cannot finish because jsFiddle cannot do ajax. Just look at syntax.').
$.ajax({
type: "POST",
url: "some_php_file.php",
data: 'myTotalSum='+sum,
success:function(somedata){
alert(somedata);
}
});
}
});
In the AJAX code block, notice the URL that is specified. A PHP file with the same name must exist on the server (in same folder as your HTML code, for this example). It will receive the info sent via AJAX in a POST variable called myTotalSum.
Once you have that number, your PHP file can stick it into the database. If you want, you can even have the PHP file send information back to the webpage (it arrives in the success function of the AJAX code block). Note that the javascript on the webpage continues processing without waiting for the PHP page to finish. If you need the javascript to wait, then you would insert async: false, somewhere near the top of that code block.
To see this actually work, create a text file with this name and these contents:
some_php_file.php
<?php
$theSum = $_POST['myTotalSum'];
$r = '<h2>Mr. PHP received this number:</h2><h1>' .$theSum. '</h1>';
echo $r;
The echo in the PHP file sends the contents of variable $r back to the AJAX code block, where it is received in the success function. Important: this incoming data must be dealt with here, and no where else. It will not exist outside the success function.
To access received data outside the success function, stick the received data into an element, such as a hidden input element, like this:
success:function(mydata){
$('#a_hidden_input_element').val(mydata);
}
Here is an SO post with some additional AJAX code examples.