Showing hidden divs element using jQuery show() not working in IE7 - javascript

I'm attempting to make a tree view using JavaScript. I have a list of Divs created dynamically. A parent node that is showing and a child node that will not be showing. When you hit the button on the parent node it will call show('slow'). This works on IE8 and IE9, but when I test it with IE7, the child node will show with out it's CSS class. How can I make this work with IE7?
code in the main page
function CreateEventCategoryDiv(EventCategoryName) {
var NewEventCategoryNode = document.createElement('div');
NewEventCategoryNode.id = EventCategoryName + "Node";
if (TreeNodeCounter == 0 || (TreeNodeCounter % 2) == 0) {
NewEventCategoryNode.className = "EventCategoryNodesEven";
}
else {
NewEventCategoryNode.className = "EventCategoryNodesOdd";
}
NewEventCategoryNode.innerHTML = "<input type='button' value='+' id='ExpandButton' class='ExpandNodeButtons' onclick='ExpandNode(\"" + EventCategoryName + "\");' /> " + EventCategoryName;
var EventTree = document.getElementById("EventTree");
EventTree.appendChild(NewEventCategoryNode);
TreeNodeCounter++;
}
function ExpandNode(PassedNode) {
var ParentNode = CalendarObject.SearchCategoryNode(PassedNode);
if (ParentNode.IsChildrenShowing == false) {
ParentNode.ExpandNodes(CalendarObject.Months);
}
else if (ParentNode.IsChildrenShowing == true) {
ParentNode.CollapseNode(CalendarObject.Months);
}
}
This Part is called in the EventCategory Class to add the child nodes(sorry I forgot this one at first)
this.AddEventType = function (EventTypeNode) {
var NewElement = document.createElement('Div');
NewElement.id = EventTypeNode.DivAssociateId;
NewElement.innerText = EventTypeNode.Name;
if (this.NodesCount == 0 || (this.NodesCount % 2) == 0) {
NewElement.setAttribute("class", "EventTypeNodesEven");
}
else {
NewElement.setAttribute("class", "EventTypeNodesOdd");
}
NodesCount = this.EventTypeNodesArray.push(EventTypeNode);
$(NewElement).hide();
var ParentElement = document.getElementById("EventTree");
ParentElement.appendChild(NewElement);
this.NodesCount++;
};
This Part is in the CalendarGrid class
this.ExpandNodes = function (MonthArray) {
for (var x in this.EventTypeNodesArray) {
var SelectedNode = document.getElementById(this.EventTypeNodesArray[x].DivAssociateId);
if (this.IsChildrenShowing == false) {
$(SelectedNode).show('slow');
for (var y = 0; y < MonthArray.length; y++) {
var SelectedRow = document.getElementById(this.EventTypeNodesArray[x].Name + MonthArray[y].MonthName + "Row");
$(SelectedRow).show('slow');
}
}
}
this.IsChildrenShowing = true;
};
CSS Code:
.EventTypeNodesOdd
{
font-family:Arial;
font-weight:bold;
text-align:center;
height:27px;
background-color:#dbe2e6;
display:block;
}
.EventTypeNodesEven
{
font-family:Arial;
font-weight:bold;
text-align:center;
height:27px;
background-color:#f9fafb;
}

Try setting the class to whatever it should be after showing it.

Related

Javascript list with clickable elements [duplicate]

