I have a span which has a predefined value which is initiated on page load.
The user can alter the values by interacting with an input field.
My problem is that all the spans are in a table, and whenever the number is altered
instead of appearing in the exact same spot as the predefined number, it positions itself up like 20px or so.
Any help will be appreciated.
HTML
<table class="tbl1">
<tr>
<td style="overflow: hidden; width: 280px; text-align: left; valign: top"><span class="Cs boxGreen">A</span>
</td>
<td width="18%"><span class="number1Output"></span>
</td>
</tr>
</table>
JS
var currency = "£";
(function ($) {
$(window).load(function () {
$('.number1Output').html($('#number1').val());
});
});
function displayNumber(value, id, id2) {
var output = '.' + id + "Output";
if (value == 0) {
$(output).html('');
$(id2).html("free");
} else {
$(output).html('+' + value + currency + ' ');
$(id2).html(value + currency);
}
}
If you are changing the width of a span/field/window/etc. and the positioning does not look right you might want to use CSS. min-width can help with this.
Related
I'm sorry, i'm very new to develop code. Now I'm doing some homework and want to do something outside of the textbook, but I'm failing ... :)
I created some simple html. Example:
<tr>
<td id="som1">5 + 3 =
<input id="a_som1" type="number" required>
</td>
<td>
<img src="goed.png" alt="goed" title="goed" id="i-s1g">
<img src="fout.png" alt="fout" title="fout" id="i-s1f">
</td>
And it ends with a button:
What I want is when you click on this button, the script checks your answer and either shows the "goed" or the "fout" image.
I hided the images with a css-stylesheet and this code:
img {
width: 35px;
display: none;
}
I tried the following as javascript, however, it doesn't work. (I know this code is probably very stupid, I just tried some things when searching the internet.) I hope someone can help me :):
Oh, and is it necessary to use $(document).ready(function() { . It was in my textbook, but I don't really know if it's necessary...
$(document).ready(function() {
$("#cont").click {
if ($("#a_som1").val() 8 ) {
show("#i-s1g")
}
else {
show("#i-s1f")
}
}
}
Thanks for helping!!
getting all the things i need 1:input 2:gIMAGE 3:fIMAGE & saving them in three variables..
putting eventListener on input of keypress then checking if the is enter,if is enter check if the number is equal to my answer("8").if yes show gimage and hide fimage,
if not hide gimage and show fimage
let input = document.getElementById("a_som1");
let gImg = document.getElementById("i-s1g");
let fImg = document.getElementById("i-s1f");
input.addEventListener("keypress", function(event) {
if (event.key === "Enter") {
if (input.value == 8) {
gImg.style.display = "block"
fImg.style.display = "none"
} else {
fImg.style.display = "block"
gImg.style.display = "none"
}
}
});
img {
width: 35px;
display: none;
}
<tr>
<td id="som1">5 + 3 =
<input id="a_som1" type="number" required>
</td>
<td>
<img src="goed.png" alt="goed" title="goed" id="i-s1g">
<img src="fout.png" alt="fout" title="fout" id="i-s1f">
</td>
</tr>
I use this wildcard in css to select the data containing "," commas.
td[data-content*=","]{
background-color: yellow;
}
Is there a way to make a distinction for the numbers of "," in the data. I can highlight data containing one comma in yellow. I'd like to highlight data containing two commas in green. Is there a way to do this with CSS? Thanks.
I want to use different colors at the same time according to the number of commas data contains. So the data like (1,2) will be yellow. and the data like (1,2,3) will be green.
Here's a jQuery solution:
$('td').each(function() {
var c = $(this).text();
if (!c) return;
var commas = c.split(",").length - 1;
if (commas === 1) $(this).css("background-color", "yellow");
if (commas === 2) $(this).css("background-color", "green");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>a</td>
<td>a,b</td>
<td>a,b,c</td>
</tr>
</tbody>
</table>
Should be pretty self-explanatory:
grab tds
read data-content attribute and count commas
set style
You cannot do this in pure CSS.
The CSS attribute selectors only allow literal matching and no wildcard/glob/regexp matching
See here for a definition: https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors
I have made a VanillaJS solution. In that I count the comma matches in the data-content attribute and add a new data-content-classification attribute with different values depending on number of matches.
console.clear()
// Start after loading of the document
window.addEventListener('load', function() {
// get all the table cells with data-content attribute
var tdContents = document.querySelectorAll('td[data-content]');
// loop over those cells
for (var i = 0; i < tdContents.length; i++) {
// anonymous function which gets a single table cell element as argument
;(function(el) {
// get the attribute's value
var dc = el.getAttribute('data-content')
// react according to the length of the comma matches (with fallback to prevent error)
switch ((dc.match(/,/g) || []).length) {
case 0:
// if no comma found
el.setAttribute('data-content-classification', 0);
break;
case 1:
// if one comma found
el.setAttribute('data-content-classification', 1);
break;
default:
// default, meaning more than one comma
el.setAttribute('data-content-classification', 2);
}
})(tdContents[i]);
}
})
#charset "UTF-8";
td[data-content-classification="1"] {
background-color: yellow;
}
td[data-content-classification="2"] {
background-color: red;
}
td:after,
td:before {
order: -2;
content: "data-content: " attr(data-content);
background-color: goldenrod;
min-width: 50px;
display: inline-block;
margin: 2px;
padding: 2px;
margin-right: 10px;
}
td:after {
order: -1;
content: "data-content-classifiction: " attr(data-content-classification) " ";
}
td {
padding: 3px;
display: flex;
width: 100%;
}
<table>
<tr>
<td>Lorem, ipsum dolor.</td>
</tr>
<tr>
<td data-content="1">Lorem, ipsum dolor.</td>
</tr>
<tr>
<td data-content="1,2">Lorem, ipsum dolor.</td>
</tr>
<tr>
<td data-content="2,3">Eveniet, sunt reiciendis.</td>
</tr>
<tr>
<td data-content="1,2,3">Accusantium, quam impedit.</td>
</tr>
<tr>
<td data-content="1,2,3,5">Accusantium, quam impedit.</td>
</tr>
</table>
Note that this answer contains jQuery notation, and so it will require a jQuery library to work.
What you could do is loop through all your data-content that has a , like you initially wanted with your wildcard selector.
You can then use $(this).attr() to get the contents of your custom attribute.
You can then take that string, turn it into an array using .split(). After that you count the length of the array. Remember to subtract by 1, because arrays count from 0.
You then check for the condition of commas and set your CSS logic by using the css() function.
Example:
function testing() {
$('[data-content*=","]').each(function() {
var myAttr=$(this).attr('data-content');
var myArr=myAttr.split(",");
var countCommas=myArr.length - 1;
var yellow=1;
var green=2;
if(countCommas == yellow) {
$(this).css("background-color", "yellow");
}
else if(countCommas == green) {
$(this).css("background-color", "green");
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td data-content="1,2">
1,2
</td>
</tr>
<tr>
<td data-content="1,2,3">
1,2,3
</td>
</tr>
<tr>
<td>
No color
</td>
</tr>
</table>
<br />
<button onclick="testing();">Test</button>
You don't need to trigger the function via a button click, I just added that for test purposes, so that you could see the effect.
If you want it to run automatically, all you have to do is put it inside a document.ready block.
Example:
$(document).ready(function() {
$('[data-content*=","]').each(function() {
var myAttr=$(this).attr('data-content');
var myArr=myAttr.split(",");
var countCommas=myArr.length - 1;
var yellow=1;
var green=2;
if(countCommas == yellow) {
$(this).css("background-color", "yellow");
}
else if(countCommas == green) {
$(this).css("background-color", "green");
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td data-content="1,2">
1,2
</td>
</tr>
<tr>
<td data-content="1,2,3">
1,2,3
</td>
</tr>
<tr>
<td>
No color
</td>
</tr>
</table>
Scenario:
I have a results table with a checkbox, when the checkbox is checked, the content of the row(actually 2 columns concateneted only, are copied to a new div, with the job code and job name). This works pretty well, and I am avoiding duplicated already.
However, in the new results div, I am creating an anchor tag to remove the div itself.
After the div has been removed, I should be able to add the selected job again with the checkbox.
Please note that there are many jobs in the results table, so putting the flag to false again will not work.
Also if you find a better title for this question, please let me know
//On every checkbow that is clicked
var flag = false;
$("#ctl00_PlaceHolderMain_myGrid input").change(function () {
if (this.checked && flag === false) {
flag = true;
var jobCode = $(this).parent().parent().parent().find("td:eq(2)").text()
var jobName = $(this).parent().parent().parent().find("td:eq(1)").text()
var displayvalue = jobCode.toUpperCase() + " - " + jobName.toUpperCase();
AddSelectedJob(jobCode, displayvalue);
//$(this).unbind('change'); //Unbind the change event so that it doesnt fire again
FillSelectedJobs();
}
});
//Add selected job in the results div
function AddSelectedJob(id, display) {
//create a div for every selected job
$("[id$=ResultsDiv]").append('<div class="selectedjobs" id=' + id + '>' + display + 'Remove selected job</div>');
}
//Removes the selected job from the resutls div
function removeSelectedJob(el) {
$(el).parent().remove();
}
The generated html is like this:
<div>
<div style="height: 300px; overflow: auto; float: left">
<div>
<table cellspacing="0" cellpadding="4" id="ctl00_PlaceHolderMain_myGrid" style="color:#333333;width:100%;border-collapse:collapse;">
<tr style="color:White;background-color:#5D7B9D;font-weight:bold;">
<th scope="col"> </th><th scope="col">JobCode</th><th scope="col">JobName</th><th scope="col">JobPartner</th><th scope="col">JobManager</th><th scope="col">ClientName</th>
</tr><tr style="color:#333333;background-color:#F7F6F3;">
<td>
<input id="ctl00_PlaceHolderMain_myGrid_ctl02_CheckBox1" type="checkbox" name="ctl00$PlaceHolderMain$myGrid$ctl02$CheckBox1" />
</td><td>jobcode01</td><td>jobname</td><td>xx</td><td>xx</td><td>xx</td>
</tr>
</table>
</div>
</div>
<div style="margin-top: 0px; margin-left: 10px; float: left">
<span>Selected :</span>
<div id="ResultsDiv" style="margin-top: 0px">
</div>
</div>
Firstly I suggest some changes to your HTML. Separate out the styles from your DOM and place them in classes.
This makes sure there is separation of concerns
HTML
<div>
<div class="divMain">
<div>
<table cellspacing="0" cellpadding="4"
id="ctl00_PlaceHolderMain_myGrid" class="table">
<tr class="rowHead">
<th scope="col"> </th>
<th scope="col">JobCode</th>
<th scope="col">JobName</th>
<th scope="col">JobPartner</th>
<th scope="col">JobManager</th>
<th scope="col">ClientName</th>
</tr>
<tr class="row">
<td>
<input id="ctl00_PlaceHolderMain_myGrid_ctl02_CheckBox1"
type="checkbox"
name="ctl00$PlaceHolderMain$myGrid$ctl02$CheckBox1"
data-flag="false" />
</td>
<td>column1</td>
<td>column2</td>
<td>column3</td>
<td>column4</td>
<td>column5</td>
</tr>
</table>
</div>
</div>
<div class="m0 selected">
<span>Selected :</span>
<div id="ResultsDiv" class="m0"></div>
</div>
CSS
.divMain{
height: 300px;
overflow: auto;
float: left
}
.table{
color:#333333;
width:100%;
border-collapse:collapse;
}
.rowHead{
color:White;
background-color:#5D7B9D;
font-weight:bold;
}
.row{
color:#333333;
background-color:#F7F6F3;
}
.m0{
margin-top: 0px;
}
.selected{
margin-left: 10px;
float: left
}
Javascript
$("#ctl00_PlaceHolderMain_myGrid input").change(function () {
// Next cache your selector
// so that you need not crawl the DOM multiple times
var $this = $(this),
$row = $this.closest('.row'),
currFlag = Boolean($this.data('flag'));
// As there might be multiple jobs , a single flag variable
// will not work. So you can set a data-flag attribute on the
// input that stores the current value
if (currFlag === false && this.checked) {
// Set the corresponding flag to true
$this.data('flag', true);
var jobCode = $row.find("td:eq(2)").text(),
jobName = $row.find("td:eq(1)").text(),
displayvalue = jobCode.toUpperCase() + " - "
+ jobName.toUpperCase(),
inputId = $this.attr('id')
// Pass the input name too as you need to set the value of
// the corresponding flag value again as you can add it multiple times
AddSelectedJob(jobCode, displayvalue, inputId);
FillSelectedJobs();
}
});
//Add selected job in the results div
function AddSelectedJob(id, display, inputId) {
//create a div for every selected job
// Use the inputId to save it as a data-id attribute
// on anchor so that you can set the value of the flag after
// removing it
var html = '<div class="selectedjobs" id=' + id + '>' + display ;
html += '<a href="javascript" data-id="'+ inputId
+'">Remove selected job</a></div>';
$('[id$=ResultsDiv]').append(html);
}
// Remove the inline click event for the anchor and delgate it to the
// static parent container
$('[id$=ResultsDiv]').on('click', 'a', function(e) {
var $this = $(this),
$currentCheckbox = $this.data('id');
// Set the flag value of the input back to false
$('#'+ $currentCheckbox).data('flag', false);
e.preventDefault(); // prevent the default action of the anchor
$this.closest('.selectedjobs').remove();
});
function FillSelectedJobs() {
//save values into the hidden field
var selectedJobs = $("[id$=ResultsDiv]").find("[class$='selectedjobs']");
var returnvalue = "";
for (var i = 0; i < selectedJobs.length; i++)
returnvalue += selectedJobs[i].id + ";";
$("[id$=HiddenClientCode]").val(returnvalue);
}
Check Fiddle
Here is my code. I have tried everything I can think of. I have tried using just div ID's and have now tried classes. Nothing seems to work. I just want the number 2 not to be visible if there is no entry beside it. It doesn't matter if it is in a table or not.
Thanks.
<style type="text/css">
<!--
.leftone {
float: left;
height: auto;
width: auto;
}
.rightone {
float: left;
height: auto;
width: auto;
}
.lefttwo {
float: left;
height: auto;
width: auto;
}
.righttwo {
float: left;
height: auto;
width: auto;
}
-->
</style>
<table width="400" border="0" cellpadding="0" cellspacing="3" id="tableONE">
<tr>
<td width="200" height="50"><div class="leftone">1.)</div></td>
<td width="200" height="50"><div class="rightone">The Number One</div></td>
</tr>
<tr>
<td width="200" height="50"><div class="lefttwo">2.)</div></td>
<td width="200" height="50"><div class="righttwo"></div></td>
</tr>
</table>
<p> </p>
<script type="text/javascript">
<!--
function shownumbers() {
var myNum1 = '[.rightone]';
if(myNum1 != ''){
document.getElementById('.leftone').style.display = "block";
}
else if(myNum1 == ''){
document.getElementById('.leftone').style.display = "none";
}
var myNum2 = '[.righttwo]';
if(myNum2 != ''){
document.getElementById('.lefttwo').style.display = "block";
}
else if(myNum2 == ''){
document.getElementById('.lefttwo').style.display = "none";
}
}
//-->
</script>
You cannot use getElementById with classes. Also, you don't need the '.' or '#' when using these methods in javascript. Below should do what you are asking. Although if there is only ever 1 item of class 'rightone' and 'leftone' you should use ID's.
var myNum1 = document.getElementsByClassName('rightone')[0].innerHTML;
if(myNum1 != ''){
document.getElementsByClassName('leftone')[0].style.display = 'block';
} else if(myNum1 == ''){
document.getElementsByClassName('leftone')[0].style.display = 'none';
}
A more elegant solution would be:
HTML:
<table width="400" border="0" cellpadding="0" cellspacing="3" id="tableONE">
<tr>
<td><div class="left">1.)</div></td>
<td><div class="right">The Number One</div></td>
</tr>
<tr>
<td><div class="left">2.)</div></td>
<td><div class="right"></div></td>
</tr>
</table>
JS:
var right = document.getElementsByClassName('right');
for(var i=0;i<right.length;i++){
if(!right[i].innerHTML){
right[i].parentNode.parentNode.getElementsByClassName('left')[0].style.display = 'none';
} else {
right[i].parentNode.parentNode.getElementsByClassName('left')[0].style.display = 'right';
}
}
Kinda similar to Jason's, but I spent the time so I'mma post it. ;)
JSFiddle: http://jsfiddle.net/H3UNH/1/
HTML:
<table id="tableONE">
<tr>
<td width=50>1.)</td>
<td >The Number One</td>
</tr>
<tr>
<td>2.)</td>
<td></td>
</tr>
</table>
(I do still like the width attribute for cells in tables; it can be moved to CSS but this is one of those exceptions for me where the markup and presentation can have a tiny bit of overlap. Move everything else to CSS. Your mileage may vary.)
CSS:
td { padding: 3px; text-align:left; height: 50px;}
JavaScript:
function shownumbers() {
var rows = document.getElementsByTagName('tr');
for(var i=0,len=rows.length;i<len;i++) {
var _this = rows[i];
var rowCells = _this.getElementsByTagName('td');
if(rowCells[1].innerHTML == "") {
_this.style.display = "none";
}
}
}
shownumbers();
(for the purpose of the demo, I just separately call shownumbers. If you want it to be automatic, make it self-invoking. Otherwise call it from wherever it makes sense)
I think the more important lesson here isn't the JavaScript, actually. ;) I understand that not everyone is writing perfect JavaScript (heck, mine's not perfect either). But you really need to understand the purpose of CSS and classes in general to write good maintainable markup and presentation for the web! I hope that doesn't sound too condescending or anything; it wasn't meant to be.
By using the :empty selector.
var els = document.querySelectorAll('td div:empty'),
i = els.length,
el;
for(;i--; ) {
el = els[i];
do {
el = el.parentNode;
} while ( el.nodeName != 'TR' )
el.style.display = 'none';
}
Fiddle: http://jsfiddle.net/uAUt8/
I'm trying to do dynamic sortable list with link "Add Destination" such as Google - Get directions screenshot below. Big problem is that in sorted inputs sequence IDs should be maintained and the contents changed after draging. Input is able to drag before "A" and last, remove by "x" right field. Adding additional waypoints, judging by this: directions-waypoints tutorial should be get as array in JavaScript, waypoints is always middle "A" and last fields, input point "A" always name eg. "from", last "goal". I would like to do latter fields filling by autosuggestion from Google places. I was looking everywhere for some solution but its is too different.
EDIT: I collected everything from different sources end I got in result not quite good code: jsfiddle.net/fasE5/5/
Here is a complete working example: http://jsfiddle.net/fasE5/19/
The HTML I came up with:
<div id="sortable" class="isOnlyTwo">
<div class="destination">
<span class="handle">A</span>
<input type="text" name="dest1" value="" />
×
</div>
<div class="destination">
<span class="handle">B</span>
<input type="text" name="dest2" value="" />
×
</div>
</div>
Add Destination
And the CSS, to make it look a little more pretty:
#add_input
{
text-decoration:none;
color:#15C;
margin-left:35px;
}
#add_input:hover
{
text-decoration:underline;
}
.placeholder
{
border:2px dashed #bfbfbf;
margin:5px;
width:240px;
}
.handle
{
background-color:#06B500;
border:2px solid #3D7311;
cursor:n-resize;
padding:0 3px;
border-radius:99px;
font-size:12px;
}
.destination
{
margin:5px 15px;
}
.destination input
{
border:1px solid #B9B9B9;
width:200px;
}
#sortable.isOnlyTwo .remove_input
{
display:none;
}
.remove_input
{
color:#999;
text-decoration:none;
font-weight:bold;
}
.remove_input:hover
{
color:#666;
}
.destination.ui-sortable-helper
{
opacity:0.8;
filter:alpha(opacity=80);
}
.destination.ui-sortable-helper .remove_input
{
display:none;
}
To keep the right order of the input's name attribute and the order letters (A, B, C...), we call to RecalculateOrder on sort update and when removing an destination.
To prevent from removing the last 2 destinations, we add an isOnlyTwo class to the #sortable div when there is only 2 destinaitons left. Which thanks to our CSS hides the remove_input.
For the autocomplete we need GoogleMaps API
<script src="//maps.googleapis.com/maps/api/js?sensor=false&libraries=places" type="text/javascript"></script>
Which provides us an new google.maps.places.Autocomplete(input) to add google's autocomplete functionality.
$(function(){
$("#sortable").sortable({
containment: "document",
placeholder: 'placeholder',
handle: ".handle",
axis: "y",
update: RecalculateOrder,
forcePlaceholderSize: true
});
$("#add_input").click(function () {
var inputIndex = $("#sortable > .destination").length;
// Building the new field's HTML
var html = '<div class="destination">';
html += '<span class="handle">' + String.fromCharCode(inputIndex + 65) + '</span> ';
html += '<input type="text" name="dest' + (inputIndex + 1) + '" value="" /> ';
html += '×';
html += '</div>';
var newField = $(html);
newField .find(".remove_input").click(RemoveInput);
$("#sortable").append(newField ).removeClass("isOnlyTwo");
// Adding autocomplete to the new field
BindAutoComplete(newField.find("input")[0]);
return false;
});
$(".remove_input").click(RemoveInput);
// Adding autocomplete to the first two fields
$("#sortable input").each(function(){
BindAutoComplete(this);
});
function RemoveInput()
{
$(this).parent().remove();
RecalculateOrder();
var isOnlyTwo = $("#sortable > .destination").length == 2;
$("#sortable").toggleClass("isOnlyTwo", isOnlyTwo);
return false;
}
// Recalculating from scratch the fields order
function RecalculateOrder()
{
$("#sortable .handle").text(function(i) {
return String.fromCharCode(i + 65);
});
$("#sortable input").attr("name", function(i){
return "dest" + (i + 1);
});
}
function BindAutoComplete(input)
{
var autocomplete = new google.maps.places.Autocomplete(input);
}
});