I have the javascript code below which disables an asp.net button during page postback. I also have a dropdownlist whose Autopostback property is set to true. Unfortunately, when i change the selectedItem in the dropdownlist, the button is disabled.
I want the Button disabled only when the page postback is caused by that same button, but not any other control on the page.
Some one please help on what change i should make to the code below to achieve this.
<script type="text/javascript">
// Get a reference to the PageRequestManager.
var prm = Sys.WebForms.PageRequestManager.getInstance();
// Using that prm reference, hook _initializeRequest
// and _endRequest, to run our code at the begin and end
// of any async postbacks that occur.
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndRequest);
// Executed anytime an async postback occurs.
function InitializeRequest(sender, args) {
// Change the Container div's CSS class to .Progress.
$get('Container').className = 'Progress';
// Get a reference to the element that raised the postback,
// and disables it.
$get(args._postBackElement.id).disabled = true;
}
// Executed when the async postback completes.
function EndRequest(sender, args) {
// Change the Container div's class back to .Normal.
$get('Container').className = 'Normal';
// Get a reference to the element that raised the postback
// which is completing, and enable it.
$get(sender._postBackSettings.sourceElement.id).disabled = false;
}
</script>
Well, you're hooking into any asynchrous postback, sounds like you just want to hook into a particular button's postback.
However, you could fix this with minimal code adjustment, just by checking the ID of the control which triggered the postback before disabling it.
if (args._postBackElement.id == idOfTheButton)
$get(args._postBackElement.id).disabled = true;
Of course, if your button is a server-side button (asp:button), then you would need to either render out the client-id to the client from the server, or access it directly:
if (args._postBackElement.id == '<%= YourButton.ClientId %>')
$get(args._postBackElement.id).disabled = true;
As i said, there are better solutions than this (like only hooking into the postback event of the button, not any postback event).
But nonetheless, this should solve your problem.
You are referencing the id of the button here:
$get(args._postBackElement.id).disabled = true;
So all you need to do is to check the value of the ID prior to setting it to disabled:
if(args._postBackElement.id == '<%=MyButton.ClientID %>')
$get(args._postBackElement.id).disabled = true;
Related
I used this code to change the class of an html-element when an onclick-event occurs. The change occurs(i.e. the text color changes) but the change is not stable, it goes back to the styling of its previous class, and my javascript code doesn't seem to have any effect.
function submitrequest(){
var x = document.forms["signupform"]["name"].value;
if(x.toString().length <= 0){
var y = document.getElementById("nametd");
y.className = 'change';
}
}
What should I do to make this effect permanent?
You do not have to define a click-handler to notice that a button of a form was clicked.
A form can have an submit-button:
and when this button is clicked an submit event is fired for the form.
Furthermore when an user do not clicks on the button and just presses enter then a submit-event is fired too. So you handle both situations automatically.
I suggest that you define you function that way:
window.onload = function(){
document.getElementById('signupform').addEventListener('submit',function(e){
changeClassOfNametd();
e.preventDefault(); // this prevents the side from being reloaded by the script.
});
};
function changeClassOfNametd(){
var nameValue = document.forms["signupform"]["name"].value;
if(nameValue){ // when value is "" (zero, no signs) it is false anyway
var y = document.getElementById("nametd");
y.className = 'change';
//y.classList.toggle('change'); you can toggle classname "change" too
// which works that way class="unchange" -> class="unchange change"
// you have to define appropriate css-classes for toggle.
}
}
The Code above works whereever you put it into your html-file.
By the name of the function it is called on a form submission.
Because the form submits and it goes back to the original that was set when the new page loads.
If you want to maintain that, you would have to apply the class on the next page load. Most developers will do that with the serverside. If you do not actually want the form to submit, cancel it.
I can't seem to get this to work in JavaScript. I've tried using plain old JavaScript and also JQuery but nothing seems to work.
Here's my situation:
I have this PopUp "Panel" and in it I have a Button. The button has an event listener for click and I want that handler to fire off a custom event that the Panel will listen for. This is because I need to handle all the logic of the button click in the Panel.
Here's what I'm doing:
Before I launch the Panel I call a constructor for my "Class":
function PopUpStageAsssignmentTaker(content) {
PopUpStage.call(this);
this.allPagesAdded = false;
this.questionsCreated = [];// will be an array of pages that will be submitted
this.listLabel = null;
addAssignmentTakerParts.call(this);
this.popUpDiv.addEventListener("assignmentTakingSubmitEvent", handleAssignmentSubmit, true);
function handleAssignmentSubmit(event) {
alert("YESSS!");
}
}
This does quite a bit but just know that in the call to PopUpStage it creates the div that represents the Panel and saves that in this.popUpDiv. So I add a event listener to this.popUpDiv listening for some custom event that I'm making up.
Later on I have code that creates the content in the Panel and we have something like this:
SubmitQuestionTakingPage.prototype.makeContent = function(question) {
var questionWrapper = getQuestionWrapper();
var submitDiv = document.createElement("section");
submitDiv.innerHTML = "Pressing Submit will cause this Assignment to be submitted and you will be unable to make any changes after that. If this " +
"Assignment is automatically graded you will receive a Grade upon clicking submit. If this Assignment is not automatically submitted you must wait" +
" for the creator of this Assignment to assign you a Grade. To continue, please press Submit.";
submitDiv.setAttribute("class", "separatedSmaller");
questionWrapper.appendChild(submitDiv);
var submitButton = document.createElement("input");
submitButton.setAttribute("type", "submit");
submitButton.setAttribute("class", "fancyButton");
submitButton.addEventListener("click", handleSubmitButtonClick);
questionWrapper.appendChild(submitButton);
return questionWrapper;
};
function handleSubmitButtonClick(event) {
var event = document.createEvent("Event");
event.initEvent("assignmentTakingSubmitEvent", true, true);
window.dispatchEvent(event);
// $(this).trigger("assignmentTakingSubmitEvent");
}
So we create some content and in it we create a button that has a listener for click. In the click handler you can see how I fire off the event.
Problem: I'm reading that this does not work in IE under version 9+. What can I do in to make it work in all browsers? Is there a way?
I want to write Jquery code in master file, so that if there if user changes page and there is any unsaved changes user should get alert.
I got one answer from this: link
However in most solution I will have to write code on all pages. I want it to write only at one place so that everybody dont have to worry to write it in their modules. My code is like:
<script type="text/javascript">
var isChange;
$(document).ready(function () {
$("input[type='text']").change(function () {
isChange = true;
})
});
$(window).unload(function () {
if (isChange) {
alert('Handler for .unload() called.');
}
});
</script>
But everytime i make changes in text boxes .change() event is not firing.
What can be wrong in the code?
EDIT:
I changed .change() to .click and it is fired. i am using jquery 1.4.1..is it because of jquery version that change() is not working?
This is what i am using, Put all this code in a separate JS file and load it in your header file so you will not need to copy this again and again:
var unsaved = false;
$(":input").change(function(){ //triggers change in all input fields including text type
unsaved = true;
});
function unloadPage(){
if(unsaved){
return "You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?";
}
}
window.onbeforeunload = unloadPage;
EDIT for $ not found:
This error can only be caused by one of three things:
Your JavaScript file is not being properly loaded into your page
You have a botched version of jQuery. This could happen because someone edited the core file, or a plugin may have overwritten the $
variable.
You have JavaScript running before the page is fully loaded, and as such, before jQuery is fully loaded.
Make sure all JS code is being placed in this:
$(document).ready(function () {
//place above code here
});
Edit for a Save/Send/Submit Button Exception
$('#save').click(function() {
unsaved = false;
});
Edit to work with dynamic inputs
// Another way to bind the event
$(window).bind('beforeunload', function() {
if(unsaved){
return "You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?";
}
});
// Monitor dynamic inputs
$(document).on('change', ':input', function(){ //triggers change in all input fields including text type
unsaved = true;
});
Add the above code in your alert_unsaved_changes.js file.
A version that use serialization of the form :
Execute this code, when dom ready :
// Store form state at page load
var initial_form_state = $('#myform').serialize();
// Store form state after form submit
$('#myform').submit(function(){
initial_form_state = $('#myform').serialize();
});
// Check form changes before leaving the page and warn user if needed
$(window).bind('beforeunload', function(e) {
var form_state = $('#myform').serialize();
if(initial_form_state != form_state){
var message = "You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?";
e.returnValue = message; // Cross-browser compatibility (src: MDN)
return message;
}
});
If the user change a field then manually rollback, no warn is displayed
change event is fired once the user blurs from input not on every single character inputed.
If you need it to be called every time something is changed (even if focus is still in that input field) you would have to rely on combination of keyup and bunch of events to keep track of pasting/cuting using mouse only.
P.S.
I hope you're aware that your approach to detecting changes isn't the best one? If user input some text, leaves the field and then reverts the changes the script would still alert him about modified text.
you should register events for not only inputs but also textareas, if you mean textarea with text box. You can use keyup for isChange, so that you don't wait for user to blur from this area.
$("input[type='text'], textarea").keyup(function () {
isChange = true;
})
This is really just a different version of #AlphaMale's answer but improved in a few ways:
# Message displayed to user. Depending on browser and if it is a turbolink,
# regular link or user-driven navigation this may or may not display.
msg = "This page is asking you to confirm that you want to leave - data you have entered may not be saved."
# Default state
unsaved = false
# Mark the page as having unsaved content
$(document).on 'change', 'form[method=post]:not([data-remote]) :input', -> unsaved = true
# A new page was loaded via Turbolinks, reset state
$(document).on 'page:change', -> setTimeout (-> unsaved = false), 10
# The user submitted the form (to save) so no need to ask them.
$(document).on 'submit', 'form[method=post]', ->
unsaved = false
return
# Confirm with user if they try to go elsewhere
$(window).bind 'beforeunload', -> return msg if unsaved
# If page about to change via Turbolinks also confirm with user
$(document).on 'page:before-change', (event) ->
event.preventDefault() if unsaved && !confirm msg
This is better in the following ways:
It is coffeescript which IMHO automatically makes it better. :)
It is entirely based on event bubbling so dynamic content is automatically handled (#AlphaMale's update also has this).
It only operates on POST forms as GET forms do not have data we typically want to avoid loosing (i.e. GET forms tend to be search boxes and filtering criteria).
It doesn't need to be bound to a specific button for carrying out the save. Anytime the form is submitted we assume that submission is saving.
It is Turbolinks compatible. If you don't need that just drop the two page: event bindings.
It is designed so that you can just include it with the rest of your JS and your entire site will be protected.
Why not simply bind the event to the change callback?
$(":input").change(function()
{
$(window).unbind('unload').bind('unload',function()
{
alert('unsaved changes on the page');
});
});
As an added bonus, you can use confirm and select the last element that triggered the change event:
$(":input").change(function()
{
$(window).unbind('unload').bind('unload',(function(elem)
{//elem holds reference to changed element
return function(e)
{//get the event object:
e = e || window.event;
if (confirm('unsaved changes on the page\nDo you wish to save them first?'))
{
elem.focus();//select element
return false;//in jQuery this stops the event from completeing
}
}
}($(this)));//passed elem here, I passed it as a jQ object, so elem.focus() works
//pass it as <this>, then you'll have to do $(elem).focus(); or write pure JS
});
If you have some save button, make sure that that unbinds the unload event, though:
$('#save').click(function()
{
$(window).unbind('unload');
//rest of your code here
});
Without jQuery:
var unsaved = false;
document.addEventListener("DOMContentLoaded", function() {
var els = document.querySelectorAll('textarea, input, select');
els.forEach( function(el) {
el.addEventListener('change', function() {
unsaved = true;
});
});
window.addEventListener('beforeunload', function(event) {
if(unsaved){
event.returnValue = "string";
}
});
var forms = document.querySelectorAll('form');
forms.forEach( function(form) {
form.addEventListener('submit', function() {
unsaved = false;
});
});
});
The weird 'string' hack explanation can be found here.
I use $('form').change etc. function to set a dirty bit variable. Not suitable to catch all changes (as per previous answers), but catches all that I'm interested in, in my app.
okay, if I have six buttons in a list, under the li tag (each on is rel to a part of an array), how can I disable a button while it's doing it's thing? (In this case playing a video)I know it's a little vague (i haven't supplied code or anything of the sort), but that's because I don't know how to go about it. If I could at least get pointed in the right direction, that would be helpful, so that even if I can't figure it out, at least I can be specific with my problem... thanks...EDIT this is what I've now done
<li rel='1' id="first">
<div style="top:0px;">
<img src="graphics/filler.png" alt="" width="280" height="128" onClick="asess"/>
</div>
</li>
and then added the corresponding function
function asess() {
document.getElementById("first").disabled = true;
}
I'm not to concerned with adding the function back just yet, because first I'd like to make this part work.EDIT I've got this, which should work, but I guess it's not "talking" to the button?
$("li, .thumbs").bind("touchstart click", function() {
var $this = $(this);
if (!document.getElementById("first").disabled) {
document.getElementById("first").disabled = true }
else {document.getElementById("first").disabled = false};
});
I know it will only talk to the button with that id (first one) but as long as I can make it work for one, I can do the rest. So, what am I doing wrong?
Each button will have an onclick event handler. To prevent the onclick handler from doing anything the JavaScript method attached to the handler should return false. If you are doing this with jQuery return false; is the same as calling e.preventDefault (or event.preventDefault for IE).
When the normal event handler initiates the action associated with the button it should add the event handler that disables the onclick action.
You will probably need to apply a new CSS style to the button as well so the user knows it's disabled.
When the action completes you need to remove event handler that disables the onclick action and use the normal one again.
You could always just use a flag to say an action is in progress and set this on and off with the actions. If the flag is on then the event handler method returns false.
By using the event handler you could also show an alert to the user when they try and click the button before you return false.
EDIT:
Here is the sort of JavaScript you'll need, the first click starts the process which will stop itself after five seconds using setTimeout('stopAction()', 5000);. If you click the item again during that time you get the wait message.
I would recommend you look at using jQuery to develop a robust cross browser solution.
var inProgress = false;
function asess() {
if(inProgress) {
alert('Please wait ...');
return false;
} else {
startAction();
}
}
function startAction() {
inProgress = true;
alert('Starting');
document.getElementById("first").style.backgroundColor = '#333333';
setTimeout('stopAction()', 5000);
}
function stopAction() {
inProgress = false;
alert('Stopping');
document.getElementById("first").style.backgroundColor = '#FFFFFF';
}
document.getElementById("my_button").disabled = true;
and when you're done.
document.getElementById("my_button").disabled = false;
You could "disable" the element within the click handler and re-enable it when the callback is executed successfully.
Click handler binding to elements with disabled="disabled" attribute is not guaranteed to be consistently implemented across browsers (i.e. the event could/would still fire) and is not allowed except on form elements anyway. I'd just add class="disabled" which gives me additional powers to style the disabled element state by, say, greying it out.
Oh, and jQuery. Naturally, this logic could be reproduced in "normal" javascript but is so tidier with library usage, fiddle:
$('#my-button').click(function() {
var $this = $(this); //cache the reference
if (!$this.hasClass('disabled')) {
$this.addClass('disabled');
alert('hello world!');
setTimeout(function($btn) {
$btn.removeClass('disabled');
}, 5000, $this);
} else {
return false;
}
});
How can I stop sending data to the server if the button allready has been clicked ? I don't want a disable="disabled" response (buttons are custom made).
I tried setting a global var button_clicked = FALSE; set it true when button has been clicked, after that set it again to false when the response has been received . But that doesnt work neither because my mouse is messed up and spam clicks really fast (although i click only once -> this actualy helped me to see that the method mentioned isn't so acurate).
Are there better methods to stop a process or disable a DOM element onClick? Maybe disable the event? js or jquery answer preferable . Or maybe this really can't be done on really fast requests . I know it depends on alot of things (like user's cpu). Any comment or answer is welcome. Maybe for every click on the page set the user to wait for some miliseconds ?
Try this little constructor:
function MyForm()
{
this.check = false;
this.form = function(){
var f = this;
$('#form').submit(function(e){
e.preventDefault
if( f.check === false )
{
f.check = true;
$.ajax({
...blah blah
success: function( data )
{
//if you want to let them send again, uncomment this next line
//f.check = false;
}
})
}
});
this.form();
}
$(document).ready(function(){
var my = new MyForm();
});
If you register an event listener, the Event object you get will have a preventDefault() method. This avoids following a clicked link or sending a submitted form.
If it is a custom action triggered by an event handler, the only possibility is to check a condition in the handler function whether the action really should be taken. Yet, a disabled button is not that bad because you will need to inform the user that nothing will happen.
Remove the click handler when the button is clicked. Add it again when you are ready for the next click.
button.onclick = null;