Binding JSON data to a html angularjs data table - javascript

Im a newbie to angular, currently i have created a datatable using html and angular, can you guys help me on how to bind a JSON data into this table... my scripts are as follows
html script
<div class="container-fluid">
<div class="row">
<div class="col-xs-12 col-sm-7 col-md-7 col-lg-4">
<page-title [title]=pageTitle></page-title>
</div>
</div>
<div class="row">
<div class="col-12">
<data-table [dataTable]="dataTable" ></data-table>
</div>
</div>
ts script
export class UploadsComponent implements OnInit {
pageTitle = '<i class="fa fa-table fa-fw"></i>Uploads';
dataTable: DataTable;
constructor() {
}
ngOnInit() {
this.initDataTable();
}
initDataTable() {
let startDateHeader = new DataTableHeader();
startDateHeader.text = 'Start Date';
startDateHeader.dataType = DataTableColumnDataType.DATE;
let uploadtypeHeader = new DataTableHeader();
uploadtypeHeader.text = 'Upload Type';
let statusHeader = new DataTableHeader();
statusHeader.text = 'Status';
let modifiedDateHeader = new DataTableHeader();
modifiedDateHeader.text = 'Modified Date';
modifiedDateHeader.dataType = DataTableColumnDataType.DATE;
let descriptionHeader = new DataTableHeader();
descriptionHeader.text = 'Description';
this.dataTable = new DataTable();
this.dataTable.headers = [startDateHeader, uploadtypeHeader, statusHeader, modifiedDateHeader, descriptionHeader];
}
}
and this is the output table i got
so can anyone give me some guidance on how to properly bind data to this table which comes in a JSON

Related

How to render an Image loaded from postgres Database in angular

I'm trying to render dinamically and image linked to an Ad in angular, the problem is that even if in tag the 'src' parameter seems to be right it can't show the image.
This is my code in Angular
ngOnChanges(changes: SimpleChanges): void {
console.log("ngOnChanges: " + changes);
console.log(this.ads.length);
for(let i = 0; i< this.ads.length; i++){
this.service.getImage(this.ads[i]).subscribe(blobList => this.ads[i].images = blobList).add( () => {
console.log("Byte: " + this.ads[i].images.at(0));
let div = document.getElementById("ad" + this.ads[i].id) as HTMLDivElement;
console.log(div);
let bytea: ArrayBuffer = this.ads[i].images.at(0) as ArrayBuffer;
const buffer = Buffer.from(bytea);
const blob = new Blob([buffer], {type: 'image/png'});
const image = this.createImageFromBlob(blob);
div.appendChild(image);
});
}
}
This is the function I use to create an HTMLImageElement from a BLOB
public createImageFromBlob(blob: Blob): HTMLImageElement {
const image = new Image();
const url = URL.createObjectURL(blob);
image.src = url;
return image;
}
This is the Ad interface
export interface Ad{
id: number;
title: string;
description: string;
user: User;
property: Property;
price: number;
mq: number;
status: string;
city: string;
images: ArrayBuffer[];
}
This is my code in HTML
<span *ngIf="!isEmpty()">
<span *ngFor="let ad of ads">
<span *ngIf="canShow(ad.status)">
<div class="container justify-content-center">
<div class="card jumbotron">
<div class="text-center badge-info badge" style="margin-top: -2%;" id="statusTitle">
<h2>{{ad.status.toUpperCase()}}</h2>
</div>
<div class="row no-gutters m-3">
<div class="col-lg-5 col-md-7 col-md-12" id="ad{{ad.id}}">
</div>
<div class="col">
<div class="card-block px-2">
<h3 class="card-title">{{ad.title}}</h3>
<p class="card-text">{{ad.description}}</p>
{{ad.price}}
<hr>
{{ad.user.nickname}}
</div>
</div>
</div>
<div class="card-footer w-100 text-muted">
Leggi annuncio
</div>
</div>
</div>
<hr>
</span>
</span>
</span>
I'm adding the java springboot controller that I use to take data from the database. This method returns a List of Byte[] 'cause I have bytea on postgres database.
#GetMapping("/getImage")
public List<byte[]> getImage(HttpServletRequest request, #RequestParam String adId){
List<Image> imageList = DBManager.getInstance().getImageDao().findByAdId(Integer.parseInt(adId));
List<byte[]> imgList = new ArrayList<>();
for (Image image : imageList) {
imgList.add(image.getData());
}
return imgList;
}
And this is the method I use in Angular to call the java server.
getImage(adId: number): Observable<Blob[]> {
return this.http.get<Blob[]>('http://localhost:8080/image', {params: {adId: adId}, responseType: 'json'});
}
As you can see i'm trying to inject the HTMLImageElement in a div linked through an ID.
I tried some other methods but this one is the only that gave me a correct Blob, but on website it only shows the "Image not Found" icon.
image
I can't figure out what I'm doing wrong, any help will be very appreciated, thanks.
I resolved ot converting the byte[] to blob but only adding the base64 to image/jpeg encoding string, thank you all, hope this will help someone.
for(let i = 0; i< this.ads.length; i++){
this.service.getImage(this.ads[i].id).subscribe(blobList => this.ads[i].images = blobList).add( () => {
let image = document.getElementById("img" + this.ads[i].id) as HTMLImageElement;
if(this.ads[i].images.at(0) == null){
image.src = "https://fakeimg.pl/400x250/?text=No%20image"
}else{
image.src = 'data:image/jpeg;base64,' + this.ads[i].images.at(0);
}
});
}

