Cannot call method 'setData' of undefined - javascript

EDIT 1
Using the method dataTransfer.setData make it works !
http://jsfiddle.net/UH7Sf/1/
d3.event.dataTransfer.setData('type',type);
I'm facing a issue using methods setData and getData within d3.event
I have to div with a draggable img element in the top one, and some drop capabilities on the second one.
d3.select('img').on('dragstart', function() {
var type = d3.select(this).attr('type');
console.log("Drag starts with "+ type);
d3.event.transfer.setData('type',type);
});
d3.select('.drop').on('drop', function() {
d3.event.preventDefault();
var type = d3.event.transfer.getData('type');
console.log("Drag ends with "+ type);
});
d3.select('.drop').on('dragover', function() {
d3.event.preventDefault();
});
Here is the fiddle : http://jsfiddle.net/UH7Sf/
There is another solution to do this (transfering data within the drag&drop) using d3 ?

There is no object inside event called transfer. One thing you can do is try event.setData(), but I don't think that's what you want either, because the dragstart and drop events are two different event objects.
You can instead have a separate local variable to use. E.g.
var draggedType = null;
d3.select('img').on('dragstart', function() {
var draggedType = d3.select(this).attr('type');
console.log("Drag starts with "+ draggedType);
});
d3.select('.drop').on('drop', function() {
d3.event.preventDefault();
console.log("Drag ends with "+ draggedType);
// do something with draggedType here
draggedType = null; // reset draggedType to null when done, just in case
});

Related

Change value of first iteration input with next iteration input value

Structure Concept:-
Basically, i am trying to create the modal window containing input and that modal window currently fires when the input on index page get focused for that I have used data attribute to make a link between them by assigning them same attribute value.
Javascript Concept:-
for the modal window, I have created the modal object. and model object contains a bindModal method which takes one argument and that argument is data attribute value. after taking that value bindModal method will search dom elements containing that particular value and after the search, I iterate over them using each loop.
Problem
So basically I want whenever user starts typing on the model input it should get written automatically in input on the index page.
I will appreciate you all if guys help me out to make my code more optimized and well structured and most important thing is that let me know what mistake I have done in overall work Thanks
JavaScript Code
var modal = function () {
this.toggleModal = function () {
$('#modal').toggleClass('content--inActive').promise().done(function () {
$('#modal__close').on('click',function(){
$('#modal').addClass('content--inActive');
});
});
}
this.bindModal = function (bindVal) {
var bindValue = $(document).find('[data-modal-bind = ' + bindVal + ']');
$.each(bindValue, function (index) {
var bind1 = $(this);
if(index === 1) {
var bind2 = $(this);
$(bind1).change(function (){
$(bind2).val(bind1.val());
});
}
});
}
}
var open = new modal();
$('#input_search').on('click',function(){
open.toggleModal();
open.bindModal('input');
});
Here is one way to do what you want:
var modal = function() {
this.bindModal = function(bindVal) {
var bindValue = $('[data-modal-bind = ' + bindVal + ']');
bindValue.each(function(index) {
$(this).keyup(function() {
var value = $(this).val();
bindValue.each(function(i, e) {
$(this).val(value);
});
});
});
}
}
$('#input_search').on('click', function() {
var open = new modal();
open.bindModal('input');
});
Changes done:
I cached the inputs with same binding values in bindValue variable, and then bound the the keyup event for each of them. On keyup, the value of the current input is get in value, which is then assigned to each input using the inner loop.
This makes the inputs to be in sync while typing. Hope that solves your issue.

JS Hooking Custom Events

I have a client side script for my .NET control. The script hooks all the :checkbox items to trigger an event called OnOptionItemSelected.
function ControlScript() {
this.OnOptionItemSelected = function (e) { /* do something */ }
this.Configure = function () {
// hook change event of items in the input control
$('#' + this.ControlID).find(":radio, :checkbox")
.on("change", this, this.OnOptionItemSelected);
}
}
(Some pieces of code removed)
In another place on the page, I get the client side script for a particular control and need to hook the OnOptionItemSelected event. How would I hook this event?
var script = GetScriptForControl(ID);
if (script)
// hook script.OnOptionItemSelected to a custom function ????
I will suppose that the GetScriptForControl return a instance of ControlScript. So what i would do is:
if(script) {
oldOptionItemSelected = script.OnOptionItemSelected
script.OnOptionItemSelected = function(ev) {
/* before OptionItemSelected code HERE */
oldOptionItemSelected.call(script,ev);
/* after OptionItemSelected code HERE */
};
/* rebind the events */
script.Configure();
}
I actually found an answer that better suits my needs:
function ControlClientSide()
{
this.CheckBoxClicked = function() { }
this.Configure = function() {
$('#checkBox100').change(function() { $(this).triggerHandler("CheckBoxClicked"); }.bind(this));
};
this.Configure();
};
var x = new ControlClientSide();
$(x).on("CheckBoxClicked", function() { alert( this.constructor.name + ' Hi'); })
.on("CheckBoxClicked", function() { alert( this.constructor.name + ' Hi2'); });
The only thing I cant figure out is how to get "this" to be the checkbox in the "CheckBoxClicked" event handlers. Currently it is set to the ControlClientSide function.
See example: http://jsfiddle.net/KC5RH/3/

