How to pass all text of input selected row into action? - asp.net-core

i have this view in my project.
I want to get the text of input in each row that is selected.
How to pass all text of input selected row into action
<table width="100%" class="table table-striped table-bordered table-hover" id="dataTables-example">
<thead>
<tr>
<th width="45%">Select</th>
<th width="45%">User Name</th>
<th width="5%">Description</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.TypeList)
{
<tr>
<td>
<input type="checkbox" name=checklist" id="checklist"/>
</td>
<td>
#Html.DisplayFor(modelItem => item.UserName)
</td>
<td>
<input type="text" name="Extradecription"/>
</td>
</tr>
}
</tbody>
my Actions. How can I have the corresponding values of text and checkbox for the Selected rows
public IActionResult Index()
{
return View(repository.GetUser());
}
public IActionResult Save(int[] checklist,string[] Extradecription)
{
repository.Save(checklist,Extradecription);
return View(repository.GetUser());
}

If you try to get two different arrays as you have showed in you controller-action code, there will be a trouble with text for non selected items, the array for check boxes will bind as expected but for descriptions will be different, just to be clear, check the following example:
Assuming We have a list with tree options:
100 - Foo
200 - Bar
300 - Zaz
If We set the following selection for items:
Foo, a
Zaz, c
If We take a look on the request, this is the raw request:
checklist = 100,300
Extradecription = a,null,c
So, the trouble is avoid to bind null descriptions for non selected options, this is complicated, in that case I recommend to you a clear solution:
Create a model to create entity process
Create a model for option
Add a list of option model in create entity model
Initialize the model to create a new entity
Render inputs in view using asp-for tag
Retrieve the request to create a new entity
I'll assume the name of models and properties to show how to bind a typed array in your request, change the names according to your scenario.
Create entity model:
public class CreateEntity
{
public CreateEntity()
{
Items = new List<SelectedItem>();
}
// Step 3
[BindProperty]
public List<SelectedItem> Items { get; set; }
// Another properties
}
Model for option:
public class SelectedItem
{
public bool IsSelected { get; set; }
public int Code { get; set; }
public string Name { get; set; }
public string Desc { get; set; }
}
Rendering the options list:
#for (var i = 0; i < Model.Items.Count; i++)
{
<input asp-for="#Model.Items[i].IsSelected" />#Model.Items[i].Name
<input asp-for="#Model.Items[i].Desc" />
<br/>
}
The GET and POST actions in controller:
[HttpGet]
public IActionResult CreateOption()
{
// Set the items list
var model = new CreateEntity
{
Items = new List<SelectedItem>
{
new SelectedItem{ Code = 100, Name = "Foo" },
new SelectedItem{ Code = 200, Name = "Bar" },
new SelectedItem{ Code = 300, Name = "Zaz" }
}
};
return View(model);
}
[HttpPost]
public IActionResult CreateOption(CreateEntity form)
{
// Retrieve only selected items
var query = form.Items.Where(item => item.IsSelected == true).ToList();
return View();
}
If you want to know more about check boxes in Razor pages, please check this link: Checkboxes in a Razor Pages Form
Please let me know if this answer is useful.

Related

Error redirecting to page in ASP.NET Core razor pages

