Tweak CRM Sitemap to have different URL navigations for different environments - javascript

We want to have different Sitemap subarea Url, so that the Sitemap can be independent of environments & worryfree when we refresh the environments from higher region to lower. Even deployments can be error free & can avoid manual step in post deployment activity.
Dev:
<SubArea Id="nav_hub" ResourceId="Hub_SubArea_Title" DescriptionResourceId="Hub_SubArea_Description"
ToolTipResourseId="Hub_SubArea_ToolTip" Icon="/_imgs/Hub_32.png"
Url="http://mydevhub.com/home.aspx" AvailableOffline="false" />
UAT:
<SubArea Id="nav_hub" ResourceId="Hub_SubArea_Title" DescriptionResourceId="Hub_SubArea_Description"
ToolTipResourseId="Hub_SubArea_ToolTip" Icon="/_imgs/Hub_32.png"
Url="http://myuathub.com/home.aspx" AvailableOffline="false" />
Any idea to do that?

I ended up doing this workaround as we cannot pass dynamic variable url to Sitemap.
1.Created a Sub-Area with url to custom HTML web resource as below:
$webresource:pub/Scripts/External/navigation.html
2.Just used the below content to open a new window based on org url:
<html><head>
<script src="../../../ClientGlobalContext.js.aspx" type="text/javascript"></script>
<script language="javascript">
var crmUrl = parent.Xrm.Page.context.getClientUrl();
if (crmUrl.indexOf('devinstance.crm.dynamics.com') > 0)
parent.window.open('http://mydevhub.com/home.aspx');
if (crmUrl.indexOf('uatinstance.crm.dynamics.com') > 0)
parent.window.open('http://myuathub.com/home.aspx');
</script>
</head><body>
</body></html>