Detect element style change in chrome

I'm trying to find a way to detect changes to the element style but I haven't had much luck. The code below works on a new property I define like tempBgColor but I cannot override/shadow an existing property like color. I know jquery has a watch function, but it only detects changes from the jquery api but not directly changing the value of a style something like elem.style.color.
var e = document.getElementById('element');
e.style.__defineGetter__("color", function() {
return "A property";
});
e.style.__defineSetter__("color", function(val) {
alert("Setting " + val + "!");
});
Any pointers?
You should be able to do this with a MutationObserver - see demo (Webkit only), which is the new, shiny way of getting notified about changes in the DOM. The older, now deprecated, way was Mutation events.
Demo simply logs in the console the old and new values when the paragraph is clicked. Note that the old value will not be available if it was set via a non-inline CSS rule, but the change will still be detected.
HTML
<p id="observable" style="color: red">Lorem ipsum</p>​
JavaScript
var MutationObserver = window.WebKitMutationObserver;
var target = document.querySelector('#observable');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log('old', mutation.oldValue);
console.log('new', mutation.target.style.cssText);
});
});
var config = { attributes: true, attributeOldValue: true }
observer.observe(target, config);
// click event to change colour of the thing we are observing
target.addEventListener('click', function(ev) {
observable.style.color = 'green';
return false;
}, false);
Credit to this blog post, for some of the code above.
With Chrome's Developer Tools open, you can find the element whose style's change you're interested in, right click it, select "Break on..." and "Attributes modifications".
here is a naive implementation using setTimeout with undescorejs.
The only way to find out which change was made is to iterate through the style object properties.
Here is the live example
$( function () {
var ele = document.getElementById('ele'),
oldStyle = {};
function checkEquality() {
style = _.clone(ele.style);
if (!_.isEqual(style, oldStyle)) {
console.log('Not equal');
oldStyle = _.clone(style);
} else {
console.log('Equal');
}
_.delay(checkEquality, 2000);
}
checkEquality();
$('a#add_prop').on('click', function () {
var props = $('#prop').val().replace(/ /g, '').split(':');
console.log(props);
$(ele).css(props[0], props[1]);
});
$('#prop').on('keydown', function (e) {
if (e.keyCode == 13) {
$('a#add_prop').trigger('click');
}
});
});

how to fix my JQuery bug?

