Hi I have a webapplication with documents that you can comment on (see picture Webapp). I'd like the comments to update live for other users, I want the entire comment card to show up live (subcomments, emojis, username, ...), the cshtml code for one of these comment cards is about 200 lines of cshtml so it's quite big and I'm not sure if I can even replicate it using javascript.
Do you guys know any good ways to update the comments live? (They already get updated in the database and show up on refresh)
Is there maybe a way to just refresh the div using vanilla javascript?
EDIT: The question might've been a bit vague.
So I've already got a signalR connection. I can display the content of my comment live in f.e an alert or in the comment section itself (adding comment, Receiving comment alert, receiving comment in commentsection)
I just do it like this now
connection.on("ReceiveComment", function (comment) {
var li = document.createElement("li");
document.getElementById("comments").appendChild(li);
li.textContent = comment.content; });
But i'd like the entire comment card to show up but I'm not sure how I can recreate the cshtml for these comment cards in javascript since it's so huge and contains a bunch of C# code (see code below)
<div id="comments">
<div onmouseleave="unhighlight(@c.startIndex,@c.endIndex)" onmouseenter="highlight(@c.startIndex,@c.endIndex)" class="card border-dark m-1">
<div class="card-header">
<div class="row">
<div class="col">
<h5>
@c.User.UserName
@if (c.User is Projectmanager)
{
<img src="~/badge.png" width="30" height="30" alt="">
}
</h5>
</div>
<div class="col-md-auto">
@if (User.Identity.IsAuthenticated)
{
@if (c.User.UserName.Equals(User.Claims.First(claim => claim.Type == "Username").Value) || User.IsInRole("Administrator") || User.IsInRole("Projectmanager"))
{
var editicon = "editicon" + c.CommentId;
<i onclick="DeleteComment(@c.CommentId, @Model.Id)" class="fa fa-trash"></i>
<i onclick="editcmnt(@c.CommentId, @Model.Id)" id="@editicon" class="fa fa-pen"></i>
if (c.Flagged)
{
<i id="flag" class="fa fa-flag"></i>
}
}
if (Model.PlaceableSubComments)
{
<i onclick="fillSubCommentModalData('@c.User.UserName','@c.Content','@c.CommentId','@c.startIndex','@c.endIndex');ChangeEmojiList(@Model.AllowedEmojis)" data-bs-toggle="modal" data-bs-target="#SubCommentModal" class="fa fa-reply"></i>
}
if (Model.PlaceableEmojis)
{
<a onclick="fillEmojiModalData(@c.CommentId);ChangeEmojiListEmojis(@Model.AllowedEmojis)" data-bs-toggle="modal" data-bs-target="#EmojiModal">😄</a>
}
}
@if (Model.PlaceableSubComments)
{
<i class="fa fa-comment" data-bs-toggle="collapse" data-bs-target="#@commentId" aria-expanded="false">@c.Subcomments.Count</i>
}
</div>
</div>
</div>
<div class="card-body">
@{ var editcmntid = "editcommentId" + c.CommentId; }
<textarea id="@editcmntid" class="card-text cmnttextarea noneditablecmnt" readonly>@c.Content</textarea>
@if (c.Tags != null)
{
<p style="color:teal">
@foreach (Tag t in c.Tags)
{
@t.TagName
}
</p>
}
<div class="d-flex flex-row flex-nowrap card-block overflow-auto">
@foreach (Emoji e in docmgr.GetComment(c.CommentId).Emojis)
{
@if (User.IsInRole("Administrator") || User.IsInRole("Projectmanager") || User.HasClaim(ClaimTypes.NameIdentifier, docmgr.GetEmoji(e.Id).creator.Id.ToString()))
{
<button onclick="DeleteEmoji(@e.Id,@Model.Id)" class="btn btn-secondary position-relative" data-toggle="tooltip" data-placement="top" title="@docmgr.GetEmoji(e.Id).creator.UserName">
@e.content
<span class="position-absolute top-0 end-0">
×
<span class="visually-hidden">Delete</span>
</span>
</button>
}
else
{
<button class="btn btn-light position-relative" data-toggle="tooltip" data-placement="top" title="@docmgr.GetEmoji(e.Id).creator.UserName">
@e.content
</button>
}
}
</div>
</div>
</div>
<br>
<div class="collapse" id="@commentId">
@if (c.Subcomments.Count() != 0)
{
<ul id="subCommentList">
@foreach (SubComment sc in c.Subcomments)
{
<li>
<div class="card border-dark m-1">
<div class="card-header">
<div class="row">
<div class="col">
<h5>@docmgr.GetComment(sc.CommentId).User.UserName</h5>
@if (c.User is Projectmanager || c.User is Administrator)
{
<img src="~/badge.png" width="30" height="30" alt="">
}
</div>
<div class="col-md-auto">
@if (User.Identity.IsAuthenticated)
{
@if (c.User.UserName.Equals(User.Claims.First(claim => claim.Type == "Username").Value) || User.IsInRole("Administrator") || User.IsInRole("Projectmanager"))
{
<i onclick="DeleteComment(@sc.CommentId,@Model.Id)" class="fa fa-trash"></i>
}
@if (c.User.UserName.Equals(User.Claims.First(claim => claim.Type == "Username").Value) || User.IsInRole("Administrator") || User.IsInRole("Projectmanager"))
{
<i asp-action="" onclick="editcmnt(@sc.CommentId)" id="editicon" class="fa fa-pen"></i>
}
if (Model.PlaceableEmojis)
{
<a onclick="fillEmojiModalData(@sc.CommentId);ChangeEmojiList(@Model.AllowedEmojis)" data-bs-toggle="modal" data-bs-target="#EmojiModal">😄</a>
}
}
</div>
</div>
</div>
<div class="card-body">
<textarea id="@editcmntid" class="card-text cmnttextarea noneditablecmnt" readonly>@sc.Content</textarea>
@if (sc.Tags != null)
{
<p style="color:teal">
@foreach (Tag t in sc.Tags)
{
@t.TagName
}
</p>
}
<div class="d-flex flex-row flex-nowrap card-block overflow-auto">
@foreach (Emoji e in docmgr.GetComment(sc.CommentId).Emojis)
{
@if (User.IsInRole("Administrator") || User.IsInRole("Projectmanager") || User.HasClaim(ClaimTypes.NameIdentifier, docmgr.GetEmoji(e.Id).creator.Id.ToString()))
{
<button onclick="DeleteEmoji(@e.Id,@Model.Id)" class="btn btn-secondary position-relative" data-toggle="tooltip" data-placement="top" title="@docmgr.GetEmoji(e.Id).creator.UserName">
@e.content
<span class="position-absolute top-0 end-0">
×
<span class="visually-hidden">Delete</span>
</span>
</button>
}
else
{
<button class="btn btn-light position-relative" data-toggle="tooltip" data-placement="top" title="@docmgr.GetEmoji(e.Id).creator.UserName">
@e.content
</button>
}
}
</div>
</div>
</div>
</li>
<br>
}
</ul>
}
<br>
</div>
<!-- EmojiModal -->
<div class="modal fade" id="EmojiModal" tabindex="-1" role="dialog" aria-labelledby="EmojiModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="EmojiModalLabel">@localizer["add_emoji"]</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div >
@if (User.Identity.IsAuthenticated)
{
<div id="partialdivcmnt" class="modal-body">
@{
Html.RenderPartial("_AddEmojiPartial", new CreateEmojiViewModel());
}
</div>
}
</div>
</div>
</div>
<!-- SubCommentModal -->
<div class="modal fade" id="SubCommentModal" tabindex="-1" role="dialog" aria-labelledby="subCommentModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="subCommentModalLabel">@localizer["add_subcmnt"]</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div >
@if (User.Identity.IsAuthenticated)
{
<div id="partialdivcmnt" class="modal-body">
@{
Html.RenderPartial("_AddSubCommentPartial", new CreateSubCommentViewModel() { DocReviewId = Model.Id });
}
</div>
}
</div>
</div>
</div>
</div>