distinguish between click on a table row and on its text - html-table

I want to catch a click on a row of a table, but 2 actions based on where it was clicked:
the 'empty space' of 1st column or any other column --> select that row
the 'text' of 1st column --> do something based on that text (example, update that table with list of all staffs)
Note, there are multiple tables in the page, I need to catch the correct table object for updating.
The simple code (1 table) is below.
<!DOCTYPE html>
<html>
<head>
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
</style>
</head>
<body>
<h2>HTML Table</h2>
<table id="aTable">
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
</table>
<script>
const tbl=document.getElementById("aTable");
// click on a row, except on 'text' of 1st column
tbl.onclick = (e) => {
// set row = selected
}
// click on 'text' of 1st column
// update the table with new data based on the 'text' of 1st column
</script>
</body>
</html>

You can wrap your text in spans and then handle event separate for span and th.
<tr>
<th><span>Company</span></th>
</tr>
document.querySelectorAll("table tr").forEach(el=>el.addEventListener("click", () => {
// row clicked
})
document.querySelectorAll("table span").forEach(el=>el.addEventListener("click", () => {
// text clicked
})

Related

How to move a div inside a table cell to another cell vuejs

I have a div inside a cell. From the example code below, it is initially positioned on cell (1,1). Now, I want it to move to other cells inside the table on mouse drag. Here is my code.
<table class="table">
<tr v-for="row in rows">
<td v-for="col in cols">
<div class="ball" v-if="col == 1 && row == 1"></div>
</td>
</tr>
</table>
<script>
export default{
data() {
return{
cols: 10,
rows: 10,
}
}
</script>
<style scoped>
.ball{
display:inline-block;
width: 10px;
height: 10px;
background:blue;
}
td{
width: 100px;
height: 100px;
}
</style>
How could I move it on specific cell using vuejs?
https://jsfiddle.net/cmvn2yda/

vuejs conditional binding a class based on the data

Can someone tell me what am I doing wrong? I am trying to bind the class based on if in the data model is displays a yes or no. I have tried conditional binding, but guess maybe I am missing a parameter or going about this the wrong way.
What am I missing? I want the css January class to bind to the table. how do I trigger v-if if v-bind already there?
Thanks
<!DOCTYPE html>
<html>
<head>
<style>
table,
th,
td {
border: 1px solid black;
}
th {
width: 100px;
height: 100px;
background-color: yellow;
}
td {
background-color: grey;
}
.January{
background-color: pink;
}
</style>
</head>
<body>
<table>
<div id="cal">
<tr>
<th>Month</th>
<th>Savings</th>
<th>Spent</th>
</tr>
<tr>
<td v-bind:class="{'January':yes}">January</td>
<td>$100</td>
<td>$10</td>
</tr>
<tr>
<td>February</td>
<td>$80</td>
<td>$300</td>
</tr>
<tr>
<td>March</td>
<td>$80</td>
<td>$0</td>
</tr>
<script type="text/javascript" src="https://unpkg.com/vue#2.0.3/dist/vue.js"></script>
<script>
new Vue({
el: '#cal',
data: {
January:'yes',
February:'yes',
March:'yes',
April:'yes',
May:'yes',
June:'yes',
July:'yes',
August:'yes',
September:'yes',
October:'yes',
November:'yes',
December:'yes'
}
})
</script>
</div>
</table>
</body>
</html>
So for the :class binding you pass in an object that is {css_class : someThingThatResolvesToTrueOrFalse}
So you could do something like
<td v-bind:class="{'January': January == 'yes'}">January</td>
The better approach would be to replace yes with a bool and judge off that value instead of a comparison.
Here is your code updated.
new Vue({
el: '#cal',
data: {
January: 'yes',
February: 'yes',
March: 'yes',
April: 'yes',
May: 'yes',
June: 'yes',
July: 'yes',
August: 'yes',
September: 'yes',
October: 'yes',
November: 'yes',
December: 'yes'
}
})
table,
th,
td {
border: 1px solid black;
}
th {
width: 100px;
height: 100px;
background-color: yellow;
}
td {
background-color: grey;
}
.January {
background-color: pink;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="cal">
<table>
<tr>
<th>Month</th>
<th>Savings</th>
<th>Spent</th>
</tr>
<tr>
<td v-bind:class="{'January':January == 'yes'}">January</td>
<td>$100</td>
<td>$10</td>
</tr>
<tr>
<td>February</td>
<td>$80</td>
<td>$300</td>
</tr>
<tr>
<td>March</td>
<td>$80</td>
<td>$0</td>
</tr>
</table>
</div>
</body>
</html>

Aligned text of the table cells

I would like to know how can I make my text be aligned and centered the same way in every cell. Because if you see there is a slight difference between the first cell who got a link just under . I would my title to be on the same line without disturbing the responsive side and also the "same size cells" side (thanks to the table layout)
$(document).ready(function(){
$(".toggler").click(function(e){
e.preventDefault();
$('.cat'+$(this).attr('data-prod-cat')).toggle();
});
});
td{
display:block;
width:auto;
border:1px dotted red;
background-color:red;
color:white;
margin-bottom:10px;
}
#media only screen and (min-width: 70em) {
td{
display:table-cell;
border:1px dotted red;
background-color:red;
color:white;
margin-bottom:0px;
}
}
p{font-family:'Varela Round';font-weight:bold;text-align:center;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<table style="table-layout: fixed; width:100%" width="100%" cellpadding="0" cellspacing="5">
<tbody>
<tr>
<td><table>
<tr><td><p>SOCIÉTÉS: 230</p></td></tr><tr><td>+ En savoir plus</td></tr>
<tr class="cat1" style="display:none">
<td>Part CAC 40 : 90</td></tr>
<tr class="cat1" style="display:none">
<td>Part Filiales +100MK€: 120</td></tr>
</tr>
</table>
</td>
<td><p>CONTACT</p></td>
<td><p>EMAIL NOMINATIF</p></td>
<td><p>OPT OUT</p></td>
<td><p>LIGNES DIRECTES/MOBILES</p></td>
</tr>
</tbody>
</table>
What you can do is just the element td to the css to have the text-align property as well:
CSS:
p, td{
font-family:'Varela Round';
font-weight:bold;
text-align:center;
}
Also just a side note you for your js if you want to run your js code when the DOM is loaded jquery docs does not suggest you that document ready function instead they suggest:
JS
$(function() {
$(".toggler").click(function(e){
e.preventDefault();
$('.cat'+$(this).attr('data-prod-cat')).toggle();
});
});
Jquery Docs: https://api.jquery.com/ready/

Scrollable table with fixed header

I searched for some solutions in PHP/HTML/CSS for this, but nothing worked so far, maybe because in most of those examples were sooo much of code so I got lost in it. Could someone explain to me what I need to do or put some simple sample code here?
Table fixed header using CSS
The simplest would be to position: sticky; your th elements:
.tableFix { /* Scrollable parent element */
position: relative;
overflow: auto;
height: 100px;
}
.tableFix table{
width: 100%;
border-collapse: collapse;
}
.tableFix th,
.tableFix td{
padding: 8px;
text-align: left;
}
.tableFix thead th {
position: sticky; /* Edge, Chrome, FF */
top: 0px;
background: #fff; /* Some background is needed */
}
<div class="tableFix">
<table>
<thead>
<tr><th>H1</th><th>Header 2</th><th>Header 3</th><th>4</th><th>5th Header</th></tr>
</thead>
<tbody>
<tr><td>R1C2</td><td>R1C2</td><td>R1C3</td><td>R1C4</td><td>R1C5</td></tr>
<tr><td>R2C1</td><td>R2C2</td><td>R2C3</td><td>R2C4</td><td>R2C5</td></tr>
<tr><td>R3C1</td><td>R3C2</td><td>R3C3</td><td>R3C4</td><td>R3C5</td></tr>
<tr><td>R4C1</td><td>R4C2</td><td>R4C3</td><td>R4C4</td><td>R4C5</td></tr>
<tr><td>R5C1</td><td>R5C2</td><td>R5C3</td><td>R5C4</td><td>R5C5</td></tr>
<tr><td>R6C1</td><td>R6C2</td><td>R6C3</td><td>R6C4</td><td>R6C5</td></tr>
</tbody>
</table>
</div>
Table fixed header for older browsers
If the browsers you need to support do not encompass the position's sticky value, you can take a look at Fix table head using a bit of Javascript
This code (taken from the link in your comment) is the basic code you need. Next time you need to figure that kind of thing out, just remove segments of code to see what breaks, and leave out everything that doesn't break something that you need.
<html>
<head>
<style>
div.tableContainer {
clear: both;
border: 1px solid #963;
height: 285px; /* html>body tbody.scrollContent height plus 23px for the header */
overflow: auto;
width: 756px /* Remember to leave 16px for the scrollbar! */
}
html>body tbody.scrollContent {
display: block;
height: 262px;
overflow: auto;
width: 100%
}
html>body thead.fixedHeader tr {
display: block
}
html>body thead.fixedHeader th { /* TH 1 */
width: 200px
}
html>body thead.fixedHeader th + th { /* TH 2 */
width: 240px
}
html>body thead.fixedHeader th + th + th { /* TH 3 +16px for scrollbar */
width: 316px
}
html>body tbody.scrollContent td { /* TD 1 */
width: 200px
}
html>body thead.scrollContent td + td { /* TD 2 */
width: 240px
}
html>body thead.scrollContent td + td + td { /* TD 3 +16px for scrollbar */
width: 316px
}
</style>
</head>
<body>
<div id="tableContainer" class="tableContainer">
<table width="100%" cellspacing="0" cellpadding="0" border="0" class="scrollTable">
<thead class="fixedHeader">
<tr class="alternateRow">
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
</tr>
</thead>
<tbody class="scrollContent">
<tr class="normalRow">
<td>Cell Content 1</td>
<td>Cell Content 2</td>
<td>Cell Content 3</td>
</tr>
<tr class="alternateRow">
<td>More Cell Content 1</td>
<td>More Cell Content 2</td>
<td>More Cell Content 3</td>
</tr>
.........
</tbody>
</table>
</div>
</body>
</html>

Rails: How do I autocomplete using the Google Places DB?

My application has an address field, which I want an autocomplete (updates as user types, displays below the entry field) for using the Google Places Autocomplete API. Now, I've seen gems which autocomplete words based on fields in a model, which wont work for me, since I can't store all the addresses on google places locally.
I've also tried a google_places_autocomplete gem which returns a list of suggestions when given an input string to autocomplete, but I don't know how to dynamically update the list as the input changes and present it in a nice format.
Can someone please give me an overview of which gems I should use and how I should go about doing this? I can display autocomplete suggestions using predefined addresses with the google_places_autcomplete gem which should mean I don't need to manually parse JSON.
you can do it directly on the view via Google Places javascript library.
Check out this example:
<!DOCTYPE html>
<html>
<head>
<title>Place Autocomplete Address Form</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
</style>
<link type="text/css" rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500">
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places"></script>
<script>
// This example displays an address form, using the autocomplete feature
// of the Google Places API to help users fill in the information.
var placeSearch, autocomplete;
var componentForm = {
street_number: 'short_name',
route: 'long_name',
locality: 'long_name',
administrative_area_level_1: 'short_name',
country: 'long_name',
postal_code: 'short_name'
};
function initialize() {
// Create the autocomplete object, restricting the search
// to geographical location types.
autocomplete = new google.maps.places.Autocomplete(
/** #type {HTMLInputElement} */(document.getElementById('autocomplete')),
{ types: ['geocode'] });
// When the user selects an address from the dropdown,
// populate the address fields in the form.
google.maps.event.addListener(autocomplete, 'place_changed', function() {
fillInAddress();
});
}
// [START region_fillform]
function fillInAddress() {
// Get the place details from the autocomplete object.
var place = autocomplete.getPlace();
for (var component in componentForm) {
document.getElementById(component).value = '';
document.getElementById(component).disabled = false;
}
// Get each component of the address from the place details
// and fill the corresponding field on the form.
for (var i = 0; i < place.address_components.length; i++) {
var addressType = place.address_components[i].types[0];
if (componentForm[addressType]) {
var val = place.address_components[i][componentForm[addressType]];
document.getElementById(addressType).value = val;
}
}
}
// [END region_fillform]
// [START region_geolocation]
// Bias the autocomplete object to the user's geographical location,
// as supplied by the browser's 'navigator.geolocation' object.
function geolocate() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var geolocation = new google.maps.LatLng(
position.coords.latitude, position.coords.longitude);
autocomplete.setBounds(new google.maps.LatLngBounds(geolocation,
geolocation));
});
}
}
// [END region_geolocation]
</script>
<style>
#locationField, #controls {
position: relative;
width: 480px;
}
#autocomplete {
position: absolute;
top: 0px;
left: 0px;
width: 99%;
}
.label {
text-align: right;
font-weight: bold;
width: 100px;
color: #303030;
}
#address {
border: 1px solid #000090;
background-color: #f0f0ff;
width: 480px;
padding-right: 2px;
}
#address td {
font-size: 10pt;
}
.field {
width: 99%;
}
.slimField {
width: 80px;
}
.wideField {
width: 200px;
}
#locationField {
height: 20px;
margin-bottom: 2px;
}
</style>
</head>
<body onload="initialize()">
<div id="locationField">
<input id="autocomplete" placeholder="Enter your address"
onFocus="geolocate()" type="text"></input>
</div>
<table id="address">
<tr>
<td class="label">Street address</td>
<td class="slimField"><input class="field" id="street_number"
disabled="true"></input></td>
<td class="wideField" colspan="2"><input class="field" id="route"
disabled="true"></input></td>
</tr>
<tr>
<td class="label">City</td>
<td class="wideField" colspan="3"><input class="field" id="locality"
disabled="true"></input></td>
</tr>
<tr>
<td class="label">State</td>
<td class="slimField"><input class="field"
id="administrative_area_level_1" disabled="true"></input></td>
<td class="label">Zip code</td>
<td class="wideField"><input class="field" id="postal_code"
disabled="true"></input></td>
</tr>
<tr>
<td class="label">Country</td>
<td class="wideField" colspan="3"><input class="field"
id="country" disabled="true"></input></td>
</tr>
</table>
</body>
</html>
Source, with other examples:
https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete-addressform