I have a fairly large map consisting of Raphael paths which im trying to make accessible to some jquery ajax scripts to be populated. I've tried to add an ID or anything to make it accessible from jquery in an organized fashion.
As im new to Raphael I cant figure out a good way of achieving this.
I've tried using .data() to add an ID for each dot with say "seat_1","seat_2" and so on but been unsuccessful so far.
how would I go about organizing this code so I could manipulate it by looping?
I realize that its a fairly open ended question but any suggestion is much appreciated
Demo here: http://www.sam-sys.in/demo/pushparaj/ticketreservation/?page_id=203
var path_gs = rsr.path("M5.834,698.336c-3.217,0-5.833,2.615-5.833,5.831 c0,3.215,2.616,5.833,5.833,5.833c3.219,0,5.835-2.618,5.835-5.833C11.669,700.951,9.053,698.336,5.834,698.336");
path_gs.attr({"clip-path": 'url(#SVGID_2_)',fill: '#777675',parent: 'group_a','stroke-width': '0','stroke-opacity': '1'}).data('id', 'path_gs');
which generates
<path style="stroke-opacity: 1; " fill="#008000" stroke="#000000" d="M5.834,698.336C2.6169999999999995,698.336,0.0009999999999994458,700.951,0.0009999999999994458,704.167C0.0009999999999994458,707.3820000000001,2.6169999999999995,710,5.834,710C9.052999999999999,710,11.669,707.382,11.669,704.167C11.669,700.951,9.053,698.336,5.834,698.336" stroke-width="0" stroke-opacity="1"></path>
Well, the way I'm doing this is the following. First I write all the paths in an object, for example:
var paths = {
path1: 'the paths coordinates',
path2: 'the paths coordinates',
path3: 'the paths coordinates',
}
Then you just loop trough all the paths, seting the coordinates for each path and giving them an ID (this is an internal Raphael's ID):
for(path in paths){
var newpath = paper.path(paths[path]);
newpath.attr({options})
newpath.id = path;
}
Now, if you want to get one of this elements you can use the next Raphael feature:
var thisPath = paper.getById('path1');
This way you can use the path on any of the Raphael methods. So, if you need to get the node in the dome you can do the following:
var node = thisPath.node
But if you need to animate the path, you better use the Raphael's animate method, or if you need to change attibutes the attr method.
thisPath.animate(.....)
If you need to apply some change to all the paths, you can use:
paper.forEach(function(thisArg))
you need to pass the function to run on each element and thisArg reference the element on each iteration
And maybe you want to take a look to the Raphael's sets wich can be useful for use methods on groups of elements. If you need any help using this features just let me know and I'll do my best to help you out. Bye!
You could just push them to an array :
var pathArray = new Array();
var path_gs = rsr.path("path coords");
pathArray.push(path_gs);
Then loop through pathArray.
Another option is grouping them in sets.
Related
I'm using Code Mirror to create a simple code editor that creates shapes on a canvas based on certain commands. I would like to use Code Mirror's annotations to store a shape ID in the line's metadata. That way when I delete a line on the commands I can easily tell the Canvas which shape to delete.
I've been looking through the code mirror's documentation for a while now and still have no idea how I would go about implementing this.
How can I access the metadata (annotations) in text with CodeMirror?
Any help is much appreciated.
Okay, I figured it out. CodeMirror has a function "markText" which can be used to give a className to the line for specific CSS styling. It can also be used to pass in any other parameters including user-created ones like shapeID.
// Give a line an ID
function giveLineID(lineIndex,id){
editor.markText( {line:lineIndex,ch:0},{line:lineIndex,ch:line.length},{shapeID : id});
}
// Retrieve an ID from a line
function retrieveID(lineIndex){
var line = myCodeMirror.getLine(lineIndex);
var marks = cm.findMarks({line:lineIndex,ch:0},{line:lineIndex,ch:line.length});
marks.forEach(mark => {
if (mark.hasOwnProperty("shapeID")){
return mark["shapeID"];
}
});
}
I need to use JavaScript to search the source code of the current page for a string, e.g data-userId="2008", then extracts the id number (2008 in this case) and creates a hyperlink to include it, e.g. http://www.google.com?2008.
I've been attempting to use indexOf and document.documentElement.innerHTML approaches but not getting anywhere. I've got closer with the help of this post but no success yet.
Here's what i have so far:
<script type="text/javascript">
function getVals() {
code = document.getElementsByTagName("html")[0].innerHTML;
results = code.match(/data-userId=(\d*)&/g);
for (i=0;i<results.length;i++) {
value = results[i].match(/data-userId=(\d*)&/);
}
}
onload = getVals;
document.write(code);
</script>
Due to restrictions on our network the solution needs to be JavaScript.
Use the getAttribute() method of the Element object http://www.w3schools.com/jsref/met_element_getattribute.asp.
I'm not sure why exactly you'd query the html element and then look at innerHTML. Do you not know which tags/selectors will contain the data attribute you're looking for? If you don't know which selectors you're looking for you can use a recursive function like this to walk the DOM and store the values in a data structure of your choice - I'll use an array of objects in this example (not sure how you need this data formatted).
Also, I'm not sure how you're choosing to visit these pages, but the below code could be easily modified to create hyperlinks when/if the attributes you're looking for are found.
var storeElements = [];
function walkTheDOM(node){
if(node.getAttribute('data-userId') !== null){
storeElements.push({"element": node, "attrValue": node.getAttribute('data-userId'});
}
node = node.firstChild;
while(node){
walkTheDOM(node);
node = node.nextSibling;
}
}
Then you can call the function like this:
walkTheDOM(document.querySelectorAll('html')[0]);
If this isn't what you're looking for let me know and I can change my answer. For those of you who've read Douglas Crockford's "Javascript: The Good Parts" this function may look very familiar :).
I have this line of code:
var filterInputs = $(this).siblings('.filterInputs');
which performs some work on filterInputs. Later on, I would like to reduce my collection of filterInputs to just those which are visible.
Clearly, I could do this:
var visibleFilterInputs = $(this).siblings('.filterInputs:visible');
but that seems inefficient given the fact that I already have a reference to the collection I was hoping to reduce.
Is there a way to say something like:
//TODO: Example
var visibleFilterInputs = $(filterInputs:visible);
without having to iterate over the DOM tree again? Thanks
You're absolutely right, there's no reason to recollect the DOM elements, since you already have them in a jQuery object. So that's exactly what the .filter() method is for: http://api.jquery.com/filter/
Try this:
var visibleFilterInputs = filterInputs.filter(":visible");
Here's an example: http://jsfiddle.net/FC9sH/
Note that it's better to target a certain HTML tag, such as <div>, to make the :visible selector a little more efficient (since it isn't part of the CSS specs and can't be optimized by native methods). At least in your case, you're already using the filterInputs class. Anyways, maybe something like:
var visibleFilterInputs = filterInputs.filter("div:visible");
but only if that's applicable. I mean, even selecting multiple known element tags is probably better:
var visibleFilterInputs = filterInputs.filter("div:visible, p:visible");
I'm very new to SVG (using D3.js to call everything). Recently, I just came into a huge limitation with a project I am working on. I want to be able to make "g" classes for each category of data I am working with. Unfortunately, I am getting my data from an XML file that only connects data in one way (ex: person1 ---> person2, but not person2 ---> person1). What I would like to be able to do is to put each shape generated from my data in the root class AND the class it is connecting with. If I could add this shape to two or more classes (such as g class = person1 and person2), that would be the fastest solution I believe...But is something like this possible? Can I set an SVG shape to two or more classes? Or will it overwrite it as I define new ones.
I really hope someone can understand what I am asking. It is kind of hard to verbalize my problem without giving away every detail of my final project.
Yes, you can set multiple classes. For example,
<g class="person1 person2">
Or, in D3:
g.attr("class", "person1 person2");
One more note: If you're calling a function from within a file:
.attr("class",function(d) { return d.person1+" "+ d.person2;} )
I've got a web page with a US map that has clickable paths that generate a popup, coded with Raphael.js and a paths file containing all the state's paths. I loop through the paths file to create the paths and set the onClick and hover functions for the popups.
I have one path that is not a state, it is a border around the misplaced Alaska and Hawaii. Problem is when I loop through the code, it gets set to fill and onClick functions same as the other paths.
I know I need a conditional in there to change attributes for that one path, but I'm not savvy enough to be able to code it correctly. Maybe access the DOM through node, but I'm not sure how/where.
Map created with this script.
paths set with /js/paths.js
css is /css/default.css
I've searched the archive and gotten close to a solution from info posted there, but I'm banging my head trying to tweak it to work - any help GREATLY appreciated!!!
The border is called "BD" so you can do something like this or even create a different borderAttributes object and assign different attributes when country == "BD"
for (var country in paths) {
var obj = r.path(paths[country].path);
if (country != "BD") {
obj.attr(attributes);
}
arr[obj.id] = country;