Using FitText with the change() method - javascript

How do I trigger the below fittext.js function
$.fn.fitText = function( kompressor, options ) {
var compressor = kompressor || 1,
settings = $.extend({
'minFontSize' : Number.NEGATIVE_INFINITY,
'maxFontSize' : Number.POSITIVE_INFINITY
}, options);
return this.each(function(){
// Store the object
var $this = $(this);
// Resizer() resizes items based on the object width divided by the compressor * 10
var resizer = function () {
$this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize)));
};
)};
using the change() Method?
$('#drop').change(function(){
$('#tf').css('width', $(this).val());
//resizer(); // does not work
//$('#tf').fitText(1.2, { minFontSize: '20px', maxFontSize: '40px' });// does not work
});

You need to trigger a resize event because the fittext plugin listens to the window's resize event to call the internal resize method
$(window).on('resize.fittext orientationchange.fittext', resizer);
so
$('#tf').fitText(1.2, {
minFontSize: '20px',
maxFontSize: '40px'
});
$('#drop').change(function () {
$('#tf').css('width', $(this).val());
$(window).trigger('resize.fittext');
});
Demo: Fiddle - set the width as 100/300/500

Related

jQuery on function (click) only affect one class

When the blue button is clicked it affects both buttons
http://jsfiddle.net/umbriel/Lwvukzhy/1/
My setup looks like this
var
$window = $(window),
$body = $('body'),
$buttonRight = $('.button .right')
;
$buttonRight.on('click', function( ) {
buttonReveal( $( this ) );
});
function buttonReveal() {
$buttonLeft.css({'width':'25%'});
$buttonRight.css({'width':'75%'});
}
I want to to only affect one of buttons I clicked
Thank you
Use .siblings() to get siblings. Try this:
$buttonRight.on('click', function( ) {
buttonReveal($(this)); //$(this) refers to current clicked element (button)
});
$buttonLeft.on('click', function() {
buttonHide($(this)); //$(this) refers to current clicked element (button)
});
function buttonReveal(element) {
element.siblings($buttonLeft).css({'width':'25%'}); //to apply css to siblings use .siblings()
element.css({'width':'75%'});
}
function buttonHide(element) {
element.css({'width':'0%'});
element.siblings($buttonRight).css({'width':'100%'});
}
DEMO
You need to target the left/right buttons which is related to the clicked button. So you need to pass the clicked button to buttonReveal() and buttonHide().
So
(function (window, $) {
var
$window = $(window),
globalTimeout = null,
$body = $('body'),
$buttonRight = $('.button .right'),
$buttonLeft = $('.button .left');
$buttonRight.on('click', function () {
buttonReveal(this);
});
$buttonLeft.on('click', function () {
buttonHide(this);
});
function buttonReveal(button) {
var $btn = $(button).css({
'width': '75%'
});
$btn.prev('.left').css({
'width': '25%'
});
}
function buttonHide(button) {
var $btn = $(button).css({
'width': '0%'
});
$btn.next('.right').css({
'width': '100%'
});
}
}(window, $));
Demo: Fiddle

Trying to animate with on change

