I have two questions.
I am trying to create a google charts table.
A) I need the ID of the actual table element being created so I can make some modifications. So, how can I set/get the table ID?
B) How can I add custom CSS class to the table tag? I basically want to add css from material-design-lite to these tables.
Thank You so much!
First, you can assign cssClassNames to specific areas of the chart, using the Configuration Options.
Such as...
headerRow - Assigns a class name to the table header row ( element).
tableRow - Assigns a class name to the non-header rows ( elements).
...
If that doesn't help, you can modify the dom as needed, once the chart is ready.
You have to specify a container id to draw the chart originally, usually a div.
So you don't need the id of the google table to modify it. Just browse the contents of the container you defined using JavaScript to find what you need.
For instance, there is a known problem with locking the first column heading row when scrolling in certain browsers. Following is the function I use to fix that, I'm cheating a little, using MicrosoftAjax.js to getBounds.
_googleChartFixScroll: function(sender, args) {
var googleBounds;
var googleDivs;
var googleRows;
googleDivs = this._containerChart.getElementsByTagName('DIV');
if (googleDivs.length === 3) {
googleRows = this._containerChart.getElementsByTagName('TR');
if (googleRows.length > 0) {
googleBounds = Sys.UI.DomElement.getBounds(googleRows[0]);
googleDivs[2].style.height = googleBounds.height + 'px';
}
}
},
The point is, within the div you define for the chart, you can manipulte the google chart, if you just know how to explore the dom. Once you find the element you need, you can apply what ever style you want...
In my example, whenever the table has too many rows and the column header needs to be locked, there are three div's instead of two. As such, I find the first table row and lock it.
Hope this helps...
Related
I'm trying to create Table Rows in a Table that can expand by clicking on them (individually).
For example, if I would click on the specified area in the picture below, a Segment/Container (some sort of area) would drop down with content inside.
I've tried a solution that is mentioned in this thread, but the underlying problem is that every element under a Table Row/Cell is subject to the rules and boundaries of the Table HeaderCell. So if I for example try to create a Table Row with a Segment under it, the result will look like this:
As you can see the Segment is inside the new Row but is limited to the size of the HeaderCell.
When doing this I also get this error:
validateDOMNesting(...): <div> cannot appear as a child of <tr>.
in div (created by Segment)
It seems that Segment under Table Row is therefore a prohibited element structure.
Any idea on how the element structure should look to create some kind of area under a Table Row?
The the warning of a <div> not being allowed as a child of a table row is telling you that it is not valid HTML. That is true whether you are using Semantic UI React or plain HTML.
I'd recommend rendering another row below the row you have in your table already. Set a column inside of that row which spans all of the columns. Now you have a container which you can put other UI inside if you want to. You can customize the style of the wide cell if you need to for some reason.
Then you can set a toggle state on the clickable area of your table. You'll probably want to put the click events on the contents of the cells and not the cells themselves.
I threw together a quick Codepen showing how this would work. This gives you a working concept that you can modify based on your use case.
https://codesandbox.io/s/serene-water-ikco9?file=/example.js
I'm using ant design in my project. There I'm using DataTable.
It has row expand feature.
Problem
When user expand the child row, the parent row background color needs to be changed or else needs to add css class for that row.
Fiddle Here
I have created function onExpand of the table.
onExpand = (expanded, record) => {
alert(expanded);
console.log('onExpand', expanded, record); }
TIA
You have to use the onRow property to add a custom css class for each expanded row. First of all you need distinguish the expanded rows from the collapsed one. Therefore you have to store the keys of the expanded rows in the state to assign the css class to the right rows. For that purpose you have to use expandedRowKeys and onExpand properties too.
You can check the working example overhere:
https://codesandbox.io/s/2xyy8mqwoj
This question already has answers here:
Get element with a randomized class name
(2 answers)
Closed 4 years ago.
In an attempt to make web scraping with a headless browser more resilient to site changes, I'd like to combine technical properties of the elements with their visual characteristics.
E.g. when looking for a search bar, I'd like to look for a "big (>50% width), visible (:visible) text input field (<input type="text">) in the upper half of the screen/rendered page." Then, when looking for the submit button, I'd like to find a button located near the aforementioned search bar.
Is there any way to set up this kind of search criterion?
AFAICS, CSS selectors and XPath can only search by predefined parameters (tag, id, class, attributes), not by calculated ones.
The best idea I currently have is to search by predefined parameters, then filter the result further by getting size, position and such for each result and comparing them to the desired ranges. This is rather slow oftentimes since I have to use expressions like *[text()="visible text"] to not rely on technical details that are subject to change without notice.
Here are a few examples of ways to find your wanted element. All below examples are based on the assumption that you have an element that looks a little like this (can be different type and css elsewhere, but basically that you have an element somewhere with some styling and some attribute).
<div mycustomattribute="login" style="width:calc(5cm - 3cm)"></div>
Note that the below examples aren't necessarily all I the ways I can give you, it's just the ones I could think of on the fly, if your problem isn't resolved using these I can probably think of one or two more ways to solve your problem.
Selecting using a custom attribute
You can set any attribute you want on any element you want. For example, if you want <div mycustomattribute="hello"> and then querySelect that, it's totally valid.
var test = document.querySelect("div[mycustomattribute=login]")
The above script will select only the div that has an attribute name with the value login. I think you already know of this method but figured I'd mention it because it's by far the easiest, least hacky way of finding a specific element, if you can set an attribute on your element that is.
Select using position
Lets say you want to select the nearest element that is 50 px to the right of the element you selected.
var base = document.querySelect("div[name=login]")
// Get Y coordinate of base element
var y = base.getBoundingClientRect().top;
// Get X coordinate of base element on its right side, since we're gonna look to the right of it
var x = base.getBoundingClientRect().right;
// Find the element that is 50 pixels to the right of our base element
var element = document.elementFromPoint(x + 50, y);
Select using CSS values
This is more tricky but certainly possible. You are correct in that you can't just run querySelector to find an element based on a CSS value (calculated or otherwise), but you can run the calculation yourself to get the value your desired element should have and then just loop through them to get the one you want.
So, for example:
var divs = document.querySelectorAll('div');
var element = null;
for (i = 0; i < divs.length; ++i) {
/* We assume you know the result of the calculated value, either because it's
a static result (e.g. `5cm - 3cm`), or because you rerun the calculation in
javascript to find out what its result is.
Note that you can use whatever style you want here to find the div, like
"visible" or "display" or whatever you want, just set up the proper if
statements.
*/
if(div.style.width = "2cm") {
element = div;
break;
}
}
References
This is a little side note but try to use mozilla instead of w3schools, mozilla is way better for references. I was hesitant too at first to make the jump to mozillas documentation but it really is way better once you learn how to use it.
https://developer.mozilla.org/en-US/docs/Web/API/Document
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
https://developer.mozilla.org/en-US/docs/Web/API/Document/elementFromPoint
https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/
In one of my pages, I am using an example of editable html table from this link: http://mrbool.com/how-to-create-an-editable-html-table-with-jquery/27425, which works without any issues and when I click on a cell in the table, it changes it to text box.
However, I had to change the layout of my page where, I had to place the sample mentioned above within another html table (nested).
Now the problem is when I click on the cell, it does not identify the child table, which has the data and I want to click but it clicks on the cell of the parent table, which in this case is the parent table, and holds 2 different tables.
So, what I want you help with is:
Get a method to identify the cell of the child table when it is clicked
Or
Some way so align two tables on my page to be aligned side by side. Currently I am using the parent table to align my other 2 tables to sit side by side.
if the second option is easier to achieve then, I don't have to change much.
Any suggestions?
If you're using a parent table element to layout elements on your page, just know that this is a deprecated unsemantic practice, as table elements are for tabulating data. You should use the CSS float property, which is the convention, see CSS Floats 101 ยท An A List Apart Article and w3schools.com
Refactoring out that parent table should fix your problem. Otherwise you can fix it through modifying the selector in your JavaScript and by assigning the edittable td elements with a class (eg. edittable-cell) so you're not assigning event listeners to other tables' td elements unnecessarily and causing unwanted behaviour elsewhere.
JavaScript
// Instead of the 'td' selector
$("td").dblclick(function() {
// .. your code here
});
// Use a more specific selector, eg.:
$('.edittable-cell').dblclick(function() {
// .. your code here
});
If you are semantically nesting tables of data and/or still have this issue, you can try preventing the event from bubbling up to its parent elements.
JavaScript
$(".edittable-cell").dblclick(function(event) {
event.stopPropagation();
// .. your code here
});
I have an AdvancedDataGrid with editable set true on some columns. If i edit one of the values in the ADG, the row moves to the bottom of the node/branch containing the items im currently editing.
My AdvancedDataGrid is defined in ActionScript3, and i use a grouping collection to group a flat dataProvider.
My problem is that i often want to edit several cells of one row, and if i edit one of the cells and then click somewhere else, the row moves to the bottom of the ADG. How can i avoid this? I want the row to stay selected and at the same index.
I guess i was a bit to quick to post this question, but maybe my mistake helps someone else. At the time of creating the editing, i didnt know about the itemUpdate(object) method of the ArrayCollection, so i removed the item, updated the item and then added it to the same index again(code below):
ac.removeItemAt(i);
ac.addItemAt(event.itemRenderer.data, i);
This does not work together with the hierarchical data in the AdvancedDataGrid. Insead of beeing inserted back in the right index it is displayed at the bottom of the current branch in the ADG. The solution was very simple by using the following code, which works with the GroupingCollection:
var field:String = event.dataField;
var obj:Object = event.itemRenderer.data;
//Update the field that was edited by the user
obj[field] = editedValue;
//update the object in the dataProvider
ressursTavle.itemUpdated(obj);