jquery rearranging page elements - javascript

I have a body of text which is about 12 paragraphs long... inside the text are a couple of blockquotes which I would like to automatically highlight and rearrange throughout the document (every 3rd paragraph) and afterwards removing the blockquote so that the text appears twice. Once as a highlighted snippet in an automatically ordered position, and second in the original location without the block...
It sort of works, but I feel like I'm missing something because it doesn't follow the order. I would think it'd be (3,6,9, etc.) but it seems to be thrown off by something?
jQuery ->
content = $('article.city-review div')
content.find('blockquote').each (index) ->
line_space = (index+1)*3
quote_tag = '<span class=\"quote_left\">'+$(this).text()+'</span>'
content.find('p:nth-child('+line_space+')').prepend(quote_tag)
$(this).contents().unwrap().wrap('<p></p>')
UPDATE:
Input looks like:
<p>Text</p>
<p>More Text</p>
<p>Text</p>
<p>More Text</p>
<blockquote>Text</blockquote>
<p>Text</p>
<p>More Text</p>
<blockquote><p>Sometimes these appear</p></blockquote>
The output gives me empty p tags <p></p> and nested p tags <p><p>Something</p></p>

jQuery ->
content = $('article.city-review div')
content.find('blockquote').each (index) ->
position = [2,6,10]
line_space = position[index]
text = $(this).text()
quote_tag = '<span class=\"quote_left\">'+text+'</span>'
content.find('p:nth-child('+line_space+')').after(quote_tag)
$(this).replaceWith('<p>'+text+'</p>')
Making an array is an easy way to test out the spacing and unless you need an unlimited length could work. Remove the unwrap and use replacewith, maybe simpler for you and after instead of prepend unless you want the new quotes inside another tag.

Related

Spacing different in original html rendering vs dynamic JS rendering

Here is a small part of my page:
<a href="#" onclick="PolicyViolation(<%: ViewBag.DeviceData[i].DeviceID%>); return false;">
<span class="policyViolationsNumber"><%= ViewBag.DeviceData[i].ViolationCount%></span>
<span>Policy Violations</span>
</a>
This renders out to have some space between the two spans.
In code, we update this in JS:
var spanViolationNumber = $('<span>')
.html(statusModel.Violations)
.addClass('policyViolationsNumber');
var spanViolationString = $('<span>')
.html('<%=ServiceSite.Resources.Resources.DEVICES_POLICY_VIOLATIONS%>');
var imageTag = $('<img>')
.attr('src', '/Content/images/error_error.png')
.attr('align', 'absmiddle');
var anchorTag = $('<a href="#">')
.append(spanViolationNumber)
.append(spanViolationString);
cell.empty();
cell.append(imageTag)
.append(anchorTag);
However, this renders out with no space between the spans. I've seen small issues like this before but never figured out what it is. You can ignore the image tag stuff, it is irrelevant.
EDIT:
Didn't know about this, I guess it's expected behaivor: http://jsfiddle.net/2MMuA/
The extra space is happening because of the way you are formatting your HTML.
The "span" tag is an inline HTML element. This basically means you need to treat it just as you would treat text on the page.
<span>Hello</span> <span>World</span>
<!-- Prints Hello World -->
<span>Hello</span>
<span>World</span>
<!-- Prints Hello World
The line break is where your extra space is coming from. -->
<span>Hello</span><span>World</span>
<!-- prints HelloWorld
This is how the ".append()" function is formatting the HTML.
It adds it literally right after the last character in the HTML. -->
In order to normalize this across the two different techniques, you either have to butt your "span" tags right up next to each other so the HTML doesn't add an extra space...
<span></span><span></span>
..or you need to manually add the space in your ".append()" function.
obj.append(' ' + spanTag);
I hope that helps!
Perhaps you could clarify .. are you talking about there being space between these spans?
<span class="policyViolationsNumber">12</span>
<span>Policy Violations</span>
Either way I would look at adding some padding or margin to your css to insure you get the space that you want OR at minimum (though not recommended) use an HTML encoded space like so
There is most likely spaces between your spans. If you put the spans exactly next to each other then there should be no spaces.
<span></span><span></span>

HTML DOM manipulation : properly replace tag by heading tag

