I need to get a variable between jQuery function and AJAX - javascript

I have two buttons on the form I'm getting, this first piece of coce allow me to know which was the button clicked by getting the id of it.
var button;
var form = $('.register_ajax');
$('#vote_up, #vote_down').on("click",function(e) {
e.preventDefault();
button = $(this).attr("id");
});
and this other send the form data through AJAX using the info already obtained from the button using the script above.
form.bind('submit',function () {
$.ajax({
url: form.attr('action'),
type: form.attr('method'),
cache: false,
dataType: 'json',
data: form.serialize() + '&' + encodeURI(button.attr('name')) + '=' + encodeURI(button.attr('value')) ,
beforeSend: function() {
//$("#validation-errors").hide().empty();
},
success: function(data) {
if(data.message == 0){
$("#fave").attr('src','interactions/favorite.png');
$("#favorite").attr('value',1);
console.log(data.errors);
}
if(data.message == 1)
{
$("#fave").attr('src','interactions/favorite_active.png');
$("#favorite").attr('value',0);
}
if(data.message == "plus")
{
$("#vote_up").attr('class','options options-hover');
$("#vote_down").attr('class','options');
console.log(data.message);
}
if(data.message == "sub")
{
$("#vote_down").attr('class','options options-hover');
$("#vote_up").attr('class','options');
console.log("sub");
}
},
error: function(xhr, textStatus, thrownError) {
console.log(data.message);
}
});
return false;
});
The problem is that the data is not being passed to the ajax function, the button info is being saved on the button var, but it's not being obtained at time on the ajax call to work with it (or at least that is what I think). I'd like to know what can I do to make this work, any help appreciated.
1st edit: If I get the button data directly like button = $('#vote_up'); it doesn't work either, it only works if I get the button directly like this but without using the function.
2nd edit: I found the solution, I posted below.

var button is in the scope of the .on('event', function(){})
You need to declare the variable in the shared scope, then you can modify the value inside the event callback, i.e.
var button,
form = $('.register_ajax');
$('#vote_up, #vote_down').on("click",function(e) {
e.preventDefault();
button = $(this).attr("id");
});

You are being victim of a clousure. Just as adam_bear said you need to declare the variable outside of the function where you are setting it, but you are going to keep hitting these kind of walls constantly unless you dedicate some hours to learn the Good Parts :D, javascript is full of these type of things, here is a good book for you and you can also learn more from the author at http://www.crockford.com/.

I Found the solution, I just changed a little bit the click function like this:
var button;
var form = $('.register_ajax');
var data = form.serializeArray();
$('#vote_up, #vote_down').on("click",function(e) {
e.preventDefault();
button = $(this).attr("id");
data.push({name: encodeURI($(this).attr('name')), value: encodeURI($(this).attr('value'))});
form.submit();
});
using e.preventDefault(); and form.submit(); to send the form. also I changed the data.serialize to serializeArray(); because it's more effective to push data into the serializeArray(). in the second script I just changed the data.serialize() and used the data variable that I already filled with the serializeArray() and the data.push():
form.bind('submit',function () {
alert(button);
$.ajax({
url: form.attr('action'),
type: form.attr('method'),
cache: false,
dataType: 'json',
data: data,
//here goes the rest of the code
//...
});
return false;
});
it worked for me, it solved the problem between the click and submit event that wasn't allowing me to send the function through ajax.

Related

Ajax success and laravel

I'm currently working on a project using Laravel platform.
I'm trying to delete data from a model asynchronously using ajax. And when all is done my data should be removed from the table. My code runs perfectly, data are being removed from my database , yet "tr" elements arent really faded or removed. Here is my code :
ajax sucess not really working.
$(document).on('click', '.btn-remove-interview' , function() {
var id = $(this).attr('data-interview-id');
$.ajax({
url: './manage/interviews/destroy/'+id ,
type: 'post',
dataType: 'json',
data: id,
success: function (data) {
$(this).parents("tr").remove();
}
});
});
Use
$(this).closest('tr').remove();
Instead of
$(this).parents("tr").remove();
The problem is that the success function callback within your ajax request no long refers to the button when you use this. You need to get an explicit variable to the button if you want to use it.
$(document).on('click', '.btn-remove-interview' , function() {
// Get this button as a variable so we can use it later
var el = $(this);
var id = $(this).attr('data-interview-id');
$.ajax({
url: './manage/interviews/destroy/'+id ,
type: 'post',
dataType: 'json',
data: id,
success: function (data) {
$(el).parents("tr").remove();
}
});
});
Solution was by removing dataType json . My function doesnt return any data .

