Click item in SharePoint using Knockout.js - sharepoint

I am trying to display details of a SharePoint document library using knockout.js.I want the name of the item or the URL to be clickable.Is it possible? I am trying below code but it is not formatting to URL link <a hrefr=# data-bind="attr: {href: Designation}, text:Designation"></a>
Below is the source code
<table id="tblEmployeeList" border="1">
<thead>
<tr>
<th>Name</th>
<th>Designation</th>
<th>Department</th>
<th>Location</th>
</tr>
</thead>
<!-- Iterating through every list item using foreach of KO -->
<tbody data-bind="foreach: Employees">
<tr>
<td data-bind="text: Name"></td>
**<td </td>**
<td data-bind="text: Department"></td>
<td data-bind="text: Location"></td>
</tr>
</tbody>
</table>
Javascript
ExecuteOrDelayUntilScriptLoaded(MainFunction, "sp.js");
var completeEmployeeList = null;
// Class used for saving the field values.
function EmployeeList(name, designation, department, location) {
var self = this;
self.Name = name;
self.Designation = designation;
self.Department = department;
self.Location = location;
}
// View Model - JavaScript that defines the data and behavior of your UI
function EmployeeListViewModel() {
var self = this;
// observableArray equivalent of a regular array,
self.Employees = ko.observableArray([]);
self.AddEmployees = function (name, designation, department, location) {
self.Employees.push(new EmployeeList(name, designation, department, location));
}
}
function MainFunction() {
completeEmployeeList = new EmployeeListViewModel();
// Retrieve the SharePoint list items
retrieveListItems();
// Activates knockout.js
ko.applyBindings(completeEmployeeList);
}
function retrieveListItems() {
var clientContext = new SP.ClientContext.get_current();
var oList = clientContext.get_web().get_lists().getByTitle('Documents');
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml("<View><RowLimit>10</RowLimit></View>");
this.collListItem = oList.getItems(camlQuery);
clientContext.load(collListItem);
clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}
function onQuerySucceeded(sender, args) {
var listItemInfo = '';
var listItemEnumerator = collListItem.getEnumerator();
while (listItemEnumerator.moveNext()) {
var currentItem = listItemEnumerator.get_current();
completeEmployeeList.AddEmployees(currentItem.get_item("Title"), currentItem.get_item("FileRef"), currentItem.get_item("Editor"),currentItem.get_item("File_x0020_Size"), currentItem.get_item("Modified"));
}
}
function onQueryFailed(sender, args) {
alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

This seems to work as I'd expect. If you aren't seeing a clickable link maybe there's something in your css changing the styling?
Here's a repro snippet, but I removed code related to your api calls:
var completeEmployeeList = null;
// Class used for saving the field values.
function EmployeeList(name, designation, department, location) {
var self = this;
self.Name = name;
self.Designation = designation;
self.Department = department;
self.Location = location;
}
// View Model - JavaScript that defines the data and behavior of your UI
function EmployeeListViewModel() {
var self = this;
// observableArray equivalent of a regular array,
self.Employees = ko.observableArray([]);
self.AddEmployees = function(name, designation, department, location) {
self.Employees.push(new EmployeeList(name, designation, department, location));
}
}
function MainFunction() {
completeEmployeeList = new EmployeeListViewModel();
// Retrieve the SharePoint list items
//retrieveListItems();
//test value
completeEmployeeList.AddEmployees('Test Name', 'Test Dept', 'Test Designation', 'Test Location');
// Activates knockout.js
ko.applyBindings(completeEmployeeList);
}
MainFunction()
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tblEmployeeList" border="1">
<thead>
<tr>
<th>Name</th>
<th>Designation</th>
<th>Department</th>
<th>Location</th>
</tr>
</thead>
<!-- Iterating through every list item using foreach of KO -->
<tbody data-bind="foreach: Employees">
<tr>
<td data-bind="text: Name">
<span data-bind="text: Name"></span>
</td>
<td>
</td>
<td data-bind="text: Department"></td>
<td data-bind="text: Location"></td>
</tr>
</tbody>
</table>

Related

the view "Delete" or its master was not found asp.net mvc5

I want to be able to upload a file then to download it or delete it. But when I try to delete it, I get this error:
The view 'Delete' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/FileUpload/Delete.aspx ,~/Views/FileUpload/Delete.ascx, ~/Views/Shared/Delete.aspx,~/Views/Shared/Delete.ascx, ~/Views/FileUpload/Delete.cshtml, ~/Views/FileUpload/Delete.vbhtml, ~/Views/Shared/Delete.cshtml ,~/Views/Shared/Delete.vbhtml .
[HttpGet]
public ActionResult Delete( string deletedfile)
{
string current_usr = User.Identity.GetUserId();
string fullPath = Request.MapPath("~/Files/" + current_usr + "/" + deletedfile);
if (System.IO.File.Exists(fullPath))
{
System.IO.File.Delete(fullPath);
ViewBag.Message="Deleted";
}
var items = GetFiles();
return View(items);
}
// GET: FileUpload
public ActionResult Index()
{
var items = GetFiles();
return View(items);
}
// POST: FileUpload
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
try
{
string current_usr = User.Identity.GetUserId();
//string path = Path.Combine(Server.MapPath("~/Files/"),
// Path.GetFileName(file.FileName));
var folder = Server.MapPath("~/Files/" + current_usr + "/");
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
string path = Path.Combine(String.Format(folder),
Path.GetFileName(file.FileName));
file.SaveAs(path);
ViewBag.Message = "File uploaded successfully";
}
catch (Exception ex)
{
ViewBag.Message = "ERROR:" + ex.Message.ToString();
}
else
{
ViewBag.Message = "You have not specified a file.";
}
var items = GetFiles();
return View(items);
}
public FileResult Download(string downloadedfile)
{
string current_usr = User.Identity.GetUserId();
var FileVirtualPath = "~/Files/" + current_usr + "/" + downloadedfile;
return File(FileVirtualPath, "application/force-download", Path.GetFileName(FileVirtualPath));
}
private List<string> GetFiles()
{
string current_usr = User.Identity.GetUserId();
var dir = new System.IO.DirectoryInfo(Server.MapPath("~/Files/" + current_usr + "/"));
System.IO.FileInfo[] fileNames = dir.GetFiles("*.*");
List<string> items = new List<string>();
foreach (var file in fileNames)
{
items.Add(file.Name);
}
return items;
}
The View :
<h2> File Upload </h2>
#model List<string>
#using (Html.BeginForm("Index", "FileUpload", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<label for="file"> Upload </label>
<input type="file" name="file" id="file" />
<br /><br />
<input type="submit" value="Upload" />
<br /><br />
#ViewBag.Message
<br />
<h2>Documents list</h2>
<table style="width:100%">
<tr>
<th> File Name </th>
<th> Link </th>
</tr>
#for (var i = 0; i <= (Model.Count) - 1; i++)
{
<tr>
<td>#Model[i].ToString() </td>
<td>#Html.ActionLink("Download", "Download", new { downloadedfile = Model[i].ToString() }) </td>
<td>
#Html.ActionLink("Delete", "Delete", new { deletedfile = Model[i].ToString() })
</td>
</tr>
}
</table>
}
The issue is that your Delete Controller method is calling View() at the end. That method will attempt to find a view file with the name of the controller method. If you want to show the list of files after the delete you can redirect to your index action like this:
[HttpGet]
public ActionResult Delete(string deletedfile)
{
string current_usr = User.Identity.GetUserId();
string fullPath = Request.MapPath("~/Files/" + current_usr + "/" + deletedfile);
if (System.IO.File.Exists(fullPath))
{
System.IO.File.Delete(fullPath);
ViewBag.Message = "Deleted";
}
return RedirectToAction("Index");
}
See this link from the microsoft Docs for more detail on redirecting
https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/views/asp-net-mvc-views-overview-cs