In case anyone else lands here (and since I can't comment yet) the answer provided is deprecated.
The newer way of achieving this is
var globalContext = Xrm.Utility.getGlobalContext();
globalContext.getClientUrl();
(Source)

Related

Google AMP and custom Javascript

According to the docs, all I need to do is to wrap the block I'd like to "talk to" via Javascript with this:
<amp-script layout="container" src="language-toggle.js">
// Some basic HTML
</amp-script>
The Javascript file is there, I tested with a simple console.log. Yet the amp-script tag has opacity: 0.7 (AMP default style). Apparently, it needs the class i-amphtml-hydrated to be fully visible. I've been trying to wrap my head around this for a few hours now, even Google could not help me with this.
There are a bunch of ServiceWorker errors in the console, which are also all generated by AMP. I have no idea why they appear or how to get rid of them. This whole AMP thing is a mess for me.
These are the AMP scripts I currently added:
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-script" src="https://cdn.ampproject.org/v0/amp-script-0.1.js"></script>
<script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script>
<script async custom-element="amp-youtube" src="https://cdn.ampproject.org/v0/amp-youtube-0.1.js"></script>
Carousel and YouTube are working fine.
Could anybody please shed some light onto this?
I highly recommend to enable AMP development mode by adding #development=1 to the URL.
Relative URL's are not allowed in the src attribute of the amp-script tag (the development parameter would have told you that).
You can have something like this though:
<amp-script width="1" height="1" script="demo"></amp-script>
<script type="text/plain" target="amp-script" id="demo">
console.log('Foobar');
</script>
But you will need a matching hash in a meta tag in your head:
<head>
...
<meta
name="amp-script-src"
content="sha384-hash"
/>
</head>
Again, the development parameter will tell you the hash you should use, although you could also disable hash checks during development.
All of the above will still not hydrate your amp-script element. In order for your element to be hydrated, the script has to actually to something to the DOM, like for example adding a div on a button click:
<amp-script layout="container" script="demo">
<button id="hello">Add headline</button>
</amp-script>
<script type="text/plain" target="amp-script" id="demo">
console.log('Foobar');
const button = document.getElementById('hello');
button.addEventListener('click', () => {
const h1 = document.createElement('h1');
h1.textContent = 'Hello World!';
document.body.appendChild(h1);
});
</script>
Be aware that you are quite limited with what you are allowed to do. For example, the above snippet will not work without the event listener, so you can not simply add an element without user interaction.
The messages regarding the references can safely be ignored - the AMP examples do exaclty the same, the AMP still passes the validation.

Downloading jquery library to project Error:java: Illegal char <:> at index 4: http:\api.jquery.com

I use Intellij Idea. I want to download jquery library to have access offline to it in Intellij Idea in my Spring Project. So I typed "Alt + enter" on the link
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
and chose "Download library".
The library has dowloaded, and the problem is that after it I can't run my program, because all the time I see
Error:java: Illegal char <:> at index 4: http:\api.jquery.com
without any path. I have't even have something like written in my whole project.
When I had just global link to "https://code.jquery.com/jquery-1.12.4.min.js" and had internet access all worked properly.
I tried to download library in local file and put in header link to it actually after deleting library from intellij. But still don't working.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
</head>
<body>
<input type="number" id="myInput" name="myInput" onchange="countOfTryings(this)">
<a name="toChallenge" href="http://some_web_site.com?parameter1=4">This is link</a>
<a name="toChallenge" href="http://some_web_site_other.com?parameter1=4">This is link 2</a>
<script>
function countOfTryings(variable) {
$('a[name="toChallenge"]').each(function () {
var oldUrl = $(this).attr("href"); // Get current url
var str = oldUrl.substring(0, oldUrl.indexOf("parameter1"));
var newUrl = oldUrl.replace(oldUrl, str + "parameter1=" + variable.value); // Create new url
$(this).attr("href", newUrl); // Set herf value
});
}
</script>
</body>
</html>
I want my program to change the urls of hyperlinks with name="toChallenge". To change the value of the request parameter "parameter1" to new value, what will be in input with id="myInput".
After submiting a report to Intellij Idea I got an answer, that JS libraries are added to the Java classpath which is a bug, and to fix thit problem I need to do next:
Project settings (ctrl+alt+shift+s by default) -> Modules -> in "Modules" select "Dependencies" -> find jquery dependency -> delete jquery dependency -> click "apply"
I had same problem but deleting dependency did not help. I had to go to global libraries and delete jquery library as well.
[ctrl+alt+shift+s] -> Modules -> Dependencies -> delete jquery dependency
maven -> reload all maven projects
As both Jan and Odeta point out in their answers, this can be fixed by deleting the dependency in the module and global library. However, I think I can refine this a little further. When I looked under the global library, I found there was both the released artifact and a link to the documentation. If you delete the documentation reference, it should fix the problem and the dependency can remain.

how to display a rally "custom board" dashboard in confluence wiki

I have been digging in the this site and others for several days and the answer to my problem still escapes me.
I have read all of these pages:
http://pastebin.com/cbagkw8h
but none of them exactly answers this question:
I am trying to get a Rally Dashboard (custom board) to appear in HTML/Javascript in a confluence wiki. I have gotten a simple Standard Report working using a read-only account and AppSDK1.32 with loginKey by embedding the following HTML/Javascript into the Confluence wiki page:
{html}
<meta name="Name" content="App Example: Rally Application" />
<meta name="Version" content="2011.04" />
<meta name="Vendor" content="Rally Software" />
<script type="text/javascript"
src="https://rally1.rallydev.com/apps/1.32/sdk.js?loginKey=loginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkey">
</script>
<script type="text/javascript">
function onLoad() {
var rallyDataSource = new rally.sdk.data.RallyDataSource(
'__WORKSPACE_OID__',
'__PROJECT_OID__',
'__PROJECT_SCOPING_UP__',
'__PROJECT_SCOPING_DOWN__');
rally.sdk.ui.AppHeader.destroy();
var reportConfig = {report: rally.sdk.ui.StandardReport.IterationBurndown,
width : 400, height: 300};
var report = new rally.sdk.ui.StandardReport(reportConfig);
report.display("reportDiv");
}
rally.addOnLoad(onLoad);
</script>
<div id="reportDiv" style="width: 400px; margin-left:20px"></div>
<br/>
{html}
I am trying to expand this success to an entire dashboard with App SDK2.x using the new apiKey - by using the following code:
{html}
<meta name="Name" content="App Example: Rally Application" />
<meta name="Version" content="2015.04" />
<meta name="Vendor" content="eBay Enterprise" />
<script type="text/javascript"
src="https://loginapirally1.rallydev.com/apps/1.32/sdk.js?loginKey=loginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkeyloginkey">
</script>
<script type="text/javascript">
function onLoad() {
rally.sdk.ui.AppHeader.destroy();
document.getElementById("iframeA").width = screen.width - 60 ;
document.getElementById("iframeA").height = (screen.width - 60 ) * 3;
}
rally.addOnLoad(onLoad);
</script>
<iframe id="iframeA" src="https://loginapirally1.rallydev.com/#/111111111d/custom/222222222?expandApp=333333333&apiKey=_apikeyapikeyapikeyapikeyapikeyapikeyapikey" width="1024" height="1024">
</iframe>
<br/>
{html}
I am noticing a few things:
1) it almost works - I get the dashboard/report title but not the cards
2) the apiKey seems to have no affect at all - I still get prompted for a login and password (which I could stand if I could see the cards).
3) it doesn't seem to matter if I put the apiKey before or after the hash symbol
Citation A suggested using the "full screen" dashboard/report but didn't cover the apiKey.
Citaton B says that the AppSDK2 uses the apiKey as of Apr 14 2014 but doesn't say how to use it exactly with AppSDK2.
I have gotten the apiKey to work with the Ruby API but it is unclear how to access the dashboard/reports from there.
Citation C says that the AppSDK1 is based on the Javascript dojo framework and the AppSDK2 is based on the Javascript Sencha's ExtJS but avoids giving any kind of rosetta stone from one to the other.
The only other options I can think of is to 1) copy the entire HTML page-source from the "Custom Board" and then start debugging the Javascript with ExtJS (but I cannot find an example of where to put the apiKey for ExtJS) or 2) bypass all of the APIs and use Ruby Watir-Webdriver (which uses
Selenium) and VNCServer to clip an image of the "Custom Board" page and show THAT in confluence.
Citations: http://pastebin.com/YMUEPjSF
The issue seems to be specific to the canned Custom Board that cannot be loaded externally. It should work if you write a js source code to build a similar Board and compile that into a deployment html. That is similar to option (1) you mentioned in the end of your post if I understand it correctly.
Here is my test where I compared Custom Board and Custom HTML side by side.
Below is a screenshot from Rally. This custom dashboard has Custom Board on the left and Custom HTML on the right. The Custom HTML is using a code example of filterable board from AppSDK2 documentation.
Next I use this code:
<html>
<head>
<title>Custom Grid</title>
<meta name="Name" content="App: Custom Dashboard"/>
<meta name="Version" content="2011.08.31"/>
<meta name="Vendor" content="Rally Labs, NickM"/>
<script type="text/javascript" src="https://rally1.rallydev.com/apps/1.32/sdk.js?loginKey=c33e83...."></script>
<script type="text/javascript">
rally.addOnLoad(function() {
var iframe = document.createElement("iframe");
iframe.src = "https://loginapirally1.rallydev.com/#/14018981229/custom/34207853894"
iframe.width = 2000;
iframe.height = 1000;
document.getElementById("storyboard").appendChild(iframe);
});
</script>
</head>
<body>
<div id="storyboard"></div>
</body>
</html>
Here is the dashboard loaded externally on localhost:3000. The left column of the dashboard where Custom Board is expected to load is empty, but the right column with a custom html code of a board loads successfully:
It looks like the canned Custom Board cannot be loaded externally but a custom html code written in AppSDK2 can be displayed externally.
A couple of observations:
There is really no upgrade path from AppSDK1 to AppSDK2. The underlying frameworks and the class structures are very different and the code cannot be simply refactored. There is no translation from one to the other.
LoginKey is intended to work with AppSDK1. Both are legacy. Both predate AppSDK2 and ApiKey. To use ApiKey with custom html apps written with AppSDK2 see "Use API Key with AppSDK2" article.
AppSDK2 does not support LoginKey usage for authentication. The reason it seems to work in this example is that we load the entire page. Loading the entire page using iframe's src property is possible with LoginKey. In this example there is no reason to use ApiKey and LoginKey together. You are right that ApiKey makes no difference in this use case.
The way LoginKey works is that it "tricks" the browser into thinking that there is this different server, loginapirally1.rallydev.com. If you look in Network tab of your browser and see that request comes from there it means that LoginKey is working. ApiKey works differently. There is no equivalent to loginapirally1 server with ApiKey.
If you are being prompted to supply login credentials when using LoginKey it means that LoginKey is not working. See "LoginKey Troublshooting" article.
Embedding custom AppSDK2 apps in 3rd party portals (running custom apps externally) is possible with ApiKey, and the supported scenario described in this guide is similar to the option (1) you mentioned in the end of your post. Loading entire Rally page or entire Rallynavigation is not a supported use case even though it is possible with LoginKey.

