Asp.net jQuery works outside, but not inside foreach loop - c#

This is the script I am working with.
$(document).ready(function () {
$('#selectall').click(function () {
$('.selectedId').prop('checked', isChecked('selectall'));
});
});
function isChecked(checkboxId) {
var id = '#' + checkboxId;
return $(id).is(":checked");
}
function resetSelectAll() {
// if all checkbox are selected, check the selectall checkbox
// and viceversa
if ($(".selectedId").length === $(".selectedId:checked").length) {
$("#selectall").attr("checked", "checked");
} else {
$("#selectall").removeAttr("checked");
}
if ($(".selectedId:checked").length > 0) {
$('#edit').attr("disabled", false);
} else {
$('#edit').attr("disabled", true);
}
}
And this is the cshtml view.
<table id="notificationsTableId">
<thead>
<tr role="row">
<th rowspan="1" colspan="1">
<input type="checkbox" id="selectall" />
</th>
</tr>
</thead>
<tbody>
<tr class="results-table-row odd">
<td>
<input type="checkbox" class="selectedId" name="selectedId" onclick="resetSelectAll();"/>
</td>
</tr>
<tr class="results-table-row even">
<td>
<input type="checkbox" class="selectedId" name="selectedId" onclick="resetSelectAll();"/>
</td>
</tr>
<tr class="results-table-row even odd">
<td>
<input type="checkbox" class="selectedId" name="selectedId" onclick="resetSelectAll();" />
</td>
</tr>
</tbody>
</table>
Right now the select button will work like it should, if i check it it will check all the dates inside that table.
But what I want to do is I want that button to select all the Check-boxes on the page.
But if I give a checkbox the same ID inside my foreach loop like this:
#foreach (var date in group)
{
var isoDate = date.ToString("yyMMdd");
var day = date.ToString("ddd", new CultureInfo("sv-SE")).Substring(0, 2);
<label style="padding-left: 10px">
<input type="checkbox" id="selectedId" name="isoDate" value="#isoDate"/>#day-#isoDate
</label>
}
It doesn't work, it will still only select those 3 check-boxes on the top of the page. I would assume it would check all the check-boxes correct?
It ends up like this:

You are using selectedId as id instead of class like other checkboxes. Use it as class attribute as shown below
#foreach (var date in group)
{
var isoDate = date.ToString("yyMMdd");
var day = date.ToString("ddd", new CultureInfo("sv-SE")).Substring(0, 2);
<label style="padding-left: 10px">
<input type="checkbox" class="selectedId" name="isoDate" value="#isoDate"/>#day-#isoDate
</label>
}

Related

How to Bind the radio button(In HTML table) the way it retreives the whole row values? (Blazor)

I have a table in my project which works perfectly. I want to retreive the values of the whole row based on the user selected radio button for that particular row. So that I can POST it into my DB table.
For example I have this HTML Table:
Radio button ID Company Name
0 123 Company1
0 343 Company2
Based on the radiobutton selection I need a parameter which holds the whole row value , which i can pass to controller function. If user selects first row then the SaveValue stores ID = 123, CompanyName = Company1. Hope I am clear with my question. As can't paste the whole code I just edited and quickly added some snippets. Please let me know if any additional input required.
Here are some code snippets for better understanding:
<EditForm Model="#SearchFilter" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<table>
<thead>
<tr>
<th></th>
<th>ID</th>
<th>Company Name</th>
</tr>
</thead>
<tbody>
#if (lstResult != null)
{
#foreach (Models.TP Result in lstResult.tp)
{
<tr>
<td>
<input value="1" id="type_radio_1" name="type_radio" type="radio"/>
</td>
<td>#Result .id</td>
<td>#Result .companyName</td>
</tr>
}
}
#else
{
<tr>
<td><div>No record Found</div></td>
</tr>
}
</tbody>
</table>
<div class="form-row">
<div class="text-left col-6">
<button type="submit" class="btn btn-primary mr-1 btn-success">Save</button>
</div>
</div>
</EditForm>
protected async void HandleValidSubmit()
{
await Http.PostAsJsonAsync($"api/company/add", SaveValue);
toastService.ShowSuccess("Company saved successfully!");
}
Here is a simple demo you could follow:
Model:
public class Result
{
public List<TP> tp { get; set; }
}
public class TP
{
public int id { get; set; }
public string companyName { get; set; }
}
Index.razor:
<EditForm Model="#lstResult" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<table>
<thead>
<tr>
<th></th>
<th>ID</th>
<th>Company Name</th>
</tr>
</thead>
<tbody>
#if (lstResult != null)
{
#foreach (TP Result in lstResult.tp)
{
<tr>
<td> //add here!!!!
<input value="1" id="type_radio_1" name="type_radio"
type="radio" #onclick="(() => Add(Result))" />
</td>
<td>#Result.id</td>
<td>#Result.companyName</td>
</tr>
}
}
else
{
<tr>
<td><div>No record Found</div></td>
</tr>
}
</tbody>
</table>
<div class="form-row">
<div class="text-left col-6">
<button type="submit" class="btn btn-primary mr-1 btn-success">Save</button>
</div>
</div>
</EditForm>
#code{
//for easy testing, hard coded the data...
Result lstResult = new Result()
{
tp = new List<TP>()
{
new TP(){id=1,companyName="aa"},
new TP(){id=2,companyName="bb"},
new TP(){id=3,companyName="cc"}
}
};
//create a variable...
TP SaveValue = new TP();
//add this method to get the selected model...
protected async Task Add(TP tp)
{
SaveValue = tp;
}
protected async void HandleValidSubmit()
{
//do your stuff....
await Http.PostAsJsonAsync($"api/company/add", SaveValue);
}
}

