ASP.NET MVC refresh table in tab-pill - asp.net

I have a problem with my solution.
I have 2 related classes and display them like the example on the ASP.net -Webseite, but only with one related class.
This class is displayed in a tab-pill.
Now I added Modals and a Javascript to edit, delete and create new Entitys, like This., but i don't know how to implement the refresh function, that only my table from the related class refresh and not the page. I will not lose the tab-pill, with is activated.
Thanks for help
Here my View-Page:
#model Armageddon.Models.itUser
#{
ViewBag.Title = "Details ";
}
#using Armageddon.Helpers;
<h2>Details:</h2>
<div>
<hr />
<div class="col-md-5" style="text-align:right">#Html.LabelFor(model => model.displayName)</div>
<div class="col-md-5">#Html.DisplayFor(model => model.displayName)</div>
</div>
<!-- modal placeholder-->
<div id='myModal' class='modal fade in'>
<div class="modal-dialog">
<div class="modal-content">
<div id='myModalContent'></div>
</div>
</div>
</div>
<ul class="nav nav-tabs" role="tablist" id="myTab">
<li role="presentation" class="active">Logins</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane" id="UIT2SysGroup">
#if (Model.UIT2SystemGroup != null)
{
<table class="table">
<tr>
<th>Gruppen</th>
<th>#Html.NoEncodeActionLink("<span class='glyphicon glyphicon-plus'></span>", "Add", "Create", "UIT2SystemGroup", routeValues: new { PersonId = Model.itUserID }, htmlAttributes: new { data_modal = "", #class = "btn btn-primary pull-right" })</th>
</tr>
#if (Model.UIT2SystemGroup.Count() != 0)
{
foreach (var item in Model.UIT2SystemGroup)
{
<tr>
<td>
#item.SystemGroup.Name
</td>
<td>
<div class="pull-right">
#Html.NoEncodeActionLink("<span class='glyphicon glyphicon-trash'></span>", "Delete", "Delete", "UIT2SystemGroup", routeValues: new { id = item.UIT2SystemGroupID}, htmlAttributes: new { data_modal = "", #class = "btn btn-danger" })
</div>
</td>
</tr>
}
}
else
{
<tr><td colspan="3"><div class="alert alert-info" role="alert"><div class="glyphicon glyphicon-info-sign"></div> Zurzeit sind keine administrativen Aufgaben vergeben.</div></td></tr>
}
</table>
}
</div>
</div>

You need to look into Ajax to call the controller that is returning the view.
There is a good sample here
http://www.c-sharpcorner.com/UploadFile/d551d3/how-to-load-partial-views-in-Asp-Net-mvc-using-jquery-ajax/
You could put your table inside a partial view and return this as part of your page.

Related

X.PagedList .NET Core First Page always selected in #Html.PagedListPager

