In firefox, how can I change an existing CSS rule - javascript

In firefox, I have the following fragment in my .css file
tree (negative){ font-size: 120%; color: green;}
Using javascript, how do I change the rule, to set the color to red?
NOTE:
I do not want to change the element.
I want to change the rule.
Please do not answer with something like
...
element.style.color = 'red';

What you're looking for is the document.styleSheets property, through which you can access your css rules and manipulate them. Most browsers have this property, however the interface is slightly different for IE.
For example, try pasting the following in FF for this page and pressing enter:
javascript:alert(document.styleSheets[0].cssRules[1].cssText)
For me that yields the string "body { line-height: 1; }". There are methods/properties that allow you to manipulate the rules.
Here's a library that abstracts this interface for you (cross-browser): http://code.google.com/p/sheetup/

function changeCSSRule (stylesheetID, selectorName, replacementRules) {
var i, theStylesheet = document.getElementById(stylesheetID).sheet,
thecss = (theStylesheet.cssRules) ? theStylesheet.cssRules : theStylesheet.rules;
for(i=0; i < thecss.length; i++){
if(thecss[i].selectorText == selectorName) {
thecss[i].style.cssText = replacementRules;
}
}
};

You can change CSS rules in style sheets through the CSS Object Model (currently known as DOM Level 2 Style). However, if you literally have "tree (negative)" in your style sheet that rule will be dropped and not appear in the Object Model at all.

As there is no HTML element tree I am going to assume that tree is the id or class of another element.
You would first retrieve the DOM element by id:
var tree = document.getElementById("tree");
Now tree represents your DOM element and you can manipulate it any way you like:
tree.style.color = "red";
Here is a great reference for mapping css properties to their javascript equivalent.

I'm not sure you can do actual class/selector overrides. You would need to target each element that used the .tree class and set the CSS. The quickest and easiest way would be through jQuery (or another similar framework):
$('.tree').each(function() { this.style.color = "red"; });
You could even use the built-in CSS functions:
$('.tree').css('color', 'red');
(I did it the first way to show you how standard JS would do it. The $(...) part is jQuery for selecting all elements with the .tree class. If you're not using jQuery, you'd need alternative code.)
If tree is an ID, not a class (there should only be one on the page) so using getElementById should be fine. Your code should look like the other answer.

for( var i in document.getElementsByTagName("tree") ){
document.getElementsByTagName("tree")[i].style.color = "red";
}

As I said in another answer's comment, I've never seen this done how you want. I've only ever targeted elements the same way as the CSS renderer would and changed each element style.
I did see this though: jQuery.Rule
It sounds like it does what you want but the demo causes my browser to flip out a bit. I'd invite you to look at the source to see it really does do what you want, and if you want to use it without jQ, use it as a starting point.
Edit: yes this should work. It works by appending another <style> tag to the page and writing out your overrides within. It's fairly simple to follow if you wanted to port it to plain JS.

For debugging, you can use Firebug to change the CSS rules on-the-fly.

If you want to change the rendered css rules from one page request to the next then some sort of server-side scripting will be required. Otherwise the original style sheet would simply reload at the next page request.
If you want to use an event on the first page to force the server-side action then you can use AJAX to actually change the CSS rule for the user.

"I want to change the rule so that
when I navigate to the next page, I
don't have to make all the changes
again."
It sounds like what you might want then is a remote request ("ajax") back to the server with the request you want to make, and generate a dynamic stylesheet which is sent back to the client?
How/why is this Firefox specific?

I want to change the rule so that when I navigate to the next page, I don't have to make all the changes again.
There are two approaches I can think of here. Namely client side and/or server side.
Client side:
Store the theme setting into cookies and load them up next time by javascript.
Server side:
If your site have an login system, you may also store the user preference into the database and generate the webpages with this inforamtion in mind next time on.
Utimately, you are still writing things like element.style.color =. But, they should get what you want.

Related

