Show or Hide MVC WebGrid Column with Jquery - javascript

I have a MVC Webgrid with columns that I want to Hide or Show dynamically based on a javascript function after the grid is rendered.
So after the WebGrid is displayed I want to call a javascript function and pass in a ColumnName to Show or hide. Is this possible?
Thanks,
This is how my grid is setup:
#{
var gridColumns = new List<WebGridColumn>();
gridColumns.Add(grid.Column("Id", "Test ID"));
gridColumns.Add(grid.Column("Description", "Test Description"));
gridColumns.Add(grid.Column("ProjectDate", "Test Date", format: #<text> <span>#item.ProjectDate.ToString("d/M/yyyy")</span></text>));
}
<div id="divWebGrid" class="row">
#grid.GetHtml(
fillEmptyRows: false,
tableStyle: "webgrid",
alternatingRowStyle: "webgrid-alternating-row",
headerStyle: "webgrid-header",
footerStyle: "webgrid-footer",
selectedRowStyle: "webgrid-selected-row",
rowStyle: "webgrid-row-style",
mode: WebGridPagerModes.All,
columns: grid.Columns(gridColumns.ToArray())
)
</div>
And this would be my Javascript code:
function ToggleColumn(columnName)
{
//Some Code to Show or Hide the Column in the WebGrid based on the columnName parameter.
}
Is this possible?
Here is the rendered code of my grid:
<table class="webgrid" data-swhgajax="true" data-swhgcontainer="divWebGrid" data-swhgcallback="">
<thead>
<tr class="webgrid-header">
<th scope="col">
<a data-swhglnk="true" href="/Home/Index?gridItemsort=Id&gridItemsortdir=ASC">Test ID</a> </th>
<th scope="col">
<a data-swhglnk="true" href="/Home/Index?gridItemsort=Description&gridItemsortdir=ASC">Test Description</a> </th>
<th scope="col">
<a data-swhglnk="true" href="/Home/Index?gridItemsort=ProjectDate&gridItemsortdir=ASC">Test Date</a> </th>
</tr>
</thead>
<tfoot>
<tr class="webgrid-footer">
<td colspan="3">1 <a data-swhglnk="true" href="/Home/Index?gridItempage=2">2</a> <a data-swhglnk="true" href="/Home/Index?gridItempage=3">3</a> <a data-swhglnk="true" href="/Home/Index?gridItempage=2">></a> <a data-swhglnk="true" href="/Home/Index?gridItempage=3">>></a></td>
</tr>
</tfoot>
<tbody>
<tr class="webgrid-row-style">
<td>1</td>
<td>test 1</td>
<td> <span>22/7/2016</span></td>
</tr>
<tr class="webgrid-alternating-row">
<td>2</td>
<td>test 2</td>
<td> <span>22/7/2016</span></td>
</tr>
<tr class="webgrid-row-style">
<td>3</td>
<td>test 3</td>
<td> <span>22/7/2016</span></td>
</tr>
</tbody>
</table>

I faced the similar problem in my Grid. And I solved it with the help of css class added on WebGrid columns.
First, I add a class to all those columns which needs to be hidden.
gridColumns.Add(grid.Column("ID", "Test ID", null, "hidden-column"));
Added hide property on class 'hidden-column'
<style>
.hidden-column {
display:none;
}
</style>
It will hide all the columns (td elements) having this class set (in this case, it will hide "ID" column).
To hide Grid headers as well, I called IIFE function on document ready.
(function () {
$('#divWebGrid tbody tr:first').find('td.hidden-column').each(function (i, td) {
var indexOfHiddenColumn = $(td).index();
$('#divWebGrid thead th').eq(indexOfHiddenColumn).addClass('hidden-column');
});
}());
Hope this post will help you to resolve your issue.

Related

footable js removes all form elements in the table

I have implemented a responsive table with the help of footable jquery library. Now i have placed input tags, select box in it. Footable js removes all these tags and make it an empty <td>.
<table id="accordion-example-1" class="table" data-paging="true" data-filtering="false" data-sorting="false">
<thead>
<tr>
<th></th>
<th data-breakpoints="xs">Date Created</th>
<th>Source</th>
<th>Type</th>
<th data-breakpoints="xs">Status</th>
<th data-breakpoints="xs sm"> </th>
<th data-breakpoints="xs sm md" > </th>
<th data-breakpoints="xs sm md"> </th>
</tr>
</thead>
<tbody>
<tr data-expanded="true">
<td></td>
<td>6/11/16</td>
<td>Mr. Cooper - Request Info</td>
<td>Buying</td>
<td>
<select class="nobrdr">
<option>Offer</option>
</select>
</td>
<td><input type="text" class="nobrdr" placeholder="Value"/></td>
<td><input type="text" class="nobrdr" placeholder="Date" /></td>
<td><button class="nobrdr m-l-1" type="button" ><b>+ Add</b></button><br>Forms/Docs</td>
</tr>
</tbody>
</table>
jquery function :
$(function($){
$('#accordion-example-1,#accordion-example-2').footable({
});
});
You need to change the data type of the column(s) where the form elements are to "html", otherwise FooTable assumes the column contains only text and formats it as such - i.e. it will strip out all HTML markup from the cell contents, and not just form elements.
For example in your case:
<th data-type="html" data-breakpoints="xs">Status</th>
will tell it to respect HTML markup within any cells in the Status column.
The possible column types supported are "text", "number", "html" and "date". "text" is the default if no type is specified.
For more detailed discussion I suggest you read the guide at http://fooplugins.github.io/FooTable/docs/getting-started.html and find the "Column options" section.