I have created pagination for .Net Core 3 project using X.PagedList nuget, when I click on page number it call action that retrieve partial view and update div for data list, all ok but when I click on page number 2 the data in list updated but current page selection is still on 1, it should changed to 2. and every time click on page greater that 1 the selection remain on 1 in PagedListPager.
#Html.PagedListPager(Model.OrderViewModels, page => Url.Action("OrdersSearch2", "Orders",
new { ViewBag.SearchName, page = page }),
PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(new PagedListRenderOptions
{
LiElementClasses = new string[] { "page-item" },
PageClasses = new string[] { "page-link" },
}
, new AjaxOptions()
{
HttpMethod = "POST",
UpdateTargetId = "OrdersList",
}))
OrdersIndexViewModel
public class OrdersIndexViewModel
{
public IPagedList<OrderViewModel> OrderViewModels { get; set; }
public SearchOrderViewModel SearchOrderViewModel { get; set; }
}
And my Action in Orders controller
public ActionResult OrdersSearch2(int? page)
{
if (!ModelState.IsValid)
{
return View(mymodel);
}
OrderSearch ors = new OrderSearch();
ors.PageNumber = page ?? 1;
var entitiesList = orderService.FindBy(ors).ToPagedList(ors.PageNumber, 5);
var model = new OrdersIndexViewModel();
model.OrderViewModels = entitiesList.ToViewModels();
return PartialView("_OrdersListPartial", model.OrderViewModels);
}
Index.cshtml
#model OrdersIndexViewModel
<div id="OrdersList">
<partial name="_OrdersListPartial.cshtml" model="Model.OrderViewModels" />
</div>
_OrdersListPartial.cshtml
#model X.PagedList.IPagedList<OrderViewModel>
#{
int rowNo = 0;
}
<div id="basic-examples">
<div class="card">
<div class="card-content">
<div class="card-body">
<div class="row">
<div class="col-12">
<input type="submit" value="New Order" class="btn btn-primary mr-1 mb-1 waves-effect waves-light" onclick="location.href='#Url.Action("AddOrder", "Orders")'" />
</div>
</div>
<div class="" id="OrdersList">
#if (Model == null || Model.Count == 0)
{
<div class="alert alert-warning">No Orders</div>
}
else
{
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="mb-0">Orders List</h4>
</div>
<div class="card-content">
<div class="table-responsive mt-1">
<table class="table table-hover-animation mb-0">
<thead>
<tr>
<th>#</th>
<th>ID</th>
<th>CUSTOMER NAME</th>
<th>CREATED</th>
<th>DELIVERY DATE</th>
<th>STATUS</th>
<th>OPERATORS</th>
<th></th>
<th style="display:none"></th>
</tr>
</thead>
<tbody>
#foreach (var i in #Model)
{
rowNo = rowNo + 1;
<tr>
<td>#rowNo</td>
<td>#ViewBag.OrdersPrefix #i.ID</td>
<td><i class="fa fa-circle font-small-3 text-success mr-50"></i>#i.CustomerName</td>
<td>#Html.DisplayFor(x => i.CreatedDate)</td>
<td>#Html.DisplayFor(x => i.DeliveryDate)</td>
<td>#i.OrderStatusText</td>
<td class="p-1">
<ul class="list-unstyled users-list m-0 d-flex align-items-center">
<li data-toggle="tooltip" data-popup="tooltip-custom" data-placement="bottom" data-original-title="Vinnie Mostowy" class="avatar pull-up">
<img class="media-object rounded-circle" src="../../../app-assets/images/portrait/small/avatar-s-5.jpg" alt="Avatar" height="30" width="30">
</li>
<li data-toggle="tooltip" data-popup="tooltip-custom" data-placement="bottom" data-original-title="Elicia Rieske" class="avatar pull-up">
<img class="media-object rounded-circle" src="../../../app-assets/images/portrait/small/avatar-s-7.jpg" alt="Avatar" height="30" width="30">
</li>
<li data-toggle="tooltip" data-popup="tooltip-custom" data-placement="bottom" data-original-title="Julee Rossignol" class="avatar pull-up">
<img class="media-object rounded-circle" src="../../../app-assets/images/portrait/small/avatar-s-10.jpg" alt="Avatar" height="30" width="30">
</li>
<li data-toggle="tooltip" data-popup="tooltip-custom" data-placement="bottom" data-original-title="Darcey Nooner" class="avatar pull-up">
<img class="media-object rounded-circle" src="../../../app-assets/images/portrait/small/avatar-s-8.jpg" alt="Avatar" height="30" width="30">
</li>
</ul>
</td>
<td>
#Html.ActionLink("Edit", "EditOrder", "Orders", routeValues: new { ID = i.ID })
</td>
<td style="display:none">
<i class="feather icon-trash"></i>
#Html.ActionLink("Delete", "DeleteOrderDetailTempItem", "Orders", routeValues: new { ID = i.ID }, htmlAttributes: new
{
#data_ajax = "true",
#data_ajax_method = "Get",
#data_ajax_update = "#OrderDetailList",
#data_ajax_failure = "onFailureDefault",
#data_ajax_success = "ViewOnSuccess",
})
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
}
</div>
</div>
</div>
</div>

ASP.NET MVC is it possible to use ajax.beginform inside a partial view?

