IE not updating code after jQuery? - javascript

I have a calendar asp page that users schedule times and everyone's times are displayed on this table (similar to Google calendar but only month view). I have it up and running and it works great but I need to edit the page on printing to ensure everything fits on one page. The table is generated through an ASP loop but here is basic structure
<table id='calendar' class="cal">
<tr class="cal">
<td class="cal" onclick="shoForm('5_10');">10
<div class="cellDiv" id="5_10"></div>
</td>
</tr>
</table>
I populate this table using jQuery and AJAX so an example item under one of the cells could be like so:
<div id='1' class='item'>
<span name='itmUserName' id='User1'>User1</span>
<span class='dnPrint'><br/></span>
Project: <span name='tasks' id='2'>Reviewing</span>1.5 hrs
</div>
In jQuery, then I append items to cells like so (where curItemDay is the date for the item):
$("#"+curItemDay).append(
"<div id='"...see above.../div>"
);
Now this all works fine and dandy and visually the web page loads perfect. However, I am trying to hide certain pieces when they click on a "Print" button.
function printThis(){
var names=document.getElementsByName("itmUserName");
for(var i=0;i<names.length;i++){
if(names[i].innerHTML.split(" ").length>1)
names[i].innerHTML=names[i].innerHTML.charAt(0)+names[i].innerHTML.split(" ")[1].charAt(0);
names[i].innerHTML="["+names[i].innerHTML+"] ";
}
...more code....
}
This works fine in FF but in IE it does not work. When I look through the code in IE using the developer console (F12) it doesn't even show the items that were added via jQuery. The page loads and displays everything, but the code doesn't seem to be reflecting what is on the page.
<td class="cal" onclick="shoForm('5_16');">
Text - 16
<div class="cellDiv" id="5_16"/>
</td>
NOTE: IE version is 8.0.6001.18702

You are excessively abusing the innerHTML property.
Instead, why not do something like this:
<span name="itmUserName"><span class="printOn">[</span>J<span class="printOff">ohn </span>S<span class="printOff">mith</span><span class="printOn">]</span></span>
Then use this CSS:
#media screen {.printOn {display:none}}
#media print {.printOff {display:none}}
This will show/hide the relevant parts when the user is printing or viewing on-screen.

I found the answer here: Accessing getElementsByName array after Jquery Ajax IE
Changed
var names=document.getElementsByName("itmUserName");
To
var names=$('[name="itmUserName"]');
And now it works like it should.

Related

Are there reasons that Javascript can only access some of the new DOM after Ajax?

I am just learning JS and while implementing AJAX I ran into some strange behavior.
In my code I have the following
<div id="saved_listing_form"></div>
an onchange in a select element runs a script where ajax fills the above div with a preview of the saved listing along with a form populated with fields that can be edited in order to edit the listing if desired.
There is a button in the form that is used to preview the changes to the listing before saving them.
Below is the code that will be populated by the "preview" script that does not respond to JS
<article class="listing" id="listing_preview" style="display:none;" title="">
<a href="" id="preview_url" target="_blank"><img id="preview_picture" src="" alt=""><h3 id="preview_name"></h3>
<span id="preview_phone"></span><address><span id="preview_address_1"></span><br><span id="preview_address_2"></span>
<span id="preview_city_state_zip"></span></address>
</a>
</article>
I tried manipulating the listing through the console in Firefox as a last resort. The console is able to find the article,
document.getElementById('listing_preview')
but cannot produce changes in the DOM
document.getElementById('listing_preview').style.display = 'block';
will not make it appear
I can even
make changes to the object in the console, but that will not show up on the page.
ie document.getElementById('preview_name').innerHTML = 'Hello';
This change will show up in the console, but not in the page.
Here is the strange part. The already-saved listing that is populated by ajax in the saved_listing_form works perfectly and can be manipulated via the console and scripts as expected.
<article class="listing" id="listing" title="Dr. Peter Griffin of Q'Hog, RI"><img id="saved_image" src="images/clients/Peter_Griffin20200827180833.jpg"><h3>Peter Griffin, D.C.</h3>+11234567890<br><address>123 Spooner St<br>Q'Hog, RI 12345</address></article>
Are there any reasons that part of the ajax-populated div works as expected while other DOM objects within the same div would not? I don't appear to have any broken html elements that would throw things off.
The reference to the JS that controls the preview is loaded in at the very end of the code that ajax populates.
Any help would be much appreciated.

JQuery selector, partial DOM searching for performances

