Numbering in jQuery - javascript

How could I change the text below so that the text within it has a number appended to it.
<div class="right">This is some text</div>
<div class="right">This is some text</div>
<div class="right">This is some text</div>
So the code above would become,
This is some text
This is some text
This is some text

you should use an ordered list... ol
or else you will need use css and add the content property your selector with the :after pseudo element.

How about the following?
$("div.right").each(function(i){
$(this).prepend((i + 1) + ". ");
});
UPDATE:
Here is one way that should work.
"number" is a custom element (it can be anything you want) that will/should be ignored by browsers.
$("div.right").each(function(i){
$(this).find("number").remove().end()
.prepend("<number>(i + 1) + ". </number>");
});
OR use the following which is probably a little slower but semantically correct...
$("div.right").each(function(i){
$(this).find("span.number").remove().end()
.prepend("<span class='number'>" + (i + 1) + ". </span>");
});
OR an even better way would be to prepend span.number before your first drag:
$(function(){ // document ready...
// caching the "numbers" will only work if you use the DOM
// for updating div position (like jQuery's "append()", "prepend()", "before()", and "after()") and not "innerHTML" or "html()"
var numbers = $("div.right").each(function(i){
$(this).prepend("<span class='number'>" + (++i) + "</span>. ");
}).find("span.number");
function dragEnd(){
// do your drag end stuff here...
numbers.each(function(i){
this.innerHTML = ++i;
});
)};
});

This is really an elaboration on another comment. I can't format code in a comment, I guess. You could use jQuery core's each:
$('div.right').each(function(ii){
html = $(this).html();
$(this).html(ii + '. ' + html);
});

jQuery selectors are your friend...
Get your stuff and loop on through something like this:
texts = $("div.right");
for(i = 0;i < texts.length;i++)
{
node = $(texts[i]);
content = node.html();
number = i + 1;
node.html(number + ". " + content);
}
Update: Jeez, last time post untested code straight off the dome here (disclaimer: not actually the last time). In the interest of correctness, I've updated it to at least run (and work!) if you still want to do it this way. Although I admit the other solutions are cleaner and more elegant.

Does this have to be done dynamically through jquery? Can't you just combine all that text into one div and then make a ordered list around it?

Using [] notation with a result set will give you the raw DOM element which does not have the html() function. Use the eq() function to get each element wrapped in a jQuery object.
You can also use each() as mentioned above, but I prefer straight 'for loops' so I don't have to adjust for 'this' if I'm in an event handler.
var texts = $("div.right");
var elem;
for(i = 1; i < texts.length; i++) {
elem = texts.eq(i);
html = elem.html();
elem.html(i + '. ' + html);
}

Related

Add HTML Value To JavaScript Variable

Ok.. So i have a html element that displays a current value, value is changed via range slider, i change the value of the html element using javascript with the following code:
hex_out = document.querySelector('#hex');
hex_out.value=rangeValue;
Which the above works fine, but recently I've needed to be able to add a bit of html code into hex_out.value
for example if i try
hex_out.value="<font color='red'>"+rangeValue+"</font>"
it will change hex_out.value to the code shown below
<font color='red'>Range slider value</font>"
which is obviously not what i'm trying to accomplish. How would i add html code to hex_out.value and have it display correctly?
Before anyone trys to say "This is a duplicate question", realize i've tried nearly ALL solutions shown on stack overflow with no luck
You'll need to modify the color via the element's style property. Try the following:
hex_out.style.color = 'red';
If you need to add any HTML, then (assuming that the hex_out element is a container element, and not an <input> tag), you can assign the HTML to its innerHTML property like so:
hex_out.innerHTML = '<strong>This is a <em>formatted</em> value.</strong>';
Another edit: It looks like you're using an <output> element, which doesn't accept child elements as far as I know. In this case, you'll likely want to use a regular <div> or <span> tag instead of <output> and then update its value manually as your sliders move using the innerHTML property described above.
I think you are looking for something like this:
var hex_out = document.querySelector('#hex'),
rangeValue = document.querySelector('#val');
rangeValue .addEventListener('input', function () {
hex_out.innerHTML = "<font color='red'>"+rangeValue .value+"</font>";
}, false);
<input type=range id=val>
<span id=hex>50</span>
Your difficulty arose because you put an obsolete font tag in the output tag which only accepts "phrasing content". The font tag is not supported in HTML5 and not on the list of phrasing content elements.
As #Mark said, a simple div will do if you require HTML to be rendered.
The example you gave is the thing normally expecting from javascript. I consider you want to change html of an existing element not value. If it is you can use below code:
hex_out. innerHTML ="<font color='red'>"+rangeValue+"</font>"
Existing fiddle link JSFiddle
Tested and works:
function setColor() { debugger;
Rval = parseFloat((r_out.value / 255.00).toFixed(3));
Gval = parseFloat((g_out.value / 255.00).toFixed(3));
Bval = parseFloat((b_out.value / 255.00).toFixed(3));
hex = "R: " + Rval + " " + "G: " + Gval + " " + "B: " + Bval;
var r_hex = parseInt(r.value, 10).toString(16),
g_hex = parseInt(g.value, 10).toString(16),
b_hex = parseInt(b.value, 10).toString(16),
hex1 = "#" + pad(r_hex) + pad(g_hex) + pad(b_hex);
body.style.backgroundColor = hex1;
hex_out.innerHtml = hex + [
'<br/><font size="1px">GSC RGB Selector</font>'
].join('#hex');
}

