adds a tabulator redraw when adding the details column to the tableWidget

This commit is contained in:
SimonGschnell
2024-04-23 09:49:41 +02:00
parent e1fac8e871
commit 51ee16926c
8 changed files with 3083 additions and 2940 deletions
@@ -4,7 +4,7 @@ const ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR = 'inProgressLektor';
$STUDIENSEMESTER = $studiensemester_selected;
$STUDIENGAENGE_ENTITLED = implode(', ', $studiengaenge_entitled); // alle STG mit Lese- und Schreibberechtigung
$ORGANISATIONSEINHEITEN_SCHREIBBERECHTIGT = "'". implode('\',\'', $oes_schreibberechtigt). "'"; // alle OE nur mit Schreibberechtigung; singlequote für jeden string notwendig
$ORGANISATIONSEINHEITEN_SCHREIBBERECHTIGT = "'" . implode('\',\'', $oes_schreibberechtigt) . "'"; // alle OE nur mit Schreibberechtigung; singlequote für jeden string notwendig
$LANGUAGE_INDEX = getUserLanguage() == 'German' ? '1' : '2';
$query = '
@@ -109,9 +109,8 @@ $query = '
LIMIT 1)
END "empfehlungsanfrageAm",';
if ($configFachbereichsleitung === TRUE)
{
$query.= ' CASE
if ($configFachbereichsleitung === TRUE) {
$query .= ' CASE
WHEN (anrechnungen.empfehlung_anrechnung IS NULL AND anrechnungen.status_kurzbz = \'' . ANRECHNUNGSTATUS_PROGRESSED_BY_STGL . '\') THEN NULL
ELSE
(SELECT COALESCE(
@@ -136,10 +135,8 @@ if ($configFachbereichsleitung === TRUE)
) as tmp_empfehlungsanfrageEmpfaenger
)
END "empfehlungsanfrageAn"';
}
else
{
$query.= ' CASE
} else {
$query .= ' CASE
WHEN (anrechnungen.empfehlung_anrechnung IS NULL AND anrechnungen.status_kurzbz = \'' . ANRECHNUNGSTATUS_PROGRESSED_BY_STGL . '\') THEN NULL
ELSE
(SELECT COALESCE(
@@ -164,7 +161,7 @@ else
END "empfehlungsanfrageAn"';
}
$query.= ' FROM anrechnungen
$query .= ' FROM anrechnungen
JOIN lehre.tbl_anrechnungstatus as anrechnungstatus ON (anrechnungstatus.status_kurzbz = anrechnungen.status_kurzbz)
WHERE studiensemester_kurzbz = \'' . $STUDIENSEMESTER . '\'
AND studiengang_kz IN (' . $STUDIENGAENGE_ENTITLED . ')
@@ -190,8 +187,8 @@ $filterWidgetArray = array(
ucfirst($this->p->t('lehre', 'lehrveranstaltung')),
'ECTS (LV)',
'ECTS (LV + Bisher)',
'ECTS (Bisher schulisch)',
'ECTS (Bisher beruflich',
'ECTS (Bisher schulisch)',
'ECTS (Bisher beruflich',
ucfirst($this->p->t('global', 'begruendung')),
ucfirst($this->p->t('person', 'studentIn')),
ucfirst($this->p->t('anrechnung', 'nachweisdokumente')),
@@ -201,13 +198,38 @@ $filterWidgetArray = array(
ucfirst($this->p->t('anrechnung', 'empfehlung')),
'status_kurzbz',
'Status',
'PrestudentID',
'PrestudentID',
ucfirst($this->p->t('anrechnung', 'empfehlungsanfrageAm')),
ucfirst($this->p->t('anrechnung', 'empfehlungsanfrageAn'))
),
'datasetRepOptions' => '{
height: func_height(this),
layout: "fitColumns", // fit columns to width of table
layoutColumnsOnNewData:true,
persistenceID: "approveAnrechnungUebersicht_V1",
autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated
index: "anrechnung_id", // assign specific column as unique id (important for row indexing)
selectable: true, // allow row selection
selectableRangeMode: "click", // allow range selection using shift end click on end of range
selectablePersistence:false, // deselect previously selected rows when table is filtered, sorted or paginated
tableWidgetFooter: {
selectButtons: true // tableWidgetFooter properties are checked in _renderTabulatorFooterHTML function
},
selectableCheck: function(row){
return func_selectableCheck(row);
},
rowFormatter:function(row){
func_rowFormatter(row,this);
},
columnDefaults:{
//columnDefaults tooltip did not work
tooltip:function(e, cell, onRendered){
return func_tooltips(cell);
},
},
height: func_height(this),
layout: "fitColumns", // fit columns to width of table
persistenceID: "approveAnrechnungUebersicht_V1",
@@ -232,7 +254,7 @@ $filterWidgetArray = array(
tooltip:function(e, cell, onRendered){
return func_tooltips(cell);
},
headerFilterPlaceholder: " ",
//headerFilterPlaceholder: " ",
}
}', // tabulator properties
@@ -274,4 +296,4 @@ $filterWidgetArray = array(
echo $this->widgetlib->widget('TableWidget', $filterWidgetArray);
?>
?>
+5 -5
View File
@@ -4,15 +4,15 @@
<!-- Table widget header -->
<div id="tableWidgetHeader"></div>
<!-- TableWidget help site ( only rendered if widget is Tabulator )-->
<!-- TableWidget help site ( only rendered if widget is Tabulator )-->
<?php $this->load->view('widgets/table/tableHelpsite') ?>
<!-- Table info top -->
<div id="tableDatasetActionsTop"></div>
<!-- TableWidget table -->
<div class="border border-2 mb-4">
<div class="border border-1 mb-4">
<?php TableWidget::loadViewDataset(); ?>
</div>
@@ -23,4 +23,4 @@
<div id="tableWidgetFooter"></div>
</div>
</div>
</div>
+219 -203
View File
@@ -3,245 +3,261 @@
// Add Edit and Update Buttons to table rows
function func_tableBuilt(table) {
table.tabulator("addColumn",
{
title: "Aktion",
align: "center",
width: 150,
formatter: addActionButtons,
}, false // place column right
);
table.tabulator(
"addColumn",
{
title: "Aktion",
align: "center",
width: 150,
formatter: addActionButtons,
},
false // place column right
);
// fully redrawing the table after adding the Details column
table.tabulator("redraw", true);
}
// Returns relative height (depending on screen size)
function func_height(table){
return $(window).height() * 0.50;
function func_height(table) {
return $(window).height() * 0.5;
}
// Converts string date postgre style to string DD.MM.YYYY.
// This will allow correct filtering.
var formatDate = function(cell, formatterParams){
let postgreDate = cell.getValue();
if (postgreDate != null)
{
var d = new Date(postgreDate);
return ("0" + (d.getDate())).slice(-2) + "." + ("0" + (d.getMonth() + 1)).slice(-2) + "." + d.getFullYear();
}
}
var formatDate = function (cell, formatterParams) {
let postgreDate = cell.getValue();
if (postgreDate != null) {
var d = new Date(postgreDate);
return (
("0" + d.getDate()).slice(-2) +
"." +
("0" + (d.getMonth() + 1)).slice(-2) +
"." +
d.getFullYear()
);
}
};
// Create Edit and Update Buttons for table rows
var addActionButtons = function(cell) {
var addActionButtons = function (cell) {
// Create edit button
var editBtn = document.createElement("button");
editBtn.type = "button";
editBtn.innerHTML = '<i class="fa fa-edit"></i>';
editBtn.classList.add("azrEditBtn");
editBtn.classList.add("btn");
editBtn.classList.add("btn-outline-secondary");
editBtn.addEventListener("click", function () {
adminAnrechnung.editRow(cell);
});
// Create edit button
var editBtn = document.createElement("button");
editBtn.type = "button";
editBtn.innerHTML = "<i class=\"fa fa-edit\"></i>";
editBtn.classList.add("azrEditBtn");
editBtn.classList.add("btn");
editBtn.classList.add("btn-outline-secondary");
editBtn.addEventListener("click", function(){
adminAnrechnung.editRow(cell);
});
// Create delete button
var delBtn = document.createElement("button");
delBtn.type = "button";
delBtn.innerHTML = '<i class="fa fa-times"></i>';
delBtn.classList.add("azrDeleteBtn");
delBtn.classList.add("btn");
delBtn.classList.add("btn-outline-secondary");
delBtn.style.marginLeft = "5px";
delBtn.addEventListener("click", function () {
adminAnrechnung.deleteRow(cell);
});
// Add buttons to cell
var buttonHolder = document.createElement("span");
buttonHolder.appendChild(editBtn);
buttonHolder.appendChild(delBtn);
// Create delete button
var delBtn= document.createElement("button");
delBtn.type = "button";
delBtn.innerHTML = "<i class=\"fa fa-times\"></i>";
delBtn.classList.add("azrDeleteBtn");
delBtn.classList.add("btn");
delBtn.classList.add("btn-outline-secondary");
delBtn.style.marginLeft = '5px';
delBtn.addEventListener("click", function(){
adminAnrechnung.deleteRow(cell);
});
// Add buttons to cell
var buttonHolder = document.createElement("span");
buttonHolder.appendChild(editBtn);
buttonHolder.appendChild(delBtn);
return buttonHolder;
}
return buttonHolder;
};
// ---------------------------------------------------------------------------------------------------------------------
$(function () {
$(document).on("tableInit", function (event, tabulatorInstance) {
// tablutBuilt has to be attached as a callback the the tabulator in tabulator5
func_tableBuilt($("#tableWidgetTabulator"));
});
$(document).on("tableInit", function(event,tabulatorInstance) {
// tablutBuilt has to be attached as a callback the the tabulator in tabulator5
func_tableBuilt($("#tableWidgetTabulator"))
});
// Empty Modal fields on 'Anrechnungszeitraum hinzufuegen'
$(document).on("click", ".azrOpenModal", function () {
let defaultStudiensemester_kurzbz = $(
".modal-body #defaultStudiensemester_kurzbz"
).val();
// Empty Modal fields on 'Anrechnungszeitraum hinzufuegen'
$(document).on('click', '.azrOpenModal', function(){
$(".modal-header #azrModalLabel").text(
FHC_PhrasesLib.t("anrechnung", "anrechnungszeitraumHinzufuegen")
);
let defaultStudiensemester_kurzbz = $('.modal-body #defaultStudiensemester_kurzbz').val();
$(".modal-body #anrechnungszeitraum_id").val("");
$(".modal-body #studiensemester")
.val(defaultStudiensemester_kurzbz)
.change();
$(".modal-body #azrStart").val("");
$(".modal-body #azrEnde").val("");
});
$('.modal-header #azrModalLabel').text(FHC_PhrasesLib.t("anrechnung", "anrechnungszeitraumHinzufuegen"));
$('.modal-body #anrechnungszeitraum_id').val('');
$('.modal-body #studiensemester').val(defaultStudiensemester_kurzbz).change();
$('.modal-body #azrStart').val('');
$('.modal-body #azrEnde').val('');
});
// Insert Anrechnungszeitraum
$(document).on("click", "#azrInsertBtn", function () {
var studiensemester_kurzbz = $(".modal-body #studiensemester").val();
var anrechnungstart = $(".modal-body #azrStart").val();
var anrechnungende = $(".modal-body #azrEnde").val();
// Insert Anrechnungszeitraum
$(document).on('click', '#azrInsertBtn', function(){
var studiensemester_kurzbz = $('.modal-body #studiensemester').val();
var anrechnungstart = $('.modal-body #azrStart').val();
var anrechnungende = $('.modal-body #azrEnde').val();
// Insert Anrechnungszeitraum
adminAnrechnung.insertAzr(studiensemester_kurzbz, anrechnungstart, anrechnungende);
});
})
adminAnrechnung.insertAzr(
studiensemester_kurzbz,
anrechnungstart,
anrechnungende
);
});
});
var adminAnrechnung = {
insertAzr: function(studiensemester_kurzbz, anrechnungstart, anrechnungende){
FHC_AjaxClient.ajaxCallPost(
FHC_JS_DATA_STORAGE_OBJECT.called_path + "/save",
{
studiensemester_kurzbz: studiensemester_kurzbz,
anrechnungstart: anrechnungstart,
anrechnungende: anrechnungende
},
{
successCallback: function (data, textStatus, jqXHR)
insertAzr: function (
studiensemester_kurzbz,
anrechnungstart,
anrechnungende
) {
FHC_AjaxClient.ajaxCallPost(
FHC_JS_DATA_STORAGE_OBJECT.called_path + "/save",
{
studiensemester_kurzbz: studiensemester_kurzbz,
anrechnungstart: anrechnungstart,
anrechnungende: anrechnungende,
},
{
successCallback: function (data, textStatus, jqXHR) {
if (FHC_AjaxClient.isError(data)) {
FHC_DialogLib.alertWarning(FHC_AjaxClient.getError(data));
}
if (FHC_AjaxClient.hasData(data)) {
data = FHC_AjaxClient.getData(data);
// Update row
$("#tableWidgetTabulator").tabulator(
"addData",
[
{
if (FHC_AjaxClient.isError(data))
{
FHC_DialogLib.alertWarning(FHC_AjaxClient.getError(data));
}
if (FHC_AjaxClient.hasData(data))
{
data = FHC_AjaxClient.getData(data);
// Update row
$('#tableWidgetTabulator').tabulator('addData', [{
anrechnungszeitraum_id: data.anrechnungszeitraum_id,
studiensemester_kurzbz: studiensemester_kurzbz,
anrechnungstart: anrechnungstart,
anrechnungende: anrechnungende
}], true); // true to add row on top
// Close Modal
$('#azrModal').modal('hide');
// Success message
FHC_DialogLib.alertSuccess(FHC_PhrasesLib.t("ui", "gespeichert"));
}
anrechnungszeitraum_id: data.anrechnungszeitraum_id,
studiensemester_kurzbz: studiensemester_kurzbz,
anrechnungstart: anrechnungstart,
anrechnungende: anrechnungende,
},
errorCallback: function (jqXHR, textStatus, errorThrown)
{
FHC_DialogLib.alertError(FHC_PhrasesLib.t("ui", "systemfehler"));
}
}
);
},
editRow: function (cell){
// Open Modal
$('#azrModal').modal('show');
],
true
); // true to add row on top
let row = cell.getRow();
var anrechnungszeitraum_id = row.getData().anrechnungszeitraum_id;
var studiensemester_kurzbz = row.getData().studiensemester_kurzbz;
var anrechnungstart = row.getData().anrechnungstart;
var anrechnungende = row.getData().anrechnungende;
// Close Modal
$("#azrModal").modal("hide");
$('.modal-header #azrModalLabel').text('Anrechnungszeitraum bearbeiten');
// Success message
FHC_DialogLib.alertSuccess(FHC_PhrasesLib.t("ui", "gespeichert"));
}
},
errorCallback: function (jqXHR, textStatus, errorThrown) {
FHC_DialogLib.alertError(FHC_PhrasesLib.t("ui", "systemfehler"));
},
}
);
},
editRow: function (cell) {
// Open Modal
$("#azrModal").modal("show");
$('.modal-body #anrechnungszeitraum_id').val(anrechnungszeitraum_id);
$('.modal-body #studiensemester').val(studiensemester_kurzbz).change();
$('.modal-body #azrStart').val(anrechnungstart);
$('.modal-body #azrEnde').val(anrechnungende);
let row = cell.getRow();
var anrechnungszeitraum_id = row.getData().anrechnungszeitraum_id;
var studiensemester_kurzbz = row.getData().studiensemester_kurzbz;
var anrechnungstart = row.getData().anrechnungstart;
var anrechnungende = row.getData().anrechnungende;
},
updateAzr: function (anrechnungszeitraum_id, studiensemester_kurzbz, anrechnungstart, anrechnungende) {
FHC_AjaxClient.ajaxCallPost(
FHC_JS_DATA_STORAGE_OBJECT.called_path + "/edit",
{
$(".modal-header #azrModalLabel").text("Anrechnungszeitraum bearbeiten");
$(".modal-body #anrechnungszeitraum_id").val(anrechnungszeitraum_id);
$(".modal-body #studiensemester").val(studiensemester_kurzbz).change();
$(".modal-body #azrStart").val(anrechnungstart);
$(".modal-body #azrEnde").val(anrechnungende);
},
updateAzr: function (
anrechnungszeitraum_id,
studiensemester_kurzbz,
anrechnungstart,
anrechnungende
) {
FHC_AjaxClient.ajaxCallPost(
FHC_JS_DATA_STORAGE_OBJECT.called_path + "/edit",
{
anrechnungszeitraum_id: anrechnungszeitraum_id,
studiensemester_kurzbz: studiensemester_kurzbz,
anrechnungstart: anrechnungstart,
anrechnungende: anrechnungende,
},
{
successCallback: function (data, textStatus, jqXHR) {
if (FHC_AjaxClient.isError(data)) {
FHC_DialogLib.alertWarning(FHC_AjaxClient.getError(data));
}
if (FHC_AjaxClient.hasData(data)) {
// Update row
$("#tableWidgetTabulator").tabulator("updateData", [
{
anrechnungszeitraum_id: anrechnungszeitraum_id,
studiensemester_kurzbz: studiensemester_kurzbz,
anrechnungstart: anrechnungstart,
anrechnungende: anrechnungende
},
{
successCallback: function (data, textStatus, jqXHR)
{
if (FHC_AjaxClient.isError(data))
{
FHC_DialogLib.alertWarning(FHC_AjaxClient.getError(data));
}
anrechnungende: anrechnungende,
},
]);
if (FHC_AjaxClient.hasData(data))
{
// Update row
$('#tableWidgetTabulator').tabulator('updateData', [{
anrechnungszeitraum_id: anrechnungszeitraum_id,
studiensemester_kurzbz: studiensemester_kurzbz,
anrechnungstart: anrechnungstart,
anrechnungende: anrechnungende
}]);
// Close Modal
$("#azrModal").modal("hide");
// Close Modal
$('#azrModal').modal('hide');
// Success message
FHC_DialogLib.alertSuccess(FHC_PhrasesLib.t("ui", "gespeichert"));
}
},
errorCallback: function (jqXHR, textStatus, errorThrown) {
FHC_DialogLib.alertError(FHC_PhrasesLib.t("ui", "systemfehler"));
},
}
);
},
deleteAzr: function (anrechnungszeitraum_id) {
FHC_AjaxClient.ajaxCallPost(
FHC_JS_DATA_STORAGE_OBJECT.called_path + "/delete",
{
anrechnungszeitraum_id: anrechnungszeitraum_id,
},
{
successCallback: function (data, textStatus, jqXHR) {
if (FHC_AjaxClient.isError(data)) {
FHC_DialogLib.alertWarning(FHC_AjaxClient.getError(data));
}
// Success message
FHC_DialogLib.alertSuccess(FHC_PhrasesLib.t("ui", "gespeichert"));
if (FHC_AjaxClient.hasData(data)) {
let row = $("#tableWidgetTabulator").tabulator(
"getRow",
anrechnungszeitraum_id
);
row.delete(anrechnungszeitraum_id);
}
},
errorCallback: function (jqXHR, textStatus, errorThrown)
{
FHC_DialogLib.alertError(FHC_PhrasesLib.t("ui", "systemfehler"));
}
}
);
},
deleteAzr: function(anrechnungszeitraum_id){
FHC_AjaxClient.ajaxCallPost(
FHC_JS_DATA_STORAGE_OBJECT.called_path + "/delete",
{
anrechnungszeitraum_id: anrechnungszeitraum_id
},
{
successCallback: function (data, textStatus, jqXHR)
{
if (FHC_AjaxClient.isError(data))
{
FHC_DialogLib.alertWarning(FHC_AjaxClient.getError(data));
}
if (FHC_AjaxClient.hasData(data))
{
let row = $('#tableWidgetTabulator').tabulator('getRow', anrechnungszeitraum_id);
row.delete(anrechnungszeitraum_id);
// Success message
FHC_DialogLib.alertSuccess(FHC_PhrasesLib.t("ui", "geloescht"));
}
},
errorCallback: function (jqXHR, textStatus, errorThrown)
{
FHC_DialogLib.alertError(FHC_PhrasesLib.t("ui", "systemfehler"));
}
}
);
},
deleteRow: function (cell){
if(!confirm(FHC_PhrasesLib.t("ui", "frageSicherLoeschen")))
{
return;
}
// Delete Anrechnungszeitraum
adminAnrechnung.deleteAzr(cell.getRow().getData().anrechnungszeitraum_id);
// Success message
FHC_DialogLib.alertSuccess(FHC_PhrasesLib.t("ui", "geloescht"));
}
},
errorCallback: function (jqXHR, textStatus, errorThrown) {
FHC_DialogLib.alertError(FHC_PhrasesLib.t("ui", "systemfehler"));
},
}
);
},
deleteRow: function (cell) {
if (!confirm(FHC_PhrasesLib.t("ui", "frageSicherLoeschen"))) {
return;
}
}
// Delete Anrechnungszeitraum
adminAnrechnung.deleteAzr(cell.getRow().getData().anrechnungszeitraum_id);
},
};
File diff suppressed because it is too large Load Diff
@@ -1,13 +1,14 @@
const BASE_URL = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
const BASE_URL =
FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
const CALLED_PATH = FHC_JS_DATA_STORAGE_OBJECT.called_path;
const CONTROLLER_URL = BASE_URL + '/' + CALLED_PATH;
const CONTROLLER_URL = BASE_URL + "/" + CALLED_PATH;
const APPROVE_ANRECHNUNG_DETAIL_URI = "lehre/anrechnung/ReviewAnrechnungDetail";
const ANRECHNUNGSTATUS_PROGRESSED_BY_STGL = 'inProgressDP';
const ANRECHNUNGSTATUS_PROGRESSED_BY_KF = 'inProgressKF';
const ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR = 'inProgressLektor';
const ANRECHNUNGSTATUS_APPROVED = 'approved';
const ANRECHNUNGSTATUS_REJECTED = 'rejected';
const ANRECHNUNGSTATUS_PROGRESSED_BY_STGL = "inProgressDP";
const ANRECHNUNGSTATUS_PROGRESSED_BY_KF = "inProgressKF";
const ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR = "inProgressLektor";
const ANRECHNUNGSTATUS_APPROVED = "approved";
const ANRECHNUNGSTATUS_REJECTED = "rejected";
const COLOR_LIGHTGREY = "#f5f5f5";
@@ -17,134 +18,152 @@ const COLOR_LIGHTGREY = "#f5f5f5";
// Converts string date postgre style to string DD.MM.YYYY.
// This will allow correct filtering.
var mut_formatStringDate = function(value, data, type, params, component) {
if (value != null)
{
var d = new Date(value);
return ("0" + (d.getDate())).slice(-2) + "." + ("0" + (d.getMonth() + 1)).slice(-2) + "." + d.getFullYear();
}
}
var mut_formatStringDate = function (value, data, type, params, component) {
if (value != null) {
var d = new Date(value);
return (
("0" + d.getDate()).slice(-2) +
"." +
("0" + (d.getMonth() + 1)).slice(-2) +
"." +
d.getFullYear()
);
}
};
// TABULATOR FUNCTIONS
// ---------------------------------------------------------------------------------------------------------------------
// Returns relative height (depending on screen size)
function func_height(table){
return $(window).height() * 0.50;
function func_height(table) {
return $(window).height() * 0.5;
}
// Filters boolean values
function hf_filterTrueFalse(headerValue, rowValue){
function hf_filterTrueFalse(headerValue, rowValue) {
if ("ja".startsWith(headerValue) || "yes".startsWith(headerValue)) {
return rowValue == "true";
}
if ('ja'.startsWith(headerValue) || 'yes'.startsWith(headerValue))
{
return rowValue == 'true';
}
if ("nein".startsWith(headerValue) || "no".startsWith(headerValue)) {
return rowValue == "false";
}
if ('nein'.startsWith(headerValue) || 'no'.startsWith(headerValue))
{
return rowValue == 'false';
}
if (headerValue = '-')
{
return rowValue == null;
}
if ((headerValue = "-")) {
return rowValue == null;
}
}
// Filters empfehlungsberechtigt boolean values
function hf_empfehlungsberechtigt(headerValue, rowValue){
return rowValue == headerValue.toString();
function hf_empfehlungsberechtigt(headerValue, rowValue) {
return rowValue == headerValue.toString();
}
// Adds column details
function func_tableBuilt(table) {
table.tabulator("addColumn",
{
title: "Details",
field: 'details',
align: "center",
width: 100,
formatter: "link",
formatterParams:{
label:"Details",
url:function(cell){
return BASE_URL + "/" + APPROVE_ANRECHNUNG_DETAIL_URI + "?anrechnung_id=" + cell.getData().anrechnung_id
},
target:"_blank"
}
}, true // place column on the very left
);
table.tabulator(
"addColumn",
{
title: "Details",
field: "details",
align: "center",
width: 100,
formatter: "link",
formatterParams: {
label: "Details",
url: function (cell) {
return (
BASE_URL +
"/" +
APPROVE_ANRECHNUNG_DETAIL_URI +
"?anrechnung_id=" +
cell.getData().anrechnung_id
);
},
target: "_blank",
},
},
true // place column on the very left
);
// fully redrawing the table after adding the Details column
table.tabulator("redraw", true);
}
// Formats the rows
function func_rowFormatter(row){
let status_kurzbz = row.getData().status_kurzbz;
let empfehlungsberechtigt = row.getData().empfehlungsberechtigt;
function func_rowFormatter(row) {
let status_kurzbz = row.getData().status_kurzbz;
let empfehlungsberechtigt = row.getData().empfehlungsberechtigt;
row.getCells().forEach(function(cell){
if (status_kurzbz != ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR || empfehlungsberechtigt == "false")
{
row.getElement().style["background-color"] = COLOR_LIGHTGREY; // default
}
});
row.getCells().forEach(function (cell) {
if (
status_kurzbz != ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR ||
empfehlungsberechtigt == "false"
) {
row.getElement().style["background-color"] = COLOR_LIGHTGREY; // default
}
});
}
// Formats row selectable/unselectable
function func_selectableCheck(row){
let status_kurzbz = row.getData().status_kurzbz;
let empfehlungsberechtigt = row.getData().empfehlungsberechtigt;
function func_selectableCheck(row) {
let status_kurzbz = row.getData().status_kurzbz;
let empfehlungsberechtigt = row.getData().empfehlungsberechtigt;
return (
status_kurzbz == ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR || empfehlungsberechtigt == "false"
);
return (
status_kurzbz == ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR ||
empfehlungsberechtigt == "false"
);
}
// Performes after row was updated
function func_rowUpdated(row){
// Refresh row formatters
row.reformat();
function func_rowUpdated(row) {
// Refresh row formatters
row.reformat();
// Deselect and disable new selection of updated rows
row.deselect();
row.getElement().style["pointerEvents"] = "none";
// Deselect and disable new selection of updated rows
row.deselect();
row.getElement().style["pointerEvents"] = "none";
// ...but leave url links selectable
row.getCell('dokument_bezeichnung').getElement().firstChild.style["pointerEvents"] = "auto";
row.getCell('details').getElement().firstChild.style["pointerEvents"] = "auto";
// ...but leave url links selectable
row.getCell("dokument_bezeichnung").getElement().firstChild.style[
"pointerEvents"
] = "auto";
if (row.getCell("detils")) {
row.getCell("details").getElement().firstChild.style["pointerEvents"] =
"auto";
}
}
// Returns tooltip
function func_tooltips(e, cell, onRendered){
//e - mouseover event
//cell - cell component
//onRendered - onRendered callback registration functionfunction
// Return tooltip if row is unselectable
if (!func_selectableCheck(cell.getRow())){
return FHC_PhrasesLib.t("ui", "nichtSelektierbarAufgrundVon") + 'Status';
}
function func_tooltips(e, cell, onRendered) {
//e - mouseover event
//cell - cell component
//onRendered - onRendered callback registration functionfunction
// Return tooltip if row is unselectable
if (!func_selectableCheck(cell.getRow())) {
return FHC_PhrasesLib.t("ui", "nichtSelektierbarAufgrundVon") + "Status";
}
}
// Formats empfehlung_anrechnung
var format_empfehlung_anrechnung = function(cell, formatterParams){
return (cell.getValue() == null)
? '-'
: (cell.getValue() == 'true')
? FHC_PhrasesLib.t("ui", "ja")
: FHC_PhrasesLib.t("ui", "nein");
}
var format_empfehlung_anrechnung = function (cell, formatterParams) {
return cell.getValue() == null
? "-"
: cell.getValue() == "true"
? FHC_PhrasesLib.t("ui", "ja")
: FHC_PhrasesLib.t("ui", "nein");
};
/**
* Returns formatter params for field dokument_bezeichnung (= Spalte Nachweisdokumente)
* NOTE: Returning a formatter param object fixes the problem, that tabulator did not know the url after refreshing the page.
*/
function paramLookup_dokBez(cell){
return {
labelField: 'dokument_bezeichnung',
url: CONTROLLER_URL + '/download?dms_id=' + cell.getData().dms_id,
target: '_blank'
}
function paramLookup_dokBez(cell) {
return {
labelField: "dokument_bezeichnung",
url: CONTROLLER_URL + "/download?dms_id=" + cell.getData().dms_id,
target: "_blank",
};
}
/*
@@ -152,319 +171,338 @@ function paramLookup_dokBez(cell){
* Select all (filtered) rows that are progressed by stg leiter.
* (Ignore rows that are approved, rejected or in request for recommendation)
*/
function tableWidgetHook_selectAllButton(tableWidgetDiv){
var resultRows = tableWidgetDiv.find("#tableWidgetTabulator").tabulator('getRows', true)
.filter(row =>
row.getData().status_kurzbz == ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR
);
function tableWidgetHook_selectAllButton(tableWidgetDiv) {
var resultRows = tableWidgetDiv
.find("#tableWidgetTabulator")
.tabulator("getRows", true)
.filter(
(row) =>
row.getData().status_kurzbz == ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR
);
tableWidgetDiv.find("#tableWidgetTabulator").tabulator('selectRow', resultRows);
tableWidgetDiv
.find("#tableWidgetTabulator")
.tabulator("selectRow", resultRows);
}
$(function () {
const empfehlung_panel = $("#reviewAnrechnungUebersicht-empfehlung-panel");
const begruendung_panel = $("#reviewAnrechnungUebersicht-begruendung-panel");
$(function(){
// Pruefen ob Promise unterstuetzt wird
// Tabulator funktioniert nicht mit IE
var canPromise = !!window.Promise;
if (!canPromise) {
alert(
"Diese Seite kann mit ihrem Browser nicht angezeigt werden. Bitte verwenden Sie Firefox, Chrome oder Edge um die Seite anzuzeigen"
);
window.location.href = "about:blank";
return;
}
const empfehlung_panel = $('#reviewAnrechnungUebersicht-empfehlung-panel');
const begruendung_panel = $('#reviewAnrechnungUebersicht-begruendung-panel');
$(document).on("tableInit", function (event, tabulatorInstance) {
func_tableBuilt($("#tableWidgetTabulator"));
// Pruefen ob Promise unterstuetzt wird
// Tabulator funktioniert nicht mit IE
var canPromise = !! window.Promise;
if(!canPromise)
{
alert("Diese Seite kann mit ihrem Browser nicht angezeigt werden. Bitte verwenden Sie Firefox, Chrome oder Edge um die Seite anzuzeigen");
window.location.href='about:blank';
return;
// event rowUpdated needs to be attached as a callback to the tableBuilt event in tabulator5
$("#tableWidgetTabulator").tabulator("on", "rowUpdated", (row) => {
func_rowUpdated(row);
});
});
// Redraw table on resize to fit tabulators height to windows height
window.addEventListener("resize", function () {
$("#tableWidgetTabulator").tabulator("setHeight", $(window).height() * 0.5);
$("#tableWidgetTabulator").tabulator("redraw", true);
});
// Set status alert color
reviewAnrechnung.setStatusAlertColor();
// Show only rows with anrechnungen ohne Empfehlung
$("#show-need-recommendation").click(function () {
$("#tableWidgetTabulator").tabulator("setFilter", [
{
field: "status_kurzbz",
type: "=",
value: ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR,
},
]);
});
// Show only rows with empfohlene + noch nicht genehmigte/abgelehnte anrechnungen
$("#show-recommended").click(function () {
$("#tableWidgetTabulator").tabulator("setFilter", [
{
field: "status_kurzbz",
type: "=",
value: ANRECHNUNGSTATUS_PROGRESSED_BY_STGL,
},
{ field: "empfehlung_anrechnung", type: "=", value: "true" },
]);
});
// Show only rows with nicht empfohlene + noch nicht genehmigte/abgelehnte anrechnungen
$("#show-not-recommended").click(function () {
$("#tableWidgetTabulator").tabulator("setFilter", [
{
field: "status_kurzbz",
type: "=",
value: ANRECHNUNGSTATUS_PROGRESSED_BY_STGL,
},
{ field: "empfehlung_anrechnung", type: "=", value: "false" },
]);
});
// Show only rows with genehmigte anrechnungen
$("#show-approved").click(function () {
$("#tableWidgetTabulator").tabulator("setFilter", [
{ field: "status_kurzbz", type: "=", value: ANRECHNUNGSTATUS_APPROVED },
]);
});
// Show only rows with abgelehnte anrechnungen
$("#show-rejected").click(function () {
$("#tableWidgetTabulator").tabulator("setFilter", [
{ field: "status_kurzbz", type: "=", value: ANRECHNUNGSTATUS_REJECTED },
]);
});
/**
* Show all rows: clear filter and blur button
* Bootstrap button remains in activated style, even when clicking various times.
* This function "resets" button style and clear all tabulators filter.
* NOTE: MUST be after all other filters
*/
$(".btn-clearfilter").click(function () {
if ($(this).hasClass("active")) {
$("#tableWidgetTabulator").tabulator("clearFilter");
$(this).blur();
}
});
// Ask ifRecommend Anrechnungen
$("#reviewAnrechnungUebersicht-recommend-anrechnungen-ask").click(
function () {
begruendung_panel.css("display", "none");
$(document).on("tableInit", function(event,tabulatorInstance) {
func_tableBuilt($("#tableWidgetTabulator"))
// event rowUpdated needs to be attached as a callback to the tableBuilt event in tabulator5
$("#tableWidgetTabulator").tabulator("on","rowUpdated",(row)=>{func_rowUpdated(row)})
});
// Redraw table on resize to fit tabulators height to windows height
window.addEventListener('resize', function(){
$('#tableWidgetTabulator').tabulator('setHeight', $(window).height() * 0.50);
$('#tableWidgetTabulator').tabulator('redraw', true);
});
// Set status alert color
reviewAnrechnung.setStatusAlertColor();
// Show only rows with anrechnungen ohne Empfehlung
$("#show-need-recommendation").click(function(){
$('#tableWidgetTabulator').tabulator('setFilter',
[
{field: 'status_kurzbz', type: '=', value: ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR}
]
);
});
// Show only rows with empfohlene + noch nicht genehmigte/abgelehnte anrechnungen
$("#show-recommended").click(function(){
$('#tableWidgetTabulator').tabulator('setFilter',
[
{field: 'status_kurzbz', type: '=', value: ANRECHNUNGSTATUS_PROGRESSED_BY_STGL},
{field: 'empfehlung_anrechnung', type: '=', value: 'true'}
]
);
});
// Show only rows with nicht empfohlene + noch nicht genehmigte/abgelehnte anrechnungen
$("#show-not-recommended").click(function(){
$('#tableWidgetTabulator').tabulator('setFilter', [
{field: 'status_kurzbz', type: '=', value: ANRECHNUNGSTATUS_PROGRESSED_BY_STGL},
{field: 'empfehlung_anrechnung', type: '=', value: 'false'},
]
);
});
// Show only rows with genehmigte anrechnungen
$("#show-approved").click(function(){
$('#tableWidgetTabulator').tabulator('setFilter',
[
{field: 'status_kurzbz', type: '=', value: ANRECHNUNGSTATUS_APPROVED}
]
);
});
// Show only rows with abgelehnte anrechnungen
$("#show-rejected").click(function(){
$('#tableWidgetTabulator').tabulator('setFilter',
[
{field: 'status_kurzbz', type: '=', value: ANRECHNUNGSTATUS_REJECTED}
]
);
});
/**
* Show all rows: clear filter and blur button
* Bootstrap button remains in activated style, even when clicking various times.
* This function "resets" button style and clear all tabulators filter.
* NOTE: MUST be after all other filters
*/
$(".btn-clearfilter").click(function(){
if($(this).hasClass('active'))
{
$('#tableWidgetTabulator').tabulator('clearFilter');
$(this).blur();
}
})
// Ask ifRecommend Anrechnungen
$("#reviewAnrechnungUebersicht-recommend-anrechnungen-ask").click(function(){
begruendung_panel.css('display', 'none');
if (empfehlung_panel.is(":hidden"))
{
// Show begruendung panel if is hidden
empfehlung_panel.slideDown(400, function() {
$('html, body').animate({
scrollTop: empfehlung_panel.offset().top // Move empfehlung panel bottom up to be visible within window screen
}, 400);
});
return;
}
});
// Recommend Anrechnungen
$("#reviewAnrechnungUebersicht-recommend-anrechnungen-confirm").click(function(e){
// Avoid bubbling click event to sibling break button
e.stopImmediatePropagation();
// Get selected rows data
let selected_data = $('#tableWidgetTabulator').tabulator('getSelectedData')
.map(function(data){
// reduce to necessary fields
return {
'anrechnung_id' : data.anrechnung_id,
}
});
// Alert and exit if no anrechnung is selected
if (selected_data.length == 0)
{
FHC_DialogLib.alertInfo(FHC_PhrasesLib.t("ui", "bitteMindEinenAntragWaehlen"));
return;
}
// Prepare data object for ajax call
let data = {
'data': selected_data
};
// Hide empfehlung panel again
empfehlung_panel.slideUp('slow');
FHC_AjaxClient.ajaxCallPost(
FHC_JS_DATA_STORAGE_OBJECT.called_path + "/recommend",
data,
if (empfehlung_panel.is(":hidden")) {
// Show begruendung panel if is hidden
empfehlung_panel.slideDown(400, function () {
$("html, body").animate(
{
successCallback: function (data, textStatus, jqXHR)
{
if (data.error && data.retval != null)
{
// Print error message
FHC_DialogLib.alertWarning(data.retval);
}
scrollTop: empfehlung_panel.offset().top, // Move empfehlung panel bottom up to be visible within window screen
},
400
);
});
return;
}
}
);
if (!data.error && data.retval != null)
{
// Update status 'genehmigt'
$('#tableWidgetTabulator').tabulator('updateData', data.retval);
// Recommend Anrechnungen
$("#reviewAnrechnungUebersicht-recommend-anrechnungen-confirm").click(
function (e) {
// Avoid bubbling click event to sibling break button
e.stopImmediatePropagation();
// Print success message
FHC_DialogLib.alertSuccess(FHC_PhrasesLib.t("ui", "anrechnungenWurdenEmpfohlen"));
}
},
errorCallback: function (jqXHR, textStatus, errorThrown)
{
FHC_DialogLib.alertError(FHC_PhrasesLib.t("ui", "systemfehler"));
}
}
// Get selected rows data
let selected_data = $("#tableWidgetTabulator")
.tabulator("getSelectedData")
.map(function (data) {
// reduce to necessary fields
return {
anrechnung_id: data.anrechnung_id,
};
});
// Alert and exit if no anrechnung is selected
if (selected_data.length == 0) {
FHC_DialogLib.alertInfo(
FHC_PhrasesLib.t("ui", "bitteMindEinenAntragWaehlen")
);
});
return;
}
// Ask if Dont recommend Anrechnungen
$("#reviewAnrechnungUebersicht-dont-recommend-anrechnungen-ask").click(function(){
// Prepare data object for ajax call
let data = {
data: selected_data,
};
empfehlung_panel.css('display', 'none');
// Hide empfehlung panel again
empfehlung_panel.slideUp("slow");
if (begruendung_panel.is(":hidden"))
FHC_AjaxClient.ajaxCallPost(
FHC_JS_DATA_STORAGE_OBJECT.called_path + "/recommend",
data,
{
// Show begruendung panel if is hidden
begruendung_panel.slideDown(400, function() {
$('html, body').animate({
scrollTop: begruendung_panel.offset().top // Move genehmigung panel bottom up to be visible within window screen
}, 400);
});
return;
successCallback: function (data, textStatus, jqXHR) {
if (data.error && data.retval != null) {
// Print error message
FHC_DialogLib.alertWarning(data.retval);
}
if (!data.error && data.retval != null) {
// Update status 'genehmigt'
$("#tableWidgetTabulator").tabulator("updateData", data.retval);
// Print success message
FHC_DialogLib.alertSuccess(
FHC_PhrasesLib.t("ui", "anrechnungenWurdenEmpfohlen")
);
}
},
errorCallback: function (jqXHR, textStatus, errorThrown) {
FHC_DialogLib.alertError(FHC_PhrasesLib.t("ui", "systemfehler"));
},
}
});
);
}
);
// Dont recommend Anrechnungen
$("#reviewAnrechnungUebersicht-dont-recommend-anrechnungen-confirm").click(function(e){
// Ask if Dont recommend Anrechnungen
$("#reviewAnrechnungUebersicht-dont-recommend-anrechnungen-ask").click(
function () {
empfehlung_panel.css("display", "none");
// Avoid bubbling click event to sibling break button
e.stopImmediatePropagation();
let begruendung = $('#reviewAnrechnungUebersicht-begruendung').val();
empfehlung_panel.css('display', 'none');
// Check if begruendung is given
if (!begruendung.trim()) // empty or white spaces only
{
FHC_DialogLib.alertInfo(FHC_PhrasesLib.t("ui", "bitteBegruendungAngeben"));
return;
}
// Get selected rows data and add begruendung
let selected_data = $('#tableWidgetTabulator').tabulator('getSelectedData')
.map(function(data){
// reduce to necessary fields
return {
'anrechnung_id' : data.anrechnung_id,
'begruendung' : begruendung
}
});
// Alert and exit if no anrechnung is selected
if (selected_data.length == 0)
{
FHC_DialogLib.alertInfo(FHC_PhrasesLib.t("ui", "bitteMindEinenAntragWaehlen"));
return;
}
// Prepare data object for ajax call
let data = {
'data': selected_data
};
// Hide begruendung panel again
begruendung_panel.slideUp('slow');
FHC_AjaxClient.ajaxCallPost(
FHC_JS_DATA_STORAGE_OBJECT.called_path + "/dontRecommend",
data,
if (begruendung_panel.is(":hidden")) {
// Show begruendung panel if is hidden
begruendung_panel.slideDown(400, function () {
$("html, body").animate(
{
successCallback: function (data, textStatus, jqXHR)
{
if (data.error && data.retval != null)
{
// Print error message
FHC_DialogLib.alertWarning(data.retval);
}
scrollTop: begruendung_panel.offset().top, // Move genehmigung panel bottom up to be visible within window screen
},
400
);
});
return;
}
}
);
if (!data.error && data.retval != null)
{
// Update status 'genehmigt'
$('#tableWidgetTabulator').tabulator('updateData', data.retval);
// Dont recommend Anrechnungen
$("#reviewAnrechnungUebersicht-dont-recommend-anrechnungen-confirm").click(
function (e) {
// Avoid bubbling click event to sibling break button
e.stopImmediatePropagation();
// Print success message
FHC_DialogLib.alertSuccess(FHC_PhrasesLib.t("ui", "anrechnungenWurdenNichtEmpfohlen"));
}
},
errorCallback: function (jqXHR, textStatus, errorThrown)
{
FHC_DialogLib.alertError(FHC_PhrasesLib.t("ui", "systemfehler"));
}
}
let begruendung = $("#reviewAnrechnungUebersicht-begruendung").val();
empfehlung_panel.css("display", "none");
// Check if begruendung is given
if (!begruendung.trim()) {
// empty or white spaces only
FHC_DialogLib.alertInfo(
FHC_PhrasesLib.t("ui", "bitteBegruendungAngeben")
);
});
return;
}
// Break Empfehlung abgeben
$('#reviewAnrechnungUebersicht-empfehlung-abbrechen').click(function(){
empfehlung_panel.slideUp('slow');
// Get selected rows data and add begruendung
let selected_data = $("#tableWidgetTabulator")
.tabulator("getSelectedData")
.map(function (data) {
// reduce to necessary fields
return {
anrechnung_id: data.anrechnung_id,
begruendung: begruendung,
};
});
})
// Alert and exit if no anrechnung is selected
if (selected_data.length == 0) {
FHC_DialogLib.alertInfo(
FHC_PhrasesLib.t("ui", "bitteMindEinenAntragWaehlen")
);
return;
}
// Break Begruendung abgeben
$('#reviewAnrechnungUebersicht-begruendung-abbrechen').click(function(){
// Prepare data object for ajax call
let data = {
data: selected_data,
};
begruendung_panel.slideUp('slow');
// Hide begruendung panel again
begruendung_panel.slideUp("slow");
})
FHC_AjaxClient.ajaxCallPost(
FHC_JS_DATA_STORAGE_OBJECT.called_path + "/dontRecommend",
data,
{
successCallback: function (data, textStatus, jqXHR) {
if (data.error && data.retval != null) {
// Print error message
FHC_DialogLib.alertWarning(data.retval);
}
// Copy Begruendung into textarea
$(".btn-copyIntoTextarea").click(function(){
reviewAnrechnung.copyIntoTextarea(this);
})
if (!data.error && data.retval != null) {
// Update status 'genehmigt'
$("#tableWidgetTabulator").tabulator("updateData", data.retval);
// Print success message
FHC_DialogLib.alertSuccess(
FHC_PhrasesLib.t("ui", "anrechnungenWurdenNichtEmpfohlen")
);
}
},
errorCallback: function (jqXHR, textStatus, errorThrown) {
FHC_DialogLib.alertError(FHC_PhrasesLib.t("ui", "systemfehler"));
},
}
);
}
);
// Break Empfehlung abgeben
$("#reviewAnrechnungUebersicht-empfehlung-abbrechen").click(function () {
empfehlung_panel.slideUp("slow");
});
// Break Begruendung abgeben
$("#reviewAnrechnungUebersicht-begruendung-abbrechen").click(function () {
begruendung_panel.slideUp("slow");
});
// Copy Begruendung into textarea
$(".btn-copyIntoTextarea").click(function () {
reviewAnrechnung.copyIntoTextarea(this);
});
});
var reviewAnrechnung = {
setStatusAlertColor: function () {
let status_kurzbz = $('#reviewAnrechnung-status_kurzbz').data('status_kurzbz');
setStatusAlertColor: function () {
let status_kurzbz = $("#reviewAnrechnung-status_kurzbz").data(
"status_kurzbz"
);
switch (status_kurzbz) {
case ANRECHNUNGSTATUS_APPROVED:
$('#reviewAnrechnung-status_kurzbz').closest('div').addClass('bg-success-subtle');
break;
case ANRECHNUNGSTATUS_REJECTED:
$('#reviewAnrechnung-status_kurzbz').closest('div').addClass('bg-danger-subtle');
break;
case '':
$('#reviewAnrechnung-status_kurzbz').closest('div').addClass('bg-info-subtle');
break;
default:
$('#reviewAnrechnung-status_kurzbz').closest('div').addClass('bg-warning-subtle');
}
},
copyIntoTextarea: function(elem){
// Find closest textarea
let textarea = $(elem).closest('div').find('textarea');
// Copy begruendung into textarea and set focus
textarea.val($.trim($(elem).parent().text())).focus();
switch (status_kurzbz) {
case ANRECHNUNGSTATUS_APPROVED:
$("#reviewAnrechnung-status_kurzbz")
.closest("div")
.addClass("bg-success-subtle");
break;
case ANRECHNUNGSTATUS_REJECTED:
$("#reviewAnrechnung-status_kurzbz")
.closest("div")
.addClass("bg-danger-subtle");
break;
case "":
$("#reviewAnrechnung-status_kurzbz")
.closest("div")
.addClass("bg-info-subtle");
break;
default:
$("#reviewAnrechnung-status_kurzbz")
.closest("div")
.addClass("bg-warning-subtle");
}
}
},
copyIntoTextarea: function (elem) {
// Find closest textarea
let textarea = $(elem).closest("div").find("textarea");
// Copy begruendung into textarea and set focus
textarea.val($.trim($(elem).parent().text())).focus();
},
};
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff