I have got a form with two tabs, on both tabs you can edit data and submit your changes which is working already.
Now I want the tab where you made changes to get reloaded after you changed something (e.g. a picture URL and the thumbnail should get refreshed) to see the changes.
I have this code for the second tab
<script>
$(document).ready(function(){
$('.btn').click(function(){
var clickBtnValue = $(this).val();
if(clickBtnValue == 'Save') {
var ajaxurl = 'ajax.php',
data = $('form').serialize();
$.post(ajaxurl, data, function (response) {
if(response == '')
{
alert("Successfully saved");
location.href="catalog.php";
}
else alert(response);
});
}
else if(clickBtnValue == 'Save & Continue Edit')
{
var ajaxurl = 'ajax.php',
data = $('form').serialize();
$.post(ajaxurl, data, function (response) {
if(response == '') alert("Successfully saved");
else alert(response);
});
}
else if(clickBtnValue == 'Add new Item')
{
var ajaxurl = 'ajax.php',
data = $('#itemform').serialize();
$.post(ajaxurl, data, function (response) {
if(response == '')
{
alert("Successfully added new Item");
location.href="catalog.php";
}
else alert(response);
});
}
else if(clickBtnValue == 'Save Images')
{
var ajaxurl = 'saveimages.php',
data = $('#imageform').serialize();
$.post(ajaxurl, data, function (response) {
if(response == '')
{
alert("Successfully saved");
$("#tab_images").load(location.href+" #tab_images>*","");
}
else alert(response);
});
}
});
});
Everything is working until now, the data get saved and the DIV reloads, but now whenever I try to press a button nothing happens, even on the first tab.
What am I doing wrong?
EDIT:
My Tab Code: http://i.epvpimg.com/9SaKb.png
Can't post it here since it is too long so I had to make a screenshot.
It looks like the buttons you try to click are inside the div what you are reloading. When the content of that div is replaces, all the elements you fetched with ajax are considered as new - that also means that the click handlers you had previously on those buttons are also lost - hence they don't react the same way :D
try binding the event not on the button itself but an element outside the div that is being replaced
$("parent_selector_outside_ajax_div").on("click", ".btn", function() {
//your button function
});
read move about event delegation with jQuery at http://api.jquery.com/on/
As your external js library binds it's own buttons I suggest moving those buttons outside the div you are trying to update (which shouln't be a big problem as you are trying to update only for the sake of them image previews? :D).
The other alternative (which I wouln't do) would be to rebind those buttons again after the ajax has reloaded by calling whatever function the library offers to initialize itself. If your application is long lived, you also should, before replacing the old content with a new one, remove all the event handlers from the current content, to avoid possible memory leaks in some browsers (not sure what is your target audience).
Related
I'm using AJAX to submit the form without reloading. I'm using it for my register form. After I catch my error/success message I append it to my div and remove it after 5 seconds using timeout function.
Now if the user clicks on the button and gets error, and then again clicks the button (before 5 seconds pass) the second error message div will appear with the same error but it will be removed at the same time the first one is removed. So what I'm trying to achieve is to set my error/success messages to have individual timeouts. So first error appears, then after 2 seconds I press the button again and get second error, now the first error will be removed after 5 seconds, and the second will stay untill its 5 seconds pass.
So I have a div in my HTML code with the id "msg-response", where my error/success messages appear.
And here is how I call them:
$("#registerform").submit(function(event) {
var ajaxRequest;
event.preventDefault();
$("#result").html('');
var values = $(this).serialize();
ajaxRequest = $.ajax({
url: "include/auth/register.php",
type: "post",
data: values
});
ajaxRequest.done(function (response){
if ($.trim(response) == 'error') {
$("#msg-response").prepend("<div class='error-msg'>Email format isn't valid. Try again.</div>").hide().fadeIn("slow");
setTimeout(function() {
$('.error-msg').fadeOutAndRemove('slow');
}, 5000);
}
});
ajaxRequest.fail(function (){
alert("error");
});
});
So how can I add individual timeouts to each div appeared? And not one timeout for all divs with class .error-msg.
Thanks in advance.
You can store your .error-msg inside a var and then remove it by var reference:
var error = $("<div class='error-msg'>Email format isn't valid. Try again.</div>");
error.fadeOutAndRemove('slow');
Final code:
if ($.trim(response) == 'error') {
var error = $("<div class='error-msg'>Email format isn't valid. Try again.</div>");
$("#msg-response").prepend(error).hide().fadeIn("slow");
setTimeout(function() {
error.fadeOutAndRemove('slow');
}, 5000);
}
Intresting, I got it working by making my error-msg div to be an ID instead of CLASS, so like this:
$("#registerform").submit(function(event) {
var ajaxRequest;
event.preventDefault();
$("#result").html('');
var values = $(this).serialize();
ajaxRequest = $.ajax({
url: "include/auth/register.php",
type: "post",
data: values
});
ajaxRequest.done(function (response){
if ($.trim(response) == 'error') {
$("#msg-response").prepend("<div id='error-msg'>Email format isn't valid. Try again.</div>").hide().fadeIn("slow"); // Changed line
setTimeout(function() {
$('#error-msg').fadeOutAndRemove('slow'); // Changed line
}, 5000);
}
});
ajaxRequest.fail(function (){
alert("error");
});
});
I'm confused a little, so can atleast someone write me explanation why its good now that I'm using ID and not while using classes? And is this the right approach?
I am testing using the w3-include-html library in order to avoid hard coding certain code blocks that are used frequently such as the menu bar, footer, contact form, etc. on a website I am working on. At first I encountered an error with the mobile menu bar that I found a solution for HERE. I was able to change the on click event listener that I was using for $('body').on('click','.navbar-toggle',function() { as instructed by the solution.
The remaining problem is that at first the email subscribe field was able to avoid redirecting a blank page that would say "You have subscribed successfully." and simply show a green check mark. After using w3-include-js it now redirects to this blank page with the text. While looking through some of the js functions I found this code:
$('.ajax-form').on('submit', function(event) {
event.preventDefault();
});
$('.form-required').each(function() {
var form = this;
var formname = this.id;
var $form = $(form);
if($form.data('ajaxInProcess')) {
return;
};
$form.data('ajaxInProcess', true);
$.ajax({
url: form.action,
type: form.method,
data: $(form).serialize(),
success: function(response) {
var responseObject = {};
if (typeof response === 'string') {
responseObject = JSON.parse(response);
} else {
responseObject = response;
}
var statusText = responseObject.status;
if (formname == 'subscribe') {
$('#subscribe-button').removeClass('successful');
} else if (formname == 'subscribe2') {
$('#subscribe-button2').removeClass('successful');
}
I believe that this is the code that needs to be edited in order to get the email subscribe working again with w3-include-html. I am hoping someone here is able to help me in applying the solution above to this code that I have included. Any help here is greatly appreciated.
You need to delegate the submit event as well
$('body').on('submit','.ajax-form',function(event) {
event.preventDefault();
});
Jtable pagination is not working if I am pressing back button.
I have some 4 option in menu. First option is home and last is report. When I am clicking on report, getting a list which I am displaying by using jtable. After clicking page 1,2,3,4,10,20 new page come. But after pressing back button previous should display. For that I modified some code of jtable api.
/* Performs an AJAX call to reload data of the table.
*************************************************************************/
_reloadTable: function (completeCallback) {
var self = this;
//Disable table since it's busy
self._showBusy(self.options.messages.loadingMessage, self.options.loadingAnimationDelay);
//Generate URL (with query string parameters) to load records
var loadUrl = self._createRecordLoadUrl();
//Load data from server
self._onLoadingRecords();
self._ajax({
type:'GET',
url: loadUrl,
cache : false,
data: self._lastPostData,
success: function (data) {
var historyData = self._lastPostData;
historyData.url=loadUrl;
history.pushState(stringifyObject(self),'List',window.location.href);
location.hash = loadUrl;
self._hideBusy();
//Show the error message if server returns error
if (data.Result != 'OK') {
self._showError(data.Message);
return;
}
//Re-generate table rows
self._removeAllRows('reloading');
self._addRecordsToTable(data.Records);
self._onRecordsLoaded(data);
//Call complete callback
if (completeCallback) {
completeCallback();
}
},
error: function () {
self._hideBusy();
self._showError(self.options.messages.serverCommunicationError);
}
});
},
And added one more method
window.onhashchange = function() {
//console.log(JSON.stringify(eval("(" + history.state + ")"));
if(history.state!=null){
var self = JSON.parse(history.state);
alert(self._createRecordLoadUrl());
alert(self.state._lastPostData);
self._reloadTable(completeCallback);
}
}
I am not able to call these method because self is not jtable object.
Please provide better solution.
I have a series of buttons that execute different functions when clicked. The function checks whether the user is logged in, and if so proceeds, if not it displays an overlay with ability to log in/create account.
What I want to do is re-execute the button click after log-in, without the user having to reclick it.
I have it working at the moment, but I'm pretty sure that what I'm doing isn't best practice, so looking for advice on how I can improve...
Here's what I'm doing: setting a global variable "pending_request" that stores the function to be re-run and in the success part of the log-in ajax request calling "eval(pending_request)"
Example of one of the buttons:
jQuery('#maybe_button').click(function() {
pending_request = "jQuery('#maybe_button').click()"
var loggedin = get_login_status();
if (loggedin == true) {
rec_status("maybe");
}
});
.
success: function(data) {
if(data === "User not found"){
alert("Email or Password incorrect, please try again");
}else{
document.getElementById('loginscreen').style.display = 'none';
document.getElementById('locationover').style.display = 'none';
eval(pending_request);
pending_request = "";
}
}
Register a function to handle the click and then invoke that func directly without eval().
jQuery('#maybe_button').on('click', myFunction)
This executes myFunction when the button is clicked. Now you can "re-run" the function code every time you need it with myFunction().
And btw since you are using jQuery you can do $('#loginscreen').hide() where $ is an alias for jQuery that's auto defined.
EDIT
Please, take a look at the following code:
var pressedButton = null;
$('button1').on('click', function() {
if (!isLoggedIn()) {
pressedButton = $(this);
return;
}
// ...
});
And, in your success handler:
success: function() {
// ...
if (pressedButton) pressedButton.trigger('click');
// ...
}
I am using Magnific Popup version 0.8.9.
I am loading content into it via Ajax, and I use a callback for ajaxContentAdded. This callback sets up an event handler for submitting a form that was loaded into the popup, like so:
$('.add-item-btn').magnificPopup({
type: 'ajax',
closeOnContentClick: false,
callbacks: {
ajaxContentAdded: HandleItemFormSubmit
}
});
This works fine, the form submit is handled correctly. The event handler function posts it to the server, which (in case of errors) returns the entire form including error messages.
For this purpose I let it replace the popup's content with the returned form, and setup the submit handler again.
function HandleItemFormSubmit()
{
var popup = this;
// Submit form using ajax
$('form.item-form').submit(function()
{
var data = $(this).serialize();
var url = $(this).attr('action');
$.post(url, data, function(resp)
{
if (resp == 'OK')
{
// All good, close up
popup.close();
}
else
{
// Show HTML from response (with errors)
popup.closeOnContentClick = false;
popup.content.replaceWith(resp);
popup.updateItemHTML();
HandleItemFormSubmit();
}
});
return false;
});
}
However, despite setting closeOnContentClick to false at two different points, the popup immediately closes when content is clicked after the content was replaced (it does work the first time).
The content in the popup has a single root element by the way.
I hope the author or someone else can help out here, I have no idea what is wrong here.
Thank you very much!
I've found another solution:
$('html').on('submit', '#UR_FORM', function(e) {
e.preventDefault();
$.ajax({
data: $(this).serialize(),
type: $(this).attr('method'),
url: $(this).attr('action'),
success: function(response) {
var magnificPopup = $.magnificPopup.instance;
magnificPopup.items[0].type = "inline";
magnificPopup.items[0].src = response;
magnificPopup.updateItemHTML();
}
});
});
You need to call the HandleItemFormSubmit for the popup object:
HandleItemFormSubmit.call(popup);
Otherwise when you call it the way you do, HandleItemFormSubmit();, the this will be set to window and this will not work as expected.
Update
Use this in the else clause:
if (resp == 'OK')
{
popup.close();
}
else
{
// Show HTML from response (with errors)
popup.closeOnContentClick = false;
popup.content.replaceWith(resp);
popup.updateItemHTML();
HandleItemFormSubmit.call(popup);
}