[英]Getting undefined error trying to use AngularJS DateRangePicker in SharePoint environment
I am trying to use a AngularJS daterange picker to filter data based on a date range.我正在尝试使用 AngularJS 日期范围选择器根据日期范围过滤数据。 I cannot figure out why I am getting the TypeError "Cannot read property 'startDate' of undefined. Near the top of the angularjs controller I'm defining the date object with the startDate property. But I still get this error. Is this an issue with SharePoint? How do can I fix this to work in SharePoint. The code works fine in a LAMP stack with a local json file but not on SP. I attempting to run on SP 2016. Thank you.我无法弄清楚为什么我会收到 TypeError "Cannot read property 'startDate' of undefined。在 angularjs controller 的顶部附近我正在定义日期 ZA8CFDE6331BD59EB2AC96F8911C4B6使用 SharePoint?如何解决此问题以在 SharePoint 中工作。该代码在具有本地 json 文件的 LAMP 堆栈中运行良好,但在 SP.20 上无法运行。谢谢您。
Here is how I am bringing in all the dependencies in the head of the html file.以下是我如何在 html 文件的头部引入所有依赖项。
<head>
<title>Rolling Log</title>
<meta charset="uft-8">
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/daterangepicker.css" />
<link rel="stylesheet" href="css/styles.css">
<script src="js/jquery-3.4.1.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/angular.js"></script>
<!-- <script src="js/angular-route.js"></script> -->
<script src="js/moment.js"></script>
<script src="js/daterangepicker.js"></script>
<script src="js/angular-daterangepicker.js"></script>
</head>
This the body of the html file:这是 html 文件的主体:
<body ng-app="myApp" ng-controller="myController" ng-clock>
<nav class="navbar navbar-expand-md bg-dark navbar-dark">
...
</nav>
<div class="wrapper">
<div><h1>CM Rolling Log</h1></div>
<div id="top">
<hr>
<span style="float: right; padding: 2px;">Search: <input type="text" ng-model="searchText"></span>
<label class="my-auto mr-2">Date Opened:</label>
<input date-range-picker class="form-control" ng-model="datePicker.date" clearable="true" style="max-width: 280px;">
<table>
<tr>
<th ng-click="sortBy('timestamp')" width="10%">Date Time</th>
<th ng-click="sortBy('Action')" width="70%">Action</th>
<th ng-click="sortBy('AO')" width="15%">AO</th>
</tr>
<tr ng-repeat="item in log | orderBy:sortField:reverseOrder | filter:searchText | myfilter: datePicker.date">
<td>{{item.timestamp | date: 'MM/dd/yyyy HH:MM'}}</td>
<td>{{item.Action | removeHTMLTags | strip }}</td>
<td>{{item.AO}}</td>
</tr>
</table>
</div>
<div id="bottom">
<form action="" method="POST" ng-submit="createFunc()">
<br /><span id="user"></span> <br /> <br />
Comment: <br /> <textarea id="action" rows="5" cols="130" name="comment"></textarea> <br /><br />
<input type="submit" name="submit_btn" value="Post comment">
</form>
</div>
</div>
The angularjs code with the applied date range picker is at bottom.带有应用日期范围选择器的 angularjs 代码位于底部。
var app = angular.module('myApp', ['daterangepicker']);
app.filter('removeHTMLTags', function() {
return function(text) {
return text ? String(text).replace(/<[^>]+/gm, '') : '';
}
});
app.controller('myController',
function($scope, $http) {
$http({
method: 'GET',
url: "https://.../_api/web/lists/GetByTitle('RollingLog')/items?$top=1000&$select=timestamp,Action,AO",
headers: {"Accept": "application/json;odata=verbose"}
}).then(function (data, status, headers, config) {
$scope.log = data.data.d.results;
$scope.datePicker = { date: {
startDate: null, endDate: null
} };
$scope.searchText = "";
$scope.reverseOrder = true;
$scope.sortField = "timestamp";
$scope.sortBy = function(sortField) {
$scope.reverseOrder = ($scope.sortField === sortField) ? !$scope.reverseOrder : false;
$scope.sortField = sortField;
};
jQuery.ajax({
url: "https://.../_api/web/currentuser?$select=Title",
type: "GET",
headers: {"Accept": "application/json;odata=verbose","Content-Type": "application/json;odata=verbose"},
success: function(data) {
username = data.d.Title;
console.log("user name: " + username);
document.getElementById("user").innerHTML = username;
},
error: function(data) {
console.log("Error occurred trying to get user id");
}
});
}, function errorCallback(response) {
});
$scope.getFormDigest = function() {
console.log("Inside getFormDigest");
var formdigest;
jQuery.ajax({
url: "https://.../_api/contextinfo",
type: "POST",
async: false,
headers: {
"accept": "application/json;odata=verbose",
type: "POST"
},
success: function(data)
{
console.log(typeof data);
formdigest = data.d.GetContextWebInformation.FormDigestValue
}
});
return formdigest;
};
$scope.createFunc = function() {
console.log("Inside createFunc...");
var dt = new Date();
var action = document.getElementById("action").value;
var formdigest = $scope.getFormDigest();
jQuery.ajax({
url: "https://.../_api/web/lists/GetByTitle('RollingLog')/items",
method: "POST",
data: JSON.stringify({
'__metadata' : {'type': 'SP.Data.RollingLogListItem'},
'Action': action,
'AO': username,
'timestamp': dt
}),
headers: {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose",
"X-RequestDigest": formdigest
},
success: function(data) {
console.log("entry created successfully...");
},
error: function(data) {
console.log(("#__REQUESTDIGEST").val());
console.log("Error message: " + JSON.stringify(data.responseJSON.error));
}
});
};
}
).filter('strip', function() {
return function(str) {
return str.replace(/>/g, '').replace(/ /g, ' ').replace(/>/g, '').replace(/>>/g, '').replace(/;/g, '').replace(/#/g, '"').replace(/"/g,'"');
}
});
app.filter("myfilter", function() {
return function(items, date) {
if (!date.startDate || !date.endDate) {
return items
}
startDate = moment(date.startDate);
endDate = moment(date.endDate);
return items.filter(function(elem) {
var openedDate = moment(elem.date_opened);
return startDate.diff(openedDate, 'days') <= 0 && endDate.diff(openedDate, 'days') >= 0;
});
};
});
You are initializing your datepicker when your promise is resolved (inside "then"), therefore before then your datepicker is undefined and because of this you are getting "Cannot read property 'startDate' of undefined" error.当您的 promise 被解析(在“then”内)时,您正在初始化您的 datepicker,因此在此之前您的 datepicker 是未定义的,因此您会收到“Cannot read property 'startDate' of undefined”错误。 You can你可以
1) move your initialization code to the begining of the controller 1)将您的初始化代码移动到 controller 的开头
app.controller('myController',
function($scope, $http) {
$scope.datePicker = { date: {
startDate: null, endDate: null
} };
...
2) or you can add null control inside your filter 2)或者您可以在过滤器中添加 null 控件
app.filter("myfilter", function() {
return function(items, date) {
if(date == undefined){
return items;
}
if (!date.startDate || !date.endDate) {
return items
}
startDate = moment(date.startDate);
endDate = moment(date.endDate);
return items.filter(function(elem) {
var openedDate = moment(elem.date_opened);
return startDate.diff(openedDate, 'days') <= 0 && endDate.diff(openedDate, 'days') >= 0;
});
};
});
To get rid of such errors I would use ng-if
to promise that the filter receives datePicker
with date
.为了消除此类错误,我将使用ng-if
到 promise 过滤器接收带有date
的datePicker
。
I believe you don't want to show the table rows ae to call ng-repeat
till datePicker.date
is initialized.我相信您不想显示表格行 ae 来调用ng-repeat
直到datePicker.date
被初始化。
<tr ng-if="datePicker && datePicker.date"
ng-repeat="item in log | orderBy:sortField:reverseOrder | filter:searchText | myfilter: datePicker.date">
</tr>
In this case, myfilter
will be called once datePicker.date
is not undefined
and it is already synced with the digest cycle so you don't need additional watchers.在这种情况下,一旦myfilter
undefined
并且它已经与摘要周期同步,将调用datePicker.date
,因此您不需要额外的观察者。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.