On the page I am building, I have four buttons which show/hide (visible="true" || visible="false") certain div's. What I want is before the AJAX function is called, my own custom function be called, which animates opacity of current visible div to zero, then displays a loading image and finally after the AJAX function completes another custom function is called which animates the "to be" shown div from zero opacity to 1 and from left to right. What I am trying to accomplish is windows phone 7 kind of effect in the webpage. So, any ideas how I can do that?
If your are using Asp.net ajax then yo can achieve this by following these steps
Register your javascript methods with these statement.
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequestHandle);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequestHandle);
Definition of registered methods
function beginRequestHandle(sender, Args)
{
alert("Begin Request Handle called.");
}
function endRequestHandle(sender, Args)
{
alert("End Request Handle called.");
}
You can do this by writing a custom ajax handler in your code. For example, in your cs file:
[WebMethod]
public static bool CustomAjaxMethod(string arg)
{
// do work
return true;
}
Then, in your aspx file:
<input type="button" value="Do Ajax Call" onclick="doWork();" />
And in javascript:
function doWork() {
// do your 1st animation here
PageMethods.CustomAjaxMethod('foo', callback);
}
function callback(result, userContext, methodName) {
if (methodName == 'CustomAjaxMethod') {
// may want to check result here
// do your 2nd animation here
}
}
Related
I have a Blazor server app with two buttons. The first button calls the MenuOpen method in C#, and the second calls the TestJSInterop method in C#. Here is the code:
#inject IJSRuntime JSRuntime;
<!-- buttons -->
#code {
List<int> tabs = new List<int>();
protected override Task OnAfterRenderAsync(bool firstRender)
{
JSRuntime.InvokeVoidAsync("monacoInit");
return base.OnAfterRenderAsync(firstRender);
}
async Task OpenNewTab(string title)
{
int newId = await JSRuntime.InvokeAsync<int>("addEditorModel", new object[]
{
title, "test", "test", "test"
});
tabs.Add(newId);
await JSRuntime.InvokeVoidAsync("addTab", newId);
}
async Task MenuOpen()
{
await OpenNewTab("testing");
}
async Task TestJSInterop()
{
await JSRuntime.InvokeVoidAsync("console.log", "test");
}
}
In the Javascript, I've added console.logs to each method that's being called from C#. When I press the button to call TestJSInterop, I get the following result in the console:
test
call addEditorModel
call addTab: parameter is 0
call addEditorModel
call addTab: parameter is 0
When I press the button to call MenuOpen, I get this result:
call addEditorModel
call addTab: parameter is 1
call addEditorModel
call addTab: parameter is 0
call addEditorModel
call addTab: parameter is 0
I know that the OpenNewTab C# method is not being called multiple times, as when I put a breakpoint there and click the button to call TestJSInterop I do not reach the breakpoint.
The JSRuntime.InvokeVoidAsync call does work correctly in OnAfterRenderAsync.
Why am I getting this behavior?
I was trying to understand your partial code, but it seems as though I've failed. However, you should take into account the following:
The OnAfterRenderAsync method is executed each time your component is being rendered. It is primarily used to initialize JavaScript objects. When you want to initialize your JavaScript objects (I guess only once, right ?), the code should be placed within an if statement checking that this is the first time:
if( firstRender )
{
// Here's you place code that is executed only once
// the parameter firstRender is evaluted to true only the first time
// the OnAfterRenderAsync method is executed
}
Only UI events, such as the click event, cause your component to re-render.
If you need to re-render your component in order to see changes made
otherwise, you'll have to call the StateHasChanged method
If your app is pre-rendering ( render-mode="ServerPrerendered" ), your components are rendered twice, and thus you may see messages printed in the console window twice. This is OK.
Hope this helps... If you did not solve your issues, please post a complete repo of your code, and I'll try to help you with this.
I have no idea how to do this. I am using swt browser to run openlayers , I had some basic function. So I want to capture the coordinates where I click on a map.
I try ta add a listener to the browser widget, so it calls a function on javascript that returns the coordinates of the mouse, but for what I can tell the click listener on the browser gets executed first, then on javascript the clik event gets executed, so on the first try it returns undefined and then it returns the previews clicks, not the current one.
So part of the problem is that in order to get the coordinates i am using ol3 function to get the position
I am using ol3 functions to set the mouse click
map.on('singleclick', function (evt) {
position = evt.coordinate;
....
})
and I have a function to return position but it takes a while to position to change.
Is there a way to create something like a callback that when a function in javascript is done it will call a function on java so it can update my window?
You can define a function in your code that can be called from JavaScript by using a class derived from BrowserFunction:
class MyFunction extends BrowserFunction {
MyFunction(Browser browser, String name) {
super (browser, name);
}
#Override
public Object function(Object[] arguments) {
// Your code
}
}
name is the JavaScript name for the function.
More details here
How can I return a parent function from a child function on click? Here's an example code:
function returnFunction() {
var output = false;
$('a').click(function() {
output = true;
});
return output;
}
var result = returnFunction();
The result will always be false since the click hasn't happened at the time the code is being run. How could I make this work though?
My intention is to call pop-up dialogs, and I'd like to have all the logic inside one function that can easily be loaded - including the click events of a Confirm dialog box.
Elsewhere in scripts I'd be calling it this way for example:
// Menu click triggers the dialog
$('a').click(function(e) {
// The function displays the dialog and returns the click events of the dialog
var result = returnFunction();
// If result was false, we'll prevent the menu access, for example
if (!result) {
e.preventDefault();
}
});
I'm aware of the jQuery UI dialog plugin. But I'd like to achieve this without it for now.
Thanks.
An over-simplification of it is:
Everything stops (including scrolling and clicking on hyperlinks) while executing javascript. This means you cannot "pause" the script until someone clicks on a link.
The typical way of solving this is a callback function:
function my_callback(some, arguments) {
// you can do whatever in here: an ajax load, set a global variable, change some of the page, ...
console.log(some, arguments);
alert(some + " " + arguments);
}
function returnFunction(callback, param) {
var output = false;
$('a').click(function() {
callback(param, "world");
});
}
returnFunction(my_callback, "hello");
demo at http://jsfiddle.net/UnBj5/
EDIT:
I did mention global variables because they are an option, but they are typically bad style. Try to use other means if possible.
If you want more help with it, provide more details of what you are trying to do.
Try using parameters instead. Send a parameter to a function that shows your alert boxes, show a different pop-up alert depending on the parameter, what you are trying to do won't work because its basically a chicken-egg problem.
I'm using a jQuery tip plugin to show help tips when the user hovers certain elements of the page.
I need to register the plugin events after the page is loaded using css selectors.
The problem is I'm using an ASP.NET Update Panel and after the first postback, the tips stop working because the update panel replaces the page content but doesn't rebind the javascript events.
I need a way to execute a javascript callback after the Update Panel refreshes its content, so I can rebind the javascript events to have the tips working again.
Is there any way to do this?
Instead of putting your jQuery code inside of $(document).ready(), put it inside
function pageLoad(sender, args) {
...
}
pageLoad is executed after every postback, synchronous or asynchronous. pageLoad is a reserved function name in ASP.NET AJAX that is for this purpose. $(document).ready() on the other hand, is executed only once, when the DOM is initially ready/loaded.
See this Overview of ASP.NET AJAX client lifecycle events
The pageLoad didn't work. I used this instead:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(pageLoaded);
function pageLoaded() {
}
This is probably far from the most elegant solution, but its a solution nonetheless:
public class UpdatePanel : System.Web.UI.UpdatePanel
{
/// <summary>
/// Javascript to be run when the updatepanel has completed updating
/// </summary>
[Description("Javascript to be run when the updatepanel has completed updating"),
Category("Values"),
DefaultValue(null),
Browsable(true)]
public string OnUpdateCompleteClientScript
{
get
{
return (string)ViewState["OnUpdateCompleteClientScript"];
}
set
{
ViewState["OnUpdateCompleteClientScript"] = value;
}
}
protected override void OnPreRender(System.EventArgs e)
{
base.OnPreRender(e);
if(!string.IsNullOrEmpty(this.OnUpdateCompleteClientScript))
Page.ClientScript.RegisterStartupScript(this.GetType(), this.ClientID, string.Concat("Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args){for(var panelId in sender._updatePanelClientIDs){if(sender._updatePanelClientIDs[panelId] == '", this.ClientID, "'){", this.OnUpdateCompleteClientScript, "}}});"), true);
}
}
Use it like this:
<uc:UpdatePanel OnUpdateCompleteClientScript="alert('update complete');">
<!-- stuff in here -->
</uc:UpdatePanel>
Of course you'll need to register the custom control in youre webconfig or page to use it like this.
Edit: also, have you looked at jquery.live?
If you want to do specific operations before and after the UpdatePanel has loaded, you can override BeginPostbackRequest and EndPostbackRequest like so:
var postbackControl = null;
var updatePanels = null;
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_beginRequest(BeginPostbackRequest);
prm.add_endRequest(EndPostbackRequest);
function BeginPostbackRequest(sender, args) {
prm._scrollPosition = null;
postbackControl = args.get_postBackElement();
postbackControl.disabled = true;
updatePanels = args._updatePanelsToUpdate;
// do your stuff
}
function EndPostbackRequest(sender, args) {
// do your stuff
postbackControl.disabled = false;
postbackControl = null;
updatePanels = null;
}
This is very handy if you want to process only HTML that was delivered by the update panel. Some operations require more resources and it would be overkill to process the whole DOM tree on pageLoad.
Use pageLoaded event and check whether callback or postback:
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(function (sender, args) {
if (args._panelsUpdated && args._panelsUpdated.length > 0) {
//callback;
}
else {
//postback;
}
});
I've got a short function that should show messages on a website.
function showHint() {
$('#notify').html('message text').show('slide', {direction: 'right'}, 500);
}
And there is another function that hides the messages.
function hideHint() {
$('#notify').hide('slide', {direction: 'right'}, 500);
}
The Problem is that if I call this function more than one times it tries to show all messages at the same time and everything breaks. I want to call the function twice and then it should queue the animations and show one message after another. The function should be called more than one times at the same time but shown one after another. The next message should be shown when the firs hides.
How could I solve the Problem? Would be nice!
Here's a mini custom plugin that I've used in the past that chains a bunch of animations one after another.
// Good for serializing animations
$.fn.chain = function(fn) {
var elements = this;
var i = 0;
function nextAction() {
if (elements.eq(i)) fn.apply(elements.eq(i), [nextAction]);
i++;
}
nextAction();
};
You might call it like so (Here's an example of it in use):
$(document).ready(function() {
$('li').chain(function(nextChain) { this.slideToggle("fast", nextChain); });
});
The function you pass to chain passes another function that you must call when you're down with one cycle. In the example above, we just pass the nextChain function as the callback to the slideToggle.
Your showhint function could just start by hiding the notification and when that is complete the callback would be what is the existing showhint function, that would change the text and show it. Code shouldn't be difficult given what you've already done.
can you not just use a notification plugin? here are two (one, two) that are pretty spiffy.