Dynamically add new element and change its content

I want to "copy" a certain elements and the change some of the text inside them with a regex.
So far so good: (/w working fiddle - http://jsfiddle.net/8ohzayyt/25/)
$(document).ready(function () {
var divs = $('div');
var patt = /^\d\./;
var match = null;
for (i = 0; i < divs.length; i++) {
match = ($(divs[i]).text().match(patt));
$(divs[i]).text($(divs[i]).text().replace(match[0], "5."));
}
});
HTML
<div>1. peppers</div>
<div>2. eggs</div>
<div>3. pizza</div>
This works exactly the way I want it, but I want to add some of the content dynamically, but when I try to change the content of the copied divs, nothing happens.
Please refer to this fiddle:
http://jsfiddle.net/8ohzayyt/24/
I have put some comments, to be more clear what I want to achieve.
I thing that your problem is that you're not passing an element to your changeLabel function, but just a string.
Look at this solution: http://jsfiddle.net/8ohzayyt/26/
Here is the line I changed to make your code work:
var newContent = $("<hr/><div id='destination'>" + $("#holder").html() + "</div>");
I just wrapped your HTML in $(). this creates an element from the string.
try:
var newContent = $("<hr/><div id='destination'>" + $("#holder").html() + "</div>");
EDIT:
Brief explanation What I've done.
In order to make $(el).find('div'); work changeLabel() needs an element. Instead of passing newContent as a string doing the above will make it pass as an element which will make $(el).find('div'); work.

Change the type of element using jQuery

If I know the ID of an element, is it possible to change the type of HTML tag that it has?
For example if you have <p id="p">Lots and lots of text here.</p>, is it possible to change it to <span id="p">....?
Thanks.
You can use the replaceWith method to do this. You'll need to rebuild the attributes for the replacement though.
$('#p').replaceWith(function(){
return '<span>' + $(this).contents().text() + '</span>';
});
Working example
You can do this:
var a = $('#p').text();
$('#p').replaceWith('<span id="#p">' + a + '</span>');
http://jsfiddle.net/teBuN/
var el = document.getElementById(id);
var new = document.createElement("span");
new.id = el.id;
[].forEach.call(el.childNodes, function (node) {
new.appendChild(node);
});
el.parentNode.replaceChild(new, el);
Now, a good question, is why. Why would you want to change the html element?
Surely you choose the most semantic element for this piece of data, why would another element be a better choice?
$("p").replaceWith(....) .............

jQuery 'not' function giving spurious results

Made a fiddle: http://jsfiddle.net/n6ub3/
I'm aware that the code has a LOT of repeating in it, its on the list to refactor once functionality is correct.
The behaviour i'm trying to achieve is if there is no selectedTab on page load, set the first tab in each group to selectedTab. If there is a selectedTab present, then use this as the default shown div.
However, as you can see from the fiddle its not working as planned!
If anyone has any ideas how to refactor this code down that'd be great also!
Change
if($('.tabs1 .tabTrigger:not(.selectedTab)')){
$('.tabs1 .tabTrigger:first').addClass('selectedTab');
}
to
if ( !$('.tabs1 .tabTrigger.selectedTab').length ) {
$('.tabs1 .tabTrigger:first').addClass('selectedTab');
}
Demo at http://jsfiddle.net/n6ub3/1/
They way you are doing it (the first code part) you are adding the .selectedTab class if there is at least one of the tabs in that group that is not selected at start .. (that means always)
Update
For a shortened version look at http://jsfiddle.net/n6ub3/7/
Your selector are doing exactly what you're writing them for.
$('.tabs3 .tabTrigger:not(.selectedTab)') is true has long as there is at least one tab that has not the selected tab (so always true in your test case).
So you should change the logic to !$('.tabs3 .tabTrigger.selectedTab').length which is true only if there are no selectedTab
WORKING DEMO with simplified code
$('.tabContent').hide();
$('.tabs').each(function(){
var search = $(this).find('div.selectedTab').length;
if( search === 0){
$(this).find('.tabTrigger').eq(0).addClass('selectedTab')
}
var selectedIndex = $(this).find('.selectedTab').index();
$(this).find('.tabContent').eq(selectedIndex).show();
});
$('.tabTrigger').click(function(){
var ind = $(this).index();
$(this).addClass('selectedTab').siblings().removeClass('selectedTab');
$(this).parent().find('.tabContent').eq(ind).fadeIn(700).siblings('.tabContent').hide();
});
That's all! You don't need all that ID's all around. Look at the demo!
With a couple of very minor changes you code can be reduced to:
$('.tabContent').hide();
$('.tabs').each(function(){
if($('.tabTrigger.selectedTab',$(this)).length < 1)
$('.tabTrigger:first').addClass('selectedTab');
});
$('.tabTrigger').click(function(){
var content = $(this).data('content');
$(this).parents('div').children('.tabContent').hide();
$(this).parents('div').children('.tabTrigger').removeClass('selectedTab');
$(this).addClass('selectedTab');
$('#' + content).show();
});
$('.tabTrigger.selectedTab').click();
Those changes are
Change the class on the surrounding div to just class="tabs.
Add a data-content attribute with the name of the associated content div
Live example: http://jsfiddle.net/gsTBQ/
Well, I'm a bit behind the times obviously; but, here's my updated version of your demo...
I have updated your fiddle as in the following fiddle: http://jsfiddle.net/4y3Xp/1/.
Basically I just tidied it up a bit, and to refactor I put everything in a separate function instead of having each of the cases in their own. This is basically just putting a new function in that does similar to what yours was doing (e.g. not modifying your HTML model), but I tried to clean it up a bit, and I also just made a function that took the tab number and did each of the items that way rather than needing a separate copy for each.
The main issue with the 'not' part of your query is that the function doesn't return a boolean; like all JQuery queries, it's returning all matching nodes. I just updated that part to return whether .selected was returning more than 0 results; if not, I go ahead and call the code to select the first panel.
Glad you got your problem resolved :)
$(document).ready(function(){
var HandleOne = function (i) {
var idxString = i.toString();
var tabName = '.tabs' + idxString;
var tabContent = tabName + ' .tabContent';
$(tabContent).hide();
var hasSelected = $(tabName + ' .tabTrigger.selectedTab').length > 0;
if (!hasSelected)
$(tabName + ' .tabTrigger:first').addClass('selectedTab');
var selectedTabId =
$(tabName + ' .tabTrigger.selectedTab').attr('id');
var selectedContentId = selectedTabId.replace('tab','content');
$('#' + selectedContentId).show();
$(tabName + ' .tabTrigger').click(function() {
$(tabName + ' .tabTrigger').removeClass('selectedTab');
$(tabName + ' .tabContent').hide();
$(this).addClass('selectedTab');
var newContentId = $(this).attr('id').replace('tab','content');
$('#' + newContentId).show();
});
}
HandleOne(1);
HandleOne(2);
HandleOne(3);
});