I'm actually working with Jquery and at some point I use Jquery selectors to make my page work. The issue here is that the HTML I work with can get very long depending on the data I work with and it looks like this.
HTML
<div class="mailing"></div>
<input type="text" class="mail_subject"/>
<input type="text" class="mail_body"/> <!-- I can have 1 to n number of these -->
<!-- Preview tags -->
<p class='main_subject'></p>
<p class='main_body'></p>
<!--
And a few more things we don't use here
-->
</div>
<div id="table1">
<table id="ranking">
<tbody>
<!-- Data, can have 0 to ~3500 rows -->
</tbody>
</table>
</div>
As you can see, my page is more or less divided in two parts, the <div class="mailing">, which contains a few forms, and the <div id="table1"> that is about displaying lots of data.
In my mailing div I have a few inputs and an auto-updated preview that takes the data from the inputs. What I have here is a kind of "mail builder" with the preview giving me the result with html formatting.
The problem here is about performance, my JQuery is slowed by the table and I got lag when I type in a form and I don't want it to search the whole document as I already know my data will be in the mailing div.
JS
$('.mailing').on('change click keyup keydown', function () {
// Here I append the mail_subject input to the preview
var text = $(this).val();
$('.main_subject').text($('.subject_select').val());
// Here I append each mail_body input to the preview
$('.bodies_select').each(function () {
text = $(this).val();
/*
* Some computation for the text
*/
jQuery('<span/>', {text: text}).appendTo('.main_body');
});
});
I have a few more functions like theses and a few more computation, but I think we got the idea of what my code looks like.
My question is, is there a way, when I use JQuery selectors like $('.main_subject') or $('.bodies_select') to not search the whole DOM document but only in my mailing div for example? The problem is that I can store my elements in variable since it as multiple occasion to be updated.
You can use context with jQuery to improve performances :
$('.bodies_select', '.mailing')
http://api.jquery.com/jquery/#jQuery1
You can even optimize the selectors with some technics :
https://learn.jquery.com/performance/optimize-selectors/
Sure, you just need to place the parent elemenent before
$('.mailing .main_subject')
You should probably read a bit about selectors
https://api.jquery.com/category/selectors/

JQuery insertAfter in chrome & safari causes the content to be inserted as String

i'm using jQuery to insert rows into a table dynamically. the row itself is a (text-) template, which gets some stuff inside replaced, is then 'casted' to an jQuery DOM node. While this works fine in Firefox and IE:
jQuery(jQuery.parseHTML(node)).insertAfter("#imgTable tr:last()");
Chrome and Safari won't insert the node, but insert the HTML as String. This way i'm not gaining a row, bug a solid block of html sourcecode...which is an UX disaster :)
very simple reproduction:
http://jsfiddle.net/288sp1qb/4/
...i already found out that the source of the error is that i store my templates inside a <noscript> tag. I have to do that, since all other tags that i know of are interpreted, so most browsers either remove the <tr> and <td> tags or otherwise modify the content.
storing the template in a variable isn't an option either, since the template already contains some backend generated data.
so the actual question is: how can i get webkit browsers to interpret the data after inserting them? or: how should i store the templates otherwise?
HTML Code -
<table id="table">
<tr>
<th>bsp.</th>
</tr>
</table>
<noscript id="tpl" style="display:none">
<tr><td>%VAR%</td></tr>
</noscript>
jQuery Code -
var node = $("#tpl").text();
node = node.replace("%VAR%","test");
$($.parseHTML(node)).insertAfter("#table tr:last()");
JSFiddle - http://jsfiddle.net/Ashish_developer/s35ppva8/
This solution is working fine in all browsers.

c# Webbrowser - identify javascript function by div id

