I have an old asp page that had a small image that could be clicked to change some selected text in a form text input box to italics using javascript. This was working fine for many years, but a user just informed me that it no longer seems to be working. In looking around for a solution, it seems the createRange() function is no longer supported by many current browsers, causing the browser to throw an error, and getSelection() should now be used instead.
The old script is listed below.
<script type="text/javascript">
var j; // this is the currently selected form element i.e., line number
function getelement_num(k) {
j = k;
return;
}
function format_sel(v) {
var str = document.selection.createRange().text;
document.form1.strMessage.focus();
var sel = document.selection.createRange();
sel.text = "[" + v + "]" + str + "[/" + v + "]";
return;
}
</script>
I have modified the format_sel function as follows:
function format_sel(v) {
var str = window.getSelection().toString;
document.FrontPage_Form2.elements[j].focus();
var sel = window.getSelection().toString;
sel.text = "<" + v + ">" + str + "</" + v + ">";
return;
}
So, the getSelection() seems to be working fine. If I alert(sel), it returns the selected text. However, the sel.text portion is not replacing the selected text in the input field of the form.
My question is, how should I modify the code above so that the selected text in the form input field will be replaced with the modified text as found in sel.text?
Pertinent HTML code (with only 1 of 9 form fields shown for brevity):
<a title="Select text in fields below and then click this button to add Italics" href="#" onclick="format_sel('i');" ><img alt="Select text in fields below and then click this button to add Italics" border="0" src="images/italic.gif" width="21" height="19" align="middle" class="style33" /></a>
<input name="Title" id="Title" type="text" placeholder="Add Title" style="border: 1px solid #B5DB38; width: 250px" onfocus="lastFocus=this; getelement_num('0');" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" /></td>
I should note that I also have code that will insert special characters into the form as well, which is what the storeCaret code is for. That seems to work fine.
Many thanks for the assistance.
There seem to be two types of problem with this code.
The first one is that if you want to get the string value of the selection, you should use toString() instead of toString. Using the latter will give you a reference to the function toString instead of the returned value. I don't know what your alert function is calling, but it doesn't seem correct.
The second problem is that your sel variable is currently a function, and even if you did it correctly (using toString()) you would get a string which has no .text attribute. What you should be calling there is actually
var sel = window.getSelection();
So that you get a reference to the Html Element, which does have the .text attribute.
Ok, in searching around a little bit, I found some code that seems to work. I modified it slightly for my own purposes (see below), but the original code by Er. Anurag Jain can be found here: https://stackoverflow.com/a/11170137/2121627.
Many thanks as well to #user2121627 for their suggestions on amending and testing the code.
<script type="text/javascript">
var j; // this is the currently selected form element i.e, line number
function getelement_num(k) {
j = k;
return;
}
function format_sel(v) {
var elem = document.FrontPage_Form2.elements[j];
var start = elem.selectionStart;
var end = elem.selectionEnd;
var len = elem.value.length;
var sel_txt = elem.value.substring(start, end);
if (sel_txt != "") {
document.FrontPage_Form2.elements[j].focus();
var replace = "<" + v + ">" + sel_txt + "</" + v + ">";
elem.value = elem.value.substring(0, start) + replace + elem.value.substring(end, len);
}
}
</script>
Here is a jsfiddle for those interested: https://jsfiddle.net/jwfetz/kzcywvnh/42/
Related
I'm trying to add parameters to an onclick function when generating HTML via javascript. When I inspect the code it is putting a quotation mark in the onclick function's parameter.
var lengthOfCats = ArrayOfCategories.length;
for (var a = 0; a < lengthOfCats; a++) {
$("#CatTable").append("<div class='better-table-cell'>" + ArrayOfCategories[a].Name + "</div>\
<div class='better-table-cell'>" + ArrayOfCategories[a].DepartmentName + "</div>\
<div class='better-table-cell'>" + ArrayOfCategories[a].Active + "</div>\
<div class='better-table-cell'>\
<button onclick=OpenUpdateCat(" + ArrayOfCategories[a].CategoryID + "," + ArrayOfCategories[a].Name + ");" + ">Edit</button>\
</div>");
Here is an image of the HTML that is getting generated for the edit button.
The browser is normalising the HTML and putting quote marks around the attribute value.
The problem is that because the attribute value includes spaces, and you didn't put the quote marks in the right spots yourself, the attribute value finishes in the middle of the JavaScript.
The next bit of JS is then treated as a new attribute.
Mashing together strings to generate HTML is fundamentally a bad idea. Ensuring all the right things are quoted and escaped is hard.
Use DOM to generate your HTML instead.
It is a little longer, but clearer and easier to maintain in the long run.
var $cat_table = $("#CatTable");
var lengthOfCats = ArrayOfCategories.length;
for (var a = 0; a < lengthOfCats; a++) {
$cat_table.append(
$("<div />").addClass("better-table-cell").text(ArrayOfCategories[a].Name)
);
$cat_table.append(
$("<div />").addClass("better-table-cell").text(ArrayOfCategories[a].DepartmentName)
);
$cat_table.append(
$("<div />").addClass("better-table-cell").text(ArrayOfCategories[a].Active)
);
$cat_table.append(
$("<div />").addClass("better-table-cell").append(
$("<button />").text("Edit").on("click", generate_edit_handler(ArrayOfCategories[a].CategoryID, ArrayOfCategories[a].Name))
)
);
}
function generate_edit_handler(cat_id, name) {
return function () {
OpenUpdateCat(cat_id, name);
};
}
I am trying to pass arguments to onclick event of dynamically generated element. I have already seen the existing stackoveflow questions but it didn't answer my specific need.In this existing question , they are trying to access data using $(this).text(); but I can't use this in my example.
Click event doesn't work on dynamically generated elements
In below code snippet, I am trying to pass program and macroVal to onclick event but it doesn't work.
onClickTest = function(text, type) {
if(text != ""){
// The HTML that will be returned
var program = this.buffer.program;
var out = "<span class=\"";
out += type + " consolas-text";
if (type === "macro" && program) {
var macroVal = text.substring(1, text.length-1);
out += " macro1 program='" + program + "' macroVal='" + macroVal + "'";
}
out += "\">";
out += text;
out += "</span>";
console.log("out " + out);
$("p").on("click" , "span.macro1" , function(e)
{
BqlUtil.myFunction(program, macroVal);
});
}else{
var out = text;
}
return out;
};
console.log of out give me this
<span class="macro consolas-text macro1 program='test1' macroVal='test2'">{TEST}</span>
I have tried both this.program and program but it doesn't work.
Obtain values of span element attributes, since you include them in html:
$("p").on("click" , "span.macro" , function(e)
{
BqlUtil.myFunction(this.getAttribute("program"),
this.getAttribute("macroVal"));
});
There are, however, several things wrong in your code.
you specify class attribute twice in html assigned to out,
single quotes you use are not correct (use ', not ’),
quotes of attribute values are messed up: consistently use either single or double quotes for attribute values
var out = "<span class='";
...
out += "' class='macro' program='" + program + "' macroVal='" + macroVal + ;
...
out += "'>";
depending on how many times you plan to call onClickTest, you may end up with multiple click event handlers for p span.macro.
Is there any way to increase Chromes default 524288 character limit for text input elements? (Seems to also occur in Safari, so I'm assuming it's WebKit related)
For context, I'm using this input to hold a base64 encoded image. Unfortunately I need to use an input element due to the situation, so just using a hidden element isn't an option.
To demonstrate, in WebKit browsers these number will not match, every other browser doesn't seem to limit the input. Is there a way to work around this?
$(document).ready(function(){
// Build a really long string
var reallyLongString = "abcdefghijklmnopqrstuvwxyz";
for(var i = 0; i < 15; i++){
reallyLongString = reallyLongString + reallyLongString;
}
// The important bit
$("#inputElement").val(reallyLongString);
$("#quantityDisplay").html(
"Actual length: " + reallyLongString.length +
"<br />" +
"Input length: " + $("#inputElement").val().length
);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="inputElement" type="text" />
<div id="quantityDisplay"></div>
You can use a hidden input instead if the value is from js not users.
It appears this restriction doesn't apply to the textarea element, which can be substituted in and will work correctly.
$(document).ready(function(){
// Build a really long string
var reallyLongString = "abcdefghijklmnopqrstuvwxyz";
for(var i = 0; i < 15; i++){
reallyLongString = reallyLongString + reallyLongString;
}
// The important bit
$("#inputElement").val(reallyLongString);
$("#quantityDisplay").html(
"Actual length: " + reallyLongString.length +
"<br />" +
"Input length: " + $("#inputElement").val().length
);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="inputElement" type="text"></textarea>
<div id="quantityDisplay"></div>
I'm trying to create a simple web page in JavaScript, HTML, and CSS. The web page generates 5 div elements. Each div element includes a random number, text input, and submit button. My code below does that.
The user then should be able to enter the random number into the text input box and click the submit button. The script should check if they entered the correct answer or not.
I'm not sure if this is possible? I understand how to write the code for just a single form on the page but this example is using 5 forms on a single page that are dynamically generated. Any help would greatly be appreciated.
<html>
<head>
<style type="text/css">
#test {
width:250px;
padding:10px;
border:5px solid gray;
margin:10px;
}
</style>
</head>
<body>
<script>
for (i = 0; i < 5; i++) {
document.write('<div id="test">');
var ranNum = Math.floor(Math.random()*10);
document.write(ranNum);
document.write("<p>Enter the number above:</p>");
document.write("<form id=\"form1\" name=\"form1\" method=\"post\" action=\"\"><input type=\"text\" name=\"answer\" id=\"answer\" /><input type=\"submit\" name=\"button\" id=\"button\" value=\"Submit\" /></form>");
document.write('</div>');
}
</script>
</body>
</html>
You don't even interact with the server to check if it was the correct answer.
So, yes, you can easily do that.
Use jquery, make those numbers properties to a global object, properties named after #id of your inputs, so when user clicks, just compare the value of input with the property of your global object with the same name.
eg:
window.myObject = {}
myObject.div1 = // your code for random number
myObject.div2 = // again, code for random number
And so on, even better put your random number code into a function and call
it for each property.
then just set the divs values as properties:
$("div.div1").append("<span class='value'>" + myObject.div1 + "</span>");
Or maybe even you could create a loop to do it so you don't need to type it for all divs.
After that, test your inputs:
$("div.div1").find("submit").click(function(){
// here you collect the data from your form, lazy to type
// and test it for equality with coresponding myObject.div1
// or with the value in <span class="value>
//e.g.
if ($(this).parent().find(".mytextinput").val() == $(this).parent().find("span.value").val())
{ //do something} else {//do something else }
});
Of course, this presumes you can use jquery.
as has been pointed out in the comments, make sure id's are always unique. I wouldn't use ajax for something this simple, you can check the values client side. See below for a working solution.
for (i = 0; i < 5; i++) {
document.write('<div id="div-' + i + '">');
var ranNum = Math.floor(Math.random()*10);
document.write(ranNum);
document.write("<p>Enter the number above:</p>");
document.write("<form id=\"form-" + i + "\" name=\"form-" + i + "\"><input type=\"text\" name=\"answer\" id=\"answer-" + i + "\" /><input type=\"submit\" name=\"button\" id=\"button-" + i + "\" value=\"Submit\" onclick=\"checkAnswer(this); return false;\"/></form>");
document.write('</div>');
}
function checkAnswer(element) {
var thisAnswer=element.form.parentElement.textContent.substring(0,1);
var answerGiven=element.form.children[0].value;
if (thisAnswer==answerGiven) {
alert("correct!");
} else {
alert("wrong!");
}
}
Noob question alert! So, I've got this script, which loops through an array and adds a <br> tag to the end of each array item. But i dont know the proper way of displaying this output on my page. Currently, when it loads the <br> tags show up on screen, whereas I want them to render as line-breaks. It is outputting into a <textarea> if that makes a difference. Thanks a bunch.
var outputLinkText = document.getElementById('outputLinkText');
var outputStageOne = "";
for (var i = 0; i < arrayOne.length; i++) {
outputStageOne += (arrayOne[i] + "<br>");
}
if ( 'textContent' in timePlace ) {
outputLinkText.textContent = outputStageOne;
}
else {
outputLinkText.innerText = outputStageOne;
}
<textarea> tags don't support <br> tags (or any other HTML tags) within their contents. They only hold plain text.
You need to add "\n" as the separator instead.
(Strictly, it should be "\r\n" but a "\n" on its own is usually sufficient)
Yes the textarea is a difference, try this :
"\r\n" instead of "<br>"