AngularJS - simple tutorial wont work

I started out with Angular and came across this code that should work, but it doesn't.
Angular is downloaded and added via the script tag and it is correct, others tutorials worked before.
I have tried everything but just doesnt seem to find out what's the problem. Started learning from the book AngularJS from O'Reilly.
<html ng-app="nameApp">
<head>
<title>Angular Training</title>
</head>
<body ng-controller="NameCtrl">
<ul>
<li ng-repeat="name in names"> {{ name }}
remove
</li>
</ul>
<form ng-submit="addName()">
<input type="text" ng-model="enteredName">
<input type="submit" value="add">
</form>
<script src='unzipped___AngularJS-1.3.12\angular-1.3.12\angular.min.js'></script>
<script>
var nameApp = angular.module('nameApp', []);
nameApp.controller('NameCtrl', function ($scope){
$scope.names = ['Larry','Curly', 'Moe'];
$scope.addName = function(){
$scope.names.push($scope.enteredName);
$scope.enteredName = '';
};
$scope.removeName = function(name){
var i = $scope.names.indexOf(name);
$scope.names.splice(i, 1);
};
});
</script>
</body>
</html>
https://jsfiddle.net/eqk5adc1/3/
https://jsfiddle.net/5qv2e2jm/
Try adding this
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
Based on comments, it sounds like you are likely running into security issues. Modern browsers can typically prevent loading external js files from the local file system for security reasons. This is dependent on the browser you use. For more information, this security concept is called the same-origin policy.
"this is a Javascript frameworks so in my opinion a server could be omitted..."
This is not necessarily true because of the aforementioned security concept. If you are using Firefox you can disable this security feature (though I would recommend only temporarily) using the following steps:
Navigate to about:config
In the search bar type security.fileuri.strict_origin_policy
Set this property to false.
These steps should allow local js files to be loaded in Firefox. In the end, it may be easier to simply setup a server or use a cheap cloud server (google, amazon, c9.io, etc.). Another option might be just using jsfiddle like you did above.

