I'm using ASP.NET MVC4 and C# for a small web application. Its use is for creating a simple to-do list. What I'm struggling with is that I've got a list of tasks displayed in a foreach. With each task is a checkbox, and basically when the checkbox is clicked (i.e true) then the text should have a strike through it. I tried to use Javascript but it did not work. Here is my code:
#foreach (var item in Model)
{
<tr style="border: 1px solid;">
<td>
<input type="checkbox" name="checkbox" onchange="taskDone(#item.Id)" />
</td>
<td>
<p id="#item.Id">#Html.DisplayFor(modelItem => item.TaskDetails)</p>
</td>
</tr>
}
and Javascript:
<script language="javascript" type="text/javascript">
function taskDone(id) {
var c = document.getElementById(id);
if (this.checkbox.checked) {
c.className = "strike";
}
else {
c.className = "nostrike";
}
}
</script>
and the bit of CSS:
.strike
{text-decoration: line-through;}
could someone explain where I'm going wrong. thanks
Problem is (this.checkbox.checked) which does not refer the checkbox element
Pass the checkbox id mychekbox as second paramter into taskDone(), get that element and validate that it's checked or not by if(checkBox.checked),
<input id="mychekbox" type="checkbox" name="checkbox" onchange="taskDone(#item.Id, 'mychekbox')" />
function taskDone(id, checkBoxId) {
var c = document.getElementById(id);
var checkBox = document.getElementById(checkBoxId); //getting checkbox
if (checkBox.checked) { //validating checked or not
c.className = "strike";
}
else {
c.className = "nostrike";
}
}
Related
I'm using ASP.NET MVC and have a table with 9 columns which shows results from the database where the user can filter values based on columns. The table structure looks like this:
<table class="tableMain" id="x">
<thead>
<tr class="trMain">
<th class="thMain">
#Html.DisplayNameFor(model => model.ID)
</th>
<th class="thMain">
#Html.DisplayNameFor(model => model.YEAR)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr class="trMain">
<td class="tdMain">
#Html.DisplayFor(modelItem => item.ID)
</td>
<td class="tdMain">
#Html.DisplayFor(modelItem => item.YEAR)
</td>
<td class="tdMain">
<input type="checkbox" class="chkCheckBoxId" name="airlineId" value="#item.ID" />
</td>
<td class="tdMain">
#Html.ActionLink("EditValue", "Edit", new { id = item.ID })
</td>
</tr>
}
</tbody>
</table>
Now I need a button, so that the dynamically generated table opens in a new window and the print dialog opens automatically. I had this piece of code:
<div class="line-btn">
<input type="submit" value="print" onclick="printTable()" class="btn fl btn-print">
</div>
<script language="javascript">
function printTable()
{
var printContent = document.getElementById("x");
var windowUrl = 'about:blank';
var num;
var uniqueName = new Date();
var windowName = 'Print' + uniqueName.getTime();var printWindow = window.open(num, windowName, 'left=50000,top=50000,width=0,height=0');
printWindow.document.write(printContent.innerHTML);
printWindow.document.close();
printWindow.focus();
printWindow.print();
printWindow.close();
}
</script>
The problem here is that the table is completely unsorted when printed so the rows/columns are shifted.
I found this example:
https://datatables.net/extensions/buttons/examples/print/simple.html
This is exactly what I need (open the table in a new window and open print dialog). But unfortunately this sample has a lot of code in the javascript files that I don't need. There is a search field included and a pagination.
Can someone help me please? Thank you very much!
Ok I found a good solution.
This is the code I used:
<script src="#Url.Content("~/Scripts/jquery-3.5.1.js")" type="text/javascript"></script>
<script>
var myApp;
myApp = (function (app) {
$('#x').click(function () {
myApp.print();
});
app.print = function () {
$.ajax({
url: 'Home/Print',
success: function (data) {
if (myApp.arePopupsBlocked()) {
alert('please allow popups.');
}
var printWindow = window.open();
if (printWindow) {
$(printWindow.document.body).html(data);
} else {
alert('please allow popups.');
}
},
error: function () {
alert('Error');
}
});
};
app.arePopupsBlocked = function () {
var aWindow = window.open(null, "", "width=1,height=1");
try {
aWindow.close();
return false;
} catch (e) {
return true;
}
};
return app;
})(window.myApp || {})
</script>
and right before the table-tag the link to click:
<style>
/* suppress link for printing */
##media only print {
a {
display: none;
}
}
</style>
[print table]
There opens no new window but the table is well formated for printing.
Long shot here, but I don't even know where to start. I maintain an MVC site. The form features several dozen drop menus. Rather than type them all out manually in the view, I'm generating them in loops.
Drop Menu options:
List<string> menuList = new List<string>() { "Correct", "Incorrect", "N/A" };
Drop Menu names (one of several lists on the page):
List<string> auditList1 = new List<string>() { "AE_FIRST","AE_SECOND","AE_THIRD", ... ,"AE_NTH"};
And here's the code to generate the drop menus:
#foreach (string audElement in auditList1)
{
string selected = "";
dropMenuCount = 0;
bool menuItemMatched = false;
<tr>
<td>#audElement: </td>
<td>
<select name="#audElement">
#foreach (string menuElement in menuList)
{
selected = "";
if (Model.AuditFound == true
&& auditElementCount < 45
&& menuElement == auditArray[auditElementCount].ToString()
&& menuItemMatched == false)
{
selected = "selected";
auditElementCount++;
menuItemMatched = true;
}
if (menuElement == null)
{
auditElementCount++;
}
if (dropMenuCount == 2 && menuItemMatched == false)
{
selected = "selected";
}
dropMenuCount++;
<option value=#menuElement #selected>#menuElement</option>
}
</select>
</td>
</tr>
}
So that's the setup. I did it this way because I'm working with an old, flat Oracle table that has 64 columns that I'm not allowed to change. Works as intended. They use the same form to enter a new audit or to review an existing audit, so that's the reason for the #selected logic.
The business unit is asking me to make a comments box mandatory if the user selects "Incorrect" for ANY of the drop menus.
<textarea name="AUDIT_COMMENTS" cols="66" rows="6">#audit_comments</textarea>
Best way to go about this?
Here is a demo,when one of the dropdownlists' values is incorrect,add required to textarea,otherwise,remove required.
View:
<form id="myform" method="post">
#foreach (string audElement in Model.auditList1)
{
<div>
<label>#audElement</label>
<select>
<option value="Correct">Correct</option>
<option value="Incorrect">Incorrect</option>
<option value="N/A"></option>
</select>
</div>
}
<textarea id="audit_comments" name="AUDIT_COMMENTS" cols="66" rows="6"></textarea>
<input type="submit" value="submit" />
</form>
<style>
.error {
color:red;
}
</style>
js:
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<script>
$(function () {
check();
})
$("#myform").validate();
$("select").change(function () {
check();
});
function check() {
var required = false;
$("select").each(function () {
if ($(this).val() == "Incorrect") {
required = true;
}
})
$('#audit_comments').attr('required', required);
}
</script>
result:
I am creating dynamic rows on html table and trying to get table value on c#. but whenever I am putting runat=server on table jQuery doesn't work and hence I could not access html table on server side. Please give me some suggestion.
<table id="purchaseItems" name="purchaseItems" align="center">
<tr>
<th>Paragraph</th>
<td>
<input type="text" name="description[]" class="tbDescription next" required />
</td>
<td>
<input type="button" name="addRow[]" class="add" value='+' />
</td>
<td>
<input type="button" name="addRow[]" class="removeRow" value='-' />
</td>
</tr>
</table>
and this is my jQuery:
$(document).ready(function () {
$(document).on('click', '#purchaseItems .add', function () {
var row = $(this).closest('tr');
var clone = row.clone();
// clear the values
var tr = clone.closest('tr');
tr.find('input[type=text]').val('');
$(this).closest('tr').after(clone);
});
$(document).on('keypress', '#purchaseItems .next', function (e) {
if (e.which == 13) {
var v = $(this).index('input:text');
var n = v + 1;
$('input:text').eq(n).focus();
//$(this).next().focus();
}
});
$(document).on('keypress', '#purchaseItems .nextRow', function (e) {
if (e.which == 13) {
$(this).closest('tr').find('.add').trigger('click');
$(this).closest('tr').next().find('input:first').focus();
}
});
$(document).on('click', '#purchaseItems .removeRow', function () {
if ($('#purchaseItems .add').length > 1) {
$(this).closest('tr').remove();
}
});
});
Your problem is in ID, which generated by asp.net. After adding runat="server", it won't be simply purchaseItems. To get real ID, you should use next code:
$(document).on('keypress', '#<%= purchaseItems.ClientID %> .next', function (e) {
if (e.which == 13) {
var v = $(this).index('input:text');
var n = v + 1;
$('input:text').eq(n).focus();
//$(this).next().focus();
}
});
But in this case, you won't be able to separate js and asp.net files. As alternative work around, you can use Dev Tools from any browser, to figure out which ID will be generated on client side.
I'm building an MVC app and right now my view generates a pack of items. The user needs to check a checkbox if he wants to send the data.
Here's my view and how it is builded:
<script type="text/javascript">
$(document).ready(function() {
//alert("The document is ready");
$("#selectAll").click(function() {
//alert("The case has been clicked");
var chkValue = $(this).is(":checked");
$(".divChckBox").prop("checked", chkValue);
});
});
</script>
<p>
#using (Html.BeginForm("SendObj", "Manager"))
{
<p>
Select / UnSelet All Items #Html.CheckBox("selectAll", true)
</p>
<table>
<tr>
<th>Card Name</th>
<th>Number In Stock</th>
(...)
</tr>
#for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td>#Html.DisplayFor(x => x[i].m_OthObj.m_ObjName)</td>
<td>#Html.DisplayFor(x => x[i].m_NbInStock)#Html.HiddenFor(x => x[i].m_NbInStock)</td>
(...)
<td>
<input type="checkbox" name="itdoesnotmatter" class="divChckBox" checked="true"/>
</td>
</tr>
}
</table>
<input type="submit" value="Send"/>
}
</p>
So you understand why I cannot use "CheckboxFor". Now what I want to do is send only the items which checkbox status is "checked". I know how to do this via model binding (checkboxfor), but I'm clueless as to how to build this.
I need to return a list of items. So how could I do this? Thank you very much!
Your form will return the values based on name, so shoot whoever told you such a stupid name :)
Use
<input type="checkbox" name="InStock" class="divChckBox" checked="true" value="#Model[i].ID" />
Or something more representative. Note that it is CRITICAL that you supply a unique identifier as the value of your checkbox. The value is how you will identify what was checked!
In your controller, there's several ways you can capture it. I do it like this:
public ActionResult Create(List<int> InStock)
{
foreach(var inStockItem in InStock)
{
//do what you need to do
}
}
The important points:
List<int> InStock
This must match the NAME attribute on your checkbox. The actual values will be the Value of your checkboxes.
Here I just randomly selected Create for your Action, but you need to make it match whatever action you are in (Edit, Index, etc..)
Good Luck!
try using the attr method to change the property checked.
$(document).ready(function() {
$("#selectAll").click(function() {
var chkValue = $(this).is(":checked");
$(".divChckBox").attr("checked", chkValue);
});
});
View code:
<!-- note "x[i].m_id"; Use the entity's id property is here
...maybe this should be m_NbInStock? -->
<input type="checkbox" name="selectedItems" value="#x[i].m_id" class="divChckBox" checked="true"/>
Controller code:
public class Manager : Controller
{
/* ... */
[HttpPost]
public ActionResult SendObj(IList<Int32> selectedItems)
{
// Grab those items by their IDs found within `selectedItems` and perform
// any processing necessary
// ...
//return View();
}
/* ... */
}
I want to create a checkbox that will have the "power" to check / uncheck a checkboxfor for each items presents in a list.
Here is part of the view as I built it right now (please bear with the false names and convention):
<p>
#using (Html.BeginForm("SendObj", "Manager"))
{
<p>
Select / UnSelet All Items #Html.CheckBox("selectAll", true)
</p>
<table id="objToSend">
<tr>
<th>Obj Name</th>
<th>Number In Stock</th>
(...)
</tr>
#for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td>#Html.DisplayFor(x => x[i].m_OthObj.m_ObjName)</td>
<td>#Html.DisplayFor(x => x[i].m_NbInStock)#Html.HiddenFor(x => x[i].m_NbInStock)</td>
(...)
<div id="divChckBox">
<td>
#Html.CheckBoxFor(x => x[i].m_IsSelected)
</td>
</div>
</tr>
}
</table>
<input type="submit" value="Send"/>
}
</p>
As for the "how", well, I have searched a bit around and I have tried this jquery script, but to no avail:
**** EDIT ****
Here's a new jQuery based on the comments people posted below. The alerts are there on debug purpose, and both appears when needed:
<script type="text/javascript">
$(document).ready(function() {
alert("The document is ready");
$("#selectAll").click(function() {
alert("The case has been clicked");
var chkValue = $(this).is(":checked");
$("#divChckBox").attr("checked", "checked");
});
});
</script>
I do not mind using jquery, far from it, I just do not know how it works yet. Maybe that's why what I have in mind does not work.
Can anyone help me out? Thank you!
* EDIT *
I will add here what the rendered page gives out for the checkboxes:
<td><input checked="checked" class="chckBoxList" data-val="true" data-val-required="The m_IsSelected field is required." name="[0].m_IsSelected" type="checkbox" value="true" /><input name="[0].m_IsSelected" type="hidden" value="false" /></td>
Maybe that will give out more informations on what's going on.
#Html.CheckBox("TheOneCheckBoxToRuleThemAll")
Change your current checkbox code to:
<td>#Html.CheckBoxFor(x => x[i].m_IsSelected, new{ #class = "checkGroup1"})</td>
The easiest Jquery ever (make sure to put it in document.ready like shown):
<script type="text/javascript">
$(document).ready(function () {
//alert("the document is ready");
$("#TheOneCheckBoxToRuleThemAll").click(function () {
//alert("inside my click event");
var chkValue = $(this).is(":checked");
$(".checkGroup1").prop("checked", chkValue);
});
});
</script>
EDIT:
My previous answer used the .attr() attribute. After testing, I had all sorts of trouble getting that to work. After referring to this SO post, I switched to using .prop() and everything magically began to function correctly.
Jquery .Attr()
Jquery .Prop()
EDIT:
In the example I've provided, your checkboxes MUST look like this:
<input name='itdoesnotmatter' id='donotcare' class='checkGroup1' />
also, do not use that stupid name that I put on there, use something easy like
#Html.CheckBox("MasterCheck")
I stand corrected: CheckBoxFor does NOT allow class setting
In your Helper
<div id="divChckBox">
#Html.CheckBoxFor(x => x[i].m_IsSelected)
</div>
And then make your selector group by the class:
$("#divChckBox :checkbox").attr("checked", "checked");
As there are MANY comments around and many answers, here's my current code (which works!):
<script type="text/javascript">
$(document).ready(function() {
//alert("The document is ready");
$("#selectAll").click(function() {
//alert("The case has been clicked");
var chkValue = $(this).is(":checked");
$(".divChckBox").prop("checked", chkValue);
});
});
</script>
<p>
#using (Html.BeginForm("SendObj", "Manager"))
{
<p>
Select / UnSelet All Items #Html.CheckBox("selectAll", true)
</p>
<table>
<tr>
<th>Card Name</th>
<th>Number In Stock</th>
(...)
</tr>
#for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td>#Html.DisplayFor(x => x[i].m_OthObj.m_ObjName)</td>
<td>#Html.DisplayFor(x => x[i].m_NbInStock)#Html.HiddenFor(x => x[i].m_NbInStock)</td>
(...)
<td>
<input type="checkbox" name="itdoesnotmatter" class="divChckBox" checked="true"/>
</td>
</tr>
}
</table>
<input type="submit" value="Send"/>
}
</p>
Now every checkboxes are checked or not depending on the state of the select all checkboxes! Thank you everyone.
Now I need to solve the problem of "unlinking" the result of the checkbox in my controller because a behavior was linked to this. But it's another problem.