I'm trying to update numbers on a page based on button pushing by a user. I have it working, but when the number updates, the text is no longer formatted like it came in a <code></code> block. Here's the code I'm using minus any effort to control the format:
<script>
var countUp = function() {
$("#num").html(parseInt($("#num").html()) + 1);
$("#textWithNumInIt").html("The number is now"+$("#num").html() );
}
</script>
<p id="textWithNumInIt"><code>The number is 0</code></p>
I've tried putting <code></code> tags inside the jQuery, with and without escape characters. I've tried using .val() and .text() to set the text in an effort to leave the formatting alone. I've tried using a span around the number itself, but then the value doesn't even update.
This is the first time I have changed HTML using jQuery inside a javascript function, so the trouble might have something to do with that. Any help would be awesome, and if you have advice on a totally different way to do this, please share.
When you edit the contents of the textWithNumInIt paragraph, the <code> tags inside that paragraph are naturally replaced as well. This should work:
$("#textWithNumInIt").html("<code>The number is now "+$("#num").text()+"</code>" );
Maybe try this -
$('#textWithNumInIt code').html("The number is now "+$("#num").text() )
When you parseInt it, it gets converted into plain text and the <code> wrapper is gone. Use this and you will be on your path.
var countUp = function() {
var t = parseInt($("#num").text()) + 1);//using text() to avoid any unintentional html tag issues
$("#num").html(t);
$("#textWithNumInIt").html("<code>The number is now "+t+"</code>" );
}
or otherwise you can continue with your code by making a simple edit.
var countUp = function() {
$("#num").html(parseInt($("#num").html()) + 1);
$("#textWithNumInIt code").html("The number is now"+$("#num").html() );
}
Related
I am in the process of learning JavaScript and jQuery, so apologies if any of this sounds naive or obvious. I started what I thought was a fairly simple project to practice and hopefully learn something in the process.
What I want to do is this: the user inputs a sentence and hits a submit button. The sentence gets added to a list of other sentences submitted by people (preferably on a separate file, preferably encrypted, but not necessary). Then, the website grabs a random sentence from the list and displays it.
I am not asking on how to build all of this. I have already put most of it together, but I am including it here for reference.
I have a separate javascript file with the array of quotes.
var quotes=new Array();
quotes[0]="<p>Quote 1</p>";
quotes[1]="<p>Quote 2</p>";
quotes[2]="<p>Quote 3</p>";
quotes[3]="<p>Quote 4</p>";
quotes[4]="<p>Quote 5</p>";
quotes[5]="<p>Quote 6</p>";
quotes[6]="<p>Quote 7</p>";
Then I randomly display one using this:
function getQuote(){
var thisquote=Math.floor(Math.random()*(quotes.length));
document.write(quotes[thisquote]);
}
And adding <script> getQuote(); </script> to the html.
This all works fine.
The part I cannot seem to figure out is taking user input and adding it to the jQuery array. I am using a contenteditable div instead of an <input> because I want it to have multiple lines of text and have a character limit, which as far as I know can only be done with a contenteditable div (according to the research I did at the time, I may be wrong).
I have looked around and tried many if not all the examples I found of how to do this, and none of them worked. This is the last method I tried, if it helps:
$(".submit").click(function() {
quotes[quotes.length] = document.getElementsByClassName("input").value;
});
So, to reiterate, I want to take user input and add it to a JavaScript array. I have scoured stackoverflow and the interet but nothing has worked. Please help!
UPDATE: Arvind got it right. I still have a lot to learn, and it seems I need to read up on localstorage and cookies. I will also need to use PHP to save the sentences on the server. Thank you to all who answered!
Problem is document.getElementsByClassName("input") gives you a NodeList and not just a single html element. So if you do this document.getElementsByClassName("input").value, you will end up quotes as [undefined, undefined ... undefined]. Assuming you have single element with the class name input, go with index 0. Also as you stated that you are using div with attribute contenteditable, you may try this instead. document.getElementsByClassName("input")[0].innerHTML
Try this example.
var quotes = localStorage.getItem('quotes'); //get old, if any, gives you string
quotes = quotes ? [quotes] : []; // if got quotes then make it as array else make new array
$(function() {
var quote = $('#quote'); //get the quote div
quote.html(quotes.join('') || quote.html()); //set the default text
$('#btn').on('click', function(e) {
quotes.push(quote.html());
localStorage.setItem('quotes', quotes.join('')); //save the quotes
alert(quotes.join(''));
});
});
#quote {
border: 1px solid grey;
height: 100px;
overflow: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div contenteditable='' id='quote'>
<ol>
<li>Quote 1</li>
<li>Quote 2</li>
</ol>
</div>
<input type='button' id='btn' value='Submit' />
P.S.
In order to preserve the old quotes you may possibly use cookie, localStorage, etc.
Are these "quotes" being saved locally?
Yes, to share it among several users visiting by different browsers, you have to save it with the server script like PHP, Java, ASP, etc. Here you can either use ajax, if you wana avoid page reload on submit, else you can go for form submit.
$(".submit").click(function() {
quotes[quotes.length] = document.getElementsByClassName("input").value;
});
should be
$(".submit").click(function() {
quotes.push(document.getElementsByClassName("input").text());
});
EDIT: With a content editable div you need to use text() instead. Here is an example fiddle. https://jsfiddle.net/
var quotes=[];// better
// function to add to array
function addQuote(myquote){
quotes.push('<p>'+myquote+'</p>');
}
addQuote("Quote 1");
addQuote("Quote 2");
addQuote("Quote 3");
addQuote("Quote 4");
addQuote("Quote 5");
addQuote("Quote 6");
addQuote("Quote 7");
addQuote("Quote 8");
$(".submit").on('click',function() {
addQuote(document.getElementsByClassName("input")[0].value);
});
NOTE: suggest NOT using the "input" class name and use some other one as that might be confusing to others at some point later (confused by element named input)
I also added the paragraph tags as that would provide a consistent pattern for your input text. Assumption on my part however.
NOTE I also assume that the element IS an input type with the .value since that is NOT provided (the markup)
When a user create a message there is a multibox and this multibox is connected to a design panel which lets users change fonts, color, size etc.. When the message is submited the message will be displayed with html tags if the user have changed color, size etc on the font.
Note: I need the design panel, I know its possible to remove it but this is not the case :)
It's a Sharepoint standard, The only solution I have is to use javascript to strip these tags when it displayed. The user should only be able to insert links, images and add linebreaks.
Which means that all html tags should be stripped except <a></a>, <img> and <br> tags.
Its also important that the attributes inside the the <img> tag that wont be removed. It could be isplayed like this:
<img src="/image/Penguins.jpg" alt="Penguins.jpg" style="margin:5px;width:331px;">
How can I accomplish this with javascript?
I used to use this following codebehind C# code which worked perfectly but it would strip all html tags except <br> tag only.
public string Strip(string text)
{
return Regex.Replace(text, #"<(?!br[\x20/>])[^<>]+>", string.Empty);
}
Any kind of help is appreciated alot
Does this do what you want? http://jsfiddle.net/smerny/r7vhd/
$("body").find("*").not("a,img,br").each(function() {
$(this).replaceWith(this.innerHTML);
});
Basically select everything except a, img, br and replace them with their content.
Smerny's answer is working well except that the HTML structure is like:
var s = '<div><div>Link<span> Span</span><li></li></div></div>';
var $s = $(s);
$s.find("*").not("a,img,br").each(function() {
$(this).replaceWith(this.innerHTML);
});
console.log($s.html());
The live code is here: http://jsfiddle.net/btvuut55/1/
This happens when there are more than two wrapper outside (two divs in the example above).
Because jQuery reaches the most outside div first, and its innerHTML, which contains span has been retained.
This answer $('#container').find('*:not(br,a,img)').contents().unwrap() fails to deal with tags with empty content.
A working solution is simple: loop from the most inner element towards outside:
var $elements = $s.find("*").not("a,img,br");
for (var i = $elements.length - 1; i >= 0; i--) {
var e = $elements[i];
$(e).replaceWith(e.innerHTML);
}
The working copy is: http://jsfiddle.net/btvuut55/3/
with jQuery you can find all the elements you don't want - then use unwrap to strip the tags
$('#container').find('*:not(br,a,img)').contents().unwrap()
FIDDLE
I think it would be better to extract to good tags. It is easy to match a few tags than to remove the rest of the element and all html possibilities. Try something like this, I tested it and it works fine:
// the following regex matches the good tags with attrinutes an inner content
var ptt = new RegExp("<(?:img|a|br){1}.*/?>(?:(?:.|\n)*</(?:img|a|br){1}>)?", "g");
var input = "<this string would contain the html input to clean>";
var result = "";
var match = ptt.exec(input);
while (match) {
result += match;
match = ptt.exec(input);
}
// result will contain the clean HTML with only the good tags
console.log(result);
Ok so I finally figured out which part of my code is causing the exception. You can read the initial post here. The code in the initial post is missing the part which is actually causing the exception (the manual subscription to the viewPortData observable). Apparently, I'm doing it wrong somehow... Here's the code:
self.viewPortData = ko.observable();
self.viewPortData.subscribe(function (newValue) {
var viewPort = $('#metro-view-port');
if (viewPort && newValue) {
self.fadeInOut(viewPort, newValue);
}
});
self.fadeInOut = function (domObject, newContent) {
if (newContent) {
var currentContent = domObject.html();
if (currentContent) {
var wrappedContent = $(currentContent);
wrappedContent.fadeOut(400, function () {
wrappedContent.empty();
domObject.html(newContent).hide().fadeIn(400);
});
} else {
domObject.html(newContent).hide().fadeIn(400);
}
}
};
So where did I go wrong?
The same error occurred to me. The problem was caused because the HTML had comments on it. Something like:
<!-- Some Comment goes here -->
<div>
...
</div>
To fix that, without changing the HTML, you need to wrap the HTML with something else, so you pass only one element to jQuery:
var div = document.createElement( 'div' );
div.innerHTML = nativeHtml;
var $html = $( div );
I created a fiddle using your code from this post and the previous post, and it works as it should.
However, I'm only returning a simple <div> tag to populate the HTML of the metro-view-port <div>.
My best guess is that the HTML that you're returning is the problem.
My advice to you is to first confirm this by reducing the HTML returned to something very simple, and then gradually reintroduce the intended code until you find the problem.
Flip your fadeIn(400) to a show().
It is simpler for jQuery to do the math for.... I think that it can't get computed style of the elements due to some floats inside it or something.
I had the same problem..... but after some research I got to here (DAMMET I LOST THE TAB - it was a jQuery bug report anyway ) and realised what needed to be fiddeled with to fix it.
In my code I swapped out fadeIn() to show() so it isn't to do with the animation
you would have thought that without the animation the problem wouldn't be prevalent either - but it is.
try slideDown(0 if your still after an animation, it might not work but its worth a pop.
This bug was in old versions of jQuery. Try to change .hide() to .css('display', 'none')
According to this jQuery bug, the problem may have to do with newline characters and whitespace text nodes in your HTML. In my case, I was taking a template like this one:
<script id="myTemplate" type="text/template">
<div>
<h2>Important stuff</h2>
</div>
</script>
And parsing it like this:
var currentContent = $.parseHTML($('#myTemplate').html());
So I ended up with a bunch of text nodes representing the newline and whitespace characters in the original HTML template. Probably something similar has happened to you.
To fix this, I stripped out the newlines and whitespaces like so:
$('#myTemplate').html().replace(/\n/g, '').replace(/>\s+</g, '><').trim();
Hope that helps someone!
I've been looking at this code:
http://www.jquery4u.com/jquery-date-and-time-2/online-jquery-stopwatch/
I'm trying to understand exactly how it is working because I'd like a timer on a page I'm working on.
I can't for the life of me work out where the value of the timer is added to the input "disp" and how I could put this into a regular text, not a form input.
The only thing I can see that refers to it is:
t[6]=document.getElementById('disp');
Can anyone help me understand this please,
Thanks
You've correctly identified that they use t[6] to refer to the HTML element. But to set it, earlier on there is:
function disp() {
if (t[2]) t[1]=(new Date()).valueOf();
t[6].value=format(t[3]+t[1]-t[0]);
}
Since t[6] is the form input, they set the value of the form input to the formatted time. If you wanted to use some other element, e.g. <div id="myTime"></div>, you could say instead:
function disp() {
if (t[2]) t[1]=(new Date()).valueOf();
document.getElementById("myTime").innerText = format(t[3]+t[1]-t[0]);
}
Which changes only the last line, so that you may set the text of your div.
Alrite, I have seen other Questions with similar titles but they don't do exactly what Im asking.
I have 2 x HTML documents, one containing my page, one containing a element with a paragraph of text in it. As-well as a separate .js file
what I want to do is extract this text, store it as a JS variable and then use jQuery to edit the contents of an element within the main page. This is the conclusion I came to but it didnt work as expected, im not sure if it is me making a syntax error or if i am using the wrong code completely:
$(document).ready(function(){
var c1=(#homec.substring(0))
// #homec is the container of the text i need
$(".nav_btn #1").click(function(c1){
$(".pcontent span p") .html(+c1)}
);
});
i know +c1 is most probably wrong, but i have been struggling to find the syntax on this one. thankyou in advance :D
var c1=(#homec.substring(0)) will throw an error because #homec is not a valid variable name, is undefined, and does not have a property function called substring. To get the html of an element with an id of homec, use the html method:
var c1 = $("#homec").html();
c1 should not be an argument of the click function because it is defined in the parent scope. +c1 is unnecessary because you do not need to coerce c1 to a number.
If you are trying to add content to the end of the paragraph, use the append method:
$(".pcontent span p").append(c1)
That means you should use this code instead:
$(document).ready(function() {
var c1 = $("#homec").html();
$(".nav_btn #1").click(function() {
$(".pcontent span p").append(c1)
});
});
P.S. Numbers are not valid ID attributes in HTML. Browsers support it, so it won't make anything go awry, but your pages won't validate.
Try this:
$(".nav_btn #1").click(function(c1){
var para = $(".pcontent span p");
para.html(para.html() + c1);
});
The JQuery text() function will allow you to get the combined text contents of each element in the set of matched elements, including their descendants. You can then use the text(value) function to set the text content of your target paragraph element. Something like this should suffice:
$(document).ready(function() {
var c1 = $("homec").text();
$(".nav_btn #1").click(function() {
$(".pcontent span p").text(c1);
});
});
See the JQuery documentation for more details on the text() function. If you need to capture the full structure of the other document, then try the html() function instead.