I've got a list of checkboxes and an ImageButton with an OnClick event in my page, clicking the ImageButton performs a postback and runs the OnClick event fine
The trouble is that I want to move the div to be the first child of the <form> so that I can make it appear in a modal window - I've done this using the prototype.js code...
document.observe("dom:loaded", function() {
if ($$('.CheckboxListContainer').length>0) {
var modalShadow = document.createElement('div');
modalShadow.setAttribute( "class", 'MyFormModalShadow' );
modalShadow.style.width = document.viewport.getWidth() + 'px';
modalShadow.style.height = document.viewport.getHeight() + 'px';
var modalDiv = document.createElement('div');
modalDiv.setAttribute( "class", 'MyFormModal' );
var checkboxesDiv = $$('.CheckboxListContainer')[0];
checkboxesDiv.remove();
modalDiv.appendChild( checkboxesDiv );
$$('form')[0].insert( {top: modalShadow} );
$$('form')[0].insert( {top: modalDiv} );
Event.observe(window, "resize", function() {
if ($$('.MyFormModalShadow').length>0) {
var modalShadow = $$('.MyFormModalShadow')[0]
modalShadow.style.width = document.viewport.getWidth() + 'px';
modalShadow.style.height = document.viewport.getHeight() + 'px';
}
});
}
});
... which works fine, but the ImageButton is no longer triggering my OnClick event on postback.
Is there a way to move my div around in the DOM and retain its postback abilities?
Quick answer, yes. Long answer below:
If you're talking ASP.NET WebForms, does your form have the runat="server" attribute and an id? If you're using standard HTML, are the method and action attributes set on the form?
When you look at the HTML source in your browser, if the form looks like: <form action="/your_post_back_page.html" method="post">, then that's all good. Inspect the form with FireBug after the modal dialog has been added, see if it is INSIDE the form tags. If so, that's good.
Do your check boxes <input type="checkbox" /> have a name attribute set? Is your image button <input type='submit' /> or is it a <button>?
If these conditions are met, then there is probably a JavaScript event (a function) wired to your button that is returning false and/or swallowing the postback. JavaScript onclick events generally need to return true to submit a form. Is there any output in your browser's error console?
Personally, I find more and more that pure HTML (by way of ASP.NET MVC) beats the pants off old school ASP.NET WebForms, and jQuery has, in my experience, a far nicer feel than prototype. Using jQuery templates to create a modal dialog would be easy. Can you swap libraries?
First of all, i am not very clear why you need to move the element to be the first child of the form to make it modal. You can make any div modal no matter where is the position in the form. The most important think is controlling the absolute positioning properly.
Each postback gets triggered by a __DoPostBack() javascript function, so you should not have any issues with moving the control around, unless you changed the id of the control.
One possible solution to your problem is calling the __DoPostBack() function from your client code in document.ready, and that way you have full control over the form submission.
Related
I have a menu that is a nested ListView Control that is on my master page. I use the Jquery below to turn this ListView into a accordion. The problem is when I click on the Menu titles it will cause a postback. So the submenu flashes and ones the post back is complete it reloads the page and the menu(closing the Active submenu).
$('.head').each(function () {
var $content = $(this).closest('li').find('.content');
$(this).click(function (e) {
// e.preventDefault();
$content.not(':animated').slideToggle();
});
});
Well simply put there are few ways you can maintain state during postback. Two easiest are using POST and GET, ie the ViewState or some kind of query string.
Continued
I would personally recommend using a hidden field, let's say that you want the 3rd item to open on load, then you would use something like
<input id="hidMenuItem" type="hidden" value="3" />
Then using jQuery
$(document).ready(function {
var itemIndex = $("#hidMenuItem").val();
$("li .content:nth-child(" + itemIndex + ")").slideToggle();
});
To save the open item before postback do this in the click event
var itemIndex = $("li .content").index(this);
$("#hidMenuItem").val(itemIndex);
It's untested but this is the idea.
Hope that helps
Here is the context:
I am building a .aspx page that allows the user to administrate some xml documents we have on our server. The page content is loaded using AJAX, so buttons and forms are dynamically added to the document.
If I had static buttons that I was creating within the .aspx page before it loads on the client's machine, I could attach an event to it very easily. However, I'm dynamically adding and removing buttons and forms on the fly, using jQuery.
Here is a simplified example:
In the following jsFiddle, I'm pretending that the html document contains the following script:
<script language="C#" type="text/C#" runat="server">
void SaveAllChanges(Object sender, EventArgs e)
{
Button clickedButton = (Button)sender;
clickedButton.Text = "foobar";
}
</script>
And that I have a javascript file that contains the following:
$('button.buttonGenerator').click(function() {
$('.buttonContainer').append(
'<button onclick="SaveAllChanges">' +
'Save All Changes!' +
'</button>'
);
});
Obviously the buttons I am creating can not run the function SaveAllChanges with the way it is now. I added the onclick attribute to show what I needed to happen, in a pseudo-code kind of style.
How can I make it so that dynamically added buttons can run the C# method I have defined within the script tag at the top of the document?
Here is the jsfiddle: http://jsfiddle.net/2XwRJ/
Thanks.
You can give all buttons that must save changes a common class (e.g. class="ajaxButton") and have one jQuery method that responds to click events on elements matching that class (use live so that updates to the DOM are reflected).
$("button.ajaxButton").live("click", function(){
// Perform your Ajax callback to run server-side code
});
What you need to do is use something like ..
$(document).ready(function() {
$('button.buttonGenerator').click(function() {
$('.buttonContainer').append(
'<button id="#dynamicCommentButton" onclick="SaveAllChanges">' +
'Save All Changes!' +
'</button>'
);
});
$(document).on('click', '#dynamicCommentButton', function() {
alert($(this).attr('id'));
});
});
You are not going to be able to add the buttons like you have it there as this code here is just adding it as an HTML DOM element and the onclick attribute will be the on the client element. As a result clicking the button will try fire a SaveAllChanges javascript function
$('.buttonContainer').append(
'<button onclick="SaveAllChanges">' +
'Save All Changes!' +
'</button>'
);
What would be best would be to create that SaveAllChanges function in javascript and then you can handle it from there. Two of the ways I see you being able to do this are:
Have a http endpoint setup (script service, web api or just posting to a page) that you call using Ajax from your javascript. You can then pass through any needed arguments.
You could have a hidden element and hidden button on the page so that when the javascript is called it populates any arguments you need and then clicks the hidden button and posts the page back.
Personally I would choose the first approach from a user experience stand point as the page will not be posting back each time. I have used something similar to the second approach and it works fine but just feels very clunky.
I know this is a basic question, but I am curious as to what the different options are, and what the best practice would be.
If I have a form that is responsible for saving reservations into a system, how can I prevent the form from being posted twice if the user hits the button twice really quickly?
I know there are a few ways in which I can accomplish this, but I am not quite sure which is the standard way of preventing this. Partially because I am new to web forms, and am used to dealing with MVC.
Thanks ahead of time.
I've used two approaches to this problem:
Use a token based approach. Each page has a hidden input with the current random token. This token is also stored in the user's session. Once the postback occurrs, I compare tokens and, if they are valid, generate a new session token and continue processing. When the second postback occurs, the token no longer matches and prevents processing.
Use javascript to disable the submit button. If you take this approach, and need the button event handler to fire, you'll need to create a hidden input with the name attribute of the button before submitting. The hidden input is required because disabled inputs do not end up in the post data.
I would recommend a client-side onClick event handler that disables the button or makes it invisible, preferably the latter, and replace the button with a label that reads "Processing..." or something like this
I have been using something like this when using an asp:Button for submitting:
1) Set the submit button's UseSubmitBehavior="false"
2) Set the submit button's OnClientClick="pleaseWait(this, 'Please Wait...');"
3) Include javascript code in the page:
function pleaseWait(obj, message) {
if (typeof(Page_ClientValidate) == 'function') {
if (Page_ClientValidate()) {
obj.disabled = true;
obj.value = message;
return true;
}
}
return false;
}
This solution is nice because it is simple but still accounts for client-side javascript validations. It isn't perfect, because it still relies on Javascript, which could be turned off, but that's unlikely to be done by someone who doesn't have the sense to click once and wait for a response. :)
Easy way - use the ajax AnimationExtender control.http://www.asp.net/ajaxLibrary/AjaxControlToolkitSampleSite/Animation/Animation.aspx
Simply attach the extender to the button and add a disable action.
<asp:Button ID="CopyScenarioButton" ClientIDMode="Static" OnClick="CopyScenarioButton_Click"
OnClientClick="setTimeout( function() {$('#CopyScenarioButton').attr('disabled', 'disabled');},0)"
EnableViewState="false" Text="Save New Scenario" ToolTip="Save New Scenario"
CssClass="btnNormal" runat="server" />
or the later version that includes some validation first:
function PreSaveHybrid() {
var doSave = PreSave();
if (doSave !== false) //returns nothing if it's not a cancel
setTimeout(function () { $('#btnSave').attr('disabled', 'disabled'); }, 0);
return doSave;
}
I have a button which right now is set as a type "submit". This calls the controller, execute some code and returns back to the view. When I use jquery to hide the button, I see that when I click on the button, what I have hides the button but as soon as the view is returned, the button is not hidden no more. Whereas with type "button", when I click the button, this hides the button but doesnt execute the code in the controller. Is there a way to hide the type "submit" button so when the view returns, the button is still hidden?
$('#btnAdd').click(function() {
$('#btnAdd').hide();
});
<input type='submit'> creates a button that submits a form to a server and triggers your server code. If you want the button hidden when the page comes back, you need to add logic to your page to do that. How you do this will depend on your server technology (php, .net, etc.).
The reason the behavior with <button> is different is that <button>s don't submit the form (unless you add more code to make them do that)...so the above mentioned stuff never happens. It's not so much that a <button> stays hidden as much as the page never changes/reloads. If you added code to the <button> to make it refresh the page, it'd reappear, too.
The button is shown because the page is newly displayed after submiting the form. Your "old" page, where clicked and hid the button is history.
What do you want?
Pressing a button, do something on serverside, do not change your current page:
Use a button of type button, use ajax to call the server side.
Or use a button of type submit and do what Pablo said http://en.wikipedia.org/wiki/Post/Redirect/Get on serverside.
Pressing a button, do something on serverside, give user feedback:
Use <form method="post" to markup your form. Use a submit button to call the server side. On serverside hide the submit button, if it is called by method post (calling a page with link or typing it into the address field is calling it with method = get).
What is the difference between type submit and type button?
A submit button works without javascript to send some input to serverside. The surrounding form is send to the server and the response is rendered in browser.
A button button needs a javascript onclick handler, a javascript function. The onclick handler is called when the user pressed the button.
Since the page will be reloaded upon pressing the submit button, the button will reappear. One quick and dirty to get what you want is...
First, create a hidden field
<input type="hidden" id="hidden" value="" />
Then, when you press submit, in a click event for submit button, do something like this..
$('#submit').click(function() {
$('#hiddenField').val("1");
$('#form').submit();
return false;
});
Now in your controller, use the value of hiddenField of pass some variable to the view which can be used like this...
<?php if($hidden == "1"): ?>
<input type="submit" id="submit" value="Submit" />
<?php endif; ?>
As far as the button not submitting the form is concerned, it won't submit the form, until you submit the form yourself on the click event of button. Something like this...
$('button').click(function() {
$('#form').submit();
});
Of course, as I mentioned this is a quick and dirty way to implement the function you want, there are better ways - using AJAX, also the implementation can change depending on what server side language you use (I used php over here).
When your form is submitted and your controller process the data, if certain criteria is met, you can set a temporary session variable or a cookie in server side code. So, basically the page will check for this variable on every page load. Example in PHP:
if( empty($_SESSION['temp']['hideSubmitButton']) ) {
$submitButton = '<button type="submit">Normal Button</button>';
} else {
$submitButton = '<button type="submit" disabled="disabled">Disabled Button</button>';
// or $submitButton = '';
}
But then you have to decide when to unset() the $_SESSION['temp'] or $_COOKIE['temp'] variable.
I have an ASP.NET application that also uses jQuery for modal pop-ups. If I put an ASP button (or image button) within the DIV for the jQuery modal, the "OnClick" event does not fire.
How can I fix this?
When you create the dialog, you need to move it a bit for ASP.Net, like this:
$(".class").dialog({
//options
}).parent().appendTo("form");
By default the .dialog() moves the content to just before </body> which most importantly is outside the <form></form>, so elements within it won't be included in the POST (or GET) to the server. If you manually move it like I have above, it'll resolve this issue.
By default, jQuery places the modal OUTSIDE of the asp.net <form> element.
You can easily append it to the form like:
$("#your-modal").parent().appendTo("form:first");
And this should fix your problems. It's a common problem with jQuery/ASP.NET.
Enjoy