I want to redirect to this page
root that I want to redirect to,
but I got this error :
InvalidOperationException: No page named 'Miner/MinerDetail' matches the supplied values.
I want to redirect to this page miner/MinerDetail with a model that it is minerPartsView
Want to redirect to this page miner/MinerDetail with a model that it
is minerPartsView
Well, as per your shared screenshot, it appeared that, you were not able to redirect to your MinerDetails page due to two main reason.
Firstly, if your Request.IsAjaxRequest() executes then your next block will not executes, you have already returned the statements.
Second, reason you are not redirecting to the MinerDetails page in correct manner. As you haven't share your MinerDetails page details design thus I am sharing how you could redirect to a new razorpage with new object.
Model:
Let's assume, we have below model which we would like to pass from our intial page to MinerDetails page.
public class MinerCustomModel
{
public string? PowerSerialNumber { get; set; }
public string? MinerSerialNumber { get; set; }
public string? WorkerName { get; set; }
}
Note: In your scenario, model would be minerPartsView model
Intial Index/ Loading Page:
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}
public async Task<IActionResult> OnGet()
{
var myData = new MinerCustomModel()
{
MinerSerialNumber = "SM-001",
PowerSerialNumber = "PSN-002",
WorkerName = "Worker Name"
};
string data = System.Text.Json.JsonSerializer.Serialize(myData);
return RedirectToPage("Miner/MinerDetails", new { objectData = data });
}
}
MinerDetails Page:
public class MinerDetailsModel : PageModel
{
[BindProperty]
public MinerCustomModel? minerCustomModel { get; set; } = new MinerCustomModel();
public void OnGet(string objectData)
{
var enitity = System.Text.Json.JsonSerializer.Deserialize<MinerCustomModel>(objectData);
minerCustomModel.PowerSerialNumber = enitity.PowerSerialNumber;
minerCustomModel.MinerSerialNumber = enitity.MinerSerialNumber;
minerCustomModel.WorkerName = enitity.WorkerName;
}
}
Note: Make sure, we are defining the MinerCustomModel which should a class not pageModel with [BindProperty] which should intializing as new MinerCustomModel() to avoid null reference exception.
MinerDetailsModel Page View:
#page
#model MinerDetailsModel
<h1>Miner Details</h1>
<table class="table">
<thead>
<tr>
<th>
PowerSerialNumber
</th>
<th>
MinerSerialNumber
</th>
<th>
WorkerName
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
#Model.minerCustomModel?.PowerSerialNumber
</td>
<td>
#Model.minerCustomModel?.MinerSerialNumber
</td>
<td>
#Model.minerCustomModel?.WorkerName
</td>
</tr>
</tbody>
</table>
Note: In MinerDetails view we should refer #model MinerDetailsModel page model not the MinerCustomModel or IndexModel.
Output:

Why is my controller return wrong response data?

