Server-Side callback function to solve JS-CF execution order dependency? - javascript

I would like to call a form as pop-up window (a form with some input fields and a submit button) and then read the user selected results from the session. The problem is that the mixing of JS code (pop-up window) with CF (server-side) code, as is expected, causes the process to output the session variable before the process updates it. For better understanding, hereunder is the scenario together with some relevant code snippets:
Scenario:
1. User calls ShowForm(..)
2. ShowForm(..) displays a pop-up window and waits for the user
to submit his selection
3. The result gets stored in the session
4. The function returns the user-submitted result
form.cfc
<cffunction name="ShowForm" access="public" output="true" returntype="string">
<script>
window.showModalDialog('formpage.cfm',null,"dialogHeight=400px,dialogLeft=150px");
</script>
<cfreturn session.form_result> <!--- #toFix: The return of form_result is happening before the actual form_result is set. --->
</cffunction>
formpage.cfm
<cfajaxproxy cfc="components.sess_mgr" jsclassname="JSMaskProxy">
<script>
function submitSelection(formObj)
{
for (i=0; i<intSelValue.length; i++)
result.push(intSelValue[i]);
var instCfProxy = new JSMaskProxy();
instCfProxy.setToSession(result); // updates session.form_result
//window.returnValue=result;
window.close();
}
</script>
<form name="frmDtls">
<td align="center"><input type="button" id="selectButton" name="selectButton" onClick="submitSelection(details);">
</form>
What's your take on this? How to solve this problem?
ColdFusion.navigate(..) function can have a callback function and an error handler but the thing is that the callback function can only be a client-side function. If the function could be a CF function or maybe a server-side page I think that would solve this dependency problem.
Something on the side, ideally I would love to read the value from window.showModalDialog rather than reading it from the session, but this is just a sketch and the main point here is how to overcome this JS-CF intermingling problem.

Rather than using window.showModalDialog use something like cfwindow, jQuery dialog or an extjs window. All of these have some form of callback or event listener. cfwindow has a onHide function, jQuery dialog has a close option to which a function can be assigned, ext.window has onHide, as well as event listeners.
All of these will allow you to open a new "window" and run some function when the window is hidden or closed. Those functions should all have access to anything from the window as well as being able to access the main window.
Ray Camden has a cfwindow example : http://www.coldfusionjedi.com/index.cfm/2008/9/26/Ask-a-Jedi-Another-CFWINDOW-Example
jQuery dialog has an example of what you're after : http://jqueryui.com/demos/dialog/#modal-form
Sencha's Ext.Window examples show passing values to the main window when a dialog is closed : http://dev.sencha.com/deploy/dev/examples/message-box/msg-box.html
Plenty of options there. I hope they help.

Problem solved!
The solution adopted is based on Stephen Moretti idea which is that of replacing window.showModalDialog with cfwindow call. This alone does not solve the problem. However, I worked when replacing the script tag with cfscript, and then inside the cfscript I simply do a server-side redirection to the page with cfwindow tag.

Related

Dynamics CRM 2016 Online - Refresh record after using dialog