This question already has an answer here:
Basic questions about javascript
(1 answer)
Closed 5 years ago.
I am working on a script that would generate random list of 100 elements where every third element would be clickable. So far I am stuck at stage below. Any ideas how to progress?
var hundred = Array(100);
hundred.toString();
for (i = 0; i < hundred.length; i++) {
document.write("Item " + (i + 1) + " of" + hundred.length + "</br>")
}
I used buttons. every third element will be clickable. remaining elements will have disabled property
var hundred = Array(100);
hundred.toString();
for (i = 0; i < hundred.length; i++) {
if(i%3===0 && i!==0){
var button = document.createElement("button");
button.innerHTML ="Click "+i ;
document.getElementsByTagName('body')[0].appendChild(button);
}else{
var button = document.createElement("button");
button.innerHTML ="Click "+i ;
button.disabled = true;
document.getElementsByTagName('body')[0].appendChild(button);
}
}
Edited: full example
var hundred = Array(100);
var node;
hundred.toString();
for (i = 0; i < hundred.length; i++) {
if(i%3===0 && i!==0){
node = document.createElement("button");
node.addEventListener('click', function() { alert('clicked'); });
node.innerHTML = 'clickablke';
} else {
node = document.createElement("div");
node.innerHTML = 'just div';
}
document.body.appendChild(node);
}
First you need create the element. Then apply the onclick with this consition i%3 == 0 to every 3 rd element
Updated
after click its a bolder using classList.add()
for (i = 1; i < 10; i++) {
var s = document.createElement('SPAN');
if (i % 3 == 0) {
s.className = 'clickable';
s.onclick = clicks;
}
s.textContent=i;
document.body.appendChild(s)
}
function clicks() {
console.log(this.innerHTML)
this.classList.add('bold')
}
.clickable {
color: red;
}
.bold{
font-weight:bolder;
}
As commented,
Instead of using document.write, use document.createElement to create an element and assign them event listener and append these elements to an element in html or document.body
var hundred = Array(100);
for (i = 0; i < hundred.length; i++) {
let el = document.createElement('span');
el.textContent = i + " ";
if((i+1) % 3 === 0){
el.classList.add('clickable')
el.addEventListener("click", notify)
}
document.body.appendChild(el)
}
function notify(){
this.classList.add('clicked')
console.log(this.textContent)
}
.clickable{
color: blue;
text-decoration: underline;
}
.clicked{
color: gray;
}
References
Why is document.write considered a "bad practice"?
Document.createElement
add onclick event to newly added element in javascript
Multiple wayst to do this, i'd make an event listener to every item reference, hence: every third clickable element goes bold:
var hundred = Array(100);
hundred.toString();
var btn = Array(100);
for (i = 0; i < hundred.length+1; i++) {
btn = document.createElement("p");
btn.innerHTML="Item " + (i-1 + 1) + " of" + hundred.length + "</br>";
if(i%3===0 && i!==0){
btn.addEventListener('click', function() {
this.style.fontWeight = 'bold'; }, false);
}
document.body.appendChild(btn);
}

firstChild of an element in JavaScript constructor class