RowIndex returning null when trying to find

I'm trying to find the rowIndex of the row that had the delete button that was clicked. However when the delete button is clicked it doesn't find the ID instead it returns null and errors out.
I have tried this:
$("#delete").on("click", function (e) {
var row = $(this).closest("tr");
row.remove();
return false;
});
but this solution doesn't post. Then I have also tried this:
<td><input type="submit" formaction="/LansingMileage/DeleteEntry/#item.RowIndex" value="Delete" name="Deletebtn" id="delete" /></td>
which is causing my null issue.
My Controller:
[HttpPost]
public ActionResult DeleteEntry(string rowIndex)
{
// try
{
//rowIndex = Request.Form["Deletebtn"];
using (db)
{
LansingMileage lansing = db.LansingMileages.Find(rowIndex);
db.LansingMileages.Remove(lansing);
db.SaveChanges();
LansingMileageViewModel model = new LansingMileageViewModel();
model.Records = db.LansingMileages.OrderBy(
//will need to change to a select all
//I'm not following the Take command
m => m.RowIndex).ToList();
model.SelectedLansingMileage = null;
model.DisplayMode = "";
return View("Index", model);
}
}
// catch(Exception e)
{
///Debug.WriteLine(e);
}
}
My Index.cshtml:
<table id="LansingData" class="table">
<thead>
<tr>
<th>Action</th>
<th>Row ID</th>
<th>Expense Month/Yr</th>
<th>Travel Date</th>
<th>Travel Type</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Records)
{
if(Model.SelectedLansingMileage != null)
{
if(item.RowIndex == Model.SelectedLansingMileage.RowIndex)
{
#:<tr class="SelectedLansingMileage">
}
else
{
#:<tr>
}
}
else
{
#:<tr>
}
<td><input type="submit" formaction="/LansingMileage/DeleteEntry/#item.RowIndex" value="Delete" name="Deletebtn" id="delete" /></td>
<td>#item.RowIndex</td>
<td>#item.ExpMonthYr</td>
<td>#item.TravelDate</td>
<td>#item.TripType</td>
#:</tr>
#*<tr id="#item.RowIndex">
<td><a class="Delete" href="javascript:;">Delete</a></td>
<td>#item.ExpMonthYr</td>
<td>#item.TravelDate</td>
<td>#item.TripType</td>
<!--Here is where I will create a table to display my data from the above section-->
</tr>*#
}
</tbody>
</table>
The desired result is that when the user clicks on the delete button it removes the row and post to the database.
You can use the Select overload, something like:
#foreach (var item in Model.Select((item,index)=>new{item,index})
{
<tr>
<td>
<input type="submit" formaction="/LansingMileage/DeleteEntry/#item.index" value="Delete" name="Deletebtn" id="delete" />
</td>
</tr>
}
Or do it manually like this:
#{int RowNo = 0;}
#foreach (var item in Model) {
<tr>
<td><input type="submit" formaction="/LansingMileage/DeleteEntry/#RowNo" value="Delete" name="Deletebtn" id="delete" /></td>
</tr>
Note: Why not use the #id for the row? If it's possible that rows are added while one is being deleted, bad things can happen.

Passing model with list of checkboxes from view to controller

