The first letter of each <h3> into a hyperlink - javascript

Using javascript I'm looping through my H3 elements like this:
$('h3').each(function(){ });
I'm then generating an anchor for that tag formatted like this: "section-x" where x increments for each H3 on the page. The problem I have is that I'd like the first letter of the header to be an anchor link, like this:
*H*eading
.. where H is underlined, representing a link. I can format the anchors however I don't know how to wrap a hyperlink tag around the first letter in each heading. Some help would be greatly appreciated.
Regards,
kvanberendonck

Something like this?
$('h3').each(function(){
var currentHeading = $(this).text();
$(this).html("<a href='link'>" + currentHeading.substr(0,1) + "</a>" + currentHeading.substr(1, currentHeading.length - 1));
});

Let's throw some plain javascript into the mix:
$('h3').html(function(i){
var self = $(this)
, html = self.html()
return html[0].anchor('section-'+i) + html.substring(1)
})
html (and most other setter functions) accepts a function as an argument and uses the return value for each element
"string".link(target) creates the code string. A nice vintage useful method
edit: switched from .link to .anchor. Anchors are deprecated though, you should start using IDs for that:
$('h3').html(function(i){
var self = $(this)
, text = self.text()
// give the H3 an id and link to it
// ideally the headers should already have an id
this.id = 'section-'+i
return text[0].link('#section-'+i) + text.substring(1)
})

$('h3').each(function(i){
var firstLetter = $(this).text()[0];
$(this).html('' + firstLetter + '' + $(this).text().substr(1));
});
Not sure where you'd like to put section-x in that heading, but you can use i inside that each() to get the current iteration index.

Related

Javascript - How can I replace text in HTML with text in script