I'm having trouble understanding why I can't properly access firstChild of an element object in a JavaScript class. I can set innerHTML without the firstChild properly, but I'd like to set it on firstChild. Using console.dir(this.waitStatus) shows that it has a firstChild. I'm not using jQuery because it may not be loaded when I want this run, since it is a loading indicator.
class LoadingIndicator{
constructor(elementID){
this.tick = 8;
this.waitStatus = document.getElementById(elementID);
setInterval(
this.animateLoader.bind(this),
10
)
}
animateLoader (){
if(this.tick == 8){
this.waitStatus.firstChild.innerHTML = ".";
}
else if(this.tick == 16){
this.waitStatus.firstChild.innerHTML = "..";
}else if(this.tick == 24){
this.waitStatus.firstChild.innerHTML = "...";
this.tick = 0;
}
this.tick += 1;
}
}
var supervisorLoadingIndicator = new LoadingIndicator('supervisorsTableLoading');
html
<p id='supervisorsTableLoading' style='width:700px; height:0px; text-align:left; padding-bottom:20px;'>
<span id='supervisorsTableLoadingInner' style='margin-left:30%'> </span>
</p>
The firstChild is a text node (the line break before the <span), so .innerHTML isn't useful. Use .firstElementChild instead, or .children[0].
class LoadingIndicator {
constructor(elementID) {
this.tick = 8;
this.waitStatus = document.getElementById(elementID);
setInterval(this.animateLoader.bind(this), 10)
}
animateLoader () {
if (this.tick == 8) {
this.waitStatus.firstElementChild.innerHTML = ".";
} else if (this.tick == 16) {
this.waitStatus.firstElementChild.innerHTML = "..";
} else if (this.tick == 24) {
this.waitStatus.firstElementChild.innerHTML = "...";
this.tick = 0;
}
this.tick += 1;
}
}
var supervisorLoadingIndicator = new LoadingIndicator('supervisorsTableLoading');
Or you could simply get rid of that whitespace text and use .firstChild.
Also, you're not really setting HTML content, so I'd personally use .textContent instead.
this.waitStatus.firstElementChild.textContent = "...";
IE8 and lower don't support either of these properties.
If you're still supporting IE8, then you can polyfill them both.
If you're supporting IE6/7, then stick with .innerHTML and get rid of that whitespace.
use this.waitStatus.children[0], firstChild will return non element node.
class LoadingIndicator{
constructor(elementID){
this.tick = 8;
this.waitStatus = document.getElementById(elementID);
console.log(this.waitStatus.firstChild);
setInterval(
this.animateLoader.bind(this),
10
)
}
animateLoader (){
if(this.tick == 8){
this.waitStatus.children[0].innerHTML = ".";
}
else if(this.tick == 16){
this.waitStatus.children[0].innerHTML = "..";
}else if(this.tick == 24){
this.waitStatus.children[0].innerHTML = "...";
this.tick = 0;
}
this.tick += 1;
}
}
var supervisorLoadingIndicator = new LoadingIndicator('supervisorsTableLoading');
<p id='supervisorsTableLoading' style='width:700px; height:0px; text-align:left; padding-bottom:20px;'>
<span id='supervisorsTableLoadingInner' style='margin-left:30%'> </span>
</p>

Cascading Multi select pick lists CRM 2011

I Have multi select pick list which work fine however it now contains around 70 options to select from with around 12 categories - I have searched around the internet to find a solution that could make the list a little more user friendly.
It would be perfect if I was able to have the pick list with the 12 categories and on select of them they cascade in to their sub options. However the tricky part is this has to be done from within the same field.
Has anyone had a similar request or know of anyway to make this possible?
Thank You
here is the code for the multi select pick list I have currently:
<html xmlns="http://www.w3.org/1999/xhtml"><head><title></title>
<script src="sc_json2.js" type="text/javascript"></script>
<meta charset="utf-8"></head>
<body style="margin: 0px; border: 0px currentColor; font-family: Segoe UI; font-size: 11px; background-color: rgb(246, 248, 250);" onload="onload()">
<div id="MultiSelectField"></div>
<script type="text/javascript">
var FORM_TYPE_CREATE = 1;
var FORM_TYPE_UPDATE = 2;
var FORM_TYPE_READ_ONLY = 3;
var FORM_TYPE_DISABLED = 4;
var FORM_TYPE_QUICK_CREATE = 5;
var FORM_TYPE_BULK_EDIT = 6;
var var_sc_optionset;
var var_sc_optionsetvalue;
var options;
var checkedValues;
var isDirty = false;
var html = "";
function onload() {
var formType = parent.Xrm.Page.ui.getFormType();
if (formType == FORM_TYPE_BULK_EDIT) {
displayMessage();
}
else {
init();
}
}
function init() {
getParameters();
getOptionSetValues();
getCheckedValues();
convertToMultiSelect();
}
function displayMessage() {
MultiSelectField.innerHTML = "This field cannot be displayed or edited in this form mode.";
}
function getParameters() {
var querystring = unescape(window.location.search.replace('?', '').replace('data=', ''));
var params = querystring.split(',');
for (var i = 0; i < params.length; i++) {
if (i == 0) {
var_sc_optionset = params[i];
}
else if (i == 1) {
var_sc_optionsetvalue = params[i];
}
}
}
//populate option-set values and integers
function getOptionSetValues() {
options = parent.Xrm.Page.getAttribute(var_sc_optionset).getOptions();
}
function getCheckedValues() {
var dirtyCheckedOptions = parent.Xrm.Page.getAttribute(var_sc_optionsetvalue).getValue();
if (dirtyCheckedOptions != null) {
checkedValues = dirtyCheckedOptions.split(';');
}
else {
checkedValues = '';
}
}
//Method to convert an optionset to multi select Option Set
function convertToMultiSelect() {
for (var i = 0; i < options.length - 1; i++) {
var pOption = options[i];
if (!isChecked(pOption.text))
html += "<input type='checkbox' class='multiselect_cb' onclick='makeDirty()' style='border:none; width:25px; align:left;' title='" + pOption.text + "'/>";
else
html += "<input type='checkbox' class='multiselect_cb' checked='checked' onclick='makeDirty()' style='border:none; width:25px; align:left;' title='" + pOption.text + "'/>";
html += "<label>" + pOption.text + "</label>";
if (i != options.length - 2) {
html += "<br/>"; //it's a 'br' flag
}
}
MultiSelectField.innerHTML = html;
}
function makeDirty() {
isDirty = true;
}
function isChecked(ptext) {
for (var i = 0; i < checkedValues.length; i++) {
if (checkedValues[i] == ptext)
return true;
}
return false;
}
function saveMultiSelect() {
if (isDirty) {
var divElement = document.getElementById("MultiSelectField");
var result = '';
for (var i = 0; i < divElement.childNodes.length; i++) {
if (divElement.childNodes[i].type == "checkbox" && divElement.childNodes[i].checked) {
result += divElement.childNodes[i].title + ";";
}
}
//clear out the previous results from the field
parent.Xrm.Page.getAttribute(var_sc_optionsetvalue).setValue("");
//populate var_sc_optionsetvalue with the checked values
parent.Xrm.Page.getAttribute(var_sc_optionsetvalue).setValue(result);
isDirty = false;
}
}
</script>
</body></html>

