In addition to this question Highlight text when hover imagemap area and vice versa - using imagemapster I'm searching for a solution to add a class to an image outside the imagemap. The intention is when hovering on a part of the imagemap a line is showing beneath a image above the imagemap. For an example and partly working script (which is based on the question above): http://jsfiddle.net/kyzho2v4/3/
jQuery(document).ready(function ($) {
$('#house').mapster({
mapKey: 'name',
singleSelect: true,
fillOpacity: 0.6,
fillColor: 'FF0000',
//
onMouseover: function (evt) {
var parts = evt.key.split('-');
var part = parts[1];
highlightArea(part);
},
//
onMouseout: function (evt) {
var parts = evt.key.split('-');
var part = parts[1];
highlightAreaX(part);
}
});
//
$('a').hover(function () {
var parts = $(this).closest('div').attr('class').split('-');
var part = parts[2];
highlightArea(part);
});
//
$('a').mouseleave(function () {
var parts = $(this).closest('div').attr('class').split('-');
var part = parts[2];
highlightAreaX(part);
});
});
//
function highlightArea(key) {
$('area[name=part-' + key + ']').mouseenter();
$('a').addClass('line');
$('div.menu-item-' + key + ' a').addClass('line');
}
//
function highlightAreaX(key) {
$('area[name=part-' + key + ']').mouseout();
$('a').removeClass('line');
$('div.menu-item-' + key + ' a').removeClass('line');
}
Posted OP's answer as an answer:
I found a solution, so for those who are searching the same thing: I only added a new css class (line1) and changed the jquery script a little bit: http://jsfiddle.net/88c0odmn/7/
//
function highlightArea(key) {
$('area[name=part-' + key + ']').mouseenter();
$('div.menu-item-' + key + ' a').addClass('line1');
}
//
function highlightAreaX(key) {
$('area[name=part-' + key + ']').mouseout();
$('a').removeClass('line');
$('div.menu-item-' + key + ' a').removeClass('line1');
}
Related
I am using d3-dagre to render the data. Initially i can render the data without any problem. When i try to update the same view in watch mode, it is updating the data but still some error is thrown in the console for "g" attribute transformation. Whenever i try to rewrite the SVG elements i am removing the "g" element inside the "svg" tag. I am trying this in vuejs2 ui library.
watch: {
workflowDetails: function (changes) {
console.log('Update component ==> ' + changes)
this.workflowName = changes.label
this.workflowDetails = changes
this.metricGraph = false
this.drawDAGView()
}
},
mounted () {
this.drawDAGView()
},
methods: {
getJobid: function (nodeId) {
console.log('Function to get graph api' + nodeId)
this.metricGraph = true
},
drawDAGView: function (isUpdate) {
/* eslint-disable */
d3.selectAll('svg > g').remove()
// Create a new directed graph
var g = new dagreD3.graphlib.Graph().setGraph({})
var DagNodes = this.workflowDetails.nodes
var fillColor
// Add states to the graph, set labels, and style
Object.keys(DagNodes).forEach(function(key) {
console.log("Nodes - "+ DagNodes[key].name)
var value = DagNodes[key]
value.label = DagNodes[key].name + " (" + DagNodes[key].exec_time + ")"
value.rx = value.ry = 5
g.setNode(DagNodes[key].name, value)
})
var DagEdges = this.workflowDetails.edges;
// Add states to the graph, set labels, and style
Object.keys(DagEdges).forEach(function(key) {
g.setEdge(DagEdges[key].startEdge, DagEdges[key].endEdge, { label: ""} )
})
// Create the renderer
var render = new dagreD3.render()
// Set up an SVG group so that we can translate the final graph.
var svg = d3.select("svg"),
inner = svg.append("g")
// Set up zoom support
var zoom = d3.behavior.zoom().on("zoom", function() {
inner.attr("transform", "translate(" + d3.event.translate + ")" +
"scale(" + d3.event.scale + ")")
})
svg.call(zoom)
// Simple function to style the tooltip for the given node.
var styleTooltip = function(name, description) {
return "<p class='name'>" + name + "</p><p class='description'>" + description + "</p>"
}
// Run the renderer. This is what draws the final graph.
render(inner, g)
inner.selectAll("g.node")
.attr("title", function(v) {
return styleTooltip(v, "Execution Time: "+g.node(v).label + " <br /> Description: "+g.node(v).label)
})
//.each(function(v) { $(this).tipsy({ gravity: "w", opacity: 1, html: true }) })
var self = this
inner.selectAll("g.node")
.on("click", function(v) {
console.log("Nodes --> "+ v + " -- "+ g.node(v).node_id)
// whatever
//window.location = "../dag/"+g.node(v).job_id
self.nodeId = g.node(v).node_id
console.log("Node id -- "+ self.nodeId)
self.getJobid(self.nodeId)
})
// Center the graph
var initialScale = 1.2
zoom
.translate([(svg.attr("width") - g.graph().width * initialScale) / 50, 20])
.scale(initialScale)
.event(svg)
svg.attr('height', g.graph().height * initialScale + 40)
svg.attr('width', "100%")
}
Error - Due to this below error newly loaded data not able to zoom
Error: <g> attribute transform: Expected number, "translate(NaN,20)
Have you tried removing the svg? After removing the svg you can add the new Graph.
I would like to prevent the pressing of ENTER if the kendo editor body has a certain height (to limit the max height of the editor field). But none of my tries worked.
<textarea data-role="editor"
data-bind="events: { keydown: onEditorKeyDown }">
</textarea>
viewModel.onEditorKeyDown = function (e) {
var key = e.keyCode;
if (key == 13) {
var editor = e.sender;
var body = editor.body;
var height = body.scrollHeight;
if (height > 195) {
?? //tried e.preventDefault(), return false etc.
}
}
};
I've managed to find two solutions. One is dirty hack and other doesn't match your requirements 100%. But both perform what is needed more or less.
New paragraph is added via embedded editor insertParagraph command which overrides default keydown logic. So the first solution is to temporary override this command using keydown and keyup events like this:
<textarea data-role="editor"
data-bind="events: { keydown: onEditorKeyDown, keyup: onEditorKeyUp }">
</textarea>
// this should probably be moved to viewModel, it's here for demo puproses only
var savedCommand;
var viewModel = kendo.observable({
html: null,
isVisible: true,
onChange: function() {
kendoConsole.log("event :: change (" + kendo.htmlEncode(this.get("html")) + ")");
}
});
viewModel.onEditorKeyDown = function (e) {
var key = e.keyCode;
if (key == 13) {
var editor = e.sender;
var body = editor.body;
var height = body.scrollHeight;
if (height > 195) {
savedCommand = editor.toolbar.tools.insertParagraph.command;
editor.toolbar.tools.insertParagraph.command = function() {};
}
}
};
viewModel.onEditorKeyUp = function (e) {
var key = e.keyCode;
if (key == 13) {
if (savedCommand) {
var editor = e.sender;
editor.toolbar.tools.insertParagraph.command = savedCommand;
savedCommand = undefined;
}
}
};
kendo.bind($("#example"), viewModel);
This works fine, but looks a bit ugly.
Other solution is to execute editor undo command if needed. It works too, but empty line always flickers for a moment:
<textarea data-role="editor"
data-bind="events: { keyup: onEditorKeyUp }"></textarea>
var viewModel = kendo.observable({
html: null,
isVisible: true,
onChange: function() {
kendoConsole.log("event :: change (" + kendo.htmlEncode(this.get("html")) + ")");
}
});
viewModel.onEditorKeyUp = function (e) {
var key = e.keyCode;
if (key == 13) {
var editor = e.sender;
var body = editor.body;
while (body.scrollHeight > 195) {
editor.exec('undo');
}
}
};
kendo.bind($("#example"), viewModel);
UPD: I've found event better solution. You can use execute event, see http://docs.telerik.com/kendo-ui/api/javascript/ui/editor#events-execute
Then check conditions and filter by command name to cancel insert of new paragraph:
execute: function(e) {
alert(e.name);
e.preventDefault();
}
I am developing an app where I use 2 API's a.k.a Instagram API and Google Map API. Using AJAX, I get the first set of Images filtered by a tag name. In the 1st set we receive 20 images. Among the received images, the images that have the latitude and longitude info (geotagged images) are displayed on the map.
Now the first time when my page loads, I cannot see the map. But when I press the load more button to get the next set of images, the Map works fine showing my previous images too.
Here is the code for what happens on page load:
$( window ).load(function() {
$.ajax({
type: "GET",
url: "https://api.instagram.com/v1/tags/nyc/media/recent?client_id=02e****",
dataType:'JSONP',
success: function(result) {
onAction(result, 2, tag);
instaMap(result, 2, from);
}
});
});
These are the functions being called:
/**
* [initialize description]
* Initialize the map with markers showing all photos that are geotagged.
*/
var initialize = function(markers) {
var bounds = new google.maps.LatLngBounds(),
mapOptions = {
scrollwheel: false,
mapTypeId: 'roadmap',
center: new google.maps.LatLng(22.50, 6.50),
minZoom: 2
},
gmarkers = [],
map,
positions,
markCluster;
markers = remDuplicate(markers);
// Info Window Content
var infoWindowContent = [];
for (var j = 0; j < markers.length; j++ ) {
var content = [
'<div class="info_content">' +
'<h3>' + markers[j][2] + '</h3>' +
'<a href="' + markers[j][3] + '" target="_blank">' +
'<img src="' + markers[j][4] + '" style="z-index:99999">' + '</a>' +
'</div>'
];
infoWindowContent.push(content);
}
// Display a map on the page
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setTilt(45);
// Display multiple markers on a map
var oms = new OverlappingMarkerSpiderfier(map);
var infoWindow = new google.maps.InfoWindow(), marker, i;
// Loop through our array of markers & place each one on the map
for( i = 0; i < markers.length; i++ ) {
positions = new google.maps.LatLng(markers[i][0], markers[i][1]);
marker = new google.maps.Marker({
position: positions,
map: map,
animation:google.maps.Animation.BOUNCE,
title: markers[i][2]
});
oms.addMarker(marker);
// Allow each marker to have an info window
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.close();
infoWindow.setContent(infoWindowContent[i][0]);
infoWindow.open(map, marker);
map.setCenter(marker.getPosition());
};
})(marker, i));
gmarkers.push(marker);
}
google.maps.event.addListener(map, 'click', function() {
infoWindow.setMap(null);
});
markCluster = new MarkerClusterer(map, gmarkers);
// Override our map zoom level once our fitBounds function runs (Make sure it only runs once)
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
map.setZoom(2);
google.maps.event.removeListener(boundsListener);
});
};
/**
* [onAction]
* OnAction() function helps in loading non-geotagged pics.
*
* #param {[type]} result [Result retruned from the Instagram API in json format]
* #param {[type]} likey [hearts the user has entered as per which the posts will be filtered]
*/
var onAction = function (result, likey, tag) {
$('.load-pics').remove();
if (result.pagination.next_url) {
paginate = removeURLParameter(result.pagination.next_url, 'count');
}
$.each(result, function(key, value) {
if (key === 'data') {
$.each(value, function(index, val) {
liked = val.likes.count;
link = val.link;
imgUrl = val.images.low_resolution.url;
locations = val.location;
if (liked >= likey) {
if (locations === null) {
output = '<li class="img-wrap">' + '<div class="main-img">' +
'<a href="' + link + '" target="_blank">' +
'<img src="' + imgUrl + '" ><span class="hover-lay"></span></a>' +'<p>' +
'<span class="heart"></span><span class="likes-no">' + liked + '</span>' +
'<span class="comment-box"></span><span class="comment-no">' +
val.comments.count + '</span> ' + '</p>' + '</div>' +
'<div class="img-bottom-part">'+ '' + '<div class="headin-hastag">' +
'by ' + '<h2>Sebastien Dekoninck</h2>#hello <span>#kanye</span> #helloagain #tagsgohere</div>'
+'</div></li>';
$('#instafeed').append(output);
}
}
});
}
});
if ($('#instafeed').children().length === 0) {
alert('There are no pics with ' + likey + ' likes or #' + tag + ' was not found.');
} else {
// $('.not-geo').remove();
// $('#instafeed').before('<button class="not-geo">Click To See Images That Are Not Geotagged <img src="assets/imgs/down.png" ></button>');
}
$('#instafeed').append('<div class="load-pics"><button id="show-more">Show more <span></span></button> </div>');
};
/**
* [instaMap]
* instaMap() will be the function which will deal with all map based functionalities.
*/
var instaMap = function(result, likey, from) {
$('.load-mark').remove();
if (result.pagination.next_url) {
pagiMap = removeURLParameter(result.pagination.next_url, 'count');
}
$.each(result, function(key, value) {
if (key === 'data') {
$.each(value, function(index, val) {
liked = val.likes.count;
link = val.link;
imgUrl = val.images.low_resolution.url;
locations = val.location;
if (liked >= likey) {
if (locations && locations.latitude !== null) {
tempArr = [
locations.latitude,
locations.longitude,
val.user.username,
val.link,
val.images.low_resolution.url
];
mark.push(tempArr);
}
}
});
}
});
if (mark.length) {
initialize(mark);
$('.map-parent-wrapper').append('<div class="load-mark"><button id="show-mark">See More </button></div>');
} else {
alert('No geotagged pics found in the retrieved set. Click see more');
$('.map-parent-wrapper').append('<div class="load-mark"><button id="show-mark">See More </button></div>');
}
};
I have created a See More button to retrieve the next set of images and load those on the Map. When clicking see more, everything seems to work fine. Not sure why it's happening so. Console.log does not show any error. Also, all the values I feed does flow appropriately. I even tried clearing cache. Not sure, why it's happening.
If instaMap is the function which is going to handle all your map based functionality, it has to be the one that loads map in your $( window ).load function ();
Otherwise, if you want Google maps to load on initial window load you need to put below in there:
google.maps.event.addDomListener(window, 'load', initialize);
I am try to get the values from the selected row and pass them through $.getJSON as parameters. I can get the value, however, when I click on the link strange characters appear before and after the value. The character in the link appears as %OA++++++++++value+++++++%0A.
Here is my code
var className='';
var Section='';
$('#listsubject tr').click(function () {
var th = $(this);
var td = $(this).find('td');
$.each(td, function (index, item) {
if (index == 2) className = item.innerHTML;
});
$.getJSON('#Url.Action("getStudentList/","Student")',
{ classname: className
}, function (data) {
alert('test');
});
Kindly help me. Am stuck here
Thanks in advance
EDIT
when i try the code
$.getJSON('#Url.Action("getStudentList/","Student")',
{ classname: className,
section:'A'
}, function (data) {
alert('test');
});
in the link the section part shows fine, only problem is with the classname
UPDATE
fiddle link
http://jsfiddle.net/gordon/vzTDc/2/
Try this. I think its OK now.
var className = '',
Section = '';
// you were trying with $('#listsubject tr'), but first tr has no td
// so click should bind with tr from 2nd
// so correct selector will be $('#listsubject tr:gt(0)')
$('#listsubject tr:gt(0)').click(function() {
var th = $(this);
var td = $(this).find('td');
$.each(td, function(index, item) {
// As you have 2 td with in each row, so the index will be 0 and 1
// not 2 and 3
if (index == 0) {
className = $.trim($(item).text()); // $.trim() will remove spaces
}
if (index == 1) {
Section = $.trim($(item).text());
}
});
console.log('ClassName: ' + className + ', Section: ' + Section);
$.getJSON('StudentMarks/getSubjectGrading', {
classname: className,
section: Section
}, function(data) {
alert(data);
});
});
DEMO
I'm using a ajax script to load content from other pages, without having to reload the browser.
For now I'm retrieving the content of the #inside div, but I'm using a full-background slideshow (#full) wich needs to be loaded as wel.
Maybe this can be achieved by loading the content of the #full div also, but I don't know how I could do that.
This is my code:
// Self-Executing Anonymous Function to avoid more globals
(function() {
// Home link isn't dynamic, so default set class name to it to match how dynamic classes work in WordPress
$(".home li.home").removeClass("home").addClass("current_page_item");
// Add spinner via JS, cuz would never need it otherweise
$("body").append("<img src='http://themeclubhouse.digwp.com/images/ajax-loader.gif' id='ajax-loader' />");
var
$mainContent = $("#wrapper"),
$ajaxSpinner = $("#ajax-loader"),
$searchInput = $("#s"),
$allLinks = $("a"),
$el;
// Auto-clear search field
$searchInput.focus(function() {
if ($(this).val() == "Search...") {
$(this).val("");
}
});
$('a:urlInternal').live('click', function(e) {
// Caching
$el = $(this);
if ((!$el.hasClass("comment-reply-link")) && ($el.attr("id") != 'cancel-comment-reply-link')) {
var path = $(this).attr('href').replace(base, '');
$.address.value(path);
$(".current_page_item").removeClass("current_page_item");
$allLinks.removeClass("current_link");
$el.addClass("current_link").parent().addClass("current_page_item");
return false;
}
// Default action (go to link) prevented for comment-related links (which use onclick attributes)
e.preventDefault();
});
// Fancy ALL AJAX Stuff
$.address.change(function(event) {
if (event.value) {
$ajaxSpinner.fadeIn();
$mainContent
.empty()
.load(base + event.value + ' #content', function() {
$ajaxSpinner.fadeOut();
$mainContent.fadeIn();
});
}
var current = location.protocol + '//' + location.hostname + location.pathname;
if (base + '/' != current) {
var diff = current.replace(base, '');
location = base + '/#' + diff;
}
});
})(); // End SEAF
try to repeat the procedure:
// Fancy ALL AJAX Stuff
$.address.change(function(event) {
if (event.value) {
//load ajax image
$ajaxSpinner.fadeIn();
$mainContent.empty().load(base + event.value + ' #content', function() {
$ajaxSpinner.fadeOut();
$mainContent.fadeIn();
});
// repeat here
//load another div
$mainContent.empty().load(base + event.value + ' #mydiv1', function() {
$mainContent
});
//load another div
$mainContent.empty().load(base + event.value + ' #mydiv2', function() {
$mainContent
});
}
let me know if it works, Ciao! :)