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>');
Related
I've got again a rather simple question, that I couldn't find an answer to.
I was using sofar the Jquery function .text() to write text on mouseenter on a dynamically created div. I came to realise that this only worked on my Iceweasel, but not in Chrome for instance. Instead ot .text() everywhere people advised of using the .val(), but I can't seem to figure out exactly how to use it in my implementation, since the divs had no previous text value.
Please find below a simple code, with .text() to understnad the question.
(function(){
for (var i = 0; i < 3; i++) {
var span = document.createElement("span");
span.innerHTML = "<img width=\"" + data.size[i][0] + "\" height=\"" + data.size[i][1] + "\" id=\"" + i + "\">";
span.style.position = "absolute";
span.style.left = data.coords[i][0] + "px";
span.style.top = data.coords[i][1] + "px";
document.body.appendChild(span);
}
}());
for (var i=0; i<3; i++) {
$('#' + i).mouseenter(function() {
$(this).text("text");
});
$('#' + i).mouseleave(function() {
$(this).text("")
});
}
http://jsfiddle.net/ckpx6esj/1/
I hope someone can give me an idea, of how to apply .val() or use something else entirely to make this work for chrome also.
Best Regards and Thanks in advance!
The problem is that you put text in an image tag!
<img>Some text</img>
This is invalid HTML, see this answer.
If you want text over an image, I suggest using a div with background: url(...) instead.
Updated fiddle.
The cleverest I could think to don't screw up your for loop is appending a <p> tag containing your text and removing it on mouseleave:
for (var i=0; i<3; i++){
$('#' + i).on("mouseenter",function() {
$(this).parent().append("<p>text</p>");
});
$('#' + i).on("mouseleave",function() {
$(this).parent().find("p").remove();
});
}
Fiddle:
http://jsfiddle.net/ckpx6esj/2/
Besides, text was not working because you are listening to the image (<img>) instead of the span. Images has no .text() prototype, hence you should access its parent() (which is a <span> in that case) if you want to use the .text() prototype, but using .text() on the parent will remove the image, hence the idea of appending the text and removing it later.
According to specification, val() function is to set value attribute and it only matters for input fields on your page. text() function is to change content of your element.
The .val() method is primarily used to get the values of form elements
such as input, select and textarea.
So you should use text() function in your code.
Also according to your code you change text property of <img> element. This is not good. You should change text of your <span>. So just move your id to span element.
If you want the jQuery equivalent of Javascript's native innerHtml, go for $(this).html('text');.
Take a look at these functions:
http://api.jquery.com/html/
$(this).html('text');
http://api.jquery.com/append/
$(this).append('text'); // Note that this appends instead of replaces
http://api.jquery.com/val/
$(this).val('text');
Or if you're feeling adventurous:
http://api.jquery.com/appendto/
$('text').appendTo($(this)); // Performance penalty for creating an object out of 'text'
First I will use class instead id, it will save using the second loop,
also if you want to have also text and also image you can do it but it will be littel complicated I would recommand add some child element to the span that will contain the text, I didnt do it just for the challenge
http://jsfiddle.net/ckpx6esj/5/
simple plugin to change the text without changing the html elements
$.fn.selectorText = function(text) {
var str = '';
this.contents().each(function() {
if (this.nodeType === 3) {
if(typeof(text) === 'string'){
this.textContent = text;
return false;
}else{
str += this.textContent || this.innerText || '';
}
}
});
return str;
};
var thisData = [{
'coords' : [[100,100], [300, 300], [200, 200]],
'size' : [[30, 30], [30, 30], [30, 30]]
}];
var data = thisData[0];
(function(){
for (var i = 0; i < 3; i ++){
var span = document.createElement("span");
span.setAttribute('class','spanImage');
span.style.position = "absolute";
span.style.left = data.coords[i][0] + "px";
span.style.top = data.coords[i][1] + "px";
span.innerHTML = "\n<img width=\"" + data.size[i][0] + "\" height=\"" + data.size[i][1] + "\" id=\"" + i + "\">";
document.body.appendChild(span);
}
$('.spanImage')
.on( 'mouseenter', function() {
$(this).selectorText('text');
})
.on( 'mouseleave', function() {
$(this).selectorText('');
});
}());
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;
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 scoured the the site and found a few examples, I got close but not close enough.
I have 2 checkboxes and if a user checks them they are placed in the textarea, if the user removes the check. the value is removed. I want to keep cursor position too.
I am able to add but its still clunky.
My fiddle is http://jsfiddle.net/pU2P9/18/
here is my code
Testing. Values from another field will be inserted here.
<form>
<p>Favorite Color <label><input type="checkbox" value="Green" />Green</label>
<label><input type="checkbox" value="Red" />Red</label></p>
</form>
var textarea = document.getElementById("myTextArea1");
// $('input[type=checkbox]').click(function () {
$('input[type=checkbox]').change(function () {
var $parentForm = $(this).closest("form");
// var text = $(".insert-text", $parentForm).val();
var text = $('input[type=checkbox]:checked').val() + " ";
// var text = $('input[type=checkbox]:checked', $parentForm).val() + " ";
insertAtCursor(textarea, text);
});
function insertAtCursor(myField, myValue) {
if (document.selection) {
myField.focus();
sel = document.selection.createRange();
sel.text = myValue;
}
else if (myField.selectionStart || myField.selectionStart == '0') {
var startPos = myField.selectionStart;
var endPos = myField.selectionEnd;
myField.value = myField.value.substring(0, startPos) + myValue + myField.value.substring(endPos, myField.value.length);
}
else {
myField.value += myValue;
}
}
;
Any help would be appreciated.
Not sure exactly what you are trying to do, but it seems you're a little confused.
Try something like
$('input[type=checkbox]').change(function () {
if ($(this).is(':checked')) {
var text = $(this).val() + " ";
insertAtCursor(textarea, text);
}
});
I think you're going to drive yourself crazy trying to treat the textarea like you are. You can prepend the colors easily enough, but what do you do when the user un-checks them? For example, what if they check green, then red, then un-checks green? It's now no longer a simple matter of removing 5 characters from the textarea.
If I understand your application, though, you're combining values from different fields in the textarea, so I would do something like this:
function updateTextArea() {
var text = "";
$('input[type=checkbox]:checked').each( function() {
text += $(this).val() + " ";
});
$('input[type=text]').each( function() {
text += $(this).val() + " ";
});
$('#myTextArea1').val( text );
}
Then you can just call this every time one of your values changes. For example, when the user changes one of the check boxes:
$('input[type=checkbox]').change(function () {
updateTextArea();
});
I believe that this will be much cleaner than the approach you're outlining. You can see it in action here: http://jsfiddle.net/8y4D8/19/
Also, you could consider using Backbone.js (http://documentcloud.github.com/backbone/) or some similar Javascript MVC framework.
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);