Drag and drop events in embedded SVG? - drag-and-drop

Is there any possibility of receiving drag and drop events from SVG elements within a web page?
I tried the Google Closure library, to no avail.
Specifically, suppose my page contains
<ul id = "list">
<li class="item" id="item1">foo</li>
<li class="item">bar</li>
<li class="item">baz</li>
</ul>
And my script contains (Clojurescript/C2)
(let [items (select-all ".item")
lst (select "#list")
target (fx/DragDrop. lst nil)]
(dorun (map
(fn [item]
(let [source (fx/DragDrop. item nil)]
(. source (addTarget target))
(. source (init))))
items))
(. target (init)))
Then I do get a drag image (ghost), although I do not manage to receive drag events e.g. by doing
(on-raw "#item1" :dragstart (fn [e] (.log js/console (str "dragstart " e))))
Using similar code for SVG elements, I do not even get a ghost...
Any hints?
Thanks

Drag events are not supported on SVG Elements: http://www.w3.org/TR/SVG/svgdom.html#RelationshipWithDOM2Events.
You can fake the drag events with mouse events, see http://svg-whiz.com/svg/DragAndDrop.svg (view the source).

You can always implement it. Basically, you have to check if the element is touching another one when you are dragging:
this.isTouching = function(element){
if(this.x <= element.x && element.x <= (this.x + this.width) &&
this.y <= element.y && element.y <= (this.y + this.height)){
return true;
}else{
return false;
}
};
And it works in all browsers. Hope it helps :)

Related

TInyMCE Preview Plugin : Link is not clickable

I am uses TinyMCE 4 where I have inserted source content as link
Sample Link
After inserting above content in the TinyMCE, if I click on the preview button of TinyMCE then anchor tag is coming in the form of link but it's not clickable.
Can anyone guide how anchor we can make it as clickable?
I have followed below links(by adding default_link_target: "_blank"):
https://community.tinymce.com/communityQuestion?id=90661000000MrWjAAK
&
How to open hyperlink in new window under tinymce text editor?
but none seems to be worked.
but none seems to be worked.
The preview plugin has code that specifically stops links from being clickable. If you look at the JavaScript code for the plugin you will see something like this:
var preventClicksOnLinksScript = (
'<script>' +
'document.addEventListener && document.addEventListener("click", function(e) {' +
'for (var elm = e.target; elm; elm = elm.parentNode) {' +
'if (elm.nodeName === "A") {' +
'e.preventDefault();' +
'}' +
'}' +
'}, false);' +
'</script> '
);
This code is there specifically to address an issue that could cause a link in preview to unintentionally remove the editor instance.
If you click a link in the preview pane that has a target=_top you will end up blowing away the editor and replacing it with the content of that link - likely not what you want.
I know it's an old thread but maybe it will help someone out there. If you want the links to open in a new window in tinymce prevew plugin remove this script:
<script>document.addEventListener && document.addEventListener("click", function(e) {for (var elm = e.target; elm; elm = elm.parentNode) {if (elm.nodeName === "A") {e.preventDefault();}}}, false);</script>
and place this one instead:
<script>function externalLinks() { for(var c = document.getElementsByTagName("a"), a = 0;a < c.length;a++) { var b = c[a]; b.getAttribute("href") && b.href.hostname !== location.hostname && (b.target = "_blank") } } ; externalLinks();<\/script>
Enjoy!

How deep down the DOM tree is contenteditable-ity retained?

Background:
I wish to execute work based off whether a node is content editable or not. The node is captured onkeyup through event.target. Consider this complex contenteditable node structure:
<div contenteditable="true">
<div contenteditable="true">
<ol>
<li>
<a href="google.com">
<span style="color: red;">Hi!</span>
</a>
</li>
</ol>
"A text node"
<p>Some more text</p>
</div>
</div>
I wish a keyup inside the span node, as well as the text node, to detect them as a contenteditable node and perform work.
So, I wrote this function (long but straightforward):
// callForParent: flag to prevent infinite recursion
window.isContentEditable = function(node, callForParent){
var tgN = node && node.tagName,
attr, parentCount, parent, MAX_PARENTS_CHECKED = INTEGER_VALUE (3,4,5,etc.);
// insanity checks first
if(!node || tgN === "TEXTAREA" || tgN === "INPUT" || !node.getAttribute)
return false;
else{
attr = node.attr("contenteditable");
// empty string to support <element contenteditable> markup
if(attr === "" || attr === "true" || attr === "plaintext-only")
return true;
// avoid infinite recursion
if(callForParent) return false;
parentCount = 1;
parent = node;
do{
parent = parent.parentNode;
parentCount++;
if(!parent) return false;
// parent check call
if(isContentEditable(parent, true)) return true;
}while(parentCount <= MAX_PARENTS_CHECKED);
return false;
}
};
Problem:
Notice the counter limit MAX_PARENTS_CHECKED above. That makes sure how many levels up the DOM tree I go in search of a parent contenteditable node.
Does that counter affect the logical correctness of my program? I mean, like in the HTML structure I showed above, we need the limit to be 4 to cover all cases. There might be need of more.
But I fear that increasing the limit greater than some point might make non-contenteditable nodes to be detected to be detected as contenteditable. Is this fear of mine true/possible? Are there examples to show that deep descendants of contenteditable node can be non-CE node?
I don't want to execute things in a deep-down non-CE node if say, it CANNOT be edited by the user and then my app gives an error.
Sorry if I sound nitpicky but I need confirmation
UPDATE: As confirmed by user3297291 in the comments, there exist instances where keyup on a non-CE child of a CE node are detected as having event.target == to the parent and NOT the child, contrary to what one might expect. These are situations where my app might fire, and expect a caret Range, Selection, etc. to perform some work, and there it will give an error.
Does there exist some fix/proper way of doing this?

