Im just trying to build a basic site for linking tenants and properties, and I am coming into some issues with a collapsible web grid. This javascript comes from a tutorial, have repurposed it to fit my task. The issue is my javascript simply doesnt seem to be running. Find below my cshtml and also my shared layout.
Cshtml
#model IEnumerable<HousingProject.Models.Property>
#{
ViewBag.Title = "Index";
WebGrid grid = new WebGrid(source: Model, canSort: false);
}
<style type="text/css">
th, td {
padding: 5px;
}
th {
background-color: rgb(248, 248, 248);
}
#gridT, #gridT tr {
border: 1px solid #0D857B;
}
#subT, #subT tr {
border: 1px solid #f3f3f3;
}
#subT {
margin: 0px 0px 0px 10px;
padding: 5px;
width: 95%;
}
#subT th {
font-size: 12px;
}
.hoverEff {
cursor: pointer;
}
.hoverEff:hover {
background-color: rgb(248, 242, 242);
}
.expand {
background-image: url(/Content/themes/base/images/pm.png);
background-position: -22px;
background-repeat: no-repeat;
}
.collapse {
background-image: url(/Content/themes/base/images/pm.png);
background-position: -2px;
background-repeat: no-repeat;
}
</style>
<h2>Index</h2>
<p>
#using (Html.BeginForm("Index", "Property", FormMethod.Get))
{
#Html.TextBox("filter")
<input type="submit" value="Search" />
}
</p>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.HouseNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.StreetName)
</th>
<th>
#Html.DisplayNameFor(model => model.Town)
</th>
<th>
#Html.DisplayNameFor(model => model.City)
</th>
<th>
#Html.DisplayNameFor(model => model.Postcode)
</th>
<th>
#Html.DisplayNameFor(model => model.MaxOccupancy)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.HouseNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.StreetName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Town)
</td>
<td>
#Html.DisplayFor(modelItem => item.City)
</td>
<td>
#Html.DisplayFor(modelItem => item.Postcode)
</td>
<td>
#Html.DisplayFor(modelItem => item.MaxOccupancy)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
#Html.ActionLink("Details", "Details", new { id=item.ID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ID })
</td>
</tr>
}
</table>
<div id="main" style="padding:25px; background-color:white;">
#grid.GetHtml(
htmlAttributes: new { id = "gridT", width = "700px" },
columns: grid.Columns(
grid.Column("HouseNumber", "House Number"),
grid.Column("StreetName","Street Name"),
grid.Column("Town", "Town"),
grid.Column("City", "City"),
grid.Column("Postcode", "Postcode"),
grid.Column("MaxOccupancy", "Max Occupancy"),
grid.Column("CurrentOccupancy", "Current Occupancy"),
grid.Column(format: (item) =>
{
WebGrid subGrid = new WebGrid(source: item.CurrentTenants);
return subGrid.GetHtml(
htmlAttributes: new { id = "subT" },
columns: subGrid.Columns(
subGrid.Column("FirstName", "First Name"),
subGrid.Column("Surname", "Surname"),
subGrid.Column("Age", "Age"),
subGrid.Column("Employer", "Employer")
)
);
})
)
)
</div>
<script type="text/javascript">
$(document).ready(function () {
var size = $("#main #gridT > thead > tr >th").size(); // get total column
$("#main #gridT > thead > tr >th").last().remove(); // remove last column
$("#main #gridT > thead > tr").prepend("<th></th>"); // add one column at first for collapsible column
$("#main #gridT > tbody > tr").each(function (i, el) {
$(this).prepend(
$("<td></td>")
.addClass("expand")
.addClass("hoverEff")
.attr('title', "click for show/hide")
//.attr('onclick', 'toggleWebGrid()')
);
//Now get sub table from last column and add this to the next new added row
var table = $("table", this).parent().html();
//add new row with this subtable
$(this).after("<tr><td></td><td style='padding:5px; margin:0px;' colspan='" + (size - 1) + "'>" + table + "</td></tr>");
$("table", this).parent().remove();
});
//by default make all subgrid in collapse mode
$("#main #gridT > tbody > tr td.expand").each(function (i, el) {
$(this).toggleClass("expand collapse");
$(this).parent().closest("tr").next().slideToggle(100);
});
});
//toggle expand and collapse
$(function () {
$("#main #gridT > tbody > tr td.collapse").on('click', function () {
alert('test');
$(this).toggleClass("expand collapse");
$(this).parent().closest("tr").next().slideToggle(100);
});
});
</script>
Shared Layout
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - My ASP.NET Application</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
#Html.ActionLink("Application name", "Index", "Home", null, new { #class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
<li>#Html.ActionLink("Properties","Index","Property")</li>
</ul>
#Html.Partial("_LoginPartial")
</div>
</div>
</div>
<div class="container body-content">
#RenderBody()
<hr />
<footer>
<p>© #DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
</body>
</html>
Im sure you guys will figure it out, been banging my head for a while now, cant even get the debugger to step into it so I'm sure its something wrong in config not the javascript. Please note the tabled part of the page is simply a legacy thing, I dont desperately want to remove it untill this new webgrid works. Ta.
I simply needed to move the
#Scripts.Render("~/bundles/jquery")
#RenderSection("scripts", required: false)
to head section of the sharedLayout. No idea why MVC defaults them to being at the bottom. Seems unhelpful.
Related
I have a searchable table I'm developing where users need to be able to export their results, but also select the number of results they see. The problem is that everything looks too crammed together. I want to be able to add a line break, paragraph, or a div to space things out. Basically, I want this:
Project Search Show [Number] Entries
[Copy] [Excel] [CSV] [PDF] [Column Visibility]
[My table]
How would I go about doing this? I can't rely on my trusty BR and P html tags here, but I would like to figure this out.
$(document).ready(function() {
$('#example').DataTable({
"lengthMenu": [10, 25, 50, 75, 100],
dom: 'lBfrtip',
"columnDefs": [{
"targets": [],
"visible": false,
"searchable": false
},
{
"targets": [],
"visible": false
}
],
buttons: [{
extend: 'copyHtml5',
exportOptions: {
columns: ':visible',
format: {
body: function(data, row, column, node) {
var text = node.textContent;
return column === 10 ? text.replace(/Open$/, '').trim() : data;
}
}
}
},
{
extend: 'excelHtml5',
exportOptions: {
columns: ':visible',
format: {
body: function(data, row, column, node) {
var text = node.textContent;
return column === 10 ? text.replace(/Open$/, '').trim() : data;
}
}
}
},
{
extend: 'csvHtml5',
exportOptions: {
columns: ':visible',
format: {
body: function(data, row, column, node) {
var text = node.textContent;
return column === 10 ? text.replace(/Open$/, '').trim() : data;
}
}
}
},
{
extend: 'pdfHtml5',
orientation: 'landscape',
exportOptions: {
columns: ':visible',
format: {
body: function(data, row, column, node) {
var text = node.textContent;
return column === 10 ? text.replace(/Open$/, '').trim() : data;
}
}
}
},
'colvis'
]
});
});
div.dt-button-collection {
width: 215px;
}
.display.dataTable {
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: 12px;
}
.modal {
max-width: 1000px;
margin: 2rem auto;
}
td.none {
display: none;
}
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css" />
<link rel "=stylesheet" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.dataTables.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<!-- jQuery Modal -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-modal/0.9.1/jquery.modal.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-modal/0.9.1/jquery.modal.min.css" />
<link href="https://cdn.datatables.net/buttons/1.2.2/css/buttons.dataTables.css" rel="stylesheet" />
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.4.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/vfs_fonts.js"></script>
<script src="https://cdn.datatables.net/buttons/1.4.2/js/buttons.html5.min.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.html5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.colVis.min.js"></script>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<table id="example" class="display">
<thead>
<tr>
<th class="all" data-toggle="tooltip" title="The known name of the project.">Project Name</th>
<th class="all" data-toggle="tooltip" title="The provided unique ID that distinguishes projects.">Project Number</th>
<th class="all" data-toggle="tooltip" title="The conclusing time point of a project, which is sometimes, but not always the point at which funding ends.">End Date</th>
<th class="all" data-toggle="tooltip" title="The primary funder of the project.">Funder</th>
<th class="all" data-toggle="tooltip" title="A brief description on the scope and aims of a project.">Abstract</th>
</tr>
</thead>
<tbody>
<tr>
<td>Project 1</td>
<td>P-1</td>
<td>2018-04-30 00:00:00</td>
<td>NIH</td>
<td>
<div id="ex83" class="modal">
<p>
Abstract 1
</div>
<p><button class="button">Open<span></span></button></p>
</td>
</tr>
<tr>
<td>Project 2</td>
<td>P-2</td>
<td>2024-03-31 00:00:00</td>
<td>NIH</td>
<td>
<div id="ex103" class="modal">
<p>
Abstract 2
</div>
<p><button class="button">Open<span></span></button></p>
</td>
</tr>
<tr>
<td>Project 3</td>
<td>P-3</td>
<td>2021-01-31 00:00:00</td>
<td>NIH</td>
<td>
<div id="ex111" class="modal">
<p> Abstract 3</p>
</div>
<p><button class="button">Open<span></span></button></p>
</td>
</tr>
</tbody>
</table>
If I understood you correctly, I only added this CSS rule:
.dataTables_length {
position: relative;
float: none !important;
text-align: center;
}
Obviously, if you don't want the Show [Number] Entries horizontally centered, just remove text-align: center;
$(document).ready(function() {
$('#example').DataTable({
"lengthMenu": [10, 25, 50, 75, 100],
dom: '<l>Bfrtip',
"columnDefs": [{
"targets": [],
"visible": false,
"searchable": false
},
{
"targets": [],
"visible": false
}
],
buttons: [{
extend: 'copyHtml5',
exportOptions: {
columns: ':visible',
format: {
body: function(data, row, column, node) {
var text = node.textContent;
return column === 10 ? text.replace(/Open$/, '').trim() : data;
}
}
}
},
{
extend: 'excelHtml5',
exportOptions: {
columns: ':visible',
format: {
body: function(data, row, column, node) {
var text = node.textContent;
return column === 10 ? text.replace(/Open$/, '').trim() : data;
}
}
}
},
{
extend: 'csvHtml5',
exportOptions: {
columns: ':visible',
format: {
body: function(data, row, column, node) {
var text = node.textContent;
return column === 10 ? text.replace(/Open$/, '').trim() : data;
}
}
}
},
{
extend: 'pdfHtml5',
orientation: 'landscape',
exportOptions: {
columns: ':visible',
format: {
body: function(data, row, column, node) {
var text = node.textContent;
return column === 10 ? text.replace(/Open$/, '').trim() : data;
}
}
}
},
'colvis'
]
});
});
div.dt-button-collection {
width: 215px;
}
.display.dataTable {
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: 12px;
}
.modal {
max-width: 1000px;
margin: 2rem auto;
}
td.none {
display: none;
}
div.dt-buttons {
float: none;
}
.dataTables_length {
position: relative;
float: none !important;
text-align: center;
}
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css" />
<link rel "=stylesheet" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.dataTables.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<!-- jQuery Modal -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-modal/0.9.1/jquery.modal.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-modal/0.9.1/jquery.modal.min.css" />
<link href="https://cdn.datatables.net/buttons/1.2.2/css/buttons.dataTables.css" rel="stylesheet" />
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.4.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/vfs_fonts.js"></script>
<script src="https://cdn.datatables.net/buttons/1.4.2/js/buttons.html5.min.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.html5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.colVis.min.js"></script>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<table id="example" class="display">
<thead>
<tr>
<th class="all" data-toggle="tooltip" title="The known name of the project.">Project Name</th>
<th class="all" data-toggle="tooltip" title="The provided unique ID that distinguishes projects.">Project Number</th>
<th class="all" data-toggle="tooltip" title="The conclusing time point of a project, which is sometimes, but not always the point at which funding ends.">End Date</th>
<th class="all" data-toggle="tooltip" title="The primary funder of the project.">Funder</th>
<th class="all" data-toggle="tooltip" title="A brief description on the scope and aims of a project.">Abstract</th>
</tr>
</thead>
<tbody>
<tr>
<td>Project 1</td>
<td>P-1</td>
<td>2018-04-30 00:00:00</td>
<td>NIH</td>
<td>
<div id="ex83" class="modal">
<p>
Abstract 1
</div>
<p><button class="button">Open<span></span></button></p>
</td>
</tr>
<tr>
<td>Project 2</td>
<td>P-2</td>
<td>2024-03-31 00:00:00</td>
<td>NIH</td>
<td>
<div id="ex103" class="modal">
<p>
Abstract 2
</div>
<p><button class="button">Open<span></span></button></p>
</td>
</tr>
<tr>
<td>Project 3</td>
<td>P-3</td>
<td>2021-01-31 00:00:00</td>
<td>NIH</td>
<td>
<div id="ex111" class="modal">
<p> Abstract 3</p>
</div>
<p><button class="button">Open<span></span></button></p>
</td>
</tr>
</tbody>
</table>
By the way, you didn't say anything about the Search box
I am working on a small application that displays a "users" JSON in an HTML5 table. I use Bootstrap 3, Axios and Vue.js 2 for this purpose.
The items displayed are paginated. Here is the code for all that:
var app = new Vue({
el: '#app',
data: {
users: [],
loading: true,
errored: false,
url: "https://randomuser.me/api/?&results=100&inc=name,location,email,cell,picture",
page: 1,
perPage: 10,
pages: [],
},
methods: {
getUsers() {
axios
.get(this.url)
.then(response => {
this.users = response.data.results
})
.catch(error => {
console.log(error)
this.errored = true
})
.finally(() => this.loading = false)
},
setPages() {
var numberOfPages = Math.ceil(this.users.length / this.perPage);
for (var index = 1; index <= numberOfPages; index++) {
this.pages.push(index);
}
},
paginate(users) {
var page = this.page;
var perPage = this.perPage;
var from = (page * perPage) - perPage;
var to = (page * perPage);
return users.slice(from, to);
}
},
created() {
this.getUsers();
},
watch: {
users() {
this.setPages();
}
},
computed: {
displayedUsers() {
return this.paginate(this.users);
}
},
filters: {
lowercase(value) {
return value.toLowerCase();
},
capitalize(value) {
return value.charAt(0).toUpperCase() + value.slice(1);
}
}
});
.table-container {
margin: 10px;
}
.table-container .panel-heading {
font-weight: bold;
}
.table-container .panel-body {
padding: 0;
}
.table-container table {
margin-bottom: 0;
border: none;
}
.table-container table tr:last-child td {
border-bottom: none;
}
.table-container table tr th {
font-weight: bold;
}
.table-container table tr th:first-child,
.table-container table tr td:first-child {
border-left: none;
}
.table-container table tr th:last-child,
.table-container table tr td:last-child {
border-right: none;
}
.table-container table tr td {
padding: 2px 8px !important;
vertical-align: middle;
}
.table-container table tr td .picture {
padding-right: 10px;
}
.table-container table tr td img {
max-height: 30px;
width: auto;
border: 1px solid #c7c7c7;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div id="app" class="container">
<div class="panel panel-default table-container">
<div class="panel-heading">Users</div>
<div class="panel-body">
<div class="table-responsive">
<table class="table table-striped table-bordered" id="dataTable">
<thead>
<tr>
<th class="text-right">#</th>
<th>Name</th>
<th>Email</th>
<th>City</th>
</tr>
</thead>
<tbody>
<tr v-for="(user, index) in displayedUsers">
<td class="text-right">{{perPage * (page - 1) + index + 1}}</td>
<td>
<span class="picture">
<img :src="user.picture.thumbnail" :alt="user.name.first + ' ' + user.name.last" class="img-circle">
</span>
<span>{{user.name.first | capitalize}} {{user.name.last | capitalize}}</span>
</td>
<td><a :href="'mailto:' + user.email | lowercase">{{user.email | lowercase}}</a></td>
<td>{{user.location.city | capitalize}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<nav class="text-center" aria-label="Page navigation">
<ul class="pagination pagination-sm">
<li>
<a href="#" #click="page = 1" aria-label="First">
<span aria-hidden="true">«</span>
</a>
</li>
<li>
<a href="#" v-if="page != 1" #click="page--" aria-label="Previous">
<span aria-hidden="true">‹</span>
</a>
</li>
<li v-for="pageNumber in pages.slice(page-1, page+4)" :class="{'active': page === pageNumber}">{{pageNumber}}</li>
<li>
<a href="#" #click="page++" v-if="page < pages.length" aria-label="Next">
<span aria-hidden="true">›</span>
</a>
</li>
<li>
<a href="#" #click="page = pages.length" aria-label="Last">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/axios#0.18.0/dist/axios.min.js"></script>
I have ran into a problem after adding a search/filter functionality to he application. I have added this to the template/view:
<div class="panel-heading clearfix">
<h2 class="pull-left">Users</h2>
<div class="searchbox">
<input type="text" v-model="search" class="form-control" placeholder="Search...">
</div>
</div>
and replaced <tr v-for="(user, index) in displayedUsers"> with <tr v-for="(user, index) in searchResults">.
Then, to computed section of the script the script, I added:
searchResults() {
return this.users.filter((user) => {
return user.name.first.match(this.search);
});
}
The search (through names) works, but neither the entire JSON, nor the search results are paginated.
I have failed to make them work together. The broken application can be seen HERE.
What is missing?
In order to make the pagination work together with the filtering you need to combine the pagination logic with your searchResults in displayedUsers
displayedUsers() {
return this.paginate(this.searchResults);
},
Then you will need to use displayedUsers everywhere where you are interested the combined result, so in your template:
<tr v-for="(user, index) in displayedUsers">
There is one more thing to fix in your code: the number of pages currently always uses the original user count, which has to be updated to use the "current" user count:
setPages(users) {
this.pages.length = 0; //we need to clear the previously set pages
var numberOfPages = Math.ceil(users.length / this.perPage);
for (var index = 1; index <= numberOfPages; index++) {
this.pages.push(index);
}
},
And update the pages whenever the dispayedUsers are changed:
watch: {
displayedUsers() {
this.setPages(this.searchResults);
}
},
If you also want to reset the page when on search you just need to set the page in searchResults
searchResults() {
this.page = 1;
return this.users.filter((user) => {
return user.name.first.match(this.search);
});
}
Working JSFiddle.
I have a table on my page and I was wondering if it was possible to change the values of the 2nd column when a user clicks on the heading of the 2nd column.
For example,
-----------------------------
| 1st heading | 2nd heading |
|-------------|-------------|
| | |
| | |
| | |
| | |
| | |
Now when the user clicks on "2nd heading" the value of the second column will change and the name of the heading will change too ( from 2nd heading to 3rd heading )
This is a simple task using jquery.
First add id to the columns. The second heading column should be like this
Without jQuery
<th id="th2" onclick="changeVal()">2nd Heading</th>
<script>
function changeVal() {
document.getElementById("th2").innerHTML = "3rd Heading";
}
</script>
With jQuery
This section has been updated. I added a data-state attribute the column head, so when you toggle values it will record the last change.
<th id="th2" data-state="2">2nd Heading</th>
Add jquery code like this after linking a jquery file
<script type="javascript" src="path_to_jquery.js" />
<script>
$("#th2").click(function() {
var state = $(this).attr("data-state");
if(state=="2") {
$(this).html("3rd Heading");
$(this).attr("data-state", "3");
} else if(state=="3") {
$(this).html("2nd Heading");
$(this).attr("data-state", "2");
}
});
//you can replace $(this) with $("#th2") or thr id of another element or table cell to manipulate the value inside
</script>
Try it out and give feedback
Add a event listener on each th elements and add change the innerHTML as you want.
The int value is, for now, just based on the th index so it will change only once (index + 1).
We need more informations to change the logic.
var ths = document.getElementsByTagName("th");
var tds = document.getElementsByTagName("td");
for (var i = 0; i < ths.length; i++) {
(function(i) {
ths[i].addEventListener('click', function(e){
changeText(i);
});
}(i));
}
function changeText(index) {
ths[index].innerHTML = "TH" + ( index + 1 );
tds[index].innerHTML = "TD" + ( index + 1 );
}
<table>
<thead>
<th>TH0</th>
<th>TH1</th>
</thead>
<tbody>
<tr>
<td>TD0</td>
<td>TD1</td>
</tr>
</tbody>
</table>
Here is a simple example with jQuery. Maybe it will help you
$(document).ready(function(){
$("table th:nth-child(2)").click(function(){
$(this).text("3rd heading");
$("tr td:nth-child(2)").text("changed");
});
});
table, th, td {
border: 1px solid black;
border-collapse: collapse;
padding: 5px;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<th>1st heading </th> <th>2nd heading</th>
</tr>
<tr>
<td>val1</td><td>val2</td>
</tr>
<tr>
<td>val1</td><td>val2</td>
</tr>
</table>
For the sake of argument (I would never recommend to do it like this - javascript is there for some reason!), here is a solution with pure CSS - though it is a hack using checkbox and label to simulate the CSS click and changing the content that is already hidden in the table - see demo below:
table {
border-collapse: collapse;
}
table td,
table th {
border: 1px solid #ddd;
padding: 10px;
}
.hide{
display: none;
}
#h1:checked ~ table > tbody > tr > td[data-attr='h1'] span.new {
display: block;
}
#h1:checked ~ table > tbody > tr > td[data-attr='h1'] span.new + span{
display: none;
}
#h2:checked ~ table > tbody > tr > td[data-attr='h2'] span.new {
display: block;
}
#h2:checked ~ table > tbody > tr > td[data-attr='h2'] span.new + span {
display: none;
}
<input type="checkbox" id="h1" class="hide"/>
<input type="checkbox" id="h2" class="hide"/>
<table>
<thead>
<tr>
<th>
<label for="h1">Heading 1</label>
</th>
<th>
<label for="h2">Heading 2</label>
</th>
</tr>
</thead>
<tbody>
<tr>
<td data-attr="h1">
<span class="new hide">New Content 1</span>
<span>Content 1</span>
</td>
<td data-attr="h2">
<span class="new hide">New Content 2</span>
<span>Content 2</span>
</td>
</tr>
<tr>
<td data-attr="h1">
<span class="new hide">New Content 1</span>
<span>Content 1</span>
</td>
<td data-attr="h2">
<span class="new hide">New Content 2</span>
<span>Content 2</span>
</td>
</tr>
</tbody>
</table>
I am trying to get a button in the bootstrap popover to change class when I hover over it using jQuery but for some reason, it is not working. I have looked everywhere and I am using the same method as everybody else for hover events in jQuery but, for some reason, it is just not working.
I am trying to change the classes from btn btn-default to btn btn-success on hover. I realize that this could be achieved using CSS(the color change) but this is supposed to work and it is not working and I wanna know why and resolve it.
I am using : Bootstrap 3.3.6, jQuery
The Entire HTML file :
<!DOCTYPE html>
<html>
<head>
<title>Easy ToDo</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<!--<script type="text/javascript" src="https://cdn.jsdelivr.net/bootstrap.native/1.0.2/bootstrap-native.min.js"></script> -->
<script>
function checkTaskStatus(checkbox) {
var tasktext = document.getElementById('tasktext');
var taskrow = document.getElementById('taskrow');
if (checkbox.checked){
taskrow.className = "active";
tasktext.className = "text-muted";
tasktext.style.textDecoration = "line-through";
}
else {
document.getElementById("taskrow").className = "warning";
document.getElementById('tasktext').className = "text-success";
tasktext.style.textDecoration = "none";
}
}
function changeBtn(button) {
var temp = button.className;
if(temp === "btn btn-primary") {
button.className = "btn btn-danger";
button.innerText = "Close";
}
else {
button.className = "btn btn-primary";
button.innerText = "Add New Task";
}
}
</script>
<script>
$(document).ready(function(){
$('[data-toggle="popover"]').popover({
html: true,
title: 'New Task',
trigger: 'click',
content: function () {
return $('.popoverContent').html();
},
placement: 'right'
});
});
</script>
<script>
$(document).ready(function () {
$("#btntask").hover(function () {
$(this).removeClass('btn btn-default');
$(this).addClass('btn btn-success');
}, function () {
$(this).removeClass('btn btn-success');
$(this).addClass('btn btn-default');
});
});
</script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<h1 style="border: 2px solid rebeccapurple; margin-top: 0; background-color: rebeccapurple; color: white; padding-left: 0.6em; padding-bottom: 0.1em; margin-bottom: 1.5em;">An Easy To - Do Web App!</h1>
<button type="button" class="btn btn-primary" style="margin-bottom: 15px; margin-left: 10px;" data-toggle="popover" onclick="changeBtn(this)">Add New Task</button>
<div class="popoverContent hide">
<label for="newTask">Task:</label>
<textarea rows="3" name="newTask" class="form-control input-lg" placeholder="Task HTML"></textarea>
<button class="btn btn-default" type="submit" style="margin-top: 10px;" id="btntask">Done</button>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th style="width: auto"> </th>
<th style="width: auto">#</th>
<th style="width: auto">Date</th>
<th style="width: auto">Task</th>
<th style="width: auto">Notes</th>
</tr>
</thead>
<tbody>
<tr class="warning" id="taskrow">
<td><div class="checkbox"><label><input type="checkbox" onclick="checkTaskStatus(this)"></label></div></td>
<td scope="row" style="font-weight: bold;">1</td>
<td><p style="font-style: italic; font-weight: bold;">7th May, 2016</p></td>
<td class="text-success" id="tasktext" style="text-decoration: none;"><h5 id="task-heading" style="margin-top: 0; text-decoration: underline; font-weight: bold;">Tesla Share Purchase Reasearch:</h5>
<ul>
<li>Find out how an Australian citizen can purchase shares in an American company (e.g. Tesla) which is not listed on the ASX (Australian Stock Exchange)</li>
<li>Prepare a brief list of the steps, costs and general time frame for an Australian to get set up to purchase share in American companies</li>
<li>Please also state the current stock price of Apple, Google (potentially Alphabet as they are the parent??), Facebook, Twitter and Tesla</li>
<li>Bullet points are fine</li>
<li>Please include any relevant links</li>
<li>Spend no longer than 1.5 – 2 hours on this</li>
</ul>
</td>
<td><div class="form-group">
<textarea class="form-control input-md" rows="4" placeholder="Notes"></textarea>
<button class="btn btn-default btn-block" type="submit" style="margin-top: 10px;">Save</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
Note that, I am fairly new to jQuery and JS so if there is any inaccuracies on my part, please point them out.
The issue is when you are trying to add the hover state on the popover , the popover element is not yet available. The element is only added when you click. Hence, the function in $(document).ready() actually adds no hover state.
Instead use jQuery .on
If your hover has not much work to do, you can opt for css hover
#element:hover
{
/*Add your css after hover here*/
}
As pointed out by #Sukhmeet Singh the popover did not appear until on click and not on document.ready.
So I tweaked my script from :
$(document).ready(function () {
$("#btntask").hover(function () {
$(this).removeClass('btn btn-default');
$(this).addClass('btn btn-success');
}, function () {
$(this).removeClass('btn btn-success');
$(this).addClass('btn btn-default');
});
});
To :
$(document).ready(function () {
$('[data-toggle="popover"]').on('click', function () {
$("#btntask").hover(function () {
$(this).removeClass('btn btn-default');
$(this).addClass('btn btn-success');
}, function () {
$(this).removeClass('btn btn-success');
$(this).addClass('btn btn-default');
});
});
});
And it worked. The popover is non-existent in document.ready but appears there when I click on the button with the property [data-toggle="popover"] and thus, when I target the button I want to highlight then, it does it.
I'm using Bootstrap 3.2. I'm trying to figure out if there's a way to show/hide a "col-sz-#" div AND change the "col-sz-#" class in visible divs to resize them to fit the container using checkbox style buttons for each column.
For example, if I start with
<div class="row">
<div class="col-md-2">...</div>
<div class="col-md-2">...</div>
<div class="col-md-2">...</div>
<div class="col-md-2">...</div>
<div class="col-md-2">...</div>
<div class="col-md-2">...</div>
</div>
Then if hide 2 of them and the others resize:
<div class="row">
<div class="col-md-2 hidden">...</div>
<div class="col-md-2 hidden">...</div>
<div class="col-md-3">...</div>
<div class="col-md-3">...</div>
<div class="col-md-3">...</div>
<div class="col-md-3">...</div>
</div>
if the total columns can't divide 12 evenly like 5, then it wouldn't change.
You can do this:
var $myCols = $("#myColumns");
$("#toggleColumns input").change(function() {
var index = +this.value - 1;
var visible = this.checked;
$($myCols.children().get(index)).toggle(visible);
resizeColumns();
});
function resizeColumns() {
var visibleCols = $myCols.children(":visible").length;
var div = Math.floor(12 / visibleCols);
var rem = 12 % visibleCols;
var colSize = (rem === 0) ? div : 2;
$myCols.children().removeClass().addClass('col-md-'+colSize);
}
Demo in jsFiddle
UPDATE:
If you want to act on multiple identical rows, just find all of them with a selector and call a function on each row:
$(".resizeRow").each(function(){
var $eachRow = $(this);
// Do Stuff
});
Updated Fiddle
This is how I solved the issue, I adapted it from https://codepen.io/feger/pen/deIki.
$("input:checkbox:not(:checked)").each(function() {
var column = "table ." + $(this).attr("name");
$(column).hide();
});
$("input:checkbox").click(function(){
var column = "table ." + $(this).attr("name");
$(column).toggle();
});
.clearfix:before,.clearfix:after {
content: " ";display: table; /* 2 */}
.clearfix:after {clear: both;}
.clearfix {*zoom: 1;}
.options {margin-bottom: 8px;}
/* Style checkboxes as Toggle Buttons */
.ck-button {
margin:2px;
background-color:#EFEFEF;
border-radius:4px;
border:1px solid #aaa;
overflow:auto;
float:left;
color:#aaa;
}
.ck-button:hover {
background-color:#ddd;
}
.ck-button label {
float:left;
width:auto;
margin-bottom: 0;
}
.ck-button label span {
text-align:center;
padding:3px 8px;
display:block;
}
.ck-button label input {
position:absolute;
top:-20px;
}
.ck-button input:checked + span {
color:#111;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
</head>
<body>
<div class="options clearfix">
<div class="ck-button">
<label><input type="checkbox" value="1" name="first_name" checked="checked"><span>First Name</span></label>
</div>
<div class="ck-button">
<label><input type="checkbox" value="1" name="last_name" checked="checked"><span>Last Name</span></label>
</div>
<div class="ck-button">
<label><input type="checkbox" value="1" name="email"><span>Email</span></label>
</div>
</div>
<table class="table table-striped table-bordered table-hover table-condensed">
<thead>
<tr>
<th class="first_name">First Name</th>
<th class="last_name">Last Name</th>
<th class="email">Email</th>
</tr>
</thead>
<tbody>
<tr>
<td class="first_name">Larry</td>
<td class="last_name">Hughes</td>
<td class="email">larry#gmail.com</td>
</tr>
<tr>
<td class="first_name">Mike</td>
<td class="last_name">Tyson</td>
<td class="email">mike#gmail.com</td>
</tr>
</tbody>
</table>
</body>
</html>
Check out this fiddle. Here, I used jquery toggle to show/hide the elements. I think, the fiddle will be a good starting point for you. You can also do this with css (without jquery). Then, you have to set
the display: none property.