We have this function on a js file to pull a menu tree when users click on the parent item:
function menusel(unid)
{
//if its in the array, deactivate it and take it out
var index = inarray(unid,selectedarray);
//first arrange the array
if(index)
{
selectedarray[index] = 0;
}
else
{
//we have restrictions
if(treeRestrictMode==1)
{
//now check its not in the array of items not allowed to b picked
if(inarray(unid,nonSelArr))
{
alert('This Item is Unselectable');
return;
}
}
//if we are in unique tree mode, can only select one
if(treeSingleMode==1)
{
//check for a non zero value, and deselect it [recursively]#
for(var x=0;x<selectedarray.length;x++)
{
if(selectedarray[x]!=0)
{
//alert(unid+' '+selectedarray[x]);
menusel(selectedarray[x]);
}
}
}
selectedarray.push(unid);
}
sel_unselect(unid,index);
//if we have an override function, it means we will assume that the parent page
//as an input type function called treeSelFunc which takes the id and takes care of the rest
if(overrideFunction!='')
{
parent.parent.treeSelFunc(unid,selName);
return;
}
if(treeSingleMode!=1)
{
var selObj = emptySel(0);//set txt will fill it for us
}
else
{
var selObj = parent.parent.MM_findObj(selName);
//see if we have options..will need to empty them
if(selObj.size>1)
{
emptySel(1);
}
else
{
selObj.value=0;
}
}
setTxt(selObj);
selObj.fireEvent('onchange');
}
which we call like this on a page as this:
<a id="troot[VMENU]_040" onclick="menusel(40);" class="sel">All</a>
And we are getting this:
Uncaught TypeError: selObj.fireEvent is not a function
It used to work on an older browser version (I think with explorer 8) but now is not working any more using Chrome. Any ideas why?
The fireEvent method is a proprietary Microsoft Internet Explorer alternative to the standard EventTarget.dispatchEvent() method.
Use the dispatchEvent method instead.
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent
Related
So far I have tried this:
if ($scope.flag) {
$scope.partialPricing.push([$scope.p]);
$scope.flag = false;
} else {
for (var i = 0; i < $scope.partialPricing.length; i++) {
console.log("finding object = " + $scope.partialPricing);
if ($scope.partialPricing[i].type != $scope.p.type) {
$scope.partialPricing.push([$scope.p]);
break;
} else {
console.log("Already Given . Please Clear .");
}
}
}
Problem is when it enters into the else condition, it gets
$scope.partialPricing = [Object Object] and also, $scope.partialPricing[i].type = undefined.
My goal is to prevent user from giving same type twice. Here type is Hourly , Monthly , Weekly.
He can set the value only once. Tell me the solution or any other way i can do it?
Your if condition in the loop won't work properly: it will add the element to the list if its type is different from the first element of the list, independently of all the rest of the list.
The easiest is to make a lookup function as follows:
function lookupByType(type) {
for (var i = 0; i < $scope.partialPricing.length; i++) {
if ($scope.partialPricing[i].type == type) {
return true;
}
}
return false;
}
And then use it as follows (no for loop here):
if (lookupByType($scope.p.type)) {
console.log("Already Given . Please Clear .");
} else {
$scope.partialPricing.push($scope.p);
}
About $scope.flag, I assume you're aware that you use it to bypass the verification, you probably have a good reason for this. However, if the goal is only to insert the first element, there's no need for it: the lookup function will always return false if the list so far is empty.
Edit: You also had a type problem: your pricing list was an array of array of objects, and you used it as an array of objects. You probably want to use the latter, so you need to push($scope.p) rather than push([$scope.p]).
You may switch your else part a bit and check for equality, because that is what you need for exiting the loop. Then break and make your next action according of the check.
if ($scope.flag) {
$scope.partialPricing.push([$scope.p]);
$scope.flag = false;
} else {
var found = false;
for (var i = 0; i < $scope.partialPricing.length; i++) {
console.log("finding object = " + $scope.partialPricing);
if ($scope.partialPricing[i].type === $scope.p.type) {
console.log("Already Given . Please Clear .");
found = true;
break;
}
}
if (!found) {
$scope.partialPricing.push([$scope.p]);
}
}
Otherwise, you could use Array#some and perform a check
if ($scope.flag) {
$scope.partialPricing.push([$scope.p]);
$scope.flag = false;
} else {
var found = false;
if ($scope.partialPricing.some(function (price) { return price.type === $scope.p.type; })) {
console.log("Already Given . Please Clear .");
} else {
$scope.partialPricing.push([$scope.p]);
}
}
Why you need to push "$scope.P" into the partialPricing. Any logic related you handled this line?
$scope.partialPricing.push([$scope.p]);
Using edge animate, I don't seem to have the control over orders of operations that I am looking for. I have a function that operates a switch and another that tests the conditions of one or many switches. The problem I am running into is edge keeps wanting to run the test before the switch.
I can have the switch launch the test but run into the issue that I load the objects in an array inside of edge. What I am thinking is I need a way of pre-loading variables that the function can use but they don't need to be global since they are only used in this one function.
Here is what I have so far.
Inside Edge Animate:
twoPhaseSwitch('.btn1','on'); //sets up switch 1
twoPhaseSwitch('.swtch1','off'); //sets up switch 2
conditionsArray(['.btn1','.swtch1']); // tells the test script what the buttons are
In JavaScript file:
function twoPhaseSwitch(object,state)
{
var obj = $(object);
stage.getSymbol(obj).stop(state);
obj.data('state',state);
obj.mousedown(function(e)
{
if(obj.state == 'off')
{
stage.getSymbol(obj).stop('on');
obj.state = 'on';
obj.data('state','on');
}else{
stage.getSymbol(obj).stop('off');
obj.state = 'off';
obj.data('state','off');
};
});
};
function conditionsArray(obj)
{
var answers = ['on','on'];
// compare lengths
if (obj.length != answers.length)
return 'Argument Miscount';
var challengResults = challangeArray();
if (challengResults == true)
{
lightOn('.LED1','on');
}else if(challengResults == false)
{
lightOn('.LED1','off');
};
console.log(challengResults);
function challangeArray()
{
for (var i = 0, l=obj.length; i < l; i++)
{
if ($(obj[i]).data('state') != answers[i]) {
return false;
}
}
return true;
};
};
function lightOn(lightOBJ,state)
{
lightOBJ = $(lightOBJ);
stage.getSymbol(lightOBJ).stop(state);
};
I use mousedown and mouseup currently to fake the order of operations but it brings some pretty unacceptable issues so I am trying to do this right.
did you try wrapping your code in
$( document ).ready(){
your code here
}
to prevent any javascript from running until the page loads?
So, I have this little code in my js file:
window.onload = function Equal() {
var a = 'b1'
var b = 'box1'
var bookstorname = localStorage.getItem(a)
if (bookstorname == 1) {
document.getElementById(b).setAttribute('checked','checked');
}
if (bookstorname == 0) {
document.getElementById(b).removeAttribute('checked','checked');
}
var a = 'b2'
var b = 'box2'
var bookstorname = localStorage.getItem(a)
if (bookstorname == 1) {
document.getElementById(b).setAttribute('checked','checked');
}
if (bookstorname == 0) {
document.getElementById(b).removeAttribute('checked','checked');
}
}
The function itself is not important (it equals checkboxvalues set in the localstorage), but I execute it 2 times. First time with var a & b set to 'b1' & 'box1'. Then I run the script again (same script), but with var a & b set to 'b2' & 'box2'. Now, this code works, but my question is if there is a shorter way to write this? I can imagine some sort of array with a loop, but I could not get it to work for some reason. The 2 variables are pairs, and I know this might be a dumb question, but I can't find the answer anywhere.
You can use a second function which will accept the local storage key and the checkbox id like
window.onload = function Equal() {
setCheckboxState('box1', 'b1');
setCheckboxState('box2', 'b2');
}
function setCheckboxState(id, key) {
document.getElementById(id).checked = 1 == localStorage.getItem(key);
}
You might separate common logic into another function
window.onload = function Equal() {
function extractFromStorage(a, b) {
var bookstorname = localStorage.getItem(a)
if (bookstorname == 1) {
document.getElementById(b).setAttribute('checked','checked');
}
if (bookstorname == 0) {
document.getElementById(b).removeAttribute('checked','checked');
}
}
extractFromStorage('b1', 'box1');
extractFromStorage('b2', 'box2');
}
function doTheStuff(a, b) {
var bookstorname = localStorage.getItem(a)
if (bookstorname == 1) {
document.getElementById(b).setAttribute('checked','checked');
}
if (bookstorname == 0) {
document.getElementById(b).removeAttribute('checked','checked');
}
}
window.onload = function Equal() {
doTheStuff('b1', 'box1');
doTheStuff('b2', 'box2');
}
?
This is how I would do it.
There are several problems with your code.
You do not check that the element you are stetting an attribute to
exists. You do not check if the localStorage item you get is
defined.
You pollute the global name space with the function name Equal.
That function should not be named with a capital as it is not a Object generator.
There is no need to use setAttribute and removeAttribute, in
fact removeAttribute makes no sense in this case as you can not
remove the checked attribute from the element. BTW why use setAttribute here and not for window.onload?
The checked attribute is either true or false, it does not use the
string "checked"
Binding the load event via the onload attribute is not safe as you may
block 3rd party code, or worse 3rd party code may block you.
There is no error checking. DOM pages are dynamic environments, pages
have adverts and content from many places that can interfer with your
code. Always code with this in mind. Check for possible errors and deal with them in a friendly way for the end user. In this case I used an alert, not friendly for a normal user but for you the coder.
My solution.
// add an event listener rather than replace the event listener
window.addEventListener(
"load", // for the load event
function(){
// the update function that is called for each item;
var update = function(item){
// the right hand side equates to true if the localstorage
// is equal to "1". LocalStorage allways returns a string or
// undefined if the key is not defined.
item.element.checked = localStorage[item.storageName] === "1";
}
// safe element getter
var getElement = function(eId){
var e = document.getElementById(eId); // try and get the element
if(e === null){ // does it exist?
throw "Missing element:"+eId; // no then we can not continue
// the program stops here unless
// you catch the error and deal with
// it gracefully.
}
return e; //ok return the element.
}
// Item creator. This creates a new item.
// sName is the local storage name
// eId id the element ID
var item = function(sName, eId){
return {
storageName: sName, // set the loaclStorage name
element:getElement(eId); // get the element and check its safe
};
}
// make it all safe
try{
// create an array of items.
var items = [
item("b1","box1"),
item("b2","box2")
];
// for each item update the element status
items.forEach(update);
}catch(e){
alert("Could not update page?");
}
}
);
I've a page with a TreeView control and the parent node is checked, the child nodes will be checked as well. It was done using javascript. But when the page is opened is IE9 and trying to check the parent node, I will get an error of:
Microsoft JScript runtime error: Object doesn't support property or method 'getElementsByTagName'
function AreAllSiblingsChecked(chkBox)
{
var parentDiv = GetParentByTagName("div", chkBox);
var childCount = parentDiv.childNodes.length;
for(var i=0;i<childCount;i++)
{
var prevChkBox = parentDiv.childNodes[i].getElementsByTagName("input")[0];
//if any of sibling nodes are not checked, return false
if(prevChkBox.checked)
{
return true;
}
}
return false;
}
//utility function to get the container of an element by tagname
function GetParentByTagName(parentTagName, childElementObj)
{
var parent = childElementObj.parentNode;
while(parent.tagName.toLowerCase() != parentTagName.toLowerCase())
{
parent = parent.parentNode;
}
return parent;
}
Appreciate if someone can help me to solve this! thanks in advance...
In IE9, childNodes[] returns text nodes (comments or whitespace) as well as child tags. Text nodes do not support getElementsByTagName(). There's a good summary of the underlying DOM model here.
The easiest fix is just to check for the existence of the method before using it:
function AreAllSiblingsChecked(chkBox)
{
var parentDiv = GetParentByTagName("div", chkBox);
var childCount = parentDiv.childNodes.length;
for(var i=0;i<childCount;i++)
{
if (parentDiv.childNodes[i].getElementsByTagName) {
var prevChkBox = parentDiv.childNodes[i].getElementsByTagName("input")[0];
//if any of sibling nodes are not checked, return false
if(prevChkBox.checked)
{
return true;
}
}
}
return false;
}
I am working with a decent sized set of data relating to objects on the page and some objects need links applied to them onclick. The link to connect to is part of the dataset and I build a string for the link with the variable linkTarget and apply it like so.
if (dataTag[i][3]==true){
if(prepend==undefined || prepend=="undefined"){
var linkTarget=ResultsJSON["targetUrl"];
ele.onclick = function(){
window.open(linkTarget);
};
} else {
var linkTarget=prepend+ResultsJSON["targetUrl"];
ele.onclick = function(){
window.open(linkTarget);
};
}
ele refers to an element picked up with getElementByID. Now I am going through quite a few objects and the problem I have is the onclick for every object is the last value of linkTarget. This is all contained in a function and link target is a local variable so I have no idea why. I have tried using an array with something like
ele.onclick=function(){window.open(linkTarget[linkTarget.length-1]);};
and even
ele.onclick=function(){window.open(linkTarget.valueOf());};
with the same results. I am at a loss now and would appreciate any help.
Use Array.forEach() to iterate your data and watch your troubles melt away.
dataTag.forEach(function (item) {
if (item[3]==true) {
var linkTarget = "";
if (prepend==undefined || prepend=="undefined") {
linkTarget = prepend;
}
linkTarget += ResultsJSON.targetUrl;
ele.onclick = function () {
window.open(linkTarget);
};
}
});
See this compatibility note for using Array.forEach() in older browsers.
You're in a loop — therefore, you need to put your things-to-be-executed in another function, like so:
if(dataTag[i][3]) {
if(prepend) {
(function(linkTarget) {
ele.onclick = function() {
window.open(linkTarget);
};
})(ResultsJSON.targetUrl);
} else {
(function(linkTarget) {
ele.onclick = function() {
window.open(linkTarget);
};
})(ResultsJSON.targetUrl);
}
I also made some general corrections.