I have a custom button on my ribbon which fires a dialog up. It's part of a workaround Qualification solution I'm putting together.
The creation of an Account/Contact/Opportunity and the choices given work fine, as well as changing the status of the Lead to qualified. The problem is that when the user is done with the Dialog and closes it, they're still looking at the Lead in its original state.
How do I force the form to refresh so that it shows its new state?
I've seen a Javascript solution online (codeplex), Process.js - callDialog() which seems popular but it doesn't want to work as described by the creator on my version of CRM - always get a invalid URL error message & it fires on load of the form as well as when using the custom button.
Has anyone come across a requirement like this and how have you resolved it?
Thanks
Edit: Here is the JS I use on my ribbon button currently. Where do I put my refresh call and what/how do I call the event being used when closing the Dialog.
I tried adding a refresh call at the bottom of the this code but its called whilst opening the Dialog at the start, which isn't much use as the changes I want to see are applied throughout the Dialog itself.
Thanks
Develop1_RibbonCommands_runDialogForm = function(objectTypeCode, dialogId) {
var primaryEntityId = Xrm.Page.data.entity.getId();
var rundialog = Mscrm.CrmUri.create('/cs/dialog/rundialog.aspx');
rundialog.get_query()['DialogId'] = dialogId;
rundialog.get_query()['ObjectId'] = primaryEntityId;
rundialog.get_query()['EntityName'] = objectTypeCode;
var hostWindow = window;
if (typeof(openStdWin) == 'undefined') {
hostWindow = window.parent; // Support for Turbo-forms in CRM2015 Update 1
}
if (typeof(hostWindow.openStdWin) != 'undefined') {
hostWindow.openStdDlgWithCallback(rundialog, hostWindow.buildWinName(null), 615, 480, Xrm.Page.data.refresh(false));
}
}
})();
Check out the Xrm.Page.data (client-side reference), you'll want to call Xrm.Page.data.refresh().
Depending on how you're launching your dialog, and assuming your dialog is a webresource hosted in CRM, the dialog can reach back out to the form it launched from and call refresh, or a callback could potentially be used.
EDIT (based on your posted code): If the 5th parameter of the function openStdDlgWithCallback is the callback for when the dialog closes you'd want to pass the function like Xrm.Page.data.refresh or wrap your call in a function function(){Xrm.Page.data.refresh()}. Currently your code is executing the function right away which is why you're seeing the refresh right away.
Using openStdDlgWithCallback you can subscribe a callback function which runs after the dialog is closed. You can then use Xrm.Page.data.refresh() inside the callback function.

Completely delete all instances of a div with a specific class using javascript/jquery?

I am using Popup.js by Toddish.
http://docs.toddish.co.uk/popup/demos/
Long story short, the popup plugin creates divs by default given the classes ".popup_back" and ".popup_cont".
I have another button I wish to press which should completely delete the added divs with those classes after they have been generated and added to the html. As if they never even existed. Surely this is possible?
I have tried running a function which simply runs:
$(".popup_back").remove();
$(".popup_cont").remove();
As shown in this example:
http://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_dom_remove
Unfortunately despite the code running, the actual divs are never deleted as required.
Any ideas? I am new to this kind of thing and have googled around and read a lot about DOM etc but am yet to crack it.
Thanks
EDIT:
In reply to the comments:
The Javascript:
function removePopups() { // This function is called to remove the popups.
console.log("removing...");
$(".popup_back").remove();
$(".popup_cont").remove();
}
function func(url) { // url is the url of the image to be displayed within the popup.
removePopups(); // As soon as the function casillas is called, removePopups is used to remove any existing instances of the divs.
$('a.theimage').popup({ // This is where the Popup plugin is utilised.
content : $(url),
type : 'html'
});
}
The HTML:
<a class="theimage" onclick="func('image/image1.jpg')" href="#" >
Long story short, an image is displayed in the popup.
I think the issue is that the popup plugin runs due to the class but the function func is never actually run when the click occurs. However simultaneously "removing..." still prints out in the console which tells me that the function IS being executed. The problem is I want the popup plugin to run together with the javascript function. Is there a solution for this conflict?
Your implementation should really be as simple as this:
<a class="theimage" href="#" >Open</a>
Bind the popup creation to your popup link:
$('a.theimage').popup({
content : 'image/image1.jpg',
type : 'html'
});
I'm speculating here, but what might be happening is that you're invoking the popup twice by binding the popup() call to a click handler in your markup. The popup plugin already binds the popup creation to a click event.
View working demo. Note the 3 external resource: the popup CSS, the popup JS, and the jQuery JS.

Call Javascript Function from seperate Classic ASP page

I'm updating a Classic ASP page (login.asp) which includes another Classic ASP Page (logincode.asp -- contains functions for the first page).
Previously, after clicking the login button, it would run several functions on logincode.asp and then open a terms agreement dialog if needed ...
If Not Application("RequireTermsAcceptance") Then
Response.Redirect(redirectURL)
Else
response.Write("<script>$(function () {displayTerms();});</script>")
End If
... and this worked by calling a Javascript function on login.asp
<script>
function displayTerms() {
//open Dialog box here
}
</script>
The Dialog box has two buttons ... one which passes them to the next page upon agreement, or the other which returns them to login.asp.
However, the new setup doesn't want to go to the function properly any longer.
There are several possible reasons for this ...
using a newer version of jquery ui ... jqueryui/1.8.8/jquery-ui.min.js - on the old ... jquery-ui-1.8.16.custom.min.js on the new.
The old one didn't build the jquery UI dialog box until you called the displayTerms function. The new one builds the jquery UI dialog in $(document).ready(function () but is hidden until the displayTerms function is called.
The displayTerms function is in the wrong location. Currently on the new version it's inside the $(document).ready(function () section. But I'm not sure that's the correct location.
I'm not familiar enough with javascript syntax to know how the call to the displayTerms function needs to change, but it still needs to be in a response.Write I believe.
Currently, the code executes all the way through, but when it gets to the response.Write that should call the displayTerms function, it hits it, passes it and then simply reloads the login.asp page.
Any Suggestions on how this should work would be appreciated.
If you need any further detail, please let me know and I'll be happy to provide it.
Try moving <!-- '#include file="../includes/logincode.asp"--> after the $(document).ready(function () { ... });

