How to post table cell value in a Razor page - asp.net-core

Looking for ideas on how to pass the 'RecordId' value for the specific row in the table, when the 'view details' button for that row is pushed. This project is .NET Core 5 Web app with Razor pages. I'm not set on the button, open to other ideas to post the value and display the details.
Here is snippet of code generating the table rows:
#foreach(var x in Model.masterrecords)
{
<tr class="border text-center">
<td>#x.RecordId</td>
<td>#x.FirstName</td>
<td>#x.LastName</td>
<td>#x.NumberOfRecords</td>
<td>
<input type="submit" asp-page-handler="ViewDetailsBtn" value="view details" class="btn btn-sm" />
</td>
</tr>
}

Try to use a form to post RecordId:
#foreach (var x in Model.masterrecords)
{
<tr class="border text-center">
<td>#x.RecordId</td>
<td>#x.FirstName</td>
<td>#x.LastName</td>
<td>#x.NumberOfRecords</td>
<td>
<form method="post" asp-page-handler="ViewDetailsBtn" asp-route-RecordId=#x.RecordId>
<input type="submit" value="view details" class="btn btn-sm" />
</form>
</td>
</tr>
}
handler(If your RecordId is string type,try to use string RecordId):
public void OnPostViewDetailsBtn(int RecordId)
{
}
result:

Related

How can I make a DIV fullscreen in Blazor Server app on button click?

In my new Blazor application I have a table with real live weather data. I want to have a button which puts the table or the div that encapsulates this table to go fullscreen. It would be really easy by using Javascript, but I'm new to Blazor so I don't know how to make it work with C#.
Any ideas?
[BUTTON]
<button id="forecastbuttonfullscreen" type="submit" class="btn btn-primary" #onclick="fullscreenforecast"> Fullscreen forecast </button>
<div class ="weathercontainer">
<table class="Weathertable">
<tr>
<td>"2022-03-12"</td>
<td>
<div class="icon sunny">
</div>
</td>
<td> "-10" °</td>
<td> "-2" °</td>
</tr>
</table>
</div>
#code {
private void fullscreenforecast()
{
?????
}
}

How to clear dynamic values passed into vue-js-modal

In my vueJs project, i have a table that displays some products data from the database. When i click on a product tr, it should open a modal that displays a form to enter further details for the product clicked like so:
<table class="table table-responsive table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Product Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr v-for="prod in products" :key="prod.id">
<td>{{ prod.id }}</td>
<td>{{ prod.name }}</td>
<td><button class="btn btn-success btn-sm" #click.prevent="addStocks(prod)">Add Stock</button></td>
</tr>
</tbody>
</table>
Now in my script, i have a method to open the modal and pass the value of the item clicked to the modal like so;
addStocks(prod){
this.$modal.show('add-stocks')
this.newStock.unitPrice = prod.sellin_price
this.newStock.id = prod.id
this.newStock.name = prod.name
},
and my data object
data() {
return {
newStock: {
id: null,
name: '',
size: '',
srln: '',
colour: '',
mfg: '',
expiry: '',
selling_price: ''
},
}
}
and the modal component
<modal name="add-stocks" height="auto" :draggable="true" :width="600">
<div class="modal-header">
<h4>Add new stock</h4>
</div>
<div class="modal-body form-horizontal">
<div class="form-group">
<label for="unitPrice" class="control-label col-md-2">Unit Price</label>
<div class="col-md-4">
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">₦</span>
<input class="form-control" v-model="newStock.unitPrice" readonly aria-describedby="basic-addon1">
</div>
</div>
<div style="clear:both"></div>
</div>
<div class="form-group">
//form fields here
</div>
<div class="modal-footer modal_btns">
<button class="btn btn-primary" #click.prevent="uploadStock">Save</button>
<button class="btn btn-danger" #click.prevent="cancelUpload">Cancel</button>
</div>
</modal>
Now, the issue is when i fill the fields in the modal and click on the cancel button (without saving), i expect the fields to be cleared so when i click on another product tr, i get a fresh form, but this is not the case, the details filled into the previously closed modal form displays. In the cancelUpload methods, i have cleared the fields before closing the modal;
cancelUpload(){
this.$modal.hide('add-stocks')
this.newStock.unitPrice = prod.sellin_price
this.newStock.id = prod.id
this.newStock.name = prod.name
}
When i click on the save button and after api call is made, i call this method to hide the modal but the same issue occurs as the details display when next i open another modal.
How do i fix this?
First of all check whether your method is called everytime the modal is being closed i.e either by clicking on cancel button,cross sign or esc key.
Next this could be the issue of vue reactivity.
An object property should be updated using set method in vue js to keep it reactive.
Hence try as below.
cancelUpload(){
this.$modal.hide('clear-stocks')
this.$set(this.newStock,unitPrice,'');
this.$set(this.newStock,id,'');
this.$set(this.newStock,name,'');
}
You can clear other properties also in the above method.
Or else in the addStocks method also you can set the rest of properties to empty.
More on Vue.set here.

