Unable to place div on other div - css

Let me explain what I'm trying to achieve. Currently, I have button and want to add image and add text. I have parent div container in which all child div adds dynamically.
Add image button adds img tag with image inside the parent div and add text button adds div containing text inside parent by using append method.
But what I want that when ever I create them, they should place in a specific position which will be common to all. Lets take center of the parent so when ever I add image or text it should create at the center of the parent
Code for adding dynamic image
$(document).ready(function () {
$('#addImage').click(function () {
var url = 'Default.aspx';
var dialog = $('<iframe"></iframe>').appendTo('body');
dialog.load(url).dialog('open').dialog({ modal: true, width: 480,resizable: false ,open: function (type, data) { $(this).parent().appendTo("form"); },
buttons: {
'OK': function() {
var img = document.createElement('img');
$(img).attr("id", "dyndiv" + count);
$(img).attr("width", 60);
$(img).attr("height", 140);
$(img).attr("src", 'Uploads/'+ $get('dvFileName').innerHTML) ;
var $ctrl = $(img).addClass("draggable ui-widget-content").draggable({ containment: '#containment-wrapper', cursor: 'move', snap: '#containment-wrapper' });
objid = "dyndiv" + count ;
count++;
$("#containment-wrapper").append($ctrl);
$(this).dialog('destroy');
},
'Cancel': function() {
$(this).dialog('destroy');
// I'm sorry, I changed my mind
}
}
});
return false;
});
});

At last i got the solution. In the above question I am appending the div, now i am also explicitly defining the position of the div after the append statement above.

Related

$timeout in a directive link function

So I'm using this directive to collapse a variable height card in Ionic. The directive grabs the auto height and changes it to a defined height so it can then be collapsed to 0 with a css animation. It was working fine for my needs, but now I need to use ng-src to dynamically load an image within the card. What's happening is the image is being loaded after the directive, so the image loads and overflows the card.
Directive:
.directive('collapse', ['$timeout', function ($timeout) {
return {
restrict: 'A',
link: function ($scope, ngElement, attributes) {
var element = ngElement[0];
$timeout(function(){
$scope.$watch(attributes.collapse, function (collapse) {
var newHeight = collapse ? 0 : getElementAutoHeight();
element.style.height = newHeight +"px";
ngElement.toggleClass('collapsed', collapse);
});
function getElementAutoHeight() {
var currentHeight = getElementCurrentHeight();
element.style.height = 'auto';
var autoHeight = getElementCurrentHeight();
element.style.height = currentHeight +"px";
getElementCurrentHeight(); // Force the browser to recalc height after moving it back to normal
return autoHeight;
}
function getElementCurrentHeight() {
return element.offsetHeight
}
});
}
};
}])
and HTML:
<div ng-repeat="item in items | orderBy : '-'" collapse="item.deleted">
<div class="list card">
<img class="full-image" ng-src="{{item.image}}"/>
</div>
</div>
As you can see I've injected $timeout and leaving the interval blank in hopes it will wait until the DOM is loaded, but it seems no matter how I use it, the directive still explicitly sets the height of the element in css before the image child element is rendered. How can I delay the setting of element height until after ng-src is loaded in each ng-repeat item?
First thing, angular $timeout without an $interval will not wait for the DOM tree to load, basically, what it does is waiting for the current digest cycle to finish before executing the function in the first parameter. By doing so, it will allow the your code to wait till the directive finish compile and render before calculating the height of the div.
However, there is no guarantee that the image will be loaded by that time. Images are loaded by the browser independently from DOM rendering, therefore, to calculate the height of the container having images precisely, you should make use of JS Image Object and the load event. Once the images are fully loaded, then you can update the height.
Also, for your directive, I don't think you need to calculate the height every times the collapse variable changed (inside the watch), you can simply wait till the image being loaded, calculate the height once, store it inside the scope object, and reuse it whenever the collapse variable change.
Okay, so thanks to Thai's input, I have a working solution:
.directive('collapse', [function () {
return {
restrict: 'A',
link: function ($scope, ngElement, attributes) {
var element = ngElement[0];
var img = element.querySelector('.full-image');
angular.element(img).bind('load', function() {
var autoHeight = getElementAutoHeight();
element.style.height = autoHeight + "px";
});
$scope.$watch(attributes.collapse, function (collapse) {
var newHeight = collapse ? 0 : getElementAutoHeight();
element.style.height = newHeight +"px";
ngElement.toggleClass('collapsed', collapse);
});
function getElementAutoHeight() {
var currentHeight = getElementCurrentHeight();
element.style.height = 'auto';
var autoHeight = getElementCurrentHeight();
element.style.height = currentHeight +"px";
getElementCurrentHeight(); // Force the browser to recalc height after moving it back to normal
return autoHeight;
}
function getElementCurrentHeight() {
return element.offsetHeight
}
}
};
}])

