I have solved my websocket warnings “access denied” with forms on the tablesspanel.
The servoy-api (hide-form / show-form) takes some time to load or onload. In the meanwhile the client is calling method getActiveTabUrl constantly (why this much of calls I don’t know.? Because of all client/server communication with replicating browser/server state / form watchers ?). When the form is in a busy process of showing or hiding it will give “denied access” errors in the application server.
I changed the code like servoy-default-tabpanel. When a form is getting onshow or hide it put a waiting-status. When show/hide is ready the status is released. Other methods which are calling the forms on the server are checking first the waiting status and only run when the form/server is not busy with showing/hiding.
In my case I needed a reload form. When the main-template with tabless panel is the same as the previous but formstate on tabpanel changes I had problems that on the new forms the OnShow methods were not running on the server. With a ReloadForm of the main-template it is working normal. For changing the containedForm I have also made an API. I experienced that model-changes are not pushed to the client on the moment of call in the method but on the end when the server is ready with the complete method.
Andrei/Servoy: Can you check my code? I’m a little afraid that a form can get in a wait-status and gets in an endless waitingloop. Application could freeze on the client.
angular.module('angularmaterialTablesspanel',['servoy']).directive('angularmaterialTablesspanel', ['$sabloApplication', '$q', function($sabloApplication, $q) {
return {
restrict: 'E',
scope: {
model: "=svyModel",
svyServoyapi: "=",
handlers: "=svyHandlers",
api: "=svyApi"
},
controller: function($scope, $element, $attrs) {
var realContainedForm;
var formWillShowCalled;
$scope.waitingForServerVisibility = { } // Used to wait for true of tab
function setRealContainedForm (formname, relationname) {
if (!$scope.waitingForServerVisibility[formname]){
if (formWillShowCalled != formname && formname) {
$scope.waitingForServerVisibility[formname] = true;
formWillShowCalled = formname;
if ($scope.model.waitForData) {
$q.when($scope.svyServoyapi.formWillShow(formname, relationname)).then(function() {
realContainedForm = formname;
delete $scope.waitingForServerVisibility[formname];
});
} else {
$scope.svyServoyapi.formWillShow(formname, relationname).then(function() {
realContainedForm = formname;
delete $scope.waitingForServerVisibility[formname];
});
}
}
}
}
$scope.getActiveTabUrl = function() {
if (realContainedForm && !$scope.waitingForServerVisibility[realContainedForm])
{
return $scope.svyServoyapi.getFormUrl(realContainedForm)
}
return "";
}
setRealContainedForm($scope.model.containedForm, $scope.model.relationName);
$scope.$watch("model.containedForm", function(newValue,oldValue) {
if (newValue !== oldValue)
{
if (oldValue && !$scope.waitingForServerVisibility[oldValue]) {
$scope.waitingForServerVisibility[newValue] = true;
$scope.waitingForServerVisibility[oldValue] = true;
$scope.svyServoyapi.hideForm(oldValue,null,null,newValue,$scope.model.relationName,null).then(function(ok) {
realContainedForm = $scope.model.containedForm;
delete $scope.waitingForServerVisibility[newValue];
delete $scope.waitingForServerVisibility[oldValue];
})
}
else if (newValue && !$scope.waitingForServerVisibility[newValue]) {
setRealContainedForm(newValue, $scope.model.relationName);
}
}
});
$scope.$watch("model.visible", function(newValue,oldValue) {
if ($scope.model.containedForm && newValue !== oldValue)
{
formWillShowCalled = realContainedForm = undefined;
if (newValue)
{
setRealContainedForm($scope.model.containedForm, $scope.model.relationName);
}
else
{
$scope.svyServoyapi.hideForm($scope.model.containedForm);
}
}
});
$scope.getContainerStyle = function() {
var height = 0;
if ($scope.model.height)
{
height = $scope.model.height
}
else if ($scope.model.containedForm && $sabloApplication.hasFormStateWithData($scope.model.containedForm))
{
// for absolute form default height is design height, for responsive form default height is 0
var formState = $sabloApplication.getFormStateEvenIfNotYetResolved($scope.model.containedForm);
if (formState && formState.properties && formState.properties.absoluteLayout)
{
height = formState.properties.designSize.height;
}
}
return {position:"relative", minHeight:height+"px"};
}
$scope.showEditorHint = function()
{
return !$scope.model.containedForm && $element[0].getAttribute("svy-id") !== null;
}
$scope.api.SetContainedForm = function(_formname){
$scope.model.containedForm = _formname
}
$scope.api.ReloadForm = function(_formname){
if($scope.model.containedForm == _formname){
if (!$scope.waitingForServerVisibility[_formname]) {
$scope.waitingForServerVisibility[_formname] = true;
$scope.svyServoyapi.hideForm(_formname,null,null,_formname,$scope.model.relationName,null).then(function(ok) {
realContainedForm = $scope.model.containedForm;
delete $scope.waitingForServerVisibility[_formname];
})
}
}
$scope.model.containedForm = _formname
}
},
templateUrl: 'angularmaterial/tablesspanel/tablesspanel.html'
};
}]);