Run OnChange event for each row in table - MVC - javascript

MVC 5 - Razor, Javascript
Novice user!!
I would like to be able to run a simple onchange event when a checkbox is altered in the table, but the onchange only works for the first row.
I have read that this is because the script only runs on the first row and does not run for the subsequent dynamically populated data.
I understand this but don't know how to fix it... I assume that I need to create an individual ID for each checkbox in the each row - I don't know how to do this.
Also, when the checkboxes have different IDs I don't know how to refer to them to add the onchange.
Hope this makes sense. Thanks in advance.
#model IEnumerable<core_point.Models.RegisterEmployee_Step6Model>
#{
ViewBag.Title = "Index";
}
<h2>Select the roles that you have been employed to do, by clicking the check-box...</h2>
<table class="table">
#foreach (var item in Model)
{
<tr class="h3">
<td class="vert-align">
<img src="#item.IconLocation" height="80" width="80" />
</td>
<td class="vert-align">
#Html.CheckBoxFor(modelItem => item.Selected, new { #id = "CheckBoxSelected" })
</td>
<td class="vert-align">
#Html.DisplayFor(modelItem => item.RoleDescription)
</td>
<td class="vert-align">
#Html.TextBoxFor(modelItem => item.Role, new { hidden = "hidden"} )
</td>
</tr>
}
</table>
<div>
Roles selected:<input type="number" id="noSelected" value="0"/>
</div>
<script>
var fld_CheckBoxSelected = document.getElementById("CheckBoxSelected");
var fld_noSelected = document.getElementById("noSelected");
fld_CheckBoxSelected.onchange = function () {
if (fld_CheckBoxSelected == true) {
fld_noSelected = fld_noSelected.value + 1;
}
else
{
fld_noSelected = fld_noSelected.value - 1;
}
}
</script>

replace id with class in CheckBoxFor:
<td class="vert-align">
#Html.CheckBoxFor(modelItem => item.Selected, new {#class= "CheckBoxSelected"})
</td>
In Javascript code use fallowing code:
(function($) {
var onChanged = function(){
/*Do smth that you needed*/
};
$(function() {
$(".checkbox").on("change", onChanged)
});
}(jQuery));

Because all your input boxes will have the same Id value "CheckBoxSelected". That is invalid markup.Id values should be unique.
You may consider removing the id from the markup and use a css class.
#Html.CheckBoxFor(modelItem => item.IsSelected, new { #class = "mycheckBox" })
and using jQuery library, listen to the change event on the input element with this css class.
$(function(){
$("input.mycheckBox").change(function(){
var isSelected = this.checked;
alert("Checkbox changed");
if (isSelected ) {
$("#noSelected").val( parseInt($("#noSelected").val())+ 1));
}
else
{
$("#noSelected").val( parseInt($("#noSelected").val()) - 1));
}
});
});
Assuming the current value of input with id noSelected is a numeric value(else parseInt will fail).

Related

Adding a details button to a dynamic HTML list

I have an HTML list that is generated dynamically using filtered data.
<tbody>
#{
foreach (var item in listado.Where(x => x.Raw != null)) {
<tr>
<td>#item.Id</td>
<td>#item.Usuario</td>
<td>#item.NIF_CIF</td>
<td>
#if (!(String.IsNullOrEmpty(item.Telefono)) && !(String.IsNullOrWhiteSpace(item.Telefono))) {
#item.Telefono
} else {
#Html.Raw("No disponible")}
</td>
<td>#Math.Round(item.PrecioTotal) €</td>
<td>#item.FechaCreacion.ToShortDateString()</td>
<td>
<button id="detalles#(item.Id)">Detalles</button>
</td>
</tr>
<tr id="vistaDetalles#(item.Id)" hidden>
<td>Detalles del presupuesto</td>
</tr>
}
}
</tbody>
I've tried to tag the button as you can see using the item.Id and then point to it in this script:
<script>
$("document").ready(function (Id) {
$("#detalles"+ Id).click(function (Id) {
$("#vistaDetalles" + Id).show();
});
});</script>
I've also tried not to tag them and catch all the buttons (removing the +Id part) and the same technique to catch all the hidden tds, but nothing works. What am I doing wrong? Also, can you recommend some learning material so I can get this part a bit clearer?
Thanks in advance. Regards.
You can use data attributes for this purpose
HTML
<button class="detalles" data-itemid="#item.Id">Detalles</button>
jQuery
$(".detalles").on("click",function(){
var itemId = $(this).data('itemid');
$('#vistaDetalles'+itemId).show();
});
I would replace your button with
<button onclick="detalles(#item.Id)">Detalles</button>
And change your JavaScript to:
<script>
function detalles(Id) {
$("#vistaDetalles" + Id).show();
};
</script>
Try it:-
<script>
$("document").ready(function (Id) {
$("body").on("click","#detalles"+ Id, function (Id) {
$("#vistaDetalles" + Id).show();
});
});</script>

call function for each element in a foreach using jQuery

