Why does 'show' event on Kendo View fire twice? - kendo-ui

If a Kendo View is rendered into a Layout (using layout.showIn()), the show event for the view fires twice.
Interestingly, if the view is rendered directly into a DOM element (using view.render()) the event is only fired once, like it's supposed to.
The code is pretty well copied from the Kendo UI Dojo thingee.
I wonder if can you run this :
https://dojo.telerik.com/AkOwiMAZ/2
<div id="app"></div>
<script>
var foo = new kendo.View("<span>Foo</span>", { hide: function() { console.log("Foo is hidden now"); }, show: function() { console.log( "Foo is shown now"); }});
var layout = new kendo.Layout("<header>Header</header><section id='content'></section><footer></footer>");
// Creating the layout, and using the showIn method to render the view
// is where I'm having the issue (2 'show' events fire)
layout.render($("#app"));
layout.showIn("#content", foo);
//
// But this way works fine (rendering directly to a DOM element) (just // one 'show' event fires)
//foo.render('#app');
</script>
I would like the 'show' event to fire once, as it is only shown once :)

This appears to be a bug introduced into the latest 2019 R2 kendo release (2019.2.514). Switching your sample to use the previous 2019 R1 SP1 (2019.1.220) version causes it to behave as expected https://dojo.telerik.com/AkOwiMAZ/5
Telerik usually release a service pack roughly a month after each quarterly release; we've raised a bug report with them, so there's a chance it might be fixed in 2019 R2 SP1. Otherwise, I guess your best bet is stick with 2019.1.220 for the time being. Hope this helps.
Edit: Confirmed as being fixed in 2019 R3 (2019.3.917) release.

Related

jqGrid Strange behavior with 'loadComplete': vs loadComplete:function()

I have a function that runs in load complete event, however, depending on which loadComplete I use in my grid, one way it works and one way it does not.
For example, I want to modify color of particular div on the the table after load complete. so I have
$(grid).jqGrid(
{...options...
loadComplete: function()
{
changeColor();
}
...remaining grid options/events
)};
I can see the code inside the changeColor work, but then coloring reverts back to before code when grid is done.
BUT If I have this...
$(grid).jqGrid(
{...options...
'loadComplete': changeColor,
...remaining grid options/events
)};
the code changes color and stays there. I also tried gridComplete: function() and got same result as using loadComplete:function().
Based on what I am seeing, it appears to me that the grid continues to load after loadComplete:function() but not after 'loadComplete':.
I also discovered, by accident, that if grid contains both loadComplete:function() and 'loadComplete', the 'loadComplete' fires.
I can work around the issue described above(I don't like to), but if anyone know why this occurs i would appreciate an answer.
Using jqGrid 5.0.2.
Thanks.

Update Panel in Firefox loading forever

I have 2 select controls. One change event updates the other. Also, it updates a grid inside update panel.
On page load, I call an ajax method to get the drop down values for both select. I populate the control and trigger a button click event which then updates the grid inside the update panel.
Everything works fine in all browsers, except in Firefox. Any idea as to why this might be happening?
Upon using break point i discovered that in other browsers the server side method is called first and then the ajax method while in Firefox its the other way around.
I narrowed down the issue to when using EndRequestHandler. I use EndRequestHandler event to change the class for a control. I remove that functionality and its perfect. The code for it is below:
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); function EndRequestHandler()
{
var type = $('[id$=ddlType]').val();
$('a[data-categoryid="' + type + '"').parent().addClass('selected');
}
Finally, there was a typo in my code. I forgot the closing square bracket in the EndRequestHandler. Surprisingly, the other browsers didn't care about it!
Updated code.
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); function EndRequestHandler()
{
var type = $('[id$=ddlType]').val();
$('a[data-categoryid="' + type + '"]').parent().addClass('selected');
}

The view area of ckEditor sometimes shows empty at the start

