When I click on the button to launch my modal, it rather duplicataes the content on the same browser page and this is the "Js error" i get in my console window. Tried many suggestions but still.Please help.
Uncaught TypeError: Cannot read properties of undefined (reading 'classList')
at Pe._isAnimated (modal.js:312:26)
at Pe._initializeBackDrop (modal.js:194:24)
at new Pe (modal.js:82:27)
at Pe.getOrCreateInstance (base-component.js:55:41)
at HTMLButtonElement.<anonymous> (modal.js:414:22)
at HTMLDocument.n (event-handler.js:120:21)
My Code:
Controller:
using BOGBitwiseApp.Data;
using BOGBitwiseApp.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Dynamic;
namespace BOGBitwiseApp.Controllers
{
public class CustomerRequestController : Controller
{
private readonly ApplicationDbContext _context;
public CustomerRequestController(ApplicationDbContext context)
{
_context = context;
}
//Get: Customer Requests
public IActionResult Index()
{
var customerRequest = _context.CustomerRequests.ToList();
return View(customerRequest);
}
[HttpGet]
public IActionResult Create()
{
CustomerRequestModel customer = new CustomerRequestModel();
return PartialView("AddCustomerModelPartial", customer);
}
Index.cshtml:
#model IEnumerable<BOGBitwiseApp.Models.CustomerRequestModel>
#{
ViewData["Title"] = "Index";
}
<div id="PlaceHolderHere">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-
target="#addCustomerRequest" data-bs-url="#Url.Action("Create")">New Customer
Request</button>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>
#Html.DisplayNameFor(m => m.AccountName)
</th>
<th>
#Html.DisplayNameFor(m =>m.AccountNumber)
</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#item.AccountName
</td>
<td>
#item.AccountNumber
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.BitwiseId}) ||
#Html.ActionLink("Delete", "Delete", new { id=item.BitwiseId})
</td>
</tr>
}
</tbody>
PartialView:
I created a partialview "AddCustomerModelPartial.cshtml".
#model CustomerRequestModel
<div class="modal fade" id="addCustomerRequest">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title" id="addCustomerRequestLabel">Bitwise
Information</h2>
<button type="button" class="btn-close" aria-label="Close" data-bs-
dismiss="modal">
</button>
</div>
<div class="modal-body">
<form asp-action="Create" >
<div class="form-group">
<label asp-for="AccountName"></label>
<input asp-for="AccountName" class="form-control" />
<span asp-validation-for="AccountName" class="text-danger">
</span>
</div>
<div class="form-group">
<label asp-for="AccountNumber"></label>
<input asp-for="AccountNumber" class="form-control" />
<span asp-validation-for="AccountNumber" class="text-danger">
</span>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-bs-
dismiss="modal">Cancel Request</button>
<button type="button" class="btn btn-info" data-bs-toggle="modal">Save
Request</button>
</div>
</div>
</div>
</div>
Site.js Code:
This is my js code in the wwwroor folder.
$(function () {
var PlaceHolderElement = $('#PlaceHolderHere');
$('button[data-bs-toggle="modal"]').click(function (event) {
var url = $(this).data('url');
$.get(url).done(function (data) {
PlaceHolderElement.html(data);
PlaceHolderElement.find('.modal').modal('show');
})
})
})
It should be data-url="#Url.Action("Create")" if you want to get the value by using $(this).data('url').
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-
target="#addCustomerRequest" data-url="#Url.Action("Create")">New Customer Request</button>
Another way, if you do not want to change data-bs-url, you can change the js below to receive the url value:
var url = $(this).attr("data-bs-url");
Related
I've got an asp.net mvc webpage set up. All of my actions, like: create, edit, etc... have their own views, except delete, because I'm trying to pop up a modal with help from Bootstrap. I pass an id to the modal, through jQuery/JavaScript, and with the asp-action as the form's attribute, it should theoretically work, but well it doesn't.
Index View:
#if (Model.Tenants.Any())
{
<h3>Tenants (#Model.Tenants.Count)</h3>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Id</th>
<th>UrlFriendlyName</th>
<th>MicrosoftGraphTenantId</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var tenant in Model.Tenants.OrderByDescending(x => x.Name))
{
<tr>
<td>
<button class="btn btn-primary" onclick="document.location.href = '#Url.Action("Index", "User", new {id = tenant.Id})'">Show Users</button>
</td>
<td>
#tenant.Name
</td>
<td>
#tenant.Id
</td>
<td>
#tenant.UrlFriendlyName
</td>
<td>
#tenant.MicrosoftGraphTenantId
</td>
<td>
<div class="btn-group-justified pull-right ">
<button class="btn btn-success" onclick="document.location.href = '#Url.Action("Edit", "Tenant", new {id = tenant.Id})'">Edit</button>
<button type="button" class="btn btn-danger" onclick="deleteTenant('#tenant.Id', '#tenant.Name')" data-toggle="modal" data-target="#deleteModal">Delete</button>
</div>
</td>
</tr>
}
</tbody>
</table>
</div>
<div class="align-items-sm-end">
<button onclick="document.location.href='#Url.Action("Create", "Tenant")'" class="btn btn-outline-success">Create new Tenant</button>
</div>
<div class="modal fade" id="deleteModal" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Are you sure you want to delete the selected Tenant?</p>
</div>
<div class="modal-footer">
<form asp-action="Delete">
<input type="hidden" id="tenantidinput"/>
<button type="submit" class="btn btn-outline-danger">Delete Tenant</button>
</form>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
}
Delete Action in Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteAsync(Guid id)
{
if (ModelState.IsValid && id != Guid.Empty)
{
var tenant = await _context.Tenants.AsQueryable().Where(x => x.Id == id).FirstOrDefaultAsync().ConfigureAwait(false);
_context.Tenants.Remove(tenant);
await _context.SaveChangesAsync().ConfigureAwait(false);
}
return RedirectToAction("Index");
}
Javascript:
function deleteTenant(tenantid, tenantname) {
$(".modal-title").text("Delete " + tenantname);
$("#tenantidinput").attr("name", ''+tenantid+'');
}
Input getting the id as the value of the name:
When debugging, it receives no id whatsoever:
The javascript-function receives the parameters just fine. I think that the problem lies in, the way, the form passes the id to the controller. It somehow doesn't pass the value of the name-attribute.
This is happening for two reasons. Firstly, the hidden input should have the name matching the argument in the action. In your case id:
<input type="hidden" name="id" id="tenantidinput" />
Secondly, your JS should set the value of the field, not its name:
function deleteTenant(tenantid, tenantname) {
$(".modal-title").text("Delete " + tenantname);
$("#tenantidinput").val(tenantid);
}
I'm new to ASP.NET MVC and I'm having trouble editing an item and showing it in a modal form and updating it in the database. The data is not showing in a modal. The data is coming from different tables in the database.
Expected output: show the list in a single view(table) and edit a selected item from the list (modal) and update it.
Here's my code:
AdminController:
public JsonResult EditItem(int? itemID)
{
var id = db.Items.Where(i => i.ItemID == itemID).FirstOrDefault();
List<Item> itemList = db.Items.ToList();
List<ItemDetail> itemDetailList = db.ItemDetails.ToList();
List<ProductType> productTypeList = db.ProductTypes.ToList();
var details = from itm in itemList
join itmDetail in itemDetailList on itm.ItemID equals itmDetail.ItemID into ItemInfo
from itmDetail in ItemInfo.DefaultIfEmpty()
join product in productTypeList on itmDetail.ProductID equals product.ProductID into ProductInfo
from product in ProductInfo.DefaultIfEmpty()
where itm.ItemID.Equals(id)
select new TableCollection { Item = itm, ItemDetail = itmDetail, ProductType = product };
return Json(details, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ActionResult EditItem(Item item, ItemDetail details)
{
ItemDetail itmDetails = db.ItemDetails.Where(d => d.ItemID == item.ItemID).FirstOrDefault();
itmDetails.ItemID = details.ItemID;
db.SaveChanges();
return RedirectToAction("Inventory", "Admin");
}
InventoryList View:
#model IEnumerable<VetClinic.Models.Admin.TableCollection>
#if (Model != null)
{
<table id="inventory" class="table table-striped table-hover">
<thead class="thead-dark">
<tr>
<th>Product Type</th>
<th>Item Name</th>
<th># of Stock</th>
<th>Price</th>
<th>Action</th>
</tr>
</thead>
<tbody class="bg-light">
#foreach (var item in Model)
{
<tr id="row_#item.ItemDetail.ItemID">
<td>#item.ProductType.Name #item.ProductType.Type</td>
<td>#item.ItemDetail.ItemName</td>
<td>#item.ItemDetail.NumOfStock</td>
<td>#item.ItemDetail.Price</td>
<td>
<i class="fa fa-pencil" data-toggle="tooltip" title="Edit" style="color: blue;"></i>
</td>
</tr>
}
</tbody>
</table>
<div class="modal fade" id="EditItem" tabindex="-1" role="dialog" aria-labelledby="EditItem" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Edit Item</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
#using (Html.BeginForm("EditItem", "Admin", FormMethod.Post))
{
<input type="hidden" id="hiddenItemID" />
<div class="form-group row">
<div class="col-lg-3">
<label>Product Type:</label>
</div>
<div class="col-lg-4">
<input type="text" id="productType"/>
</div>
</div>
<div class="form-group row">
<div class="col-lg-2">
<label>Item Name:</label>
</div>
<div class="col-lg-3">
<input type="text" id="itemName" class="form-control" />
</div>
</div>
<div class="form-group row">
<div class="col-lg-5">
<label>Number of Stocks</label>
</div>
<div class="col-lg-2">
<input type="text" id="numOfStocks" class="form-control" />
</div>
</div>
<div class="form-group row">
<div class="col-lg-2">
<label>Price:</label>
</div>
<div class="col-lg-3">
<input type="text" id="price" class="form-control" />
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary">Update</button>
</div>
}
</div>
</div>
</div>
</div>
}
else
{
<i class="fa fa-info-circle"> </i>#ViewBag.EmptyList;
}
<script>
function EditItem(id) {
$.ajax({
url: "/Admin/EditItem/" + id,
type: "GET",
dataType: "json",
success: function (response) {
$("#hiddenItemID").val(response.ItemID);
$("#EditItem").modal("show");
}
});
return false;
}
</script>
I have an event page which contains a list of participants. From there users can be invited to that event by opening a modal view containing a user list. Users are shown in the same modal with each having an 'Invite'(submit) button next to them. How can I let the controller action know which user is invited?
From what I could find, creating a form for each list element is bad and in addition displays warnings, but if I create a form element on top of the 'foreach', I then need to somehow find which user to submit.
Also thought about appending incrementing numbers to each of submit button name, but I still need to somehow map them to 'their' users.
Along with the invited user id, controller post action also needs to receive the event id.
Here's the code:
<div class="modal" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Select user</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<form id="eventMemberForm" method="post" class="col-sm-6 custom-close" data-ajax="true" data-ajax-method="post" data-ajax-complete="completed" data-ajax-url="#Url.Action("SendInvitation", "Sports")">
<input type="hidden" asp-for="Invitation.FkEvent" value="#Model.Event.EventId" />
<input type="hidden" asp-for="Invitation.EventInvitationId" />
<div class="modal-body">
<input class="form-control p-2 mb-2" id="myInput" type="text" placeholder="Search..">
<h4 class="align-content-center">Users</h4>
<div class="form-group">
<table class="w-100">
<tbody id="myField">
#foreach (var item in Model.Users)
{
<tr>
<td class="d-flex">
<div> #Html.DisplayFor(modelItem => item.Text) </div>
<input type="hidden" asp-for="Invitation.FkUser" value="#item.Value" />
<div class="ml-auto">
<input id="btnSave" type="submit" value="Invite" class="btn btn-success" />
</div>
</td>
</tr>
++i;
}
</tbody>
</table>
</div>
</div>
</form>
</div>
</div>
</div>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script>
$(document).ready(function () {
$("#myInput").on("keyup", function () {
var value = $(this).val().toLowerCase();
$("#myField tr").filter(function () {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
completed = () => {
alert("User invited");
};
</script>
You can use jquery ajax to pass the parameters you need, through the click event, get the corresponding value of the control needed next to the current button.
By adding the name attribute to the submit button, and then triggered in jquery.
And add the id to the div that stores the Text value of User to facilitate finding the corresponding value in jquery.
#section Scripts{
<script>
$(document).ready(function () {
$("#myInput").on("keyup", function () {
var value = $(this).val().toLowerCase();
$("#myField tr").filter(function () {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
$("[name=submitBtn]").click(function () {
event.preventDefault();
var obj = {
myUser: {
Text: $($(this).parent().siblings()[0]).text(),
Value: $($(this).parent().siblings()[1]).val()
},
eventId: $("#Invitation_FkEvent").val()
};
$.ajax({
url: $("#eventMemberForm").attr("data-ajax-url"),
method: 'post',
data: obj,
})
});
});
completed = () => {
alert("User invited");
};
</script>
}
<h1>Index</h1>
<button data-toggle="modal" data-target="#myModal" class="btn btn-primary">Submit</button>
<div class="modal" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Select user</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<form id="eventMemberForm" method="post" class="col-sm-6 custom-close" data-ajax="true" data-ajax-method="post" data-ajax-complete="completed" data-ajax-url="#Url.Action("SendInvitation", "Sports")">
<input type="hidden" asp-for="Invitation.FkEvent" value="#Model.Event.EventId" />
<input type="hidden" asp-for="Invitation.EventInvitationId" />
<div class="modal-body">
<input class="form-control p-2 mb-2" id="myInput" type="text" placeholder="Search..">
<h4 class="align-content-center">Users</h4>
<div class="form-group">
<table class="w-100">
<tbody id="myField">
#foreach (var item in Model.Users)
{
<tr>
<td class="d-flex">
<div id="textValue"> #Html.DisplayFor(modelItem => item.Text) </div>
<input type="hidden" asp-for="Invitation.FkUser" value="#item.Value" />
<div class="ml-auto">
<input id="btnSave" type="submit" value="Invite" class="btn btn-success" name="submitBtn"/>
</div>
</td>
</tr>
++i;
}
</tbody>
</table>
</div>
</div>
</form>
</div>
</div>
</div>
Controller:
public IActionResult SendInvitation(User myUser, string eventId)
{
//do what you want
return View();
}
I have aproblem with angularjs ng-click does not works, my model is not updated.
When I want to read the model variables are empty.
I'm using bootstrap popup to show the model values(title, action is using for validation in a funciton inside controller).
HTML code
<button ng-click="title = 'Add Project'; action='Add'" data-toggle="modal" data-target="#myModal" id="btnOpenPopUpForAdding" class="btn btn-default" title="Add new project"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span></button>
<table class="table" id="tblProjects" style="display:none;">
<thead>
<tr>
<th>
</th>
<th>
Project Name
</th>
<th>
Project Description
</th>
</tr>
</thead>
<tr ng-repeat="project in projects" >
<td>
<button ng-click="title = 'Update Project'; action='Update'" data-toggle="modal" data-target="#myModal" class="btn btn-default" title="Update project">
<span class="glyphicon glyphicon-edit" aria-hidden="true"></span>
</button>
</td>
<td>
<span>{{project.ProjectName}}</span>
</td>
<td>
<span>{{project.ProjectDescription}}</span>
</td>
</tr>
</table>
#Html.Partial("../ProjectView")
</div>
Partial view
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">{{title}}</h4>
</div>
<div class="modal-body">
<label for="txtProjectName">Project Name</label>
<input ng-model="singleProject.ProjectName" type="text" class="form-control" style="width:65%" id="txtProjectName" placeholder="Type the project name" />
<br />
<label for="txtProjectDescription">Project Description</label>
<textarea ng-model="singleProject.ProjectDescription" class="form-control" style="width:65%" id="txtProjectDescription" placeholder="Type the project description" rows="4"></textarea>
</div>
<div class="modal-footer">
<button id="btnSave" type="button" class="btn btn-primary" ng-click="ThrowEvent()">Save</button>
<button id="btnCancel" type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
</div>
Controller code
$scope.ThrowEvent = function () {
if ($scope.action == 'Add')
$scope.AddProject($scope.singleProject);
if($scope.action == 'Update')
$scope.UpdateProject($scope.singleProject);
//if($scope.action == 'Delete')
}
The issue is that ng-repeat creates separate child scopes. In your case ng-click="title = 'Update Project'; action='Update'" where title and action are assigned to the child scope, not the parent.
To fix this you must prefix your model in your controller, for example
$scope.myActions = {title: 'Default Title', action: 'Default action'};
Then you can change ng-click="title = 'Update Project'; action='Update'" to ng-click="myActions.title = 'Update Project'; myActions.action='Update'"
ng-repeat will create a new scope for each iteration.
"title = 'Update Project'; action='Update'" will execute successful, but it will write the values to the sub-scope of ng-repeat and is not visible by the controller.
To solve the issue you can create a data container in the controller
$scope.data = {};
and write to the container
ng-click="data.title = 'Update Project'; data.action='Update'"`
I have this view in mvc in which I display details for a model. The modal popup was working fine until I didn't put it in form block. Now its only posting back instead of displaying the popup.
This is the view I have:
#using App.Portal.WebUI.Controllers
#using MvcPaging
#model IPagedList<App.Models.Device>
#{
ViewBag.Title = "Manage Devices";
}
<h2>Manage Devices</h2>
#Html.ActionLink("Add New Device", "Manage", "Handhelds", new { #class = "editUser btn btn-info" })
<button id="showInactive" class="btn btn-primary">Show Inactive Devices</button>
<br /><br />
#using (Ajax.BeginForm("Home", "Handhelds",
new AjaxOptions {UpdateTargetId = "grid-list", HttpMethod = "get", LoadingElementId = "loading", OnBegin = "beginPaging", OnSuccess = "successPaging", OnFailure = "failurePaging"},
new {id = "frm-search"}))
{
<div class="input-append">
<input class="span2" id="appendedInputButton" type="text" name="handheld" placeholder="Enter Text" />
<button class="btn" type="submit">
<i class="icon-search"></i> Search</button>
</div>
<br />
<div id="grid-list">
<div class="table-responsive">
<table id="dataTable" class="table table-striped">
<tr>
<td>No</td>
<td>Device ID</td>
<td>Serial Number</td>
<td>Options</td>
</tr>
#foreach (var device in Model)
{
<tr>
<td>#device.DeviceID</td>
<td>#device.DeviceIDView</td>
<td>#device.DeviceSerialNumber</td>
<td>
#Html.ActionLink("Edit", "Manage", new {id = #device.DeviceID}, new {#class = "editUser btn btn-info"})
<button id="btnDeleteHandheld" class="deleteHandheld btn btn-danger" data-id="#device.DeviceID">Delete</button>
</td>
</tr>
}
</table>
</div>
</div>
}
<script type="text/javascript">
$(document).ready(function () {
$('button.btnAddDevice').click(function () {
$('#addNewDevice').modal('show');
});
$('button.deleteHandheld').click(function () {
$("#hfDeviceId").val($(this).data('id'));
$('#deleteConfirm').modal('show');
});
$('button.deleteDeviceConfirm').click(function () {
$.ajax({
url: '#Url.Action("Delete", "Handhelds")',
data: { deviceid: $("#hfDeviceId").val() },
dataType: "json",
type: 'POST',
success: function (data) {
if (data === "OK") {
$('#deleteConfirm').modal('hide');
$('#deleteConfirmation').modal('show');
setTimeout(function () {
location.reload();
}, 3000);
}
},
error: function (textStatus, errorThrown) {
Success = false;//doesn't goes here
}
});
});
});
</script>
<div id="deleteConfirm" class="modal fade" data-backdrop="static" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<h4>Are you sure you want to remove the device?</h4>
<button class="btn btn-success deleteDeviceConfirm">Yes</button>
<button class="btn btn-danger" data-dismiss="modal">No</button>
<input type="hidden" id="hfDeviceId" />
</div>
</div>
</div>
</div>
<div id="deleteConfirmation" class="modal fade" data-backdrop="static" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<h4>Device removed</h4>
<button class="btn btn-danger btn-block" data-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>
I need the button with id of btnDeleteHandheld to trigger the associated modal popup. What do I need to change?
I think the button make an input submit by default. To prevent the post use the preventDefault like so :
$('button.deleteHandheld').click(function (e) {
e.preventDefault();
$("#hfDeviceId").val($(this).data('id'));
$('#deleteConfirm').modal('show');
});
You can also replace you button with this :
<input type="button" "id="btnDeleteHandheld" class="deleteHandheld btn btn-danger" data-id="#device.DeviceID">Delete</input>