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.
Related
I'm learning javascript by creating a program which requests an API and dispays various properties (price in this example) to html. I have a few questions about my code and some problems I've been facing.
1). I have a bunch of $.getJSON functions corresponding to each value that I want to retrieve. I put them all in a a single 2 min. timer. When the page FIRST loads, however, some of the html elements fail to load at all. But if I refresh the page, they sometimes do load. If I refresh again, they might not load at all again. Every time I refresh, there's like a 10% chance of that particular function not inserting the content in the element. If it does load and I leave the page open, it will correctly function (update its value and html element every 2 mins and add/remove the green and red classes). If it doesn't load and I leave the page open, it will correctly function in 2 mins when the 2nd api request is made. I have already tested that the variables have some value (are not null) before and after each $('#price').text('$' + price);.
Here's an example of a function that does that:
var tempPrice;
var myVar = setInterval(myTimer, 1200000);
myTimer();
function myTimer() {
$.getJSON(link, function (json) {
$.each(json, function (index, value) {
if (value.id == "price") {
var price = value.price_eur;
if (!tempPrice) {
$('#price').text('$' + price);
tempPrice = parseFloat(price);
}
if (parseFloat(price) !== tempPrice) {
$('#price').text('$' + price).removeClass();
if (parseFloat(price) > tempPrice) {
setTimeout(function () {
$('#price').addClass("green");
}, 1);
} else {
setTimeout(function () {
$('#price').addClass("red");
}, 1);
}
tempPrice = parseFloat(price);
}
}
});
});
// Many more $.getJSON functions below...
}
If I run this function alone on either jsfiddle or my dev server (flask), it works fine. It only breaks down when I use it in conjunction with more api requests. If I remember correctly, I didn't have this problem before when I used to have a separate timer for each $.getJSON function and put each in its own <script> tag directly in html.
2) I know I can loop through the json instead of using $.each. How else can I improve the code?
1
As for the problem you're having with the inconsistent behavior of the initial page loading, it's because you are executing JavaScript before giving the browser the time to load the page fully first. You can solve this simply by waiting for the page the load, and then executing your code.
Example in jQuery:
$(document).ready(function() {
// Page is loaded, execute code...
});
2
To help you improve the way you're handling the supplied JSON data, a sample of the data would be useful.
I have an angular app within the ionic framework which has an encrypted database. The step of opening the database is an intensive task. (up to 6000ms on a typical device).
I have a Login button on the page which sets a flag in the controller "Data.Loading = true".
Within the on-page ng-template there is a block
<div ng-show="Data.Loading">Please Wait</div>
The code which "logs in" is as follows:
$scope.Login = function() {
if ($scope.IsCorrect($scope.Data.Password)) {
$scope.Data.Loading = true;
$scope.OpenAndContinue();
}
}
$scope.OpenAndContinue = function(){
MyDatabase.open().then(function() {
$scope.Data.Loading = false;
$rootScope.Display.Menu = true;
$ionicHistory.nextViewOptions({
disableAnimate: true,
disableBack: true,
historyRoot: true
});
$state.go("app.home")
})
}
The problem with the above is that the UI is NOT particularly responsive. On this page. In fact it is downright slow - especially compared to numerous other buttons within the app.
The view takes a second or two to update and say "please wait" then another couple seconds to actually finish opening the database.
If I accept that the core-function of opening an encrypted database is sufficiently complex as to prevent opening quickly, I would at the very least like the view to respond to a user's tap instantly in order to let them know
that the thing isn't broken.
I have tried a number of different published angular fixes.
$scope.Login = function() {
if ($scope.IsCorrect($scope.Data.Password)) {
$scope.Data.Loading = true;
$timeout($scope.OpenAndContinue);
//$timeout($scope.OpenAndContinue, 0, false);
//$timeout($scope.OpenAndContinue, 250, false);
}
}
$scope.Login = function() {
if ($scope.IsCorrect($scope.Data.Password)) {
$scope.Data.Loading = true;
$scope.$evalAsync($scope.OpenAndContinue);
}
}
$scope.Login = function() {
if ($scope.IsCorrect($scope.Data.Password)) {
$scope.Data.Loading = true;
$ionicModal.fromTemplateUrl("templates/modals/login.html", {
scope: $scope,
animation: 'scale-in',
backdropClickToClose: false,
hardwareBackButtonClose: false
})
.then($scope.OpenAndContinue);
}
}
Nothing I've tried so far gives the "responsiveness" that I'd expect from a button tap. Nor the snappiness I've seen elsewhere in the APP.
Is there anything else I can do to make sure the login feels "snappy"?
Even the modal doesn't have that "snap" feeling.
Sadly - it seems that the answer was unobtainable based on the information I gave.
The function $scope.IsCorrect contained a call to another function $rootScope.$broadcast('myapp.login')
There was an event listener elsewhere in the APP that opened the database itself (thereby doubling processor usage in those few milliseconds and running before the $apply() updates as handled in the code above.)
I eventually found the additional call to "opendatabase" by adding a console.trace() command to the code that opened the database. This allowed me to see a full stack trace at that point in time, and determine that something else was causing the performance problem.
StackOverflow penalizes users for deleting questions, so I've decided not to kill this Q&A - hopefully someone can find something useful in this.
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 am using ajaxtoolkit modalpopupextender to display a processing message. It's working fine on a typical postback (button click, etc).
However, I am calling a postback in javascript and the progress message isn't showing UNLESS I add an "alert" in the javascript.
Here's my javascript:
function getOrder() {
beginRequest('', '')
var hid = document.getElementById("ctl00_ContentPlaceHolder_hid");
//alert(hid.value);
__doPostBack("SaveOrder", hid.value);
endRequest('', '')
}
I obviously don't want to have an "alert" so does anyone have a solution or ran into this?
Here's the other pience of javascript used relating to this (typical stuff):
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequest);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest);
var mdlCtl = document.getElementById('ctl00_hfModalCtlID').value;
function beginRequest(sender, args){
$find(mdlCtl).show();
}
function endRequest(sender, args) {
$find(mdlCtl).hide();
}
I'm stumped on why the "alert" makes a difference in the javascript that shows the processing message...?
Thoughts? Ideas?
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);