Can I use javascript to change individual page css entries (as opposed to swapping stylesheets)?

I know it's possible to change css attributes on elements on the current page:
$('.changeMyStyle').css("color", "#FF0000");
But this won't affect new elements added after the change is made.
I know it's possible to remove, add, or swap out css stylesheets to re-style a page after it's been loaded:
$('link.swappableStylesheet').attr('href', 'path/to/new/style.css');
But this is a poor solution for changing one or two attributes, especially to programmatically-determined values (such as changing color from a colorpicker).
I could probably grab a stylesheet's raw data, search it, and modify it:
var sheet= document.styleSheets[0];
var rules= 'cssRules' in sheet? sheet.cssRules : sheet.rules; // IE compatibility
rules[0].style.padding= '0.32em 2em';
// assumes the first entry in the first stylesheet is the one you want to modify.
// if it's not, you have to search to find the exact selector you're looking for
// and pray it's not in a slightly different order
But that's also a poor solution and requires IE-compatibility hacks.
This linked answer also suggests appending another <style> element and adding css there. That could work for narrow cases, but it's still not ideal (and the answer is 5 years old, so new tools may be available now).
Is there a way to alter the page's css at a selector & attribute level instead of stylesheet level or DOM element level? jQuery and vanilla javascript solutions both welcome, as well as libraries designed to do this specifically. Ideally I'd like something that's as easy and versatile as
$(document).stylesheet('.arbitraryCssSelector.Here').put('color', '#FF0000');
...where .stylesheet('.Here.arbitraryCssSelector') would modify the exact same style entry.
Even Chrome's dev tools just modifies the stylesheet it's using when you make modifications or add new rules. There's not currently a way around it, but you can keep a dedicated stylesheet at the bottom of the page that you update with the newest rules. If it's empty or contains invalid rules it will just fall back to the current stylesheet. If any library exists out there this is how it would do it, and it's very little code.
I think the key to keeping it uncluttered is to simply keep overwriting one stylesheet instead of adding new stylesheets to the DOM.
document.getElementById("dynamic-color").addEventListener("input", function () {
document.getElementById("dynamic-styles").innerHTML = "label { color: " + this.value + " }";
});
label {
color: blue;
}
<label for="#dynamic-color">Change the label's color!</label>
<input id="dynamic-color" />
<style id="dynamic-styles"></style>

Listen to specific changes on contenteditable?

Warning: not duplicate with existing questions, read through
I know I can have an event listen on changes on an contenteditable element.
What I would like is to be able to know what the changes are.
For example:
inserted "This is a sentence." at position X.
deleted from position X to Y.
formatted from X to Y with <strong>
Is that possible? (other than by doing a diff I mean)
The reason for this is to make a WYSIWYG editor of other languages than HTML, for example Markdown.
So I'd like to apply the changes to the Markdown source (instead of having to go from HTML to Markdown).
You may be able to do something with MutationObservers (falling back to DOM Mutation events in older browsers, although IE <= 8 supports neither) but I suspect it will still be hard work to achieve what you want.
Here's a simple example using MutationObservers:
http://jsfiddle.net/timdown/4n2Gz/
Sorry, but there is no way to find out what the changes are without doing a diff between the original content and the modified one when changes occur.
Are you looking for this
var strong=document.createElement("strong");
var range=window.getSelection().toString().getRangeAt(0);
range.surroundContents(strong);
this was for third part
You just need to select what you want to surround using real User interaction.
If you wanna do it dynamically
var range=document.createRange();
range.setStart(parentNode[textNode],index to start[X])
range.setEnd(parentNode[textNode],index to end[Y])
range.surroundContents(strong);
For 2nd Part
range.deleteContents()
1st part can be done by using simple iteration
var textnode=// node of the Element you are working with
textnode.splitText(offset)
offset- position about which text node splitting takes place[here==X]
Two child Nodes have been created of the parent editable Element
Now use simple insertBefore() on parent editable Element Node.
hope you will find it useful
The API you're looking for does not exist, as DOM nodes do not store their previous states.
The data / events you're wishing to get back are not native implementations in any browser Ive come across, and I struggle to think of a datatype that would be able to generically handle all those cases. perhaps something like this:
function getChanges() {
/* do stuff here to analyse changes */
var change = {
changeType : 'contentAdded',
changeStart : 50, /* beginning character */
changeContent : 'This is a sentence'
}
return change;
}
Since you're trying to get custom events / data, you're probably going to need a custom module or micro-library. Either way, to look at the changes of something, you need somehow be aware of what has changed, which can only be done by comparing what it was to what it is now.