Leaflet Popups with Clojurescript

I'm pretty sure this is a conceptual error, but I'm not sure where I'm making the incorrect call.
Following the leaflet tutorial, I'm trying to create a popup on a map. Per the tutorial, this is a simple operation
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(mymap);
}
mymap.on('click', onMapClick);
However, when I translate this into clojurescript, I receive the following error:
Uncaught TypeError: t.openPopup is not a function
I'm 100% positive I'm calling the javascript incorrectly. I'm doing the following:
(defn onMapClick [e]
(let [popup (js/L.Popup.)]
(-> popup
(.setLatLng (.-latlng e))
(.setContent (str "You clicked the map at " (.-latlng e)))
(.openOn map))))
And then I call this as:
(.on map "click" onMapClick)
where map is correctly defined. (I say correctly because I am able to draw polygons and create popups that are bound to those polygons with .bindPopup)
I was thinking of not relying on return values at all. Just relying on the call sequence:
(defn onMapClick [e]
(let [popup (js/L.Popup.)]
(.setLatLng popup (.-latlng e))
(.setContent popup (str "You clicked the map at " (.-latlng e)))
(.openOn popup map)))
If the docs say that these js setter functions return popup then this won't make much of an answer!
You should be able to isolate the problem down to just one function call??

Google analytics in SPA

I have a website which is like this
http://domain/?key=32dxzQW
where the key is auto generated from other site per user
What I need to know are the sections most visited, so I was thinking in use GA, and as my webpage is SPA the sections are handled using hash (#) in the URL. Here some examples:
http://domain/?key=32dxzQW#start
http://domain/?key=32dxzQW#section1
http://domain/?key=sfd2ACS#start
http://domain/?key=sfd2ACS#section1
http://domain/?key=sfd2ACS#section2
http://domain/?key=ssC56tE#start
I want to know if there is a way to get by GA a summary of the sections, like this:
start 3
section1 2
section2 1
Help please
Update:
I already did the change to handle fragments and works:
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date(); a = s.createElement(o),
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
function sendToGA() {
ga('create', 'XXXXXXXXXXX', 'auto');
ga('send', 'pageview', {
'page': location.pathname + location.search + location.hash
});
}
sendToGA();
window.onhashchange = sendToGA;
The first thing that came to my mind is to add click or other events on the sections you want to track and check them in the Behavior -> Events section in GA.
GA doesn't track hashes (URL fragments) by default, but you can follow this guide to help with setting up virtual page views for each section of your page:
Tracking URL page fragments

Why is IOS 7.0.3 picker goofing up my LiveCode webform?

I don't know where the best place to ask about this is. My problem seems to be with IOS 7.0.3 and how Safari is handling the picker in a web form. I've created a web form with LiveCode that works just fine in every browser I've tried. But on the iPhone, the picker malfunctions. If you choose one item and press Done, it reverts to 0 items chosen. If you choose two items and press done, it shows one item chosen. The same goes for three, four, and so on. Has anyone else had this experience? Here is a snippet of one of the multiple choice buttons.
<label for="authors[]">
Select Author(s)
<select name="authors[]" id="authors" multiple="yes" size="7" >
<?lc
put the number of lines in tAuthorList into tTotalAuthors
repeat with x = 1 to tTotalAuthors
put "<option value=" & q(line x of tAuthorList)
put lineOffset(line x of tAuthorList,tPrevAuthors) into tLineHit
if bDataSubmitted and line x of tAuthorList is line tLineHit of tPrevAuthors then
put " selected"
end if
put ">" & line x of tAuthorList & "</option>" & return
end repeat
?>
</select>
</label>
This is the URL:
http://lc.scs.earlham.edu/soul_therapy3.lc
Incidentally, I use it with an iframe in my Drupal 7 site:
http://soulshare.org/soul_therapy/tool
There is an issue (design choice?) in iOS7 where you need to not only scroll to the correct value but also tap your selected value. I don't know if this is your problem though...
In some forms you only needs to scroll to the correct value but in many, you need to scroll and THEN select. As you probably have guessed this has nothing to do with LiveCode...
This is a bug in IOS and has been reported to apple. Currently the best solution I've found uses jQuery to fix the selected items upon closing the picker. Simply paste this into your JS file and away you go.
// hack for iPhone 7.0.3 multiselects bug
if(navigator.userAgent.match(/iPhone/i)) {
$('select[multiple]').each(function(){
var select = $(this).on({
"focusout": function(){
var values = select.val() || [];
setTimeout(function(){
select.val(values.length ? values : ['']).change();
}, 1000);
}
});
var firstOption = '<option value="" disabled="disabled"';
firstOption += (select.val() || []).length > 0 ? '' : ' selected="selected"';
firstOption += '>« Select ' + (select.attr('title') || 'Options') + ' »';
firstOption += '</option>';
select.prepend(firstOption);
});
}
Multiple select in Safari iOS 7