Raphael: Chaining ".data" to a raphael.js element - javascript

I'm having trouble chaining ".data" to a raphael.js element.
When I try to retrieve the data later, I get "undefined".
Here's my fiddle: http://jsfiddle.net/HkNgT/9/
//Draw:
paper.circle(circleCenterX, circleCenterY, circleCenterRadius)
.attr({'fill':'blue', 'stroke':'red', 'stroke-width':2, 'opacity': 0.8})
.data({"circleCenterX":circleCenterX,
"circleCenterY":circleCenterY,
"boxYPosition":boxYPosition,
"boxXPosition":boxXPosition})
.id = name+"-circle";
//Output:
console.log("data is = ", paper.getById(name+"-circle").data("circleCenterX"));
With this code, the ".data(...)" part just doesn't work.
When I try to retrieve it (with paper.getById), it displays "data is = undefined".
Other ways that I have tried:
//Doesn't work
paper.circle....
.data("circleCenterX",circleCenterX)
.data("circleCenterY",circleCenterY)
.data("boxYPosition",boxYPosition)
.data("boxXPosition",boxXPosition);
And another:
//Doesn't work
var c = paper.circle....;
c.data("circleCenterX",circleCenterX);
c.data("circleCenterY",circleCenterY);
c.data("boxYPosition",boxYPosition);
c.data("boxXPosition",boxXPosition);
And another:
//DOES work, but gives me huge performance losses
paper.circle....;
paper.getById(name+"-circle").data("circleCenterX",circleCenterX);
paper.getById(name+"-circle").data("circleCenterY",circleCenterY);
paper.getById(name+"-circle").data("boxYPosition",boxYPosition);
paper.getById(name+"-circle").data("boxXPosition",boxXPosition);
Any help?

So, just trying to help, I've never used raphael before. I assume you're trying to retrieve the circleCenterX value?
Inspecting the data function, it looks as though it's only used for setting the value. (It only returns a value, if you're setting a value).
function (b,c){
var d = bb[this.id] = bb[this.id] || {};
if(arguments.length==1){
if(a.is(b,"object")){
for(var e in b)b[g](e)&&this.data(e,b[e]);
return this
}
eve("raphael.data.get."+this.id,this,d[b],b);
return d[b]
}
d[b]=c,eve("raphael.data.set."+this.id,this,c,b);
return this
}
(Afaict, eve is an Event framework, bundled with Raphael. Anyone know where the data goes from here?)
So this isn't going to help.
Inspecting the circle object, I was able to see/pull out a cx value, which I assume is the circleCenterX value that you're looking for...
var circ = paper.getById(name+"-circle");
console.log("baseVal is = ", circ[0].cx.baseVal.value);
console.log("animVal is = ", circ[0].cx.animVal.value);
Gives
baseVal is = 100
animVal is = 100
Is this what you're looking for?

Related

Check if rotation of model has changed?

How would you check if the rotation of a model has changed?
tried:
var oldRotate = this._target.quaternion;
console.log('works returns vector3 quaternion: ', oldRotate);
var newRotate = oldRotate;
if (oldRotate != newRotate) {
console.log('this isnt triggering');
}
this doesn't work and yes it's in a 'loop'
also tried:
var oldRotation = new THREE.Vector3();
oldRotation.copy(controlObject.quaternion);
controlObject.position.copy(pos);
this._position.copy(pos);
this._parent.SetPosition(this._position);
this._parent.SetQuaternion(this._target.quaternion);
var newRotation = new THREE.Vector3();
newRotation.copy(controlObject.quaternion);
console.log(oldRotation.equals(newRotation));
any ideas?
You can't compare objects for equality using the ==/!= operator. This will merely compare the references to the objects, not their values. You will need to compare using the .equals method.
Also, in your example, you're assigning oldR to newRotate directly. I'm not sure if you've not included some intervening code. Either way, you should also be using .clone otherwise the != will never happen.
See: https://threejs.org/docs/#api/en/math/Quaternion for information about the clone and equals methods.