How to call ajax again when user click back button to go back last webpage?

Below is my code..
HTML Code
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="body">
<div class="dropdown_div">
<select id="q_type" class="dropdown" onchange="getSubject(this.value)">
<option>Question1</option>
<option>Question2</option>
</select>
</div>
<div class="dropdown_div">
<select id="q_subject" class="dropdown">
<option>Subject1</option>
</select>
</div>
</div>
JS Code
function getSubject(val){
$("option", $("#q_subject")).remove();
var option = "<option>Subject</option>";
$("#q_subject").append(option);
$.ajax({
url: "api.path",
type: 'POST',
dataType: 'json',
data: {id: id},
async: true,
cache: false,
success: function(response) {
alert("Hi");
$("option", $("#q_subject")).remove();
var option = "<option>Subject1</option>";
option += "<option value=1234>Subject2</option>";
$("#q_subject").append(option);
}
});
}
How do I use pushState into my code and let user can click back button to return last page and then still see the ajax data?
First of all, you should save data received from ajax request to browser local storage. Afterwards, in order to show ajax result when browser "back" button was fired, you should bind statements that you are calling in ajax.success() method to window onpopstate event. To omit code duplication, it`s better to use a declared function instead of anonymous one.
function success(response) {
alert("Hi");
$("option", $("#q_subject")).remove();
var option = "<option>Subject1</option>";
option += "<option value=1234>Subject2</option>";
$("#q_subject").append(option);
}
Save data to localstorage and call success function:
$.ajax({
url: "api.path",
type: 'POST',
dataType: 'json',
data: {id: id},
async: true,
cache: false,
success: function(response) {
localStorage.setItem("response", response);
success(response);
}
});
Call success() when "back" button was fired:
window.onpopstate = function (e) {
var res = localStorage.getItem('response');
success(res);
}
I would rather suggest you to use sessionStorage which expires when the browser window is closed :)
$.ajax({
url: "api.path",
type: 'POST',
dataType: 'json',
data: {id: id},
async: true,
cache: false,
success: function(response) {
sessionStorage.setItem("DataSaved", response);
success(response);
}
});
And then
window.onpopstate = function (e) {
var res = sessionStorage.getItem('DataSaved');
success(res);
}
You can solve this using the local Storage or Session storage. You will also need to have a onload function callback, to check if there are any previous values that you stored in the local/session storage, if yes, then show that data in the select box.
I noticed this Back() issue when using Ajax to navigate an MVC-5 application from within a JavaScript generated diagram. All clicks in the diagram are handled by Ajax.
Above solutions do not replace the complete body, in the repaired cases a Back() would restore just the edit fields. In my case, I don't need that. I need to replace the entire page from the AJAX and also enable the Back button to return to my original diagram context.
I tried above solution to replace body, and I have to note, it would only trigger the window.pop event after
history.pushState({}, '')
But when the event triggered and it uses Ajax to fill the body, my Javascript would not properly re-initialize the diagram page.
I decided to use another pattern, to circumvent the the window.pop event and avoid the back-issue. Below code will not return into the Ajax code context, but instead simply replace current page, processing the Ajax return information from the server (=Controller) as a redirect link, like
var url = "/ProcessDiagram/MenuClick?command=" + idmenuparent+"_"+citem; // my Ajax
$.get(url,
function (data) {
window.location = data; // Server returns a link, go for it !
return true; // Just return true after going to the link
});
.. this will preserve the Back() context, because the browser will take care of things.
Controller side composes the redirect link, like
public ActionResult MenuClick(string command)
{
List<string> sl = command.Split(new char[] {'_'}).ToList();
var prId = int.Parse(sl[0].Substring(3));
if (sl[1] == "PU")
return Content("/ProductionUnitTypes/Details/" + UnitContextId(prId) );
if (sl[1] == "IR")
return Content("/ItemRoles/Details/" + RoleContextId(prId) );
// etcetera
}
I solved it by including the below code just before the $.get() function
$.ajaxSetup({cache: false});
It works! Try it :)

How can I pass a variable to alert() with $.ajax?

I want to let the user confirm to deletion of a record by letting them click on the button and the button sends the value Yes to a $_POST request so I can delete the record with PHP, instead it's showing me the javascript file that contains the function.
What am I doing wrong, I've been tinkering and searching for 3 hours straight, while in the back of my mind I know it's a easy fix.
Any help is greatly appreciated.
If you think there is a smarter way to be doing this, please let me know.
$(function () {
$("#DeleteConfirm").dialog({
buttons: {
"Confirm": function() {
var DeleteConfirmation = "Yes";
$.ajax({
type: "POST",
url: "index.php",
data: DeleteConfirmation,
success: function(DeleteConfirmation){
alert(DeleteConfirmation);
},
dataType: "text"
});
},
"Cancel": function() {
$(this).dialog("close");
}
}
});
});
Javascript:
if( confirm('Are you sure?')){
/*proceed?*/
}
That is standard javascript. It wraps your AJAX call within the braces and if the user clicks 'yes' - the ajax call will execute. If he click 'no', then nothing happens. The confirm() prompt pops up an alert on screen with buttons. The resulted is captured by the if. You can also capture the result of that: var res=confirm('are you sure?');.
You need to assign the YES value to a property name:
data: { "confirmed": DeleteConfirmation},
Then in your PHP you can ready this using $_POST["confirmed"].
This does seem a little redundant however, as the user has already clicked the button to confirm the deletion, so there seems little value in sending the value in the POST request. Sending the id of the item to delete would make more sense.
Your ajax is misformed, try:
$.ajax({
type: "POST",
url: "index.php",
data: {answer: DeleteConfirmation }, //what you send to the php
success: function(data){ //answer from your php
alert(data);
},
dataType: "text"
});
},

How to pass form input field value to external page using jquery

I have a form where I would like to pass the value of an text input field to an external page without a form submit event. I would like to field value to become a php variable on the external page.
Here is what I have so far:
<script type="text/javascript">
jQuery(document).ready(function() {
$(function() {
cityField = $('#the_form input[id=city]');
$.ajax({
type: "POST",
url: "external.php",
data:{ city: cityfield },
success: function(data){
console.log(data);
}
});
});
});
</script>
Within the external.php page, I would like to declare the city form field value as a php variable as
$city = $_POST['city'];
To start with
jQuery(document).ready(function() {
and
$(function() {
are equivalent. The $(function() should be something like
$("input[type='button']").click(function() {
so that when you click the button, it runs the ajax request.
I cleaned up the code but the data is not being sent to external.php. It is being set but not posting. Here is my revised code
<script type="text/javascript">
$('#city').blur(function() {
var cityField = document.querySelector('#city').value;
$.ajax({
type: "post",
url: "external.php",
data: {'cityField': cityField },
dataType: "text",
success: function(data, status){
if(status=="success") {
alert("You typed: " + cityField);
}
}
});
});
I dont feel right posting an answer for a single change... But
EDIT: There are actually a few things...
<!-- For .click() -->
Click Me!
<script type="text/javascript">
// $(function() { // Trigger on page load
// $('#doStuff').click(function() { // Trigger on a click
$('#city').blur(function() { // Trigger when the focus on the field is lost (click away, tab to another field, ect)
// $('#city').change(function() { // Trigger when the fields value changes
var cityField = $('#city');
$.ajax({
type: "POST",
url: "external.php",
data:{ 'city': cityField.val() },
success: function(data){
console.log(data);
}
});
});
</script>
Changes:
You dont need jQuery(document).ready(function() {}) AND $(function(){ }). Its the same thing.
Its smart to put a var in front on your variables.
Case is important. cityField and cityfield are not the same thing
You were just sending the whole dom element to your external script. (which I assume you only wanted the contents of the input)
Also, you dont need to look for "an input, with an 'id' attribute , with a value of 'city'". Just look for #city
EDIT:
Your updated code (just putting it here so its easier to see):
<script type="text/javascript">
$('#city').blur(function() {
var cityField=$('#city').val();
$.ajax({
type:"post",
url:"autosuggest.php",
data:{'cityField':cityField },
dataType:"text",
complete:function(data, status) {
alert("You typed: "+cityField);
}
});
});
</script>
Your data will should be available in autosuggest.php as $_POST['cityField'];
Having a status check within the success function, is a little redundant, in my opinion.
It would be better to move the success:function(data,... to a complete:function(data,...

Why do I get undefined when displaying value in a global variable?

I just don't get it, obviously. I've tried setters and getters, self invoking functions, you name it. It's like the click handler is returning a value but there's no way for me to keep it?
This is my code in the first file request.js
var testId = (function (inId) {
var citeId = inId;
return citeId;
})();
function mainAjax() {
return $.ajax({
type: 'GET',
url: 'https://www.sciencebase.gov/catalog/items?parentId=504108e5e4b07a90c5ec62d4&max=60&offset=0&format=jsonp',
jsonpCallback: 'getSBJSON',
contentType: "application/json",
dataType: 'jsonp'
});
}
var promise = mainAjax();
this is the code in my second file requestMain.js,
promise.done(function (json) {
var linkBase = "http://www.sciencebase.gov/catalog/item/";
var link = "";
var itemId = "";
var urlId = "";
$.each(json.items, function(i,item) {
link = linkBase + this.id;
$('#sbItems').append('<li><b>' + this.title + ' - </b>' + this.summary + '</li>');
});
$('#sbItems a').on('click', function (e) {
e.preventDefault();
var str = $(this).attr('id');
if (str.length == 7) {
itemId = str.slice(5,6);
}
else if (str.length == 8) {
itemId = str.slice(5,7);
}
testId = json.items[itemId].id;
alert(testId);
}); // END Click event
}).fail(function() {
alert("Ajax call failed!");
});
This webpage displays a list of links. A link could have some more information that I want displayed on a second webpage or it could have nothing. So when a link is clicked I need to store/save/keep the id from the link so that I can use it in the url to make another ajax request, because until I get the id the ajax request for the next page will have no idea what information to ask for.
For now I'm simply doing this
alert(testId);
But what I'm trying to do is this,
$.ajax({
type: 'GET',
url: 'https://www.sciencebase.gov/catalog/itemLink/' + testId + '?format=jsonp',
jsonpCallback: 'getSBJSON',
contentType: "application/json",
dataType: 'jsonp',
// Then doing something with json.something
testId would be used in the url and it would change depending on the link that was clicked on the previous page. The ajax call is totally dependent on the click event and is displayed on a separate webpage with new information.
And this would be in my third file requestCitation.js which currently gives me a big undefined when doing
alert(testId);
I think this is a scope issue, but how can I store the value returned from a click??? So that I can then use it globally? It seems like the value disappears outside of the scope as if there was never a click at all even thought I'm storing it in a variable?
the html for the first page has script tags for request.js and requestMain.js and the second page has script tags for request.js and requestCitation.js, so they can both see the variable testId.
Thanks for the help!
Here's the jsfiddle
These are the links and when a link is clicked
Your testId is holding the value retuned by the function you're calling, and since the function returns its argument and you've called it without arguments, it will be undefined:
var testId = (function (inId) {
var citeId = inId;
return citeId; //returns the argument
})(); // called with no argument
I'm not entirely sure what you're trying to do but if you're trying to keep the data returned from the AJAX request as a global variable, I would have thought it was done using something similar to the below.
E.g.
var promise = '';
$.ajax({
type: 'GET',
url: 'https://www.sciencebase.gov/catalog/items?parentId=504108e5e4b07a90c5ec62d4&max=60&offset=0&format=jsonp',
jsonpCallback: 'getSBJSON',
contentType: "application/json",
dataType: 'jsonp'
data: '';
success: function(data){
promise = data;
}
});
But as I said I'm not understanding fully so I could be very wrong with my answer.

Categories

Resources