I'm new to jQuery and am struggling to figure out an issue that's plaguing me.
In my code, I am appending a new form after a DIV, and have set up a custom button for submission. I set up an on-click jQuery event, but am having trouble accessing one of the local variables successfully.
....
callbacks {
open function() {
this.wrap.on('click.pinhandler' .socialLink', function(e) {
var fileName = $(this).attr('fileName');
var eventName = $(this).attr('eventName');
var destination = "test#test.com";
$(".test-area").after('<input type="email" id="emailShare" placeholder="enter your email">
<div id="btnSubmit"><div id="btnLabel">GO</div>
<script>
$("#btnSubmitA").on("click",
function(event) {
destination=$("#emailShare").val();
console.log("About to send mail: " + destination);
$.ajax({
type: "GET",
url: "https://myURL/api.php?fileName=' +fileName+ '&eventName=' +eventName+ '&destination=' +destination+ '",
headers: { "Access-Control-Allow-Origin": "https://babelandphoto.com/babeconnect/getShortcode.php" },
cache: false,
success: function(data) {
console.log("Response:" + data["status"] + this.destination)
}
});
});
</script>');
});
}
}
...
This is all embedded in a callback from a Magnific Popup button, in which a user clicks a button within the popup and the above is triggered. In my code, I am setting the global destination variable with the code;
destination=$("#emailShare").val();
Just before my AJAX call, I am logging the state of destination, with successfully reports the proper user input of the #emailShare text field. I am logging like so;
console.log("About to send mail to " + destination)
Both before the call, and in the response, I am successfully logging the proper variable. But the actual variable being sent to the API is still the global variable, having never been updated.
I recognize this is complex, but I"m unsure if there's a better way...
For anyone that stumbles across this, #taplar's comment in the above question got me on the right path. Specifically, this Stackoverflow post, discussed how to bind to dynamically created elements.
By refactoring my code, I ended up using the following;
$(document).on('click', '.doSocial', function(){
//stuff happens here
});
In my case, .doSocial is a class applied to dynamically created buttons. Once the user clicks a .doSocial button, I use the //do stuff here section to add my additional dynamic HTML elements, including the form field which is now recognized by my AJAX function. If #taplar would like to answer, I'll happily mark it as correct.
Related
I have an HTML form that is trigged with AJAX to submit using a Rails backend. However, after submitting the first time, the form stops submitting. From reading other posts, I realize part of the problem is that the issue is related to including $(document) and not the form submit handler in the JQUERY call, but changing it to something like $('.new_todo form').submit will return the page as a JSON object instead of just the instantiated object {} response that I get with using $(document) in the Jquery.
I'm essentially trying to create an object and then to keep appending it to the index page, which works on the first submit, but as noted not on subsequent ones.
I'd really appreciate any insight because I've been staring at this for hours and while tons of answers address similar challenges (unbinding etc), nothing I found successfully addresses this use case.
The current AJAX call is:
$(document).on('submit', '.new_todo', (e) => {
e.preventDefault()
$.ajax({
type: "POST",
url: "/todos",
data: {
'authenticity_token': $("input[name='authenticity_token']").val(),
'todo': {
'name': $("#todo_name").val()
}
},
success: function(response) {
$("#todo_name").val("")
$("#todo_location").html("")
$("#todo_date").html("")
let newTodo = new Todo(response)
let todoHtml = newTodo.formatIndex()
$('.todo-list').append(todoHtml)
}
})
})
The controller action for my create is:
def create
#todo = Todo.new(todo_params)
#todo.save
render json: #todo
end
Thank you!!
I have the following program in which a user can enter any name in a search box after which I redirect the user to a page called usernameSearchResults.php where I print a list of the usernames obtained in the form of an array from usernamesearch.php. Here is the javascript:
$(window).on('load', function() {
$(".searchBarForm").submit(function(e){
e.preventDefault();
var search=document.getElementsByClassName("search")[0].value;
$.ajax
({
type: 'POST',
url: 'usernamesearch.php',
data:
{
search:search
},
success: function (response)
{
window.location.href="usernameSearchResults.php";
response = JSON.parse(response);
var array_length = Object.keys(response).length;//getting array length
for(var i=0;i<array_length;i++){
if(i==0){
document.getElementById("searchResults").innerHTML=""+response[0].username+"<br>";//i=0
}else{
document.getElementById("searchResults").innerHTML+=""+response[i].username+"<br>";
}
}
window.stop();//stops page from refreshing any further(put here to fix a bug that was occuring)
},
error: function(xhr, status, error) {
alert(xhr.responseText);
}
});
return false;
})
});
This is usernameSearchResults.php(inside tags):
<h1>Username Search Results</h1>
<p id="searchResults"></p>
But the problem is that whenever I go to any other page say index.php and enter the username to be searched, the page redirected to is indeed usernameSearchResults.php but the page is blank and error in the console shown says document.getElementById("searchResults") is null.But if I stay at the page usernameSearchResults.php and refresh it and then search any name again, then the results are correctly obtained. What is the problem here?
I would say that the user is being redirected to usernameSearchResults.php but the JavaScript code is still being executed from the current page, which have no element with id "searchResults" defined.
As #Kashkain said, one way to achieve what you want is to pass your response variable in your redirection url and process it then into your other page.
I think the problem here is that the new document could very well still not have been loaded when you call getElementById.
You could add a listener on your target element which would trigger on the load event. In this event's handler you could execute the operations that are now giving you an error.
I have never done or tried this, but maybe something like this would work:
$('#searchResults').on('load', function() {
//execute code here
});
Or you could add a form to the page with action="target_url" method="post" and send your response data through post by doing form.submit, and place the problematic code into usernameSearchResults.php, which will need to read data from POST - this way you can send your ajax data to the new page
I have taken some source code from here to submit a form using AJAX. The form is basically taking some information from a user and putting it into a database via PHP. The code I have works, but given that what I am working on has many forms all doing the same thing, I - obviously - want to make sure my code is lean and mean. So, making sure that each of my form field names have the same as my database with some matching IDs for various parts of the form for user feedback, have changed it to the following:
<script type="text/javascript">
$(document).ready(function() {
// process the form
$('#formId').submit(function(event) { // for the specified form:
// completeForm('#formId'); // WHERE I CALL THE FUNCTION
// FUNCTION STARTS HERE WHEN IT IS ONE
var formData = {}; formId = '#formId';
$(formId + ' input, ' + formId + ' select, ' + formId + ' textarea').each(
function(index){ // for each item (input, select, textarea in the specified form
var input = $(this);
// First, clear any existing formatting that has been added by previous form inputs
$('#' + input.attr('id') + '-group').removeClass('has-info has-error has-success bg-error bg-info bg-success');
// Next, add data to the array of data to pass to the PHP script
Array.prototype.push.call(formData, input.val());
}
); // End of loop through each item.
// Now the data is collected, call the requested PHP script via AJAX.
$.ajax({
type : 'POST', // define the type of HTTP verb we want to use (POST for our form)
url : $(this).attr('action'), // '/processing/general_settings_processing.php', // the url where we want to POST
data : formData, // our data object
dataType : 'html' // 'json' // what type of data do we expect back from the server
})
// using the done promise callback
.done(function(data) {
// log data to the console so we can see
console.log(data);
// Return success and error messages to the user
// Code to come once the basics have been sorted out!
});
// FUNCTION WOULD END HERE WHEN IT IS ONE.
event.preventDefault();
});
});
</script>
The code as above works absolutely fine; the relevant PHP file is called and - although I have no processing done in this particular file yet - does its stuff (I have it echoing the $_POST array to a file and returning to view in the console log atm).
However, when I try and make it a function, it doesn't - the console log simply echoes out the source code for this document instead of the PHP array that it supposed to be doing. The function is placed above the $(document).ready line; specified as function completeForm(formID) { . . . } , contains the section of code as noted in the comments and called in the commented out line as shown. So, logically (to me) it should work.
The ultimate idea is to have the function to do this in a file that can be called by all the forms that call it, while the code to call the function is in the relevant part of the page. Some pages will have more than one form using it. (I mention that should even if what I am doing here works, it wouldn't when I come to reuse the code!)
(I'm relatively new to JS and JQuery, although have a fairly good grasp of some programming techniques, mainly these days just in PHP.)
The issue you are having with making that a function is you forget to include the "thisBinding". As a result, when you tried to use the form's action target in your ajax call with this code:
url : $(this).attr('action')
it does not find an "action" attribute - basically the issue is that this is actually window and as a result there is no action attribute. Simply bind this to your function call and your code will work as written.
completeForm.call(this,'#formId');
.call MDN
I was wondering, we have this front-end delivered by a third party. They made the design implemented this in a PHP website (Symphony based, irrelevant to my issue I believe).
The problem is, they used a lot of Javascript, which is nice for the dynamic parts. However when submitting the form, the data is being transferred through jQuery $.ajax or post too. Meaning the client side will never store the user's input for future use, which is actually something they'll want since this front end is designed for re-use ever x weeks or per month.
Anyone know if there is a way to make the form behave like if it's being posted?
As addition, the user is NOT logged in, and there could be multiple users allthough it's likely it's his private system, or shared at home. High chance it'll even be a mobile device.
You need to use cookies to save the form data, preferably after the submit. I like to use jquery.cookie when working with stuff like this. I would do something like this. This will only work on a single browser.
$( document ).ready(function() {
// Fetch the submit_form_input cookie that was set after submitting the form
var submit_form_input = JSON.parse($.cookie("submit_form_input"));
// Loop through the values inside the cookie
for (i = 0; i < submit_form_input.length; i++) {
// Find the form with the correct id and set the value on it
$("#" + submit_form_input[i].name).val(submit_form_input[i].value);
}
$("#submit_form").submit(function(ev) {
ev.preventDefault();
var url = $(this).attr('action');
var data = JSON.stringify($(this).serializeArray());
$.ajax({
type: "POST",
url: url,
data: $(this).serialize(), // serializes the form's elements.
success: function(response)
{
// Set the cookie
$.cookie("submit_form_input", data);
alert('Thank you for submitting the form.');
}
});
});
});
Here is a JSFiddle.
Hey all. I was fortunate enough to have Paolo help me with a piece of jquery code that would show the end user an error message if data was saved or not saved to a database. I am looking at the code and my imagination is running wild because I am wondering if I could use just that one piece of code and import the selector type into it and then include that whole json script into my document. This would save me from having to include the json script into 10 different documents. Hope I'm making sense here.
$('#add_customer_form').submit(function() { // handle form submit
The "add_customer_form" id is what I would like to change on a per page basis. If I could successfully do this, then I could make a class of some sort that would just use the rest of this json script and include it where I needed it. I'm sure someone has already thought of this so I was wondering if someone could give me some pointers.
Thanks!
Well, I hit a wall so to speak. The code below is the code that is already in my form. It is using a datastring datatype but I need json. What should I do? I want to replace the stupid alert box with the nice 100% wide green div where my server says all is ok.
$.ajax({
type: "POST",
url: "body.php?action=admCustomer",
data: dataString,
success: function(){
$('#contact input[type=text]').val('');
alert( "Success! Data Saved");
}
});
Here is the code I used in the last question, minus the comments:
$(function() {
$('#add_customer_form').submit(function() {
var data = $(this).serialize();
var url = $(this).attr('action');
var method = $(this).attr('method');
$.ajax({
url: url,
type: method,
data: data,
dataType: 'json',
success: function(data) {
var $div = $('<div>').attr('id', 'message').html(data.message);
if(data.success == 0) {
$div.addClass('error');
} else {
$div.addClass('success');
}
$('body').append($div);
}
});
return false;
});
});
If I am right, what you are essentially asking is how you can make this piece of code work for multiple forms without having to edit the selector. This is very easy. As long as you have the above code included in every page with a form, you can change the $('#add_customer_form') part to something like $('form.json_response'). With this selector we are basically telling jQuery "any form with a class of json_response should be handled through this submit function" - The specific class I'm using is not relevant here, the point is you use a class and give it to all the forms that should have the functionality. Remember, jQuery works on sets of objects. The way I originally had it the set happened to be 1 element, but every jQuery function is meant to act upon as many elements as it matches. This way, whenever you create a form you want to handle through AJAX (and you know the server will return a JSON response with a success indicator), you can simply add whatever class you choose and the jQuery code will take over and handle it for you.
There is also a cleaner plugin that sort of does this, but the above is fine too.
Based on your question, I think what you want is a jQuery selector that will select the right form on each of your pages. If you gave them all a consistent class you could use the same code on each page:
HTML
<form id="some_form_name" class="AJAX_form"> ... </form>
Selector:
$('form.AJAX_form")