Nested Bootstrap Tooltip divs Toggles Parent div's Tooltip

I have 2 nested <div>s, both with tooltip().
When I hover over the
inner <div>, the outer <div> also shows it's tooltip.
I tried to work around this by setting the inner <div>'s title
to an empty string on :hover.
$(inner).hover({
$(outer).attr('title','');
},{
$(outer).attr('title','original title');
});
I created a codepen examplenote: I changed title to 'red' so you can see that the title did indeed change.
Why is it that changing the title doesn't change tooltip's content?
How do we change the Bootstrap Tooltip's content? (this should be a stackoverflow question of it's own)
Answering #1:
By inspecting the elements and watching it change with your JS code, i noticed a attribute on the divs called data-original-title which still holds "blue" when you enter green (this is what the tooltip element reads and displays). By changing your script to
$('#a').attr({"data-original-title": "red"});
the blue becomes red. Does this answer your question?
Use .tooltip('hide') and .tooltip('show')
this was answered in part by #BuddhistBeast, thanks!
$("#b").on('mouseover', function(){
$('#a').tooltip('hide');
}).on('mouseleave', function(){
$('#a').tooltip('show');
});
$('[data-toggle="tooltip"]').tooltip({
animated : 'true',
placement : 'bottom',
container: 'body'});
You can check whether you are currently hovering inside of the inner block
jQuery:
$(document).ready(function(){
var bIsShown = true;
$("#b").on('mouseenter', function(){
bIsShown = true;
}).on('mouseleave', function() {
bIsShown = false;
})
$("#a").on('mousemove', function(){
if(bIsShown) {
$(this).data("bs.tooltip").$tip.removeClass("in");
}
else {
$(this).data("bs.tooltip").$tip.addClass("in");
}
})
$('[data-toggle="tooltip"]').tooltip({
animated : 'fade',
placement : 'bottom',
container: 'body'});
});
Your Example: http://codepen.io/anon/pen/JGqXPw

What element is jQuery UI draggable being dragged over in an iframe