actually i´m having some trouble with a webiste.
I´m trying to get a div content that is created by a javascript.
Sadly I can´t figure out which Javascript actually is filling this div.
How could I find that script ?
<div id="messageContent" class="msg_content textBeefy textCenter">
<script>
<form action="http://s124-de.ogame.gameforge.com/game/index.php?page=messages&displayCategory=9&displayPage=1" name="delMsg" method="POST">
<input id="new_msg_count" type="hidden" value="0" />
<table id="mailz" class="list" cellspacing="0" cellpadding="0">
<tbody>
<tr class="first">
<tr id="TR30739146" class="entry trigger " />
<tr id="TR30738105" class="entry trigger alt" />
<tr id="TR30734795" class="entry trigger " />
<tr id="TR30734031" class="entry trigger alt" />
<tr id="TR30731272" class="entry trigger " />
<tr class="last" />
</tbody>
</table>
</form>
The tables including those TR30739... are created by that unkown script.
I´ve tried to checkout the scripts I found with firebug one by one but I´m not sure if I´m calling them correctly and may not notice if it´s the one I´m looking for.
You question boils down to: How do I know what code is modifying a given DOM element?
You can do that with Chrome's Dev Tools (probably others as well), if you can get a chance to set a "DOM breakpoint" before the code in question runs:
Open the page
Open Dev Tools
Right-click the table and click Inspect
Right-click the table element in the DOM window and choose Break on... > Subtree modifications
Then when the table is modified, Chrome will stop the script and show you where the modification is happening in the JavaScript code. Then if you look at the call stack you should be able to find the code in question.
The trick, of course, is getting the breakpoint set before the code modifying the table runs.
Another option, again with Chrome, is to use the old deprecated mutation events. The new (and in most ways better) MutationObserver callbacks are not made synchronously with the code modifying the DOM, but old mutation event callbacks are:
Open a blank tab
Open Dev Tools
In the console, type (but don't press Enter yet)
function setBreak() { var elm = document.getElementById("mailz"); if (!elm) { setTimeout(setBreak); return; } elm.addEventListener("DOMSubtreeModified", function() { debugger; }); } setBreak();
In the address bar, paste the page's URL and then **as quickly as possible* switch back to the console and press Enter
Or of course, if you can modify the content of the page, just put that in a script element.
That code looks for the mailz element and, if it finds it, sets a DOMSubtreeModified listener on it that uses the debugger; statement. If the code doesn't see the element (yet), it schedules itself to run again at the next opportunity. When the event fires, the debugger; statement tells Chrome to stop the code and bring up the source pane. Then, again, inspect the call stack.

Is it possible to position a div on top of another starting from the bottom using CSS?

I have a chat window made using HTML, CSS & JS. I want to position the message from bottom to top.
Example:
first message div at the bottom, 2nd message div on top of first an so on. Is it possible?
I can't imagine a pure CSS solution. But Using jQuery, if you already have this library for your project, you could write something this:
$(':button').click(function() {
var message = $('input[type=text]').val();
$('#chat').prepend('<div class="line">'+message);
});
Demo: http://jsfiddle.net/Vbd67/1/
**I changed the append to prepend according to the comment
I know that this is not an answer to your question, rather this is a better option that you should consider implementing in the chat window.
Newest comment should be at the bottom, that is how most basic chat windows work.
Next thing, you can do this all using css:
because such a design requires either use of table rows or list elements
Obviously you have to use javascript for using ajax, so that you can asynchronously fetch user records like messages and profile pic etc
CSS:
<style type="text/css">
table#chat_window {
}
tr#message_row {
}
td#profile_pic {
}
td#message {
}
</style>
HTML STRUCTURE:
<table id="chat_window">
<tr id="message_row">
<td id="profile_pic"></td>
<td id="message"></td>
</tr>
</table>
OR USING LISTS:
<ul id="chat_window">
<li id="message_row">
<div id="profile_pic"></div>
<div id="message"></div>
</li>
</ul>
Now you have to just using javascript:ajax to fetch values and add a child:
If you are using table based chat-window, then you have to fetch the table id using javascript and add row element <tr> per value/message that you fetch.
If you are using list based chat-window, then you have to fetch the list id using javascript and add list element <li> per value/message that you fetch.
I am sorry if there are any typos I have less time.
You can do this using jQuery like;
var first = $('div > div:first-child');
first.appendTo(first.parent());
To deal with several elements, you can do this:
$('div > div').each(function() {
$(this).prependTo(this.parentNode);
});
Here is a working Live Demo.
You should use a combination of display:table-cell and vertical-align:bottom.
I use Sotiris's fiddle and fixed its CSS.
The HTML is
<div style="display:table; height:200px;">
<div style="display:table-row">
<div id="chat" style="width:400px; border:1px solid black;display:table-cell; vertical-align:bottom">
</div>
</div>
</div>
<input type="text"><input type="button" value="post">
​
And this is the JavaScript code
$(':button').click(function() {
var message = $('input[type=text]').val();
$('#chat').append( $('<div/>').text(message) );
});
​
Please let me know if there is a problem.
This is the fiddle
I kept searching for a better solution because table layout is always suspicious to me, but I found css-tricks article about it and they do the same as I do.. so I guess this solution is the right one.
ADDING - keep scroll to bottom code
Since new messages are coming at the bottom, we need to keep scroll to bottom.
I updated the fiddle link

Categories