The client is making a request to the server.
I need to take part of that request, and make the form button work with Ajax.
This piece of code works perfectly for links:
var pagination_render = function() {
var pagination = $('.pagination a');
pagination.each(function() {
$(this).click(function(event) {
load_server(this.href, '.houseindex');
return false;
});
});
};
pagination_render();
I tried numerous things for making the Ajax button work, and this is one of the tries:
var contact_user = function () {
$('.expanded').find('#submit').each(function() {
$(this).unbind('click');
});
$('.expanded').each(function() {
$(this).find('#submit').click(function(event) {
form_submit($(this).parent(), '.contactuser .msg');
return false;
});
});
}
Whenever there is a successful Ajax call, it goes through all of the expanded items, and then binds a click event.
Now, sometimes this code works, and sometimes it doesn't.. When it doesn't work, it disables other events (toggle links) I have set up.
It seems as if I need to wait a few ms for it to load the component into the DOM.. Do I?
So I get that when you call contact_user you:
First unbind any previous binded click events from the submit button. I see one possible problem there and is that you are looking for an id of #submit. You should only have one id in a single page. Therefore you only need to use $('#submit').each(...) or if you have several submit buttons in the page either use a class if there are several submit buttons inside an .expanded item or just use $('.expanded :submit')
Adding a custom event when clicking the submit button. Same thing, you can simplify this by $('.expanded :submit') or if you truly only have one button with an id of submit (quite confusing). Go with $('#submit').
In conclusion:
var contact_user = function(){
$('.expanded :submit').unbind('click');
$('.expanded :submit').click(function(){
form_submit($(this).parent(), '.contactuser .msg');
return false;
});
};
the :submit selector will select all <input type="submit" />.
Related
I am using the following code to send the ajax, but the problem is when user clicks for a second time on the button it does not post to backend or do not submit data, for it to work again the user needs to reload the page again. Anyone has an idea why?
$(document).ready(function () {
$('#btn_follow').click(function (e) {
e.preventDefault();
//e.stopPropagation();
//$('#divId :input').serialize();
var follow_and_unfollow = $("#user_page_follow :input").serialize();
$.post(
"backend/ajax/follow_and_unfollow.php",
follow_and_unfollow
).done(function (data) {
//$("#testimonials").load(location.href+" #testimonials>*","");
$("#follow").html(data);
$("#user_followers").load(location.href + " #user_followers>*", "");
}).fail(function () {
//alert("Error submitting forms!");
});
});
});
on second click on #btn_follow it's not submitting, the user needs to reload the page for it to work
As we've confirmed in the comments, you're overwriting your original button with new content returned via AJAX. As such, the button element that you'd bound the click even too is gone, replaced with a new bit of HTML from the server.
I'd suggest you do the following. Replace:
$('#btn_follow').click(function (e) {
With:
$('#follow').on('click', '#btn_follow', function (e) {
This essentially binds the handler to the #follow element, but only runs it if the element clicked matches the filter expression. It's called event delegation and it's an important concept. Read about it here.
I have a next issue:
My application contains many buttons that make async requests to the server, currently if user is fast enough to click button more than one time - same request gets executed twice or more and data on the server gets duplicated.
Is there a way to disable clicked button, until the request is executed?
Someone suggested this solution:
$("input[type='button']")
.each(function () {
var el = $(this);
var onclickFunction = el.attr('onclick'), alreadyChecked = el.attr('clickHandler');
if (typeof onclickFunction != 'undefined' && typeof alreadyChecked == 'undefined')
{
el.removeAttr("onclick");
el.removeAttr("onclickFunction", onclickFunction);
el.attr('clickHandler', 'true');
el.on('click', function()
{
el.attr("disabled", "disabled");
$.when(eval(onclickFunction)).then(function () { el.removeAttr('disabled'); })
})
}
});
But if i understood correctly, this code runs only once. So if my application contains many views, this code should be executed on each view load.
Is there any more apropriate solution?
Two ways.
1) Use a flag(let's call it requestInProgress) in the page scope that is turned on once the request is made. Once the request is completed, turn off the flag.
2) Disable the button once the button is request is getting processing so as to prevent user from hitting it a second time. Enable the button once the request processing is complete.
Try using .one()
function handleClick(e) {
// not necessary, though notifies user button is disabled
$(this).attr("disabled", true);
// do ajax stuff
$.ajax().then(function() {
$(e.target).removeAttr("disabled")
// reattach `click` when ajax completes
.one("click", handleClick)
})
}
$("input[type='button']").one("click", handleClick)
What I would recommend is using a CSS class to prevent the user from multiple submissions. This also provides you the flexibility of easily styling the appearance for disabled buttons as well, say for their color or opacity in your stylesheet.
Something like this:
function onClickHandler() {
var myButton = $(this);
// check to see if it's already disabled
if (myButton.hasClass('disabled')) {
// if so, just exit out
return;
}
// add the disabled class
myButton.addClass('disabled');
// continue with your processing...
}
If browser compatibility is not an issue, you could also check out the disabled attribute, but I'm personally a bigger fan of using a class.
I'm new to Javascript and JQuery, and I'm implementing a warning to users that displays when they have made unsaved changes to a form's input/select/textarea elements if they navigate away from a page. I currently have the following which works fine when they leave a static form page:
/*
* Warn users when leaving a page with unsaved content, watches elements: (input, textarea, select) unless
* they are tagged with the "noWarning" class
*/
$(document).ready(function() {
$(document).on('change', 'input:not(.noWarning),textarea:not(.noWarning),select:not(.noWarning)', function () {
window.onbeforeunload = function(e) {
return 'You have unsaved changes';
};
});
});
The only page where it does not work, is in our main editing page. This page, unlike the others, has multiple tabs for editing different aspects of an item, which when clicked, trigger an AJAX call which replaces the content div with the appropriate form for editing the different aspect.
No warning dialog is displayed when a user clicks on a tab though, so any unsaved changes to the input are lost.
My intuition is that because the url is not changing, onBeforeUnload() is not executing. So I would have to check for any changes directly in the function which handles the AJAX call for replacing the form when a tab is clicked:
function clickedTabbedMenu() {
// This function replaces the content div with a new div and form
}
So my question is, how do I go about checking if any changes have been made to the elements in the current form before I replace the content div with another??? Can I directly call the "change" event listener for a true/false??? Or perhaps a different approach to handle this page's warning messages?
Any help is appreciated
Attach a change event handler to all the elements of the form. Have a variable outside the handler's scope dirty (or even a data on the form element) be set to false when a form is loaded, and true on every change event. Then, before replacing the form, check if dirty.
This would also be a good strategy for your non-AJAX pages as well - instead of setting the whole onBeforeUnload each time an element changes, just set onBeforeUnload once, and check if dirty inside it. This makes handling your AJAX and non-AJAX pages very similar.
EDIT: Untested because it's late and I need bed, but basically:
$(document).ready(function() {
var dirty = false;
$(document).on('change', 'input:not(.noWarning),textarea:not(.noWarning),select:not(.noWarning)', function () {
dirty = true;
});
function checkDirty() {
if (dirty) {
alert('You have unsaved changes');
return false;
}
return true;
}
// for non-AJAX pages
window.onbeforeunload = function(e) {
return checkDirty();
};
// for AJAX pages
$('.ajax_navigation_tab').on('click', function() {
if (!checkDirty()) {
// do the ajax thing
dirty = false;
}
});
});
I would try checking for and calling window.onbeforeunload() in your ajax script.
If it exists and returns a string, use it as an error message and halt the operation :)
I am both setting a form's action and submitting the form via the onclick event of a div:
<div class="action_button" onclick="document.forms['test'].action='url/to/action';document.forms['test'].submit()">
<span class="action_button_label">Save</span>
</div>
This works fine, but I'm wanting to use some code that conditionally checks for the 'Save' in the action_label_button, and only lets the submit() fire once. I'm trying to prevent multiple saves (which is yielding duplicate data in my app) from occurring.
// disable save buttons onclick (prevent multiple clicks of save buttons)
$('.action_button_label').one('click', function() {
// if the button is a save button
if($(this).html().indexOf('Save') != -1) {
// submit the parent form
$(this).html('<span class="action_button_label" style="color:gray;">Saving...</span>');
$(this).parents('form').submit();
}
});
$('form').bind('submit', function() {
$(this).find('action_button').attr('onclick', '');
});
This code doesn't seem to work as I expected. I'm afraid I'm a bit out of my depth here, any pointers would be great.
Try replacing
$(this).find('action_button').attr('onclick', '');
with
$(this).find('.action_button').attr('onclick', '');
You should always handle multiple submits server side to ENSURE you don't get them. However you can hide the button-label to assist with this client side.
$('.action_button_label').one('click', function() {
// if the button is a save button
if($(this).html().indexOf('Save') != -1) {
// submit the parent form
$('.action_button_label').hide(); //ADD THIS
$(this).html('<span class="action_button_label" style="color:gray;">Saving...</span>');
$(this).parents('form').submit();
}
});
$('form').bind('submit', function() {
$(this).find('action_button').attr('onclick', '');
});
I have a list of radio buttons that I can toggle "yes" or "no" to using Javascript.
$(document).ready(function(){
$('#select-all').click(function(){
$('#notifications .notif-radio').each(function(){
$('input[type="radio"]', this).eq(0).attr('checked', true);
$('input[type="radio"]', this).eq(1).attr('checked', false);
});
});
$('#deselect-all').click(function(){
$('#notifications .notif-radio').each(function(){
$('input[type="radio"]', this).eq(0).attr('checked', false);
$('input[type="radio"]', this).eq(1).attr('checked', true);
});
});
});
this works just fine. Now I have a separate piece of code that detects when a user has changed something, and asks them if they want to leave the page.
var stay_on_page;
window.onbeforeunload = confirm_exit;
$('.container form input[TYPE="SUBMIT"]').click(function(){
stay_on_page = false;
});
$('#wrapper #content .container.edit-user form').change(function(){
stay_on_page = true;
});
function confirm_exit()
{
if(stay_on_page){ return "Are you sure you want to navigate away without saving changes?"; }
}
The problem is that if the user uses the first piece of functionality to toggle all radio buttons one way or another. The JS detecting form changes doesn't see that the form was changed. I have tried using .live, but to no avail. Anyone have any ideas?
I do something similar to this by adding change() (or whatever's appropriate, click() in your case I suppose) event handlers which set either a visible or hidden field value, then check that value as part of your onbeforeunload function.
So, my on before unload looks like:
window.onbeforeunload = function () {
if ($('#dirtymark').length) {
return "You have unsaved changes.";
}
};
And, or course, dirtymark is added to the page (a red asterisk near the Save button), when the page becomes dirty.