kendo ui resize column - javascript

I am using the following function(which i got from web) to resize the column in kendo ui.
this is based on Index, i am looking out to see if there can be an option to select by column title or field/key.
when i reorder the grid column, this function fails.
function resizeColumn(idx, width) {
$("#grid .k-grid-header-wrap") //header
.find("colgroup col")
.eq(idx)
.css({ width: width });
$("#grid .k-grid-content") //content
.find("colgroup col")
.eq(idx)
.css({ width: width });
}

To resize by column title, you just need to figure out the correct index, e.g. like this:
function resizeColumn(title, width) {
var index = $("#grid .k-grid-header-wrap").find("th:contains(" + title + ")").index();
$("#grid .k-grid-header-wrap") //header
.find("colgroup col")
.eq(index)
.css({ width: width });
$("#grid .k-grid-content") //content
.find("colgroup col")
.eq(index)
.css({ width: width });
}

Search column by field id to make sure that is the corrected field.
function resizeColumn(fieldId, width) {
var index = $('#grid .k-grid-header-wrap').find('th[data-field="' + fieldId + '"]').index();
$("#grid .k-grid-header-wrap") //header
.find("colgroup col")
.eq(index)
.css({ width: width });
$("#grid .k-grid-content") //content
.find("colgroup col")
.eq(index)
.css({ width: width });
}

click here to get complete Answer
Loading Column State
function loadColumnState(columnStateKey: string, realGrid): void
{
var colState = JSON.parse($.jStorage.get(columnStateKey));
if(colState && colState.length > 0)
{
var visibleIndex = -1;
for (var i = 0; i < colState.length; i++)
{
var column = colState[i];
// 1. Set correct order first as visibility and width both depend on this.
var existingIndex = -1;
if (typeof column.field !== 'undefined')
{
existingIndex = findFieldIndex(realGrid, column.field);
}
else if (typeof column.commandName !== 'undefined')
{
existingIndex = findCommandIndex(realGrid, column.commandName);
}
if (existingIndex > -1 && existingIndex != i) // Different index
{ // Need to reorder
realGrid.reorderColumn(i, realGrid.columns[existingIndex]);
}
// 2. Set visibility state
var isHidden = (typeof column.hidden === 'undefined') ? false : column.hidden;
if (isHidden)
{
realGrid.hideColumn(i);
}
else
{
realGrid.showColumn(i);
++visibleIndex;
}
// 3. Set width
var width = (typeof column.width === 'undefined') ? null : column.width;
if(width != null)
{
realGrid.columns[i].width = width; // This sets value, whilst rest redraws
realGrid.thead.prev().find('col:eq(' + visibleIndex + ')').width(width);
realGrid.table.find('>colgroup col:eq(' + visibleIndex + ')').width(width);
}
}
}
}

Related

Adding translate class to mobile navigation