The script is on jsfiddle here : CODE
What it does at the moment: it's a form that have two types of URL field textarea and input, it converts the texts in those fields to a link to be click-able.
How it works: if you click next to the link/links you can edit the link or on a double click on the link. IF you click once on the link it takes you to that page.
Last update: i added the .trigger('blur'); on the last line, Because before i did that, the text area was showing the links like one merged link, for example : test.com and test2.com were showing test.comtest2.com, after i added this last update, the split for textera work also on the load of page not just on the edit of textarea ( it was working without the last update but only when you edit the textarea and put between links a space, and i want it to be working on the load of page because the textarea format was sent already as one link pre row ).
My problem: after i did this last update, the double click is messed up, it should just be able to edit the link and don't go to that page unless one click, but now it edits it and in like one second it goes also to that page. I want the double click just to edit without going to that page. and to go only with one click.
Thanks a lot in advance!
The code also here:
$('.a0 a').click(function(){
var href = $(this).attr('href');
// Redirect only after 500 milliseconds
if (!$(this).data('timer')) {
$(this).data('timer', setTimeout(function () {
window.open(href, '_blank')
}, 500));
}
return false; // Prevent default action (redirecting)});
$('.a0').dblclick(function(){
clearTimeout($(this).find('a').data('timer'));
$(this).find('a').data('timer', null);
$(this).parent().find('input,textarea').val($(this).find('a').text()).show().focus();
$(this).hide();})
$('.a0').click(function(){
$(this).parent().find('input,textarea').val($.map($(this).find('a'),function(el){return $(el).text();}).join(" ")).show().focus();
$(this).hide();})
$('#url0, #url1,#url4').each(
function(index, element){
$(element).blur(function(){
var vals = this.value.split(/\s+/),
$container = $(this).hide().prev().show().empty();
$.each(vals, function(i, val) {
if (i > 0) $("<span><br /></span>").appendTo($container);
$("<a />").html(val).attr('href',/^https?:\/\//.test(val) ? val : 'http://' + val).appendTo($container);;
}); })
}).trigger('blur');
A double-click is always predeeded by the following chain of events:
mousedown, mouseup, click, mousedown, mouseup, click, dblclick
You can make your click-events wait and check if a double-click event happened afterwards. setTimeout is your friend. Be sure to copy any data you need from the event object passed to your handler. That object is destroyed after the handler finished - which is before your delayed handler is invoked.
You can manually dispatch a double click event to prevent click-events from being executed prior to them. See the Fiddle
// ms to wait for a doubleclick
var doubleClickThreshold = 300;
// timeout container
var clickTimeout;
$('#test').on('click', function(e) {
var that = this;
var event;
if (clickTimeout) {
try {
clearTimeout(clickTimeout);
} catch(x) {};
clickTimeout = null;
handleDoubleClick.call(that, e);
return;
}
// the original event object is destroyed after the handler finished
// so we'll just copy over the data we might need. Skip this, if you
// don't access the event object at all.
event = $.extend(true, {}, e);
// delay click event
clickTimeout = setTimeout(function() {
clickTimeout = null;
handleClick.call(that, event);
}, doubleClickThreshold);
});
function handleClick(e) {
// Note that you cannot use event.stopPropagation(); et al,
// they wouldn't have any effect, since the actual event handler
// has already returned
console.log("click", this, e);
alert("click");
}
function handleDoubleClick(e) {
// this handler executes synchronously with the actual event handler,
// so event.stopPropagation(); et al can be used!
console.log("doubleclick", this, e);
alert("doubleclick");
}
jsfiddle refuses to load on my connection for some reason, so cant see the code.
Based on your explanation i suggest you look into event.preventDefault to add more control on what should happen on your click events. This could be used in conjunction with #rodneyrehm's answer.
Refer to my previous answer.
For your quick reference, I have pasted my answer here
$('.a0 a').click(function(){
var href = $(this).attr('href');
// Redirect only after 500 milliseconds
if (!$(this).data('timer')) {
$(this).data('timer', setTimeout(function() {
window.open(href, '_blank')
}, 500));
}
return false; // Prevent default action (redirecting)
});
$('.a0').dblclick(function(){
var txt = document.createElement('div');
$.each($(this).find('a'), function(i, val) {
clearTimeout($(val).data('timer'));
$(val).data('timer', null);
$(txt).append($(val).text());
$("<br>").appendTo(txt);
});
var content = $(this).parent().find('input,textarea');
var text = "";
$.each($(txt).html().split("<br>"), function(i, val) {
if (val != "")
text += val + "\n";
});
$(content).html(text);
$(this).hide();
$(content).show().focus();
})
$('#url0, #url1, #url4').each(function(index, element) {
$(element).blur(function(){
if ($(this).val().length == 0)
$(this).show();
else
{
var ele = this;
var lines = $(ele).val().split("\n");
var divEle = $(ele).hide().prev().show().empty();
$.each(lines, function(i, val) {
$("<a />").html(val).attr({
'href': val,
'target': '_blank'}).appendTo(divEle);
$("<br/>").appendTo(divEle);
});
}
});
});
​

How do I declare event object with onclick event using Javascript (not html)?

Here is my code:
function testimage() {
var image;
image = new Image();
with (image) {
id = "page1";
border = 0;
name = "IllustGIF";
useMap = "#MAP1";
src = "sample.gif" + "?d=" + new Date();
// The event argument here is invalid; it's to show what is the desired result.
onclick = function() { RecordMouseClick(event, this.id); };
}
// attached to body tag
document.getElementById("body_ID").appendChild(image);
}
function RecordMouseClick(event, id) {
alert("id: " + id + ", and event object should contain mouse x- and y- coordinates clicked");
}
I need to define the onclick event in JavaScript, not HTML. Now in HTML, it's easy -- just pass event as an argument to the function and, voila, event object in JavaScript But doing it all from scratch, all in JavaScript, without HTML, is challenging for me. When the reference function is called, it's supposed to record the element id and the mouse click x- and y- coordinates from the onclick event.
How can I pass an event to the onclick, such that the event object is valid at run-time?
Thank you.
Here's a sample fiddle.
image.onclick = function(e) {
e = e || window.event;
RecordMouseClick(e, image.id);
};
document.getElementById('id-of-the-html-element').onclick = function(){
// your code
};
or
function doSth(){
// your code
}
document.getElementById('id-of-the-html-element').onclick = doSth;
Read more about it over here: https://developer.mozilla.org/en/DOM/event
Try addEventListener().
image.addEventListener('click',
function(e) {
RecordMouseClick(e, this.id);
}, false);

Categories

Resources