Multiply two different numeric data in separate rows in react table

I am trying to multiply two different data fetched from the database and have the result displayed on a table. I am having issues multiplying data from two different rows and displaying the result on same table.
// code to filter and render table
renderTable() {
var totalCount = 0;
var shownCount = 0;
var lowerBound = 0;
var upperBound = 0;
var filtered = [];
filtered = this.state.data.map( (row, i,) => {
if(row.department.toLowerCase().indexOf(this.state.departmentFilter) > -1){
return (
<tr key={"employeeData"+i}>
<td>{i+1}</td>
<td>{row.name}</td>
<td>{row.numberofPresentAttendances}</td>
<td>{row.department}</td>
<td>{row.wages}</td>
<td>{row.totalWages}</td>
<td>
</td>
</tr>
);
} else {
return undefined;
}
});
<table className="employee-table">
<tbody>
<tr>
<th>No</th>
<th>Name</th>
<th>Attendance in the last 7days</th>
<th>Department</th>
<th>Wage/hr</th>
<th>Total Wages</th>
<th></th>
</tr>
{ filtered }
</tbody>
</table>
// mongoose models
var employeeSchema = mongoose.Schema({
name: String,
department: String,
wages:Number,
attendances: Object
},{timestamps:true});
var Employee = mongoose.model('Employee', employeeSchema);
I would like to multiply the Wages/hr and numberofPresentAttendances in the frontend
I am not sure if I understand your question completely but if you want to show the result of (numberofPresentAttendances * wages) then you can do something like this:
filtered = this.state.data.map( (row, i,) => {
if(row.department.toLowerCase().indexOf(this.state.departmentFilter) === -1){
return null;
}
return (
<tr key={"employeeData"+i}>
<td>{i + 1}</td>
<td>{row.name}</td>
<td>{row.numberofPresentAttendances}</td>
<td>{row.department}</td>
<td>{row.wages}</td>
<td>{row.numberofPresentAttendances * row.wages}</td>
</tr>
);
});
Although I am not sure why you are using variable numberofPresentAttendances instead of attendances as mentioned in your mongoose schema.

row span using MVC5

#if (ViewData["post"] != null)
{
foreach (var item in ViewData["post"] as IEnumerable<Employee.Models.ApplyJob>)
{
<tr>
<td>#item.PerferenceNo</td>
<td>#item.JobName</td>
<td>#item.Location</td>
<td>Action</td>
</tr>
}
}
how to use row span on PerferenceNo and JobName using MVC4>
You need to compare the previous values with the current values, but there is no need to use rowspan (which would unnecessarily complicate it). You can just generate an empty <td> element when the cell matches the previous value.
#{
var data = ViewData["post"] as IEnumerable<Employee.Models.ApplyJob>;
int perferenceNo = 0;
string jobName = "";
}
#foreach (var item in data)
<tr>
#if (item.PerferenceNo == perferenceNo)
{
<td></td>
}
else
{
perferenceNo = item.PerferenceNo;
<td>#item.PerferenceNo</td>
}
... // ditto for JobName
<td>#item.Location</td>
</tr>
}
And I strongly recommend you pass a model to the view, rather than casting it from ViewData
If you do want to use the rowspan attribute, then you code will need to be
#foreach (var item in items)
{
int perferenceNoCount = data.Count(x => x.PerferenceNo == item.PerferenceNo);
int jobNameCount = data.Count(x => x.JobName == item.JobName);
<tr>
#if (item.PerferenceNo != perferenceNo)
{
perferenceNo = item.PerferenceNo;
<td rowspan="#(perferenceNoCount)">#item.ID</td>
}
#if (item.JobName != jobName)
{
jobName = item.JobName;
<td rowspan="#(jobNameCount)">#item.Name</td>
}
<td>#item.Location</td>
</tr>
}
But you really should be using view model in that case with properties for the rowspan values and run your queries in the controller.