I am using the following directive to create a ckEditor view. There are other lines to the directive to save the data but these are not included as saving always works for me.
app.directive('ckEditor', [function () {
return {
require: '?ngModel',
link: function ($scope, elm, attr, ngModel) {
var ck = ck = CKEDITOR.replace(elm[0]);
ngModel.$render = function (value) {
ck.setData(ngModel.$modelValue);
setTimeout(function () {
ck.setData(ngModel.$modelValue);
}, 1000);
}; }
};
}])
The window appears but almost always the first time around it is empty. Then after clicking the [SOURCE] button to show the source and clicking it again the window is populated with data.
I'm very sure that the ck.setData works as I tried a ck.getData and then logged the output to the console. However it seems like ck.setData does not make the data visible at the start.
Is there some way to force the view window contents to appear?
You can call render on the model at any time and it will simply do whatever you've told it to do. In your case, calling ngModel.$render() will grab the $modelValue and pass it to ck.setData(). Angular will automatically call $render whenever it needs to during its digest cycle (i.e. whenever it notices that the model has been updated). However, I have noticed that there are times when Angular doesn't update properly, especially in instances where the $modelValue is set prior to the directive being compiled.
So, you can simply call ngModel.$render() when your modal object is set. The only problem with that is you have to have access to the ngModel object to do that, which you don't have in your controller. My suggestion would be to do the following:
In your controller:
$scope.editRow = function (row, entityType) {
$scope.modal.data = row;
$scope.modal.visible = true;
...
...
// trigger event after $scope.modal is set
$scope.$emit('modalObjectSet', $scope.modal); //passing $scope.modal is optional
}
In your directive:
ngModel.$render = function (value) {
ck.setData(ngModel.$modelValue);
};
scope.$on('modalObjectSet', function(e, modalData){
// force a call to render
ngModel.$render();
});
Its not a particularly clean solution, but it should allow you to call $render whenever you need to. I hope that helps.
UPDATE: (after your update)
I wasn't aware that your controllers were nested. This can get really icky in Angular, but I'll try to provide a few possible solutions (given that I'm not able to see all your code and project layout). Scope events (as noted here) are specific to the nesting of the scope and only emit events to child scopes. Because of that, I would suggest trying one of the three following solutions (listed in order of my personal preference):
1) Reorganize your code to have a cleaner layout (less nesting of controllers) so that your scopes are direct decendants (rather than sibling controllers).
2) I'm going to assume that 1) wasn't possible. Next I would try to use the $scope.$broadcast() function. The specs for that are listed here as well. The difference between $emit and $broadcast is that $emit only sends event to child $scopes, while $broadcast will send events to both parent and child scopes.
3) Forget using $scope events in angular and just use generic javascript events (using a framework such as jQuery or even just roll your own as in the example here)
There's a fairly simple answer to the question. I checked the DOM and found out the data was getting loaded in fact all of the time. However it was not displaying in the Chrome browser. So the problem is more of a display issue with ckEditor. Strange solution seems to be to do a resize of the ckEditor window which then makes the text visible.
This is a strange issue with ckeditor when your ckeditor is hidden by default. Trying to show the editor has a 30% chance of the editor being uneditable and the editor data is cleared. If you are trying to hide/show your editor, use a css trick like position:absolute;left-9999px; to hide the editor and just return it back by css. This way, the ckeditor is not being removed in the DOM but is just positioned elsewhere.
Use this java script code that is very simple and effective.Note editor1 is my textarea id
<script>
$(function () {
CKEDITOR.timestamp= new Date();
CKEDITOR.replace('editor1');
});
</script>
Second way In controller ,when your query is fetch data from database then use th
is code after .success(function().
$http.get(url).success(function(){
CKEDITOR.replace('editor1');
});
I know, that this thread is dead for a year, but I got the same problem and I found another (still ugly) solution to this problem:
instance.setData(html, function(){
instance.setData(html);
});

difference between on and mon in ExtJs MVC

I need to add click event in my xtype : 'panel' in extjs 4.1.3
But I can do this by two ways.
panel.mon(panel.getEl(), 'click', function(){
panel.fireEvent('click');
});
panel.getEl().on('click',function(){
panel.fireEvent('click');
});
So after doing above code, in controller I can get click event of panel and can do my stuff there. But I can't get difference between these ways.
And also other question in my mind is which is best way?
Please can anybody help me to understand this diff??
Thanks in advance.
mon is used when a component is binding an event to something that we want to remove when the component is destroyed. For example:
// Some shared menu
var menu = new Ext.menu.Menu();
var p = new Ext.panel.Panel();
p.mon(menu, 'show', function(){
p.update('Menu was shown');
});
// This automatically causes the show event on the menu
// to be removed, even though the menu wasn't touched
p.destroy();
In your case, a component will always clean up it's element, so it doesn't really matter either way.

Modifying main Activities grid view in CRM 4.0 using JavaScript

I have a task to change envelope icons on the main Activities view page (Work Place, My Work -> Activities) for every row in the grid, depending on the custom status of the row in crm 4.0. I need to do it using JavaScript. Does anybody know if there is a way to do that and where should the JavaScript code be placed? I am assuming that I need to intercept grid onLoad event, go through the grid, check the condition and flip the url of the icon. But I cannot figure out how to hook into that event...
Thanks very much!
I got several very useful advices and here is what I got so far.
1. I added SiteMap to load a custom page, instead of default one (/workplace/home_activities.aspx)
2. Here is the code of the custom page, placing onreadystatechange in the html was the only way I could get this function to run. Do not know why.
HTML>
HEAD>
TITLE>
script language="javascript" type="text/javascript">
function Run()
{
var objIframe = getIframe();
if(objIframe.readyState == "complete")
{
var docFrame = objIframe.contentWindow.document;
var grid = docFrame.getElementById("crmGrid");
var allRecords = grid.InnerGrid.AllRecords;
for(var i=0; i
function getIframe()
{
return document.getElementById("wraperActivitiesFrame");
}
/script>
/HEAD>
body >
iframe id="wraperActivitiesFrame" src="/workplace/home_activities.aspx" WIDTH="100%" HEIGHT="100%" onreadystatechange="Run()">
/HTML>
The issue I am having now is that the function does not run again when I try to page the grid. I have 2 pages of Activities; when the page loads for the first time - I have my alert boxes, but when I click on "page 2" arrow - nothing happens. Why??? What I am doing wrong?
You kinda can hook into that event. You create a "wrapper" HTML page that you load in CRM instead of the default activities grid via Sitemap. This wrapper contains a full-size IFrame in which you load the actual grid, and in the IFrame's onreadystatechange handler (for readyState == 4), you traverse the grid's DOM (jQuery might make this a little easier, but I haven't used jQuery much myself) and do whatever changes you need to do (that means the JavaScript goes within the wrapper HTML page). If you call this via setInterval and put a try-catch around it, this will even be safe against grid refreshes and browsing through the pages.

Resources