Angular table loading spinner on table columns visibility change

I have quite big table with many columns. Many columns have attribute "ng-show". Also i have created a functionality which hides or displays some table columns (with "ng-show").
When i trying to apply table columns visibility change ir takes 2-3 seconds for angular to update the table. Is it possible to add loading spinner on the table while it happens?
Simplified table structure:
<table class="classesList" id="tableId">
<thead>
<tr>
<th ng-show="tableColumns[0].show" >
<span>Header1</span>
</th>
<th ng-show="tableColumns[1].show" >
<span>Header1</span>
</th>
<th ng-show="tableColumns[2].show" >
<span>Header1</span>
</th>
...
</tr>
</thead>
<tbody>
<tr ng-repeat="row in rows">
<td ng-show="tableColumns[0].show">
<span>Data1</span>
</td>
<td ng-show="tableColumns[1].show">
<span>Data2</span>
</td>
<td ng-show="tableColumns[2].show">
<span>Data3</span>
</td>
...
</tr>
</tbody>

How do you sort for row details in HTML?

I am using sorttable to sort my columns in table.
Now I have a table as follows:
<table class="sortable draggable">
<thead>
<tr>
<th class="col-salesOrderId">Order Number</th>
<th class="col-orderDate">Date of Order</th>
<th class="col-party">Party</th>
<th class="col-edit">Edit</th>
<th class="col-delete">Delete</th>
</tr>
</thead>
<tbody>
{#orders}
<tr>
<td class="col-salesOrderId">{.salesOrderId}</td>
<td class="col-orderDate">{#formatDate date=orderDate format="DD-MM-YYYY" /}</td>
<td class="col-party">{.party.partyName}</td>
<td class="col-edit">
<button class="btn btn-info btn-edit">
</button>
</td>
<td class="col-delete">
<button class="btn btn-danger btn-delete">
</button>
</td>
</tr>
<tr class="row-details">
<td>{.salesOrderId}</td>
<td colspan="4">
<table class="sortable draggable">
<thead>
<tr>
<th class="col-itemName">Item Name</th>
<th class="col-quantity">Quantity</th>
<th class="col-rate">Rate</th>
<th class="col-amount">Amount</th>
</tr>
</thead>
<tbody>
{#items}
<tr>
<td>{.item.itemName}</td>
<td>{.quantity}</td>
<td>{.rate}</td>
<td>{#math key="{.quantity}" method="multiply" operand="{.rate}"/}</td>
</tr>
{/items}
</tbody>
</table>
</td>
</tr>
{/orders}
</tbody>
</table>
Have you noted in the above mentioned table I have row details for each row?
Now when I click on a column header to sort it, I get the row details first and then I get all the main rows.
Here is how my table looks before sorting:
Here is how my table looks after sorting:
Is there any solution to this problem still using sorttable?
Update:
Here is sample jsFiddle
Row details are now sorted correctly as shown in the above jsFiddle. But now the problem is :
When you click on City column everything looks fine. Now if we again click on City Column, the row details are displayed before the actual rows which is wrong.
Please look at the images below for more information on problem:
After Clicking on City Column: (Which looks perfect)
After Clicking on City Column Again: (Expected for a developer but unexpected for a user)
I'am guessing but maybe the problem is the empty td beside the row details. I added first name as value and set css style display:none. Now the row details will be sorted also correctly.
Updated answer:
try to just nest the table inside the td like the below example.
Try this:
<table class="sortable">
<thead>
<tr>
<th>First Name</th>
<th>LastName</th>
</tr>
</thead>
<tbody>
<tr>
<td>Vishal</td>
<td> Sherathiya
<table>
<thead>
<tr>
<th>Degree</th>
<th>Percentage</th>
</tr>
</thead>
<tbody>
<tr>
<td>B.E.</td>
<td>67</td>
</tr>
</tbody>
</table>
<td>
</tr>
<tr>
<td>Nikunj</td>
<td>Ramani
<table>
<thead>
<tr>
<th>Degree</th>
<th>Percentage</th>
</tr>
</thead>
<tbody>
<tr>
<td>B.E.</td>
<td>80</td>
</tr>
<tr>
<td>M.E.</td>
<td>54</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td>Raj</td>
<td>Gosai</td>
</tr>
</tbody>
</table>

Hierarchical Grid in Angularjs

I want to make a hierarchical data table with angularjs.
For example, it can lower the table and took a table in the first row of the table.
How can I create nested tables this event ?
I wrote how I wanted to do something as an example below.
Please hepl me! Thank you.
Example:
<table>
<thead>
<tr>
<th>Head 1</th>
</tr>
</thead>
<tbody>
<tr>
<td>Content 1</td>
</tr>
<tr>
<td style="margin-left: 10px">
<table>
<thead>
<tr>
<th>Head 1.1</th>
</tr>
</thead>
<tbody>
<tr>
<td>Content 1.1</td>
</tr>
<table>
<thead>
<tr>
<th></th>
</thead>
<tbody>
<tr>
<td>Content 1.1.1</td>
</tr>
</tbody>
</table>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
First of all - Table in Tables is valid html (see: Is a html table within a table valid?)
Second of all - What is the real question here? You need a controller storing the data you want to display. You can iterate with ng-repeat to get the structure.
It looks like you want to display a Table of Contents. A list is a better option here:
HTML:
<div ng-controller="TableController">
<ul>
<li ng-repeat="c in content">
{{c.header}}
<ul>
<li ng-repeat="cc in c.content">{{cc}}</li>
</ul>
</li>
</ul>
</div>
Controller:
var app = angular.module("tableApp", []);
app.controller("TableController", ["$scope",function($scope){
$scope.content = [
{ header: "Head 1", content: ["Content 1"]},
{ header: "Head 1.1", content: ["Content 1.1", "Content 1.1.1"]}
];
}]);
// See: https://jsfiddle.net/6se8xq41/
see example here

change the class of a specific tag

I am trying to put together a page which contains several tables with data. Since the page can become long I want the user to be able to collapse the tables by clicking the header. I plan to use a + icon to indicate that there is more content available and - icon to show that it is collapsible. So I need to switch the class name of the i tag which is the icon. Like I said the page can contain several tables with identical i tags tags so I need something to cover that
Here is example HTML.
<table class="table table-bordered">
<thead class="heading" id="thead">
<tr id="tr">
<th id="th" colspan="3"><i class="icon-plus"></i> Basic info</th>
</tr>
</thead>
<tbody class="content">
<tr>
<td>Registration</td>
<td>ABC 123</td>
<td> </td>
</tr>
</tbody>
</table>
<table class="table table-bordered">
<thead class="heading" id="thead">
<tr id="tr">
<th id="th" colspan="3"><i class="icon-plus"></i> More info</th>
</tr>
</thead>
<tbody class="content">
<tr>
<td>Start time</td>
<td>11:57</td>
<td> </td>
</tr>
</tbody>
</table>
and here is the script
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('.content').show();
jQuery('.heading').click(function()
{
jQuery(this).next('.content').slideToggle('0');
jQuery(this).parent().next("i").removeClass('icon-plus').addClass('icon-minus');
});
});
</script>
the showing and hiding of the tbody works fine but I cant get the icon to change, any clues?
Try changing
jQuery(this).parent().next("i").removeClass('icon-plus').addClass('icon-minus');
to
jQuery(this).find('i').toggleClass('icon-plus icon-minus');
ok first of all never give multiple elements the same ID in a page... ever. Very bad practice and will cause complications when needing to refer to one specific element.
As for the jquery, use addClass and removeClass:
jquery('.headingClass').removeClass('.headingclass');
jquery(this + 'i').addClass('.headingclass');
Like this:
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('.content').show();
jQuery('.heading').click(function()
{
jquery('.headingClass').removeClass('.headingclass');
jquery(this + 'i').addClass('.headingclass');
jQuery(this).next('.content').slideToggle('0');
jQuery(this).parent().next("i").removeClass('icon-plus').addClass('icon-minus');
});
});
</script>
Instead of jQuery(this).parent().next("i"), use jQuery(this).find("i")
In your sample, jQuery(this) is the thead element; the i element you want to reference is a descendant, not a sibling, so .parent().next("i") tries to match an element at the same level as your thead and tbody elements!
try this ( without icon of + and - )
note : i have changed the markup a bit.
CSS
i { padding:4px; cursor:pointer; }
.icon-minus { color :red; }
.icon-minus:before { content:"-";}
.icon-plus { color :green }
.icon-plus:before { content:"+";}
HTML
<table class="table table-bordered">
<thead class="heading" >
<tr >
<th colspan="3" ><i class="icon-minus"></i>Basic info</th>
</tr>
</thead>
<tbody class="content">
<tr>
<td>Registration</td>
<td>ABC 123</td>
<td> </td>
</tr>
</tbody>
</table>
<table class="table table-bordered">
<thead class="heading" >
<tr >
<th colspan="3"> <i class="icon-minus"></i>More info</th>
</tr>
</thead>
<tbody class="content">
<tr>
<td>Start time</td>
<td>11:57</td>
<td> </td>
</tr>
</tbody>
</table>
​jQuery
jQuery('.heading').bind('click',function(){
jQuery(this).siblings('tbody').slideToggle('0');
jQuery(this).find('i').toggleClass('icon-minus icon-plus');
});
​
DEMO

Categories

Resources