How to select all checkboxes in JHipster

I created test Spring Boot + AngularJS app to test checkboxes:
html:
... <thead>
<tr>
<th><input type="checkbox" ng-model="isAllSelected"
ng-click="selectAll()"></th>
<th>Lp.</th>
<th>ID</th>
<th>Name</th>
<th>Parent Id</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="test in tests">
<td><input type="checkbox" ng-model="test.checked"
ng-change="optionSelected()" /></td>
<td>{{$index+1}}.</td>
<td>{{test.id}}</td>
<td>{{test.name}}</td>
<td>{{test.parentId}}...
test_controller.js:
(function(angular) {
var AppTestController = function($scope, Test) {
var vm = this;
vm.tests = [];
vm.loadAll = loadAll;
loadAll();
function loadAll() {
Test.query(function(result) {
vm.tests = result;
});
}
vm.selectAll = function() {
var toggleStatus = vm.isAllSelected;
angular.forEach(vm.tests, function(itm) {
itm.checked = toggleStatus;
});
}
vm.optionSelected = function() {
vm.isAllSelected = vm.tests
.every(function(itm) {
return itm.checked;
})
}
};
AppTestController.$inject = [ '$scope', 'Test' ];
angular.module("myApp.test_controller").controller(
"AppTestController", AppTestController);
}(angular));
This works for me as spring Boot app, but when I do the same in JHipster it doesn't work.
How can I get it to work in JHipster?
This is what I currently used and it works!:
.html
<thead>
<tr jh-sort="vm.predicate" ascending="vm.reverse" callback="vm.transition()">
<!--th jh-sort-by="id"><span data-translate="global.field.id">ID</span> <span class="glyphicon glyphicon-sort"></span></th-->
<th><input type="checkbox" icheck ng-change="vm.selectAll()" ng-model="vm.checkAll[vm.page]"></th>
<th jh-sort-by="id"><span data-translate="global.field.id">ID</span></th>
---
</tr>
</thead>
<tbody>
<tr ng-repeat="school in vm.schools track by school.id">
<td><input type="checkbox" icheck ng-model="vm.checkboxes[school.id]" ng-change="vm.select(school)"/></td>
<td>{{($index + 1) + (vm.page - 1) * vm.itemsPerPage}}</td>
...
</tr>
</tbody>
.js
vm.checkAll = [];
var map = {};
vm.checkboxes = [];
vm.selectedItems = [];
vm.selectAll = selectAll;
vm.select = select;
function selectAll () {
var value = vm.checkAll[vm.page];
angular.forEach(vm.schools, function(item) {
if (angular.isDefined(item.id)) {
if(vm.checkboxes[item.id] != value) {
vm.checkboxes[item.id] = value;
vm.select(item);
}
}
});
};
function select (item) {
var value = vm.checkboxes[item.id];
if(value) {
vm.selectedItems.push(item);
if(map[vm.page] == null) map[vm.page] = 1;
else map[vm.page] = map[vm.page] + 1;
if(map[vm.page] == vm.schools.length) {
vm.checkAll[vm.page] = true;
}
} else {
vm.selectedItems.splice(item, 1);
if(map[vm.page] == null) map[vm.page] = 0;
else map[vm.page] = map[vm.page] - 1;
if(map[vm.page] < vm.schools.length) {
vm.checkAll[vm.page] = false;
}
}
};