I am new to javascript. I was thinking getelementbyid but i don't know how to make it work
Like the title, here is what I mean
For example I have in HTML:
<p>fw_93</p>
<p>fw_94</p>
<p>fw_93</p>
So what I want is to make script to replace those fw_93 fw_94 to what I want.
For example
Instead of displaying "fw_93" I want it to display "9.3". Same with fw_94 to 9.4
Replace fw_ with nothing, divide the number by 10:
Array.prototype.forEach.call(document.getElementsByTagName('p'), function(el) {
el.innerHTML = parseInt(el.innerHTML.replace(/[A-Za-z_]*/, '')) / 10;
});
<p>fw_93</p>
<p>fw_94</p>
<p>fw_93</p>
Okay so select the tags.
Loop over the collection
read the html
match the string
replace the html
var ps = document.querySelectorAll("p");
for (var i=0; i<ps.length; i++) {
var p = ps[i];
var txt = p.innerHTML; //.textContent
var updated = txt.replace(/.+(\d)(\d)/, "$1.$2");
p.innerHTML = updated;
}
<p>fw_93</p>
<p>fw_94</p>
<p>fw_93</p>
Using JQuery
Not sure why I did it with JQuery, guess I wasn't paying enough attention. No point in me re-writing as there are already good answers in JS. Though I will leave this in case it's of use to anyone that is using JQuery.
You can loop though each <p> element and covert the contents, something like this:
$("p").each(function() {
var text = $(this).html();
var text = text.substring(text.indexOf("_") + 1);
var text = text[0] + "." + text.substring(1);
$(this).html(text);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>fw_93</p>
<p>fw_94</p>
<p>fw_93</p>
You may need to add validation depending on how reliable your input is.
Note that the code makes the following assumptions:
There will always be a _ followed by at least 2 digits
The . will always go after the first digit
Your HTML:
<p id="p1">init_value</p>
Your JS:
document.getElementById("p1").innerHTML = "new_value";

Dynamic nested list : insert line on click, after current element

I am struggling with a list that can be drag/dropped and nested.
How it should work :
1.Each row has an "add line" button.
2.When this button is clicked, I am trying to insert a new line, which is a text box, directly below/after the element where the button was clicked
3.Then get/add a unique ID for the new element/row.
4.Lastly once typing text in the new elements text box, get this text (to post to server).
The Javascript looks like this now :
$(document).on('click', '#addLabel_Item', function () {
var tree_id = ($(this).prop("title"));
var $tree_box = '#' + tree_id;
var $tree_box_item = '#' + tree_id + ' li';
var currentListItem = $(this).closest(".listed").attr("id");
var $items=$('.listed');
var parentID = $items.index($(this).closest(".listed"));
$("#list_reference_2").show();
//$("#list_reference_2").clone(true).insertAfter($("li").closest("ol#top_list_items li:eq(" + parentID + ")"));
//$("#list_reference_2").clone().insertAfter('ol > li:nth-child(1)');
$("#list_reference_2").clone().insertAfter("ol li:eq(" + parentID + ")");
});
Right now if I click to add a new line, it adds to the proper place on the initial/first click on the button. However, subsequent clicking on a different button adds the lines under the initial/first row rather than under the current one just clicked.
Fiddle showing what it does
Apologies if my explanation is confusing, I am confusing myself a bit :-)
Any help or point in the right direction would be greatly appreciated.
You can add the lines in this way:
$(document).on('click', '#addLabel_Item', function () {
var $li = $(this).closest('.listed');
$("#list_reference_2").show();
$li.after($("#list_reference_2").clone().removeAttr('id'));
$("#list_reference_2").hide();
});
JSFiddle: http://jsfiddle.net/tx7hbkjL/15/
PS: Take a look at your duplicate IDs, like #addLabel_Item. IDs must be unique in the page, use class instead.
Give it a try and let me know if it helps!

jQuery+ PHP adding new attributes to elements with specific value

I need to create a function that will add an attribute to elements that have an attribute with specific values.
$index have values 0-10, Code is working to this point: var element = $("a[data-slide-index*='"i"']");
Firebug gives me:
Blockquote
SyntaxError: missing ) after argument list
Rest looks like that:
<script type="text/javascript">
jQuery(document).ready(function($){
for(var i=0; i<parseInt(<?php echo json_encode($index); ?>);i++){
var hoverAtt = "onHover"+i+"()";
var element = $("a[data-slide-index*='"+ i +"']");
element.next().attr("onmouseover", function(){
return hoverAtt;
});
}
})
</script>
There is jFidle example for $index=6:
http://jsfiddle.net/Fuh9P/
Edit: I changed concatenation as Sjoerd suggested but still doesn't work.
The error message is because you concatenate strings the wrong way. You have this:
var element = $("a[data-slide-index*='"i"']");
Within the $() you try to concatenate three parts, like this:
"a"i"b"
Instead, you should use something like this:
"a" + i + "b"
var element = $("a[data-slide-index*='" + i + "']");

Equivalent of PHP preg_match, substr in javaScript

i'm makeing a tinyMce plugin that change word/letter space between highlighted text. My fn() looks like this:
function wordsLettersSpace(words, letters) {
var inst = tinyMCE.activeEditor;
var currSelection = $.trim(inst.selection.getSel());
if(currSelection != ""){
var content = "";
content = inst.selection.getContent({
format: 'html'
});
contentReplace = '<span style="word-spacing: '+words+'px; letter-spacing: '+letters+'px;">' + inst.selection.getContent({
format: 'html'
}) + '</span>';
inst.selection.setContent(content.replace(content, contentReplace));
window.alert(content);
}else{
Hyphenator.hyphenate(inst.getBody(), language);
}
tinyMceUpdate();
}
Now i need to find closest tag before select start position (if exist) and get style values of "word-spacing" and "letter-spacing". Also i need to get rid of any inside of selection, but only tags not the text, knowing that span tags can have different styles so simple str.replace won't work.
I know that there is a built-in plugin for that, but i need to do it outside of tinyMce iframe, and customize it.
Any sugestions?
JS regexes are available and do exactly what you want with preg_match.
https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Regular_Expressions
Substring in javascript is str.substr(start, length)

JavaScript RegExp match text ignoring HTML