I am new to javascript and I don't quite know where I should be adding in my class that allows for the website to be translated.
I have a mobile nav that appears when the screen width is X small and in that nav I have numerous directional buttons that lead to other parts of the website, BUT two buttons (The english and Chinese translation buttons) don't work when being pressed.
I assume this is because I have not added the 'lang' class in my 'is-mobile' class but I am unaware of how to do this.
Here is my code
(function($) {
var $window = $(window),
$body = $('body'),
$header = $('#header'),
$banner = $('#banner'),
settings = {
banner: {
// Indicators (= the clickable dots at the bottom).
indicators: true,
// Transition speed (in ms)
// For timing purposes only. It *must* match the transition speed of "#banner > article".
speed: 1500,
// Transition delay (in ms)
delay: 5000,
// Parallax intensity (between 0 and 1; higher = more intense, lower = less intense; 0 = off)
parallax: 0.25
}
};
/**
* Applies parallax scrolling to an element's background image.
* #return {jQuery} jQuery object.
*/
$.fn._parallax = (browser.name == 'ie' || browser.name == 'edge' || browser.mobile) ? function() {
return $(this)
} : function(intensity) {
var $window = $(window),
$this = $(this);
if (this.length == 0 || intensity === 0)
return $this;
if (this.length > 1) {
for (var i = 0; i < this.length; i++)
$(this[i])._parallax(intensity);
return $this;
}
if (!intensity)
intensity = 0.25;
$this.each(function() {
var $t = $(this),
on, off;
on = function() {
$t.css('background-position', 'center 100%, center 100%, center 0px');
$window
.on('scroll._parallax', function() {
var pos = parseInt($window.scrollTop()) - parseInt($t.position().top);
$t.css('background-position', 'center ' + (pos * (-1 * intensity)) + 'px');
});
};
off = function() {
$t
.css('background-position', '');
$window
.off('scroll._parallax');
};
breakpoints.on('<=medium', off);
breakpoints.on('>medium', on);
});
$window
.off('load._parallax resize._parallax')
.on('load._parallax resize._parallax', function() {
$window.trigger('scroll');
});
return $(this);
};
/**
* #return {jQuery} jQuery object.
*/
$.fn._slider = function(options) {
var $window = $(window),
$this = $(this);
if (this.length == 0)
return $this;
if (this.length > 1) {
for (var i = 0; i < this.length; i++)
$(this[i])._slider(options);
return $this;
}
// Vars.
var current = 0,
pos = 0,
lastPos = 0,
slides = [],
indicators = [],
$indicators,
$slides = $this.children('article'),
intervalId,
isLocked = false,
i = 0;
// Turn off indicators if we only have one slide.
if ($slides.length == 1)
options.indicators = false;
// Functions.
$this._switchTo = function(x, stop) {
if (isLocked || pos == x)
return;
isLocked = true;
if (stop)
window.clearInterval(intervalId);
// Update positions.
lastPos = pos;
pos = x;
// Hide last slide.
slides[lastPos].removeClass('top');
if (options.indicators)
indicators[lastPos].removeClass('visible');
// Show new slide.
slides[pos].addClass('visible').addClass('top');
if (options.indicators)
indicators[pos].addClass('visible');
// Finish hiding last slide after a short delay.
window.setTimeout(function() {
slides[lastPos].addClass('instant').removeClass('visible');
window.setTimeout(function() {
slides[lastPos].removeClass('instant');
isLocked = false;
}, 100);
}, options.speed);
};
// Indicators.
if (options.indicators)
$indicators = $('<ul class="indicators"></ul>').appendTo($this);
// Slides.
$slides
.each(function() {
var $slide = $(this),
$img = $slide.find('img');
// Slide.
$slide
.css('background-image', 'url("' + $img.attr('src') + '")')
.css('background-position', ($slide.data('position') ? $slide.data('position') : 'center'));
// Add to slides.
slides.push($slide);
// Indicators.
if (options.indicators) {
var $indicator_li = $('<li>' + i + '</li>').appendTo($indicators);
// Indicator.
$indicator_li
.data('index', i)
.on('click', function() {
$this._switchTo($(this).data('index'), true);
});
// Add to indicators.
indicators.push($indicator_li);
}
i++;
})
._parallax(options.parallax);
// Initial slide.
slides[pos].addClass('visible').addClass('top');
if (options.indicators)
indicators[pos].addClass('visible');
// Bail if we only have a single slide.
if (slides.length == 1)
return;
// Main loop.
intervalId = window.setInterval(function() {
current++;
if (current >= slides.length)
current = 0;
$this._switchTo(current);
}, options.delay);
};
// Breakpoints.
breakpoints({
xlarge: ['1281px', '1680px'],
large: ['981px', '1280px'],
medium: ['737px', '980px'],
small: ['481px', '736px'],
xsmall: [null, '480px']
});
// Play initial animations on page load.
$window.on('load', function() {
window.setTimeout(function() {
$body.removeClass('is-preload');
}, 100);
});
// Mobile?
if (browser.mobile)
$body.addClass('is-mobile', 'tr');
else {
breakpoints.on('>medium', function() {
$body.removeClass('is-mobile');
});
breakpoints.on('<=medium', function() {
$body.addClass('is-mobile');
});
}
// Dropdowns.
$('#nav > ul').dropotron({
alignment: 'center',
hideDelay: 400
});
// Header.
if ($banner.length > 0 &&
$header.hasClass('alt')) {
$window.on('resize', function() {
$window.trigger('scroll');
});
$banner.scrollex({
bottom: $header.outerHeight(),
terminate: function() {
$header.removeClass('alt');
},
enter: function() {
$header.addClass('alt');
},
leave: function() {
$header.removeClass('alt');
$header.addClass('reveal');
}
});
}
// Banner.
$banner._slider(settings.banner);
// Off-Canvas Navigation.
// Navigation Panel Toggle.
$('')
.appendTo($header);
// Navigation Panel.
$(
'<div id="navPanel">' +
'<nav>' +
$('#nav').navList() +
'</nav>' +
'' +
'</div>'
)
.appendTo($body)
.panel({
delay: 500,
hideOnClick: true,
hideOnSwipe: true,
resetScroll: true,
resetForms: true,
side: 'right'
});
// onclick behavior
$('.lang').click('touchstart', function() {
var lang = $(this).attr('id'); // obtain language id
// translate all translatable elements
$('.tr').each(function(i) {
$(this).text(aLangKeys[lang][$(this).attr('key')]);
});
});
document.getElementById('ch').onclick = function() {
var lang = $(this).attr('id'); // obtain language id
// translate all translatable elements
$('.tr').each(function(i) {
$(this).text(aLangKeys[lang][$(this).attr('key')]);
});
}
// preparing language file
var aLangKeys = new Array();
aLangKeys['en'] = new Array();
aLangKeys['ch'] = new Array();
aLangKeys['en']['home'] = 'Home';
aLangKeys['en']['about'] = 'About Us';
aLangKeys['en']['serv'] = 'Services';
aLangKeys['en']['sem'] = 'Search Engine Marketing';
aLangKeys['en']['webdev'] = 'Website Development';
aLangKeys['en']['app'] = 'Mobile App Development';
aLangKeys['en']['tbd'] = 'Technical Business Development';
aLangKeys['en']['ourteam'] = 'Our Team';
aLangKeys['en']['contactus'] = 'Contact Us';
aLangKeys['en']['submit'] = 'Send Message';
aLangKeys['en']['reset'] = 'Reset';
aLangKeys['ch']['home'] = '首页';
aLangKeys['ch']['about'] = '关于我们';
aLangKeys['ch']['serv'] = '服务';
aLangKeys['ch']['sem'] = '谷歌与雅虎推广';
aLangKeys['ch']['webdev'] = '品牌网站建设';
aLangKeys['ch']['app'] = 'APP 开发';
aLangKeys['ch']['tbd'] = '加拿大工商业与市场拓展';
aLangKeys['ch']['ourteam'] = '我们的团队';
aLangKeys['ch']['contactus'] = '联络我们';
aLangKeys['ch']['submit'] = '发留言';
aLangKeys['ch']['reset'] = '重新';
})(jQuery);
<!-- Header -->
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<header id="header" class="alt">
<h1>
<img src="images/Artboard%201.png" alt="logo" class="logo">
</h1>
<nav id="nav">
<ul class="translate">
<li>Home</li>
<li>About Us</li>
<li>
Services
<ul>
<li>Search Engine Marketing</li>
<li>Website Development </li>
<li>App Development</li>
<li>Technical Business Development</li>
</ul>
</li>
<li>Our Team</li>
<li>English</li>
<li>中文</li>
<li>Contact Us</li>
</ul>
</nav>
</header>
<!-- begin snippet: js hide: false console: true babel: false -->
Here is the other part of JS code:
(function($) {
/**
* Generate an indented list of links from a nav. Meant for use with panel().
* #return {jQuery} jQuery object.
*/
$.fn.navList = function() {
var $this = $(this);
$a = $this.find('a'),
b = [];
$a.each(function() {
var $this = $(this),
indent = Math.max(0, $this.parents('li').length - 1),
href = $this.attr('href'),
target = $this.attr('target');
b.push(
'<a ' +
'class="link depth-' + indent + '"' +
((typeof target !== 'undefined' && target != '') ? ' target="' + target + '"' : '') +
((typeof href !== 'undefined' && href != '') ? ' href="' + href + '"' : '') +
'>' +
'<span class="indent-' + indent + '"></span>' +
$this.text() +
'</a>'
);
});
return b.join('');
};
/**
* Panel-ify an element.
* #param {object} userConfig User config.
* #return {jQuery} jQuery object.
*/
$.fn.panel = function(userConfig) {
// No elements?
if (this.length == 0)
return $this;
// Multiple elements?
if (this.length > 1) {
for (var i = 0; i < this.length; i++)
$(this[i]).panel(userConfig);
return $this;
}
// Vars.
var $this = $(this),
$body = $('body'),
$window = $(window),
id = $this.attr('id'),
config;
// Config.
config = $.extend({
// Delay.
delay: 0,
// Hide panel on link click.
hideOnClick: false,
// Hide panel on escape keypress.
hideOnEscape: false,
// Hide panel on swipe.
hideOnSwipe: false,
// Reset scroll position on hide.
resetScroll: false,
// Reset forms on hide.
resetForms: false,
// Side of viewport the panel will appear.
side: null,
// Target element for "class".
target: $this,
// Class to toggle.
visibleClass: 'visible'
}, userConfig);
// Expand "target" if it's not a jQuery object already.
if (typeof config.target != 'jQuery')
config.target = $(config.target);
// Panel.
// Methods.
$this._hide = function(event) {
// Already hidden? Bail.
if (!config.target.hasClass(config.visibleClass))
return;
// If an event was provided, cancel it.
if (event) {
event.preventDefault();
event.stopPropagation();
}
// Hide.
config.target.removeClass(config.visibleClass);
// Post-hide stuff.
window.setTimeout(function() {
// Reset scroll position.
if (config.resetScroll)
$this.scrollTop(0);
// Reset forms.
if (config.resetForms)
$this.find('form').each(function() {
this.reset();
});
}, config.delay);
};
// Vendor fixes.
$this
.css('-ms-overflow-style', '-ms-autohiding-scrollbar')
.css('-webkit-overflow-scrolling', 'touch');
// Hide on click.
if (config.hideOnClick) {
$this.find('a')
.css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');
$this
.on('click', 'a', function(event) {
var $a = $(this),
href = $a.attr('href'),
target = $a.attr('target');
if (!href || href == '#' || href == '' || href == '#' + id)
return;
// Cancel original event.
event.preventDefault();
event.stopPropagation();
// Hide panel.
$this._hide();
// Redirect to href.
window.setTimeout(function() {
if (target == '_blank')
window.open(href);
else
window.location.href = href;
}, config.delay + 10);
});
}
// Event: Touch stuff.
$this.on('touchstart', function(event) {
$this.touchPosX = event.originalEvent.touches[0].pageX;
$this.touchPosY = event.originalEvent.touches[0].pageY;
})
$this.on('touchmove', function(event) {
if ($this.touchPosX === null ||
$this.touchPosY === null)
return;
var diffX = $this.touchPosX - event.originalEvent.touches[0].pageX,
diffY = $this.touchPosY - event.originalEvent.touches[0].pageY,
th = $this.outerHeight(),
ts = ($this.get(0).scrollHeight - $this.scrollTop());
// Hide on swipe?
if (config.hideOnSwipe) {
var result = false,
boundary = 20,
delta = 50;
switch (config.side) {
case 'left':
result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta);
break;
case 'right':
result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta));
break;
case 'top':
result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta);
break;
case 'bottom':
result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta));
break;
default:
break;
}
if (result) {
$this.touchPosX = null;
$this.touchPosY = null;
$this._hide();
return false;
}
}
// Prevent vertical scrolling past the top or bottom.
if (($this.scrollTop() < 0 && diffY < 0) ||
(ts > (th - 2) && ts < (th + 2) && diffY > 0)) {
event.preventDefault();
event.stopPropagation();
}
});
// Event: Prevent certain events inside the panel from bubbling.
$this.on('click touchend touchstart touchmove', function(event) {
event.stopPropagation();
});
// Event: Hide panel if a child anchor tag pointing to its ID is clicked.
$this.on('click', 'a[href="#' + id + '"]', function(event) {
event.preventDefault();
event.stopPropagation();
config.target.removeClass(config.visibleClass);
});
// Body.
// Event: Hide panel on body click/tap.
$body.on('click touchend', function(event) {
$this._hide(event);
});
// Event: Toggle.
$body.on('click', 'a[href="#' + id + '"]', function(event) {
event.preventDefault();
event.stopPropagation();
config.target.toggleClass(config.visibleClass);
});
// Window.
// Event: Hide on ESC.
if (config.hideOnEscape)
$window.on('keydown', function(event) {
if (event.keyCode == 27)
$this._hide(event);
});
return $this;
};
/**
* Apply "placeholder" attribute polyfill to one or more forms.
* #return {jQuery} jQuery object.
*/
$.fn.placeholder = function() {
// Browser natively supports placeholders? Bail.
if (typeof(document.createElement('input')).placeholder != 'undefined')
return $(this);
// No elements?
if (this.length == 0)
return $this;
// Multiple elements?
if (this.length > 1) {
for (var i = 0; i < this.length; i++)
$(this[i]).placeholder();
return $this;
}
// Vars.
var $this = $(this);
// Text, TextArea.
$this.find('input[type=text],textarea')
.each(function() {
var i = $(this);
if (i.val() == '' ||
i.val() == i.attr('placeholder'))
i
.addClass('polyfill-placeholder')
.val(i.attr('placeholder'));
})
.on('blur', function() {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
return;
if (i.val() == '')
i
.addClass('polyfill-placeholder')
.val(i.attr('placeholder'));
})
.on('focus', function() {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
return;
if (i.val() == i.attr('placeholder'))
i
.removeClass('polyfill-placeholder')
.val('');
});
// Password.
$this.find('input[type=password]')
.each(function() {
var i = $(this);
var x = $(
$('<div>')
.append(i.clone())
.remove()
.html()
.replace(/type="password"/i, 'type="text"')
.replace(/type=password/i, 'type=text')
);
if (i.attr('id') != '')
x.attr('id', i.attr('id') + '-polyfill-field');
if (i.attr('name') != '')
x.attr('name', i.attr('name') + '-polyfill-field');
x.addClass('polyfill-placeholder')
.val(x.attr('placeholder')).insertAfter(i);
if (i.val() == '')
i.hide();
else
x.hide();
i
.on('blur', function(event) {
event.preventDefault();
var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
if (i.val() == '') {
i.hide();
x.show();
}
});
x
.on('focus', function(event) {
event.preventDefault();
var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']');
x.hide();
i
.show()
.focus();
})
.on('keypress', function(event) {
event.preventDefault();
x.val('');
});
});
// Events.
$this
.on('submit', function() {
$this.find('input[type=text],input[type=password],textarea')
.each(function(event) {
var i = $(this);
if (i.attr('name').match(/-polyfill-field$/))
i.attr('name', '');
if (i.val() == i.attr('placeholder')) {
i.removeClass('polyfill-placeholder');
i.val('');
}
});
})
.on('reset', function(event) {
event.preventDefault();
$this.find('select')
.val($('option:first').val());
$this.find('input,textarea')
.each(function() {
var i = $(this),
x;
i.removeClass('polyfill-placeholder');
switch (this.type) {
case 'submit':
case 'reset':
break;
case 'password':
i.val(i.attr('defaultValue'));
x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
if (i.val() == '') {
i.hide();
x.show();
} else {
i.show();
x.hide();
}
break;
case 'checkbox':
case 'radio':
i.attr('checked', i.attr('defaultValue'));
break;
case 'text':
case 'textarea':
i.val(i.attr('defaultValue'));
if (i.val() == '') {
i.addClass('polyfill-placeholder');
i.val(i.attr('placeholder'));
}
break;
default:
i.val(i.attr('defaultValue'));
break;
}
});
});
return $this;
};
/**
* Moves elements to/from the first positions of their respective parents.
* #param {jQuery} $elements Elements (or selector) to move.
* #param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations.
*/
$.prioritize = function($elements, condition) {
var key = '__prioritize';
// Expand $elements if it's not already a jQuery object.
if (typeof $elements != 'jQuery')
$elements = $($elements);
// Step through elements.
$elements.each(function() {
var $e = $(this),
$p,
$parent = $e.parent();
// No parent? Bail.
if ($parent.length == 0)
return;
// Not moved? Move it.
if (!$e.data(key)) {
// Condition is false? Bail.
if (!condition)
return;
// Get placeholder (which will serve as our point of reference for when this element needs to move back).
$p = $e.prev();
// Couldn't find anything? Means this element's already at the top, so bail.
if ($p.length == 0)
return;
// Move element to top of parent.
$e.prependTo($parent);
// Mark element as moved.
$e.data(key, $p);
}
// Moved already?
else {
// Condition is true? Bail.
if (condition)
return;
$p = $e.data(key);
// Move element back to its original location (using our placeholder).
$e.insertAfter($p);
// Unmark element as moved.
$e.removeData(key);
}
});
};
})(jQuery);
Here is the code snippet of my dropotron jquery file I have been using for the menu drop down if needed.
Where would I go to insert my lang class so that when it is in mobile nav the class is recognized? Thank you!
I figured it out!
I needed to add the class 'tr' into:
'class="tr link depth-' + indent + '"' +
Just forgot that little thing...