I have a view-model which has a data grid like the one shown below
<table>
#foreach (var item in Model)
//for(int i=0;i<Model.Count();i++)
{
using (Html.BeginForm("Edit", "Views", FormMethod.Post))
{
<tr>
<td>
#Html.TextBoxFor(modelItem => item.Description, new { id = "description" })
</td>
<td>
#Html.DisplayFor(modelItem => item.DisplayAt, new { id = "displayat" })
</td>
<td>
#Html.DropDownListFor(m => item.selectedRegion, item.RegionsList, item.Region, new { id = "ddlregion" })
</td>
<td>
#Html.DropDownListFor(modelItem => item.Products, item.ProductsList, item.Products, new { id = "ddlproduct" })
</td>
<td>
#Html.DropDownListFor(modelItem => item.Companies, item.CompaniesList, item.Companies, new { id = "ddlcompany" })
</td>
<td>
#Html.DropDownListFor(modelItem => item.UserName, item.UserNamesList, item.UserName, new { id = "ddlusers" })
</td>
<td>
#Html.CheckBoxFor(modelItem => item.Visible, new { id = "chkVisible" })
</td>
<td>
<input type="submit" value="Edit" id="button" />
</td>
</tr>
}
}
</table>
I have written a jquery function to work on the click of the button with id=button
However, it works only for the first row.
When I click on the buttons from the second row the function is not being called.
How do I write a jquery which will be called when any of the buttons is clicked.
My jQuery code:
$('#button').click(function () {
var product = $("#ddlproduct").find("option:selected").text();
var user = $("#ddlusers").find("option:selected").text();
*does something*
});
This is being called only for the first row.
I'm assuming there is something like a foreach button with id that is clicked.
Once you change your ids to classes so they are not restricted to being unique, you can look up your related elements contextually.
$('.button').click(function () {
//get a reference to the row that contains the button that was clicked
var $contextualRow = $(this).closest('tr');
var product = $contextualRow.find(".ddlproduct").find("option:selected").text();
var user = $contextualRow.find(".ddlusers").find("option:selected").text();
*does something*
});
Give the button a class instead of the ID.
<button class="button">Submit</button>
That will trigger the event each time the button with class button is clicked.
$('.button').click(function () {
*does something*
});
To get the values of your selects, you can go about doing it contextually just like Taplar wrote or you can select the parent of the button and go about its children:
var parent = $(this).parent().parent();
var product = $(".ddlproduct", parent).val();
var user = $(".ddlusers", parent).val();
Dont forget to change those IDs to classes.

MVC razor display element that can be edited by javascript

I'm working with a table that I would like to have display text but also have that text updated by javascript.
I can create a readonly textbox and have javascript edit that, but I would rather just have some text on the screen. Here is a sample that has a DisplayFor which displays text and a readonly textbox which shows the same text.
#for (var i = 0; i < Model.ProjectSubmissions.Count; i++)
{
<tr>
<td>
#Html.DisplayFor(modelItem => Model.ProjectSubmissions[i].ChapterNumber)
</td>
<td>
#Html.TextBox("recordsToSort[" + i + "].ChapterNumber", Model.ProjectSubmissions[i].ChapterNumber, new { #id = "recordsToSort[" + i + "].ChapterNumber", #class = "SortOrder", #readonly = "readonly" })
</td>
</tr>
}
My javacript can edit the textbox like this:
$(".sortable-table tr").each(function (index, element) {
var hiddenInput = $(element).find(".SortOrder").first();
hiddenInput.val(index);
});
Can I write javascript that will update the DisplayFor? Or should I use a different element than DisplayFor that javascript can update?
UPDATE:
I'd like to end up with something like this (I would like to keep the hidden .SortOrder element.):
#for (var i = 0; i < Model.ProjectSubmissions.Count; i++)
{
<tr>
<td>
<span id="#Html.Id("recordstosort[" + i + "].ChapterNumber")" class="SortOrderDisplay">#Model.ProjectSubmissions[i].ChapterNumber</span>
#Html.Hidden("recordsToSort[" + i + "].ChapterNumber", Model.ProjectSubmissions[i].ChapterNumber, new { #id = "recordsToSort[" + i + "].ChapterNumber", #class = "SortOrder" })
</td>
</tr>
}
And javascript like this:
$(".sortable-table tr").each(function (index, element) {
var hiddenInput = $(element).find(".SortOrder").first();
hiddenInput.val(index);
var displayInput = $(element).find(".SortOrderDisplay").first();
if (displayInput !== 'undefined') {
displayInput.text = index;
}
});
But this isn't working.
You can use jQuery text instead of val.
#for (var i = 0; i < Model.ProjectSubmissions.Count; i++)
{
<tr>
<td class="SortOrder">
#Html.DisplayFor(modelItem => Model.ProjectSubmissions[i].ChapterNumber)
</td>
</tr>
}
Then the javascript would be
$(".sortable-table tr").each(function (index, element) {
var hiddenInput = $(element).find(".SortOrder").first();
hiddenInput.text(index);
});
Javascript can be used to update any element you like. The easiest way would probably be to create a span with an id property and then use document.getElementById.innerText to set the text.
You can easily replace the #Html.DisplayFor with a <span id="#Html.IdFor(m => m.ProjectSubmissions[i].ChapterNumber)"></span>.
This only an example, and there are several ways to go about changing text client-side.