Is it possible to match "the dog is really really fat" in "The <strong>dog</strong> is really <em>really</em> fat!" and add "<span class="highlight">WHAT WAS MATCHED</span>" around it?
I don't mean this specifically, but generally be able to search text ignoring HTML, keeping it in the end result, and just add the span above around it all?
EDIT:
Considering the HTML tag overlapping problem, would it be possible to match a phrase and just add the span around each of the matched words? The problem here is that I don't want the word "dog" matched when it's not in the searched context, in this case, "the dog is really really fat."
Update:
Here is a working fiddle that does what you want. However, you will need to update the htmlTagRegEx to handle matching on any HTML tag, as this just performs a simple match and will not handle all the cases.
http://jsfiddle.net/briguy37/JyL4J/
Also, below is the code. Basically, it takes out the html elements one by one, then does a replace in the text to add the highlight span around the matched selection, and then pushes back in the html elements one by one. It's ugly, but it's the easiest way I could think of to get it to work...
function highlightInElement(elementId, text){
var elementHtml = document.getElementById(elementId).innerHTML;
var tags = [];
var tagLocations= [];
var htmlTagRegEx = /<{1}\/{0,1}\w+>{1}/;
//Strip the tags from the elementHtml and keep track of them
var htmlTag;
while(htmlTag = elementHtml.match(htmlTagRegEx)){
tagLocations[tagLocations.length] = elementHtml.search(htmlTagRegEx);
tags[tags.length] = htmlTag;
elementHtml = elementHtml.replace(htmlTag, '');
}
//Search for the text in the stripped html
var textLocation = elementHtml.search(text);
if(textLocation){
//Add the highlight
var highlightHTMLStart = '<span class="highlight">';
var highlightHTMLEnd = '</span>';
elementHtml = elementHtml.replace(text, highlightHTMLStart + text + highlightHTMLEnd);
//plug back in the HTML tags
var textEndLocation = textLocation + text.length;
for(i=tagLocations.length-1; i>=0; i--){
var location = tagLocations[i];
if(location > textEndLocation){
location += highlightHTMLStart.length + highlightHTMLEnd.length;
} else if(location > textLocation){
location += highlightHTMLStart.length;
}
elementHtml = elementHtml.substring(0,location) + tags[i] + elementHtml.substring(location);
}
}
//Update the innerHTML of the element
document.getElementById(elementId).innerHTML = elementHtml;
}
Naah... just use the good old RegExp ;)
var htmlString = "The <strong>dog</strong> is really <em>really</em> fat!";
var regexp = /<\/?\w+((\s+\w+(\s*=\s*(?:\".*?"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>/gi;
var result = '<span class="highlight">' + htmlString.replace(regexp, '') + '</span>';
A simpler way with JQuery would be.
originalHtml = $("#div").html();
newHtml = originalHtml.replace(new RegExp(keyword + "(?![^<>]*>)", "g"), function(e){
return "<span class='highlight'>" + e + "</span>";
});
$("#div").html(newHtml);
This works just fine for me.
Here is a working regex example to exclude matches inside html tags as well as javascripts:
http://refiddle.com/lwy6
Use this regex in a replace() script.
/(a)(?!([^<])*?>)(?!<script[^>]*?>)(?![^<]*?<\/script>|$)/gi
this.keywords.forEach(keyword => {
el.innerHTML = el.innerHTML.replace(
RegExp(keyword + '(?![^<>]*>)', 'ig'),
matched => `<span class=highlight>${matched}</span>`
)
})
You can use string replace with this expression </?\w*> and you'll get your string
If you use jQuery, you can use the text property on the element containing the text you're searching for. Given this markup:
<p id="the-text">
The <strong>dog</strong> is really <em>really</em> fat!
</p>
This would yield "The dog is really really fat!":
$('#the-text').text();
You could do your regex search on that text instead of trying to do so in the markup.
Without jQuery, I'm unsure of an easy way to extract and concatenate the text nodes from all child elements.

Categories