javascript - Show data in loop with html tags

I have an array of objects. Each object contain few parameters. What I am trying to do is to run over the array and get from each cell the data and present it on a tabel/grid.
Example code
function addButton(){
var phoneNumber = document.getElementById("phoneNumber").value;
var email = document.getElementById("email").value;
var typeNotification = document.getElementById("typeNotification").value;
var valueNumber = document.getElementById("valueNumber").value;
var delayLimit = document.getElementById("delayLimit").value;
var timeStart = document.getElementById("timeStart").value;
var timeEnd = document.getElementById("timeEnd").value;
var notify = {
typeNotification : typeNotification,
email : email,
delayLimit : delayLimit,
timeStart : timeStart,
timeEnd : timeEnd,
valueNumber : valueNumber,
phoneNumber : phoneNumber
};
var notificationList = [];
notificationList.push(notify);
console.log(notificationList);
var notificationListLength = notificationList.length;
for(var i = 0;i < notificationListLength;i++){
<div class="container">
<div class="row">
<div class="col">
1 of 2
</div>
<div class="col">
2 of 2
</div>
</div>
<div class="row">
<div class="col">
1 of 3
</div>
<div class="col">
2 of 3
</div>
<div class="col">
3 of 3
</div>
</div>
</div>
}
}
Inside the loop it gives me error with the Tags.
As you can see, when the user press the AddButton it gets all the data and restore it in object, then I add the object into Array, and then I run on the array and get from each cell of the array the data and I want to show it in Grid.
Like I said it gives me error inside the loop with the tags.
Any idea how can I solve it?
You need to build up the output of html/tags you want, then add that to a targeted element on the page, like so:
<div id="target"></div>
<button onclick="addButton()">Add</button>
<script>
const
target = document.querySelector('#target'),
notificationList = [{
typeNotification: 'typeNotification',
email: 'email',
delayLimit: 'delayLimit',
timeStart: 'timeStart',
timeEnd: 'timeEnd',
valueNumber: 'valueNumber',
phoneNumber: 'phoneNumber'
}];
let output = '';
function addButton() {
notificationList.forEach(item => {
output = `
<div class="container">
<div class="row">
<div class="col">
${item.email} - 1 of 2
</div>
<div class="col">
${item.typeNotification} - 2 of 2
</div>
</div>
<div class="row">
<div class="col">
${item.timeStart} - 1 of 3
</div>
<div class="col">
${item.timeEnd} - 2 of 3
</div>
<div class="col">
${item.delayLimit} - 3 of 3
</div>
</div>
</div>
`;
target.innerHTML += output
});
}
</script>
As you can see, you can adjust the output before you add it to the target.
I have made all the properties in notificationList strings to save time, but in your example, they would be made up of other elements on the page.
Here is a working example: https://jsfiddle.net/14o8n30u/6/
--EDIT--
Here is the same thing, but this time a table gets updated, using javascript builtin table functions:
<button onclick="addButton()">Add</button>
<table></table>
<script>
const
targetTable = document.querySelector('table'),
headerRow = targetTable.createTHead().insertRow(),
tableBody = targetTable.createTBody(),
notificationList = [];
headerRow.insertCell().textContent = 'Notification Type';
headerRow.insertCell().textContent = 'Email';
headerRow.insertCell().textContent = 'Delay Limit';
function addButton() {
while (tableBody.firstChild) {
tableBody.removeChild(tableBody.firstChild);
}
notificationList.push({
typeNotification: `Type${Math.floor(Math.random() * Math.floor(10))}`,
email: `Name${Math.floor(Math.random() * Math.floor(1000))}#test.com`,
delayLimit: `${Math.floor(Math.random() * Math.floor(100))} seconds`,
});
notificationList.forEach(item => {
const newRow = tableBody.insertRow(0);
newRow.insertCell().textContent = item.typeNotification;
newRow.insertCell().textContent = item.email;
newRow.insertCell().textContent = item.delayLimit;
});
}
</script>
On mine, I used random data for illustration purposes, but in yours the data will be built from elements on the page.
Note that you have to keep the notificationList outside the addButton, or it gets reset to an empty array each time the button is clicked.
When the page loads, the table head and body are populated.
Then when the addButton is clicked, the table body is emptied, then a new notification is added to the notificationList.
Then, inside the forEach, which loops over the notifications, all the notifications get their own row added at the top of the table (i.e. the entire table body is repopulated each time addButton is clicked).
You may not need to populate your own table header, but if you do, you can see how in this example.
Here it is working (I couldn't get it to work on jsfiddle for some reason): https://codepen.io/leonsegal/pen/oyKBQb
Hope that helps
var notificationListLength = notificationList.length;
var html_data = '';
for(var i = 0;i < notificationListLength;i++)
{
html_data += '<div class="container">
<div class="row">
<div class="col">
1 of 2
</div>
<div class="col">
2 of 2
</div>
</div>
<div class="row">
<div class="col">
1 of 3
</div>
<div class="col">
2 of 3
</div>
<div class="col">
3 of 3
</div>
</div>
</div>';
}
/* Make a div(id="html_div") when you need display data */
document.getElementById("html_div").innerHTML = html_data ;

How to show user is online using Chatter Application MVC?

I am Creating MVC application chatter Application. I want show who is online in chatter. How can i show it?
I have chatter controller Code:
public ActionResult ChatterList(int ProjectId)
{
ReadCookieValue cookie = new ReadCookieValue();
clientId = cookie.readuserinfo().ClientId;
userId = cookie.readuserinfo().Id;
roleId = cookie.readuserinfo().RoleId;
ChatterViewModel model = new ChatterViewModel();
model.chattersList = Task.Run(() => _project.GetChatterList(ProjectId)).Result;
foreach (var item in model.chattersList)
{
item.CurrentUserId = userId;
}
model.newChatter = new ChatterModel();
model.newChatter.ProjectId = ProjectId;
model.newChatter.UserId = userId;
model.newChatter.UserName = cookie.readuserinfo().UserName;
return View("ProjectChatter", model);
}
public async Task<ActionResult> AddChatter(ChatterViewModel model)
{
if (model != null)
{
var obj = await _project.AddChatterList(model);
if (model.newChatter.ProjectId == 3)
{
return RedirectToAction("EbitDaReports");
}
}
return RedirectToAction("Reports");
}
and i created chatter using Project ID view Code looks like
<div class="col-lg-6">
<div class="ibox-content">
<div class="chat-discussion">
<div class="ibox float-e-margins">
<div class="chat-element right">
<div class="row m-t-lg">
#if (Model.ProjectId > 0)
{
#Html.Action("ChatterList", "Projects", new { #ProjectId = Model.ProjectId })
}
</div>
</div>
</div>
</div>
</div>
</div>
I am trying To use
<div class="row">
#if (HttpRuntime.Cache["ProjectId"] != null)
{
var loggedOnUsers = HttpRuntime.Cache["ProjectId"] as Dictionary<string, DateTime>;
if (loggedOnUsers != null)
{<div class="ProjectId">
}
<span> Online Users: </span>
</div>
}
}
</div>
I am getting Nothing. i need to create new controller ? or else i can override existing controller ?
You need to loop through the dictionary items and display that.
<div class="row">
#if (HttpRuntime.Cache["ProjectId"] != null)
{
var loggedOnUsers = HttpRuntime.Cache["ProjectId"] as Dictionary<string, DateTime>;
<span> Online Users: </span>
if (loggedOnUsers != null)
{
foreach (var userItem in loggedOnUsers.Keys)
{
<p>#userItem <span>#loggedOnUsers[userItem]</span></p>
}
}
else
{
<p>No users!</p>
}
}
else
{
<h2>Could not find a HttpRuntime Cache entry with key "ProjectId"</h2>
}
</div>
This will list the users and their time assuming that HttpRuntime.Cache["ProjectId"] stores a dictionary of string & date time for the online users.
EDIT : Showing sample code how to set data to the Cache.
This is how you add item to the Cache, You need to execute code like this somewhere in your app ( may be when user logs to chat, add a new entry).
var data = HttpRuntime.Cache["ProjectId"] as Dictionary<string, DateTime>;
if(data==null)
data=new Dictionary<string, DateTime>();
data.Add("Scott",DateTime.Now);
data.Add("Shyju", DateTime.Now);
data.Add("Kevin", DateTime.Now);
HttpRuntime.Cache["ProjectId"] = data;

