How can I implement pseudo-dynamic css? - javascript

Im having trouble with managing custom colored elements on the page.
For example, we have 100 navigation squares on the page, each one has its own color, cant think of any way except of creating css classes for each type of color. Which will produce LOTS of css code.
Need some help with this,
Thanks
*added javascript & jquery tags as one of the possible ways of solving this question
Update:
Thanks for responses guys, feeling like I need to get into details.
Im having squared category navigation on my search page, colors can go from server side or can be stored in client's js.
Im getting list of categories from server (lets assume im getting color for each one too)
Then Im building all squares (they are white by default, but on :hover they change their color)
So I would go for such solution:
<ul id="squares">
<li class="greencolor"></li>
<li class="redcolor"></li>
<li class="bluecolor"></li>
</ul>
with css:
#squares li.redcolor:hover{
background:red;
}
#squares li.greencolor:hover{
background:green;
}
#squares li.bluecolor:hover{
background:blue;
}
Hopefully now you can see what I was talking about referring tons of css code for 100 elements.
And yes, I understand that I can go for such solution:
var colorsMap={'redcolor':'red','greencolor':'green'};
$('#squares li').on('hover',function(e){
$(this).css('background-color', colorsMap[$(this).attr('class')];
});
but this doesnt sound as an elegant solution to me and Im trying to find way to make it through css, not inline css changes by js

Although I recommend to use CSS to achieve it, but there's still a solution better than inline style:
var selector = '#squares li'
, css = []
, style = document.createElement( 'style' )
, colorsMap= {
'redcolor': 'red',
'greencolor': 'green',
'bluecolor': 'blue'
}
$( selector ).each( function() {
css.push( selector +
'.' +
// recommand to use data-attr to store color info
// assuming `className == 'bluecolor'`
this.className +
':hover' +
'{' +
'background:' +
colorsMap[ this.className ] +
'}'
)
})
style.textContent = css.join('')
document.head.appendChild( style )
By dynamic insert CSS into <head>, you still get the benefits from normal CSS, demo.
And, you also can generate dynamic CSS file in back-end side, it's more easier to manage colors, by a configuration form or something else.

First,my English is poor(But I'm trying my best to learn).So I can't say that I understand you clearly.But what you say let me think of the chooser.I didn't know if it is you want,but I think it's not a bad idea. Just like these:
$(":header").css("color","#FF00FF");
$("div:contains('test')").css("background","#666600");
$("div:empty").css("background","#888800");
$("div:has(span)").css("background","#008080");
etc.
Their role's I won't say it.I think it nessary for to learn, they are very useful.

Related

JS querySelector + ID with dynamic values

Im trying to make a simple quiz with a dynamic questions using Jinja (so a bit of python as well) + some SQL + JS.
Since im quite new to this, I was trying to do a simple "click here -> change color to green if your answer is the right one"
Here's the thing: to not complicate things, i want every answer to change the color to red (if wrong) or green (if right). Right know, thanks to this thread Javascript getElementById based on a partial string i manage to create a function that turns the right answer to green wih the code, no matter where the user clicks (as long its inside the question box answers):
document.querySelector('[ id$="{{ question.correct_answer }}"]').style.backgroundColor="rgb(0, 221, 135)";
I thought i could do something like "id$!=" and that would solve my problem, but that didnt work. So i tried to search for other stuff like the :not or not() selectors, but that showed me a lot of jquery stuff, which im not studying/learning right now. So, is there any way to write:
"if the id$ does not match the value {{ question.correct_answer }}, turn red" in plain JS?
Some important stuff about the code:
All answers have id="answer_a", "answer_b" etc.
That matches the way i save que "correct_answer" in the database, which comes exactly like the ID (so if the correct_answer is answer_d, i can call "{{ question.correct_answer }}" and that will always turn D into GREEN;
my HTML looks like <div class=question_answer id="answer_d" onclick="selecResposta()"> {{ question.answer_d }} </div> <br>. These are inside a DIV called "question_options" which i can also put the "onclick" function and everything works the same.
I can provide more information if necessary.
Thanks a lot for the help and sorry if this is something easy to solve. Any guidance (if you dont wanna say the answer) is quite welcome as well.
UPDATE:
Thanks to #connexo and #Vijay Hardaha, i manage to mix both answers and create a code that helped me. It might not be pretty, but its doing what i want so its perfect. Here's the solution:
html part:
<div class=question_answer data-answer="answer_a"> {{ question.answer_a }} </div> <br>
etc.etc
js:
function selecRightAnswer() {
document.querySelector("[data-answer={{ question.correct_answer }}]").style.backgroundColor="rgb(0, 221, 135)";
}
function selectWrongAnswer() {
const elements = document.querySelectorAll("div.question_answer:not([data-answer={{ question.correct_answer }}])");
elements.forEach(function (element) {
element.style.backgroundColor = "red";
});
}
Selects div with class question_answer when div has id=answer_a with an exact match.
document.querySelector("div.question_answer[id=answer_a]");
Selects div with class question_answer when div doesn't have id=answer_a with an exact match.
document.querySelector("div.question_answer:not([id=answer_a])");
document.querySelector will only selector first matched div. so if you have to work with all
unmatched with answer_a then you need to use document.querySelectorAll
and then you'll have to loop reach element and work with each element inside the loop.
Example
const elements = document.querySelectorAll(".box");
elements.forEach(function (element) {
element.style.color = "green";
});

.js, css or html - how change object to two different colors?

I ask participants yes/no questions in an experiment and they answer by keypress (Y/N). Now, I want to display YES green and NO red.
I'm doing this with Ibex farms where you have an experiment file in .js format. In this file, one defines the "Question controller" as follows:
"Question", {
as: [["Y","Yes"],["N","No"]], //defines keys+answer displays
}
Adding html tags <font-size>, <div style> in this line did not work.
Besides that, there is a .css file in which I can change the color for both answers, but give the same color to both:
span.Question-fake-link {
color: #ff6600; //changing this to red; both Yes and No are red now
cursor: pointer;
}
The third file is a Question.js file which defines behavior and properties of the question controller beyond its appearance. It is too long to post here, I think, and I don't have authorship. But in there, the answers are defined as "left Comment" and "right Comment". So I attempted to add the 4th line at the (I hope) relevant place:
var lcd = $(document.createElement("li"))
.addClass(this.cssPrefix + "scale-comment-box")
.append(this.leftComment);
.document.getElementById("leftComment").style.color = "red"; //added this, made experiment dysfunctional
this.xl.append(lcd);
Does anyone know how to change the colours individually?
I'm sorry, I know this must look complicated, but maybe someone can give me a pointer on what to do...If you need more of the scripts, please let me know.
Many thanks.
EDIT: After trying out some of the suggestions here, I see the answers are somehow as "span.fake-link". Maybe this code snippet can help (line 1/2):
var a = $(document.createElement("span")).addClass(this.cssPrefix + "fake-link");
__Question_answers__[i] = ans;
__Question_callback__ = function (i) {
var answerTime = new Date().getTime();
var ans = __Question_answers__[i];
var correct = "NULL";
if (! (t.hasCorrect === false)) {...}
}
But how can I replace "span" or "fake-link"? I guess I have to replace both. Removing the span.fake-link properties in css-files doesn't seem to help.
EDIT: Or could this be the problem?
if ((this.presentAsScale || this.presentHorizontally) && this.leftComment) {
var lcd = $(document.createElement("li"))
.addClass(this.cssPrefix + "scale-comment-box")
.append(this.leftComment)
.appendTo(this.xl)
this.xl.append(lcd);
}
I attempted to replace "scale-comment-box" by "red" (defined as a class in css before), but that also doesn't help.
You could probably use jquerys css function:
$("<li>")
.addClass(this.cssPrefix + "scale-comment-box")
.css({color:"red"})
.append(this.leftComment)
.appendTo(this.xl);
Since you're already using Javascript, is it feasible for you to add two extra css classes?
One could be .red and the other, .green and then append those classes to the element accordingly at creation:
//CSS
.red{
color:#F00;
}
.green{
color:#0F0;
}
//javascript
//Your javascript seems to be a mix of jQuery and JS so I assume jQuery is imported. If this is incorrect, you would need to use a raw javascript solution
//Hint: Look at document.getElementsByClassName and .classname += "red"
//jQuery version:
$("li").addClass("red") //for any items that need to be red. replace red with green for the green items

Randomising Color Selection in Wordpress

I'm using the construct theme on Wordpress. I would like to make it such that the top_title class changes color everytime the page is refreshed. I am not sure whether to edit the stylesheet or to place it in some unknown php file, I have tried a lot of suggestions from this site but none seem to work, in the stylesheet, this is what appears for the top_title class:
.top_title {background: #hexval}
Any suggesitons are welcome, but please be thorough, I am rather new at this particular section.
P.S. Also if possible I would like to choose the colors myself.
I would definitely suggest picking your own colors.
Probably the easiest way to accomplish this is to create 1) an array of color codes, 2) choose your HTML element to target (in this case, .top_title), and 3) call a random position in that array.
So if you really want to use JS something like this in your header:
<script> var colorArray = ["ffffff", "cccccc"]; </script>
Then this in your HTML element:
<div class='top_title' style="background:<script>colorArray[Math.floor(Math.random() * colorArray.length)];</script>">
I think that is what you are looking to do?
Try this
jsfiddle http://jsfiddle.net/harshdand/f4p7dj3g/ everytime you run you will get a new color
var colors = ['ababab','cc66ff','fefefe','ff0000','ff9900']; //colors array
//randomly pick color
var random_color = colors[Math.floor((Math.random() * colors.length))];
//add color as background color
$('.top_title').css('background-color','#'+random_color);

Apply style on insert into div

I'm building a search by tags input box as seen here:
http://jsfiddle.net/Newtt/7nUAf/
Forgive the terrible styling as this is just a small component of a larger application and I've just added the styles needed to show my issue.
My search box is a div that has it's text inserted using Jquery as follows:
$(document).ready(function () {
$('.search-box').click(function () {
$('.search-options').toggle();
});
$('.options').click(function () {
var d = $('.search-box').html();
console.log(d);
var c = $(this).html();
console.log(c);
if (d != '') {
$('.search-box').html(d + ', ' + c);
} else {
$('.search-box').html(c);
}
$('.search-options').hide();
});
$('#reset').click(function () {
$('.search-box').html('');
});
});
where .search-box is the input div, .options are the clickable options from the drop down box search-options.
Currently, the text of each option is inserted into the search-box div. I need this to be styled dynamically while it enters the search box.
I tried something on the lines of:
$('<span>').addClass('tag').append(
$('<span>').text(value).append(' '),
$('<a>', {
href : '#',
title : 'Removing tag',
text : 'x'
});
where the tag class is defined in the style sheet to style the element to look like a tag,
but this doesn't work at all. Can someone help me out with how to achieve styling the input text to look like a tag from, say, Evernote notebooks?
Thanks!
I adapted your fiddle. Just wrap c in a span with a class (like you were trying to do in the second part of your post) and apply styles in css. I have just made the background red, but it should be easy enough to make it look like a tag like the ones in the drop down do.
http://jsfiddle.net/7nUAf/1/
JS:
$('.options').click(function () {
var d = $('.search-box').html();
var c = $(this).html();
$('.search-box').append('<span class="tag">'+c +'</span>');
$('.search-options').hide();
});
CSS:
.tag {
background: red;
}
For what you are looking to do - there are lots of excellent plug ins already available that provide much "prettier" functionality and with much less work on your part. Some have already been suggested in the comments - I might suggest consider using "chosen". The syntax is amazingly simple. Just create a select box as follows:
<select id="test" multiple>
<option>pdf</option>
<option>document</option>
</select>
Then in your document ready function you simply need to call chosen plugin:
$(document).ready(function () {
$('#test').chosen({width: "80%"});
});
I put together an example that does this on JSFiddle here: http://jsfiddle.net/7nUAf/3/. Once you get to the point that you have it working you can easily style the elements by inspecting what elements chosen is creating. For example the "li.search-choice" selector will allow you to style the selected items.
In General - even if you don't like this particular plug in, always consider running a search for existing items that do what you are looking for. In the case that these aren't perfect you can always improve them and provide that insight back to the community as a whole. In that way, everyone learns together.
Best of luck!

Wrapping a jquery validate span.error with nested divs

Heyo. This is my first stack overflow post because I am stumped and not finding many people who are trying to accomplish the same thing. I've tried using jquery .before(), .after(), and .wrap() to resolve this. I was initially using css :before and :after pseudo-elements, but as that won't work for legacy browsers, I've decided to use jquery.
I already have several forms on several pages with validation working. The error messages vary in length. We were using a static, one size background image on the default span element, so content was bleeding out on longer error messages. I built a flexible rounded corner series of nested divs to allow the error box to grow or shrink dynamically. The html I want to output is:
<div class="errorWrap">
<div class="errorTop"><span></span></div>
<div class="errorContent">
<span class="error">This is an error</span>
</div>
<div class="errorBottom"><span></span></div>
</div>
Here's an example of a solution I tried, but I'm still pretty new to javascript.
$('.error').before('<div class="errorWrap"><div class="errorTop"><span></span></div><div class="errorContent">');
$('.error').after('</div><div class="errorBottom"><span></span></div></div>');
Correct me if I'm wrong, but I think that I have the right idea with the jquery. But it's just kind of sitting there, not in any function being called. So I imagine that since the code isn't re-executing, it just doesn't show up. Is there an appropriate function to wrap this in? I'm certain I'm just not attacking this from the right direction. Any help is super appreciated.
the plugins "before" and "after" dont take html as string. you cannot start a div in one and close it in an other.
Either you take your current html and generate a new html string which you append where you want to or you use the "wrap" plugin http://api.jquery.com/wrap/
Using pure HTML
$(".error").html("<div class='beforeContent'>" + $(".error").html() + "</div>");
Using wrap (http://api.jquery.com/wrap/)
$(".error").wrap("<div class='beforeAndAfter'></div>");
If you want to show an error div after focus out of an input then you have to create it using html/wrap as Luke said and then you have to append it in ot the dom useing
$('.errorWrap').insertAfter('.focusedElement');
But there are other methods available to insert a new element like append/appendTo e.t.c,
I ended up fixing this problem on my own using jquery to create the div and it's nesting on pageload, the divs are generated with an error class that gives display:none. A custom errorPlacement function nests the error in the correct div. Then I used a custom validator highlight function to remove the class that hides the element. Then I used the unhighlight function to re-add the class to re-hide the div.
$(function() {
//Generate the elements and assign attributes
var errorWrap = document.createElement('div');
$(errorWrap).addClass('errorWrap hideError');
var errorTop = document.createElement('div');
$(errorTop).addClass('errorTop');
var topSpan = document.createElement('span');
var errorContent = document.createElement('div');
$(errorContent).addClass('errorContent');
var errorBottom = document.createElement('div');
$(errorBottom).addClass('errorBottom');
var bottomSpan = document.createElement('span');
//Place the elements directly after each dd element
$("dl > dd").append(errorWrap);
$("div.errorWrap").append(errorTop)
.append(errorContent)
.append(errorBottom);
$("div.errorTop").append(topSpan);
$("div.errorBottom").append(bottomSpan);
//Add custom validator defaults
$.validator.setDefaults({
errorPlacement: function(error, element) {
$(element).nextAll('.errorWrap').children('.errorContent').append(error);
},
highlight: function(element) {
$(element).nextAll('.errorWrap').removeClass('hideError');
},
unhighlight: function(element) {
$(element).nextAll('.errorWrap').addClass('hideError');
}
});
}
Although I'm sure this could have been done more shorthand, I really like this technique because I didn't have to update any of my pages that contained forms to get it to work. All of the nested divs are dynamically created by javascript, so I can include a global file to any page with forms and it will just work. Thanks for all who offered suggestions.

Categories

Resources