HTML javascript: expanding function changes the level relationship incorrectly - javascript

The problem is explained in the picture below. Once clicking the expanding function of "Parameter 1", the level of "Parameter 2" will change as seen in the middle picture. But actually it should remain in the same level.
Any suggestion is highly appreciated. Thanks in advance.
JAVASript
$('.P1').click(function() {
$(this).find('span').text(function(_, value) {
return value == '-' ? '+' : '-'
});
$(this).closest('tr').nextUntil('tr:has(.P2)').slideToggle(100, function() {});
});
$('.Sub-parameter-1').click(function() {
$(this).find('span').text(function(_, value) {
return value == '-' ? '+' : '-'
});
$(this).closest('tr').nextUntil('tr:has(.Sub-parameter-2)').slideToggle(100, function() {});
});
HTML
<table width="200" border="1">
<tr>
<td rowspan="6">Summary </td>
<td colspan="3">
<div align="center">1 st level</div>
</td>
</tr>
<tr>
<td colspan="3">
<div class="P1"><span>-</span>Parameter 1</div>
</td>
</tr>
<tr>
<td rowspan="3">L1</td>
<td colspan="2"><div class="Sub-parameter-1"><span>-</span>Sub parameter (1)</div></td>
</tr>
<tr>
<td>L2</td>
<td>description</td>
</tr>
<tr>
<td colspan="2"><div class="Sub-parameter-2"><span>-</span>Sub parameter (2)</td>
</tr>
<tr>
<td colspan="3">
<div class="P2">Parameter 2</div>
</td>
</tr>
</table>
JSFiddle: https://jsfiddle.net/gft08cmb/4/
EDIT based on answer
When applying the answer to more than 1 row of sub parameter, then the "Parameter 2" still changes its level seen in following link.
https://jsfiddle.net/gka7312L/ or https://jsfiddle.net/p2a2wxfv/1/

Your rowspan attribute in L1 is making problems since it should change from 3 to 2 and back in your case.
This works as you would want I think: https://jsfiddle.net/gft08cmb/6/
You should of course make it dynamic if your data is going to be dynamic also.
So probably a count of rows etc. and then manipulate based on this.
Let me know if you need further help.

Related

How to replace text of tds instead of href

