In this table, the rows are selectable only when Approved? column is empty. User can also add text in Deny Reason column.
When Deny button clicked, I want to make sure all deny reasons are filled in all selected rows before the rest of action can be executed. I tried to use return false , e.stopPropagation() , e.stopImmediatePropagation() and none of those works. As you can see in my example, alert("test") will always be executed. I want to stop that. Could you help?
$(function() {
var table = $("#myDataTable").DataTable({
info: false,
paging: false,
searching: false,
sorting: false
});
$("#myDataTable tbody").on('click', 'tr', function() {
var tr = $(this).closest("tr");
var rowText = tr.children("td").text();
var approveDeny = tr.children("td:nth-child(2)").text();
if (approveDeny == "") {
$(this).toggleClass('selected');
}
});
$("#myDataTable tbody tr td:nth-child(4)").click(function(e) {
if ($(this).prev().prev().text() == "") {
var text = $(this).text();
$(this).text('');
$('<textarea />').appendTo($(this)).val(text).select().blur(function() {
var newText = $(this).val();
var parentCell = $(this).parent();
parentCell.find('textarea').remove();
table.cell(parentCell).data(newText).draw();
});
}
e.stopPropagation();
});
$("#btnDeny").click(function(e) {
table.cells('.selected',3).every(function(rowIdx, tableLoop, rowLoop) {
var data = this.data();
if(data == "") {
alert( rowIdx + " is empty, you have to fill it.");
return false;
}
console.log(data);
});
alert("test");
});
});
<link href="https://cdn.datatables.net/1.10.10/css/jquery.dataTables.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js"></script>
<table id="myDataTable" class="table">
<thead>
<tr>
<th>Name</th>
<th>Approved?</th>
<th>Date</th>
<th>Deny Reason</th>
</tr>
</thead>
<tbody>
<tr id="1">
<td>Mickey Mouse</td>
<td>Yes</td>
<td>1/1/2016</td>
<td></td>
</tr>
<tr id="2">
<td>Minnie Mouse</td>
<td></td>
<td>1/3/2016</td>
<td></td>
</tr>
<tr id="3">
<td>Donald Duck</td>
<td></td>
<td>1/5/2016</td>
<td></td>
</tr>
</tbody>
</table>
<br/>
<div>
<input type="button" id="btnApprove" value="Approve">
<input type="button" id="btnDeny" value="Deny">
</div>
You can use a variable outside of the scope of your inner .every() function and change it within that function so you know if the data is valid or not.
$("#btnDeny").click(function(e) { // Outer scope function
var valid = true;
table.cells('.selected',3).every(function(rowIdx, tableLoop, rowLoop) { // inner scope function
var data = this.data();
if(data == "") {
valid = false;
alert( rowIdx + " is empty, you have to fill it.");
}
});
if (valid)
alert("Data valid");
});
Right, you need to assign the boolean output of every() to a variable, and then execute your alert only if that variable is true. Right now the result of the every() call is ignored, and the alert is executed regardless. Something like:
var isValid = table.cells('.selected',3).every(function(rowIdx, tableLoop, rowLoop) {
var data = this.data();
if(data == "") {
alert( rowIdx + " is empty, you have to fill it.");
return false;
}
console.log(data);
});
if (isValid) {
alert("test");
}
Related
I have a jquery function, that activates only when a table row is clicked and if so, it invokes controller method. However, this row also contains checkbox, and if i click it i don't want this method to be called. I tried checking the clicked element type or other parameters like class, but it seems to only apply to the entire row. Any ideas how to make it work?
JQuery:
function AllowTableRowsToBeClicked() {
$('#pref-table tbody tr').click(function () {
var resourceName = $(this).attr('title');
var categoryName = $('#pref-table').attr('name');
var url = "/Home/GetSpecific";
$.post(url, { categoryName: categoryName, resourceName: myClass }, function (data) {
});
});
}
cshtml:
<table class="table table-striped table-hover margin-top-20 pref-table" id="pref-table" name=#Model.CurrentItemMode>
#for (int i = 0; i < Model.BiData.Count; i++)
{
<tr id=#Model.BiData[i].Name name=#i title="#Model.BiData[i].Name" class="tableRow">
#Html.Hidden("resourceList[" + i + "]", Model.BiData[i].Name)
<th>
#Html.CheckBox("checkBoxList[" + i + "]", Model.BiData[i].Selected, new { #class = "resourceCheckbox" })
</th>
<th>
#Model.BiData[i].Name
</th>
</tr>
}
</table>
If your checkbox has some id like box then you can check if the event originated from that checkbox and stop processing.
$('#pref-table').on('click',function (event) {
if(event.target.id === 'box'){
return;
}
var resourceName = $(this).attr('title');
var categoryName = $('#pref-table').attr('name');
var url = "/Home/GetSpecific";
$.post(url, { categoryName: categoryName, resourceName: myClass }, function (data) {
});
Here's a Pen to demonstrate the idea.
Try event.stopPropagation():
$('#pref-table input[type="checkbox"]').click(function(e) {
e.stopPropagation();
});
Using eventPropagation in the example below:
Html
<table width="100%">
<tr style="background:yellow">
<td>
<input type="checkbox" />
</td>
</tr>
</table>
javascript/jquery
$(document).ready(function() {
$('table tr').click(function(e) {
alert("row clicked");
});
$('input[type=checkbox]').click(function(e) {
e.stopPropagation();
alert("checkbox clicked")
});
});
Jsfiddle demo
I think your problem is you don't want to activate your event code when user clicks on checkbox, irrespective of checkbox state.
$('#pref-table tbody tr').click(function (event) {
if($(event.target).is(":checkbox")) return;
// your event code
});
I am trying to hide a table based on the value of two fields, so that if field2 is equal to field1 the table is hidden.
JSfiddle
HTML:
<form>
Expected Number of Items: <input type="text" value="14" name="totalItems" id="totalItems">
<p>
Number of Items Entered: <input type="text" value="14" name="enteredItems" id="enteredItems">
</form>
<p>
<table border="1" style="width:100%" id="hideThis">
<tr>
<td>This should be hidden when "totalItems" equals "enteredItems"</td>
</tr>
</table>
JS:
function toggleClass(eid, myclass){
var theEle = document.getElementById(eid);
var eClass = theEle.className;
if(eClass.indexOf(myclass) >= 0){
theEle.className = eClass.replace(myclass, "");
}else{
theEle.className += "" +myclass;
}
}
See the comments in the code.
// Function to hide/show the table based on the values of inputs
function toggleTable() {
// Hides the table if the values of both input are same
$('#hideThis').toggle($('#totalItems').val() !== $('#enteredItems').val());
}
$(document).ready(function() {
// Bind the keyup event on both the inputs, call the function on event
$('#totalItems, #enteredItems').on('keyup', toggleTable).trigger('keyup');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<form>Expected Number of Items:
<input type="text" value="14" name="totalItems" id="totalItems">
<p>Number of Items Entered:
<input type="text" value="14" name="enteredItems" id="enteredItems">
</form>
<p>
<table border="1" style="width:100%" id="hideThis">
<tr>
<td>This should be hidden when "totalItems" equals "enteredItems"</td>
</tr>
</table>
jsfiddle Demo
$(document).ready( function() {
$('#totalItems, #enteredItems').keyup(function(){
if( $('#totalItems').val() == $('#enteredItems').val() ){
$('#hideThis').hide();
}else{
$('#hideThis').show();
}
});
});
If you need to check also at page load:
function checkFields(){
if( $('#totalItems').val() == $('#enteredItems').val() ){
$('#hideThis').hide();
}else{
$('#hideThis').show();
}
}
$(document).ready( function() {
$('#totalItems, #enteredItems').keyup(function(){
checkFields();
});
checkFields();
});
Plain JavaScript implementation:
function checkFields(){
if( document.getElementById('totalItems').value == document.getElementById('enteredItems').value ){
document.getElementById('hideThis').style.display = 'none';
}else{
document.getElementById('hideThis').style.display = 'inline-block';
}
}
document.getElementById('totalItems').addEventListener('keyup', function (){
checkFields();
}, false);
document.getElementById('enteredItems').addEventListener('keyup', function (){
checkFields();
}, false);
checkFields();
Here is the new JSFiddle
$(document).ready(function () {
var webpart_ID = 'hideThis';
var FieldA_id = 'totalItems';
var FieldB_id = 'enteredItems';
if ($('#' + FieldA_id).val() === $('#' + FieldB_id).val())
$('#' + webpart_ID).hide();
else
$('#' + webpart_ID).show();
});
This works.
You can bind a keyup events for both the text boxes, from where you can call a function to check if both the values are same..
compare();
$("#totalItems,#enteredItems").keyup(function() {
compare();
});
function compare() {
if ($("#totalItems").val() == $("#enteredItems").val()) {
$("#hideThis").hide();
} else {
$("#hideThis").show();
}
}
Fiddle
In the table the first column is editable and after edit it/change it I want to show the alert as Changed. I am calling the check function after 5000ms.
Adding Code Snippet for My code
Something I missed or wrong somewhere. Please Help.
Here is the Code.
var table = $("table tbody");
table.find('tr').each(function (i) {
var $tds = $(this).find('td'),
id = $tds.eq(0).text(),
product = $tds.eq(1).text();
$check = function() {
if(($tds.eq(0).text() != id) && ($tds.eq(1).text() != product)){
alert("Changed");
}
else{
alert("Not changed");
}
}
setInterval(function() { $check(); }, 5000);
alert(id + ":" + product);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td contentEditable>63</td>
<td>Computer</td>
</tr>
</tbody>
</table>
if(($tds.eq(0).text() != id) && ($tds.eq(1).text() != product)){
This only triggers when both fields changed, change it to a "||"
Also check out this: https://developer.mozilla.org/en-US/docs/Web/Events/input for capturing contenteditable changes.
I've following HTML code of a form:
<form name="question_issue_form" id="question_issue_form" action="question_issue.php">
<table class="trnsction_details" width="100%" cellpadding="5">
<tbody>
<tr>
<td></td>
<td>
<input type="checkbox" name = "que_issue[]" value = "Question is wrong" id ="chkQueWrong">Question is wrong</input>
</td>
</tr>
<tr>
<td></td>
<td><input type="checkbox" name = "que_issue[]" value = "Answers are wrong" id ="chkAnsWrong">Answers are wrong</input></td>
</tr>
<tr>
<td></td>
<td><input type="checkbox" name = "que_issue[]" value = "Question direction is incorrect" id ="chkDirIncorrect">Question direction is incorrecct</input></td>
</tr>
<tr>
<td></td>
<td><input type="checkbox" name = "que_issue[]" value = "Other" id ="chkOther">Other</input></td>
</tr>
<tr>
<td></td>
<td class="set_message" style="display:none;"><textarea name="que_issue_comment" rows="4" cols="25" maxlength="100"></textarea></td>
</tr>
<tr>
<td></td>
<td><input type="submit" name="submit" value="Submit" id="report_question_issue"/></td>
</tr>
</tbody>
</table>
</form>
I want to validate the form before submitting the form such that at least one checkbox is checked from all the above checkboxes and when checkbox with value "Other" is checked then the text area shouldn't be blank. For it I've tried following code, but it's showing alert even after selecting one or more checkboxes. Also the text area validation is also not properly working. Can anyone please help me in correcting this validation code before submission of form? If a single error is thrown the form should not get submit. Following is the jQUery code I 've tried.
$(document).ready(function () {
$('#chkOther').click(function () {
$('.set_message').toggle(this.checked);
});
//This function is use for edit transaction status
$(document).on('click', '#report_question_issue', function (e) {
e.preventDefault();
//$.colorbox.close();
//for confirmation that status change
var ans = confirm("Are you sure to report the question issue over?");
if (!ans) { //alert("Yes its false");
return false;
}
var post_url = $('#post_url').val();
var checkbox = document.getElementsByName("que_issue[]");
var checkedAtLeastOne = false;
$('input[type="checkbox"]').each(function () {
if ($(this).is(":checked")) { alert("In If");
//atleast one is checked
checkedAtLeastOne = true;
} else { alert("In Else");
//error
alert("Check at least one checkbox");
}
var other = document.getElementById("chkOther");
var textfield = document.getElementByName("que_issue_comment");
if ($(other).is(":checked")) {
if ($(textfield).val().length == 0) {
//error
alert("Fill in the textarea");
}
}
});
$.ajax({
type: "POST",
url: post_url,
data: $('#question_issue_form').serialize(),
dataType: 'json',
success: function (data) {
alert("The values have been inserted");
}
});
});
});
The if statement is executed multiple times, once for each checkbox. You'll see the alert for every checkbox that isn't checked, even if another checkbox has been checked. You need to completely change the logic; iterate through them all looking for a checked checkbox, and stop the iteration as soon as you find one.
Then, after examining them all, determine whether or not the alert needs to be displayed.
Your if condition is checking for each checkbox in your page. That's why it going to else part and alerting Check at least one checkbox .To avoid that Try the following code,
$(document).ready(function() {
$('#chkOther').click(function() {
$('.set_message').toggle(this.checked);
});
//This function is use for edit transaction status
$(document).on('click', '#report_question_issue', function(e) {
var submit = true;
e.preventDefault();
//$.colorbox.close();
//for confirmation that status change
var ans = confirm("Are you sure to report the question issue over?");
if (!ans) { //alert("Yes its false");
submit = false;
}
var post_url = $('#post_url').val();
var checkbox = document.getElementsByName("que_issue[]");
var checkedAtLeastOne = false;
$('input[type="checkbox"]').each(function() {
if ($(this).is(":checked")) {
checkedAtLeastOne = true;
return false; //to break from each()
}
});
if (checkedAtLeastOne) {
//alert("In If");
var other = $("#chkOther");
var textfield = $("[name=que_issue_comment]");
if (other.is(":checked")) {
if ($.trim($(textfield).val()).length == 0) {
//error
alert("Fill in the textarea");
submit = false;
}
}
}
else {
alert("Check at least one checkbox");
submit = false;
}
if (submit) {
$.ajax({
type: "POST",
url: post_url,
data: $('#question_issue_form').serialize(),
dataType: 'json',
success: function(data) {
alert("The values have been inserted");
}
});
}
else {
alert("Fix the error");
}
});
});
Fiddle
If i have a table:
<table id="myTable">
<tr>
<td>1</td><td>2</td><td>NoMatch</td><td>4</td>
</tr>
<tr>
<td>1</td><td>2</td><td>Match</td><td>4</td>
</tr>
</table>
I have been trying:
$(document).ready(function () {
$('input#myInput').keyup(function (val) {
// for each third td of each row, if this value does not contain: this.val() then hide it
});
});
Something like this:
var $cells = $('#myTable tr td:nth-child(3)'),
$hidden = $();
$('#myInput').keyup(function () {
var search = this.value;
var $to_hide = $cells.filter(function() {
return $(this).text() !== search;
}).parent();
$hidden.not($to_hide.get()).show();
$hidden = $to_hide.hide();
});
I assumed that when you say contains, you mean that the text has to be equal to the provided input (otherwise NoMatch and Match would not make sense). But if the content of cell just has to contain the search string as substring, you can use .indexOf() [docs].
DEMO
There are other things you have to consider, like what should happen when the search string is empty, but this is for you to play around ;)
Use "this" in your key up event handler to get the value of the input.
$(document).ready(function () {
$('input#myInput').keyup(function () {
//add if statement
alert($(this).val());
});
});
Not quite sure what you are trying to do with the table. There is not enough information.
Try this:
jsfiddle
HTML
<table id="myTable">
<tr>
<td>1</td><td>2</td><td>NoMatch</td><td>4</td>
</tr>
<tr>
<td>1</td><td>2</td><td>Match</td><td>4</td>
</tr>
</table>
<input id="myInput"/>
Javascript/Jquery
$('#myInput').keyup(function () {
var me = $(this);
var val = me.val();
$("#myTable tr").each(function() {
var tr = $(this);
var td = tr.find("td:eq(2)");
if(td.text().substring(0, val.length) === val) {
tr.show();
} else {
tr.hide();
}
});
});