Changing URL in string to clickable link while changing its value - javascript

For a little webapp, I'm using JS to change a url inside a string to a clickable url, while changing the url to say 'tap here'. The problem however is if I keep the URl the same, without changing it to 'tap here' it all works fine. But if I change it, the clickable link links to an error page:
Not Found
The requested URL /client/http://www.google.com'
target='_blank'>tap here was not found on this server.
Here's the code I'm using that works (without changing to 'tap here')
$('.discussion').ready(function(){
$('.discussion #messages p').each(function(){
var str = $(this).html();
var regex = /(https?:\/\/([-\w\.]+)+(:\d+)?(\/([\w\/_\.]*(\?\S+)?)?)?)/ig
var replaced_text = str.replace(regex, "<a href='$1' target='_blank'>$1</a>");
$(this).html(replaced_text);
});
});
And this is the one I want to work, but gives the error:
$('.discussion').ready(function(){
$('.discussion #messages p').each(function(){
var str = $(this).html();
var regex = /(https?:\/\/([-\w\.]+)+(:\d+)?(\/([\w\/_\.]*(\?\S+)?)?)?)/ig
var replaced_text = str.replace(regex, "<a href='$1' target='_blank'>tap here</a>");
$(this).html(replaced_text);
});
});
[EDIT] and here's the HTML
<ol class="discussion" scroll-bottom="replies">
<div ng-class="getClass($index)" ng-repeat="reply in replies track by $index">
<li ng-repeat="item in reply.text.replace('?','.').replace('!','.').split('. ') track by $index" class="fix-clutter">
<div class="avatar">
<img ng-src="{{reply.avatar}}">
</div>
<div id="messages" class="animated slideInUp">
<p class="animated fadeInUp">{{item}}</p>
</div>
</li>
</div>
</ol>

I copied and pasted your code here: http://plnkr.co/edit/CK2vJdeIxtN1Bvt7Kce5?p=preview with the following HTML:
<div class="discussion">
<div id="messages">
<p>
http://stackoverflow.com/questions/32395188/changing
</p>
<p>
http://stackoverflow.com/questions/32395188/changing
</p>
</div>
</div>
Everything works pretty well on this specific scenario. Can you paste your HTML?
However the regex it's not working right. If you add "dashes" on your URI, The regex fail to get the full URI and it breaks on the dash.
Update:
I checked again... and the problem is 90% caused by the regex rule.
Another case where is breaking is when you have already on your html the link with the "href tag" as the code below:
<div class="discussion">
<div id="messages">
<p>
<a href="http://stackoverflow.com/questions/32395188/changing'>LINK</a>
</p>
</div>
</div>

Related

JS replace current tag with a new tag

So, I have some text that looks like:
<div class="content__main">
<p>This is some text<br>
This is another line<br>
Third line goes here<br>
How about one more</p>
</div>
What I'd like to do is use JavaScript or jQuery to find the <br> tags and replace them with </p><p> tags. The content is auto-generated, so I can't just add it myself.
I'd like it to look like:
<div class="content__main">
<p>This is some text</p>
<p>This is another line</p>
<p>Third line goes here</p>
<p>How about one more</p>
</div>
I tried:
<script type="text/javascript">
$(function(){
$('.content__main').replace(/<br>\\*/g,"</p><p>"));
});
</script>
But this doesn't seem to do anything, I think I'm pretty close though, can anyone shed some light on this for me?
Thanks,
Josh
Edit: Changed querySelector to querySelectorAll with a for of to support multiple class="content__main" elements
Simple, unsafe way
You could just do the replace on the innerHTML and set that to the element.
const d = Array.from(document.querySelectorAll('.content__main'));
for (let e of d) {
e.innerHTML = e.innerHTML.replace(/<br>\\*/g,"</p><p>");
}
<div class="content__main">
<p>This is some text<br>
This is another line<br>
Third line goes here<br>
How about one more</p>
</div>
Safer way to prevent un-closed tags
A more safe way of doing this, to prevent missing a closing tag is to:
Get the innerHTML
Split on newlines
For each line;
Remove all the tags
trim() the spaces
Create a p and add the text
Insert that to the original div
const d = Array.from(document.querySelectorAll('.content__main'));
for (let e of d) {
let old = e.innerHTML;
e.innerHTML = '';
for (let line of old.split("\n")) {
let cleaned = line.replace(/<\/?[^>]+(>|$)/g, "").trim();
if (cleaned !== '') {
let newE = document.createElement('p')
newE.innerHTML = cleaned;
e.appendChild(newE);
}
}
}
<div class="content__main">
<p>This is some text<br>
This is another line
Third line goes here<br>
How about one more</p>
</div>
So your problem is that you're using .replace which is a JavaScript default string function on a jQuery object $('.content__main') - you need to get the HTML value of this as a string to do .replace.
You definitely don't need jQuery for this, but if you were using it the code could look as follows:
$(function(){
let current_content = $('.content__main').html();
current_content = current_content.replace(/<br>\\*/g,"</p><p>")
$('.content__main').html(current_content);
});