asp.net mvc serialize() returns empty in controller's model

snippet of my cshtml:
#model Models.ClockingInformationViewModel
<form id="clocking-form">
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label class="control-label">Time in</label>
<div class="input-group date form_datetime">
#Html.TextBoxFor(m => m.Attendance.Time01In, new { #class = "form-control", #readonly = "readonly", size = "16" })
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="control-label">Job code</label>
#Html.TextBoxFor(m => m.Attendance.Time01InJob, new { #class = "form-control" })
Controller:
[HttpPost]
public JsonResult ClockingInformation(ClockingInformationViewModel model)
{
return null;
}
ViewModel:
public class ClockingInformationViewModel
{
public Attendance Attendance { get; set; }
public List<Clock> ClockingLocations { get; set; }
}
In my javascript, I have this:
function saveClockingInformation() {
var data = $("#clocking-form").serialize();
$.post($("#clocking-info-url").val(), { model: data });
}
When I set a break point in my controller, ClockingInformationViewModel model property is null.
When I did serializeArray() instead of serialize(), ClockingInformationViewModel model isn't null, but the property Attendance is.
I'm sure it's some silly mistake that I've over looked.
Any insights?
Your var data = $("#clocking-form").serialize(); line of code is already serializing your form to an object, so the code needs to be
function saveClockingInformation() {
var data = $("#clocking-form").serialize();
$.post($("#clocking-info-url").val(), data);
}
Which sends the form data as
Attendance.Time01In=someValue&Attendance.Time01InJob=anotherValue
whereas your current implementation using { model: data } sends the form data as
model[Attendance.Time01In]=someValue&model[Attendance.Time01InJob]=anotherValue
which has no relationship to your model, hence binding fails.
Side note: Your use of $("#clocking-info-url").val() suggests you putting the url in to a hidden input. Instead, use
var url = '#Url.Action("yourAction", "yourController")',
$.post($(url, data);
or if you have generated the form using Html.BeginForm(), then use
var form = $("#clocking-form");
var url = form.attr('action');
$.post($(url, data);

AngularJS - ng-click reinitialising database objects

I am creating a dynamic, single-paged forum site using AngularJS as the front-end and Firebase as the back-end. The page consists of a list of threads on the left-hand side and the thread content on the right-hand side. The thread content displayed is based on the thread selected from the list.
I can successfully select a thread from the list and display its contents. However, when a thread is selected from the list, all of the other threads in the list become replicas of the selected thread. By this, I mean that the attribute values for the title, comments and votes of the selected thread are assigned to the same attributes in all of the other threads simultaneously, making them all identical. The ID of each thread does not change.
Can anybody give me some insight as to what is causing this issue? I can't identify anything in my code that would cause the attribute values of each Firebase object to be reassigned.
Here is the main.html page that contains the list and thread content sections
<div ng-controller="mainPageController">
<div>
<h3>
Welcome {{user.name}}! <button class="btn-danger img-rounded" ng-click="logout()" id="LogoutBtn">Logout</button>
</h3>
</div>
<div class="col-md-6">
<h2>All Threads</h2>
<div id="searchThreads" class="input-group col-md-5 img-rounded">
<input type="text" class="col-xs-5 form-control" ng-model="searchThread" placeholder="Search threads...">
</div>
<div id="addThread" class="input-group">
<input type="text" class="col-xs-5 form-control" ng-model="newThreadTitle" placeholder="New thread title..."/>
<button ng-click="addThread()">Add thread</button>
</div>
<!-- Thread List -->
<div>
<div ng-repeat="thread in threads | filter:searchThread | orderObjectBy:'votes'">
<button class="glyphicon glyphicon-chevron-up" ng-click="upvote(thread.$id, thread.votes)"></button> |
<button class="glyphicon glyphicon-chevron-down" ng-click="downvote(thread.$id, thread.votes)"></button>
<a href ng-click="showThread(thread)">{{thread.votes}}<span style="margin-left:1em"> {{thread.title}} by {{thread.username}}</span></a>
</div>
</div>
</div>
</div>
<!-- Thread content viiew -->
<div class="col-md-6">
<div ng-controller="threadPageController">
<h1>{{currentThread.title}} by {{currentThread.username}}</h1>
<div>
<input type="text" ng-model="newComment" placeholder="Write a comment..."/>
<button ng-click="addComment()">Add Comment</button>
</div>
<div>
<div ng-repeat="comment in currentThread.comments">{{comment.username}}: {{comment.text}}
</div>
<div ng-if="!currentThread.comments.length">There are no comments on this thread</div>
</div>
</div>
</div>
The mainPageController
angular.module('richWebApp')
.controller('mainPageController', function($scope, $location, userService, threadService, fb, $firebaseAuth, $filter){
$scope.user = userService.getLoggedInUser();
$scope.newThreadTitle = '';
$scope.currentThreadId = '';
$scope.threads = threadService.getAllThreads();
$scope.threads.$loaded().then(function(){
console.log($scope.threads)
});
$scope.users = userService.getLoggedInUsers();
$scope.addThread = function(){
if(!$scope.newThreadTitle){
return false; //Don't do anything if the text box is empty
}
var newThread = {
title: $scope.newThreadTitle,
username: $scope.user.name,
comments: [],
votes: 0
};
$scope.threads.$add(newThread);
$scope.newThread = '';
$scope.newThreadTitle = ''; //Clear the text in the input box
}
$scope.showThread = function(thread) {
$scope.$emit('handleEmit', {id: thread.$id});
};
$scope.upvote = function(threadId, threadVotes) {
var newVotes = threadVotes + 1;
var ref = new Firebase(fb.url);
var threadRef = ref.child("threads");
threadRef.child(threadId).update({
votes: newVotes
});
}
$scope.downvote = function(threadId, threadVotes) {
var newVotes = threadVotes - 1;
var ref = new Firebase(fb.url);
var threadRef = ref.child("threads");
threadRef.child(threadId).update({
votes: newVotes
});
}
$scope.logout = function(){
userService.logout();
}
});
The threadPageController
angular.module('richWebApp')
.controller('threadPageController', function($scope, $location, $routeParams, threadService, fb, userService){
$scope.$on('handleBroadcast', function (event, args) {
var threadId = args.id;
var currentThread = threadService.getThread(threadId);
currentThread.$bindTo($scope, 'currentThread') //creates $scope.thread with 3 way binding
});
$scope.newComment = '';
$scope.addComment= function(){
if(!$scope.newComment){
return false; //Don't do anything if the text box is empty
}
var currentUser = userService.getLoggedInUser();
var newComment = {
text: $scope.newComment,
username: currentUser.name
};
$scope.currentThread.comments = $scope.currentThread.comments || [];
$scope.currentThread.comments.push(newComment);
$scope.newComment = ''; //Clear the input box
}
});
threadService
angular.module("richWebApp").service("threadService", function($firebaseArray, $firebaseObject, fb){
this.getAllThreads = function(){
var ref = new Firebase(fb.url + '/threads');
return $firebaseArray(ref);
};
this.getThread = function(threadId){
var ref = new Firebase(fb.url + '/threads/' + threadId);
return $firebaseObject(ref);
};
});

Categories