Breaking a line inside a span using Javascript or CSS - javascript

I'm well aware that span is an inline element and by making a separate span and simply using display:block on it would be the solution in most other cases. Mine is a bit more complicated since my code is tangled up in Javascript & semi-PHP code. So here's what I'm facing:
This part of the code is used in the template file (.tpl):
<p id="reduction_amount" {if !$product->specificPrice || $product->specificPrice.reduction_type != 'amount' || $product->specificPrice.reduction|floatval ==0} style="display:none"{/if}>
{strip}
<span id="reduction_amount_display">
{if $product->specificPrice && $product->specificPrice.reduction_type == 'amount' && $product->specificPrice.reduction|floatval !=0}
SAVE {convertPrice price=$productPriceWithoutReduction|floatval-$productPrice|floatval}
{/if}
</span>
{/strip}
</p>
..And this part inside a .js file:
if (combination.specific_price.reduction_type == 'amount') {
$('#reduction_amount_display').html('SAVE ' + formatCurrency(discountValue, currencyFormat, currencySign, currencyBlank));
$('#reduction_amount').show();
}
This works perfectly and this is how it looks like currently:
(note: the <p> element has a fixed width and height)
The thing is, I'd like to give a line break after the "SAVE" part and be able to style the amount shown with a bigger font size. Demonstration:
This could be, as I mentioned above, achieved by separating the two with two other spans and stylizing them to how I want it to look. However, as my knowledge in Javascript is quite limited I do not know the correct way to insert a span. I tried several ways, for example adding html += '<span class="blabla">' right before formatCurrency and a closing tag after the paranthesis but this kinda messed up everything in the design for some reason. I also tried without using html += and plainly with quotes and the same thing happened. What solution is there for this? It does not necessarily have to be Javascript code. It could be a CSS or an HTML solution as well.
EDIT:
Using <br> is unfortunately not plausible since I wouldn't be able to stylize the amount shown separately. Also, using that tag makes a huge gap that the amount goes way out of (overflows) the <p> element.

You can wrap the dollar value in an element created by jQuery using append(), and style it accordingly with a given class.
var amount = $('#reduction_amount_display');
amount.html('SAVE ');
amount.append('<div class="style-amount">$10</div>');
.style-amount {
font-size:32px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="reduction_amount_display">
</p>

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";
});

I'm trying to set a generic element invisible by attribute and in one line of javascript

I'm limited to one line because of a Chrome Extension and it's the only one that fits my needs.
The <td> needs to be gone through to the attribute "UserName" to determine if a blocked user needs to be invisible.
I cannot figure this out and I'm really a noob when it comes to Javascript (not my language)
I've tried display:none hidden and style.visibility="hidden".
I've tried w3Schools and searched through Javascript and HTML pages for how to this and while I've got code that does work, it's a script that takes about 8 lines which doesn't work. I may have to ditch it but I figured I've give it one last shot.
document.getElementsByTagName("td")[0].getAttribute("theUserName").value("madmax").style.visible = "hidden";
Expected - The <td> should not show up
Results - It shows up
One line to hide the content:
[...document.querySelectorAll("td[theUserName=madmax]")].forEach(e=>e.style.display = 'none');
To remove the <td>:
[...document.querySelectorAll("td[theUserName=madmax]")].forEach(e=>e.remove());
I am assuming that you to iterate through all <td> elements to search for one with theUserName attribute with value madmax, then make that element invisible. That can be achieved with:
for(TdElement of document.getElementsByTagName("td")) {
if (TdElement.getAttribute("theUserName") == "madmax") {
TdElement.style.visiblity = "hidden";
}
}
Condensed to a single line, this is:
for(TdElement of document.getElementsByTagName("td")) if TdElement.getAttribute("theUserName") == "madmax") TdElement.style.visiblity = "hidden"

How to insert html code into a loaded html page without reloading the page?

