I have variable containing some text.Basically I am trying to do toggle(hide/show) in html using c#.I want to pass this variable to javascript function that is performing hide and show .
Here is my code:
static void Main(string[] args)
{
string res = null;
string toggle = null;
res += "<div style=\"display: none;\">This is the content that is dynamically being collapsed.</div>";
toggle += "<html><head>";
toggle += "<script type=\"text/javascript\"></script><script> function toggle2(showDetails) {var ele =document.getElementById(showDetails);if(ele.style.display == \"block\") {ele.style.display = \"none\";}else {ele.style.display = \"block\";}}</script>";
toggle += "</head>";
toggle += "<body>";
toggle += "collapse";
toggle += "</body>";
toggle += "</html>";
FileStream log = new FileStream(#"E:\report2.html", FileMode.Create);
using (StreamWriter w = new StreamWriter(log, Encoding.UTF8))
{
w.WriteLine(toggle);
}
}
On clicking collapse,it should display the content of variable res.Where am I doing wrong?
Thanks in advance
You've got multiple issues:
The "quotes" inside your string are messing with the href="quotes"
Your JavaScript function is incorrect
The general approach is unusual/ very error-prone
Nitpicking: Don't use += and null
First, those quotes
Take a look at your file report2.html in your favourite text editor and you'll probably see this:
<a href="javascript:toggle2('<div style="display: none;">This is the content that is dynamically being collapsed.</div>')">
StackOverflow's code colouring helps here - notice that display:none; is black. This is because it's essentially seeing just href="javascript:toggle2('<div style="
A simple fix is to double-escape those quotes in your res string:
<div style=\\\"display: none;\\\">This is the content..
..but yikes. This kind of thing is really not recommended unless you have to!
Second, the function
I (and many others!) really dislike JavaScript inside a string like this - it promotes bad code formatting, for starters. Let's undo that and make it pretty:
function toggle2(showDetails) {
var ele =document.getElementById(showDetails);
if(ele.style.display == "block") {
ele.style.display = "none";
}else {
ele.style.display = "block";
}
}
That's better! So, firstly, showDetails is not an ID of an element - it's a full string of content. Pass an ID instead:
function toggle2(elementID) {
var ele =document.getElementById(elementID);
if(ele.style.display == "block") {
ele.style.display = "none";
}else {
ele.style.display = "block";
}
}
This way you can instead use, e.g:
toggle+="<div id='collapsibleDiv'>"+res+"</div>";
toggle+="<div onmousedown=\"toggle2('collapsibleDiv');\">Click me!</div>";
instead. A bonus here is that it doesn't need to deal with those quotes in res.
Null and +=
Right at the start you've got this:
string res=null;
res+="...";
It's safer to just use string res=".."; instead as adding a null to anything is bad practice. Some programming languages will straight crash on you.
Related
i'm trying to make some code that'll loop over html forum data and replace some brackets.
i'm basically trying to turn
<br><br>
<br>
<img src="blah"></img>
to
[br][br]
[br]
[img src="blah"][/img]
and avoid changing text like
:<
<("<) <(")> (>")>
I'm using javascript and a regex pattern for now. I was able to find a regex for something between two tags, but not two tags around a string. What would be the best way to do this?
There's probably a far more elegant way to do this - but this is basically how I did it in the early 2000's (slight update to more modern JS with const/let etc)
const input = `<br><br>
<br>
<img src="blah"></img>`;
const body = document.createElement('body');
body.innerHTML = input;
function square(obj) {
let out = '';
let el;
while(el = obj.firstChild) {
if (el.nodeType == 3) {
out += el.nodeValue;
} else {
out += `[${el.nodeName}]`;
out += square(el);
if (!["BR"].includes(el.nodeName)) {
out += `[/${el.nodeName}]`;
}
}
el.remove();
}
return out;
}
console.log(square(body));
I have this HTML button:
<button id="myButton" onClick="lock(); toggleText(this.id);">Lock</button>
And this is my toggleText JavaScript function:
function toggleText(button_id)
{
if (document.getElementById('button_id').text == "Lock")
{
document.getElementById('button_id').text = "Unlock";
}
else
{
document.getElementById('button_id').text = "Lock";
}
}
As far as I know, button text (<button id="myButton">Lock</button>) is just like any link text
(Lock). So the fact that it's a button doesn't matter. However, I can't access the button text and change it.
I tried ('button_id'), (button_id), == "Lock", == 'Lock', but nothing works.
How can I access and change a button text (not value) or a link text?
Change .text to .textContent to get/set the text content.
Or since you're dealing with a single text node, use .firstChild.data in the same manner.
Also, let's make sensible use of a variable, and enjoy some code reduction and eliminate redundant DOM selection by caching the result of getElementById.
function toggleText(button_id)
{
var el = document.getElementById(button_id);
if (el.firstChild.data == "Lock")
{
el.firstChild.data = "Unlock";
}
else
{
el.firstChild.data = "Lock";
}
}
Or even more compact like this:
function toggleText(button_id) {
var text = document.getElementById(button_id).firstChild;
text.data = text.data == "Lock" ? "Unlock" : "Lock";
}
document.getElementById(button_id).innerHTML = 'Lock';
You can simply use:
document.getElementById(button_id).innerText = 'Your text here';
If you want to use HTML formatting, use the innerHTML property instead.
Remove Quote. and use innerText instead of text
function toggleText(button_id)
{ //-----\/ 'button_id' - > button_id
if (document.getElementById(button_id).innerText == "Lock")
{
document.getElementById(button_id).innerText = "Unlock";
}
else
{
document.getElementById(button_id).innerText = "Lock";
}
}
I see examples for this all over, but for some reason, mine isn't working. I have a textbox that is added dynamically if a certain value is selected in a select list.
The part where the field shows up is working, but I am also trying to add some text to the box, which I can't get to work. I'm also trying to use JS to select the text once it's entered - but haven't gotten that far yet!
Is there something blatantly wrong with this?
function showBox() {
if (document.getElementById("ctl00_Content_WhereFound").value == "Other" || document.getElementById("ctl00_Content_WhereFound").value == "Friend/Employee Referral")
{
document.getElementById('ctl00_Content_WhereDetails').style.display = "inline";
if (document.getElementById("ctl00_Content_WhereFound").value == "Other") {
document.getElementById('ctl00_Content_WhereDetails').innerHTML += 'Enter Other';
} else {
document.getElementById('ctl00_Content_WhereDetails').innerText += "Enter Referral";
}
}
}
First thing I noticed was that you used 'innerHTML' in your if clause and 'innerText' in your else clause. Was that on purpose? They do different things...
It's a pain, but it might be worth using the document.createElement() etc functions to build/modify the dynamic content.
I've had trouble with similar stuff... in general, using the DOM functions rather than innerHTML often fixes it, though it is significantly more verbose. JQuery has some very helpful functions for this.
try this..
function showBox()
{
$Found = document.getElementById("ctl00_Content_WhereFound");
$Where = document.getElementById('ctl00_Content_WhereDetails');
if($Found.value == "Other" || $Found.value == "Friend/Employee Referral")
{
$Where.style.display = "inline";
if($Where.value == "Other")
{
$Where.value = 'Enter Other';
}else
{
$Where.value = "Enter Referral";
}
}
}
You can always assign elements to variables to shorten your code.
This looks like you're attempting to make a change to Asp.Net rendered controls. Make sure you have the actual id of the controls formatted correctly. Typically the UniqueID is formatted like ctl00_Content_WhereFound but the ClientID is formatted ctl00$Content$WhereFound.
innerText isn't supported by at least Firefox. Is there a reason you can't use innerHTML in both cases?
Also, you might want to store the element references to make your code cleaner and faster:
function showBox() {
var eFound = document.getElementById("ctl00_Content_WhereFound");
if (eFound.value == "Other" || eFound.value == "Friend/Employee Referral")
{
var eDetails = document.getElementById('ctl00_Content_WhereDetails');
eDetails.style.display = "inline";
if (eFound.value == "Other") {
eDetails.innerHTML += 'Enter Other';
} else {
eDetails.innerHTML += "Enter Referral";
}
}
}
I have a basic show/hide javascript that works, as long as i don't make it dynamic and make sure of a parameter. I would appreciate a lot if anyone could help me figure out why the dynamic version doesn't work.
Working code:
javascript
function togglesDiv(){
var catdiv = document.getElementById("addNewCat");
if(catdiv.style.display == ""){
catdiv.style.display = "none";
} else {
catdiv.style.display = "";
}
}
html
<span onclick="togglesDiv();">Add new category</span>
<div id="addNewCat" style="display: none;">
lalala
</div>
Non working code:
javascript
function togglesDiv(divsId){
var catdiv = document.getElementById("divsId");
if(catdiv.style.display == ""){
catdiv.style.display = "none";
} else {
catdiv.style.display = "";
}
}
html
<span onclick="togglesDiv(addNewCat);">Add new category</span>
<div id="addNewCat" style="display: none;">
lalala
</div>
You have a variable name wrapped in string delimiters, making it a string literal instead of a variable. Change
var catdiv = document.getElementById("divsId");
To
var catdiv = document.getElementById(divsId);
On the flipside, the call to the function needs the quotes in it's argument (because it should be a string), you can use single quotes to avoid confliction:
<span onclick="togglesDiv('addNewCat');">Add new category</span>
Your code is looking for a div with an ID "divsId" change your code to:
function togglesDiv(divsId){
var catdiv = document.getElementById(divsId);
if(catdiv.style.display == ""){
catdiv.style.display = "none";
} else {
catdiv.style.display = "";
}
}
Because you are looking for a div called "divsId" rather than the value in the variable divsId.
Remove the speach marks!
Remove quotes from
var catdiv = document.getElementById("divsId");
should be
var catdiv = document.getElementById(divsId);
And add quotes:
<span onclick="togglesDiv(addNewCat);">Add new category</span>
Should be
<span onclick="togglesDiv('addNewCat');">Add new category</span>
Remove the quotes:
var catdiv = document.getElementById("divsId");
Becomes
var catdiv = document.getElementById(divsId);
You don't have an element with an ID of "divsId".
On a completely unrelated note, you can't be sure that catdiv.style.display will always be equal to "" when it is visibile. There are other styles which cause it to be displayed ('inline', 'block', for example).
A better solution might be:
function togglesDiv(divsId){
var catdiv = document.getElementById("divsId");
if(catdiv.style.display === "none"){
catdiv.style.display = "";
} else {
catdiv.style.display = "none";
}
}
(And yes, I did mean to put the triple equals === in)
Improved function
function toggleDisplay(id){
var el = document.getElementById(id);
if(!el) return true;
// feature detect to support IE versions.
var dis = 'currentStyle' in el ? el.currentStyle.display : el.style.display;
// toggle display
el.style.display = /none/i.test(dis) ? '' : 'none';
// prevent memory leak
el = null;
}
And as mentioned, quotes are needed when writing yucky inline javascript.
<span onclick="toggleDisplay('addNewCat')"> ... etc
Tbh. pick a js toolkit/library and use it over reinventing the wheel yourself and stop writing inline javascript, your life and happiness will improve substantially if you do =P
I was wondering if it is possible to use JavaScript to add a <div> tag around a word in an HTML page.
I have a JS search that searches a set of HTML files and returns a list of files that contain the keyword. I'd like to be able to dynamically add a <div class="highlight"> around the keyword so it stands out.
If an alternate search is performed, the original <div>'s will need to be removed and new ones added. Does anyone know if this is even possible?
Any tips or suggestions would be really appreciated.
Cheers,
Laurie.
In general you will need to parse the html code in order to ensure that you are only highlighting keywords and not invisible text or code (such as alt text attributes for images or actual markup). If you do as Jesse Hallett suggested:
$('body').html($('body').html().replace(/(pretzel)/gi, '<b>$1</b>'));
You will run into problems with certain keywords and documents. For example:
<html>
<head><title>A history of tables and tableware</title></head>
<body>
<p>The table has a fantastic history. Consider the following:</p>
<table><tr><td>Year</td><td>Number of tables made</td></tr>
<tr><td>1999</td><td>12</td></tr>
<tr><td>2009</td><td>14</td></tr>
</table>
<img src="/images/a_grand_table.jpg" alt="A grand table from designer John Tableius">
</body>
</html>
This relatively simple document might be found by searching for the word "table", but if you just replace text with wrapped text you could end up with this:
<<span class="highlight">table</span>><tr><td>Year</td><td>Number of <span class="highlight">table</span>s made</td></tr>
and this:
<img src="/images/a_grand_<span class="highlight">table</span>.jpg" alt="A grand <span class="highlight">table</span> from designer John <span class="highlight">Table</span>ius">
This means you need parsed HTML. And parsing HTML is tricky. But if you can assume a certain quality control over the html documents (i.e. no open-angle-brackets without closing angle brackets, etc) then you should be able to scan the text looking for non-tag, non-attribute data that can be further-marked-up.
Here is some Javascript which can do that:
function highlight(word, text) {
var result = '';
//char currentChar;
var csc; // current search char
var wordPos = 0;
var textPos = 0;
var partialMatch = ''; // container for partial match
var inTag = false;
// iterate over the characters in the array
// if we find an HTML element, ignore the element and its attributes.
// otherwise try to match the characters to the characters in the word
// if we find a match append the highlight text, then the word, then the close-highlight
// otherwise, just append whatever we find.
for (textPos = 0; textPos < text.length; textPos++) {
csc = text.charAt(textPos);
if (csc == '<') {
inTag = true;
result += partialMatch;
partialMatch = '';
wordPos = 0;
}
if (inTag) {
result += csc ;
} else {
var currentChar = word.charAt(wordPos);
if (csc == currentChar && textPos + (word.length - wordPos) <= text.length) {
// we are matching the current word
partialMatch += csc;
wordPos++;
if (wordPos == word.length) {
// we've matched the whole word
result += '<span class="highlight">';
result += partialMatch;
result += '</span>';
wordPos = 0;
partialMatch = '';
}
} else if (wordPos > 0) {
// we thought we had a match, but we don't, so append the partial match and move on
result += partialMatch;
result += csc;
partialMatch = '';
wordPos = 0;
} else {
result += csc;
}
}
if (inTag && csc == '>') {
inTag = false;
}
}
return result;
}
Wrapping is pretty easy with jQuery:
$('span').wrap('<div class="highlight"></div>'); // wraps spans in a b tag
Then, to remove, something like this:
$('div.highlight').each(function(){ $(this).after( $(this).text() ); }).remove();
Sounds like you will have to do some string splitting, though, so wrap may not work unless you want to pre-wrap all your words with some tag (ie. span).
The DOM API does not provide a super easy way to do this. As far as I know the best solution is to read text into JavaScript, use replace to make the changes that you want, and write the entire content back. You can do this either one HTML node at a time, or modify the whole <body> at once.
Here is how that might work in jQuery:
$('body').html($('body').html().replace(/(pretzel)/gi, '<b>$1</b>'));
couldn't you just write a selector as such to wrap it all?
$("* :contains('foo')").wrap("<div class='bar'></div>");
adam wrote the code above to do the removal:
$('div.bar').each(function(){ $(this).after( $(this).text() ); }).remove();
edit: on second thought, the first statement returns an element which would wrap the element with the div tag and not the sole word. maybe a regex replace would be a better solution here.