Asynchronous Task controllers in C#4

I want to write an asynchronous Controller that is displaying in output an IEnumerable<IEnumerable<Video>>
I don't know I can manage to write correctly my function Task<IEnumerable<IEnumerable<Video>>> GetVideosAsync(xxxxx) especially the Task.ContinueWhenAll function (in order not to have blocking code ).
Is it better to use a lambda for this piece of code ...?
Can someone help me ?
Nb: *I can only use C#4 and visual Studio 2010
public class HomeController : AsyncController
{
string[] sources = {
"http://xxxx/membervideos/1",
"http://xxxx/membervideos/2"
};
public Task<ActionResult> Async()
{
var sw = Stopwatch.StartNew();
var data = GetVideosAsync();
sw.Stop();
ViewBag.Elapsed = sw.ElapsedMilliseconds;
return View("~/views/home/index.cshtml", data);
}
Task<IEnumerable<IEnumerable<Video>>> GetVideosAsync()
{
var allVideosTasks = new List<Task<IEnumerable<Video>>>();
foreach (var url in sources)
{
allVideosTasks.Add(DownloadDataAsync(url));
}
var context = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.ContinueWhenAll<IEnumerable<Video>,IEnumerable<IEnumerable<Video>>(
/// CODE TO ComplETE HERE
);
Task<IEnumerable<Video>> DownloadDataAsync(string url)
{
var httpClient = new HttpClient();
var httpResponseMessage = httpClient.GetAsync(url);
var result = httpResponseMessage.ContinueWith
(t =>
{
t.Result.EnsureSuccessStatusCode();
return t.Result.Content.ReadAsAsync<IEnumerable<Video>>();
}
).Unwrap();
return result;
}
/**** VIEW ******/
#{
ViewBag.Title = "Home Page";
}
#model IEnumerable<IEnumerable<MvcApplication1.Models.Video>>
<table>
#foreach (var memberVideos in Model)
{
<tr>
#foreach(var video in memberVideos){
<td>
<div>#video.Title</div>
<div><img src="http://xxxxxx/membervideos/#video.ImageUrl" style="width: 185px;"/> </div>
</td>
}
</tr>
}
</table>
<h1>#ViewBag.Elapsed</h1>

Resources