How do you open a kendo drop down popup on page load?

I have several uses for kendo drop-downs in my application (DDL, ComboBox, etc.).
I want them to open up on page load, but Kendo's documentation doesn't indicate that is possible.
I am using the MVC server variables.
This is my view coding:
<script id="itemTemplate" type="text/x-kendo-template">
# var index=FullName.indexOf(" *****");
if (index > 0)
{
#
<span style="font-weight:bold;">
#: FullName.substring(0, index)#
</span>
#
} else {
#
<span style="font-weight:normal;">
#: FullName#
</span>
#
}
#
</script>
<table class="form-horizontal table-condensed" style="width:100%;">
<tr style="height:400px;">
<td style="width:40%;vertical-align:top;">
<h4 style="width:100%;text-align:center;">Available Members</h4>
<h4 style="width:100%;text-align:center;font-size:smaller;">Current Cancer Center Members are highlighted in Bold.</h4>
#(Html.Kendo()
.MultiSelect()
.Name("AvailableWGMembers")
.DataTextField("FullName")
.DataValueField("id")
.ItemTemplateId("itemTemplate")
.TagTemplateId("itemTemplate")
.BindTo((System.Collections.IEnumerable)ViewBag.AvailableWGMembers)
.AutoBind(true)
.Placeholder("Click here to select one or more members to add, ...")
.AutoClose(false)
.HtmlAttributes(new { style = "width:100%;", #class = "Roles" })
.Events(events => { events.Change("doRoles");})
.Value(new int[0])
.Height(650)
)
</td>
<td style="width:20%;text-align:center;vertical-align:top;">
<input id="btnAdd" type="submit" value="Select" class="btn btn-default" disabled="disabled" />
</td>
<td style="width:40%;vertical-align:top;">
<h4 style="width:100%;text-align:center;">#Model.WGTitle</h4>
<h4 style="width:100%;text-align:center;font-size:smaller;">Current Cancer Center Members are highlighted in Bold.</h4>
#(Html.Kendo()
.MultiSelect()
.Name("ExistingWGMembers")
.AutoBind(false)
.DataTextField("FullName")
.DataValueField("id")
.ItemTemplateId("itemTemplate")
.TagTemplateId("itemTemplate")
.BindTo((System.Collections.IEnumerable)ViewBag.ExistingWGMembers)
.Placeholder("Click here to select one or more members to remove, ...")
.AutoClose(true)
.HtmlAttributes(new { style = "width:100%;", #class = "UnusedRoles" })
.Events(events => { events.Change("doRoles"); })
.Value(new int[0])
.Height(650)
)
</td>
</tr>
</table>
I want the lists to both be open when the page loads, and I want to be able to use unobstrusive jQuery or javascript to control it if I have to.
Does anyone have any suggestions?
It took a little digging, but I finally figured out the answer. It was actually pretty simple.
The following should be added to the unobstrusive javascript code file:
function openPopup(e)
{
if (e.sender.list[0].childNodes['1'].childNodes['0'].childElementCount > 0) {
e.sender.popup.open();
}
}
You add the following code to your event listing:
.Events(events => { ...; events.DataBound("openPopup"); })
This can be done with any of the lists that have popups like Kendo DropDownList or ComboBox or MultiSelect.
I would check for the list length to make sure the list has members so you don't get an ugly empty list shown, but otherwise the result is actually pretty simple.
This answer is dependent upon the code example at: http://demos.telerik.com/aspnet-mvc/window/index
I took that example from the Index.cshtml version of their example and simply replaced the Content value of the # with your table template from the original question:
#(Html.Kendo().Window()
.Name("window")
.Title("Your modal popup with dropdown menus")
.Content(#<text>
<table class="form-horizontal table-condensed" style="width:100%;">
<tr style="height:400px;">
<td style="width:40%;vertical-align:top;">
<h4 style="width:100%;text-align:center;">Available Members</h4>
<h4 style="width:100%;text-align:center;font-size:smaller;">Current Cancer Center Members are highlighted in Bold.</h4>
#(Html.Kendo()
.MultiSelect()
.Name("AvailableWGMembers")
.DataTextField("FullName")
.DataValueField("id")
.ItemTemplateId("itemTemplate")
.TagTemplateId("itemTemplate")
.BindTo((System.Collections.IEnumerable)ViewBag.AvailableWGMembers)
.AutoBind(true)
.Placeholder("Click here to select one or more members to add, ...")
.AutoClose(false)
.HtmlAttributes(new { style = "width:100%;", #class = "Roles" })
.Events(events => { events.Change("doRoles");})
.Value(new int[0])
.Height(650)
)
</td>
<td style="width:20%;text-align:center;vertical-align:top;">
<input id="btnAdd" type="submit" value="Select" class="btn btn-default" disabled="disabled" />
</td>
<td style="width:40%;vertical-align:top;">
<h4 style="width:100%;text-align:center;">#Model.WGTitle</h4>
<h4 style="width:100%;text-align:center;font-size:smaller;">Current Cancer Center Members are highlighted in Bold.</h4>
#(Html.Kendo()
.MultiSelect()
.Name("ExistingWGMembers")
.AutoBind(false)
.DataTextField("FullName")
.DataValueField("id")
.ItemTemplateId("itemTemplate")
.TagTemplateId("itemTemplate")
.BindTo((System.Collections.IEnumerable)ViewBag.ExistingWGMembers)
.Placeholder("Click here to select one or more members to remove, ...")
.AutoClose(true)
.HtmlAttributes(new { style = "width:100%;", #class = "UnusedRoles" })
.Events(events => { events.Change("doRoles"); })
.Value(new int[0])
.Height(650)
)
</td>
</tr>
</table>
</text>)
.Draggable()
.Resizable()
.Width(600)
.Actions(actions => actions.Pin().Minimize().Maximize().Close())
.Events(ev => ev.Close("onClose"))
)
I hope this helps!

The Index view does not receive the list partial from the ajax call made from Searchbox partial?

i have the following partial view for the the _searchbox partial
#model ecomm2.Models.MainSearchBoxViewModel
<div id="search-box-wrapper" style="text-align:center">
<div id="search-box-div" style="display:inline-block">
#using (Ajax.BeginForm("GetResults", "Partials",
new AjaxOptions {
HttpMethod="get",
InsertionMode=InsertionMode.Replace,
OnSuccess="updateMainResultsDiv",
UpdateTargetId="divMainResultsList"}))
{
<table>
<tr>
<td>
<fieldset>
<label>Search: </label>
</fieldset>
</td>
<td>
<fieldset>
#Html.DropDownListFor(m => m.ProdCatId, Model.MainSearchDDLCollection, new { style="width:200px;"})
</fieldset>
</td>
<td> </td>
<td>
<fieldset>
<input type="text" name="SearchText" style="width:400px"/>
</fieldset>
</td>
<td> </td>
<td><input type="submit" value="Search" /></td>
</tr>
</table>
}
</div>
</div>
<br />
then i have added this _SearchBox partial view to the layout so each page gets a searchbox with a drown category list to filter the search.
note: _searchbox partial is called by Another action in the "Partials" controller and works fine.
the action method "GetResults" is in the "Partials" controller and this is the method that is called by ajax from _SearchBox partial
[AjaxOnly]
public ActionResult GetResults(int ProdCatId, string SearchText)
{
var Products = db.mt_Products
.Where(e => e.SearchString.Contains(SearchText) & e.ProdCatId == ProdCatId)
.Select(e => new HomeSearchResultsViewModel
{
Id=e.Id,
ProdCode=e.ProdCode.Trim(),
ProductLineName= e.mt_Brands.BrandName.Trim() +" "+ e.ProdName.Trim(),
ListPrice=e.ListPrice,
ProdImage=e.ProdImg,
StockCount=e.Stock,
BrandName=e.mt_Brands.BrandName.Trim(),
CategoryName=e.mt_ProductCategories.CatName.Trim()
}).ToList();
return PartialView("_SearchResults", Products);
}
then i have the following code in Index view of the Home controller
#model IEnumerable<ecomm2.Models.HomeSearchResultsViewModel>
#{
ViewBag.Title = "Index";
}
<h2>Welcome Admin,</h2>
<p>
</p>
<div id="divMainResultsList">
#Html.Partial("_SearchResultsList", Model)
</div>
<script type="text/javascript">
function updateMainResultsDiv() {
$('#divMainResultsList').html()
}
</script>
when i passed a value to the search box and performed a search, it showed that search values were received by the action method GetResults and LINQ generates results but result were not placed on div area. Is this div placed on right spot?
it seems a bit complicated to post all and here is the video

