My problem is about DIV attributes in JavaScript.
DIV cannot have value attribute, but I need to make it have some "value" to hold the i variable.
Here's an example of what I have:
for (i = 1; i <= endDate; i++) {
if (i === today.getDate() && dt.getMonth() === today.getMonth() && dt.getFullYear() === today.getFullYear()) {
cells += "<div class='today'>" + i + "</div>";
} else {
cells += "<div onclick='dayChanger()' value='i'> " + i + "</div>";
}
}
function dayChanger(obj) {
dt.setDate(obj.value);
}
Well a div can have a value attribute, but it is less common. You should just use data-* attributes.
For example: <div ... data-value='i'>.
Then in your handler, you can access it like to:
obj.getAttribute("data-value")
// or, if you are not targeting dinosaur browsers:
obj.dataset.value
Also, you might consider building the div as an element instead of interpolating, but that is just personal taste. For this small example, it is fine.
Related
I'm currently using JS to fetch data from a JSON file and loop through it to display on the site, appending to a div in the html file i.e.
<div id = "groceries"></div>
JS code (skipping fetch code which works fine):
function appendData (data) {
const mainContainer = document.getElementById ('groceries');
for (let i = 0; i < data.length; i++) {
const div = document.createElement ('div');
div.innerHTML = '<b>' + data[i].item + '</b> x' + data[i].quantity + ' ' + data[i].calories + '<b> - ' + data[i].rating + '<br><br>';
mainContainer.appendChild (div);
}
}
The 'rating' data needs to be styled depending on what the rating is, i.e. green for 'Low', amber for 'Medium', red for 'High'...based on what's in the JSON file.
I'm not sure how to do this with pure JS / html / css however? I've tried searching around but it's surprisingly difficult to find a suitable answer.
Add a class based on the rating value. Aka
function appendData(data) {
const mainContainer = document.getElementById ('groceries');
for (let i = 0; i < data.length; i++) {
const div = document.createElement ('div');
div.classList.add('rating', 'rating--' + (data.rating < 3 ? 'low' : data.rating > 6 ? 'high' : 'med'));
div.innerHTML = '<b>' + data[i].item + '</b> x' + data[i].quantity + ' ' + data[i].calories + '<b> - ' + data[i].rating + '<br><br>';
mainContainer.appendChild (div);
}
}
Then in CSS you can simply do
.rating {
// Generic styling
}
.rating.rating--low {
color: #FF0000;
// Unique Styles
}
.rating.rating--med {
color: #FFFF00;
// Unique Styles
}
.rating.rating--high {
color: #00FF00;
// Unique Styles
}
I don't know if I get it right, but you can use simple if statement with prebuilded HTML DOM style object.
if(data[i].quantity > average){
div.style.color = "red"
}else if(data[i].quantity < average){
div.style.color = "green"
}
Hope I have helped.
Inside for loop, make a condition check to add a preferred text color,
If (data[i].rating === "High")
{div.style.color = "red"}
// and so on other conditions checked.
If (???) {...}
This example will make all text in div to be red.
If only rating portion to be color, maybe create p and multiple span(s). Then style each of them as preferred. ie.
<p style?><span style?><span style?><span style?>
I am working with some code from BioJS of which I'd like to extend the functionality. A BioJS object forms a sequence display by creating a separate span element for each letter and creating a break after x number of letters as such (simplified):
` var j=1;
for (var i=1; i <= a.length; i++) {
if( i % opt.numCols == 0) {
str += '<span class="sequence" id="' + this.getId() + '_' + i + '">' + a[i-1] + '</span>';
str += '<br/>';
j = 1;
} else {
str += '<span class="sequence" style="'+spaceStyle+'" id="' + this.getId() + '_' + i + '">' + a[i-1];
str += ( j % opt.numColsForSpace == 0)? ' ' : '';
str += (opt.spaceBetweenChars)? ' ' : '';
str += '</span>';
j++;
}
}`
This is nice for the built-in functionality of adding highlights to specific coordinates, which just uses jQuery to find the appropriate span and change the css. I've tried to take a similar approach with hiding elements by changing them to display:none, but unfortunately this leaves the line breaks behind, and thus big holes in the text. See a picture here:
Showing/Hiding
I'd like to know if there is another way I could create a similar display that would allow me to retain the fixed-width output after hiding the elements. Ideally I would still be able to use the highlight function, but I could also re-code that as well to work in a different way.
I found the source of the problem, which was that the javascript from BioJS was adding an inline style of whitespace: pre that was preventing the span elements from wrapping within the container. It was causing the containing element to only break on line breaks.
Please tell me solution of this problem.
I am creating 5 dynamic divs and their ids using a for loop. I want to get the the loop counter value and each of the created div's html in the format "counter: html" like 1:123. Right now I am getting only the loop counter value.
<html>
<div id="feed"></div>
</html>
<script>
for (var i = 1; i <= 5; i++) {
$('#feed').append('<div id="news' + i + '" value='
123 '/>');
var abc = $("#news" + i).attr("value");
console.log(abc);
}
</script>
Thanks in advance.
Try this.
$(document).ready(function() {
for (var i = 1; i <= 5; i++) {
$('#feed').append('<div id="news' + i + '" value="123"></div>');
//and I want to get the value of dynamic created div using this code but I am getting only the loop counter value. Please help me to get this answer.
var abc = $("#news" + i).attr('value');
console.log(abc + " : " + i);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<html>
<div id="feed"></div>
</html>
This snippet doesn't even work for me, this however, does:
for (var i = 1; i <= 5; i++) {
$('#feed').append('<div id="news' + i + '" value="123"/>');
var abc = $("#news" + i).attr("value");
console.log(abc);}
I simply changed the single quotes of value='123' to double quotes: value="123".
Don't use ids use a class
'<div id="news' + i + '" value='123'/>' should be '<div class="news">123</div>'
Use .html() not .attr("value")
for (var i = 0; i <= 4; i++) {
$('#feed').append('<div class="news">123</div>');
var abc = $('.news').eq(i).html(); // gets the html of the div with the class "news" at the index supplied by `i`, keep in mind that arrays are 0 based so 0 is the first, 1 is the second....
console.log((i+1)+':'+abc);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="feed"></div>
updating the answer as per the updated question. This code will work for you. Give it a try.
for (var i = 1; i <= 5; i++) {
$('#feed').append('<div id="news' + i + '">'+ i +': Test</div>');
}
But I tell you again not to use the value tag, you already have your counter in id so split it fro there if you want.
Cheers!!
You're using id's. You can't use an id on multiple divs, so you need to use class.
Not quite sure what you want, and div tag not supposed have value attribute, if you want to add your defined attribute use data-my_attribute instead. In your code, everything is ok except for this code :
Change this :
$('#feed').append('<div id="news' + i + '" value='123'></div>');
into this :
$('#feed').append('<div id="news' + i + '" value="123"></div>');
Firstly, I was trying to replace some contents in a div container using html() in Javascript on click. The problem using this approach is it only put the last value in the array.
So, I used append() instead. But it doesn't work like what I have expected. Well, it does append text in the for loops, but after a click, it just appends the content without removing the previous content like what html() does.
Here is how I implement it:
<div id="events-content"></div>
// using Responsive Calendar js
onMonthChange: function(events) {
for (var eventsDate in options.events) {
if (eventsDate.indexOf(monthKey) != -1) {
var monthEvents = options.events[eventsDate];
for(i = 0; i < options.events[eventsDate].dayEvents.length; i++) {
$('#events-content').append(
'<p><b>' + eventsDate + ':</b> ' +
monthEvents.dayEvents[i].name + '<br/></p>');
}
}
}
},
...
How do I replace the previous appended text using Javascript?
I'm using this in Responsive Calendar JS
well, you could do something like this...
Prepare all the markup in the loop.
var html = "";
for(i = 0; i < options.events[eventsDate].dayEvents.length; i++) {
html += '<p><b>' + eventsDate + ':</b> ' +
monthEvents.dayEvents[i].name + '<br/></p>';
}
$('#events-content').html(html);
Clear the html before the for loop/append mechanism.
Use .empty()
onMonthChange: function(events) {
$('#events-content').empty() //or $('#events-content').html('');
for (var eventsDate in options.events) {
if (eventsDate.indexOf(monthKey) != -1) {
var monthEvents = options.events[eventsDate];
for(i = 0; i < options.events[eventsDate].dayEvents.length; i++) {
$('#events-content').append(
'<p><b>' + eventsDate + ':</b> ' +
monthEvents.dayEvents[i].name + '<br/></p>');
}
}
}
},
The above screengrab is from Firefox. The cursor is hovering over the yellow spot at the left hand side of the image. It is an <img> element (well actually it's an image together with an image map containing a single circular <area> element, but I assume this distinction is unimportant) that has been created and styled in JavaScript, including the application of a title attribute (constructed by cutting and gluing strings). How can I get this to behave and show the intended character, an en dash, instead of –? It works for innerHTML (the text "Barrow-In-Furness" in the top middle-left is a div that was also created using JavaScript, and its innerHTML set.)
Edit: In response to question of Domenic: Here is the JavaScript function that builds and applies the title attribute (in addition to performing other jobs):
var StyleLinkMarker = function (LinkNumber, EltA, EltI) {
var AltText = LocationName[LinkStart[LinkNumber]] +
" to " +
LocationName[LinkEnd[LinkNumber]];
if (!EltA) {
EltA = document.getElementById("link_marker_area" + LinkNumber);
EltI = document.getElementById("link_marker_img" + LinkNumber);
}
if (LinkStatus[LinkNumber] === 9) {
var CanBuyLinkCode = BoardPreviewMode ? 0 : CanBuyLink(LinkNumber);
if (CanBuyLinkCode === 0) {
EltI.src = ImagePath + "icon-buylink-yes.png";
AltText += " (you can buy this " + LinkAltTextDescription + ")";
} else {
EltI.src = ImagePath + "icon-buylink-no.png";
AltText += " (you cannot buy this " + LinkAltTextDescription;
AltText += CanBuyLinkCode === 1 ?
", because you aren't connected to it)" :
", because you would have to buy coal from the Demand Track, and you can't afford to do that)";
}
} else if ( LinkStatus[LinkNumber] === 8 ||
(LinkStatus[LinkNumber] >= 0 && LinkStatus[LinkNumber] <= 4)
) {
EltI.src = ImagePath + "i" + LinkStatus[LinkNumber] + ".png";
if (LinkStatus[LinkNumber] === 8) {
AltText += " (orphan " + LinkAltTextDescription + ")";
} else {
AltText += " (" +
LinkAltTextDescription +
" owned by " +
PersonReference(LinkStatus[LinkNumber]) +
")";
}
} else {
throw "Unexpected Link Status";
}
EltA.alt = AltText;
EltA.title = AltText;
};
LocationName is as follows:
var LocationName = [
"Barrow–In–Furness", "Birkenhead", "Blackburn", "Blackpool",
"Bolton", "Burnley", "Bury", "Colne",
"Ellesmere Port", "Fleetwood", "Lancaster", "Liverpool",
"Macclesfield", "Manchester", "The Midlands", "Northwich",
"Oldham", "Preston", "Rochdale", "Scotland",
"Southport", "Stockport", "Warrington & Runcorn", "Wigan",
"Yorkshire"
];
You aren't setting the title attribute, you are setting the title property, which expects text and not HTML (although the setAttribute method also expects a text string).
Generally speaking, when dealing with DOM manipulation, you provide text and not HTML. .innerHTML is the notable exception to this rule.
Here's an easy way to convert from HTML to text:
function convertHtmlToText(value) {
var d = document.createElement('div');
d.innerHTML = value;
return d.innerText;
}
Your code could then be updated to this:
EltA.title = convertHtmlToText(AltText);