I`m using Ajax call to remove items from list. When user clicks on remove button (each button for row with id) it sends Ajax call (Post) to Order/RemoveFromCart. When backend is reached i remove the item from list. Im sure when returning data from controller the item i want to remove is truly removed. The problem is when i take my div and call html(data) from response it removes always the last item in the list.
Thank you for help.
I have tried update dotnet to latest version.
I have tried to remove Ajax call and reload whole view - that fixes the problem but i want to use an Ajax call.
#for (int i = 0; i < Model.CartItems.Count; i++)
{
<input asp-for="CartItems[i].ProductId" type="hidden">
<tr>
<td>
<input type="text" class="inputTextWithoutBorder" readonly="readonly" asp-for="CartItems[i].Product">
</td>
<td>
<select class="select-table" asp-for="#Model.CartItems[i].Packaging" asp-items="#Model.CartItems[i].PackageTypes"></select>
</td>
<td>
<input type="text" class="inputTextWithoutBorder" asp-for="#Model.CartItems[i].Amount" placeholder="Vyberte množství...">
</td>
<td>
<button id="removeFromCartId" onclick="removeFromCart(this);" type="button" value="#i" class="removeButton"></button>
</td>
</tr>
}
[HttpPost]
public IActionResult RemoveFromCart(OrderModel model, int itemToRemove)
{
if (model.CartItems[itemToRemove] != null)
{
model.CartItems.RemoveAt(itemToRemove);
}
return PartialView("_OrderCartWithCalendarPartial", model);
}
Model:
public class CartModel
{
public int ProductId { get; set; }
public int Amount { get; set; }
public string Packaging { get; set; }
public string Product { get; set; }
public List<SelectListItem> PackageTypes { get; } =
new List<SelectListItem>{
new SelectListItem {Value = "", Text = ""},
};
}
Javascript:
function removeFromCart(button) {
var index = button.value;
var placeholderElement = $('#orderFormId');
var myformdata = placeholderElement.serialize()
+ "&itemToRemove=" + index;
var result = $.post("/Order/RemoveFromCart", myformdata);
result.done(function (data) {
$("#cartWithCalendarDiv").html(data);
setDateFieldToZero();
});
}
Problem scenario:
Sending via Ajax list with two items (item0, item1). The controller receives exact list with two items. Remove item0 in controller and return partial view with that updated model. The page reloads only with item0. Why?

Display SQL table with Umbraco MVC

I need to deliver something today and I am really stuck.
My goal is to show data from a table in Umbraco MVC (I am new to it)
Do I need to create a controller?
Because All I did was create a Document type in Umbraco with a Template.
This is what I have in my Model:
public class RechargeModel
{
public string Name { get; set; }
public string Username { get; set; }
public string Email { get; set; }
}
This is on my template:
#using Repower.Cms.Umbraco.Models;
#using Umbraco.Core.Persistence;
#{
using (var ipDb = new Database("UmbracoCMS"))
{
RechargeModel recharge;
recharge = ipDb.Fetch<RechargeModel>(new Sql().Select("TOP 100").From("umbracoUsers"));
}
}
I am getting an error saying that he cant convert type List to RechargeModel.
This is my HTML which I want to place on my page but I don't if I need to place it also inside the template or not or where to put it:
#model IEnumerable<Repower.Cms.Umbraco.Models.RechargeModel>
<table class="table table-hover">
<thead>
<tr>
<td>User Name</td>
<td>User Login</td>
<td>User Email</td>
</tr>
</thead>
<tbody>
#{
foreach (var item in Model)
{
<tr>
<td>#item.Name</td>
<td>#item.Username</td>
<td>#item.Email</td>
</tr>
}
}
</tbody>
</table>
Could someone please help? Also what about the rest of the code?
Thanks in advance!
You can access the current database using ApplicationContext.Current.DatabaseContext.Database rather than newing up a Database object.
The issue is that .Fetch() returns an List (array) of RechargeModel, where as you are trying to assign this list to a single RechargeModel.
Either use:
var database = ApplicationContext.Current.DatabaseContext.Database;
var recharges = database.Fetch<RechargeModel>(new Sql().Select("TOP 100").From("umbracoUsers"));
Or change your variable so it accepts a List:
var database = ApplicationContext.Current.DatabaseContext.Database;
List<RechargeModel> recharges = null;
recharges = database.Fetch<RechargeModel>(new Sql().Select("TOP 100").From("umbracoUsers"));
Either way, you can then iterate over this list in your view:
#foreach (var recharge in recharges )
{
<tr>
<td>#recharge.Name</td>
<td>#recharge.Username</td>
<td>#recharge.Email</td>
</tr>
}

How to pass a textbox value to beginform routevalues

I have a textbox in my mvc view.I want to pass the textbox data in beginform route values.how to do that?
View:
#using (Html.BeginForm("Index", "InwardDetail", FormMethod.Post))
{
<fieldset style="width:80%;margin-left:auto;margin-right:auto;margin-top:20px;min-width:60%">
<div>
<table class="tableView" style="width:100%">
<tr>
<td>
#Html.DevExpress().Label(lbl=>{
lbl.Name = "lblFromDate";
lbl.Text = "From Date";
}).GetHtml()
</td>
<td>
#Html.TextBox("txtFromDate", value: DateTime.Now.ToString("dd/MM/yyyy"), htmlAttributes: new {id="fromDate", Class="textbox",style="width:70px"})
</td>
<td>
#Html.DevExpress().Button(but=>{
but.Name = "butView";
but.Text = "View";
but.UseSubmitBehavior = true;
}).GetHtml()
</td>
</tr>
<tr>
<td colspan="9">
#Html.Partial("InwardDetailPartial")
</td>
</tr>
</table>
</div>
</fieldset>
}
Controller:
public ActionResult Index(string fDate)
{
_unitOfWork = new UnitOfWork();
blInwarddetail = new InwardRegisterBL(_unitOfWork);
var result = blInwarddetail.GetInwardList(fDate);
return View("Index", result);
}
If I click Button the values should be passed to controller.
Your use of #Html.TextBox("txtFromDate", ..) means you generate an input with name="textFromDate". When you submit a form, the name/value pairs of the forms controls are sent - in your case it would be txtFromDate: 27/06/2015.
But the method your posting to does not have a parameter named txtFromDate (only one named fDate). You need to change the method to
[HttpPost]
public ActionResult Index(string txtFromDate)
{
....
}
However there are numerous issues with your code that you should address
First you should create a view model to represent what your wanting to display/edit in a view
public class FilterViewModel
{
[Display(Name = "...")] // some user friendly display name
[Required(ErrorMesage = "Please enter a valid date")]
public DateTime Date { get; set; }
}
Note from the code you have shown it appears your entering a date, not a string so the property should be DateTime (not string). This also ensures that you get client and server validation for the property. I also give your properties a more descriptive name that fDate (I can't begin to guess what that might mean - maybe FinishDate?)
In the GET method
public ActionResult Index()
{
FilterViewModel model = new FilterViewModel();
model.Date = DateTime.Today;
return View(model);
}
And in the view
#model yourAssembly.FilterViewModel
#using (Html.BeginForm())
{
....
#Html.LabelFor(m => m.Date)
#Html.TextBoxFor(m => m.Date, "{0:dd/MM/yyyy}", new { #class = "textbox" })
#Html.ValidationMessageFor(m => m.Date)
....
}
Note that you are now strongly binding to your model property. The second parameter specifies the format string. There seems no need to override the id property (which will be id="Date"), and to add a class name use #class = "..". Note also since you are adding a class name, you should remove style="width:70px" and instead use css. You should also remove the table elements. Html table elements are used for tabular data, not for layout.
And finally the post method will be
[HttpPost]
public ActionResult Index(FilterViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
// model.Date will contain the value enter by the user
}
Finally I would question if this really should be a POST. Form the code, you don't appear to be changing any data and perhaps this should be FormMethod.GET? Or better, use ajax to update the current page based on the filter.

Binding JSON Data Back to the MVC View to dynamically insert data to a table

I am working on an MVC4 application. In the submit action of the button, i am making a call to a controller action, which will return data back to me as Json. Number of rows in the table is dependent on the number of rows returned by the service.
I have created a new View Model to support this.
public class DataResponse
{
public List<ALSResult> Result { get; set; }
public string ResponseText {get;set;}
}
public class ALSResult
{
public string Name {get;set;}
public string DataResult {get;set;}
}
Controller Action
[HttpPost]
public ActionResult Submit(CViewModel calcModel)
{
try
{
DataResponse response = cRepository.GetDetails(calcModel.SelectedPlan,calcModel.EquipmentPrice,calcModel.DownPayment);
return Json(response, JsonRequestBehavior.DenyGet);
}
}
js file
$("#Submit").click(function () {
other code here
Process("/DPPC/Submit", "POST", JSON.stringify(model), "json", "application/json;charset=utf-8", logError, InvokeSuccess);
}
function InvokeSuccess(result) {
i will get json result in result filed
}
index.cshtml
<table id="tblResults">
<tr>
<td id="tdResultEt"></td>
<td id="tdResultEtPrice"></td>
</tr>
<tr>
<td id="tdResultDt"></td>
<td id="tdResultDtPrice"></td>
</tr>
more rows depending on the number of items in the JSON response
</table>
How do i dynamically bind the response from the Service to create rows for the table and bind the results?
I don't test it, and it maybe contain syntax errors
function InvokeSuccess(result) {
var table = $("#tblResults");
for(var i = 0; i < result.Result.lenght; ++i)
{
var item = result.Result[i];
var newTr = $("<tr>");
var newTd1 = $("<td>");
var newTd2 = $("<td>");
newTd1.text(item.Name);
newTd2.text(item.DataResult);
newTr.append(newTd1);
newTr.append(newTd2);
table.append(newTr);
}
}