So I'm trying to collect what people are selecting on our site. Currently, it works EVERYWHERE, and I don't want that. I only want it if they are selecting in a certain DIV.
it's basically a simple modification to a script I found.
<script type="text/javascript">
function appendCopyright() {
var theBody = document.getElementsByClassName("sbReview")[0];
var selection;
selection = window.getSelection();
var copyrightLink = '<br /><br /> - Read more at: '+document.location.href+'<br />©2012 <? printf($product. ' & ' .$spOrganization); ?>';
var copytext = selection + copyrightLink;
var extra = document.createElement("div");
extra.style.position="absolute";
extra.style.left="-99999px";
theBody.appendChild(extra);
extra.innerHTML = copytext;
selection.selectAllChildren(extra);
window.setTimeout(function() {
theBody.removeChild(extra);
},0);
}
document.oncopy = appendCopyright;
I tried modifying selection = window.getSelection(); but it just broke it :(
Basically, I want the above code, ONLY to work in a certain div, not the whole body
Probably you shouldn't use document.oncopy, instead try using div.oncopy where div is the div element you are interested in.
var selection = getSelection().toString(); is your solution - getSelection() returns a Selection object and you can get the string just by using .toString() method. More properties and methods of Selection object could be found here: https://developer.mozilla.org/en-US/docs/DOM/Selection
According to the Mozilla JS docs the selection class has a method containsNode. The following should work.
function appendCopyright() {
var theBody = document.getElementsByClassName("sbReview")[0];
var selection;
selection = window.getSelection();
// HERE's THE GOODS
// set aPartlyContained to true if you want to display this
// if any of your node is selected
if(selection.containsNode(aNode, aPartlyContained)){
var copyrightLink = '<br /><br /> - Read more at: '+document.location.href+'<br />©2012 <? printf($product. ' & ' .$spOrganization); ?>';
var copytext = selection + copyrightLink;
var extra = document.createElement("div");
extra.style.position="absolute";
extra.style.left="-99999px";
theBody.appendChild(extra);
extra.innerHTML = copytext;
selection.selectAllChildren(extra);
window.setTimeout(function() {
theBody.removeChild(extra);
},0);
}
}
document.oncopy = appendCopyright;
Related
Is this possible? Or is there a way to tack on and ID to an existing div?
This is my code. I can't get the code to work using classes, but I found when I used getElementById and changed the div to an ID, that it did. But I have a ton of already posted stuff so it would take forever to go through all those posts and change it manually to an ID.
Can I incorperate JQuery in this and still have it work? I tried that with something I stumbled across but it didn't work so I removed it. I don't remember what it is now though. :S
<div id="imdb" class="imdb">tt2382396</div>
<script>
function imdbdiv() {
var imdbmain = "http://www.imdb.com/title/";
var end = "/#overview-top";
var idnum = document.getElementsByClassName("imdb");
var newdiv = document.createElement("div");
var done = "<a href='" + imdbmain + idnum + end + "'>IMDB</a>";
newdiv.innerHTML = done;
document.body.appendChild(newdiv);
}
window.onload = imdbdiv();
</script>
Can anyone help. I cannot for the life of me figure this out.
JsFiddle
Your problem was, you were appending the collection returned by document.getElementsByClassName instead of looping through the elements in the collection. You can verify this by looking at the href property of the link in your jsFiddle. You must loop through the values, then access the data in their innerHTML property.
You can use document.querySelectorAll to get a list of all elements matching a certain CSS selector, in your case .imdb. This is more flexible, in case you want to select elements with more than one class. I've pasted the code from the updated jsFiddle below.
function imdbdiv() {
var imdbMain = "http://www.imdb.com/title/",
end = "/#overview-top",
imdbValueDivs = document.querySelectorAll('.imdb'),
length = imdbValueDivs.length,
// Iterator values
i,
newDiv,
newLink;
// Loop over all of your link value containers
for (i = 0; i < length; i++) {
// Create the container
newDiv = document.createElement('div');
// Create the new link
newLink = document.createElement('a');
newLink.href = imdbMain + imdbValueDivs[i].innerHTML + end;
newLink.innerHTML = "My favorite film";
// Add the link to the container,
// and add the container to the body
newDiv.appendChild(newLink);
document.body.appendChild(newDiv);
}
}
window.onload = imdbdiv();
If you have many such divs on your page, then it could be like this:
<div class="imdb">tt2382396</div>
<div class="imdb">tt2382396</div>
<div class="imdb">tt2382396</div>
<script>
function imdbdiv() {
var imdbmain = "http://www.imdb.com/title/";
var end = "/#overview-top";
var idnums = document.getElementsByClassName("imdb");
for (var i =0; i < idnums.length; i++) {
var newdiv = document.createElement("div");
var done = "<a href='" + imdbmain + idnums[i].innerText + end + "'>IMDB</a>";
newdiv.innerHTML = done;
document.body.appendChild(newdiv);
}
}
window.onload = imdbdiv();
</script>
See jsfiddle
UPDATE:
The following string was incorrect:
window.onload = imdbdiv;
Okay, so your question is a little bit unclear.
The way I understood your question is that you have a whole bunch of div elements with class attribute and what you want is to simply copy the class value to the id attribute of the div elements.
If that's correct then try something like this with jquery:
<script>
$(document).ready(function(){
$(".imdb").each(function(imdbDiv){
var classValue = imdbDiv.attr("class");
imdbDiv.attr("id", classValue);
});
});
</script>
I'm using following code to add my copyright when a text get selected in my website. Everything works well, except that if user selects an area which has link, getSelection() method does not return the link. It just returns the plain text.
I want to allow user to copy my website content as usual, without disturbing the style and content. I'm just looking for a way to add a copyright to the end of selection.
Any way?
Regards
<script type="text/javascript">
function addLink() {
var body_element = document.getElementsByTagName('body')[0];
var selection;
selection = window.getSelection();
var pagelink = "<br /><br /> Read more at: <a href='"+document.location.href+"'>"+document.location.href+"</a><br />Copyright © c.bavota"; // change this if you want
var copytext = selection + pagelink;
var newdiv = document.createElement('div');
newdiv.style.position='absolute';
newdiv.style.left='-99999px';
body_element.appendChild(newdiv);
newdiv.innerHTML = copytext;
selection.selectAllChildren(newdiv);
window.setTimeout(function() {
body_element.removeChild(newdiv);
},0);
}
document.oncopy = addLink;
</script>
You need to get the HTML of the selection, instead of the text, then you can append your link.
Have a look at this question.
The HTML code looks like this
<div id="txtarea" contenteditable="true">Some text</div>
I have to insert some new text based on some event at a particular position in the above div.
The event calls the function say updateDiv(txt, positon). For example it says
updateDiv("more ",5);
So the div should become be
<div id="txtarea" contenteditable="true">Some more text</div>
I tried a lot of javascript and jquery but nothing seem to work.
If the content of your editable <div> always consists of a single text node, this is relatively simple and you can use the code below.
var div = document.getElementById("txtarea");
var textNode = div.firstChild;
textNode.data = textNode.data.slice(0, 5) + "more " + textNode.data.slice(5);
Otherwise, you'll need to read about DOM Ranges (note that they are not supported in IE < 9) and use something like this answer to create a range corresponding to character indices within the content and then use insertNode().
var div = document.getElementById("txtarea");
var range = createRangeFromCharacterIndices(div, 5, 5);
range.insertNode(document.createTextNode("more "));
Here's how I did it:
var position = 5,
txt = "more ";
var current = $("#txtarea").html();
//alert(current.substring(0, position))
var endVal = current.substring(position);
var newValue = current.substring(0, position) + txt + endVal;
$("#txtarea").html(newValue);
jsfiddle displaying it 'in action'.
Edit: Updated the jsfiddle with the approach listed in a comment above to this post. Pretty slick!
use this function :
String.prototype.splice = function( position, newstring ) {
return (this.slice(0,position) + newstring + this.slice(position));
};
and use this function as :
var oldstr=$('#txtarea').html();
var newstr='more';
var position = 5;
$('#txtarea').html(oldstr.splice(position , newstr);
i'm trying to make a live search for my mobile website, I don't want to query the database every time a user type a letter so I created a ordered list with all the names that can be searched for and i'm looping through it with jquery, problem is that I have 3300 names and it's freezing the browser when it searches through them, can anyone give me a tip about better ways to do it? here is my code:
$(document).ready(function(){
$("input#search").keyup(function(){
var filter = $(this).val(), count = 0;
var html = "";
$("ol.pacientes li").each(function(){
var nome_paciente = $(this).text();
if(nome_paciente.indexOf(filter.toUpperCase()) != -1){
html = html + " " + nome_paciente;
}
$('#pacientes_hint').html(html);
});
Use the jQuery autocomplete version. You can load an array with all your names and pass it in to autocomplete, which will work on the fly.
http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/
You could change your each to:
var text = $("ol.pacientes li:contains(\""+filter.toUpperCase()+"\")").map(function() {
return $(this).text();
}).join(' ');
$('#pacientes_hint').text(text);
Besides being shorter, the only improvement will be setting the contents of $('#pacientes_hint') only at the end, which could help.
Let me know if you need a more creative solution.
First of all, you could move #pacientes_hint outside the each function.
$(document).ready(function(){
$("input#search").keyup(function(){
var filter = $(this).val(), count = 0;
var html = "";
$("ol.pacientes li").each(function(){
var nome_paciente = $(this).text();
if(nome_paciente.indexOf(filter.toUpperCase()) != -1){
html = html + " " + nome_paciente;
} // end if
}); // end each
$('#pacientes_hint').html(html);
Then, you can define ol.pacientes as a variable before the keyup handler, so it doesn't look for it everytime and in the each function, search inside the variable:
$(document).ready(function(){
var pacientes_list = $("ol.pacientes");
var pacientes_hint = $("#pacientes_hint");
$("input#search").keyup(function(){
...
$("li", $(pacientes_list)).each(function(){ // search in the container
...
}); // end each
$(pacientes_hint).html(html);
I am doing a self print function by gathering all the HTML from the users screen and putting it into a variable which then displays a pop-up screen so the user can print that information.
var disp_setting = "toolbar=no,location=no,directories=no,menubar=no,";
disp_setting += "scrollbars=yes, height=500, left=100, top=25";
var content_vlue = document.getElementById("print_content").innerHTML;
var docprint = window.open("", "", disp_setting);
docprint.document.open();
docprint.document.write('<html><head>');
docprint.document.write('</head><body text="#000000" onLoad="self.print()">');
docprint.document.write('<table>');
docprint.document.write(content_vlue);
docprint.document.write('</table>');
docprint.document.write('</body></html>');
docprint.document.close();
UPDATE:
OK thanks to many of the suggestions so far I'm starting to make some headway...
What I would like to do is instead of manipulating print_content, I would like to put print_content into a variable (i.e. content_vlue) and then manipulate content_vlue.
var content_vlue = document.getElementById("print_content").innerHTML;
$("content_vlue").find("INPUT[type='text']").each(function(i){
var input = $(this);
input.replaceWith("<span class='textinput'>" + input.val() + "</span>";
});
Is there a way to do this?
Can you use a library like jQuery? It would be pretty straight forward to replace the inputs with span tags once you'd created the page:
function cleaninputs(){
$("body").find("input").each(function(i) {
var input = $(this);
input.replaceWith("<span class='textInput'>" + input.val() + "</span>");
});
}
EDIT:
Here's a slightly refactored version which should do what you want:
function replaceInputs( _which ){
var cleanHTML = $("#"+_which).clone();
cleanHTML.find("input").each(function() {
var input = $(this);
input.replaceWith("<span class='textInput'>"+ " " + input.val() + "</span>");
});
return cleanHTML.html();
}
Then replace this line:
var content_vlue = document.getElementById("print_content").innerHTML;
with:
var content_vlue = replaceInputs("print_content");
And you should be all set. For good measure I made a jsfiddle: http://jsfiddle.net/pcsF3/1/
Using only CSS you can simply hide the border of the text boxes making it look like ordinary text:
docprint.document.write('<style type="text/css"> input { border: 0; }</style>');