Copy HTML from element, replace text with jQuery, then append to element

I am trying to create portlets on my website which are generated when a user inputs a number and clicks a button.
I have the HTML in a script tag (that way it's invisible). I am able to clone the HTML contents of the script tag and append it to the necessary element without issue. My problem is, I cannot seem to modify the text inside the template before appending it.
This is a super simplified version of what I'd like to do. I'm just trying to get parts of it working properly before building it up more.
Here is the script tag with the template:
var p = $("#tpl_dashboard_portlet").html();
var h = document.createElement('div');
$(h).html(p);
$(h).find('div.m-portlet').data('s', s);
$(h).find('[data-key="number"]').val(s);
$(h).find('[data-key="name"]').val("TEST");
console.log(h);
console.log($(h).html());
console.log(s);
$("div.m-content").append($(h).html());
<script id="tpl_dashboard_portlet" type="text/html">
<!--begin::Portlet-->
<div class="m-portlet">
<div class="m-portlet__head">
<div class="m-portlet__head-caption">
<div class="m-portlet__head-title">
<h3 class="m-portlet__head-text">
<span data-key="number"></span> [<span data-key="name"></span>]
</h3>
</div>
</div>
<div class="m-portlet__head-tools">
<ul class="m-portlet_nav">
<li class="m-portlet__nav-item">
<i class="la la-close"></i>
</li>
</ul>
</div>
</div>
<!--begin::Form-->
<div class="m-portlet__body">
Found! <span data-key="number"></span> [<span data-key="name"></span>]
</div>
</div>
<!--end::Portlet-->
</script>
I'm not sure what I'm doing wrong here. I've tried using .each as well with no luck. Both leave the value of the span tags empty.
(I've removed some of the script, but the variable s does have a value on it)
You have two issues here. Firstly, every time you call $(h) you're creating a new jQuery object from the original template HTML. As such any and all previous changes you made are lost. You need to create the jQuery object from the template HTML once, then make all changes to that object.
Secondly, the span elements you select by data-key attribute do not have value properties to change, you instead need to set their text(). Try this:
var s = 'foo';
var p = $("#tpl_dashboard_portlet").html();
var $h = $('<div />');
$h.html(p);
$h.find('div.m-portlet').data('s', s);
$h.find('[data-key="number"]').text(s);
$h.find('[data-key="name"]').text("TEST");
$("div.m-content").append($h.html());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script id="tpl_dashboard_portlet" type="text/html">
<div class="m-portlet">
<div class="m-portlet__head">
<div class="m-portlet__head-caption">
<div class="m-portlet__head-title">
<h3 class="m-portlet__head-text">
<span data-key="number"></span> [<span data-key="name"></span>]
</h3>
</div>
</div>
<div class="m-portlet__head-tools">
<ul class="m-portlet_nav">
<li class="m-portlet__nav-item">
<i class="la la-close"></i>
</li>
</ul>
</div>
</div>
<div class="m-portlet__body">
Found! <span data-key="number"></span> [<span data-key="name"></span>]
</div>
</div>
</script>
<div class="m-content"></div>
In my case only this is working:
var template = $('template').clone(true, true); // Copies all data and events
var $h = $('<div />');
$h.html(template);
$h.find('.input-name').attr('value', "your value here"); // Note: .val("your value here") is not working
$('.list').prepend($h.html());

How to share a post with image using addThis plugin in jquery

How can i share a post in facebook with the image using addThis. I have written this code to share in facebook,twitter and mail.
Now i can able to post or share the content without having the image and am getting like this(Refer Image)What i get.
Please help me to post with the image and caption.
I have added my code in fiddle or even you can see it in this https://jsfiddle.net/x34nnwcs/
(function () {
addthis.init();
function navigatePage(e) {
var pageId = $(this).attr("id"),
$pageContent, sharingMarkup, content,
config = $.extend(true, {}, window.addthis_config),
share = $.extend(true, {}, window.addthis_share);
if (pageId != "pageContent") {
config["some_property"] = "some value";
share.title = $(this).html();
share.url = "http://" + pageId + ".not-a-tld";
share.photo = "http://res-5.cloudinary.com/demo/image/upload/dpr_1.0,f_auto,w_365,h_133,c_fill,g_south,o_60/group.jpg";
$pageContent = $("#pageContent");
sharingMarkup = $("#sharing_markup").html();
content = $(".pageC").html();
console.log(content);
$pageContent.html(content + sharingMarkup);
addthis.toolbox(".page_sharing_toolbox", config, share);
addthis.toolbox(".page_sharing_facebook", config, share);
}
$("#page1").click(navigatePage);
}
navigatePage.call(document.getElementById("pageContent"));
}());
<div id="pageContent">
<button id="page1">Page 1</button>
<div class='pageC'>
<img src='http://res-5.cloudinary.com/demo/image/upload/dpr_1.0,f_auto,w_365,h_133,c_fill,g_south,o_60/group.jpg'/>
<p>this is a simple paragraph that is meant to be nice and easy to type which is why there will be mommas no periods or any capital letters so i guess this means that it cannot really be considered a paragraph but just a series of run on sentences this should help you get faster at typing as im trying not to use too many difficult words in it although i think that i might start making it hard by including some more difficult letters I'm typing pretty quickly so forgive me for any mistakes i think that i will not just tell you a story about the time i went to the zoo and found a monkey and a fox playing together they were so cute and i think that they were not supposed to be in the same cage but they somehow were and i loved watching them horse</p>
<p>
</div>
</div>
<script id="sharing_markup" type="text/html">
<div class="page_sharing_facebook addthis_toolbox facebook_like">
<a class="addthis_button_facebook_like" title="Facebook Like"></a>
</div>
<div class="page_sharing_toolbox addthis_toolbox addthis_default_style" style="width:290px;">
<div class="share-icons" id="share-icons">
<a class="addthis_button_email left" title="Email"></a>
<a class="addthis_button_facebook left" title="Facebook"></a>
<a class="addthis_button_twitter left last" title="Twitter"></a>
<a class="addthis_button_google left" title="Google"></a>
</div>
</div>
</script>
<script id="page1content" type="text/html">
</script>
<!-- the async parameter has been added, query parameter style, to the hash so that things won't render until you explicitly call addthis.init() -->
<script src="//s7.addthis.com/js/300/addthis_widget.js#async=1&pubid=atblog"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script>
you need only to add this meta tag to your <Head> on HTML code
<meta content="your image source" property="og:image">

to reach (ie. to unhide) a particular div using 'href' from other page

There is a pageA with 3 div(consider). also i'm having a link in another page. when users clicks the link they have to reach the 3rd div in pageA. How to do this?
In my code all div are hidden except the one which is selected at that
time. so there is no need for scrolling.
Demo
HTML:(PageA.html)
<div id="mws-navigation">
<ul id="link">
<li class="" data-related="a" id="a1"><i class="icon-book"></i>A</li>
<li data-related="b" class="" id="b1"><i class="icon-search"></i>B</li>
<li data-related="c" class="" id="c1"><i class="icon-calendar"></i>C</li>
</ul>
</div>
<!-- Main Container Start -->
<div id="mws-container" class="clearfix">
<!-- Inner Container Start -->
<div id="a" class="tab">
aaaa
</div>
<div id="b" class="tab">
bbbb
</div>
<div id="c" class="tab">
cccc
</div>
</div>
page B.html:
vvv// this link will be in other page(to reach C)
// what i have to give in herf="" to reach that particular div
JQuery:
$(function()
{
$('#link li').removeClass('actif');
$(this).find('li').addClass('actif');
$('.tab').hide();
$('#a').show();
document.getElementById('a1').className='active';
$('#link li').click(function(e){
$('#link li').removeClass('actif');
$(this).find('li').addClass('actif');
$('.tab').hide();
$('#'+$(this).attr('data-related')).show();
e.preventDefault();
});
});
Any suggestion?
Ok so I think you're saying you want to show and focus on a particular element based on what a user has clicked on coming from another page.
On pageB add a parameter to your querystring in your hrefs like so:
vvv
If you have server side access - java, php or something then I would suggest using that to handle the query string and add a class to your div on pageA
<div id="c" class="tab showAndFocus"> cccc</div>
var myElementToShow = $(".showAndFocus");
myElementToShow.show();
myElementToShow.focus();
OR
However, if you only have jquery/javascript to do this (i.e. there is no server side to help you work with the query string) then you can get access to the query string parameters as discussed here
var urlParams;
(window.onpopstate = function () {
var match,
pl = /\+/g, // Regex for replacing addition symbol with a space
search = /([^&=]+)=?([^&]*)/g,
decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
query = window.location.search.substring(1);
urlParams = {};
while (match = search.exec(query))
urlParams[decode(match[1])] = decode(match[2]);
})();
Once you have the query string you can grab the div you want to show pretty easily...
var myElementToShow = $("#"+urlParams.showdiv);
myElementToShow.show();
myElementToShow.focus();
You can read location.hash when pageA loads - in your jQuery load($) function

How to replace text inside IDless <span> with javascript?

I have some text inside <span></span> tags and I want to change that text to something else when page is loaded.
So lets say default text is 'Story' (outputted by some CMS system and I can't edit it). So when page is loaded, .js detects that 'Story' word and replaces it with 'View This Story'.
Is that possible somehow?
Cheers
Update: I did search before asking and none of those methods I found works. Like I said the text is outputted by CMS and it gives wrong title, the title itself cannot be edited via CMS because it is used for other terms and tagging which is correct, so I was looking for js workaround to rename it on page load.
And span has no ID and I cannot give it any ID, because like I said it works as designed by CMS.
<div class="views-row views-row-1 views-row-odd views-row-first active">
<div class="views-field views-field-name">
<span class="field-content">Story</span>
</div>
</div>
<div class="views-row views-row-2 views-row-even">
<div class="views-field views-field-name">
<span class="field-content">Second Story</span>
</div>
</div>
As you can see spans do not have IDs, but repeating classes only.
UPDATED as per OP request
You can replace any text within spans. You could even use regular expressions to make it more flexible, but let's leave this for now:
Native Javascript
var lookupSpanAndReplace = function(textFrom, textTo) {
var spans = document.getElementsByTagName('span');
for (i=0; i<spans.length; i++)
if (spans[i].innerHTML.indexOf(textFrom) >= 0)
spans[i].innerHTML = mySpan.innerHTML.replace(textFrom, textTo);
}
lookupSpanAndReplace("Story", "My New Text");
jQuery
var lookupSpanAndReplace = function(textFrom, textTo) {
$('span:contains(' + textFrom + ')').each(function(index, element) {
$(element).text($(element).text().replace(textFrom, textTo));
});
}
lookupSpanAndReplace("Story", "My New Text");
Try
$('#spanID').text("View This Story");
or if you want to replace a part of text
$('#spanID').text(function () {
return this.innerHTML.replace('Story', 'View This Story');
});
Give you span an ID and then run text([your new text]) on that node:
HTML
<span id="mySpan">Story</span>
jQuery
$('#mySpan').text("View This Story");
JSFiddle with jQuery
Or you can do it without jQuery:
document.getElementById("mySpan").innerHTML = "View This Story";
JSFiddle with plain 'ol Javascript
<script>
function changeSpan(){
var spans = document.getElementsByTagName ("span");
for (i = 0; i < spams.length; i++){
spans[i].innerHTML = textThatYouWant ();
}
}
</script>
<head onload="changeSpan()" >
<tile> ... </title>
</head>
<body>
...
</body>
Use the following to solve the issue.
HTML code:
<html>
<head>
<script>
function replace_text_span()
{
for(i=0;i<document.getElementsByTagName('span').length;i++)
{
document.getElementsByTagName('span')[i].innerHTML=document.getElementsByTagName('span')[i].innerHTML.replace("Story","View This Story");
}
}
</script>
<style>
</style>
</head>
<body onload="replace_text_span()">
<div class="views-row views-row-1 views-row-odd views-row-first active">
<div class="views-field views-field-name">
<span class="field-content">Story</span>
</div>
</div>
<div class="views-row views-row-2 views-row-even">
<div class="views-field views-field-name">
<span class="field-content">Second Story</span>
</div>
</div>
</body>
</html>

Categories