TD class staying active when another TD class selected

I need guidance editing a file. I have posted the Javascript below. This is a link to my working example http://www.closetos.com/top-shelf-awards_copy_copy.
The problem occurred when I added an additional row to the table. Now, when you select the text link in a cell in the second row, it stays selected and active, when clicking on something in the top row.
function $(id)
{
return document.getElementById(id);
}
function Coalesce(Value, Default)
{
if(Value == null)
return Default;
return Value;
}
function Switcher(numberOfSections, sectionContainerID, activeClass, inactiveClass)
{
this.NumberOfSections = Coalesce(numberOfSections, 1) - 1;
this.SectionContainerID = Coalesce(sectionContainerID, "sectionContainer");
this.ActiveClass = Coalesce(activeClass, "active");
this.InactiveClass = Coalesce(inactiveClass, "");
}
Switcher.prototype.Switch = function(TheLink, SectionID)
{
// Make sure all sections are hidden
var SectionContainer = $(this.SectionContainerID);
for(var ct = 0; ct < SectionContainer.childNodes.length; ct++)
{
var node = SectionContainer.childNodes[ct];
if(node.nodeType != 1)
continue;
node.style.display = "none";
}
var First = true;
// Reset button styles
for(var ct = 0; ct < TheLink.parentNode.childNodes.length; ct++)
{
if(TheLink.parentNode.childNodes[ct].nodeType != 1)
continue;
else node = TheLink.parentNode.childNodes[ct];
node.className = this.InactiveClass;
if(First)
{
node.className += " firstCell";
First = false;
}
}
// Show the selected section
$(SectionID).style.display = "block";
TheLink.className = this.ActiveClass;
if(TheLink == node)
TheLink.className += " lastCell";
}
You problem is in this section of code. this looks only at the row that the clicked cell is in. TheLink.parentNode is a reference to the row that the cell is in.
for(var ct = 0; ct < TheLink.parentNode.childNodes.length; ct++) <--- parenNode == row
{
if(TheLink.parentNode.childNodes[ct].nodeType != 1)
{
continue;
}
else
{
node = TheLink.parentNode.childNodes[ct];
}
node.className = this.InactiveClass;
if(First)
{
node.className += " firstCell";
First = false;
}
}
In order to make this work with multiple rows you need to modify it to look at other rows in the table:
for(var ct = 0; ct < TheLink.parentNode.parentNode.childNodes.length; ct++)
{
for( innerL = 0; innerL < TheLink.parentNode.parentNode.childNodes[ct].childNodes.length; innerL++)
{
if(TheLink.parentNode.parentNode.childNodes[ct].childNodes[innerL].nodeType != 1)
{
continue;
}
else
{
node = TheLink.parentNode.parentNode.childNodes[ct].childNodes[innerL];
}
node.className = this.InactiveClass;
if(First)
{
node.className += " firstCell";
First = false;
}
}
}
in the block above you are looking at the parentNode's (the tr) parentNode (tbody) and then iterating through its grandchildren. This allows you to capture all the cells in the table, not just the row.
Here is an example of it working. When you follow the link you need to hit the green 'run' button on the bottom left of the page to get the script to load.