Options to store data on desktop, using webpage

Goal:
To sum it up, I'm trying to replace an excel spreadsheet. I'm creating an application that will run in IE9, but does not connect to the internet or an intranet (I know, I know. Just bear with me. If you're curious read more below). It needs to use CRUD (create, read, update, and delete) methods on a set of data that changes daily. The dataset must persist even when the browser is closed.
Question:
What options are available, using javascript and html, for storing data on the local computer the web page is accessed on? I'm doing this at work, so there will be no server-side to this. I also will not be able to install any software on the computer, although I can download javascript plugins. The webpage will be loaded from a file on the computer, using Win 7 and IE9.
Background:
This deserves an explanation. I use an excel spreadsheet to track a set of data that changes daily. I'm learning HTML and javascript, and I can create a much better (and easier to use) solution as a webpage. I can create the UI / UX, but I'm having a difficult time figuring out how to store the data on the local computer. Any good suggestions?
Attempts:
Unfortunately, it seems localStorage is not an option. I'm attempting to use jStorage, but I've been running into problems there, also. A similar set of problems has been encountered using simpleStorage.
Thank you for considering, please let me know if any more info is needed, or if I need to clarify something.
Addendum:
Localstorage, and other forms of HTML5 storage, do not work. Officially it does, unofficially it is very buggy. See blog post here, and SO answer here. Either way, with the following simple code:
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Backlog Tracker</title>
<script src="jquery-2.1.1.min.js"></script>
<script src="backlog_localstorage.js"></script>
</head>
<body>
</body>
</html>
and javascript (ref as "backlog_localstorage.js" above):
$(document).ready(function(){
$("body").append("<button>Try It</button>");
$("button").click(function(){
localStorage.setItem("key1", "Hello");
console.log(localStorage.getItem("key1"));
});
});
... I get the following error: "SCRIPT5007: Unable to get value of the property 'setItem': object is null or undefined" on the line localStorage.setItem("key1", "Hello");
HTA (which is really just an html file with one extra tag and a different file extension) is one possible solution for windows users:
Important: Save as demo.hta to run on windows as an app
<!DOCTYPE html>
<html> <!-- some parts lifted from
http://msdn.microsoft.com/en-us/library/ms536496(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/ms536473(v=vs.85).aspx
-->
<head>
<title>State Saving Demo</title>
<hta:application id="App"
application="yes"
applicationname="demo"
icon="calc.exe"
border="thin"
caption="yes"
sysmenu="yes"
showintaskbar="yes"
singleinstance="yes"
sysmenu="no"
maximizeButton="yes"
minimizeButton="yes"
navigable="no"
scroll="yes"
contextmenu="no"
selection="no"
windowstate="normal" >
<!-- Use Internet Explorer 10 Standards mode (to use JSON, CSS3, etc...) -->
<meta http-equiv="x-ua-compatible" content="IE=10">
</head>
<body onload=loadMe() >
<h1 id=h1>Command-line args: </h1>
<h3>Persisted Text</h3>
<textarea rows=20 cols=100 id=mydata onchange=saveMe() >
You can change me and i won't forget!
</textarea>
<script>
document.title+=" - Today is " + Date(); // task/title bar demo
h1.innerHTML+= JSON.stringify( App.commandLine ); // optional invocation info here (much like a real app)
// app-specific custom code:
FILENAME="state.txt";
function saveMe(){save(FILENAME, mydata.value); }
function loadMe(){mydata.value=load(FILENAME) || mydata.value;}
// generic utils:
function load(filename) { //IE FSO file Loader
var file,
text="",
fso= new ActiveXObject('Scripting.FileSystemObject');
try{
file = fso.OpenTextFile(filename, 1, false);
text = file.readAll();
file.Close();
}catch(y){}
return text;
}
function save(filename, sData){ //IE FSO file Saver
var file,
fso = new ActiveXObject('Scripting.FileSystemObject');
file = fso.CreateTextFile(filename, 2, false);
file.write(sData);
file.Close();
return file;
}
</script>
</body>
</html>
I recently re-discovered HTAs, and they are not half bad. I don't think I would want to distribute and maintain them, but HTA's are an easy way to make simple desktop app using HTML, CSS, and JS. Its nice not to have to build anything to "recompile" the app after changes are made. saves a few steps compared to node-webkit, packaged apps, air, cordova, etc, but HTA's have a major downside: they only work on windows afaik...
Looks to me like you can use LocalStorage, the big question is how are you trying to store it? You can easily store an object/array into LocalStorage, and that object/array can be your data, then JS can output this into a table. If you're looking to store actual files then you're looking at something more like an ActiveX plugin.
http://caniuse.com/#search=localstorage
Alternatively if you have internet access through a desktop or a phone you can put this on Google Drive. This would be far easier than reinventing the wheel.

Categories