I am trying to animate the width of something when the .change() function is called, but it doesn't seem to be working.
Any idea why?
Here is my code:
$(document).ready(function(){
$('#code').change(function(){
//on change animate a width of +16px increase.
$(this).animate({width: '+=16'});
});
});
Here is a js fiddle with the issue recreated: http://jsfiddle.net/BUSSX/
If you really want a change event for input controls, then here's a jQuery plug-in method I wrote a little while ago that does this and works for nearly all ways that the content of the input control can be changed including drag/drop, copy/paste, typing, etc... It takes advantage of newer events that help with this if they exist, otherwise it falls back to listening for lots of other events and looking to see if the data has changed.
(function($) {
var isIE = false;
// conditional compilation which tells us if this is IE
/*#cc_on
isIE = true;
#*/
// Events to monitor if 'input' event is not supported
// The boolean value is whether we have to
// re-check after the event with a setTimeout()
var events = [
"keyup", false,
"blur", false,
"focus", false,
"drop", true,
"change", false,
"input", false,
"textInput", false,
"paste", true,
"cut", true,
"copy", true,
"contextmenu", true
];
// Test if the input event is supported
// It's too buggy in IE so we never rely on it in IE
if (!isIE) {
var el = document.createElement("input");
var gotInput = ("oninput" in el);
if (!gotInput) {
el.setAttribute("oninput", 'return;');
gotInput = typeof el["oninput"] == 'function';
}
el = null;
// if 'input' event is supported, then use a smaller
// set of events
if (gotInput) {
events = [
"input", false,
"textInput", false
];
}
}
$.fn.userChange = function(fn, data) {
function checkNotify(e, delay) {
var self = this;
var this$ = $(this);
if (this.value !== this$.data("priorValue")) {
this$.data("priorValue", this.value);
fn.call(this, e, data);
} else if (delay) {
// The actual data change happens aftersome events
// so we queue a check for after
// We need a copy of e for setTimeout() because the real e
// may be overwritten before the setTimeout() fires
var eCopy = $.extend({}, e);
setTimeout(function() {checkNotify.call(self, eCopy, false)}, 1);
}
}
// hook up event handlers for each item in this jQuery object
// and remember initial value
this.each(function() {
var this$ = $(this).data("priorValue", this.value);
for (var i = 0; i < events.length; i+=2) {
(function(i) {
this$.on(events[i], function(e) {
checkNotify.call(this, e, events[i+1]);
});
})(i);
}
});
}
})(jQuery);
Then, your code would look like this:
$(document).ready(function(){
$('#code').userChange(function(){
//on change animate a width of +16px increase.
$(this).animate({width: '+=16'});
});
});
In looking at your code, you are increasing the width of the input control by 16px on every change. You probably should be looking at the number of characters in the control and assessing what to do about the width based on that because this will make things wider event if the user hits the backspace key. I'd probably do something like this that grows the item as content is added, but doesn't shrink it:
$(document).ready(function(){
$('#code').userChange(function(){
// on change animate width as chars are added
// only grow it when the width needs to be larger than it is currently
var item = $(this);
var origWidth = item.data("initialWidth");
var curWidth = item.width();
if (!origWidth) {
origWidth = curWidth;
item.data("initialWidth", origWidth);
}
var newWidth = origWidth + (8 * item.val().length);
if (newWidth > curWidth) {
item.stop(true, true).animate({width: newWidth}, 500);
}
});
});
Working code example: http://jsfiddle.net/jfriend00/BEDcR/
If you want the userChange method to execute when you programmatically set the value with .val(), then you can make your own method for that:
$(document).ready(function(){
function updateWidth() {
// on change animate width as chars are added
// only grow it when the width needs to be larger than it is currently
var item = $(this);
var origWidth = item.data("initialWidth");
var curWidth = item.width();
if (!origWidth) {
origWidth = curWidth;
item.data("initialWidth", origWidth);
}
var newWidth = origWidth + (8 * item.val().length);
if (newWidth > curWidth) {
item.stop(true, true).animate({width: newWidth}, 500);
}
}
$('#code').userChange(updateWidth);
$.fn.valNotify = function(value) {
this.val(value);
this.each(function() {
updateWidth.call(this);
});
return this;
}
});
Then, you can change your values with this and it will automatically resize too:
$("#code").valNotify("foo");
If based on your previous question HTML markup :
<button class="I button">I</button>
<button class="O button">O</button>
<input id="code" type="text" disabled />
So if you want to animate the width of the textbox, you need to animate it when click the button:
$('.button').click(function(event) {
var text = $(this).text();
$('input:text').val(function(index, val) {
return val + text;
});
$('#code').animate({width: '+=16'});
});
Working Demo
If based on your above question HTML markup, you need to use keyup instead of change as well as include the jQuery library in the jsFiddle:
$(document).ready(function(){
$('#code').keyup(function(){
//on change animate a width of +16px increase.
$(this).animate({width: '+=16'});
});
});
Updated Demo
You just need to check which key was pressed:
$(document).ready(function(){
$('#code').keyup(function(e){
//on change animate a width of +16px increase.
if(e.keyCode == 8) { // Backspace pressed
$(this).animate({width: '-=16'});
} else {
$(this).animate({width: '+=16'});
}
});
});
Updated Demo
You forgot to load jQuery, working fine here http://jsfiddle.net/BUSSX/13/ - also you need the click event. Or even better use the keyup event so that as soon as something is typed, the textbox increases in width - http://jsfiddle.net/BUSSX/15/
you have a bad implementation check http://jsfiddle.net/3dSZx/ and you need add jquery to fiddle
JS
$(document).ready(function(){
$('#push').click(function(){
//on change animate a width of +16px increase.
$('#code').animate({ width: '+=16'});
});
});
IrfanM, instead of incrementing by a fixed amount, you might consider incrementing by just the right amount to accommodate each character as it is typed.
Unless I've overcomplicated things (not completely unknown), this is moderately tricky.
In the following jQuery plugin :
text input fields are each given a hidden <span> with the same font-family and font-size as its respective input element.
the <span> elements act as "measuring sticks" by accepting a copy of their input field's entire text every time a character is typed.
the width of the <span> plus one generous character width is then used to determine the width of the input field.
Here's the code :
(function ($) {
var pluginName = 'expandable';
$.fn[pluginName] = function () {
return this.each(function (i, input) {
var $input = $(input);
if (!$input.filter("input[type='text']").length) return true;
// Common css directives affecting text width
// May not be 100% comprehensive
var css = {
fontFamily: $input.css('fontFamily'),
fontSize: $input.css('fontSize'),
fontStyle: $input.css('fontStyle'),
fontVariant: $input.css('fontVariant'),
fontWeight: $input.css('fontWeight'),
fontSizeAdjust: $input.css('fontSizeAdjust'),
fontStretch: $input.css('fontStretch'),
letterSpacing: $input.css('letterSpacing'),
textTransform: $input.css('textTransform'),
textWrap: 'none'
};
var $m = $("<span/>").text('M').insertAfter($input).css(css).text('M').hide();
var data = {
'm': $m,
'w': $m.width()
};
$input.data(pluginName, data).keyup(function (e) {
$this = $(this);
var data = $this.data(pluginName);
var w = data.m.html($this.val().replace(/\s/g, " ")).width();
$this.css({
'width': w + data.w
});
}).trigger('keyup');
});
};
})(jQuery);
$(document).ready(function () {
$('input').expandable();
});
DEMO
This works because a <span> element automatically expands to accommodate its text, whereas an <input type="text"> element does not. A great feature of this approach is that the keystrokes don't need to be tested - the plugin automatically responds to character deletions in the same way it responds to character strokes.
It works with proportional and monospaced fonts and even responds appropriately to cut and paste.
The only precaution necessary is to convert spaces to non-breaking spaces, $nbsp;, otherwise HTML renders multiple spaces as a single space in the <span> element.
Of course, it you really want exactly 16px growth for every keystroke, then stick with what you already have.