"object HTMLDivElement" with outerHTML and with replaceWith() does nothing

I'm confused as to why this is failing.
I'm trying to directly replace a DIV completely with replaceWith from jquery.
i've tried bunch of variation, but either nothing gets updated. or if i try outerhtml [object HTMLDivElement] instead of the html. (which means I'm for sure working with a node, right? which means replaceWith() should work?).
I'm iterating through an array of currently displayed 'cardObjects', and comparing it to an identically structured incoming array (it's a sorted ordered list). the object's.html is the node element. and the object's.target is pointing to the element's id.
function cardConstructor(item)
{
var cardDiv = constructElement('div', "queCard", "machine"+item.machineID+"ID"+item.ID, "");
//more html stuff gets appended to this element, but not relevant for problem
cardObject =
{
ID: item.ID,
machineID: item.machineID,
lastID: item.lastID,
nextID: item.nextID,
jobID: item.jobID,
target: cardDiv.id, //string
html: cardDiv //node
}
return cardObject;
}
// here is where the problem is -
//it is in an update loop,
//this is failing
else if(inc[y].ID != current[y].ID)
{
console.log("ids do not match, splicing and replacing");
console.log("current y target is:");
console.log(current[y].target); //334 ---console output
var updateTarget = document.getElementById(current[y].target);
console.log("old html"); //337
console.log(updateTarget); //338
console.log("new html"); //339
console.log(inc[y].html); //340
updateTarget.replaceWith(inc[y].html);
console.log("update target updated: as"); //343
console.log(updateTarget); //344
current.splice(y,1, inc[y]);
}
the console.log output is:
current y target is:
machinewindow.php:334 machine1ID775
machinewindow.php:337 old html
machinewindow.php:338 <div class=​"queCard" id=​"machine1ID775">​<div class=​"queCardTitle" id=​"Titlemachine1ID775">​<div class=​"itter" id=​"itterDiv+1machine1ID775">​1​</div>​<button class=​"completeBtn" id=​"complete775" value=​"775">​complete​</button>​</div>​<div class=​"queCardBody" id=​"Bodymachine1ID775">​…​</div>​<div class=​"queCardFooterW" id=​"queCardFooterWmachine1ID775">​…​</div>​</div>​
machinewindow.php:339 new html
machinewindow.php:340 <div class=​"queCard" id=​"machine1ID774">​<div class=​"queCardTitle" id=​"Titlemachine1ID774">​…​</div>​<div class=​"queCardBody" id=​"Bodymachine1ID774">​…​</div>​<div class=​"queCardFooterW" id=​"queCardFooterWmachine1ID774">​…​</div>​</div>​
machinewindow.php:343 update target updated: as
machinewindow.php:344 <div class=​"queCard" id=​"machine1ID775">​<div class=​"queCardTitle" id=​"Titlemachine1ID775">​…​</div>​<div class=​"queCardBody" id=​"Bodymachine1ID775">​…​</div>​<div class=​"queCardFooterW" id=​"queCardFooterWmachine1ID775">​…​</div>​</div>​
here as shown in the console.log we get no updated div.
if i instead try updateTarget.outerHTML = inc[y].html - then I get [object HTMLDivElement] on the browser window.
I've tried a few iterations - and I'm a bit lost as to why this isn't working.
the object.html is a node, but won't replace another node with replaceWith();
I'm probably missing something.
also below is that constructElement function by request.
function constructElement(element, styleClass, type, data)
{
var ele = document.createElement(element);
ele.setAttribute("class", styleClass);
ele.setAttribute("id", type);
ele.innerHTML = data;
return ele;
}
If you want to use updateTarget.replaceWith(inc[y].html);
replace your line 335 with:
var updateTarget = $(current[y].target);
as replaceWith is a jQuery method and should be applied to jQuery object.
If you prefer using outerHTML, make sure you have a HTML string (not a node) on the right side, e.g.:
updateTarget.outerHTML = "<div>blah blah</div>";
or in your case:
updateTarget.outerHTML = inc[y].html.outerHTML;
Hope it helps.

