Client controller must contain a JavaScript function, see default value for example
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2 hours ago
Hi,
In the widget i am getting error under Client Controller
"Client controller must contain a JavaScript function, see default value for example". . Kindly help.
function($scope, TimeCardPortalService, spUtil, $sanitize, $rootScope, $window, $timeout, spModal, $q) {
var c = this;
/*
console.log('c:');
console.log(c);
*/
_highlightField();
var skipNextRecordWatchUpdate = false;
$scope.pageSize = $scope.data.pageSize;
var minWidthFields = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday", "total"];
$scope.getWidth = function(field) {
if(field && $scope.data.column_meta[field]
&& $scope.data.column_meta[field]['width_in_percent']) {
return {
'min-width': $scope.data.column_meta[field]['width_in_percent'] + '%'
};
}
// Days and Total will have Minimum width of 5%.
// Smaller the resolution, smaller the scroll.
if (field && $scope.data.column_meta[field] && (minWidthFields.indexOf(field) > -1)) {
return {
'min-width': '5%'
}
}
// Default width of 10% which has not configured width_in_percent.
return {
'min-width': '10%'
}
}
function updatePagination(from, to) {
$scope.total = c.data.totalRows;
$scope.current = {
to: to > c.data.totalRows? c.data.totalRows: to,
from: from,
pageSize: $scope.pageSize
};
$scope.paginatedList = c.data.list.slice(from-1, to);
}
updatePagination(1, $scope.pageSize);
$scope.$on('sp_load_new_page', function(event, page) {
$scope.paginatedList = c.data.list.slice(page.from-1, page.to);
});
$scope.cancelEdit = function(evt, index){
if(_isEmptyObject($scope.data.editTimecardObj))
return;
_preventDefault(evt);
$scope.data.list[index] = $scope.data.editTimecardObj;
$scope.data.editTimecardObj = {};
$scope.data.timecardInEditMode = '';
$scope.data.highlightedField = $scope.data.previousHighlightedField || $scope.data.defaultField;
$scope.highlightDuplicates();
};
$scope.saveRecord = function(evt, record, promiseResolver){
_preventDefault(evt);
if($scope.data.recordSetForDelete == record.sys_id) return;
var data = {};
var editabelFields = $scope.data.editable_fields;
for (var i in editabelFields){
var field = editabelFields[i];
if(field === "rate_type" || field === "project_time_category" || field === "resource_plan" ) {
// we don't need sanitization here as this is not directly edited by user
// this value is only selected from pre existing values and typed by user
data[field] = record[field].value;
continue;
}
var val = $sanitize(record[field].display_value);
if(!isValidNumber(val))
data[field] = 0;
else
data[field] = val;
}
$scope.data.timecardInEditMode = '';
$scope.data.editTimecardObj = {};
TimeCardPortalService.updateTimeCard(record.sys_id, data, editabelFields.join(',')+',total').then(function(response){
var result = response.data.result;
for(var field in result){
record[field].display_value = result[field].display_value;
record[field].value = result[field].value;
if(isValidNumber(result[field].value))
record[field].invalid = false;
$scope.data.highlightedField = $scope.data.previousHighlightedField;
}
var status = response.data.status;
if(status == 'error')
refreshWidget();
else {
skipNextRecordWatchUpdate = true;
$scope.highlightDuplicates();
}
if(promiseResolver) {
promiseResolver();
}
});
};
$scope.deleteRecord = function(evt){
var _target = $(evt.target);
var _id = _target.closest('.flex-item').data('id') || evt.target.id;
var record = $scope.data.list.filter(function(listItem) {
return (listItem.sys_id == _id);
})[0];
var confirmModalCtrl;
var index = $(".container .table-body .flex.tc-row").index(_target.closest('.flex.tc-row'));
$scope.data['tcPopover' + record.sys_id] = false;
$scope.data.confirmDialogOpts = {
title: $scope.data.messages.confirmDlgTitle,
text: $scope.data.messages.confirmMssg,
okTxt: $scope.data.messages['delete'],
cancelTxt: $scope.data.messages.cancel,
okBtnClass: 'btn-danger',
ok: function(){
$scope.data.recordSetForDelete = record.sys_id;
TimeCardPortalService.deleteTimeCard(record.sys_id).then(function(response){
$scope.data.recordSetForDelete = '';
$scope.data.list.splice(index, 1);
skipNextRecordWatchUpdate = true;
$scope.highlightDuplicates();
c.data.totalRows -= 1;
updatePagination($scope.current.from, $scope.current.to);
$rootScope.$broadcast("record-delete");
});
confirmModalCtrl.close();
},
afterOpen: function(ctrl){
confirmModalCtrl = ctrl;
},
afterClose : function(){
$scope.showConfirm = false;
confirmModalCtrl = null;
$scope.data.confirmDialogOpts = null;
}
};
$scope.showConfirm = true;
$scope.safeDigest();
_preventDefault(evt);
};
function updateRecordState(evt, newState) {
var _target = $(evt.target);
var _id = _target.closest('.flex-item').data('id') || evt.target.id;
var record = $scope.data.list.filter(function(listItem) {
return (listItem.sys_id == _id);
})[0];
TimeCardPortalService.updateTimeCardState(record.sys_id, newState).then(function(response) {
var status = response.data.status;
var message = response.data.data.message;
if (status != 'success')
spUtil.addErrorMessage('message');
refreshWidget();
})
}
$scope.updateRecordState = function(evt, newState){
$scope.hideTcPopover();
if($scope.data.timecardInEditMode) {
cancelGridEditModePromiseWrapper(event, true).then(function () {
updateRecordState(evt, newState);
})
} else {
updateRecordState(evt, newState);
}
};
$scope.recallRecord = function(evt){
var _target = $(evt.target);
var _id = _target.closest('.flex-item').data('id') || evt.target.id;
var record = $scope.data.list.filter(function(listItem) {
return (listItem.sys_id == _id);
})[0];
var confirmModalCtrl;
var index = $(".container .table-body .flex.tc-row").index(_target.closest('.flex.tc-row'));
$scope.data['tcPopover' + record.sys_id] = false;
$scope.data.confirmDialogOpts = {
title: $scope.data.messages.recallDlgTitle,
text: $scope.data.messages.recallConfirmMssg,
okTxt: $scope.data.messages.recall,
cancelTxt: $scope.data.messages.cancel,
okBtnClass: 'btn-danger',
ok: function(){
TimeCardPortalService.updateTimeCardState(record.sys_id, 'Recalled').then(function(response) {
var status = response.data.status;
var message = response.data.data.message;
if (status != 'success')
spUtil.addErrorMessage(message);
else
spUtil.addInfoMessage(message);
})
confirmModalCtrl.close();
},
afterOpen: function(ctrl){
confirmModalCtrl = ctrl;
},
afterClose : function(){
$scope.showConfirm = false;
confirmModalCtrl = null;
$scope.data.confirmDialogOpts = null;
}
};
$scope.showConfirm = true;
$scope.safeDigest();
_preventDefault(evt);
};
$scope.generateTimecards = function(){
TimeCardPortalService.generateTimecards({
timesheet_id: $scope.data.timesheetId,
tables: $scope.data.tables
}).then(function(response){
spUtil.addInfoMessage(response.data.message);
});
};
$scope.copyFromPreviousTimesheet = function(){
$rootScope.$broadcast('tcp.copy.timesheet');
};
$scope.validateInput = function(field){
var val = field.display_value;
if(isValidNumber(val))
field.invalid = false;
else
field.invalid = true;
};
function isValidNumber(number){
var decimalSeperator = g_user_decimal_separator;
var regx = new RegExp('^-?((\\d+(\\'+ decimalSeperator + '\\d+)?)|(\\' + decimalSeperator + '\\d+))$');
if(regx.test(number) && !isNaN(parseFloat(number))){
return true;
}
return false;
}
function refreshWidget(start, end){
/* Carry forward options for grid customizaions */
start = start ? start:1;
end = end ? end: $scope.pageSize
$scope.data.options = $scope.options.tm_grid_options;
spUtil.update($scope).then(function(){
var timecardToEdit = $scope.data.timecardToEdit;
if(timecardToEdit){
$scope.data.timecardToEdit = '';
$scope.showTimecardInEditMode(timecardToEdit);
}
updatePagination(start, end);
$scope.highlightDuplicates();
$scope.addSyncScrollEventListener();
});
}
var filterQuery = 'time_sheet='+ $scope.data.timesheetId;
var recordWatcherTimer;
spUtil.recordWatch($scope, 'time_card', filterQuery, function(){
$timeout.cancel(recordWatcherTimer);
recordWatcherTimer = $timeout(function(){
if (skipNextRecordWatchUpdate) {
skipNextRecordWatchUpdate = false;
$scope.highlightDuplicates();
} else
refreshWidget();
}, 250);
});
$scope.mergeDuplicateTimeCards = function(record) {
TimeCardPortalService.mergeDuplicateTc({
timesheet_id: $scope.data.timesheetId,
record : record
}).then(function() {
refreshWidget();
});
};
$scope.$on('tcp.refresh.widgets', function(){
skipNextRecordWatchUpdate = true;
refreshWidget();
});
$scope.$on('tcp.highlight.field',function(scope, field){
_highlightField(field);
});
$scope.$on('tcp.edit.timecard', function(scope, timecardId){
$scope.showTimecardInEditMode(timecardId);
});
var foundRecord = null;
$scope.$on('pagination.send.window.for.index', function() {
$scope.enableEditMode(foundRecord[0]);
foundRecord = null;
});
$scope.$on('ng.repeat.completed.tc-grid', function() {
if(foundRecord) {
$scope.enableEditMode(foundRecord[0]);
foundRecord = null;
}
});
function cancelGridEditModePromiseWrapper(event, buttonClicked) {
return $q(function(resolve) {
$scope.cancelGridEditMode(event, buttonClicked, resolve);
});
}
function submitTimesheet (timesheetId, oldState) {
TimeCardPortalService.submitTimesheet(timesheetId).then(function(response){
$scope.data.canSubmitTimesheet = response.data.canSubmitTimesheet;
var newState = response.data.data.value;
$scope.data.state = response.data.data;
var mssg = response.data.message;
if(response.data.status == 'error'){
refreshWidget();
if(mssg)
spUtil.addErrorMessage(mssg);
}
else if(oldState == newState){
refreshWidget();
if(mssg)
spUtil.addInfoMessage(mssg);
}
else if(mssg && response.data.status == 'success'){
spUtil.addInfoMessage(mssg);
}
}
);
}
function submitTimesheetButtonClicked(event, timesheetId, oldState) {
if($scope.data.timecardInEditMode) {
cancelGridEditModePromiseWrapper(event, false).then(function () {
submitTimesheet(timesheetId, oldState);
})
} else {
submitTimesheet(timesheetId, oldState);
}
}
$scope.$on('submitTimesheetButtonClicked', function(event, data) {
submitTimesheetButtonClicked(data.event, data.timesheetId, data.oldState);
});
$scope.showTimecardInEditMode = function(timecardId){
var index = null
var record = $scope.data.list.filter(function(record, idx){
if(record.sys_id == timecardId) {
index = index ? index: idx;
return true;
}
return false;
});
if(record.length > 0) {
foundRecord = record;
// if index is on current page. directly call enableEditmode.
// else figure out on which page it is.
var pageIndex = index + 1;
if (pageIndex <= $scope.current.to && pageIndex >= $scope.current.from) {
$scope.enableEditMode(foundRecord[0]);
} else {
// figure out which page it will be.
var targetPage = parseInt(pageIndex / $scope.current.pageSize);
targetPage += pageIndex % $scope.current.pageSize ? 1 : 0;
$rootScope.$broadcast('pagination.get.window.for.index', {
targetPage: targetPage
});
}
} else {
$scope.data.timecardToEdit = timecardId;
skipNextRecordWatchUpdate = true;
refreshWidget();
}
};
function _highlightField(field){
if(field)
$scope.data.highlightedField = field;
else
$scope.data.highlightedField = $scope.data.defaultField;
}
function _preventDefault(evt){
if(evt){
evt.stopPropagation();
evt.preventDefault();
}
}
function _isEmptyObject(obj){
return !obj || Object.keys(obj).length === 0;
}
$scope.openTimecard = function(ev){
_preventDefault(ev);
var _target = $(ev.target);
var sysId = _target.closest('.flex-item').data('id');
$scope.data['tcPopover' + sysId] = false;
spUtil.get('widget-modal', {embeddedWidgetId: 'widget-form', embeddedWidgetOptions: {table:'time_card', sys_id: sysId, view: 'worker_portal'}}).then(function(widget){
var modalCtrl;
var unregister = $scope.$on('sp.form.record.updated', function(){
skipNextRecordWatchUpdate = true;
refreshWidget();
$rootScope.$broadcast("record-add");
modalCtrl.close();
});
widget.options.afterClose = function(){
unregister();
$scope.data.modalInstance = null;
modalCtrl = null;
$rootScope.$broadcast("timesheet_portal_form_closed");
};
widget.options.afterOpen = function(ctrl){
modalCtrl = ctrl;
};
$scope.data.modalInstance = widget;
});
};
$scope.highlightDuplicates = function() {
$scope.duplicateList = {};
if($scope.data.list && $scope.data.list.length) {
for(var i=0; i< $scope.data.list.length; i++) {
list_item = $scope.data.list[i];
var _sd = list_item['task.short_description'].value.replace(/\s/g, "");
var _state = list_item.state.value;
if($scope.data.restrictedStatesForDuplicateMerge.indexOf(_state.toLowerCase()) !== -1)
continue;
var _ptc = list_item.project_time_category.value || '';
var _taskSysId = list_item.taskSysId;
//Since task can be associated with any categories
var _category = list_item.category.value;
var _rateType = (list_item.rate_type && list_item.rate_type.value) || '';
var _rpln = (list_item.resource_plan && list_item.resource_plan.value) || '';
var uniqueItemKey = _sd + _state + _ptc + _rateType + _taskSysId + _category + _rpln;
var duplicateList = $scope.duplicateList;
if(duplicateList[uniqueItemKey] && duplicateList[uniqueItemKey].length && _taskSysId) {
duplicateList[uniqueItemKey][0].isDuplicate = true;
duplicateList[uniqueItemKey].push(list_item);
list_item.isDuplicate = true;
} else {
duplicateList[uniqueItemKey] = [];
duplicateList[uniqueItemKey].push(list_item);
}
}
}
for(var prop in $scope.duplicateList) {
if($scope.duplicateList[prop] && $scope.duplicateList[prop].length === 1) {
$scope.duplicateList[prop][0].isDuplicate = false;
}
}
$scope.$$phase || $scope.$root && $scope.$root.$$phase || $scope.$digest();
};
$scope.highlightDuplicates();
}
Regards
Suman P.
1 REPLY 1
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
an hour ago
Try this tips if it works for you.
