How to call a CSJS function that uses JQuery after Dojo parser has completed? - dojo

I need to call a CSJS function which uses JQuery. The tricky part is I need to call it after the Dojo parser has completed.
The CSJS function is calling $('#pageContainer input[type!="hidden"], #pageContainer select, #pageContainer textarea').serialize();
I need to call serialize() after the Dojo parser has completed otherwise I won't have the Dojo date fields in the serialized string.
I've tried putting the call in a script block at the bottom of the page like this: $(function() { serializeForm() }); but this is running before the Dojo parser has completed because my date picker field is missing.
I've also tried doing dojo.ready(serializeForm()) but that gave me an error:
TypeError: context is not a function
info: context is not a function
The error is coming from dojo.js line 1862
FYI: The purpose of serializing is to do a "is form dirty" check when the user tries to navigate away from the page (I had no luck with the enabledModifiedFlag I think because my app is using the dynamic content control to switch pages).

ready is expecting a call back function, remove the parenthesis, or wrap in anonymous function
dojo.ready(serializeForm)
or
dojo.ready(function(){serializeForm()})

Related

Blazor Server, Conditional Elements + JS Invoking

I have a Blazor Server app that is a multi-step "wizard" form. After each relevant step the state is adjusted, and new HTML is shown/hidden via conditional statements (simple example below).
if (IsStepSignature)
{
<div>Signature HTML here</div>
}
This all works just fine. My problem comes when I need to invoke some JS logic on the dynamically generated HTML from above (e.g. click handlers to hook up external JS libraries). When I handle the "Next" click, I can invoke the JS just fine...but it is not yet seeing the dynamic HTML from above. Is there a way to invoke some JS, and control it so that it doesn't execute until after the page is redrawn from the C# code execution?
5/18/2020 Update from Nik P
Can leverage some flags and use OnAfterRenderAsync to control this ordering. This does work, but it does require some extra hops to/from the server. Below is what I see when implementing this. This may just be the nature of Blazor Server, as one of the pros/cons is some known added chattiness. In total these requests were 2.5K, so extremely small.
CLIENT --> Browser Dispatch Event (NEXT CLICK)
Render <-- SERVER
CLIENT --> Render Complete
Invoke JS <-- SERVER
CLIENT --> Invoke Complete
The issue you are having has to do with the element not existing in the client side HTML at all until after the re-render takes place. So one way to do this is to set a boolean flag in your C# code that says there is code that needs to be run after the render, and populate support fields that you will need for your JS Interop. Whenever you need to run the JS interop, set your flag to true, set your support fields to the values you need for the JS interop call, and then do something that kicks a DOM diff calculation. (Even StateHasChanged should be enough, but adding your items conditionally as you mentioned will also do it) Then, override your OnAfterRenderAsync method as follows:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if(firstRender)
{
// any first render code
}
if(yourFlag)
{
YourJSInteropMethod(supportField1, supportfield2);
yourflag = false;
}
}
The simplicity in this approach is that the DOM update will always happen ahead of the OnAfterRenderAsync call, so your HTML will be populated with what you are targeting with JS.

How do you close a vue-material md-menu?

I'd like to call close on a mouseleave event on an md-menu component. I'm using version 0.7.4 of the vue-materiallibrary, and using this documentation it says that there is a close method.
How do I call this method? I've tried the following:
<md-menu md-size="1" ref="aRef" id="aRef">
<div #mouseleave="this.$refs['aRef'].close()">
...other stuff...
</md-menu>
When I run this I get an error saying:
Uncaught TypeError: Cannot read property 'aRef' of undefined
I'm guessing this is something to do with the component not being available at creation time. What's the correct way of doing this?
I should say that the md-menu is actually nested inside another md-menu (which seems to work ok from a functional perspective). Not sure if that screws up the event hierarchy.
I stumbled across the solution for this one while I was trying to solve a different problem (how to close any other menus before opening another).
Your problem is that you can't use this inline in the html template. You need to send the event to a method and then call it...
<md-menu
ref="aRef"
#mouseleave="closeMenu"
>
// menu contents
</md-menu>
Then in your script section:
methods: {
closeMenu() {
this.$refs['aRef'].close();
}
}

How to replace jquery's live for elements that don't exist when the page is loaded

I have seen numerous advice on stackexchange and all over the web suggesting that I not use jquery's live function. And at this point, it is deprecated, so I'd like to get rid of it. Also I am trying to keep my javascript in one place(unobtrusive)--so I'm not putting it at the bottom of the page. I am unclear though on how to rewrite the code to avoid live for elements that don't yet exist on the page.
Within the javascript file for my site I have something like this:
$(function() {
$('button.test').live('click', function(){
alert('test');
});
});
.on( doesn't work since the element doesn't exist yet.
The button is in a page I load in a colorbox pop-up modal window. I'm not sure exactly where that colorbox window sits in the DOM but I think it is near the top.
I could use delegate and attach this to the document--but isn't the whole point of not using live to avoid this?
What is the best way to get rid of live in this case?
You can use .on() - http://api.jquery.com/on/
$(document).on("click", "button.test", function() {
alert('test');
});
If you use live() you can use die().
You can also use on() and off().
They do about the same thing but its recomended to use on.
I ended up avoiding both live and an on attached at the document level. Here's how:
Wrap all of the jquery code specific to objects in a page which loads in the colorbox window in the function like so:
function cboxready(){
...
}
The code wrapped in this function can attach directly to the objects (instead of attaching at the document level) since it will only get run once the colorbox window is open.
Then just call this function using colorbox's callback when you attach the colorbox, like so:
$('a.cbox').colorbox({
onComplete:function(){ cboxready(); }
});

colorbox onError

http://colorpowered.com/colorbox/
I am using color box.
$('#.boxItems').colorbox({onComplete:function(){
alert("completed");
}});
onComplete work when the event is completed.
But at some particular cases im my application onComplete don't work
I know it is because some error happening at my server side
BUT ,can i have a call back function onError()
The jQuery selector you are using is odd. Consider changing to be one of the following (not both like you have it):
$('.boxItems').colorbox...
$('#boxItems').colorbox...
As far as I know, ColorBox doesn't support an onError callback. Set a breakpoint inside the ColorBox script to trap your action.

using .aspx page as Jquery Cluetip?

I am using an .aspx page as cluetip bound to an anchor tag. I need to pass a parameter from anchor to this page and then call a WCF service to populate my template with returned JSON. I tried putting body onload function but that doesnt seems to work.
Thanks
Koby.
response to comment
You want to use the .mouseenter() event. This new event in 1.4 is better than .blur() which is what you will see in most examples (and probably why you can find it, a search of blur jquery popup should give you lots of examples). But mouseenter is better in the lastest jQuery
Docs: (very nice example code at the bottom of the page.)
http://api.jquery.com/mouseenter/
old version
just add the function to the onclick handler. You can do this in jquery with something like this
$(selector).click(function () {
code to do stuff (call wcf and populate)
you can use $(this) to see what was clicked on. ("passed" as you put it)
});
see fab new jQuery docs http://api.jquery.com/click/