Does div with certain content exist

If I have a container div called #container which has a bunch of .inside divs in it, how would I go about checking whether a certain .inside div with a specified content (just a string of English text) exists or not? I'm doing this to prevent duplicates in a notification system I'm setting up for a website. I don't need the actual text - just whether it exists. Also, being able to modify the content of the .inside div if it's found would be good, so I can increment and show the number of times that message has occurred (grouping, if you like).
Thanks,
James
I like using selectors (others have used .filter, which is equally an option).
$(".inside:contains('waldo')").css({color: 'red'});
This is case sensitive.
Use the contains-selector[docs], then the length[docs] property to see how many were found.
var some_string = "test";
var els_with_string = $('#container .inside:contains(' + some_string + ')');
// use .length to check to see if there was at least one
if( els_with_string.length ) {
alert( "at least one already exists" );
}
From the docs:
Description: Select all elements that contain the specified text.
The matching text can appear directly within the selected element, in any of that element's descendants, or a combination thereof. As with attribute value selectors, text inside the parentheses of :contains() can be written as bare words or surrounded by quotation marks. The text must have matching case to be selected.
With respect to modifying the content if found, it would depend on what sort of modification you want to do. I don't know exactly what you mean by grouping.
EDIT: With respect to your comment, you could accomplish what you need like this:
var error = "ERROR:SomeError ";
var el_with_error = $('#container .inside:contains(' + error + ')');
if (el_with_error.length) {
var text = el_with_error.text();
if (/\(\d+\)/.test(text)) {
var new_text = text.replace(/\((\d+)\)/, function(s, g1) {
g1++;
return "(" + g1 + ")";
});
el_with_error.text(new_text);
} else {
el_with_error.text(text + " (2)");
}
} else {
$('#container').append('<div class="inside">' + error + '</div>');
}
Live Example: http://jsfiddle.net/ScZbV/
We could get by without the regular expression if you were able to wrap the grouping quantity in a <span> element.
var error = "ERROR:SomeError ";
var el_with_error = $('#container .inside:contains(' + error + ')');
if (el_with_error.length) {
var span = el_with_error.find('span');
if (span.length) {
var num = +span.text();
span.text( ++num );
} else {
el_with_error.append(" (<span>2</span>)");
}
} else {
$('#container').append('<div class="inside">' + error + '</div>');
}
Example: http://jsfiddle.net/ScZbV/1/
To check existence
$("#container .inside:contains('old text')").size() > 0
To modify the text
$("#container .inside:contains('old text')").text('new text');
Here's a slightly different way of looking at it...
Apply a class name for each "type" of notification. So your notification markup looks like:
<div class="inside error">Error</div>
Then inside of looking for a string inside these divs, use these new class names to your advantage and make use of .find(). If jQuery returns an object then its exists, so do something with it. But if it returns nothing then add it.
Example: http://jsbin.com/imexi4

Categories

Resources