Trying to insert html code into running html then after being processed remove said code.
This is what I have written and don't understand why it won't work.
Shouldn't the quotes run it as a string to be into put into the div span?
<div><span id="evolutionUpgrades"></span></div>
var membrane = "bubble";
function evolutionUpgrade() {
if (membrane == "bubble") {
if (evolution >= 1) {
document.getElementById("evolutionUpgrades").innerHTML =
'<p style="color:blue" title="Choose your evolution carefully.">Evolutions</p> <
<p title="Your p title = "Your first evolution. Double wall bubbles were the first evolution of cells."><button" type="button"> onclick="doublebubble< button type = "button"
onclick = "doublebubble()"><b>Double" Bubble<> < b > Double Bubble < /b></button><button > < /p>'
}
}
};
function doublebubble() {
membrane = "doublebubble"
document.getElementById('membrane').innerHTML = "Double Bubble";
}
This should fire when the evolution variable becomes equal to or greater than 1 and run the two if functions and then copy paste the code into the html.
Unfortunately it seems my javascript is ignoring the '' as a string and trying to run the code as is.
How do I make it just insert so that while the if statements are true it creates a button that than performs the function when clicked and on running that function becomes untrue to then be removed?
Am I using the wrong flag?
The wrong punctuation?
What am I doing wrong or not know?
Please help fix this.
Please be detailed with your answer so I can learn from it.
Just fixing my code without explaining does't truly help me.
I don't mind people fixing my grammar mistakes.
But please don't change the code.
I need to see the differences between broken and fixed to learn.
Especially when you break the code.
My code was correct except for the Jason W's fix.
The html within strings is fine, but you're getting a syntax error because you've put the string onto multiple lines. Javascript parses on the newline assuming you forgot to close the string and semicolon - how thoughtful :)
To get around this, easiest thing is to add a \ to escape the newline character (should work for all browsers) or use backtick (`) instead of single quote (but only if ES6 support only is ok for your app).
document.getElementById("evolutionUpgrades").innerHTML =
'<p style="color:blue" title="Choose your evolution carefully.">Evolutions</p> \
<p title="Your first evolution. Double wall bubbles were the first evolution of cells."><button type="button" onclick="doublebubble()"><b>Double Bubble</b></button></p>'
*Notice the "\" after the first closing p tag to escape the newline within your HTML
Add to to what #Jason said.
Where's your evolution variable? The nested if won't work if there's no evolution variable.
Consider looking into using a more modern way of adding a click event to the button.
I would also probably wrap the full code in an immediately invoked function expression and call the function in that.
Just my two cents.
Instead of inserting HTML in this way, include the optional HTML into your main HTML file, then turn it on or off by adding/removing a class such as hide.
<div>
<span id="evolutionUpgrades" class="hide">
<p style="color:blue" title="Choose your evolution carefully.">Evolutions</p>
<p title="Your first evolution. Double wall bubbles were the first evolution of cells.">
<button type="button" onclick="doublebubble()"><b>Double Bubble</b></button>
</p>
</span>
</div>
var membrane = "bubble";
function evolutionUpgrade(){
if (membrane == "bubble") {
if (evolution >= 1)
document.getElementById("evolutionUpgrades").classList.remove("hide");
}
}
function doublebubble() {
membrane = "doublebubble";
document.getElementById('membrane').innerHTML = "Double Bubble";
}
.hide { display: none; }
In general, it's better to avoid treating HTML as huge strings which are inserted into or removed from the DOM. You'll run into problems with quoting and newlines, as you've found. It also makes your code harder to read. Let HTML be HTML and JS be JS.
If you are using jQuery you can also use the .append() method
$('#evolutionUpgrades').append(`
<p style="color:blue" title="Choose your evolution carefully.">Evolutions</p>
<p title="Your first evolution. Double wall bubbles were the first evolution of cells."><button type="button" onclick="doublebubble()"><b>Double Bubble</b></button></p>
`)

Add code examples on your page with Javascript

I have a html code inside string
string_eng += '<b>Year Bonus</b> - bonus for each year</br></br>';
And I want to put this inside textarea, but when I do it, the result is:
- bonus for each year
It simply deletes all things inside the html tags. I just want to show all the code inside the string. I already tried <xmp>,<pre>, but none of them worked.
Thanks for any help.
EDIT.
Code with which I input data from the array to the textarea/code.
$('body').append('<code class="code_text"></code>');
for(var i=0; i<tag_list.length; i++){
var string='';
string+='---------------------------------------------------------------------------------\n';
string+='tag: '+tag_list[i][0]+'\n';
string+='nazwa_pl '+tag_list[i][1]+'\n';
string+='nazwa_eng '+tag_list[i][2]+'\n';
string+='tekst_pl '+tag_list[i][3]+'\n';
string+='tekst_eng '+tag_list[i][4]+'\n';
string+='\n\n\n';
$('.code_text').append(string);
}
I tried this using jsfiddle:
HTML
<textarea id="code"></textarea>
JavaScript
$(document).ready(function() {
var string_eng = '';
string_eng += '<b>Year Bonus</b> - bonus for each year</br></br>';
$("#code").html(string_eng);
});
Output (contained in textarea)
<b>Year Bonus</b> - bonus for each year</br></br>
Try it here: http://jsfiddle.net/UH53y/
It does not omit values held within tags, however if you were expecting the <b></b> tags to render as bold within the textarea, or the <br /> tags to render as line breaks, this wont happen either. textarea does not support formatting.
See this question for more information: HTML : How to retain formatting in textarea?
It's because you're using the jQuery .append method which seems to parse the string and insert it afterwards. I don't know jQuery at all, so there might be another special jQuery method, but here is a simple fix:
$('.code_text').append(document.createTextNode(string));
Edit:
I just read and tried the answer of Salman A. The "special jQuery method" exists and he used it. You can use this:
$('.code_text').text(string);

JSF Set CSS Style Using Javascript?

I have been looking with no success to see if I can dynamically apply a css style to JSF component or div using javascript. Is this possible.
This is pseudo code
<div style="myJSStyleFunction("#{myBean.value}")"> stuff </div>
And the function would return something like "position:relative;left:25px;"
I've had no luck and maybe it can't be done but would like a second opinion.
Edit:
I'm trying to see if I can keep a separation / reduce the coupling between the presentation/view and the model/controller. This is for indenting commenting or product reviews (to nest replies to comments or reviews). The most I really want to track is an integer on how deep a reply is. First level = 0 second level = 1, and so on. So a comment or product review would be 0 deep, a reply to the comment or review would be 1 and so on.
Then in the EL I wanted to call a javascript function and do something like
<script>
myJSStyleFunction(depth){
if(depth<=5){
var nest=20*depth;
var style="position:relative;left:" + nest + "px;";
return style;
}
}
</script>
And then then say for a third level comment (a reply to a reply) it would look like this:
<div style="position:relative;left:40px;"> stuff </div>
where
#{myBean.value}
evaluates to 2
I suspect like Daniel says I'll have to tightly couple the view but I'd rather not have to. I'd think there has to be a way. But maybe not.
I don't know where there are cleaner solutions for this. However this is one suggestion.
Assume your page looks like below and myBean.getValue() method returns an integer.
<h:form id="frm">
<div style="#{myBean.value}"> div1 </div>
<div style="#{myBean.value}"> div2 </div>
</h:form>
So you can do something like this at 'window.onload'.
<head>
<script>
window.onload = function() {
var childList = document.forms['frm'].childNodes;
for(var i = 0; i < childList.length; i++) {
if(childList[i].nodeName == 'DIV') {
var _div = childList[i];
var depth = _div.getAttribute('style');
_div.setAttribute('style', 'position:relative;left:' +(depth *20)+ 'px;');
}
}
}
</script>
</head>
Note: 1. In above sample code I assume all the DIVs inside the form should be indented.
2. For IE you may need to use _div.style.setAttribute('cssText','position:relative;left:' +(depth *20)+ 'px;')
3. Another solution for your question is using <script> tags immediately after your divs and putting the js part inside them. In this way you don't have to use fake styling style="#{myBean.value}" or window.onload event because you can directly call #{myBean.value} in your script.
I decided to skip the javascript approach and settled on a simpler and I think cleaner method to create the dynamic css classes for my situation. I already capture/calculate the depth value for each comment when it is entered. So I am just returning that value in EL and concatenating it to a 'base name' for the css class like so:
<div class="indent_#{(comment.commentDepth le 5) ? comment.commentDepth : 5}" >
comment comment blah blah blah
</div>
"indent_" is the base name for the css class. So for a 0 level comment it will have a class="indent_0". A reply to that comment will have class="indent_1".
I use the ternary so that if there are lot of replies under a given comment it doesn't indent right off the right hand side of the page. Even though you can keep going deeper, it will only indent up to 5 levels.
For my case at the moment, this is a simpler and cleaner method of adding some dynamically generated css class names. Right now I have to define 6 classes for this in the css file, but perhaps I'll figure out how to nest the boxes but it isn't a priority this works just fine for me for now.

Categories

Resources