Find part of string throughout site and replace with new text

I am still having trouble understanding regex. I am also not even sure if you can target a whole page...but without knowledge of how to format regex, its getting play with it.
I have a trademarked name that appears throughout my page. I'd like to use JS to add a (r) to the end of it every time it appears.
Can jquery/js accomplish this?
$("body").each(function() {
this.innerHTML = this.innerHTML.replace(
'breathe right',
'breathe right(r)');
});
Thanks!
This is a good use case for the CSS :after pseudo-element:
CSS
.product-name:after {
content: " \00AE"; /* add restricted symbol after every element with the product-name class */
}
HTML
<span class="product-name">My Product</span>
Working Demo
The easiest way is to wrap your product name in a span and tag it with a class. I'm not sure if that's less work that just adding the symbol to your markup to begin with, though.
The benefit of this approach is it would allow you to easily apply other styles to your product name, like bolding the text or changing the font color.
You can read more about the :after pseudo-element here.
Yes, but it won't be efficient if you tell jQuery to search the entire document. To make it efficient, you'll need to have jQuery get a specific location to search if you want any efficiency in it.
You don't need jQuery :
document.body.innerHTML = document.body.innerHTML.replace(/breathe right/g, 'breathe right(r)')

jQuery Graceful Degradation

I want to spruce up some areas of my website with a few jQuery animations here and there, and I'm looking to replace my AJAX code entirely since my existing code is having some cross-browser compatibility issues. However, since jQuery is a JavaScript library, I'm worried about my pages not functioning correctly when JavaScript is turned off or doesn't exist in a user's browser.
I'll give an example: Currently, I'm using a pure CSS tooltip to give my users (players, the site is a browser game) information on other users. For example, if the other players in the game satisfy one or more conditions, a target icon is displayed next to their name, and upon hovering over that target icon information regarding the reasons behind the target is displayed. This is useful information, as it helps my players to know who they should plan to attack next in the game.
Currently, I do such tooltips using CSS. I have a parent div that holds the image of the target icon of class "info". I then have a div inside of that with class "tooltip" that, on the hover state of the "info" class that it is contained in, is shown, but on the normal state is hidden. I thought it was rather clever when I read about it, and since no JavaScript is used it works on any CSS compliant browser.
I would like to use jQuery to achieve the same effect, mostly because it would look much cleaner, but also because I believe quick and subtle animations can make such things "randomly appearing" make a lot more sense to the user, especially on the first encounter. I'm just wondering if the two will conflict. This is only one example of this, there are numerous other examples where the inability to use JavaScript would hinder the site.
So what I'm asking I guess is, how does one make a jQuery site degrade gracefully on browsers that do not support JavaScript, but otherwise do support most CSS? My goal is for the site to function on a basic level for all users, regardless of choice in browser. The animation is a good example, but I'm also worried about the more dynamic bits, like the auto-updating with AJAX, etc. Are there any good resources on how to achieve this, or do you have any advice about the best way such degradability could be achieved?
Thanks
PS: Totally irrelevant, but Firefox seems to think that "degradability" isn't a word, but "biodegradability" (with the "bio" prefix) is. Weird...
If you consider the "Cascading Order" of css, could you not just add a css style at the very end of all your previous css definition in order to cancel any css effect you currently have for tooltip effect ?
That css rule would only be declared if Javascript is activated and JQuery detected.
That way, you are sure your css tooltip effect is not in conflict with your JQuery effect.
Something like:
a.info:hover span{ display:none}
with the use of "js_enabled" class to make this css rule conditional.
You also can do it by adding css rule on the fly:
function createCSSRule(rule,attributes)
{
//Create the CSS rule
var newRule = "\n"+rule+"{\n";
for (var attribute in attributes)
{
newRule += "\t" + attribute + ": " + attributes[attribute] + ";\n";
}
newRule += "}\n";
//Inject it in the style element or create a new one if it doesn't exist
styleTag = $E('style[type="text/css"]') || new Element("style").setProperty('type','text/css').injectInside(document.head);
if(window.ie)
{
styleTag.styleSheet.cssText += newRule;
}
else
{
styleTag.appendText(newRule);
}
}
The most simple solution for Separation of CSS and Javascrip is to remove your css class
function jscss(a,o,c1,c2)
{
switch (a){
case 'swap':
o.className=!jscss('check',o,c1)?o.className.replace(c2,c1): <-
o.className.replace(c1,c2);
break;
case 'add':
if(!jscss('check',o,c1)){o.className+=o.className?' '+c1:c1;}
break;
case 'remove':
var rep=o.className.match(' '+c1)?' '+c1:c1;
o.className=o.className.replace(rep,'');
break;
case 'check':
return new RegExp('\\b'+c1+'\\b').test(o.className)
break;
}
}
This example function takes four parameters:
a
defines the action you want the function to perform.
o
the object in question.
c1
the name of the first class
c2
the name of the second class
Possible actions are:
swap
replaces class c1 with class c2 in object o.
add
adds class c1 to the object o.
remove
removes class c1 from the object o.
check
test if class c1 is already applied to object o and returns true or false.
If something can be done completely in CSS I say keep it that way. If lack of javascript in the browser is a concern, then most of the time I show the entire page unaffected.
Say for instance I'm going to use jQuery to toggle an element when a checkbox is clicked. On page load I look at the checkbox and update the element accordingly. If javascript is not enabled the element will still appear and the site will still be usable. Just not as nice.
Man, you have a browser-based game, right? You have less than 1% users with JS disabled! And that 1% is the apocalyptic number because I can BET that you have less than that ;)
Anyhow, if you are really concerned about this, just do the site without any JavaScript. And make it functional 100%. After your site works completely without any JS flavour, just start to improve with jQuery (or any other library; jQuery is the best :P ). But with careful: do not change ANY of you HTML. It's easier than it looks ;)
And yes, if you have things that work without JS (like those tooltips) keep it!