How do I implement something like this?

Well I have to implement something as follows:
I need to display a list of Contact IDs of all the contacts I have in my model.
<ul>
#for (int i = 0; i < Model.Contacts.ToList().Count; i++)
{
<li><a onclick="showContactInfoDialog(#Model.Contacts.ToList()[i].ContactId)">Model.Contacts.ToList()[i].ContactId</a></li>
}
</ul>
Each list element will be clickable, upon clicking which, a dialog will popup.
function showContactInfoDialog(id) {
document.getElementById('contact-dialog').style.display = 'block';
}
The dialog should show that particular contact's First Name, Last Name, Title, Email.
<div id="contact-dialog">
<form action="Contact/SaveContactEdits" method="post">
<table>
<tr>
<td>First Name</td>
<td>
<input type="text" name="FName"value="#Model.Contacts.ToList()[id].FirstName" /></td>
</tr>
<tr>
<td>Last Name</td>
<td>
<input type="text" name="LName" value="#Model.Contacts.ToList()[id].LastName" /></td>
</tr>
<tr>
<td>Title</td>
<td>
<input type="text" name="Title" value="#Model.Contacts.ToList()[id].Title" /></td>
</tr>
<tr>
<td>Email Address</td>
<td>
<input type="text" name="Email" value="#Model.Contacts.ToList()[id].Email" /></td>
</tr>
</table>
<input type="submit" value="Save"/>
</form>
</div>
The dialog should let user make edits to the contact's details.
How do I do this? I'm having problem in passing the 'id' parameter to the dialog box element.
<div id="contact-dialog">
I'm having problem in passing the 'id' parameter to the dialog box
element.
The way you are using the id is not correct as you use it like the following. In the given code below (taken from your code) you are using the id as the index and that won't work most of the time especially if the ids does not start with 0.
Model.Contacts.ToList()[id]
That also won't work because the onclick event happens on the client side where the model is no longer available. So what you can do, since calling another controller method is not an option is to write all the details in a hidden field. Put them on a single container, for example one div per contact, the assign the id of the contact to the div. When the a tag is clicked, you read the values from the div and assign them to the form. All of this can be handled easier with tools like knockout, but if using it is not an option then here's the code that will do the trick.
// in your loop do this
// btw, it would be better if you Contacts object is an IList so you can do indexing easier
<li><a onclick="showContactInfoDialog(#Model.Contacts.ToList()[i].ContactId)">Model.Contacts.ToList()[i].ContactId</a>
<div id="#("contactrow"+Model.Contacts.ToList()[i].ContactId)">
#Html.HiddenFor(m=>Model.Contacts.ToList()[i].FirstName)
// do the same for the rest of the fields you want to show on the dialog
</div>
</li>
before you show the dialog, copy the contents to the form:
function showContactInfoDialog(id) {
// we are targetting this -> <input type="text" name="FName"
// assign an id (fname) for optimal performance
var container = $("#contactrow"+id);
        $("#fname").val(container.find('#FirstName').val());
// do the same for the rest of the fields
document.getElementById('contact-dialog')
.style.display = 'block';
}