I am trying to pass model from View back to controller. I am passing NaborViewModel to View. It is a list of objects and every object has 4 checkboxes (some of them randomly checked).
Model:
public class NaborViewModel
{
public List<WowClass> WowClasses { get; set; }
}
Actions:
[HttpGet]
public ActionResult Nabor()
{
NaborViewModel viewModel = new NaborViewModel();
DatabaseDataContext context = new DatabaseDataContext();
viewModel.WowClasses = context.WowClasses.ToList();
return View(viewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Nabor(NaborViewModel model)
{
//DB actions
return RedirectToAction(Consts.ActionNabor);
}
In view i have 2 forms each with different approach. The first one is the one i have created with thought it might work.
The second form is approach i found online.
The first one is displaying passed data correctly (filled checkboxes). The second one is even displaying every checboxes unchecked.
When forms are submitted, they both returns null back to controller action.
View:
#using (Html.BeginForm(Consts.ActionNabor, Consts.ControllerAdmin, FormMethod.Post))
{
#Html.AntiForgeryToken()
<table class="admin-table">
<thead>
<tr>
<th>Class</th>
<th>Status</th>
<th colspan="3">Požadované talenty</th>
</tr>
</thead>
<tbody>
#foreach (var cls in Model.WowClasses)
{
<tr>
#Html.HiddenFor(x => cls.Id)
<td>#cls.ClassName</td>
<td>#Html.CheckBoxFor(x => cls.Open)</td>
<td style="text-align: left">#Html.CheckBoxFor(x => cls.NeedTalents1) <span>#cls.Talents1</span></td>
<td style="text-align: left">#Html.CheckBoxFor(x => cls.NeedTalents2) <span>#cls.Talents2</span></td>
<td style="text-align: left">#Html.CheckBoxFor(x => cls.NeedTalents3) <span>#cls.Talents3</span></td>
</tr>
}
</tbody>
</table>
<input type="submit" value="#Consts.Submit" />
}
<div class="horizontal-line-both"></div>
#using (Html.BeginForm(Consts.ActionNabor, Consts.ControllerAdmin, FormMethod.Post))
{
#Html.AntiForgeryToken()
<table class="admin-table">
<thead>
<tr>
<th>Class</th>
<th>Status</th>
<th colspan="3">Požadované talenty</th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < Model.WowClasses.Count; i++)
{
<tr>
<td>
<input type="text" value="#Model.WowClasses[i].ClassName" name="Expense[#i].Id">
</td>
<td>
<input type="checkbox" value="#Model.WowClasses[i].Open" name="Expense[#i].Id">
</td>
<td>
<input type="checkbox" value="#Model.WowClasses[i].NeedTalents1" name="Expense[#i].Id">
</td>
<td>
<input type="checkbox" value="#Model.WowClasses[i].NeedTalents2" name="Expense[#i].Id">
</td>
<td>
<input type="checkbox" value="#Model.WowClasses[i].NeedTalents3" name="Expense[#i].Id">
</td>
<td>
<input type="hidden" value="#i" name="Expense[#i].Id">
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="#Consts.Submit" />
}
I got this to work with a combination of your two approaches. See the following:
#for (int i = 0; i < Model.WowClasses.Count; i++)
{
...
<tr>
#Html.EditorFor(model => model.WowClasses[i].Open)
</tr>
...
}
Accessing each item in your List via its index is key. If you look at the HTML generated using this method, each item's name includes its index (in the example above, the generated input's name is this: name="WowClasses[0].Open"). This is how your controller action can distinguish between list items.
For your second form, you can modifying every input field like this,
for check box,
<input type="checkbox" id="WowClasses_#(i)_Open" name="WowClasses[#i].Open" value="true" />
for input filed,
<input type="checkbox" id="WowClasses_#(i)_ClassName" name="WowClasses[#i].ClassName" value="true" />
you just changes your every input filed by your class property.hopefully this your help

How to bind the multiple radio button values to controller action

following is my view code, I pass list from controller to view and here I am iterating that list through foreach I want to pass the same view-model list to the action when I submit the form
#model IEnumerable<AskQuestionViewModel>
.
.
.
<table class="table table-bordered">
<thead>
<tr>
<td>Question</td>
<td>Yes</td>
<td>No</td>
</tr>
</thead>
<tbody>
#foreach (var q in Model)
{
<tr>
<td>#q.Question</td>
#if (q.Answer == true)
{
<td><input type="radio" name="#q.QuestionID" value="true" checked />/td>
}
else
{
<td><input type="radio" name=#q.QuestionID value="true" required /></td>
}
#if (q.Answer == false)
{
<td><input type="radio" name=#q.QuestionID value="false" checked /></td>
}
else
{
<td><input type="radio" name=#q.QuestionID value="false" required /></td>
}
</tr>
}
The following is action code
[HttpPost]
public ActionResult AskQuestions(List<AskQuestionViewModel> askQVM)
{
...
}
I'm getting null in askQVM
This is what you need for postback.
<table class="table table-bordered">
<thead>
<tr>
<td>Question</td>
<td>Yes</td>
<td>No</td>
</tr>
</thead>
<tbody>
#using (Html.BeginForm("AskQuestions", "Questions", FormMethod.Post))
{
for (int i = 0; i < Model.Count; i++)
{
var yesOptions = Model[i].Answer ? new { #checked = "checked" } : null;
var noOptions = Model[i].Answer ? null : new { #checked = "checked" };
<tr>
<td>
#Model[i].Question
#Html.HiddenFor(model=>Model[i].QuestionID)
#Html.HiddenFor(model=>Model[i].Question)
</td>
<td>#Html.RadioButtonFor(model => Model[i].Answer, true, yesOptions)</td>
<td>#Html.RadioButtonFor(model => Model[i].Answer, false, noOptions)</td>
</tr>
}
<button type="submit">Submit</button>
}
</tbody>
</table>

I want to serialize form data using jquery

Hello guys i working on data serialize using jquery
i have pasted my HTML code below.
HTML
<div class="row">
<div class="col-md-12 col-sm-12">
<div class="ibox-content">
<form id="product">
<table class="table">
<thead>
<tr>
<th>Action</th>
<th>Product Name</th>
<th>Price</th>
<th>Qty</th>
<th>Total</th>
</tr>
</thead>
<tbody>
#foreach (var _product in Model.ProductList)
{
<tr>
<td>Details</td>
<td>
<strong>
#_product.name
<input type="hidden" name="productId" value="#_product.productId" />
</strong>
</td>
<td id="price">#_product.wholesalePrice</td>
<td id="quantity"><input style="width:50px;" name="qty" value="0"><input type="hidden" name="total" id="rowTotal" /></td>
<td id="value"></td>
</tr>
}
</tbody>
</table>
</form>
<div class="ibox-content">
<button id="totalCal" class="btn btn-primary pull-right">Calculate</button>
</div>
<table class="table invoice-total">
<tbody>
<tr>
<td><strong>Sub Total :</strong></td>
<td id="result">$1026.00</td>
</tr>
<tr>
<td><strong>Shipping :</strong></td>
<td id="Shipping">$235.98</td>
</tr>
<tr>
<td><strong>TOTAL :</strong></td>
<td id="finalTotal">$1261.98</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Jquery function
function GetTblRow() {
var data = $("#product").serializeArray();
var from = JSON.stringify(data);
console.log(from);
};
Output
[{"name":"productId","value":"1"},{"name":"qty","value":"0"},{"name":"total","value":"0"},{"name":"productId","value":"2"},{"name":"qty","value":"0"},{"name":"total","value":"0"},{"name":"productId","value":"3"},{"name":"qty","value":"0"},{"name":"total","value":"0"},{"name":"productId","value":"4"},{"name":"qty","value":"0"},{"name":"total","value":"0"},{"name":"productId","value":"5"},{"name":"qty","value":"0"},{"name":"total","value":"0"},{"name":"productId","value":"6"},{"name":"qty","value":"0"},{"name":"total","value":"0"},{"name":"productId","value":"7"},{"name":"qty","value":"0"},{"name":"total","value":"0"},{"name":"productId","value":"8"},{"name":"qty","value":"0"},{"name":"total","value":"0"},{"name":"productId","value":"9"},{"name":"qty","value":"0"},{"name":"total","value":"0"},{"name":"productId","value":"10"},{"name":"qty","value":"0"},{"name":"total","value":"0"},{"name":"productId","value":"12"},{"name":"qty","value":"0"},{"name":"total","value":"0"},{"name":"productId","value":"13"},{"name":"qty","value":"0"},{"name":"total","value":"0"}]
Expected Output
[{"ProductId":"1","qty":"0","total":"0"},"ProductId":"1","qty":"0","total":"0"},{"ProductId":"2","qty":"0","total":"0"},{"ProductId":"3","qty":"0","total":"0"},{"ProductId":"4","qty":"0","total":"0"}]
i did above code for serialize form data but i can not get above expected output. So can you help me with this?
you cannot directly use serializeArray() to get the expected json you have to separate the expected result from array
<script>
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
$(function() {
$("#totalCal").click(function(){
alert(JSON.stringify($('#product').serializeObject()));
return false;
});
});
</script>
You can use some custom code to format your array. Here is the simplest solution:
function getFormattedArray(array){
var result = [];
for(var currentPosition = 0;currentPosition < array.length; currentPosition += 3) {
result.push({ProductId: array[currentPosition].value,
qty: array[currentPosition+1].value,
total: array[currentPosition+1].value});
}
return result;
}

Categories