Layout -> View -> Partial View
In the View:
<div class="col-md-8">
#{Html.RenderPartial("_komentari", commentlist);}
<div class="gap gap-small"></div>
<div class="box bg-gray">
<h3>#Res.commentwrite_title</h3>
#using (Ajax.BeginForm("postcomment", new { propertyid = Model.PublicID }, new AjaxOptions { UpdateTargetId = "commentsarea", HttpMethod = "Post", InsertionMode = InsertionMode.Replace }, null))
{
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label>#Res.commentwrite_content</label>
<textarea id="comment" name="comment" class="form-control" rows="6"></textarea>
</div>
<div class="form-group">
<input class="btn btn-primary" type="submit" value='#Res.commentwrite_btn' />
</div>
</div>
</div>
}
</div>
</div>
In the Partial View:
<div id="commentsarea">
<ul class="booking-item-reviews list">
#if (Model != null)
{
foreach (Comment item in Model)
{
<li>
<div class="row">
<div class="col-md-2">
<div class="booking-item-review-person">
<a class="booking-item-review-person-avatar round" href="#">
<img src="/assets/img/70x70.png" alt="Image Alternative text" title="Bubbles" />
</a>
<p class="booking-item-review-person-name">
#if (item.UserId != null)
{
<a href='#Url.Action("details", "user", new { userid = item.User.PublicId })'>#item.User.Username</a>
}
else
{
Anonymous
}
</p>
</div>
</div>
<div class="col-md-10">
<div class="booking-item-review-content">
<p>
#item.Content
</p>
<p class="text-small mt20">#item.DateOnMarket</p>
<p class="booking-item-review-rate">
#using (Ajax.BeginForm("reportcomment", new { comment = item.PublicId }, new AjaxOptions { UpdateTargetId = "reportscount", HttpMethod = "Post", InsertionMode = InsertionMode.Replace }, null))
{
<a id="submit_link" href="#">Spam?</a>
<a class="fa fa-thumbs-o-down box-icon-inline round" href="#"></a>
}
<b id="reportscount" class="text-color">#item.CommentReports.Count</b>
</p>
</div>
</div>
</div>
</li>
}
}
</ul>
</div>
<script>
$(function () {
$('a#submit_link').click(function () {
$(this).closest("form").submit();
});
});
</script>
View
Both scripts for Ajax are always included in the Layout (I'm already using Ajax on other pages too). On the View page, when I add a new comment, it is added in the database and shows the updated list of comments via ajax. Everything works fine.
Partial View
But if I want to report the comment as spam, I have to click on the link inside the Partial View (#submit_link), and after reporting, inside the #reportscount part, I want to show the updated number of reports of that comment. The actionresults returns that number like Content(numberofreports.toString()). It works but I get the number in a blank page?
Thank you very much.
It's better if you don't. The main issue is that, for security reasons, <script> tags are ignored, when HTML is inserted into the DOM. Since the Ajax.* family of helpers work by inserting <script> tags in place, when you return the partial via AJAX, those will not be present. It's better if you only include the HTML contents of the form in the partial, and not the form itself.

ASP.Net Razor MVC Bootstrap Login Modal Validation

Using Bootstrap in my Razor page, I am opening a modal window:
<div class="container-fluid">
<div class="navbar navbar-fixed-top navbar-default">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="offcanvas" data-target=".navbar-offcanvas" data-canvas="body">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand pull-right" href="#">
<img src="assets/img/logo-header.png" alt="Alternate Text for Image">
</a>
</div>
<div class="navbar-offcanvas offcanvas navmenu-fixed-left">
<a class="navmenu-brand" href="#">eServices</a>
<ul class="nav nav-justified">
<li>New Here?</li>
<li>Services</li>
<li>Sign In</li>
</ul>
</div>
</div>
</div>
<div class="modal fade" id="modalLogin" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<p>
<h3 class="modal-title" id="myModalLabel">Login to MyApplication</h3>
</p>
</div>
#using (Html.BeginForm("index", "home", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { role = "form", #class = "form-horizontal" }))
{
#Html.AntiForgeryToken()
<div class="form-group #Html.ValidationErrorFor(m => m.Username, "has-error has-feedback")">
<div class="col-sm-12">
#Html.FormTextBoxFor(p => p.Username, new { #class = "form-control" })
#if (!Html.IsValid(m => m.Username))
{
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
}
#Html.ValidationMessageFor(m => m.Username, null, new { #class = "help-block" })
</div>
</div>
<div class="form-group #Html.ValidationErrorFor(m => m.Password, "has-error has-feedback")">
<div class="col-sm-12">
#Html.FormPasswordFor(p => p.Password, new { #class = "form-control" })
#if (!Html.IsValid(m => m.Password))
{
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
}
#Html.ValidationMessageFor(m => m.Password, null, new { #class = "help-block" })
</div>
</div>
#Html.ValidationSummary(true, string.Empty, new { #class = "test" }, "span")
<div class=" pull-right">
<p>
<button type="submit" class="btn btn-default">#Forms.ButtonSignin</button>
</p>
<br />
<p>
#Html.ActionLink("Forgot your username?", "ForgotUsername")
</p>
<p>
#Html.ActionLink("Forgot your password?", "ForgotPassword")
</p>
</div>
}
</div>
</div>
</div>
The issue I have is that, for example, I entered an incorrect username/password combination, the form validates, but the modal window closes. Is there a way to re-open the modal window after the form has posted if the validation triggered an error?
You could add a property named IsModalShown i.e.
public class AModel
{
public bool IsModalShown { get; set; }
}
Render this as a hidden for in your view i.e.
#Html.HiddenFor(m => m.IsModalShown)
When the modal is opened set the hidden value to true, this will enable the modal state to be posted back to the controller action i.e.
$('#modalLogin').on('show.bs.modal', function (e) {
$('#IsModalShown').val(true);
})
Please note the above will depend on the version of bootstrap you are using but there are other docs on the official site
Then add the following to your view that automatically pops it up
$(function(){
#if(Model.IsModalShown)
{
$('#signin_modal').modal('show');
}
});
I had a similar problem, but didn't have a model in view. Posting my solution, in case it would help someone. I wanted to show an error message stored in TempData (in case of wrong login/password combination, on which Batuta was asking).
Controller:
public ActionResult SignIn(string login, string password)
{
if (Membership.ValidateUser(login, password))
{
// something
}
else
{
TempData["message-error"] = "Wrong combination";
}
return RedirectToAction("Index", "Home");
}
Showing the message in modal window:
#if (TempData["message-error"] != null)
{
#TempData["message-error"]
}
Opening modal in index:
#if (TempData["message-error"] != null)
{
<script type="text/javascript">
$('#myModal').modal('show');
</script>
}
Maybe not that clean, but works for me.

Replacing jQuery UI Accordion to Bootstrap Accordion(or equivalent)

Right now we are using the jQuery UI Accordion control for our drilldowns and we are in a process of changing to Bootstrap equivalent Accordion control. So I would like to know the best practices to do so. Please advice and thanks in advance.
Following is the html used for jQuery UI Accordion
#foreach (Xyz.MenuItem menu in Model)
{
if (menu.Items.Count() > 0)
{
<div class="accordion">
<h3>
#Html.ActionLinkForMenu(menu, true, null)
</h3>
<ul>
#foreach (Xyz.MenuItem subMenu in menu.Items)
{
<li>#Html.ActionLinkForMenu(subMenu, false, null)</li>
}
</ul>
</div>
}
else
{
#Html.ActionLinkForSingleMenu(menu, new { #class = "home" })
}
}
An example would be a Great Help.
Just follow the manual from bootstrap and rewrite your form like this
<div class="panel-group" id="accordion">
#foreach (Xyz.MenuItem menu in Model)
{
if (menu.Items.Count() > 0)
{
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">
#Html.ActionLinkForMenu(menu, true, null)
</a>
</h3>
</div>
<div id="collapseOne" class="panel-collapse collapse in">
<div class="panel-body">
#foreach (Xyz.MenuItem subMenu in menu.Items)
{
<li>#Html.ActionLinkForMenu(subMenu, false, null)</li>
}
</div>
</div>
</div>
}
else
{
#Html.ActionLinkForSingleMenu(menu, new { #class = "home" })
}
}
</div>

knockout.js modal binding value update

I have the following code in this jsFiddle.
The problem I'm having is that my child items do not update properly.
I can Click "Edit User" with a problem and see the data changing, but when I attempt to add a note or even if I were to write an edit note function, the data does not bind properly
http://jsfiddle.net/jkuGU/10/
<ul data-bind="foreach: Users">
<li>
<span data-bind="text: Name"></span>
<div data-bind="foreach: notes">
<span data-bind="text: text"></span>
Edit Note
</div>
Add Note
Edit user
</li>
</ul>
<div id="userModal" data-bind="with: EditingUser" class="fade hjde modal">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>
Editing user</h3>
</div>
<div class="modal-body">
<label>
Name:</label>
<input type="text" data-bind="value: Name, valueUpdate: 'afterkeydown'" />
</div>
<div class="modal-footer">
Save changes
</div>
</div>
<div id="addJobNoteModal" data-bind="with: detailedNote" class="fade hjde modal">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>
Editing Note</h3>
</div>
<div class="modal-body">
<label>
Text:</label>
<input type="text" data-bind="value: text, valueUpdate: 'afterkeydown'" />
</div>
<div class="modal-footer">
Save changes
</div>
</div>
​
function Note(text) {
this.text = text;
}
var User = function(name) {
var self = this;
self.Name = ko.observable(name);
this.notes = ko.observableArray([]);
}
var ViewModel = function() {
var self = this;
self.Users = ko.observableArray();
self.EditingUser = ko.observable();
self.detailedNote = ko.observable();
self.EditUser = function(user) {
self.EditingUser(user);
$("#userModal").modal("show");
};
this.addNote = function(user) {
var note= new Note("original")
self.detailedNote(note);
$("#addJobNoteModal").find('.btn-warning').click(function() {
user.notes.push(note);
$(this).unbind('click');
});
$("#addJobNoteModal").modal("show");
}
for (var i = 1; i <= 10; i++) {
self.Users.push(new User('User ' + i));
}
}
ko.applyBindings(new ViewModel());​
Change this:
$("#addJobNoteModal").find('.btn-warning').click(function() {
To this:
$("#addJobNoteModal").find('.btn-primary').click(function() {
You were targetting the wrong button :)
I think the problem after all was that you must bind to "value:" not "text:" in a form input/textarea.

Resources