How to get html <td> values using javascript in grid table

I'm using mvc, I want to get the value of each and every td to edit in my table
<table>
<tr>
<td id="val"></td>
</tr>
</table>
<input type="button" value="" class="edit"/>
And in the javascript am using
var td = $(document).getElementById("val").innetHTML;
$(document).on('click', '.edit', function (e) {
if(td == null)
{
}
else
code......
})
But whenever am clicking the row edit button it is returning only the first row value, not getting the value of second and further.
Any suggestion will be greatly appreciated.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function()
{
$('.edit').click(function()
{
$('table td').each(function() {
var val = $(this).html();
alert(val);
});
});
});
</script>
You have to use 'class' attribute instead 'id':
<table>
<tr><td class="editVal"></td></tr>
<tr><td class="editVal"></td></tr>
<tr><td class="editVal"></td></tr>
</table>
You have to use JQuery for iterate each element:
$('.editVal').each(function(i) {
// get value
var $td = $(this).html;
// set value
$(this).html = 'Nuovo valore';
}
If you are trying to get the values of a table one by one, I think jquery each is the function for you.
There is also another question in SO with a good example.

How to get <td> value in textbox

I've done some code in html and in JavaScript ... My query is when I click on <td>, whatever the value associated with it, has to be displayed in the corresponding text box ...
In front of <td> I've taken the textbox ... for an example I've taken 3 <td> and 3 textboxes
<script type="text/javascript">
function click3(x) {
x = document.getElementById("name").innerHTML
var a = document.getElementById("txt");
a.value = x;
}
function click1(y) {
y = document.getElementById("addr").innerHTML
var b = document.getElementById("txt1");
b.value = y;
}
function click2(z) {
z = document.getElementById("email").innerHTML
var c = document.getElementById("txt2");
c.value = z;
}
</script>
this is my JavaScript code , I know this is not an adequate way to deal such problem, since its giving static way to deal with this problem
does anyone have a better solution for this problem ??
In JavaScript/jQuery
If click1, click2 and click3 are supposed to be three event then you have to keep all three function you can shorted the script code for assigning values to text field.
<script type="text/javascript">
function click3(x) {
document.getElementById("txt").value = document.getElementById("name").innerHTML;
}
function click1(y) {
document.getElementById("txt1").value = document.getElementById("addr").innerHTML;
}
function click2(z) {
document.getElementById("txt2").value = document.getElementById("email").innerHTML;
}
</script>
You can make a single function if you have single click event and shorten the code for assignment like this,
function SomeClick(x) {
document.getElementById("txt").value = document.getElementById("name").innerHTML;
document.getElementById("txt1").value = document.getElementById("addr").innerHTML;
document.getElementById("txt2").value = document.getElementById("email").innerHTML;
}
As far as I understood your question, you could try the following, assuming that's how your HTML is structured:
HTML Markup:
<table id="mytable">
<tr>
<th>Name</th>
<th>Address</th>
<th>Email</th>
</tr>
<tr>
<td class="name">Tom</td>
<td class="addr">789</td>
<td class="email">tom#dot.com</td>
</tr>
<tr>
<td class="name">Dick</td>
<td class="addr">456</td>
<td class="email">dick#dot.com</td>
</tr>
<tr>
<td class="name">Harry</td>
<td class="addr">123</td>
<td class="email">harry#dot.com</td>
</tr>
</table>
<input id="txt1" type="text" />
<input id="txt2" type="text" />
<input id="txt3" type="text" />​
jQuery:
$(".name").click(function(){
$("#txt1").val($(this).text());
$("#txt2").val($(this).nextAll().eq(0).text());
$("#txt3").val($(this).nextAll().eq(1).text());
});​
$(".addr").click(function(){
$("#txt2").val($(this).text());
$("#txt1").val($(this).prevAll().eq(0).text());
$("#txt3").val($(this).nextAll().eq(0).text());
});
$(".email").click(function(){
$("#txt3").val($(this).text());
$("#txt2").val($(this).prevAll().eq(0).text());
$("#txt1").val($(this).prevAll().eq(1).text());
});
DEMO: http://jsfiddle.net/Z9weS/
You can combine columns and rows. Per cell consisting id you give it th column title and
number of series it could be the index of the row combination of row and column gives the
address as per table cell by a specific event you can read the value of the id
Then you know to pull the cell value.
$('tr')
.click(function() {
ROW = $(this)
.attr('id');
$('#display_Colume_Raw')
.html(COLUME + ROW);
$('#input' + COLUME + ROW)
.show();
STATUS = $("#input" + COLUME + ROW)
.val();
});

Categories

Resources