Attaching a callback to html generated by JSF - Primefaces

I've got a Primefaces command button that I need to add a callback to in jQuery on document.ready. Basically what I've been trying to do is get a reference to the existing function and then call it in a new function that I wrote:
var existingFunction = jQuery("[id~='submit']").live("click");
jQuery("[id~='submit']").live("click", function(){
existingFunction();
alert('test');
updateControlPanel(buildControlPanelUrl(getUrlVars()));
});
It seems simple enough to me but for some reason this will not work. When I load the page and click the submit button it doesn't even reach the alert.
I've checked the error console and found that it's throwing the following errors:
((f.event.special[s.origType] || {}).handle || s.handler).apply is not a function
There is existing jQuery functions on the page that I did not write but I'd like to make sure this error is not related to the way I'm approaching this.
I'm using tomcat 6 with an older version of JQuery (1.3 or 1.4 ).
Thanks and let me know if you guys need any more info.
Edit
I've put up an example of what I'm trying to do on JS Fiddle: http://jsfiddle.net/anSXH/2/
Here is some further clarification:
I've built the button as a project in JSF 2.0 (MyFaces) using the latest Primefaces component library. I've then taken that button and embedded it into an existing web page. The button submits the form and then calls a JavaScript function to show the result on the page after an ajax request is complete. This all works when I embed the button onto the page but I now need to update something on the client side after the button calls the function. That's why I'm looking at adding a callback to the existing onclick function.
As a side note, because I'm using Primefaces I can attach a JavaScript function to run after the ajax request is complete. My plan B is to try and access this function and somehow override it.
Edit part 2
Here is the generated control from primefaces:
<button
id="topsaveform:submittop"
name="topsaveform:submittop"
class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
onclick="PrimeFaces.ab({source:'topsaveform:submittop',process:'topsaveform OEIMeasurementsTable',update:'errorMessages submittedPopup',onstart:function(cfg){jQuery('#loadingBar').show('fast');;},oncomplete:function(xhr,status,args){postSubmit();;}});return false;"
type="submit">
<span class="ui-button-text">Save</span>
</button>
Did you try making the original function die (ref)?
jQuery("[id~='submit']").die("click");
jQuery("[id~='submit']").live("click", function(){
alert('test');
updateControlPanel(buildControlPanelUrl(getUrlVars()));
});
The problem was that I was trying to do this with a primefaces button. When I switched to a standard JSF button I was able to affix the function to it no problem.

Call an already defined .onClick() function from jQuery

I created some ajax paginated comments in WordPress. Unfortunately, if the user had clicked on the reply button and then goes about to click on another comment page, the Comment Form vanishes into thin air.
Anyways, simple question: Triggering the "Cancel Reply" function from my code each time the user clicks on a new ajax page would effectively solve the problem by causing the form to jump back to the original position.
How can I trigger cancel.onclick() from my own code easily? I was going to just duplicate commands and create a new function, but thought there might be an easier way to save a few bytes!
Here's the source code:
http://core.trac.wordpress.org/browser/trunk/wp-includes/js/comment-reply.dev.js
Try something like this:
$('#id_of_your_cancel_button').click();
// same thing as $('#id_of_your_cancel_button').trigger('click');
If the "cancel" logic is to be used in multiple contexts, perhaps it would be best if it lives in its own named function declaration, rather than the anonymous function expression as in your example. This would give you the option of doing something like this:
function myCancelCode(){
do_stuff();
}
Then in your addComment object:
cancel.onclick = myCancelCode;
and from anywhere else:
if( somethingHappens ){
myCancelCode();
}

Categories