i have a table with multiple rows. and i have rows that each of them has a specific class. in the last row i have a link . how can i replace each td text infront of their name in link ?
i wrote the below code but it sets the texts at the end of my links.
here is my snippet :
$(".list").each(function(index, element) {
var route=$(this).closest("tr").find(".route").text()
var airline=$(this).closest("tr").find(".airline").text()
var route=$(this).closest("tr").find(".route").text()
var linkk=$(this).attr("href")
$(this).attr("href",linkk+route+airline+route); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<table border="1">
<tr>
<td class="route">tehran-istanbul</td>
<td class="airline">Iran air</td>
<td class="route">Ss 454</td>
<td><p class="date1">1398-5-12</p><p class="date2">(2017-08-23)</p></td>
<td>link</td>
</tr>
<tr>
<td class="route">tehran-Ankara</td>
<td class="airline">Tukish airline</td>
<td class="route">7547</td>
<td><p class="date1">1395-5-12</p><p class="date2">(2018-01-01)</p></td>
<td>link</td>
</tr>
</table>
few issues with your code:
you are redeclaring variable route, will not be helpful in your case, instead initialize two vars route1 and route2.
linkk+route+airline+route won't give the string you need you will need to add extra strings like 'route=' to identify parameters in between.
$(this).parents("tr").find(".route") will give you multiple elements with class route, you need to target specific elements, you can use first() and last() in your case.
$(".list").each(function(index, element) {
var route1= "route=" + $(this).parents("tr").find(".route").first().text();
var airline= "airline=" + $(this).parents("tr").find(".airline").first().text();
var route2= "route=" + $(this).parents("tr").find(".route").last().text();
var date1 = "date1=" + $(this).parents("tr").find(".date1").first().text();
var date2 = "date2=" + $(this).parents("tr").find(".date2").first().text();
var link = $(this).attr("href").replace(/\?.*/g, "?") + route1 + "&" + airline + "&" + route2 + "&" + date1 + "&" + date2;
$(this).attr("href", link);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<table border="1">
<tr>
<td class="route">tehran-istanbul</td>
<td class="airline">Iran air</td>
<td class="route">Ss 454</td>
<td><p class="date1">1398-5-12</p><p class="date2">(2017-08-23)</p></td>
<td>link</td>
</tr>
<tr>
<td class="route">tehran-Ankara</td>
<td class="airline">Tukish airline</td>
<td class="route">7547</td>
<td><p class="date1">1395-5-12</p><p class="date2">(2018-01-01)</p></td>
<td>link</td>
</tr>
</table>
Similar to #DiJ I slightly changed the name of one of your arguments (the second route to routeno). And then I basically tried to reduce the code to the minimum, making it simpler at the same time.
$(".list").each(function(index, element) {
['route','airline','routeno'].forEach(function(i,o){console.log(i)});
$(this).closest("tr").find("td").each((i,o)=>{
if (vars.indexOf(o.className)>-1)
this.href+=o.className+'='+encodeURIComponent(o.innerHTML)+'&';
});
this.href+='date1=&date2=';
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<table border="1">
<tr>
<td class="route">tehran-istanbul</td>
<td class="airline">Iran air</td>
<td class="routeno">Ss 454</td>
<td><p class="date1">1398-5-12</p><p class="date2">(2017-08-23)</p></td>
<td>link</td>
</tr>
<tr>
<td class="route">tehran-Ankara</td>
<td class="airline">Tukish airline</td>
<td class="routeno">7547</td>
<td><p class="date1">1395-5-12</p><p class="date2">(2018-01-01)</p></td>
<td>link</td>
</tr>
</table>
You can do the same also without the indexOf() testing, like
$(".list").each(function(index, lnk) {
var $tr=$(lnk).closest("tr");
['route','airline','routeno'].forEach(function(col,i){
lnk.href+=encodeURIComponent($tr.find("td."+col).text())+'&'; });
lnk.href+='date1=&date2=';
});

Clone a <tr> and modify the clone's content in JavaScript / jQuery

I'm stuck with a problem. I currently have a simple <table> that looks like this:
<table class="table">
<tbody>
<tr id="kc_keychain_1">
<td class="td-kc-id"> kc_keychain_1 </td>
<td class="td-kc-name"> Keychain 1 </td>
<td>
<p>my key</p>
<p>my second key</p>
</td>
</tr>
<tr id="kc_keychain_10">
<td class="td-kc-id"> kc_keychain_10 </td>
<td class="td-kc-name"> Keychain 10</td>
<td>
<p>ma clé</p>
<p>Clé 005V</p>
</td>
</tr>
</tbody>
</table>
I also have some JavaScript code, that aims at cloning a specific row, modifying the .tc-kc-id and .tc-kc-name cells of the cloned row, and finally adding the cloned and modified row to the table:
var clonedTr = document.querySelector('#' + id).cloneNode(true);
//$(clonedTr).find(".td-kc-id").innerText = "test";
//$(clonedTr).find(".td-kc-name").innerText = "test";
document.querySelector('tbody').appendChild(clonedTr);
It clones and adds the cloned row without any problem. But the commented code doesn't work. What I try in the commented code is to get specific cells thanks to their classname, and then change their innerText property.
But the innerText of the cells remain unchanged. Can anyone help me? Thanks
Thanks to #ChrisG, a possible working solution is:
$(clonedTr).find(".td-kc-id").text("test");

angular - print ng-table title dynamically

I am stuck at a point where i want to print the sub-heading title's dynamically using ng-table, header should be type1 type2 type3 and Details must be main head, subtype value must be sub-heading in details, please see picture attached below
any help is much aprreciated.
Try this out:
https://plnkr.co/edit/gypa0JDAZqhNwWcRQK93?p=preview
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<table ng-table="tableParams">
<tr>
<td colspan="3"></td>
<td colspan="{{detailsCount}}" style="text-align:center">Details</td>
</tr>
<tr ng-repeat="i in dataObject">
<td title="'Type1'">{{i.type1}}</td>
<td title="'Type2'">{{i.type2}}</td>
<td title="'Type3'">{{i.type3}}</td>
<td ng-repeat="d in i.details" ng-init="detailsColCount(i.details)">{{d.subTypeCode}}</td>
</tr>
</table>
</body>
$scope.detailsCount = 0;
$scope.detailsColCount = function(details){
if (details.length > $scope.detailsCount) {
$scope.detailsCount = details.length;
}
};

Calculating Number IDs

I wasn't quite sure how to word this in the title, so thank you for clicking to on this.
So now to my problem:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<style>
.block {
background-color: black;
}
</style>
<table border='1px'>
<tr>
<td id='11'></td>
<td id='12'></td>
<td id='13'></td>
<td id='14'></td>
<td id='15'></td>
</tr>
<tr>
<td id='21'></td>
<td id='22'></td>
<td id='23'></td>
<td id='24'></td>
<td id='25'></td>
</tr>
<tr>
<td id='31'></td>
<td id='32'></td>
<td id='33' class="block"></td>
<td id='34'></td>
<td id='35'></td>
</tr>
<tr>
<td id='41'></td>
<td id='42'></td>
<td id='43'></td>
<td id='44'></td>
<td id='45'></td>
</tr>
<tr>
<td id='51'></td>
<td id='52'></td>
<td id='53'></td>
<td id='54'></td>
<td id='55'></td>
</tr>
</table>
<button onclick="blockUp()">Up</button>
<button onclick="blockDown()">Down</button>
<button onclick="blockLeft()">Left</button>
<button onclick="blockRight()">Right</button>
<script>
var blockUp = function() {
var oldBlock = document.getElementsByClassName("block")[0].id;
var newBlock = Math.floor(oldBlock + 1);
document.getElementById(newBlock).classList.add("block");
document.getElementById(oldBlock).classList.remove("block");
}
</script>
</body>
</html>
This code is not complete, as I want to fix this problem first.
I want to use Math.floor to get a certain ID (thus, IDs as numbers), and manipulate them. More specifically, I want to find the ID of the cell that currently has the .block class, find the ID of the cell above that using Math.floor(oldBlock + 1), remove the class from the original cell, and add the class to the new cell. I used variables so that the function would always be able to run, rather than making a million if/else if/else statements.
Unfortunately, this doesn't work with my current code. How would I be able to do this?
Any help is appreciated!
You have to make sure that "oldBlock" contains a number before trying to do math with it (like adding 1):
var oldBlock = +document.getElementsByClassName("block")[0].id;
That's one way of doing it. You could also use parseInt():
var oldBlock = parseInt(document.getElementsByClassName("block")[0].id, 10);
The value of the "id" property will be a string, so if you involve that in an addition operation JavaScript will treat it as string concatenation. By forcing it to be a number first, you'll get the effect you want.

Change the css class associated with a <TD> column based on value of column with javascript

I have a grid and for one of the columns i want to dynamically change the css used based on the value of another field in the resultset.
So instead of something like
<td class='class1'>
${firstname}
</td>
pseudo-wise I would like
{{if anotherColumnIsTrue }}
<td class='class1'>
${firstname}
</td>
{{/if}}
{{if !anotherColumnIsTrue }}
<td class='class2'>
${firstname}
</td>
{{/if}}
Is this thing possible..?
I think that jQuery makes this a lot easier.
It is very possible. I assume that you would want this for each row. Lets assume you have the following table:
<table id="coolTable">
<tr>
<td class="anotherColumn">True</td>
<td class="firstName">Chris</td>
</tr>
<tr>
<td class="anotherColumn">False</td>
<td class="firstName">Roger</td>
</tr>
</table>
You could go through rows and selectively add classes using the following code:
$(function(){
$("#coolTable tr").each(function(i,row){
if($(row).children("td.anotherColumn").html()=="True") // Any condition here
{
$(row).children("td.firstName").addClass("class1");
}else{
$(row).children("td.firstName").addClass("class2");
}
});
});
Have a look at this fiddle: http://jsfiddle.net/mrfunnel/LXq3w/2/

Categories