I used this page to create this code
https://getbootstrap.com/docs/5.0/forms/checks-radios/#indeterminate
When I click the checkbox with id=(flexCheckIndeterminate),
all the checkboxes below it will be selected,
and click it again, all the checkboxes below it will be canceled.
How to do it via JS without using jQuery?
<!doctype HTML>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-
EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<body>
<h2>Bootstrap Table Checkbox Select All and Cancel</h2>
<div class="container">
<table class="table table-bordered table-hover" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>
<div class="form-check">
<input class="form-check-input" type="checkbox" value=""
id="flexCheckIndeterminate">
<label class="form-check-label" for="flexCheckIndeterminate">
</label>
</div>
</th>
<th>#</th>
<th >Name</th>
<th > ID</th>
<th >Date & Time</th>
<th >Check-in</th>
</tr>
</thead>
<tbody>
<tr>
<td><div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="defaultCheck1">
<label class="form-check-label" for="defaultCheck1">
</label>
</div>
</td>
<td>1</td>
<td>Safaa</td>
<td>20421</td>
<td>12/2/2021 16:40</td>
<td>Yes</td>
</tr>
<tr>
<td><div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="defaultCheck2">
<label class="form-check-label" for="defaultCheck2">
</label>
</div>
</td>
<td>2</td>
<td>Noor</td>
<td>19091</td>
<td>15/2/2021 16:40</td>
<td>No</td>
</td>
</tr>
</tbody>
</table>
</div>
<!-- Optional JavaScript; choose one of the two! -->
<!-- Option 1: Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
</body>
</html>
I got your point what you are facing problem related to indeterminate in pure JavaScript, If indeterminate selected then you want All checked or unchecked then need to first set indeterminate = false then assign what you want checked/unchecked.
I hope you will more learn with my below snippet code.
Source: https://css-tricks.com/indeterminate-checkboxes/
var parentCheckbox = document.getElementById('flexCheckIndeterminate');
parentCheckbox.addEventListener('change', e => {
document.querySelectorAll('.form-check-input').forEach(checkbox => {
checkbox.checked = e.target.checked
})
});
document.querySelectorAll('tbody .form-check-input').forEach(checkbox => {
checkbox.addEventListener('change', ()=> {
var tbodyCheckbox = document.querySelectorAll('tbody .form-check-input').length;
var tbodyCheckedbox = document.querySelectorAll('tbody .form-check-input:checked').length;
if(tbodyCheckbox == tbodyCheckedbox){
//console.log('All selected')
parentCheckbox.indeterminate = false;
parentCheckbox.checked = true;
}
if (tbodyCheckbox > tbodyCheckedbox && tbodyCheckedbox>=1) {
// console.log('Some selected')
parentCheckbox.indeterminate = true;
}
if(tbodyCheckedbox==0) {
// console.log('No any selected')
parentCheckbox.indeterminate = false;
parentCheckbox.checked = false;
}
})
})
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-
EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<div class="container">
<div class="row">
<div class="col-sm-12 py-2">
<h4>Bootstrap Table Checkbox (Unchecked/Indeterminate/Checked)</h4>
</div>
<div class="col-sm-12">
<table class="table table-bordered table-hover" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="flexCheckIndeterminate">
<label class="form-check-label" for="flexCheckIndeterminate">
</label>
</div>
</th>
<th>#</th>
<th>Name</th>
<th>ID</th>
<th>Date & Time</th>
<th>Check-in</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="defaultCheck1">
<label class="form-check-label" for="defaultCheck1">
</label>
</div>
</td>
<td>1</td>
<td>Raeesh</td>
<td>20421</td>
<td>03/11/2021 12:10</td>
<td>Yes</td>
</tr>
<tr>
<td>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="defaultCheck2">
<label class="form-check-label" for="defaultCheck2">
</label>
</div>
</td>
<td>2</td>
<td>Alam</td>
<td>19091</td>
<td>02/11/2021 11:30</td>
<td>No</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
I'm curious, why did you even mention JQuery? Bootstrap 5 don't use it anymore.
Well, I imagine this is what you want:
// get the global checkbox
const checkbox = document.getElementById("flexCheckIndeterminate");
// listen to changes
checkbox.addEventListener('input', evt => {
// get event value
const checked = evt.target.checked;
// get all other checkboxes
const checkboxes = document.querySelectorAll('input[type="checkbox"]');
// update them with the value of the global checkbox
checkboxes.forEach(checkbox => {
checkbox.checked = checked;
});
});
Here is an example:
document.getElementById('flexCheckIndeterminate').addEventListener('click', e => {
document.querySelectorAll('.form-check-input').forEach(checkbox => {
checkbox.checked = e.target.checked
})
})
<!doctype HTML>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-
EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<body>
<h2>Bootstrap Table Checkbox Select All and Cancel</h2>
<div class="container">
<table class="table table-bordered table-hover" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="flexCheckIndeterminate">
<label class="form-check-label" for="flexCheckIndeterminate">
</label>
</div>
</th>
<th>#</th>
<th>Name</th>
<th> ID</th>
<th>Date & Time</th>
<th>Check-in</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="defaultCheck1">
<label class="form-check-label" for="defaultCheck1">
</label>
</div>
</td>
<td>1</td>
<td>Safaa</td>
<td>20421</td>
<td>12/2/2021 16:40</td>
<td>Yes</td>
</tr>
<tr>
<td>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="defaultCheck2">
<label class="form-check-label" for="defaultCheck2">
</label>
</div>
</td>
<td>2</td>
<td>Noor</td>
<td>19091</td>
<td>15/2/2021 16:40</td>
<td>No</td>
</td>
</tr>
</tbody>
</table>
</div>
<!-- Optional JavaScript; choose one of the two! -->
<!-- Option 1: Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>
Related
I want to check the checkbox items by looking for its value using JavaScript; I have the below test table with input form. When I put the value id to the form also hitting enter, then checking its checkbox.
For now the JavaScript is checking if value is = 1, but I want to make the value come from the input form to checking specific record.
$(document).ready(function() {
var chkbox = $('.customcheckbox');
$(".customvalue").keyup(function() {
chkbox.prop('checked', this.value == 1);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.3.1/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card-header">
<h4 class="text-center">Checking Checkboxes by Id </h4>
<div class="col-md-12">
<div class="card-md-4">
<div class="card-body">
<input id="myTxt" type="text" value="" name="search" class="form-control ml-auto m-2 customvalue" style="width: 25%;" placeholder="Enter barcode">
<form action="delete.php" method="post">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>
<button type="submit" name="stud_delete_multiple_btn" class="btn btn-danger" onclick="return confirm('Are you sure you want to delete selected?')">DELETE</button>
</th>
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
</thead>
<tbody>
<tr>
<td style="width: 10px;text-align:center">
<input type="checkbox" name="stud_id_1" class="customcheckbox" value="1">
</td>
<td>1</td>
<td>Susana</td>
<td>Daivid</td>
</tr>
<tr>
<td style="width: 10px;text-align:center">
<input type="checkbox" name="stud_id_1" class="customcheckbox" value="2">
</td>
<td>2</td>
<td>Sose</td>
<td>Nawsat</td>
</tr>
<tr>
<td style="width: 10px;text-align:center">
<input type="checkbox" name="stud_id_1" class="customcheckbox" value="3">
</td>
<td>3</td>
<td>Primso</td>
<td>Navid</td>
</tr>
<tr>
<td style="width: 10px;text-align:center">
<input type="checkbox" name="stud_id_1" class="customcheckbox" value="4">
</td>
<td>4</td>
<td>Lila</td>
<td>Noord</td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
</div>
</div>
</div>
</col-md-12>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.14.7/dist/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.3.1/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
$(document).ready(function() {
var chkbox = $('.customcheckbox');
$(".customvalue").keyup(function() {
const customValue = $(this).val();
chkbox.each(function() {
$(this).prop('checked', customValue == $(this).val());
});
});
});
At first, I request you to see these two images.
image 1
image 2
There are more than 20 fields like in 'Image 1'. If select yes then show a table like in 'Image 2'. So I have 20 Yes/No field and 20 different tables.
How can I show the tables if select yes. I have tried some code for a single field. As there are lots of fields I want to know is there any way to make the code minimal and easier. Here is my code that I tried:
CSS:
#show-dc-table {
display: none;
}
Script:
<script>
$(document).ready(function() {
$('.form-check-inline input[type="radio"]').click(function() {
if ($(this).attr('id') == 'allergy-yes') {
$('#show-dc-table').show();
} else {
$('#show-dc-table').hide();
}
});
});
</script>
HTML:
<div class="form-group row">
<label class="col-sm-2 col-form-label">Do you have Allergies </label>
<div class="col-sm-10">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="allergy" value="Yes" id="allergy-yes">
<label class="form-check-label">Yes</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="allergy" value="No">
<label class="form-check-label">No</label>
</div>
</div>
</div>
<table class="table table-striped" id="show-dc-table">
<tr>
<th scope="col">Alergic Reactions to</th>
<th scope="col">Yes</th>
<th scope="col">No</th>
<th scope="col">Notes</th>
</tr>
</table>
To make the same code work for multiple repeated HTML structures group elements by behaviour using the same class on each. Then use DOM traversal to relate the elements to each other when certain events happen.
In your case you would use closest() and next() to find the table related to the changed radio. Also note that you should use the checked property of the radio, along with the change event, to determine the value selected. Try this:
$(document).ready(function() {
$('.form-check-inline input[type="radio"]').on('change', function() {
$(this).closest('.form-group').next('table').toggle(this.checked && this.value === 'Yes');
});
});
.show-dc-table {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Do you have allergies?</label>
<div class="col-sm-10">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="allergy" value="Yes">
<label class="form-check-label">Yes</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="allergy" value="No">
<label class="form-check-label">No</label>
</div>
</div>
</div>
<table class="table table-striped show-dc-table">
<thead>
<tr>
<th scope="col">Alergic Reactions to</th>
<th scope="col">Yes</th>
<th scope="col">No</th>
<th scope="col">Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>Aspirin, Ibuprofen, Codeine</td>
<td><input type="radio" name="a1" /></td>
<td><input type="radio" name="a2" /></td>
<td><input type="text" /></td>
</tr>
</tbody>
</table>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Do you have a cough?</label>
<div class="col-sm-10">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="cough" value="Yes">
<label class="form-check-label">Yes</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="cough" value="No">
<label class="form-check-label">No</label>
</div>
</div>
</div>
<table class="table table-striped show-dc-table">
<thead>
<tr>
<th scope="col">Alergic Reactions to</th>
<th scope="col">Yes</th>
<th scope="col">No</th>
<th scope="col">Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>Lorem ipsum</td>
<td><input type="radio" name="a1" /></td>
<td><input type="radio" name="a2" /></td>
<td><input type="text" /></td>
</tr>
</tbody>
</table>
To generalize any DOM manipulation script, do not use hardcoded ids. Use methods like closest , find , next , prev. Two methods closest , find are used in this particular example.
$(document).ready(function() {
$('.form-check-inline input[type="radio"]').click(function() {
if ($(this).val() == 'Yes') {
$(this).closest('.form-group').next('table').show();
} else {
$(this).closest('.form-group').next('table').hide();
}
});
});
.table.table-striped {
display: none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div class="form-group row">
<label class="col-sm-2 col-form-label">Do you have Allergies </label>
<div class="col-sm-10">
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="allergy" value="Yes" id="allergy-yes">
<label class="form-check-label">Yes</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="allergy" value="No">
<label class="form-check-label">No</label>
</div>
</div>
</div>
<table class="table table-striped" id="show-dc-table">
<tr>
<th scope="col">Alergic Reactions to</th>
<th scope="col">Yes</th>
<th scope="col">No</th>
<th scope="col">Notes</th>
</tr>
</table>
I want to change commitment text to be changed with input field when I click on commitment and when I press enter it should show the newly entered input.
I am new to javascript but I looked many codes but they didn't slove what I want please can you provide any idea how to do this?`
<div class="table-responsive">
<table class="table table-bordered table-hover" id="dtBasicExample" cellspacing="0" width="100%">
<!-- Table head -->
<thead class="theader">
<tr>
<th>Grade</th>
<th>Student</th>
<th>
<!-- Default un -->
<!-- <div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="tableDefaultCheck1">
<label class="custom-control-label" for="tableDefaultCheck1">P/A</label>
</div> -->P/A
</th>
<th>Check-In</th>
<th>Check-Out</th>
<th>Tutor</th>
<th>Videos</th>
<th>Others</th>
<th>Commitment</th>
</tr>
</thead>
<tbody>
</tr>
<tr>
<td>7</td>
<td>Name</td>
<th scope="row">
<!-- Default un -->
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="tableDefaultCheck3">
<label class="custom-control-label" for="tableDefaultCheck3"></label>
</div>
</th>
<td>Time</td>
<td>Time</td>
<td>Time</td>
<td>Time</td>
<td>Time</td>
<td>Commitment
<div class="md-form">
<input type="text" id="form2" class="form-control">
<label for="form2">New Commitment</label>
</div>
</td>
</tr>
</tbody>
</table>
Is this what you are looking for?
$('.md-form input').keydown(function(e) {
if(e.keyCode == 13 && $(this).val().length > 0){
$(this).next().text($(this).val())
}
});
Working demo
$('.md-form input').keydown(function(e) {
if (e.keyCode == 13 && $(this).val().length > 0) {
$(this).next().show().text($(this).val())
$(this).hide();
}
});
$('.Commitment label').click(function() {
$(this).prev().show();
$(this).hide();
})
.Commitment input {
display: none;
}
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>
<div class="table-responsive">
<table class="table table-bordered table-hover" id="dtBasicExample" cellspacing="0" width="100%">
<!-- Table head -->
<thead class="theader">
<tr>
<th>Grade</th>
<th>Student</th>
<th>
<!-- Default un -->
<!-- <div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="tableDefaultCheck1">
<label class="custom-control-label" for="tableDefaultCheck1">P/A</label>
</div> -->P/A
</th>
<th>Check-In</th>
<th>Check-Out</th>
<th>Tutor</th>
<th>Videos</th>
<th>Others</th>
<th>Commitment</th>
</tr>
</thead>
<tbody>
<tr>
<td>7</td>
<td>Name</td>
<th scope="row">
<!-- Default un -->
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="tableDefaultCheck3">
<label class="custom-control-label" for="tableDefaultCheck3"></label>
</div>
</th>
<td>Time</td>
<td>Time</td>
<td>Time</td>
<td>Time</td>
<td>Time</td>
<td class="Commitment">
<div class="md-form">
<input type="text" id="form2" class="form-control">
<label for="form2">New Commitment</label>
</div>
</td>
</tr>
<tr>
<td>7</td>
<td>Name</td>
<th scope="row">
<!-- Default un -->
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="tableDefaultCheck3">
<label class="custom-control-label" for="tableDefaultCheck3"></label>
</div>
</th>
<td>Time</td>
<td>Time</td>
<td>Time</td>
<td>Time</td>
<td>Time</td>
<td class="Commitment">
<div class="md-form">
<input type="text" id="form2" class="form-control">
<label for="form2">New Commitment</label>
</div>
</td>
</tr>
</tbody>
</table>
</div>
I want to press enter on the 'Buscar' input and focus on the first input ( 'Qtd on the table').
I tried
$(this).nextAll('input').first().focus();
$(this).next('input:text').focus();
And a lot of solutions and other codes I found here and online but nothing worked. I didn't get any errors on the console which makes it harder to find out what I'm missing.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!doctype html>
<html>
<head>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
</head>
<body style="padding-top: 70px;">
<div class="container-fluid">
<div class="row">
<div class="col-6">
<center>
<div class="form-group has-feedback">
<input type="text" class="form-control" name="busca" id="busca" onclick="this.select()" placeholder="Buscar">
</div>
</center>
<table class="table table-striped">
<thead class="thead-dark">
<th class="w-50">Material</th>
<th>Unidade</th>
<th>Quantidade</th>
<th class="w-25">Preço</th>
<th>Qtd</th>
</thead>
<tbody class="resultado" id="lista">
<tr id="row1">
<td style="display:none;">1</td>
<td>Adesivo Instantâneo Almasuper 100g</td>
<td>Galão</td>
<td>64</td>
<td>R$ 20,00</td>
<td>
<div class="qtd" style="width: 60px;">
<input id="1" type="text" class="form-control" name="quantidade">
</div>
</td>
</tr>
<tr id="row4">
<td style="display:none;">4</td>
<td>Batente Silicone Adesivo 12mm com 25</td>
<td>Cartela</td>
<td></td>
<td>R$ 6,50</td>
<td>
<div class="qtd" style="width: 60px;">
<input id="4" type="text" class="form-control" name="quantidade">
</div>
</td>
</tbody>
</table>
</div>
</div>
First, you shouldn't be setting numerical ids. Second, buscar has no siblings so you can't say nextAll because they aren't any siblings.
What you can do is watch the input for an enter key up and focus on the first input with the name quantidade. See the first function below.
$('#busca').on('keyup', function(e){
if(e.which === 13){
$('input[name="quantidade"]').first().focus();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!doctype html>
<html>
<head>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
</head>
<body style="padding-top: 70px;">
<div class="container-fluid">
<div class="row">
<div class="col-6">
<center>
<div class="form-group has-feedback">
<input type="text" class="form-control" name="busca" id="busca" placeholder="Buscar">
</div>
</center>
<table class="table table-striped">
<thead class="thead-dark">
<th class="w-50">Material</th>
<th>Unidade</th>
<th>Quantidade</th>
<th class="w-25">Preço</th>
<th>Qtd</th>
</thead>
<tbody class="resultado" id="lista">
<tr id="row1">
<td style="display:none;">1</td>
<td>Adesivo Instantâneo Almasuper 100g</td>
<td>Galão</td>
<td>64</td>
<td>R$ 20,00</td>
<td>
<div class="qtd" style="width: 60px;">
<input id="1" type="text" class="form-control" name="quantidade">
</div>
</td>
</tr>
<tr id="row4">
<td style="display:none;">4</td>
<td>Batente Silicone Adesivo 12mm com 25</td>
<td>Cartela</td>
<td></td>
<td>R$ 6,50</td>
<td>
<div class="qtd" style="width: 60px;">
<input id="4" type="text" class="form-control" name="quantidade">
</div>
</td>
</tbody>
</table>
</div>
</div>
// get all the inputs that are not disabled and not hidden
var $allInputs = $(':input:not(:disabled):not(:hidden)');
$('#busca').on('keyup', function(e){
// if enter was pressed
if ((e.keyCode || e.which) === 13) {
// cancel any form submit that might happen
e.preventDefault();
// focus on the input that is the next index after the index that busca has
$allInputs.eq( $allInputs.index(this) + 1 ).focus();
}
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container-fluid">
<div class="row">
<div class="col-6">
<center>
<div class="form-group has-feedback">
<input type="text" class="form-control" name="busca" id="busca" onclick="this.select()" placeholder="Buscar">
</div>
</center>
<table class="table table-striped">
<thead class="thead-dark">
<th class="w-50">Material</th>
<th>Unidade</th>
<th>Quantidade</th>
<th class="w-25">Preço</th>
<th>Qtd</th>
</thead>
<tbody class="resultado" id="lista">
<tr id="row1">
<td style="display:none;">1</td>
<td>Adesivo Instantâneo Almasuper 100g</td>
<td>Galão</td>
<td>64</td>
<td>R$ 20,00</td>
<td>
<div class="qtd" style="width: 60px;">
<input id="1" type="text" class="form-control" name="quantidade">
</div>
</td>
</tr>
<tr id="row4">
<td style="display:none;">4</td>
<td>Batente Silicone Adesivo 12mm com 25</td>
<td>Cartela</td>
<td></td>
<td>R$ 6,50</td>
<td>
<div class="qtd" style="width: 60px;">
<input id="4" type="text" class="form-control" name="quantidade">
</div>
</td>
</tbody>
</table>
</div>
</div>
I'm using DataTables with the columns.render option to implement custom sorting for a table. That works fine when the logic within the sort function only depends on static data. However, I'd like to provide some controls to my users controlling how the sorting should happen. The problem is that it seems like DataTables is caching the first sort result, so when the user tries to change the sorting controls it doesn't have any effect.
In short, I'd like to have a dynamic sort function.
Obviously this is best explained with an example. The idea is to allow the "Info" column to be sorted either by "customer name" or "price", depending on what the user selects in the radio above the table. Run it and you'll see that the sorting only works for the initial radio selection.
$(function() {
var opts = {
"columns": [{
'searchable': false
}, {
'render': function(data, type, row, meta) {
if (type === 'sort') {
var sel = $("input[name=infoFilterOptions]:checked").val();
return $(sel, $(data)).data('value');
}
return data;
}
}]
};
$("#the_table").DataTable(opts);
});
<html>
<head>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.css" />
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.js"></script>
</head>
<body>
<div style="color:green; margin-bottom: 10px;">
<div style="display: inline-block; margin-right: 10px;">Sort <i>Info</i> column by:</div>
<label class="radio-inline">
<input style="margin-top: 0;" type="radio" name="infoFilterOptions" value=".info-price" checked>Price
</label>
<label class="radio-inline">
<input style="margin-top: 0;" type="radio" name="infoFilterOptions" value=".info-customer-name">Customer name
</label>
</div>
<table id="the_table" class="stripe">
<thead>
<tr>
<th>Id</th>
<th>Info</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>
<div>Customer name: <span class="info-customer-name" data-value="John">John</span>
</div>
<div>Price: <span class="info-price" data-value="42.42">$42.42</span>
</div>
</td>
</tr>
<tr>
<td>3</td>
<td>
<div>Customer name: <span class="info-customer-name" data-value="Melvyn">Melvyn</span>
</div>
<div>Price: <span class="info-price" data-value="14.0">$14.00</span>
</div>
</td>
</tr>
<tr>
<td>18</td>
<td>
<div>Customer name: <span class="info-customer-name" data-value="Aaaaardvark">Aaaaardvark</span>
</div>
<div>Price: <span class="info-price" data-value="22.3">$22.30</span>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
Allan answered this question over on the DataTables forums. First class support, as always!
Short answer is that DataTables is indeed caching the sort result. You need to invalidate the data in the table (via row().invalidate() or rows().invalidate()) in order to recompute the sort order.
This does the trick:
$('input[type=radio][name=infoFilterOptions]').on('change', function() {
$("#the_table").DataTable().rows().invalidate();
});
Here's the full example from above including this fix:
$(function() {
var opts = {
"columns": [{
'searchable': false
}, {
'render': function(data, type, row, meta) {
if (type === 'sort') {
var sel = $("input[name=infoFilterOptions]:checked").val();
return $(sel, $(data)).data('value');
}
return data;
}
}]
};
$("#the_table").DataTable(opts);
$('input[type=radio][name=infoFilterOptions]').on('change', function() {
$("#the_table").DataTable().rows().invalidate();
});
});
<html>
<head>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.css" />
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.js"></script>
</head>
<body>
<div style="color:green; margin-bottom: 10px;">
<div style="display: inline-block; margin-right: 10px;">Sort <i>Info</i> column by:</div>
<label class="radio-inline">
<input style="margin-top: 0;" type="radio" name="infoFilterOptions" value=".info-price" checked>Price
</label>
<label class="radio-inline">
<input style="margin-top: 0;" type="radio" name="infoFilterOptions" value=".info-customer-name">Customer name
</label>
</div>
<table id="the_table" class="stripe">
<thead>
<tr>
<th>Id</th>
<th>Info</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>
<div>Customer name: <span class="info-customer-name" data-value="John">John</span>
</div>
<div>Price: <span class="info-price" data-value="42.42">$42.42</span>
</div>
</td>
</tr>
<tr>
<td>3</td>
<td>
<div>Customer name: <span class="info-customer-name" data-value="Melvyn">Melvyn</span>
</div>
<div>Price: <span class="info-price" data-value="14.0">$14.00</span>
</div>
</td>
</tr>
<tr>
<td>18</td>
<td>
<div>Customer name: <span class="info-customer-name" data-value="Aaaaardvark">Aaaaardvark</span>
</div>
<div>Price: <span class="info-price" data-value="22.3">$22.30</span>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>