How to highlighted the selected row from repeater?

I have a repeater, and i just want that when i select or click on any row of it then that would be highlighted. I had tried some code of javascript which makes the selected row highlighted, but not unhighlighting when select any other row.My code is:-
<tr id="gh" style="cursor: pointer" onclick="Select(this);">
any javascript's and style's code is:-
<style type="text/css">
.highlight
{
background-color: Red;
}
.selected
{
background-color: #ffdc87;
}
</style>
<script type="text/javascript">
function Select(obj) {
obj.className = 'selected';
var tbl = document.getElementById("Repaddressorbbl")
var firstRow = tbl.getElementsByTagName("TR")[0];
var tableRowId = tbl.rows[firstRow.getElementById("gh").parentNode.id];
alert(tableRowId);
var oldRow = tbl.rows[firstRow.getElementsByTagName("tr")[0].value];
if (oldRow != null) {
oldRow.className = '';
}
firstRow.getElementsByTagName("tr")[0].value = obj.rowIndex;
}
</script>
We can do it simply with code behind but the matter is it should be done only with jquery or javascript.
You can use code similar to this:
var INDEX = $(this).parent().children().index($(this));
$('#Repaddressorbbl tr:nth-child(' + INDEX + ')').addClass("highlight")
.siblings()
.removeClass("highlight"); // remove css class from other rows
It gets the rownumber of the TR and adds a CSS class while removing the same class from all other TRs.
i've added a function to select elements with a specific classname so you can easly search the dom for elements with that class
onload=function(){
if (document.getElementsByClassName == undefined) {
document.getElementsByClassName = function(className)
{
var hasClassName = new RegExp("(?:^|\\s)" + className + "(?:$|\\s)");
var allElements = document.getElementsByTagName("*");
var results = [];
var element;
for (var i = 0; (element = allElements[i]) != null; i++) {
var elementClass = element.className;
if (elementClass && elementClass.indexOf(className) != -1 && hasClassName.test(elementClass))
results.push(element);
}
return results;
}
}
}
function Select(obj) {
var oldRow = document.getElementsByClassName('selected');
if(oldRow.length > 0)
oldRow[0].className = '';
obj.className = 'selected';
}
Update for jQuery:
$(document).ready(function() {
$("tr").click(function() {
$(this).addClass("highlight").siblings().removeClass("highlight");
}
}
Original answer:
If I understand you correctly, all of your table rows are defined like this:
<tr id="gh" style="cursor: pointer" onclick="Select(this);">
And you want to set a class on the most recently clicked row so it looks selected, while clearing said class from the previously clicked/selected row?
If so, a much simplified version of your function should do it:
var selectedRow = null;
function Select(obj) {
if (obj != selectedRow) {
if (selectedRow != null) {
selectedRow.className = '';
}
obj.className = 'selected';
selectedRow = obj;
}
}
I don't understand what you're trying to do with the firstRow.getElementsByTagName("tr") stuff. Have you got nested tables?

Categories

Resources