setTimeout in a JQuery animation

I'm having a problem with the setTimeout(). I want, in the mouseout state, that the submenu slides Up after a interval (500 miliseconds). But the setTimeout() isn't working.
Like in this link: http://jsfiddle.net/felipepalazzo/Xyhvn/2/
The code:
(function($){
$.fn.showMenu = function(options){
var settings = $.extend({
height : '40px',
speed : '500',
heightx : '20px'
}, options || {});
return this.each(function(){
var elem = $(this);
var menu_timer;
elem.hover(function(){
$(this).stop().animate({'height' : settings.height}, settings.speed);
}, function(){
//setTimeout(function(){
$(this).stop().animate({'height' : settings.heightx}, settings.speed);
//},500);
});
});
};
})(jQuery);
This is out of scope.
var that = this;
setTimeout(function(){
$(that).stop().animate({'height' : settings.heightx}, settings.speed);
},500);
Use delay()
So for example
$(this).delay(500).stop().animate({'height' : settings.heightx}, settings.speed);
I think that the problem relies on the element $(this), when you're inside of the function of the setTimeout the element this it's not the same. Why you don't try to save the element in a var and then executes the function
var foo = this;
setTimeout(function(){
$(foo).stop().animate({'height' : settings.heightx}, settings.speed);
},500);

Jquery slide tab from right to left function

I am currently trying to slide a tab from right to left using this code but i am not achieving my initial goal. this is the jquery file. I tried implementing animate direction left but it only gave me errors.
(function ($) {
$.fn.showHide = function (options) {
//default vars for the plugin
var defaults = {
speed: 1000,
easing: '',
changeText: 0,
showText: 'Show',
hideText: 'Hide'
};
var options = $.extend(defaults, options);
$(this).click(function () {
$('.toggleDiv').slideUp(options.speed, options.easing);
var toggleClick = $(this);
var toggleDiv = $(this).attr('rel');
$(toggleDiv).slideToggle(options.speed, options.easing, function() {
if(options.changeText==1){
$(toggleDiv).is(":visible") ? toggleClick.text(options.hideText) : toggleClick.text(options.showText);
}
});
return false;
});
};
})(jQuery);
Main problem here:
var options = $.extend(defaults, options);
You're declaring options twice, in the function as a parameter, and as a variable inside the function. This is a source of problems. Just rename it to opts for example:
var opts = $.extend(defaults, options);

Mootools slider adjustments