I'm trying to use jquery to create a div containing columns but I can't get my array to format correctly

I have an array that contains dates. and for some reason I can't get it to show on my screen I've been debugging for a few days now and I've tracked it down to a single line, but the line has worked before and I can't figure out what the issue might be.
The array looks like this:
var selectItems =
[ "05-26-2017", "06-02-2017", "06-09-2017",
"06-16-2017", "06-23-2017", "06-30-2017", "07-07-2017", "07-14-2017",
"07-21-2017", "07-28-2017"...];
It's passed as an argument from another function, but that's how it's showing in console.log().
I might be going about this the wrong way, maybe even a lot further around then I need to but this is what I've come up with:
1. function setTHead(selectItems) {
2 var formatString;
3. for (var x = 0; x < 12; x++) {
4. formatString = selectItems[x].replace(/[^0-9/-]/g, "").toString();
5. console.log(selectItems);
6. $('#datTab').append("<div id='col" + x + "' class='column'>'" + formatString + "'</div>");
7. }
8. }
the array up top is what's showing from the console.log 5 lines down.
the sixth line is what is seeming to give me issues. Nothing is put on the page at all.
I'm getting a console error saying:
jQuery.Deferred exception: selectItems is undefined setTHead#http://localhost/mySite/script.js:136:9
startUp2#http://localhost/mySite/script.js:146:5
#http://localhost/mySite/table.php:19:9
mightThrow#http://localhost/mySite/lib/jquery.js:3586:52
resolve/</process<#http://localhost/mySite/lib/jquery.js:3654:49
setTimeout handler*resolve/<#http://localhost/mySite/lib/jquery.js:3692:37
fire#http://localhost/mySite/lib/jquery.js:3320:30
fireWith#http://localhost/mySite/lib/jquery.js:3450:29
fire#http://localhost/mySite/lib/jquery.js:3458:21
fire#http://localhost/mySite/lib/jquery.js:3320:30
fireWith#http://localhost/mySite/lib/jquery.js:3450:29
ready#http://localhost/mySite/lib/jquery.js:3923:13
completed#http://localhost/mySite/lib/jquery.js:3933:9
EventListener.handleEvent*#http://localhost/mySite/lib/jquery.js:3949:9
#http://localhost/mySite/lib/jquery.js:39:9
#http://localhost/mySite/lib/jquery.js:17:3
undefined
followed by:
TypeError: selectItems is undefined
and thats pointing to line 6.
if anyone has any advice I would be very much appreciative. Thank you in advance.
EDIT: A little more code:
function startTblView(defSel) {
if (defSel === true) {
setCookie('defSel', true, 7);
} else{
setCookie('defSel', false, 7);
}
saveSelected();
window.open('table.php', '_self');
defSel = getCookie('defSel');
if (defSel) {
selectItems = getDefDates();
}else {
selectItems = reGetSelected();
}
setTHead(selectItems);
}
defSel, is a boolean passed from my last page stating whether I'm doing a default view or a custom view, the custom view is passed from saveSelected();
saveSelected is a function for just saving the selected global value as a cookie so I can pull it out on the next page.
getDefDates pulls the default values for the array
reGetSelected, gets the selected array from the cookie.
I apologize for wonky naming conventions. I'm the only one working on this site and I'm just making sure the names don't overlap.
You can do this :
HTML code
<div id="datTab"></div>
JS code
var selectItems =
[ "05-26-2017", "06-02-2017", "06-09-2017",
"06-16-2017", "06-23-2017", "06-30-2017", "07-07-2017", "07-14-2017",
"07-21-2017", "07-28-2017"];
function setTHead(selectItems) {
var formatString;
$.each( selectItems, function( index, value ){
formatString = value.replace(/[^0-9/-]/g, "").toString();
$('#datTab').append("<div id='col" + index + "' class='column'>'" + value + "'</div>");
});
};
You can use $.each, its better than 'for' with javascript.
The .each() method is designed to make DOM looping constructs concise
and less error-prone. When called it iterates over the DOM elements
that are part of the jQuery object. Each time the callback runs, it is
passed the current loop iteration, beginning from 0. More importantly,
the callback is fired in the context of the current DOM element, so
the keyword this refers to the element.
I did a JsFiddle
Here.

