I am creating a timer application for Microsoft CRM. I created the application as a web resource already and it works. It uses CRM's XRM client-side code to do the work. It needs to update data in a custom entity within CRM. However requirements for the timer application have changed and it now needs to stay active even if the user navigates away from the page. So it needs to open on the incident form, but then the user could navigate anywhere else in CRM and it needs to stay open and actively tracking time.
My first thought was to just pop the web resource into a new and separate window on the button click and have it run independently. However, if the code is embedded inside a web resource in the form, if they navigate away won't the code get unloaded?
I have only been working with Microsoft CRM for a few months, so I probably don't know all the options.
So the specific question:
Is it possible to open up a stand-alone web resource in a new window that stays active when they navigate away from the form and still have access to the XRM client library? (if so, how?)
If the answer is no, then I'd love to hear alternative ideas.
Thank You.
To solve this scenario I used 2 web resources. One on the form that has a custom button to gather required case information and send it to the second web resource:
// Collect fields we know exist at this point, because they are required fields on the case
var caseId = window.parent.Xrm.Page.data.entity.getId();
if (caseId != '') {
var caseName = window.parent.Xrm.Page.data.entity.getPrimaryAttributeValue();
var accountId = window.parent.Xrm.Page.getAttribute("customerid").getValue()[0].id;
var accountName = window.parent.Xrm.Page.getAttribute("customerid").getValue()[0].name;
// package paramters to pass to timer web resource
var customParameters = encodeURIComponent("caseid=" + caseId + "&casename=" + caseName + "&accountid=" + accountId + "&accountname=" + accountName);
// Open web resource
window.parent.Xrm.Utility.openWebResource("sp_casetimer", customParameters, 500, 200);
} else {
// Error message would go here - case must be saved first.
}
The sp_casetimer web resource then parses and stores the variables into hidden fields and can function independently. I use the /XRMServices/2011/OrganizationData.svc to then do CRUD operations on my custom case time entity.
Related
We are a social start-up and are given a great opportunity by one of the biggest banks in our country. Basically they will feature our website in their Mobile App, and users can access our website via their app in an iFrame. We are currently working on integrating a SSO log in flow between their app and our website, so users are logged in immediately when they open our website in their app.
For this, they have created an API that we're able to use. The API requires 2 main things to get the flow working:
send a pageLoaded() event when the DOM is ready, when this event is sent, we get returned a token to fetch the user's personal information with a public event.
send a pageReady() event when the backend logic processing is done (eg account created and user logged in).
They will show a spinner in their app, until the pageReady event is being sent to them.
My website uses PHP and JS (jQuery) as the main technologies. I am having a number of issues on how to implement this correctly.
This is the code I am using as of now, it works in a certain way, but it's very troublesome for the reasons mentioned below the code snippet:
$(document).ready(function(){
var getUrl = window.location;
var baseUrl = getUrl.protocol + "//" + getUrl.host;
/*** Mobile App JS Code ***/
var receiver = new PostmessageExternalReceiver();
var sender = new PostmessageExternalSender();
receiver.addTokenEventListener(function (api, token, version){
if (api == 'init') {
$.ajax({
type: 'post',
cache: false,
url: baseUrl + '/login/abc/abcLogin',
data: {
'token': token
},
dataType: 'json',
success: function(response){
sender.pageReady();
window.location.replace(response.redirect_url);
}
});
}
});
sender.pageLoaded();
});
These are the problems that i'm not sure how to get around:
Since the sender.pageLoaded(); is in the jQuery document ready, and after performing the AJAX request, we are redirecting again to the same page (the homepage), because after the redirect, the user will be logged in and some extra blocks will show on the homepage. So if we are on the homepage again, the document ready will fire yet another sender.pageLoaded() event, and we are stuck in an infinite redirecting loop.
Right now I am including all 4 API javascript libraries provided by our third party, and my own javascript file including the AJAX request and the pageLoaded() and pageReady(). This is only applicable for users that come to our website via the 3rd party mobile app. For all other visitors in our website this is not applicable and requires extra resources to be loaded in when they're not used. (the ajax request will never be executed for them because a token will not be sent via the mobile app, but still we do not want to send a pageLoaded() for every visitor on our website, even if he is not from the mobile app.
This is a nice-to-have question: since we need to send the pageReady() after our PHP logic (via AJAX request) is done, we cannot do the redirect in PHP, so I return the redirect_url in my AJAX and then do the window.location.replace() method with the redirect URL. In the 3rd party app, this will cause the app to remove the spinner (on the pageReady() event) and show our website, but immediately afterwards we will redirect the user using the window.location.replace() , this causes a refresh of the page, and thus a small annoyance and not so smooth experience for the user. They expect after the spinner is gone that the website is immediately accessible. How would I go around this?
Thanks a lot in advance!
Bit of an odd predicament. Some of the users of an interactive course I'm building will have the local Outlook application, and some will be using the Webmail version. I've managed to get the code working for passing variable values into the To, Subject, and Body fields for both, however, I'd like a way to get it to figure out which one the user has. And before you ask, yes every user will only have one or the other.
Sample here so you can see what I'm working with. This is the first of two, the second is nearly identical, except the mailto command and its counterparts are different for the Webmail application.
var LearnerEmail = window.cpAPIInterface.getVariableValue("LearnerEmail");
var TLemail = window.cpAPIInterface.getVariableValue("TLemail");
var subject = window.cpAPIInterface.getVariableValue("subject");
var EmailBody = window.cpAPIInterface.getVariableValue("EmailBody")
window.location.href = "mailto:" + LearnerEmail + "; " + TLemail + "?subject=" + subject + "&Body=" + EmailBody;
I'm fully aware that the browser does not have access to all of the local system's directory unless the user installs a custom extension of some kind (this problem isn't worth all of that work, however) so to my knowledge, there's no way to check the system for the
What I'm interested in is trying to open the local Outlook app first, then if nothing happens after a short delay, running the code the Webmail application instead. Is there a way to get javascript to verify that the mailto command went through or not, or a way to see if the system has successfully opened the application or not? If so, would it be possible to set up a function that will run the local command first, then switch to the other in a reliable way?
I have multipage application and I need to check if user was alredy open an app in other browser tab or in other browser window (IE8) and avoid this (logout user in opened new window/tab)
I use JSP, JavaScript and jQuery
If its real - not to use sessionStorage
EDITED
I also use iframes and IE8 modal dialogs.
You'd need to use a technology like SignalR that keeps a connection open. Then you'd need to ping the connections to see if that user is connected and close out their existing connection. If that implementation is too daunting, you can add a timer loop to your app/page that calls the logins table (or whatever storage device for these events) and if there are new logins, calls its own logout procedure.
One approach would be to maintain a map (in memory or in db based on user count) in your application scope which stores username vs session-id. On every login, you lookup in this map if already a session exist for that username. If exist, invalidate existing session, else store the new session-id in map. [not tested]
you can pass the the user session id or random generated id to global/window variable, ie;
window.state = 'SomeLoginIdString';
keep the state in some other variable where you client pages can easily access, preferably a datastore on client.
var loginAccessCurrentState = 'SomeLoginIdString';
When use open/switch pages compare both, if it false you can redirect to a 404 page.
loginAccessCurrentState === window.state
The idea is you only pass the state during login session, if user open a new tab, the state is undefined by default.
For single page applications the following way could be an easy solution:
Create a random ID on the entry page, store it in the session and in the GUI
On each Ajax call add the random ID to the request as additional HTTP header
if the ID does not match between given header and session, the application was opened in another tab/window and this call is coming from the "old" tab
the resulting answer of the server must then lead the GUI to lock / close itself in the affected tab
Im not sure how to explain my problem in short at the title, so forgive me for this. Lets say I opened my website in some random page, and I have a register button. Really simple, but in my case I require the registration form to appear in other tab(or window). Not "RederPartial", nor popup window of some kind, legit new tab. The problem is, I want to be able do detect, from that random page of mine, when the registration completed (ie a new user has been created). How can I pass this information? without reloading the first page
There are various ways to make two windows talk with each other (through server, with cookies, using FileSystem API or Local Storage.
Locale Storage is by far the easiest way to talk between two windows who come from the same domain, but it is not supported in older browsers. Since you need to contact the server anyway to find out when someone has registered, I recommend using the server (Ajax//web sockets).
Here's a somewhat simple AJAX solution which you could use in your random page:
(function(){
var formOpened = false;
var registered = false;
//Change to whatever interaction is needed to open the form
$('#registerbutton').on('click', function(){
if (!formOpened){
formOpened = true;
//Will try to poll the server every 3 seconds
(function pollServer(){
$.ajax({
url: "/ajax/pollregistered",
type: "GET",
success: function(data) {
if (data.registered){
registered = true;
//do other stuff here that is needed after registration
}
},
dataType: "json",
complete: setTimeout(function() {if (!registered) pollServer();}, 3000),
//will timeout if request takes longer than 2 seconds
timeout: 2000,
})
})();
//opens the new tab
var win = window.open('/registrationform', '_blank');
win.focus();
}
});
})();
You can then use the session key of the visitor in the '/ajax/pollregistered' action to write your backend code to check if and when this visitor registered as user to your site.
If you don't mind using the local storage, you could poll the storage instead of the server and have the registration page write to local storage upon registration. This is less stressing for your server, but might not work for users with ancient browsers.
Also worth nothing that this method of opening a new tab is not completely reliable. Technically there is not a sure shot way of opening a new tab with javascript. It depends on browser and the preferences of the user. Opening a new tab might get blocked for users who are using anti popup plugins.
That being said, I strongly recommend revising your design and try finding a way to work with just one window instead. It's probably better for both yourself and your users.
I'm working with an old intranet site written in classic ASP. I'm trying to retrieve their username they logged into their machine with. Each user is logged into AD, but I can't retrieve it from the server since the intranet site does not use AD.
I was told I could use ActiveX in order to retrieve it. I did some research and I found the following code (javascript):
var wshshell = new ActiveXObject("WScript.shell");
var username = wshshell.ExpandEnvironmentalStrings("%username%");
Currently I'm using IE8 and I get an "Automation server can't create object" error on that first line.
1) Any ideas why I'm getting the error?
2) Is there a better way to be doing this given my limitations?
If this is done client-side, then you must have the user add the site to the Trusted Sites zone and set the security level to the lowest. Line 1 should work server-side, but I don't think line 2 is right.
Try this
var net = new ActiveXObject ( "WScript.NetWork" );
var username = net.UserName;
Basically, its impossible to retrieve client's Windows machine information using Javascript.
Because its scope is upto browser only.
For doing so you need to create COM object or say an Activex object, and using ASPX page you need to deploy it on Client's system at the very first time your page is accessed from a browser.
Now, ActiveX object has a featured to interact using javascript. You have to access the COM object or the class and function of the COM, which further interact with the system classes to get the system Information. i.e logged in client's windows user information.
var net = new ActiveXObject ( "WScript.NetWork" );
var username = net.UserName;
Above code is also initializing a COM object, if it is not deployed to your client system this script won't work.