IE7 glitches with building tables cells dynamically - javascript

I am working on jQuery plugin.
It building tables dynamically.
// ... ...
var currentTBL = document.createElement('table');
$(currentTBL).attr('width', _width).attr('height', _height);
var currZoneIndex = 0;
for (var y = 0; y < limitRow; y++) {
var currentTR = document.createElement('tr');
var currentWidth = 0;
for (var x = 0; x < limitCol; x++) {
if (!opts.matrix[y * limitCol + x]) continue;
var currZone = opts.zones[currZoneIndex];
var cellSizes = getSizes(opts.zones[currZoneIndex]);
currentTD = document.createElement('td');
$(currentTD)
.attr('colspan', currZone.colspan)
.attr('rowspan', currZone.rowspan)
.attr('width', cellSizes.x)
.attr('height', cellSizes.y);
$(currentTR).append(currentTD);
currZoneIndex++;
}
$(currentTBL).append(currentTR);
}
// ... ...
This part of code gives me a table object and It's HTML is:
<TABLE width=470 height=150>
<TR valign="top">
<TD height=48 width=107 colspan="1"></TD>
<TD height=48 width=255 colspan="1"></TD>
<TD height=48 width=108 colspan="1"></TD>
</TR>
<TR valign="top">
<TD height=61 width=362 colspan="2"></TD>
<TD height=61 width=108 colspan="1"></TD>
</TR>
<TR valign="top">
<TD height=41 width=107 colspan="1"></TD>
<TD height=41 width=255 colspan="1"></TD>
<TD height=41 width=108 colspan="1"></TD>
</TR>
</TABLE>
It looks normally with FF, Opera, Safari,..:
IE7 || IE6 showing something like this:
(source: rayz.ru)
I have a solution which re-paste table on the same place. But it breaks all kind of event handlers on my table.
Please help me with solution.
Simplified plugin demo:
http://rayz.ru/stackoverflow/test/

The HTML you say the JQuery is rendering is valid and does render correctly in IE6/7/8. So my bet is that the JQuery code is producing something other than the HTML you have listed and the most likely candidate would be this line in the code you have provided:
var currZone = opts.zones[currZoneIndex];
I'd go back and look at how you defined this object opt.zones. I understand that it apparently renders OK in other browsers but my primary point is that, in IE, so does the HTML you listed...so thats not the problem. What does your HTML actually look like?

First things first: please make sure your plugin generates valid HTML - make sure all the elements are in lowercase and that all your elements' attributes are enclosed in double quote marks.
I'd suggest that for ensuring the widths, heights and other stylistic elements, you use a stylesheet as part of your plugin. That will make it simpler to control the appearance of your table overall.
For defining column (cell) widths, try creating a <colgroup> element that can be inserted right after your <table> element.
<table>
<colgroup>
<col style="width: 107px;" />
<col style="width: 255px;" />
<col style="width: 108px;" />
</colgroup>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td colspan="2"></td>
<td></td>
</tr>
...
</table>
That will clean things up a bit and make it easier to identify what IE is misinterpreting.

Firstly don't do this in IE6 - your code will be prone to a nasty issue in IE6 called the DOM insertion order bug: http://msdn.microsoft.com/en-us/library/bb250448(VS.85).aspx.
Basically in IE6 you can't build up your table and then add it to the page (like any good developer would - why fire extra page layouts?) you have to add the table to the page, then add a row, then add a cell - all top down and forcing a layout each time. Nasty.
Your HTML looks like it would render correctly in IE7, so I'd look at the javascript - are you sure that it's producing that HTML in all browsers? For instance document.createElement('td') shouldn't create <TD> tags with unquoted attributes.
So either in IE7 (with a plugin) or IE8 (which finally has developer tools) I'd investigate the DOM actually produced.

At least IE6 is very bad with empty cells. Adding an to each cell helps.

Solution is setting rowspan and colspan attributes of TD elements directly in javascript object properties, not with .attr method of jQuery.
That's wrong:
$(currentTD)
.attr('colspan', currZone.colspan)
.attr('rowspan', currZone.rowspan);
That's correct:
currentTD.colSpan = currZone.colspan;
currentTD.rowSpan = currZone.rowspan;

Related

Cypress jQuery selector bar:contains('foo') doesn't work

