i have been developing extension for sharepoint. I was trying to implement custom callout for document library (using fancytree for library content presentation).
For reference I have used https://dev.office.com/sharepoint/docs/sp-add-ins/highlight-content-and-enhance-the-functionality-of-sharepoint-hosted-sharepoint.
I have defined callout functionality in a separate function execCallout(data).
(for simplicity functionality with data is omitted).
I have two scenarious: execCallout is initiated/called by the user (no preloaded data) and execCallout is loaded with starting data. In both cases i use the same execCallout.
function execCallout (data) {
console.log("demo");
//get our launchpoint - where callout will appear
var targetElement = document.querySelectorAll(".fancytree-active.fancytree-focused .fancytree-title")[0];
//Configure new Callout
var calloutOptions = new CalloutOptions();
calloutOptions.ID = 'MyCustomCallOut';
calloutOptions.launchPoint = targetElement;
calloutOptions.beakOrientation = 'leftRight';
calloutOptions.content = ' My Content';
calloutOptions.title = 'My Title';
// check for current callout
var myCallOut = CalloutManager.createNewIfNecessary(calloutOptions);
//Create custom action for callout
var myAction = new CalloutActionOptions();
myAction.text = 'My Special Action';
myAction.onClickCallback = function(event, action)
{
alert("I can do whatever you want");
};
var newAction = new CalloutAction(myAction);
//Add the action to the callout
myCallOut.addAction(newAction);
myCallOut.set({ openOptions: { event: "hover" } }); //or click
myCallOut.open();
}
The first scenario works fine, i.e., on user click callout is initiated/execCallout is called.
However, when with preloaded data i get "Uncaught ReferenceError: myCallOut is not defined" (from debugger console i see that function was called, however calloutManager has no callout associated with my launchPoint). It looks as if the calloutManager was not initiated.
At any time initiated execCallout from debugger console fixes the problem.
Ideas what and where is missing are welcome.
My quess about the issue: the problem was caused by fancytree rendering. The callout was initiated while the "tree" was not fully rendered. By default during rendering values were "lost", therefore default tree rendering was causing problem.
Solution: manually initiated tree rendering prior to callout operations, so that no values/variables were gone.
Related
I am facing an issue in CRM, the bug is when I create an appointment and try to save it, the commandBar go invisible after the load of the created record of the appointment. I try to inspect the javascript associated code but there is no hint about the source of the problem, I should say that after refreshing the page of the created page the command bar become visible.
OnSave: function (e) {
EOZ.Appointment.SetPivotalId();
var eventArgs = e.getEventArgs();
if (Xrm.Page.ui.getFormType() == 1 && eventArgs.getSaveMode() == 1 && !saveAndClose) {
Xrm.Page.getAttribute("createdon").addOnChange(EOZ.Appointment.CreatedOnChanged);
}
else {
saveAndClose = true;
Xrm.Page.getAttribute("createdon").removeOnChange(EOZ.Appointment.CreatedOnChanged);
}
},
CreatedOnChanged : function () {
var id = Xrm.Page.data.entity.getId();
setTimeout(function () {
Xrm.Utility.openEntityForm("appointment", id);
}, 500);
}
NB : After a lot of javascript debugging, i noticed that the problem is only happened when the method "CreatedOnChanged" is called more than once, in the other hand if it's called just once the command bar is visible. I don't know if it's the source of the bug, but it is the only difference in the code's behaviour.
Edit :
Dynamics CRM 2013, Browser : Google chrome latest version on 03/03/2017
I modified my code to be like :
CreatedOnChanged : function () {
if(!isCalled){
var id = Xrm.Page.data.entity.getId();
setTimeout(function () {
Xrm.Utility.openEntityForm("appointment", id);
}, 500);
isCalled = true;
}
}
The method "CreatedOnChanged" is called multible times but its content is executed just once, and the command bar is displayed correctly ... But really i don't why when this method is executed multiple times, the command bar become hidden.
It look to me like you are trying to refresh the page after a save.
Rather than trying to reopen the form I think that forcing a refresh may be more correct:
Xrm.Page.data.refresh(true);
I think that you code around registering the event on the OnCreate() event is probably causing an error. The ribbon automatically refreshes after a save (so any visibility / enabling conditions or javascript can be retested.
A JavaScript error on the page would potentially cause the JavaScript re-rendering the ribbon to fail.
I have a video streaming app I'm working on that lets me select a year of videos from a listTemplate, where each year is then a catalogTemplate with links to video resources. Navigation between the listTemplate and catalogTemplate works fine, but when I select a video from one of the catalogTemplates, the video plays behind the template, rather than going to the foreground. How can I fix what I presume is a navigation stack error like this? Below is the code I use to actually present stuff, taken partly from Apple's documentation.
load: function(event) {
console.log(event);
var self = this,
ele = event.target,
templateURL = ele.getAttribute("template"),
presentation = ele.getAttribute("presentation"),
videoURL = ele.getAttribute("videoURL");
if(videoURL) {
//2
var player = new Player();
var playlist = new Playlist();
var mediaItem = new MediaItem("video", videoURL);
player.playlist = playlist;
player.playlist.push(mediaItem);
player.present();
};
/*
Check if the selected element has a 'template' attribute. If it does then we begin
the process to present the template to the user.
*/
if (templateURL) {
/*
Whenever a user action is taken you need to visually indicate to the user that
you are processing their action. When a users action indicates that a new document
should be presented you should first present a loadingIndicator. This will provide
the user feedback if the app is taking a long time loading the data or the next
document.
*/
self.showLoadingIndicator(presentation);
/*
Here we are retrieving the template listed in the templateURL property.
*/
resourceLoader.loadResource(templateURL,
function(resource) {
if (resource) {
/*
The XML template must be turned into a DOMDocument in order to be
presented to the user. See the implementation of makeDocument below.
*/
var doc = self.makeDocument(resource);
/*
Event listeners are used to handle and process user actions or events. Listeners
can be added to the document or to each element. Events are bubbled up through the
DOM heirarchy and can be handled or cancelled at at any point.
Listeners can be added before or after the document has been presented.
For a complete list of available events, see the TVMLKit DOM Documentation.
*/
doc.addEventListener("select", self.load.bind(self));
// doc.addEventListener("highlight", self.load.bind(self));
/*
This is a convenience implementation for choosing the appropriate method to
present the document.
*/
if (self[presentation] instanceof Function) {
self[presentation].call(self, doc, ele);
} else {
self.defaultPresenter.call(self, doc);
}
}
}
);
}
},
One idea: templateURL is still pointing to a valid address, thus the lower portion of your shown function will directly add an overlay to your video?
Verify (or make sure) to have only one of the two options (videoURL, templateURL) set. Or only run the loadResource() part if no videoURL was seen before. Like...
if(videoURL) {
...
} else if (templateURL) {
...
}
I have isolated the issue, see and try the full source here.
Steps to reproduce:
Press Ctrl+Enter to run the snippet
Click on 'Say Hello' custom command button, and check if the event
handler runs
Click on top left 'Save State' button
Click on 'Load State' button, and restore the previous state.
Now click again on 'Say Hello' button and demonstrate the event handle will not run, instead something weird is happening.
Notes: Please do not search for the solution around the localStorage. The issue can be reproduced by using different server side state persisting solution. (as my original app does)
Any idea where to patch? ... or workaround?
Hopefully this will help you out.
http://dojo.telerik.com/EDUCO/4
I have added the following piece of code for you:
dataBound: function (e) {
$(".k-grid-SayHello").on('click', function (a) {
console.log(e);
a.preventDefault();
alert('Hello');
});
},
When the rebind occurs I suspect that it is losing the connection to the event handler so all I have done if looked for the button based on it's class name and reattached it.
Obviously you can adapt the solution to meet your needs but this is something I do for my projects when I need to "invoke" custom actions on buttons/ dynamically create things on the fly.
Any issues let me know.
To keep function references after calling grid.setOptions()
I added the function references back to the deserialized configuration object before passing it to the setOptions method.
( http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#methods-setOptions )
$(document).ready(function () {
var grid = $("#myGrid").data("kendoGrid");
var originalOptions = grid.getOptions();
var savedOptions = JSON.parse(localStorage["myGrid-options"]);
if (savedOptions) {
var detaylarFunc = originalOptions.columns[3].command[0].click;
savedOptions.columns[3].command[0].click = detaylarFunc;
grid.setOptions(savedOptions);
} else {
grid.dataSource.read();
}
});
//Custom command
function Detaylar(e) {
e.preventDefault();
var grid = $("#myGrid").data("kendoGrid");
options = grid.getOptions();
localStorage["myGrid-options"] = kendo.stringify(grid.getOptions());
}
References: https://developer.chrome.com/apps/notifications
I am using the chrome.notifications.create(string id, object options, function callback); to create a chrome notification.
var id = 'list';
var options = {};
options.title = 'test';
options.iconUrl = 'notification_icon.png';
options.type = 'list';
options.message = "test";
options.buttons = [{title: 'test'}];
options.items = [{title: 'test', message:'test'}];
var createCallback = function(notificationId) { console.log(notificationId); };
chrome.notifications.create(id, options, createCallback); // returns 'list';
This creates a notification as expected. All working correctly.
I then call chrome.notification.clear(string id, function callback);
var id = 'list';
var clearCallback= function(wasCleared) { console.log(wasCleared); };
chrome.notification.clear(id, clearCallback); // returns true;
This does clear the notification. All working correctly.
EXCEPT it does not clear the notification out if the notification panel is open. This is not a major problem 99% of the time. Until I implemented the button code within the notification.
Using chrome.notifications.onButtonClicked.addListener(function callback); On click I am calling the clear notification panel code, and it reports back as it has been cleared.
var onButtonClickedCallback = function (notificationId, buttonIndex) {
console.log(notificationId, buttonIndex);
if ( notificationId == 'list' ) {
chrome.notification.clear(id, clearCallback); // returns true;
}
}
chrome.notifications.onButtonClicked.addListener(onButtonClickedCallback); // onClick it returns 'list', 0
But I am looking right at it.. Once the notification panel closes and opens again, I can confirm it has actually gone. But obviously since I am clicking a button on the notification, the panel is open, but it does not clear away as I would have liked.
All this is running in an extension background without the persistence: false property (so the script is always loaded, and since I can see the output, I know the functions are being called).
Have I overlooked something? I do not see any functions that deal with closing the notification panel. So as far as I can tell, I am clearing the notification but the panel is not updating it's display.
I am using Chrome 37.0.2019.0 canary on Win8
If anyone can suggest something I may have missed, I would be greatful. My google searches reveal people having problems with the HTML notification.
This is a known bug, or rather an old design decision, with little progress.
Star the issue to raise its priority. I also suffer from the same.
Here's the workaround solution I've been using for several months now:
// open a window to take focus away from notification and there it will close automatically
function openTemporaryWindowToRemoveFocus() {
var win = window.open("about:blank", "emptyWindow", "width=1, height=1, top=-500, left=-500");
win.close();
}
chrome.notifications.clear("", function(wasCleared) {
openTemporaryWindowToRemoveFocus()
});
I'm having troubles with my flyout. What happens with my gadget is you double click a component and it will have a corresponding flyout window. If you double click that or any other visual component with a flyout, though, the flyout document is returned as null. I have no idea why this is, and if you make the flyout go away and reopen it or a new one it's ok. It's only when a flyout is already opened this happens. I'm looking for some ideas on why this is.
Double click code:
Blah.prototype.ondblclick = function()
{
var me = this.parent;
if (System.Gadget.Flyout.show)
{
// flyout is already shown, make sure it shows our stuff
System.Gadget.Flyout.file = FLYOUT_FILE;
onFlyoutShow();
}
else
{
System.Gadget.Flyout.file = FLYOUT_FILE;
System.Gadget.Flyout.onShow = onFlyoutShow;
System.Gadget.Flyout.show = true;
}
System.Gadget.Flyout.onHide = onFlyoutHide;
function onFlyoutShow()
{
me.flyoutOpen = true;
me.updateFlyout();
}
function onFlyoutHide()
{
me.flyoutOpen = false;
}
};
Executed code:
Blah.prototype.updateFlyout = function ()
{
var flyoutDoc = System.Gadget.Flyout.document;
//flyoutDoc is null at this point
var info = flyoutDoc.getElementById("info");
info.innerHTML = "info: " + this.information;
//Error thrown: 'null' is null or not an object
}
I don't know a lot about writing gadgets for windows 7, but to me it looks a lot like a timing issue. When the flyout is already there, you change the file property which tells it to load a new file. Without waiting you then call onFlyoutShow which tries to get the document and the document isn't loaded yet.
My first thought is: Doesn't the onShow event fire when you set the file? Probably doesn't or you wouldn't have the if, but worth verifying.
If that doesn't work, calling onFlyoutShow in a timeout. Start with a long timer, like 1000. And then shorten it, hopefully you can get down to 0: setTimeout(onFlyoutShow, 0);