Here is my code, where I'm trying to detect the element, which a jQuery UI draggable is hovering over. I need to get the element's object and attributes, such as class names (in this case .sortable-grid,.sortable-table,.sortable-row,.sortable-cell).
The answers found here only show how to get the draggable item itself (ui.helper or event.target), but not the element it is hovering above.
The best way to answer would be using the prepared JSFiddle, since my code uses an iframe, which would not work if the full code is posted here:
JSFiddle
HTML:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0-beta.1/jquery-ui.js"></script>
<div style="background-color:grey;display:inline;cursor:move" id="draggable">DRAG ME</div>
<iframe src="https://fiddle.jshell.net/piglin/UAcC7/1869/show/" id="frame" style="width:100%;overflow:visible" seamless="seamless" scrolling="no"></iframe>
JS:
$("#draggable").draggable({
drag: function(event, ui) {
//Some code here
}
}
It was possible by modifying the function from another answer to fit this purpose. After adapting it to use the contentWindow of the iframe and adding offset calculation it works now.
Solution
function allElementsFromPointIframe(x, y, offsetX, offsetY) {
var element, elements = [];
var old_visibility = [];
while (true) {
element = document.getElementById('frame').contentWindow.document.elementFromPoint(x - offsetX, y - offsetY);
if (!element || element === document.getElementById('frame').contentWindow.document.documentElement) {
break;
}
elements.push(element);
old_visibility.push(element.style.visibility);
element.style.visibility = 'hidden'; // Temporarily hide the element (without changing the layout)
}
for (var k = 0; k < elements.length; k++) {
elements[k].style.visibility = old_visibility[k];
}
elements.reverse();
return elements;
}
var selected = $('');
var tmpColor = 'transparent';
$("#draggable").draggable({
drag: function(event, ui) {
var el = $(allElementsFromPointIframe(event.pageX, event.pageY, $(frame).offset().left, $(frame).offset().top));
var div = $(el).filter('ul, li').not($(this));
selected.css({'backgroundColor': tmpColor});
selected = div.last()
tmpColor = selected.css('backgroundColor');
selected.css({'backgroundColor': 'red'});
console.dir(div);
},
iframeFix: true,
iframeOffset: $('#iframe').offset()
});

Angular nested directive ordering

i am having a hard time finding any information on the ordering of directives and their updating of css properties.
for example, i have two directives, one to set an element to full screen height, and one to align content vertically.
app.directive('fullscreenElement', function() {
return {
restrict: "A",
link: function(scope,element,attrs){
$(element).each(function(){
$(this).css('height', $(window).height());
});
}
};
});
app.directive('alignVertical', function() {
return {
restrict: "A",
link: function(scope,element,attrs){
var height = $(element).height();
var parentHeight = $(element).parent().height();
var padAmount = (parentHeight / 2) - (height / 2);
$(element).css('padding-top', padAmount);
}
};
});
They both work independantly, the trouble is when they are nested, the align-vertical directive doesnt work, im assuming this is because the css height hasn't been set yet? how do i make sure it is set before the alignVertical directive runs? any tips for writing these two directives in a more angular way would be appreciated.
this works:
<header style="height:800px">
<div align-vertical>
this content is centered vertically as expected
</div>
</header>
this doesn't work (content doesnt center vertically, even though header height is now fullscreen):
<header fullscreen-element>
<div align-vertical>
the header element is now fullscreen height but this content is *not* centered vertically
</div>
</header>
thanks
Figured out a solution, posting it here in case anyone finds it helpful.
The trick is to use scope.watch and scope.evalAsync to monitor changes of height to the parent container and run them after rendering is complete.
app.directive('alignVertical', function() {
return {
link: function($scope, element, attrs) {
// Trigger when parent element height changes changes
var watch = $scope.$watch(function() {
return element.parent().height;
}, function() {
// wait for templates to render
$scope.$evalAsync(function() {
// directive runs here after render.
var that = $(element);
var height = that.height();
var parentHeight = that.parent().height();
var padAmount = (parentHeight / 2) - (height / 2);
that.css('padding-top', padAmount);
});
});
},
};
});

customize shape of kendo tooltip

I would like to customize the shape of Kendo Tooltips for a grid.
I saw the example on kendo site, it has the arrow outside the box, and the box has a nice rounded shape.
Working on css, using .k-tooltip I can change width, height, background. But I get a square box with the arrow inside which sometimes overrides part of the text content.
I thought that callout would help but I was not able to get anything.
How can I change shape, image and position of the arrows, shape of the box ?
Moreover, how can I trigger the tooltip only when part of the text in a grid cell is visible ?
Thanks a lot for any hint
regards
Marco
I think "arrow" you mean callout. You can turn off callout by:
$(document).ready(function() {
$("#target").kendoTooltip({
callout: false
});
});
About your question "Moreover, how can I trigger the tooltip only when part of the text in a grid cell is visible?"
If I understand you correctly you would like to show tooltip only when there is text with ellipsis (partially visible in the cell), but you don't want to show a tooltip if there is a full text is visible or if there is no text in the cell. If that is the case, you can do this way:
function initializeTooltip(element, filter) {
return element.kendoTooltip({
autoHide: true,
filter: filter,
callout: false,
content: function (e) {
var target = e.target,
tooltip = e.sender,
tooltipText = "";
if (isEllipsisActive(target[0])) {
tooltipText = $(target).text();
}
tooltip.popup.unbind("open");
tooltip.popup.bind("open", function (arg) {
tooltip.refreshTooltip = false;
if (!isEllipsisActive(target[0])) {
arg.preventDefault();
} else if (tooltipText !== $(target).text()) {
tooltip.refreshTooltip = true;
}
});
return tooltipText;
},
show: function () {
if (this.refreshTooltip) {
this.refresh();
}
}
}).data("kendoTooltip");
};
// determanes if text has ellipsis
function isEllipsisActive(e) {
return e.offsetWidth < e.scrollWidth;
}
$(function () {
initializeTooltip($("#yourGridId"), ".tooltip");
});
tooltip in this case is class name of the column that you would like to use tooltip for, but you can call that class anyway you wish. In case if you are using Kendo ASP.NET MVC it will look something like this
c.Bound(p => p.ClientName)
.Title("Client")
.HtmlAttributes(new {#class = "tooltip"});

Resources