I tryıng to use jQuery selectors but it doesn't work. I use Cypress so sometimes I need to use jQuery selectors to find elements by text or some unique generated numbers. (instead of cy.contains() i.e. sometimes I can need to brake recursions etc.)
Can anyone help me please?
I tried so many selectors, one of those selectors is:
$(tbody:has(tr.dx-row.dx-data-row.dx-row-lines.dx-row-focused.dx-cell-focus-disabled) tr td:contains(`10304`))
the queries that I showed normally work well. But that question that I asked doesn't work suspiciously. I thought about maybe the console doesn't support queries but when I use :has command console shows me without a problem then why :contains doesn't work? Why I can't select elements with text that I asked as a question?
I think your selectors are very complicated, try to simplify them by maybe just select the <td>, that contains that text like in my example below.
For demonstration purposes, i show just the cell text (.text()) - but it can be whatever you want.
$(document).ready(() => {
const $table = $('table');
console.log($table.find('td:contains(10304)').text());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>1</th>
<th>2</th>
<th>3</th>
</tr>
</thead>
<tbody>
<tr class="dx-row dx-data-row dx-row-lines andsoon">
<td class="dx-command-select">UNASSIGNED</td>
<td class="dx-col-1">10304</td>
<td class="dx-col-2">YAYDIN</td>
</tr>
</tbody>
</table>

.each() function on affect current object

having some issues with my code below, first here is the HTML:
<table class="finance-table">
<tbody><tr>
<th></th>
<th>Deposit</th>
<th>Balance</th>
<th>Fees</th>
<th>Total Payable</th>
<th>Term</th>
<th>Fixed Rate</th>
<th>Representative APR</th>
<th>Monthly Pmt</th>
</tr>
<tr class="hp">
<td><strong>HP</strong></td>
<td id="td_finance_deposit">£11700.00</td>
<td id="td_finance_balance">£105300.00</td>
<td id="td_finance_fees">£298.00</td>
<td id="td_finance_total_inc_deposit">£146255.50</td>
<td id="td_finance_term">60 mths</td>
<td id="td_finance_rate">5.50%</td>
<td id="td_finance_apr">10.1%</td>
<td id="td_finance_monthly_payments">£2242.59 p/m* x 60 mths</td>
</tr>
</tbody></table>
There is about 10 of these tables [within the same document], all with the same id's and class's. I'm using an each loop to execute some code against each table found, however it only seems to be working on the first table and disregards the others.
Below is the jQuery, like I said works find on the first table, but ignores the rest!
<!-- Remove First and Final Payment from Showroom Finance Examples -->
<script>
$(".finance-table").each(function(key, value) {
// Display loading
var html = $(this);
// Remove the First Payment and Final Payment Column
$(this).find("#td_finance_first_payment, #td_finance_final_payment").remove();
$(this).find("th:contains('1st Pmt')").remove(); $(this).find("th:contains('Final Pmt')").remove();
// Get the Term and update the monthly payment
var term = $(this).find("#td_finance_term").html(); // .replace(/\D/g,'')
var payments = ($(this).find("#td_finance_monthly_payments").html()).split('x')[0];
($(this).find("#td_finance_monthly_payments")).html(payments + " x " + term);
})
</script>
Edit:
Please note, I can't change the HTML at all
You should first give a unique ID to each <td>, perhaps with your DB identifier for that record. You don't need it now but this will allow you to do other thing later if you need it.
Then change all the <td> ids to classes:
<td class="td_finance_fees">£298.00</td>
Finally change all your javascript accordingly to use class instead of IDs:
$(this).find(".td_finance_first_payment, .td_finance_final_payment").remove();
Using Attribute Equals Selector
Change your code from:
$(this).find("#td_finance_first_payment, #td_finance_final_payment").remove();
to:
$(this).find('td[id="td_finance_first_payment"], td[id="td_finance_final_payment"]').remove();
Do this type of change for all areas of #xxx to id="xxx"
What this does is find all tds with attribute id="xxx", rather than using #id identifier, this is forces jQuery to do a tree search.
Also your HTML does not match your code, (theres no td_finance_first_payment in your html, I assume you removed it?)
Edit: This solution is useful if you 100% cannot edit the html (comes from a source you have no control over, such as an API or internal software). Best solution would be to fix the ids!

Vue.js block repeat table rows doesn't work in IE

I would like to repeat adding table rows using a template tag with vue.js, but it doesn't work in IE11. Here is the code.
<table border="1">
<tr>
<td rowspan="2">ID</td>
<td colspan="2">Name</td>
</tr>
<tr>
<td>Height</td>
<td>Weight</td>
</tr>
<template v-repeat="items">
<tr>
<td rowspan="2">{{id}}</td>
<td colspan="2">{{name}}</td>
</tr>
<tr>
<td>{{height}}</td>
<td>{{weight}}</td>
</tr>
</template>
</table>
Any help?
See http://vuejs.org/guide/components.html#Using_Components and the warning at the end of that section:
The table element has restrictions on what elements can appear inside
it, so custom elements will be hoisted out and not render properly. In
those cases you can use the component directive syntax:
<tr v-component="my-component"></tr>.
I found a solution that changed the <template> tag to a <tbody> tag. However there would be multiple <tbody> tags in a table, I hope this is the best solution in this case.
Make a long story short, This is HTML restrictions in IE, if you want compatibility, you will have to change your HTML structure.
I found an issue with similar question like yours here: https://github.com/vuejs/vue/issues/2404
Vue renders the template into real html before compiling it, so the same html restrictions apply for Vue templates, no matter how you define it.
IE does not support inside elements like , ..

can anyone help me improve this code in tb getting value through javascripts

i'm trying to get values of table from javascript. The code is working fine however i was wondering if it could be improved somehow and make sure it works on almost all of the modern browsers. The table list is changed more often and list is about 100 names long so that's why im asking for help. i would like to say thank you in advance for helping.Below is sample of my code and here is http://jsfiddle.net/g2s1ahcy/
HTML
<tr>
<td>left</td>
<td><a id="toppart" href="/">Name</a></td>
</tr>
<tr>
<td>left</td>
<td><a id="label1" href="/">Name</a></td>
</tr>
<tr>
<td>left</td>
<td><a id="label2" href="/">Name</a></td>
</tr>
Javascript
document.getElementById("toppart").textContent="desc";
document.getElementById("label1").textContent="apple";
document.getElementById("label2").textContent="orange";
1) I would use innerText or innerHTML instead of textContent
2) Maybe you could use querySelector instead of getElementById
HTML
<table class="data">
<tr>
<td>left</td>
<td><a class="label1" href="/">Name</a></td>
</tr>
<tr>
<td>left</td>
<td><a class="label2" href="/">Name</a></td>
</tr>
<tr>
<td>left</td>
<td><a class="label3" href="/">Name</a></td>
</tr>
</table>
JavaScript
document.querySelector('table > .label1').innerText = "apple";
document.querySelector('table > .label2').innerText = "oranges";
document.querySelector('table > .label3').innerText = "bananas";
Note that you can use the id attribute alright, but in long documents, id tags may become hard to maintain unique, giving you additional trouble.
I think the multiple lines of code can be simplified via using a map which maps each id-text_context pair.
Replcae code:
document.getElementById("toppart").textContent="desc";
document.getElementById("label1").textContent="apple";
document.getElementById("label2").textContent="orange";
With:
var id2Content = {
"toppart": "desc",
"label1": "apple",
"label2": "orange"
};
for(var key in id2Content) {
document.getElementById(key).textContent = id2Content[key];
}
innerText doesn't work in firefox, so it's better to use innerHTML or textContent. You should take in account that innerHTML parses HTML code, like <div id ="x"> or <a href="">... which is great but also takes resources (if you don't need that funtionality, better use textContent instead).
Also, in processing terms, document.querySelector('#id1') is equivalent to document.getElementById(id1), but most advanced jQuery selectors overload the system, so you I'll recommend to use id selectors whenever you can.

Can you use CSS to reference a parent or child of a certain object?

I guess I am spoiled with JavaScript. If you want to change something about the parent, you can code something like parentNode.style.etc.
<TABLE id="hasID">
<TBODY>
<TR>
<TD>
<IMG id="hasID2" src="somePicture.png">
<IMG id="hasID3" src="someOtherPicture.png">
</TD>
</tr>
<tr>
<td>other stuff</td>
</tr>
</tbody>
</table>
As you can see from my code table has an id, and the img tags have ids. What I would like to do is add a stype class to the first TD, so that all the images are aligned to the left or middle, that kind of thing.
However, here is a tricky part, I don't want to user JavaScript, because it looks to slow. Everything starts out on the right, and then jump to the center, after everything is loaded.
Also, here is a second tricky part. I can't change add a class to the TD, because it generated by JSF.
So my main question is can I do this with CSS.
UPDATE:
I don't really need to reference a parent. Referencing a child will also work for me.
You can't select a parent via CSS. It was proposed as a feature but it's not even close to implementation.
I will suggest that you move any javascript you have to just after the content above, which means that it will run as soon as that part of the section is rendered, thus removing any delay.
<TABLE id="hasID">
<TBODY>
<TR>
<TD>
<IMG id="hasID2" src="somePicture.png">
<IMG id="hasID3" src="someOtherPicture.png">
</TD>
</tr>
<tr>
<td>other stuff</td>
</tr>
</tbody>
</table>
<script type="text/javascript">
var img = document.getElementById("hasID2");
img.parentNode.style.textAlign = "right";
</script>
Inline Javascript is OK to use in these scenarios.
Sorry no way to select parent in css.
Is there a CSS parent selector?
Not sure if this will help, but I'll mention that you can add classes using JSF with styleClass="", depending on how you are generating the table. There is also a columnClass="" if you are putting these in a datatable.

Categories