How to autogrow a textbox that has a variable font size

I am coding a website that lets you test typefaces and just like google fonts, the textarea in which you type should autogrow, when the user types in more text.
I tried this plugin by jaz303 and it works fine, if the font-size stays the same.
https://github.com/jaz303/jquery-grab-bag/blob/master/javascripts/jquery.autogrow-textarea.js
(function($) {
/**
* Auto-growing textareas; technique ripped from Facebook
*
*
* http://github.com/jaz303/jquery-grab-bag/tree/master/javascripts/jquery.autogrow-textarea.js
*/
$.fn.autogrow = function(options) {
return this.filter('textarea').each(function() {
var self = this;
var $self = $(self);
var minHeight = $self.height();
var noFlickerPad = $self.hasClass('autogrow-short') ? 0 : parseInt($self.css('lineHeight')) || 0;
var settings = $.extend({
preGrowCallback: null,
postGrowCallback: null
}, options);
var shadow = $('<div></div>').css({
position: 'absolute',
top: -10000,
left: -10000,
width: $self.width(),
fontSize: $self.css('fontSize'),
fontFamily: $self.css('fontFamily'),
fontWeight: $self.css('fontWeight'),
lineHeight: $self.css('lineHeight'),
resize: 'none',
'word-wrap': 'break-word'
}).appendTo(document.body);
var update = function(event) {
var times = function(string, number) {
for (var i = 0, r = ''; i < number; i++) r += string;
return r;
};
var val = self.value.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/\n$/, '<br/> ')
.replace(/\n/g, '<br/>')
.replace(/ {2,}/g, function(space) {
return times(' ', space.length - 1) + ' '
});
// Did enter get pressed? Resize in this keydown event so that the flicker doesn't occur.
if (event && event.data && event.data.event === 'keydown' && event.keyCode === 13) {
val += '<br />';
}
shadow.css('width', $self.width());
shadow.html(val + (noFlickerPad === 0 ? '...' : '')); // Append '...' to resize pre-emptively.
var newHeight = Math.max(shadow.height() + noFlickerPad, minHeight);
if (settings.preGrowCallback != null) {
newHeight = settings.preGrowCallback($self, shadow, newHeight, minHeight);
}
$self.height(newHeight);
if (settings.postGrowCallback != null) {
settings.postGrowCallback($self);
}
}
$self.change(update).keyup(update).keydown({
event: 'keydown'
}, update);
$(window).resize(update);
update();
});
};
However, I need the possibility for the user to change the font-size while testing and for some reason the autogrow doesn’t work anymore, as soon as I change the size.
Here is my Test jsFiddle:
http://jsfiddle.net/fquk6v3o/2/
The solution is to relaunch $("#autoGrowTextArea").autogrow(); when the slider value changes...
Sample code for doing this :
$("input[type='range']").change( function() {
$("#autoGrowTextArea").height("100px");
$("#autoGrowTextArea").autogrow();
});
New JSfiddle here : http://jsfiddle.net/newzy08/fquk6v3o/3/
You can achieve this with css as well using height and width in em units. Em means relative to the font-size of the element (2em means 2 times the size of the current font) w3schools.com/cssref/css_units.asp
I don't know if this works well together with the autogrowth plugin though.
$(document).ready(function(){
$("#font-small").click(function(){
$(".ta").css("font-size", "12px");
});
$("#font-big").click(function(){
$(".ta").css("font-size", "24px");
});
$("#font-huge").click(function(){
$(".ta").css("font-size", "36px");
});
});
.ta {
font-size: 12px;
height: 3em;
width: 10em;
resize: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<textarea class="ta">test</textarea>
</div>
<div>
<button id="font-small">fontsmall</button>
<button id="font-big">fontbig</button>
<button id="font-huge">fonthuge</button>
</div>

Add CSS only when a section or is in range

I am trying to make a "sticky" image where all images of class ".img" add a css attribute and then remove it when it is not in range.
I do this by getting the ID of each of the images and pass it to a function that makes it fixed (addCSS). It works fine - the images stick right where they are supposed to smoothly, but when I try to scroll up, they keep their css. I want to remove the CSS property when the wScroll is outside the range.
$('.img').each(function () {
var sectionOffset = $(this).offset().top;
var attID = $(this).attr('id');attID = $("#"+attID.toString()+"");
if (wScroll >= sectionOffset && wScroll <= (sectionOffset + sectionHeight)) {
addCSS(attID);
}
});
function addCSS(element) {
element.css({
'position': 'fixed',
'top': stickyPosition - 75,
'left': OffsetLeft
});
}
function removeCSS(element) {
element.css({
'position': '',
'top': '',
'left': ''
});
}
I tried modifying it this way but it makes it jump :(
$('.img').each(function () {
var sectionOffset = $(this).offset().top;
var attID = $(this).attr('id');attID = $("#"+attID.toString()+"");
if (wScroll >= sectionOffset && wScroll <= (sectionOffset + sectionHeight)) {
addCSS(attID);
}
else if (wScroll > (sectionOffset + sectionHeight) || wScroll < sectionOffset) {
removeCSS(attID);
}
});
I managed to get it working smoothly without using an array, but the code is a bit long and I was hoping to simplify it without losing function.
Here is a simplified version: http://codepen.io/ebevers/pen/xwbdbP
for this, I just need the squares to jump back into place. Thanks!
Try this:
// Last section and current section
var last_section = -1;
var current_section = -1;
// Scroll
jQuery(window).scroll(function(){
// Get current section
for (var i = 0; i < jQuery('.row').length; i++) {
if (jQuery(this).scrollTop() >= jQuery('.row:eq('+i+')').position().top) {
current_section = i;
}
}
// If change
if (current_section != last_section) {
removeCSS(jQuery('.row:eq('+last_section+') .img'));
addCSS(jQuery('.row:eq('+current_section+') .img'));
last_section = current_section;
}
});
http://jsfiddle.net/c4z9satw/
Another way of doing it, but without globals and it relies on explicitly set identifiers.
Added CSS:
.active {
position: fixed;
top: 100px;
left: 100px;
}
JavaScript:
$(window).scroll(function() {
var rows = $(".row");
$(".img").each(function() {
var row = false, i, l, id;
for (i = 0, l = rows.length; i < l; i++) {
id = "#" + this.id.toString();
if ($(rows[i]).find(id)[0] != undefined) {
row = rows[i];
break;
}
}
if (!row)
return false;
if ((window.scrollY >= $(row).offset().top) && (window.scrollY < $(row).offset().top + $(row).outerHeight()))
$(this).addClass("active");
else
$(this).removeClass("active");
});
});
JSFiddle: http://jsfiddle.net/w7ru130s/2/

Don't success to change the input width

I'm making some project like that should look like http://jsbin.com
when I'm trying to change the input width it is does'nt success
var clickedHtml = "#EFEDEF";
var clickedCss = "#EFEDEF";
var clickedJs = "#EFEDEF";
var clickedRes = "#EFEDEF";
function inputSize() {
var perc = 0;
if (clickedHtml == "#818081") {
perc++;
}
if (clickedCss == "#818081") {
perc++;
}
if (clickedJs == "#818081") {
perc++;
}
if (clickedRes == "#818081") {
perc++;
}
if (perc != 0) {
perc = 100 / perc;
}
return "\"" + perc.toString() + "%\"";
}
$("#htmlBut").click(function () {
if (clickedHtml == "#EFEDEF") {
$("#htmlBut").css("backgroundColor", "#818081");
clickedHtml = "#818081";
} else {
$("#htmlBut").css("backgroundColor", "#EFEDEF");
clickedHtml = "#EFEDEF";
}
$("#htmlField").css({
width: inputSize(),
display: 'block'
});
});
htmlField - input id.
htmlBut - html button id.
You need to just return the value as a string, no need to enclose it in ""
return perc.toString() + "%";
In your case the returned value "50%" is not valid, it should be just 50%
Return 'return perc.toString() + "%";' from inputSize method.

Calculating the maximum/minimum height of a DIV element

The Problem:
Given a DIV element with a fixed height, which contains an unknown number of child elements that are sized relative to its height, calculate the maximum/minimum height that the DIV could resize to, without violating any of the maximum/minimum values of its child elements.
Example
Find the maximum/minimum height of DIV A
Answer
Minimum: 150px
Maximum: 275px
* {
box-sizing: border-box;
}
.border {
border-style: solid;
border-width: 1px 1px 1px 1px;
}
.A {
height: 200px;
width: 200px;
}
.B {
float: left;
width: 50%;
height: 75%;
min-height: 125px;
max-height: 225px;
background: yellow;
}
.C {
float: left;
width: 50%;
height: 75%;
min-height: 100px;
max-height: 250px;
background: green;
}
.D{
float: left;
width: 100%;
height: 25%;
min-height: 25px;
max-height: 50px;
background: blue;
}
<div class="A border">
<div class="B border">
B
</div>
<div class="C border">
C
</div>
<div class="D border">
D
</div>
</div>
Additional Information:
I currently have tried using an algorithm that traverses the DIV's DOM tree and creates an object graph representing the spacial positioning of the elements, using the elements offset. Below is a rudimentary algorithm that examines the spacial relationship of the elements, allowing for a 10px spread between edges to be considered 'touching'.
jQuery and other libraries are allowed as long as they are open source.
var _isContentRoot = function(a,b){
var aRect = a.innerRect;
var bRect = b.outerRect;
//Check if child element is a root node
return Math.abs(aRect.top - bRect.top) <= 10;
}
var _isLayoutSibling = function(a,b){
var aRect = a.outerRect;
var bRect = b.outerRect;
// If element X has a boundary that intersects element Y, and
// element X is located above element Y, element Y is a child node of
// element X
if(Math.abs(aRect.bottom - bRect.top) <= 10) {
if (aRect.left <= bRect.left && aRect.right >= bRect.left ||
aRect.left <= bRect.right && aRect.right >= bRect.right ||
aRect.left >= bRect.left && aRect.right <= bRect.right ||
aRect.left <= bRect.left && aRect.right >= bRect.right) {
return true;
}
}
return false;
}
Edit: Fixed CSS error. Here is an updated Fiddle
http://jsfiddle.net/zqnscmo2/
Edit 2: Try to think of this more of a graph problem in the problem space of CSS/HTML. Imagine the CSS and HTML are used to describe a graph where each DIV is a vertex. There exists an edge between the two vertices
1.) if the HTML element's bounding rectA.top ≈ rectB.top OR
2.) there exists an edge if the bounding rectA.bottom ≈ rectB.top
Each vertex has two exclusive sets of edges, set A contains all edges that meet criterion 1. Set B contains all edges that meet criterion 2. Therefor you can traverse the graph and find the minimal and maximal path and that should be the PARENT DIV's max/min height.
This is my proposed algorithm for determining the max/min height of the inner contents. I'm very much open to less complex solutions.
If I understood your question correctly, would this work?
// - I use two support functions that can probably be found in other JSes frameworks, and they're down below.
function calculateMySizes(someElement) {
var childDiv = findChild(someElement, "DIV");
var totalWidth = 0;
var totalHeight = 0;
var maxWidth = 0;
var maxHeight = 0;
do
{
if(childDiv.offsetLeft > maxWidth) {
maxWidth = childDiv.offsetLeft;
totalWidth += childDiv.offsetLeft;
}
if(childDiv.offsetTop > maxHeight) {
maxHeight = childDiv.offsetTop;
totalHeight += childDiv.offsetTop;
}
}
while (childDiv = nextElement(childDiv));
alert("object's current width is: " + totalWidth + " and it's child's largest width is: " + maxWidth);
alert("object's current height is: " + totalHeight + " and it's child's largest height is: " + maxHeight);
}
// - Returns the next Element of object
function nextElement(object) {
var nextObject = object;
while (nextObject = nextObject.nextSibling) {
if (nextObject.nodeType == 1) {
return nextObject;
}
}
return nextObject;
}
// - Returns the first child of elementName found
function findChild(object, elementName) {
for (var i = 0; i < object.childNodes.length; i++) {
if (object.childNodes[i].nodeType == 1) {
if (object.childNodes[i].nodeName.toUpperCase() == childName) {
return object;
}
if (object.childNodes[i].hasChildNodes()) {
var child = findChild(object.childNodes[i], childName, countMatch);
if (child) {
return child;
}
}
}
}
}
I can think of a scenario where the child object's bounding box is deceptively smaller than it's own children, in the case of a float or position:absolute element, and to fix that a recursive call for all the children would be required, but other than this scenario, this should give you the minimum width/height of any element according to their children's sizes.
This is what I'm thinking:
Find the nearest ancestor with an explicit height
Find all the ancestors with percentage heights and calculate the height of the nearest one of those ancestors to find the available height. Lets call that ancestor NAR and the height NARH.
Find the distance your element is from the top of its parent (with getBoundingClientRect). Call it DT
Subtract the top boundary of NAR from DT. Call this A.
Your maximum height should be NARH-A
Something similar could be done for the minimum.
UPDATE: Ohhhh kay, I implemented this idea and it works! There's a lot of crap it takes into account including margins, borders, padding, scroll bars (even with custom widths), percentage widths, max-height/width, and sibling nodes. Check out this code:
exports.findMaxHeight = function(domNode) {
return findMaxDimension(domNode,'height')
}
exports.findMaxWidth = function(domNode) {
return findMaxDimension(domNode,'width')
}
// finds the maximum height/width (in px) that the passed domNode can take without going outside the boundaries of its parent
// dimension - either 'height' or 'width'
function findMaxDimension(domNode, dimension) {
if(dimension === 'height') {
var inner = 'Top'
var outer = 'Bottom'
var axis = 'Y'
var otherAxis = 'X'
var otherDimension = 'width'
} else {
var inner = 'Left'
var outer = 'Right'
var axis = 'X'
var otherAxis = 'Y'
var otherDimension = 'height'
}
var maxDimension = 'max'+dimension[0].toUpperCase()+dimension.slice(1)
var innerBorderWidth = 'border'+inner+'Width'
var outerBorderWidth = 'border'+outer+'Width'
var innerPaddingWidth = 'padding'+inner
var outerPaddingWidth = 'padding'+outer
var innerMarginWidth = 'margin'+inner
var outerMarginWidth = 'margin'+outer
var overflowDimension = 'overflow'+axis
var propertiesToFetch = [
dimension,maxDimension, overflowDimension,
innerBorderWidth,outerBorderWidth,
innerPaddingWidth,outerPaddingWidth,
innerMarginWidth, outerMarginWidth
]
// find nearest ancestor with an explicit height/width and capture all the ancestors in between
// find the ancestors with heights/widths relative to that one
var ancestry = [], ancestorBottomBorder=0
for(var x=domNode.parentNode; x!=null && x!==document.body.parentNode; x=x.parentNode) {
var styles = getFinalStyle(x,propertiesToFetch)
var h = styles[dimension]
if(h.indexOf('%') === -1 && h.match(new RegExp('\\d')) !== null) { // not a percentage and some kind of length
var nearestAncestorWithExplicitDimension = x
var explicitLength = h
ancestorBottomBorder = parseInt(styles[outerBorderWidth]) + parseInt(styles[outerPaddingWidth])
if(hasScrollBars(x, axis, styles))
ancestorBottomBorder+= getScrollbarLength(x,dimension)
break;
} else {
ancestry.push({node:x, styles:styles})
}
}
if(!nearestAncestorWithExplicitDimension)
return undefined // no maximum
ancestry.reverse()
var maxAvailableDimension = lengthToPixels(explicitLength)
var nodeToFindDistanceFrom = nearestAncestorWithExplicitDimension
ancestry.forEach(function(ancestorInfo) {
var styles = ancestorInfo.styles
var newDimension = lengthToPixels(styles[dimension],maxAvailableDimension)
var possibleNewDimension = lengthToPixels(styles[maxDimension], maxAvailableDimension)
var moreBottomBorder = parseInt(styles[outerBorderWidth]) + parseInt(styles[outerPaddingWidth]) + parseInt(styles[outerMarginWidth])
if(hasScrollBars(ancestorInfo.node, otherAxis, styles))
moreBottomBorder+= getScrollbarLength(ancestorInfo.node,otherDimension)
if(possibleNewDimension !== undefined && (
newDimension !== undefined && possibleNewDimension < newDimension ||
possibleNewDimension < maxAvailableDimension
)
) {
maxAvailableDimension = possibleNewDimension
nodeToFindDistanceFrom = ancestorInfo.node
// ancestorBottomBorder = moreBottomBorder
} else if(newDimension !== undefined) {
maxAvailableDimension = newDimension
nodeToFindDistanceFrom = ancestorInfo.node
// ancestorBottomBorder = moreBottomBorder
} else {
}
ancestorBottomBorder += moreBottomBorder
})
// find the distance from the top
var computedStyle = getComputedStyle(domNode)
var verticalBorderWidth = parseInt(computedStyle[outerBorderWidth]) + parseInt(computedStyle[innerBorderWidth]) +
parseInt(computedStyle[outerPaddingWidth]) + parseInt(computedStyle[innerPaddingWidth]) +
parseInt(computedStyle[outerMarginWidth]) + parseInt(computedStyle[innerMarginWidth])
var distanceFromSide = domNode.getBoundingClientRect()[inner.toLowerCase()] - nodeToFindDistanceFrom.getBoundingClientRect()[inner.toLowerCase()]
return maxAvailableDimension-ancestorBottomBorder-verticalBorderWidth-distanceFromSide
}
// gets the pixel length of a value defined in a real absolute or relative measurement (eg mm)
function lengthToPixels(length, parentLength) {
if(length.indexOf('calc') === 0) {
var innerds = length.slice('calc('.length, -1)
return caculateCalc(innerds, parentLength)
} else {
return basicLengthToPixels(length, parentLength)
}
}
// ignores the existences of 'calc'
function basicLengthToPixels(length, parentLength) {
var lengthParts = length.match(/(-?[0-9]+)(.*)/)
if(lengthParts != null) {
var number = parseInt(lengthParts[1])
var metric = lengthParts[2]
if(metric === '%') {
return parentLength*number/100
} else {
if(lengthToPixels.cache === undefined) lengthToPixels.cache = {}//{px:1}
var conversion = lengthToPixels.cache[metric]
if(conversion === undefined) {
var tester = document.createElement('div')
tester.style.width = 1+metric
tester.style.visibility = 'hidden'
tester.style.display = 'absolute'
document.body.appendChild(tester)
conversion = lengthToPixels.cache[metric] = tester.offsetWidth
document.body.removeChild(tester)
}
return conversion*number
}
}
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/number
var number = '(?:\\+|-)?'+ // negative or positive operator
'\\d*'+ // integer part
'(?:\\.\\d*)?'+ // fraction part
'(?:e(?:\\+|-)?\\d*)?' // scientific notation
// https://developer.mozilla.org/en-US/docs/Web/CSS/calc
var calcValue = '(?:'+
'('+number+')'+ // length number
'([A-Za-z]+|%)?'+ // optional suffix (% or px/mm/etc)
'|'+
'(\\(.*\\))'+ // more stuff in parens
')'
var calcSequence = calcValue+
'((\\s*'+
'(\\*|/|\\+|-)'+
'\\s*'+calcValue+
')*)'
var calcSequenceItem = '\\s*'+
'(\\*|/|\\+|-)'+
'\\s*'+calcValue
var caculateCalc = function(calcExpression, parentLength) {
var info = calcExpression.match(new RegExp('^'+calcValue))
var number = info[1]
var suffix = info[2]
var calcVal = info[3]
var curSum = 0, curProduct = getCalcNumber(number, suffix, calcVal, parentLength), curSumOp = '+'
var curCalcExpression = calcExpression.slice(info[0].length)
while(curCalcExpression.length > 0) {
info = curCalcExpression.match(new RegExp(calcSequenceItem))
var op = info[1]
number = info[2]
suffix = info[3]
calcVal = info[4]
var length = getCalcNumber(number,suffix,calcVal, parentLength)
if(op in {'*':1,'/':1}) {
curProduct = calcSimpleExpr(curProduct,op,length)
} else if(op === '+' || op === '-') {
curSum = calcSimpleExpr(curSum,curSumOp,curProduct)
curSumOp = op
curProduct = length
}
curCalcExpression = curCalcExpression.slice(info[0].length)
}
curSum = calcSimpleExpr(curSum,curSumOp,curProduct)
return curSum
}
function calcSimpleExpr(operand1, op, operand2) {
if(op === '*') {
return operand1 * operand2
} else if(op === '/') {
return operand1 / operand2
} else if(op === '+') {
return operand1 + operand2
} else if(op === '-') {
return operand1 - operand2
} else {
throw new Error("bad")
}
}
function getCalcNumber(number, suffix, calcVal, parentLength) {
if(calcVal) {
return caculateCalc(calcVal, parentLength)
} else if(suffix) {
return basicLengthToPixels(number+suffix, parentLength)
} else {
return number
}
}
// gets the style property as rendered via any means (style sheets, inline, etc) but does *not* compute values
// domNode - the node to get properties for
// properties - Can be a single property to fetch or an array of properties to fetch
function getFinalStyle(domNode, properties) {
if(!(properties instanceof Array)) properties = [properties]
var parent = domNode.parentNode
if(parent) {
var originalDisplay = parent.style.display
parent.style.display = 'none'
}
var computedStyles = getComputedStyle(domNode)
var result = {}
properties.forEach(function(prop) {
result[prop] = computedStyles[prop]
})
if(parent) {
parent.style.display = originalDisplay
}
return result
}
// from lostsource http://stackoverflow.com/questions/13382516/getting-scroll-bar-width-using-javascript
// dimension - either 'width' or 'height'
function getScrollbarLength(domNode, dimension) {
if(dimension === 'width') {
var offsetDimension = 'offsetWidth'
} else {
var offsetDimension = 'offsetHeight'
}
var outer = document.createElement(domNode.nodeName)
outer.className = domNode.className
outer.style.cssText = domNode.style.cssText
outer.style.visibility = "hidden"
outer.style.width = "100px"
outer.style.height = "100px"
outer.style.top = "0"
outer.style.left = "0"
outer.style.msOverflowStyle = "scrollbar" // needed for WinJS apps
domNode.parentNode.appendChild(outer)
var lengthNoScroll = outer[offsetDimension]
// force scrollbars with both css and a wider inner div
var inner1 = document.createElement("div")
inner1.style[dimension] = "120%" // without this extra inner div, some browsers may decide not to add scoll bars
outer.appendChild(inner1)
outer.style.overflow = "scroll"
var inner2 = document.createElement("div")
inner2.style[dimension] = "100%"
outer.appendChild(inner2) // this must be added after scroll bars are added or browsers are stupid and don't properly resize the object (or maybe they do after a return to the scheduler?)
var lengthWithScroll = inner2[offsetDimension]
domNode.parentNode.removeChild(outer)
return lengthNoScroll - lengthWithScroll
}
// dimension - Either 'y' or 'x'
// computedStyles - (Optional) Pass in the domNodes computed styles if you already have it (since I hear its somewhat expensive)
function hasScrollBars(domNode, dimension, computedStyles) {
dimension = dimension.toUpperCase()
if(dimension === 'Y') {
var length = 'Height'
} else {
var length = 'Width'
}
var scrollLength = 'scroll'+length
var clientLength = 'client'+length
var overflowDimension = 'overflow'+dimension
var hasVScroll = domNode[scrollLength] > domNode[clientLength]
// Check the overflow and overflowY properties for "auto" and "visible" values
var cStyle = computedStyles || getComputedStyle(domNode)
return hasVScroll && (cStyle[overflowDimension] == "visible"
|| cStyle[overflowDimension] == "auto"
)
|| cStyle[overflowDimension] == "scroll"
}
I'll probably put this in an npm/github module cause it seems like something that should be available naively, but isn't and takes a shiteload of work to do right.
Here is the best solution I could come up with.
First, if a DIV depends on it's child's contents to determine it's size, I give it an the selector .childDependent and if the div can resize vertically, I give it the selector .canResize.
<div class="A border childDependent canResize">
<div class="B border canResize">
B
</div>
<div class="C border canResize">
C
</div>
<div class="E border canResize">
E
</div>
<div class="D border canResize">
D
</div>
</div>
Here is a fiddle to look at:
http://jsfiddle.net/p8wfejhr/

Categories