3

so I want to use this JQuery plugin that Stack Overflow has made available to me :)

Auto-size dynamic text to fill fixed size container

However, I need to use this on an HTML element that is dynamically created server side. Example,

I create all the elements, convert them to HTML, and then return them as an array of Json strings basically (in HTML form) to the front end:

public JsonResult GetMessages()
{
    // do conversion work
    List<string> htmlMessages = new List<string>();
    foreach(Message message in this.messages)
    {
        htmlMessages.Add(message.toHTML());
    }
    return Json(htmlMessages);
}

And then on the front end I append them to a div in Jquery like this:

// make my AJAX call
// in the success method I do this
for (var i = 0; i < data.length; i++)
{
    $('#containerDiv').append(data[i]);
}

Now this works fine but how would I then call the JQuery plugin on each of these elements that's appended to format the text size within one of the divs in the element?

Community
  • 1
  • 1
slandau
  • 23,528
  • 42
  • 122
  • 184

3 Answers3

2

I don't know what the HTML itself looks like, but try something like this:

// snip...
var $container = $('#containerDiv');
for (var i = 0; i < data.length; i++)
{
    $container.append(data[i]);
}
$container.children('div').textfill({ maxFontPixels: 36 });

It looks like the plugin relies on the element containing a single <span> element, so your HTML will probably have to be structured accordingly. Also based on a wee little test, it looks like the plugin doesn't work correctly when called on a jQuery collection that contains more than one element. The simple fix:

$container.children('div').each(function ()
{
    $(this).textfill({ maxFontPixels: 36 });
});

The "Right Way" is to actually change the plugin, though:

;(function($) {
    $.fn.textfill = function(options) {
        var fontSize = options.maxFontPixels;
        this.each(function () {
            var $this = $(this),
                ourText = $this.find('span:visible:first'),
                maxHeight = $this.height(),
                maxWidth = $this.width(),
                textHeight,
                textWidth;
            do {
                ourText.css('font-size', fontSize);
                textHeight = ourText.height();
                textWidth = ourText.width();
                fontSize = fontSize - 1;
            } while ((textHeight > maxHeight || textWidth > maxWidth) && fontSize > 3);
        });
        return this;
    }
})(jQuery);

So your changed plugin, will that call it on every single span it finds in the container div?

Not quite. My changes just mean that you'd be able to replace

$container.children('div').each(function ()
{
    $(this).textfill({ maxFontPixels: 36 });
});

with

$container.children('div').textfill({ maxFontPixels: 36 });
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • Hmm, that's a good idea. So after the container has been completely filled, run the plugin on all it's children. That might just work. – slandau Jun 17 '11 at 14:55
  • So your changed plugin, will that call it on every single span it finds in the container div? – slandau Jun 17 '11 at 15:25
0

You can use .load() event to add the plugin when dom elements are dynamically added. http://api.jquery.com/load-event/

// make my AJAX call
// in the success method I do this
for (var i = 0; i < data.length; i++)
{
var elem = data[i];
elem.load(function(){
// Plugin here.
});

    $('#containerDiv').append(elem);
}
Phil
  • 4,134
  • 4
  • 23
  • 40
  • 1
    But I don't want to attach an event, I just want to run the plugin which just re-formats the text when it comes into the DOM. – slandau Jun 17 '11 at 14:53
  • 1
    Ok, they .load() should work. It will fire once that element is attached and rendered to the DOM. – Phil Jun 17 '11 at 14:56
  • Load might work as well and would be one event and I wouldn't have to worry about when to call it. I'll try this first, thanks. – slandau Jun 17 '11 at 14:57
0

This sounds like it could be a job for livequery, which allows you to run a function when an element is dynamically added to the DOM.

Town
  • 14,706
  • 3
  • 48
  • 72