I am new to mootools. I have joomla site with MooSlider:
var MooSlider = new Class({
initialize: function(options) {
this.options = Object.extend({
container: null,
slides: null,
navs:null,
transition: Fx.Transitions.Sine.easeOut,
effectDuration: 500,
fromTop: 500,
topDist: 100,
slideDelay: 5000
}, options || {});
if(!$(this.options.container)) return;
this.start();
},
start: function(){
this.elements = $(this.options.container).getElements(this.options.slides);
this.navs = $(this.options.container).getElements(this.options.navs);
this.currentElement = 0;
this.elements.each(function(elem, i){
var nav = this.navs[i];
if(i==this.currentElement){
nav.addClass('selected');
}
elem.setStyles({
'position':'absolute',
'top':0,
'left':0,
'opacity':( i==this.currentElement ? 1 : 0 )
});
this.elements[i]['fx'] = new Fx.Styles(elem, {
duration:this.options.effectDuration,
wait:false,
transition:this.options.transition
});
this.elements[i]['nav'] = nav;
elem.addEvents({
'mouseenter': function(){
$clear(this.period);
}.bind(this),
'mouseleave': function(){
if( this.options.slideDelay )
this.period = this.rotate.periodical(this.options.slideDelay, this);
}.bind(this)
});
nav.addEvent('click', function(event){
if(this.currentElement==i) return;
new Event(event).stop();
$clear(this.period);
this.changeSlide(i);
if( this.options.slideDelay )
this.period = this.rotate.periodical(this.options.slideDelay, this);
}.bind(this));
}.bind(this));
if( this.options.slideDelay )
this.period = this.rotate.periodical(this.options.slideDelay, this);
},
rotate: function(){
var i = this.currentElement+1 < this.elements.length ? this.currentElement+1 : 0;
this.changeSlide(i);
},
changeSlide: function(i){
//$(this.options.navigationContainer).addClass('preload');
var cEl = this.currentElement;
this.elements[this.currentElement]['fx'].start({'opacity':0, 'left':1500});
this.elements[i]['fx'].set({'left':0});
this.elements[i]['fx'].start({'opacity':1, 'top':[500,0]}).chain(function(){
//$(this.options.navigationContainer).removeClass('preload');
}.bind(this));
this.elements[this.currentElement]['nav'].removeClass('selected');
this.elements[i]['nav'].addClass('selected');
this.currentElement = i;
}})
This is how it used on page:
<script language="javascript" type="text/javascript">
window.addEvent('domready', function(){
new MooSlider({
container:'topslider',
slides:'.slide',
navs:'.navigator ul li',
effectDuration: 1000,
fromTop:500,
topDist:500,
slideDelay: 3000 });
})
The page url is http://www.miltonwebsitedesign.ca
You can see slider on top of the page. Each slide consists of picture at the left and description at the right.
What I need is to make slides work the same way, but the left side picture must not appear current way, it needs to fade in, when the slide is loaded, not appear, but fade in.
Description text slides and then at the left picture appears.
The structure of each slide is:
<div class='slide'>
<div class="yjsquare">
<div class="yjsquare_in">
<img src='src here' alt=''/><h1>H1 text here</h1><p>description here</p>
</div>
</div>
</div>
Will be happy to hear solution. Thanks.
this class is not well written as in, it does not allow for events like onStart and onComplete to be passed. the logical approach would be to modify the changeSlide method to fire some events:
// add
var el = this.elements[i]['fx'];
this.fireEvent("start", el);
// use el as reference...
el.start({'opacity':1, 'top':[500,0]}).chain(function(){
//$(this.options.navigationContainer).removeClass('preload');
// add
this.fireEvent("complete", el);
}.bind(this));
Make sure that your class also implements Events (which in 1.12 is done like so, if memory serves):
MooSlider.implement(new Events);
you are using a mix of 1.12 and 1.2+ code which is odd. In any case, if you do have 1.2 (joomla usually is not prior to 1.6) then instead add this into the class declaration:
Implements: [Events],
this allows you to add some callback logic upon instigating the class:
new MooSlider({
container:'topslider',
slides:'.slide',
navs:'.navigator ul li',
effectDuration: 1000,
fromTop:500,
topDist:500,
slideDelay: 3000,
onStart: function(el) {
el.getElement("img").setOpacity(0); // hide it during animation
},
onComplete: function(el) {
el.fade(1); // fade it in when done
}
});
you should really implement Options too and use this.setOptions(options) instead of your current $extend.
p.s. the onStart and onComplete code callbacks are examples, you may need to tweak this to suit your html and UI preferences.

Categories