I want to replace some tag-inside-a-paragraph-tag by a heading-tag-enclosed-by-a-paragraph tag. This would result in proper W3C coding, but it seems that jQuery is not able to manipulate the DOM in the right way!? I tried several ways of (jQuery) coding, but i can't get it to work ..
Original code:
<p>some text <span>replace me</span> some more text</p>
Desired code:
<p>some text</p><h2>my heading</h2><p>some more text</p>
Resulting code by jQuery replaceWith():
<p>some text<p></p><h2>my heading</h2><p></p>some more text</p>
Demo: http://jsfiddle.net/foleox/J43rN/4/
In this demo, look at "make H2 custom" : i expect this to work (it's a logical replace statement), but it results in adding two empty p-tags .. The other 2 functions ("make code" and "make H2 pure") are for reference.
Officially the W3C definition states that any heading tag should not be inside a paragraph tag - you can check this by doing a W3C validation. So, why does jQuery add empty paragraph tags? Does anybody know a way to achieve this? Am i mistaken somehow?
You can achieve this with this code. However it's pretty ugly:
$('.replaceMe').each(function() {
var $parent = $(this).parent(),
$h2 = $(this).before('$sep$').wrap('<h2>').parent().insertAfter($parent);
var split = $parent.html().split('$sep$');
$parent.before('<p>' + split[0] + '</p>');
$h2.after('<p>' + split[1] + '</p>');
$parent.remove();
});
http://jsfiddle.net/J43rN/5/
If you read the jQuery docs, you will find:
When the parameter has a single tag (with optional closing tag or
quick-closing) — $("<img />") or $("<img>"), $("<a></a>") or $("<a>")
— jQuery creates the element using the native JavaScript
createElement() function.
So that is exactly what it is doing. And as I said in my comment, you can't change a parent node from a child node, you're altering the DOM here, not HTML code. So you'll need to either use replaceWith on the parent node and replace everything or use something like remove and append to split it up in multiple elements which you append after each other.
Try this:
var temp = "<p>some text <span>replace me</span> some more text</p>";
temp.replace(/(\<span\>replace me\<\/span\>)/gi, '</p><h2>my heading</h2><p>');
This will do a case insensitive replace for multiple occurences as well.
Read more about capturing groups here
Original credit to this question!
Please try this I have updated the http://jsfiddle.net/J43rN/6/ example by the below java script function please check I hope it will work for you
function fnMakeCode() {
$('#myP #replaceMe').html("<code id='replaceMe'>My Code</code>");
}
function fnMakeH2pure() {
$('#myP #replaceMe').html("<h2 id='replaceMe'>My H2 pure</h2>");
}
function fnMakeH2custom() {
$('#replaceMe').html("<p></p>").html("<h2>My H2 custom</h2>");
}

Why does .text().replace() delete my html?

FIDDLE UPDATED TO CLASSES
<p id="boohoo"><b id="why did all this disappear">Old Text</b></p>
<p id="boohoo"><h4 id="why did this not work">Old Text</h4></p>
var x = $('#boohoo').text().replace('Old', 'New');
function whyNotBold() {
$('#boohoo').text(x);
}
Why is there a difference between <b> and <h4>? And how can I have the the former <b id="... html not disappear when I insert the text? I would think .text().replace(... would only replace text and not affect the html, but that doesnt seem to be the case here since it's deleting it.
Firt of all you have 2 element with the same id, this is wrong. So your replacement work with the first element only.
The second is text() function strips tags and return only text content of your first node which is: Old Text. When you use text() func to set the text, jquery thinks you want your node <p id="boohoo"> contains text ONLY and it makes this:
<p id="boohoo">New Text</p>
Becase text() func resonsible for text nodes
EDIT:
In your case, you can do what you want like this:
var x = $('b').text().replace('Old', 'New');
function whyNotBold() {
$('b').text(x);
$('h4').text(x);
}
setTimeout(whyNotBold, 300);
Demo

Change background color of arbitrary text with javascript

Is there an easy way to wrap spans around arbitrary text within an html paragraph? For example, given the following original html:
<p>Here is a dandy block of text to color up</p>
<p> WHOAH another paragraph</p>
I'd like to wrap arbitrary portions of the text based on user input. So one set of input might transform this into
<p>Here is a <span style="background:yellow">dandy block</span> of text to color up</p>
<p> WHOAH <span style="background:green">another paragraph</span></p>
While another set of input might create
<p>Here is a<span style="background:yellow">a dandy block</span> of text to color up</p>
<p> WHOAH <span style="background:green">another</span> paragraph</p>
This problem is related to this one and this one, however, the main difference with my goal is that I want the highlights to be permanent, not just temporary selections and I'd also like this to work within p elements rather than textareas.
If it's possible, I imagine it would look something like using jQuery
var innerText = $('p')[p_index].slice(char_start, char_end).text();
$('p')[p_index].slice(char_start, char_end).html(
"<span style=\"background:yellow\">"+
innerText +
"</span>");
This would (in theory) select the p_index paragraph, grab the range between the given indices and replace it with a newly created span which has the original text nested inside of it. This clearly doesn't work since subscripting on the jQuery object does not return another inner jQuery object. Though
$("p").slice(0, 1).html("<span style=\"background: blue\">" +
$("p").slice(0, 1).text() +
"</span>");
Does exactly what I want on a paragraph level, but not on the within text level. I could use this approach to do the replacement by totally writing each paragraph given the character ranges I have, but if there's an easy way, I'd greatly appreciate suggestions.
$("p")[p_index]
gives you the actual DOM element that is that paragraph at p_index, so to get the contents of the paragraph you'd need to use:
$("p")[p_index].innerHTML
// OR
$("p")[p_index].textContent
Using jQuery would be easier though. You wouldn't use the jQuery slice() method to reduce the range to a single element, you'd use the .eq() method. Try something like this:
$('p').eq(p_index).html(function(i,currentText) {
return currentText.substring(0, char_start) +
"<span style=\"background:yellow\">" +
currentText.substring(char_start, char_end) +
"</span>" +
currentText.substring(char_end);
});
When you pass a function to the .html() method, jQuery sets the html to whatever you return from the function. jQuery passes the function the current (inner) html of the element so you can process it. (If you do this on a jQuery object containing more than one element your function is called once for each element so they can be processed individually.)
Demo: http://jsfiddle.net/62HHk/
I've used this plugin in the past with nice results.
Try this:
$('input[type=text]').keyup(function() {
var val = $.trim(this.value);
var text = $('p').text().split(' ')
$.each(text, function(i, v) {
if (v == val) {
text[i] = '<span>'+v+'</span>';
}
})
$('p').html(text.join(' '))
})
Fiddle
This should work. It can easily be turned into a function that takes the word you're looking for as a parameter.
jQuery.textReplace by Ben Alman
$('.text').replaceText( /hello/g, '<span classs="interesting">hello</span>' );

Changing HTML depending on where I click with javascript/JQuery

In an html page you might have some code with two paragraphs like this:
<hr />
<p>The first paragraph</p>
<p>The second paragraph</p>
<hr />
and very simply, these two tags would render like this:
The first paragraph
The second paragraph
What I am interested in is to allow the user to click somewhere in the rendered html code so as to insert a new element with JQuery. For example if I click between the letter i and the letter r (just a click, no higlighting/selection)in the word f*ir*st found in the first paragraph, I would be able to insert a custom span element or whatever I like exactly in that position in the HTML code resulting in something like this:
<hr />
<p>The fi<span id="myCustomSpan"></span>rst paragraph</p>
<p>The second paragraph</p>
<hr />
Any ideas that can help me? My request excludes absolute positioning. That would not solve my issues.
This is dirty but makes use of contenteditable: http://jsfiddle.net/Jj9Mp/.
$('div').click(function(e) {
$('div').attr('contenteditable', true);
document.execCommand("InsertHTML", false, "<span class=red>!</span>")
e.stopPropagation();
});
$(':not(div)').click(function(e) {
if($(this).parents('div').length === 0) {
$('div').attr('contenteditable', false);
} else {
$('div').click();
}
e.stopPropagation();
});
Here is my solution : http://jsfiddle.net/gion_13/L6aeT/
It works by calculating the actual size (in px) of the string.
This can be done with somewhat complex scripting.
i can state an algorithm that you can try.
1.JQuery have an API offset() http://api.jquery.com/offset/ using that you can get the offset and element.
2.Now you need to take the innerHTML of the element, take it as string, from the offset Y val, split at position Y in the string. make the element as two elements.
3.Now you can directly create an Element in script using creteElement(tagname) and set the innerHTML and then insert it in between the two elements

Categories