How to store arbitrary data for some HTML tags

I'm making a page which has some interaction provided by javascript. Just as an example: links which send an AJAX request to get the content of articles and then display that data in a div. Obviously in this example, I need each link to store an extra bit of information: the id of the article. The way I've been handling it in case was to put that information in the href link this:
<a class="article" href="#5">
I then use jQuery to find the a.article elements and attach the appropriate event handler. (don't get too hung up on the usability or semantics here, it's just an example)
Anyway, this method works, but it smells a bit, and isn't extensible at all (what happens if the click function has more than one parameter? what if some of those parameters are optional?)
The immediately obvious answer was to use attributes on the element. I mean, that's what they're for, right? (Kind of).
<a articleid="5" href="link/for/non-js-users.html">
In my recent question I asked if this method was valid, and it turns out that short of defining my own DTD (I don't), then no, it's not valid or reliable. A common response was to put the data into the class attribute (though that might have been because of my poorly-chosen example), but to me, this smells even more. Yes it's technically valid, but it's not a great solution.
Another method I'd used in the past was to actually generate some JS and insert it into the page in a <script> tag, creating a struct which would associate with the object.
var myData = {
link0 : {
articleId : 5,
target : '#showMessage'
// etc...
},
link1 : {
articleId : 13
}
};
<a href="..." id="link0">
But this can be a real pain in butt to maintain and is generally just very messy.
So, to get to the question, how do you store arbitrary pieces of information for HTML tags?
Which version of HTML are you using?
In HTML 5, it is totally valid to have custom attributes prefixed with data-, e.g.
<div data-internalid="1337"></div>
In XHTML, this is not really valid. If you are in XHTML 1.1 mode, the browser will probably complain about it, but in 1.0 mode, most browsers will just silently ignore it.
If I were you, I would follow the script based approach. You could make it automatically generated on server side so that it's not a pain in the back to maintain.
If you are using jQuery already then you should leverage the "data" method which is the recommended method for storing arbitrary data on a dom element with jQuery.
To store something:
$('#myElId').data('nameYourData', { foo: 'bar' });
To retrieve data:
var myData = $('#myElId').data('nameYourData');
That is all that there is to it but take a look at the jQuery documentation for more info/examples.
Just another way, I personally wouldn't use this but it works (assure your JSON is valid because eval() is dangerous).
<a class="article" href="link/for/non-js-users.html">
<span style="display: none;">{"id": 1, "title":"Something"}</span>
Text of Link
</a>
// javascript
var article = document.getElementsByClassName("article")[0];
var data = eval(article.childNodes[0].innerHTML);
Arbitrary attributes are not valid, but are perfectly reliable in modern browsers. If you are setting the properties via javascript, than you don't have to worry about validation as well.
An alternative is to set attributes in javascript. jQuery has a nice utility method just for that purpose, or you can roll your own.
A hack that's going to work with pretty much every possible browser is to use open classes like this: <a class='data\_articleid\_5' href="link/for/non-js-users.html>;
This is not all that elegant to the purists, but it's universally supported, standard-compliant, and very easy to manipulate. It really seems like the best possible method. If you serialize, modify, copy your tags, or do pretty much anything else, data will stay attached, copied etc.
The only problem is that you cannot store non-serializable objects that way, and there might be limits if you put something really huge there.
A second way is to use fake attributes like: <a articleid='5' href="link/for/non-js-users.html">
This is more elegant, but breaks standard, and I'm not 100% sure about support. Many browsers support it fully, I think IE6 supports JS access for it but not CSS selectors (which doesn't really matter here), maybe some browsers will be completely confused, you need to check it.
Doing funny things like serializing and deserializing would be even more dangerous.
Using ids to pure JS hash mostly works, except when you try to copy your tags. If you have tag <a href="..." id="link0">, copy it via standard JS methods, and then try to modify data attached to just one copy, the other copy will be modified.
It's not a problem if you don't copy tags, or use read only data. If you copy tags and they're modified you'll need to handle that manually.
Using jquery,
to store: $('#element_id').data('extra_tag', 'extra_info');
to retrieve: $('#element_id').data('extra_tag');
I know that you're currently using jQuery, but what if you defined the onclick handler inline. Then you could do:
<a href='/link/for/non-js-users.htm' onclick='loadContent(5);return false;'>
Article 5</a>
You could use hidden input tags. I get no validation errors at w3.org with this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
<head>
<meta content="text/html;charset=UTF-8" http-equiv="content-type" />
<title>Hello</title>
</head>
<body>
<div>
<a class="article" href="link/for/non-js-users.html">
<input style="display: none" name="articleid" type="hidden" value="5" />
</a>
</div>
</body>
</html>
With jQuery you'd get the article ID with something like (not tested):
$('.article input[name=articleid]').val();
But I'd recommend HTML5 if that is an option.
Why not make use of the meaningful data already there, instead of adding arbitrary data?
i.e. use <a href="/articles/5/page-title" class="article-link">, and then you can programmatically get all article links on the page (via the classname) and the article ID (matching the regex /articles\/(\d+)/ against this.href).
As a jQuery user I would use the Metadata plugin. The HTML looks clean, it validates, and you can embed anything that can be described using JSON notation.
This is good advice. Thanks to #Prestaul
If you are using jQuery already then you should leverage the "data"
method which is the recommended method for storing arbitrary data on a
dom element with jQuery.
Very true, but what if you want to store arbitrary data in plain-old HTML? Here's yet another alternative...
<input type="hidden" name="whatever" value="foobar"/>
Put your data in the name and value attributes of a hidden input element. This might be useful if the server is generating HTML (i.e. a PHP script or whatever), and your JavaScript code is going to use this information later.
Admittedly, not the cleanest, but it's an alternative. It's compatible with all
browsers and is valid XHTML. You should NOT use custom attributes, nor should you really use attributes with the 'data-' prefix, as it might not work on all browsers. And, in addition, your document will not pass W3C validation.
As long as you're actual work is done serverside, why would you need custom information in the html tags in the output anyway? all you need to know back on the server is an index into whatever kind of list of structures with your custom info. I think you're looking to store the information in the wrong place.
I will recognize, however unfortunate, that in lots of cases the right solution isn't the right solution. In which case I would strongly suggest generating some javascript to hold the extra information.
Many years later:
This question was posted roughly three years before data-... attributes became a valid option with the advent of html 5 so the truth has shifted and the original answer I gave is no longer relevant. Now I'd suggest to use data attributes instead.
<a data-articleId="5" href="link/for/non-js-users.html">
<script>
let anchors = document.getElementsByTagName('a');
for (let anchor of anchors) {
let articleId = anchor.dataset.articleId;
}
</script>
I advocate use of the "rel" attribute. The XHTML validates, the attribute itself is rarely used, and the data is efficiently retrieved.
So there should be four choices to do so:
Put the data in the id attribute.
Put the data in the arbitrary attribute
Put the data in class attribute
Put your data in another tag
http://www.shanison.com/?p=321
You could use the data- prefix of your own made attribute of a random element (<span data-randomname="Data goes here..."></span>), but this is only valid in HTML5. Thus browsers may complain about validity.
You could also use a <span style="display: none;">Data goes here...</span> tag. But this way you can not use the attribute functions, and if css and js is turned off, this is not really a neat solution either.
But what I personally prefer is the following:
<input type="hidden" title="Your key..." value="Your value..." />
The input will in all cases be hidden, the attributes are completely valid, and it will not get sent if it is within a <form> tag, since it has not got any name, right?
Above all, the attributes are really easy to remember and the code looks nice and easy to understand. You could even put an ID-attribute in it, so you can easily access it with JavaScript as well, and access the key-value pair with input.title; input.value.
One possibility might be:
Create a new div to hold all the extended/arbitrary data
Do something to ensure that this div is invisible (e.g. CSS plus a class attribute of the div)
Put the extended/arbitrary data within [X]HTML tags (e.g. as text within cells of a table, or anything else you might like) within this invisible div
Another approach can be to store a key:value pair as a simple class using the following syntax :
<div id="my_div" class="foo:'bar'">...</div>
This is valid and can easily be retrieved with jQuery selectors or a custom made function.
In html, we can store custom attributes with the prefix 'data-' before the attribute name like
<p data-animal='dog'>This animal is a dog.</p>.
Check documentation
We can use this property to dynamically set and get attributes using jQuery like:
If we have a p tag like
<p id='animal'>This animal is a dog.</p>
Then to create an attribute called 'breed' for the above tag, we can write:
$('#animal').attr('data-breed', 'pug');
To retrieve the data anytime, we can write:
var breedtype = $('#animal').data('breed');
At my previous employer, we used custom HTML tags all the time to hold info about the form elements. The catch: We knew that the user was forced to use IE.
It didn't work well for FireFox at the time. I don't know if FireFox has changed this or not, but be aware that adding your own attributes to HTML elements may or may-not be supported by your reader's browser.
If you can control which browser your reader is using (i.e. an internal web applet for a corporation), then by all means, try it. What can it hurt, right?
This is how I do you ajax pages... its a pretty easy method...
function ajax_urls() {
var objApps= ['ads','user'];
$("a.ajx").each(function(){
var url = $(this).attr('href');
for ( var i=0;i< objApps.length;i++ ) {
if (url.indexOf("/"+objApps[i]+"/")>-1) {
$(this).attr("href",url.replace("/"+objApps[i]+"/","/"+objApps[i]+"/#p="));
}
}
});
}
How this works is it basically looks at all URLs that have the class 'ajx' and it replaces a keyword and adds the # sign... so if js is turned off then the urls would act as they normally do... all "apps" (each section of the site) has its own keyword... so all i need to do is add to the js array above to add more pages...
So for example my current settings are set to:
var objApps= ['ads','user'];
So if i have a url such as:
www.domain.com/ads/3923/bla/dada/bla
the js script would replace the /ads/ part so my URL would end up being
www.domain.com/ads/#p=3923/bla/dada/bla
Then I use jquery bbq plugin to load the page accordingly...
http://benalman.com/projects/jquery-bbq-plugin/
I have found the metadata plugin to be an excellent solution to the problem of storing arbitrary data with the html tag in a way that makes it easy to retrieve and use with jQuery.
Important: The actual file you include is is only 5 kb and not 37 kb (which is the size of the complete download package)
Here is an example of it being used to store values I use when generating a google analytics tracking event (note: data.label and data.value happen to be optional params)
$(function () {
$.each($(".ga-event"), function (index, value) {
$(value).click(function () {
var data = $(value).metadata();
if (data.label && data.value) {
_gaq.push(['_trackEvent', data.category, data.action, data.label, data.value]);
} else if (data.label) {
_gaq.push(['_trackEvent', data.category, data.action, data.label]);
} else {
_gaq.push(['_trackEvent', data.category, data.action]);
}
});
});
});
<input class="ga-event {category:'button', action:'click', label:'test', value:99}" type="button" value="Test"/>
My answer might not apply to your case. I needed to store a 2D table in HTML, and i needed to do with fewest possible keystrokes. Here's my data in HTML:
<span hidden id="my-data">
IMG,,LINK,,CAPTION
mypic.jpg,,khangssite.com,,Khang Le
funnypic.jpg,,samssite.com,,Smith, Sam
sadpic.png,,joyssite.com,,Joy Jones
sue.jpg,,suessite.com,,Sue Sneed
dog.jpg,,dogssite.com,,Brown Dog
cat.jpg,,catssite.com,,Black Cat
</span>
Explanation
It's hidden using hidden attribute. No CSS needed.
This is processed by Javascript. I use two split statements, first on newline, then on double-comma delimiter. That puts the whole thing into a 2D array.
I wanted to minimize typing. I didn't want to redundantly retype the fieldnames on every row (json/jso style), so i just put the fieldnames on the first row. That a visual key for the programmer, and also used by Javascript to know the fieldnames. I eliminated all braces, brackets, equals, parens, etc. End-of-line is record delimiter.
I use double-commas as delimiters. I figured no one would normally use double-commas for anything, and they're easy to type. Beware, programmer must enter a space for any empty cells, to prevent unintended double-commas. The programmer can easily use a different delimiter if they prefer, as long as they update the Javascript. You can use single-commas if you're sure there will be no embedded commas within a cell.
It's a span to ensure it takes up no room on the page.
Here's the Javascript:
// pull 2D text-data into array
let sRawData = document.querySelector("#my-data").innerHTML.trim();
// get headers from first row of data and load to array. Trim and split.
const headersEnd = sRawData.indexOf("\n");
const headers = sRawData.slice(0, headersEnd).trim().split(",,");
// load remaining rows to array. Trim and split.
const aRows = sRawData.slice(headersEnd).trim().split("\n");
// trim and split columns
const data = aRows.map((element) => {
return element.trim().split(",,");
});
Explanation:
JS uses lots of trims to get rid of any extra whitespace.

Categories

Resources