I'm using the new MVC3 WebGrid. So far so good, just having issues styling/formatting the column headers. The best I've got is a workaround that applies the same css class from the first row of the WebGrid to the table header.
var headerCells = $("#grid tr:eq(0) th");
var firstRowCells = $("#grid tr:eq(1) td");
$.each(firstRowCells, function (index, value) {
$(headerCells[index]).addClass($(firstRowCells[index]).attr("class"));
});
This example obviously lacks a check to make sure there are rows or indeed the specifed element id, but it applies the css class from the first row to the header row meaning you can style independently of each other.
td.my-column-style { width:100px }
th.my-column-style { text-align:right;}
Is there a built in way of styling the column header elements (not just using the headerStyle property)?
No, as of now there is no built-in way to style the header cells independently, only the header row via the headerStyle property.
I think your workaround is good enough.
I know this is an old question, but this may be useful to viewers who stumble across it.
The :nth-child css pseudo selector is your friend, if you don't want to rely on javascript to copy the classes. It is easy to add a class to your webgrid using the tableStyle property, and then you can style the individual headers with the following bit of css:
.webgridclass tr th:nth-child(1){
background:#ff0;
}
.webgridclass tr th:nth-child(2){
background:#f60;
}
Unfortunately, this is not supported in IE8 and earlier IE, but it does have full support in all proper browsers (newer than FF3).
We can do this using of Javascript code as below.
JsFiddle Example
$("table tr th:nth-child(n)").addClass("col-md-1");
Related
I have a quandary that I can't seem to resolve - any pointers would be hugely welcome.
When the tab link is clicked, the new tab opens, but the datatable within tabs 2 & 3 doesn't resize - tab1 is always ok.
I'm using datatables within boostrap tabs and the following code, which I've used on other sites and they work. This site i'm working in however, isn't playing ball - wondering if it's because it's BS5 causing a conflict ??
$('a[data-bs-toggle="tab"]').on("shown.bs.tab", function (e) {
$.fn.dataTable.tables({ visible: true})
.columns.adjust()
.responsive.recalc();
});
I've also tried the code provided by Datatables, and that doesn't seem to work either - in this case. https://datatables.net/examples/api/tabs_and_scrolling.html
The Problem
I think the line
$.fn.dataTable.tables({ visible: true})
is not valid DataTables syntax - and I would expect it to generate an error in your browser's console:
$.fn.dataTable.tables(...).columns is undefined
Suggested Solutions
You can re-write your approach in a couple of different ways (assuming you are using a recent version of DataTables).
The first two examples assume all your tables use a common CSS class name in their HTML <table> tags. In my case, I am using this:
<table id="example2" class="display dataTable cell-border" style="width:100%">
And therefore I will use the .dataTable class selector in the following examples.
Example One
$('button[data-bs-toggle="tab"]').on('shown.bs.tab', function (event) {
$.fn.dataTable.Api('.dataTable')
.columns.adjust()
.responsive.recalc();
} );
Example Two
$('button[data-bs-toggle="tab"]').on('shown.bs.tab', function (event) {
$('.dataTable').DataTable()
.columns.adjust()
.responsive.recalc();
} );
Note that the above example uses DataTable() with a capital "D".
Example Three
The above examples operate on all data tables in the page - it's just that the only one which is affected is the one you see in the selected tab.
If you want to explicitly target only one table in your tab event, you can use the approach shown in this question:
How to make DataTable responsive in Bootstrap tabs
In that answer, the approach retrieves the specific table name from a unique attribute value 'data-bs-target' defined for each tab, for example:
data-bs-target="#home"
See the API reference page for details.
When writing a control, prior to it's rendering you can add css classes to it's html representation's root dom node:
FooLayout.prototype.init = function() {
this.addStyleClass('fooCssClass');
};
This will work assuming writeClasses is executed during rendering:
oRenderManager.writeClasses();
--
There is another RenderManager function writeStyles which can add in-line styles to the html string buffer:
oRenderManager.addStyle("color", "green");
oRenderManager.writeStyles();
But there doesn't seem to be an analogous function to addStyleClass for adding these at the control level to be picked up during rendering.
Is there a way I can hook into writeStyles outside of the renderer?
I have to ask: What styling cannot be applied on control level with a class that can be done with a specific style attribute?
Anyway, the "solution" (which I do not like) would be to add a delegate to the class and do something on onAfterRendering:
oControl.addDelegate({
onAfterRendering: function() {
this.$().css("opacity", "0.5");
}.bind(oControl)
});
Here is an example: http://jsbin.com/seqemaqedo/1/edit?js,output
But as I said, I would advice against it because using a good name for a class uses less code and is much easier to read:
oControl.addStyleClass("semiTransparent");
Update:
After our discussion in the comments, here is an example of how to wrap a control that does not support setting width and height.
You still have to write CSS that references the inner control structure, but in this case it is very unlikely that it will change:
http://jsbin.com/lohocaqixi/3/edit?html,js,output
I have a page with Indexing enabled (and theme Apaxy)
I've search a lot trying to figure out of how could I change default language (or simply change STRING values).
I have this:
Is that possible to change this text values?
Thanks
Foud a way using jQuery .replace:
$(document).ready(function(){
$('body table tbody tr th a').each(function(i){ // THE OBJECT WHERE IS THE REPLACEING TEXT
$(this).html($(this).html().replace('Name','LOREN IPSUN'));
$(this).html($(this).html().replace('Last modified','LOREN IPSUN'));
$(this).html($(this).html().replace('Size','LOREN IPSUN'));
$(this).html($(this).html().replace('Description','LOREN IPSUN'));
});
});
Just change loren ipsun for whatever you want.
I have two divs nested under a parent div and I want all these to be source as well as targets for dojo.dnd.
I want to be able to add nodes to the div over which the content was dropped and also allow the user to move this in between the 3 divs.
Something like this -
http://www.upscale.utoronto.ca/test/dojo/tests/dnd/test_nested_drop_targets.html
This is I gues implemented in older version of Dojo and doesn' seem to work with 1.4
Is the support for nested targets removed? Is there any way to achieve this?
Nested sources/targets are not supported currently. In most cases you can work around this restriction by using independent sources/targets, yet positioning them as you wish with CSS.
I used a workaround for this case. I create another DIV element which positioned at the same place of the nested target with same width and height but with higher z-Index value. Then the new DIV element covers the nested target. When user is trying to drop on the nested target, he actually drops to the above new DIV element. As long as the new DIV element is not nested in the parent drop target, Dojo's dnd operation works well. I usually put the new DIV element as a child of the body element.
What you need to do is to create the new DIV in onDndStart and destroy it in onDndCancel, then everything should work well.
Dojo version 1.10 still does not support nested Dnd.
CSS positioning and overlay div's didn't work for me. But I noticed that dragging an element out of a dndContainer into a parent dndContainer doesn't trigger onMouseOverEvent for the parent.
In case someone is still using dojo and has the same problem, here is my approach to solve this:
Declare your own dndSource e.g. nestedDndSource.js
define([
"dojo/_base/declare",
"dojo/dnd/Source",
"dojo/dnd/Manager"
], function(declare,dndSource, Manager){
var Source = declare("dojo.dnd.Source", dndSource, {
parentSource: null,
onOutEvent: function(){
if(this.parentSource != undefined)
Manager.manager().overSource(this.parentSource)
Source.superclass.onOutEvent.call(this);
}
});
return Source;
})
Use that nestedDndSource for the children instead of dojos and make sure to provide the dndSource of the parent as parentSource-Parameter:
var parentDndSource = new dojoDndSource(parentNode, {..});
var childDnDSource = new nestedDndSource(childNode,{
parentSource: parentDndSource,
onDropExternal: ...
});
Working example: https://jsfiddle.net/teano87/s4pe2jjz/1/
I'm just getting started with dojo, and I've understood that dojo.query is the same as $ in jQuery.
But I haven't figured out what it returns. Is it a specialized object like in jQuery?
What I'm trying to do (with no luck) is:
dojo.query("output").innerHTML = data;
//this doesn't work either:
dojo.query("output").html(data);
//tried accessing by id as well
dojo.query("#output").html(data);
//and tried to access a div, incase dojo has some issues with html5 elements
dojo.query("#divOutput").html(data);
And I'm currently using the new html5 elements:
<output id="output">Output goes here</output>
<div id="divOutput">non-html5 output goes here</div>
And I can't seem to find a good list on what to do with objects returned by dojo.query()..
edit: Okay, I think dojo is just messing with me now. I found this method: addContent() and that works on the above selector. But I don't want to add content, I want to replace content...
The query method returns a NodeList object.
In the ref for NodeList you can find a list of functions that you can apply to the list
of elements. There is no innerHTML function for the list, but the html function should work.
There is no "output" element in HTML, perhaps you try to target elements with the class name "output"?
dojo.query(".output").html(data)
Or the element with id "output"?
dojo.query("#output").html(data)
If you want to replace all the output tags' content with the same thing, then this code should always work:
// replace the contents of ALL <output> tags
dojo.query('output').forEach(function(node) { node.innerHTML = data; });
Dojo also provides a little shortcut for these kinds of things. You can specify a string to NodeList's forEach function like this:
// replace the contents of ALL <output> tags (as long as data is global)
dojo.query('output').forEach("item.innerHTML = data;");
The word item in the string is special. (This is a pain to debug, so it might not be worth it.)
As was said above, query method returns NodeList object, so you can iterate it's result as array, or use dojo methods that work with NodeList (e.g. attr):
dojo.query("#divOutput").attr("innerHTML", data);
But as soon as you are trying to query nodes by id, it would be better to use dojo.byId() method, which returns domNode:
dojo.byId("divOutput").innerHTML = data;
Or in more dojo style:
dojo.attr(dojo.byId("divOutput"), "innerHTML", data)
Try this by adding the [0] like this:
dojo.query("output")[0].innerHTML = data;
Also, there is a dojox.jq wrapper (in development, coming in 1.4) which emulates the JQuery return object APIs
The documentation seems to be a mess, this is the only thing i get to work with 1.7,
dojo.query("whatever").forEach(function(node, index, array)
{
node...
});