I am trying to display the id of a selection onto the page and then remove it when it unselected. It does display the selected id, but when I click the same seat to unselect it, it just puts the id up again. I think its a problem with the tempArray.pop.
JQuery
$(this).each(function() {
// Getting the id of each seat
var seatLocation = $(this).attr('id');
// If seatLocation is not inArray - add it - else - pop it off
//$.inArray take (value , name of array)
var index = $.inArray(seatLocation, window.tempArray);
if (index = -1) { // -1 is returned if value is not found in array
window.tempArray.push(seatLocation.replace('_',''));
} else {
window.tempArray.pop(seatLocation.replace('_',''));
}
// Show the ids in a span to the users4
console.log(window.tempArray)
// join() converts an array to a string, putting the argument between each element.
$('#seatLocation').html(window.tempArray.join(', '));
});
HTML to display the seat id
<div id='ticket-options'>
<label>Seats</label>
<span id="seatLocation"></span>
<label>Passengers</label>
<span id='seatsChosen'>0</span> of <span id='numSeats2'>4</span>
</div>
<div class="legroom">
HTML of tables with id
<table>
<tr class="row1">
<td class='n' id='1_A'>T</td>
<td class='n' id='1_B'>F</td>
<td class='n' id='1_C'>T</td>
<td class="row_num">1</td>
<td class='n' id='1_D'>T</td>
<td class='n' id='1_E'>F</td>
<td class='n' id='1_F'>T</td>
<td>Extra Legroom</br>£13.99</td>
</tr>
</table>
</div>
This is an image of the results I get when I select the same seat repeatedly.
If you have two event on the same element.
Add a event.stopPropagation();
Cause the select and unselect are on the same event.
Add this in your function and try... Hope it work for you.
Related
I'm trying to do the following: I have a table populated with data from the DB. Apart from that, I have an input where you can write something and a button that will filter, only showing the lines that have that string. This is working now!
The thing is, the input should only allow you to filter by foo.name/foo.code (two propertys of my entity).
I'm adding the code I have in case anyone can guide me out, I've tried several things but this are my first experiences with JQuery while I have a strict story-delivery time. Thanks everyone!
<tbody>
<c:forEach var="foo" items="${foo}">
<tr id = "fooInformation" class="mtrow">
<th id="fooName" scope="row">${foo.name}</th>
<td id="fooCode" class="left-align-text">${foo.code}</td>
<td class="left-align-text">${foo.country}</td>
<td class="left-align-text">${foo.region}</td>
<td class="left-align-text">${foo.subregion}</td>
</tr>
</c:forEach>
</tbody>
$("#search").click(function () { -> button id
var value = $("#fooRegionSearch").val(); -> value of the input
var rows = $("#fooRegionTable").find("tr"); -> table id
rows.hide();
rows.filter(":contains('" + value + "')").show();
});
To start with, your HTML is invalid - there cannot be elemenets with duplicate IDs in HTML. Use classes instead of IDs.
Then, you need to identify which TRs pass the test. .filter can accept a callback, so pass it a function which, given a TR, selects its fooName and fooCode children which contain the value using the :contains jQuery selector:
$("#search").click(function() {
var value = $("#fooRegionSearch").val();
var rows = $("#fooRegionTable").find("tr");
rows.hide();
rows.filter(
(_, row) => $(row).find('.fooName, .fooCode').filter(`:contains('${value}')`).length
).show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="fooRegionTable">
<tr id="fooInformation" class="mtrow">
<th class="fooName" scope="row">name1</th>
<td class="fooCode" class="left-align-text">code1</td>
<td class="left-align-text">${foo.country}</td>
<td class="left-align-text">${foo.region}</td>
<td class="left-align-text">${foo.subregion}</td>
</tr>
<tr id="fooInformation" class="mtrow">
<th class="fooName" scope="row">name2</th>
<td class="fooCode" class="left-align-text">code2</td>
<td class="left-align-text">${foo.country}</td>
<td class="left-align-text">${foo.region}</td>
<td class="left-align-text">${foo.subregion}</td>
</tr>
</table>
<button id="search">click</button><input id="fooRegionSearch" />
I have a table which looks like this :
<div class="table">
<table>
<tr>
<th>FORce</th>
<th>DEXtérité</th>
<th>CONstitution</th>
<th>INTelligence</th>
<th>SAGesse</th>
<th>CHArisme</th>
</tr>
<tr class="chiffres">
<td class = "FOR">
</td>
<td class = "DEX">
</td>
<td class= "CON">
</td>
<td class ="INT">
</td>
<td class="SAG">
</td>
<td class="CHA">
</td>
</tr>
</table>
</div>
And here is my Javascript code :
function Recommand(){
if(document.getElementsByClassName("SAG").innerText >= 13)
{
document.getElementById("radio7").innerText.style.fontWeight="bold";
}
}
How do I make it so that if SAG.innerText >= x number, the id that I choose, becomes bold?
Also, I'm using and anonymous function to execute my function when my page loads.
aPar[4].addEventListener("load", Recommand());
My TD class holds a number, and that number will be in direct relation with my radio button, who also has a innerText value my "radio7" ID looks a little something like this :
<label><input type="radio" id = "radio7"
name="radio1"/> Clerc</label>
What I want to become bold, is the "Clerc" string from the radio.
When you use document.getElementsByClassName() it returns an array. So you'd have to use it like this:
if(document.getElementsByClassName("SAG")[0].innerText >= 13)
{
...
}
That means that you'll get the first element that has the class "SAG". If you have more elements with the same you could try to loop through them.
EDIT: The text is inside the label, not the radio button, so you can put the id inside the radio button and then try again. Or you can use JQuery and get the parent of the input element and then apply the style.
What I'm saying is that you'd have to put it something like this:
<label id="radio7"><input type="radio" name="radio1"/>Clerc</label>
And instead of applying it using the style.fontWeight you could just change the text to be bold like this:
document.getElementById("radio7").innerText= "<b>" + document.getElementById("radio7").innerText + </b>;
This just adds <b> and </b> before and after the text thus making it bold.
I have the following HTML structure to represent a calendar:
<table>
<thead>...</thead>
<tbody>
<tr>...</tr>
<tr>
<td day="4">...</td>
<td day="5">...</td>
<td day="6" class="is-startrange">...</td>
<td day="7">...</td>
<td day="8">...</td>
</tr>
<tr>
<td day="9">...</td>
<td day="10">...</td>
<td day="11">...</td>
<td day="12">
<button class="day" type="button">12</button>
</td>
<td day="13">...</td>
</tr>
</tbody>
</table>
My question is: starting from the button under day 12, how can I traverse up, select all the button elements until a is-startrange class is encountered?
Each table cell is a button representing a date and listeners have been added to all the button elements. When a date is clicked, I will get the selected date as starting point.
I want to add style to all the button elements between the start date and selected date (either add class or through pure CSS).
Is there a way this can be achieved in D3 selection or pure CSS?
As Gerardo Furtado already mentioned in his comment the question is not actually about traversing the DOM upwards, but rather about an iteration of td elements. This can easily be done by using d3.selectAll("td") which will yield a flattened selection of all tds found on the page. Depending on your layout you might need to further narrow the selection down to a specific table which could be done by adjusting the selector to "table.myTable td", "#tableId td" or the like.
Having this selection at hand you can apply a class, say range, by using selection.classed(names[, value]) which can take a function passed in as the second argument value:
If the value is a function, then the function is evaluated for each selected element, in order, being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element. The function’s return value is then used to assign or unassign classes on each element.
The only task left is to implement a filter function which keeps track, if an element is within the desired or range or not and, thus, determines whether to assign the range class.
The following snippet shows how this could all be put together using a filter function rangeFilter() provided to .classed():
// The day parameter determines the stop criterion
function rangeFilter(day) {
// This property is closed over by the following function to keep track of the
// range. If this is true, this element and following elements belong to the
// range until this property becomes false again once reaching the button's td.
var inRange = false;
// Filter function returning true, if the element belongs to the range.
return function(d) {
element = d3.select(this); // The actual td element of this iteration step.
// Evaluate if the element is still in the range or, in case the range has not
// yet started, check if we reached the td.is-startrange.
inRange = (inRange && element.attr("day") != day)
|| element.classed("is-startrange");
// XOR to exclude the .is-startrange element.
return inRange != element.classed("is-startrange");
}
}
d3.selectAll("button")
.on("click", function() {
// For all tds check if they belong to the range and set the class based
// on the result of the filter function passing in this buttons value.
d3.selectAll("td")
.classed("range", rangeFilter(d3.select(this).text()));
});
.is-startrange {
background-color: limegreen;
}
.range {
background-color: red;
}
<script src="https://d3js.org/d3.v4.js"></script>
<h1>Hit the button</h1>
<table>
<thead>...</thead>
<tbody>
<tr>...</tr>
<tr>
<td day="4">...4...</td>
<td day="5">...5...</td>
<td day="6" class="is-startrange">...6...</td>
<td day="7">...7...</td>
<td day="8">...8...</td>
</tr>
<tr>
<td day="9">...9...</td>
<td day="10">...10...</td>
<td day="11">...11...</td>
<td day="12">
<button class="day" type="button">12</button>
</td>
<td day="13">...13...</td>
</tr>
</tbody>
</table>
In my given example, i have two text boxes. when value in first text box changed i want to find the immediate next text box (note : without id) and change its value.
The example given contains only single text box group. actually it can be more than one text boxes. (group of from & to text boxes of Financial Data)
so, when value in from text box (txtFinancialYearFrom) changed, i want to find the to text box (txtFinancialYearTo) and change its value as well.
JsFiddle Link - Example
Thanks in advance for the help!!
<table class="fotm-table">
<tr>
<td class="text-right" width="120">
<span id="ContentPlaceHolder1_lblFinancialYear">Financial Data :</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearFrom"
name="ctl00$ContentPlaceHolder1$txtFinancialYearFrom">
</span>
</td>
<td width="20" align="center">
<span style="align-content: center">to</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearTo"
name="ctl00$ContentPlaceHolder1$txtFinancialYearTo">
</span>
</td>
</tr>
</table>
Using the given information, since you are going to have more blocks (that should be rows on your table), this solution should work:
var rows = $('.fotm-table tr');
$(rows).each(function(){
$('input:first', $(this)).on('change', function(){
var fromValue = $(this).val();
var row = $(this).closest('tr');
$('td:last input', row).val(parseInt(fromValue) + 1);
});
});
The code gets all the rows from your table and for each one of them, it will add a listener that when you change the first textbox (input), it will change the value of the next textbox (here it's adding 1 to it).
If I've understood correctly, you need something like this:
/* Loop through all table rows */
$('tr','table.fotm-table').each(function() {
var tr = this;
/* Cache all inputs a jquery object - you may want to specify which type of input you are targeting i.e. $('input[type="text"]') */
var inputs = $('input',tr);
/* Cache the slave (second in the example) input in a jquery object - you can do the same for multiple inputs, simply by modifying the eq() index parameter
*/
var slaveInput = inputs.eq(1);
/* Listen for changes on the master input */
var masterInput = inputs.eq(0).on('change',function() {
/* Do smt on the slave input - fill it with the next year in the example */
var year = $(this).val();
var followingYear = parseInt(year,10)+1
slaveInput.val(followingYear);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="fotm-table">
<tr>
<td class="text-right" width="120">
<span id="ContentPlaceHolder1_lblFinancialYear">Financial Year :</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearFrom"
name="ctl00$ContentPlaceHolder1$txtFinancialYearFrom">
</span>
</td>
<td width="20" align="center">
<span style="align-content: center">to</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearTo"
name="ctl00$ContentPlaceHolder1$txtFinancialYearTo">
</span>
</td>
</tr>
</table>
Here's an updated fork of the jsFiddle you provided:
https://jsfiddle.net/jkdaza/thonfzwu/5/
You can use this tricky solution from link:
$('#txtFinancialYearFrom').change(function(el) {
$(':input:eq(' + ($(':input').index(this) + 1) + ')').val('test');
});
https://jsfiddle.net/g34yqL0u/2/
I want to be able to find a way to hide a preceding <td>'s contents if the one above it is empty. I have my table set up as such:
<tr>
<td class="firsttd">
</td>
</tr>
<tr>
<td class="nexttd">
Hide me if above TD is empty
</td>
</tr>
<tr>
<td class="firsttd">
</td>
</tr>
<tr>
<td class="nexttd">
Hide me if above TD is empty
</td>
</tr>
And so far have:
$(".firsttd").each(function( index ) {
var dotlenght = $(this).html().length;
if (dotlenght < 1){
$(this).next('.nexttd').hide();
}
});
But cannot get it to work correctly. I cannot figure our how to tell JQuery which element to target.
Can anyone point me in the right direction?
You need to use:
$(this).parent().next().find('.nexttd').hide();
|| || ^^------find td `.nexttd`
|| ^^------Traverse to next tr
^^------Traverse to parent tr
Also you do not need to iterate over elements individually. You can target all first td elements that are empty using .filter() function and can narrow down the complete code to:
$( "td.firsttd" ).filter(function(){
return $(this).html() == "";
}).parent().next().find('.nexttd').hide();
There are two issues in your code.
First is the length of the content:
$(this).html().length; // will produce 1
$.trim($(this).html()).length; // will produce 0
The second one is hiding the next row:
$(this).next().find('.nexttd').hide();
should be:
$(this).parent().next().find('.nexttd').hide();