Adding meta data to a primitive in javascript

Background
We have much of our data formatted like
var X = {value:'some val',error:'maybe an error',valid:true}
as a result we find ourselves calling X.value ALL the time.
We don't use the .error or .valid nearly as much, but we do use it.
What I want
To quit calling .value everywhere, but to still have access to meta data on a per data point level.
The Question
Is there one of
A) A way to put meta data on a primitive? attaching .error to an int for example? Is it possible for bools or strings?
B) A way to make a class that can be treated as a primitive, providing a specific data member when I do? IE X.value = 5, X+3 returns 8.
C) A better design for our data? Did we just lay this out wrong somehow?
You can set the method toString() to your object and return value.
var X = {
value: 1,
error:'maybe an error',
valid:true,
toString: function() {
return this.value;
}
}
X.value = 5;
console.log(X+3);
You can represent you data as a function object that also has properties:
var X = () => 1;
X.value = 1;
X.error = 'maybe an error';
X.valid = true,
console.log(X()); // 1
console.log(X.valid); // true
For better design you can encapsulate the creation of the data object in another function.

How can I compare a string to an object key and get that key's value?

I want to do something relatively simple, I think anyways.
I need to compare the pathname of page with an object's kv pairs. For example:
if("pathname" === "key"){return value;}
That's pretty much it. I'm not sure how to do it in either regular Javascript or jQuery. Either are acceptable.
You can see my fiddle here: http://jsfiddle.net/lz430/2rhds1x3/
JavaScript:
var pageID = "/electrical-electronic-tape/c/864";
var pageList = [{
"/electrical-electronic-tape/c/864": "ElectronicTape",
"/industrial-tape/c/889": "IndustrialTape",
"/sandblasting-tape/c/900": "SandblastingTape",
"/Foam-Tape/c/875": "FoamTape",
"/double-coated-d-c-dhesive-tape/c/872": "DCTape",
"/Adhesive-Transfer-Tape/c/919": "ATTape",
"/Reflective-Tape/c/884": "ReflectiveTape",
"/custom-moulding": "CustomMoulding",
"/request-a-quote": "RequestQuote"
}];
var label = pageID in pageList;
$('.el').html(label);
First, your "pageList" should just be a plain object, not an object in an array:
var pageList = {
"/electrical-electronic-tape/c/864": "ElectronicTape",
"/industrial-tape/c/889": "IndustrialTape",
"/sandblasting-tape/c/900": "SandblastingTape",
"/Foam-Tape/c/875": "FoamTape",
"/double-coated-d-c-dhesive-tape/c/872": "DCTape",
"/Adhesive-Transfer-Tape/c/919": "ATTape",
"/Reflective-Tape/c/884": "ReflectiveTape",
"/custom-moulding": "CustomMoulding",
"/request-a-quote": "RequestQuote"
};
Then you can set "label" to the value from the mapping:
var label = pageList[pageID] || "(not found)";
That last bit of the statement above will set the label to "(not found)" if the lookup fails, which may or may not be applicable to your situation.
It depends kinda on the logic you want to implement. If you want to say "if object has the key, then do X, and if not, then do Y", then you handle that differently than "set label to the object's key's value if the key is there, or else set it to undefined or something else".
For the first case you do:
if (pageList.hasOwnProperty(pageID) ) {
label = pageList[pageID];
}
else {
// do whatever, maybe some error?
}
For the second case, you can just say
var label = pageList[pageID] || 'notFound';
As indicated by #Pointy, either get rid of the array or subsiture pageList[0] for pageList and pageList[0][pageID] for pageList[pageID] above, if you need to keep the array.

Categories

Resources