Elastische Textareas mit jQuery

März 11, 2011

Ich wollte dynamische Textarea haben wie sie in Facebook gibt. So habe ich im Netz nach Lösungen gesucht und bin über mehrere Lösungen/Plugins gestolpert wie hier, hier oder hier, es gibt noch mehr.

Alle diese Lösungen waren mir zu Groß und zu Komplex. Ich möchte nicht noch ein jQuery im jQuery haben, sondern Kurz und Schmerzlos. Dazu waren ein paar Ansätze nicht so Flexibel, da sie die Größe des Textarea an den Umbrüchen des Inhalts bestimmen und das muss wiederum mit ein paar Wrapper CSS Methoden gefixt werden, was wiederum viel eingriff in den Quelltext des Projekts bedeutet.

Die ganzen Unzufriedenheiten haben mich dazu veranlasst selber zu experimentieren. Und nach kurzer Zeit fand ich eine EinfachGenialeLösung so wie eine Axt, sie hat nur ein Beil und Keil das wars!

Mein Ansatz braucht etwas CSS und nur maximal 400Bytes kleinen jQuery Plugin.

textarea.input {
    	width:500px; 
    	line-height:16px; 
    	height:16px; 
}
<textarea class="input" name="name">Dynamischer Inhalt</textarea>
jQuery.fn.elasticArea = function() {
  return this.each(function(){
    function resizeTextarea() {
      this.style.height = this.scrollHeight/2 + 'px';
      this.style.height = this.scrollHeight + 'px';
    }
    $(this).keypress(resizeTextarea)
    .keydown(resizeTextarea)
    .keyup(resizeTextarea)
    .css('overflow','hidden');
    resizeTextarea.call(this);
  });
};
 
$('textarea.input').elasticArea();

Dieser Ansatz funktioniert mit der Eigenschaft scrollHeight. Sie ist sehr Präzise und gibt genau die maximale Höhe der Textarea mit Inhalt. So nehme ich sie, Teile durch die Hälfte und setze sie der Textarea als Höhe ein. Danach wird sie wieder als Textarea Höhe gesetzt. Das macht die Textarea dynamisch in beide Richtungen wenn neuer Text eingefügt oder gelöscht wird und es passiert so schnell, dass man nichts davon mitkriegt.

Das ganze ist Dynamisch und wurde miniklein gehalten. So kann jeder selbst den Code nach seinen Wünschen erweitern falls er noch maximale Höhe haben möchte, die Höhe per Parameter übergeben ohne die CSS an zufassen oder sonstige Schnickschnacks.

Getestet hab ich in gängigen Browsern. Kann sein das irgend wo noch was hängt, aber alle von mir getesteten neue Browser haben es ohne Probleme geschluckt.

Eingesetzt können diese Elastischen Textareas als Input Felder. Weil ohne Inhalt sind sie so groß wie Inputs und können dynamisch mit dem Inhalt wachsen.

Hier ist noch eine Live Demo.

Das wars und mehr brauche ich nicht.

CKEditor onChange Event

März 10, 2011

Vor ein paar Wochen habe ich lange nach einer Lösung gesucht und aufgegeben, weil auch die CKEditor Event Seite war mir nicht genug. Heute hab ich es nochmal probiert und fand hier die Lösung:

var ckeditorInstance = CKEDITOR.replace("mytextarea");
 
ckeditorInstance.on("instanceReady", function()
{
	this.document.on("keyup", CKCHANGED);
	this.document.on("paste", CKCHANGED);
}
);
function CKCHANGED() { 
	formchanged = 1;
}

Gebraucht wird die Lösung um zu erkennen ob der User den Inhalt im CKEditor Textarea geändert hat und ihn beim verlassen der Seite zu warnen, dass er sein Code verändert hat ohne gespeichert zu haben. (Ich benutze es mit jQuery)

 
var formchanged = 0;
var submitted = 0;
 
$(document).ready(function() {
	$('form').each(function(i,n){
		$('input', n).change(function(){formchanged = 1});
		$('textarea', n).change(function(){formchanged = 1});
		$('select', n).change(function(){formchanged = 1}); 
		$(n).submit(function(){submitted=1});
	});
});
 
window.onbeforeunload = confirmExit;
function confirmExit()
{
	if(formchanged == 1 && submitted == 0)
		return "Sie verlassen die Seite ohne gespeichern zu haben.";
	else 
		return;
}

Skype Nummer Formatierung deaktivieren

Februar 17, 2011

Skype benutze ich gerne, doch es gefällt mir nicht wenn Skype in meinen Seiten die Telefonnummer mit seinem Firefox AddOn formatiert. Das kann man umgehen mit einer einfachen Technik. Man bindet im Html Head folgendes Meta Tag ein:

<meta name="SKYPE_TOOLBAR" content="SKYPE_TOOLBAR_PARSER_COMPATIBLE" />

Damit kann ich zumindest meinen Skype schon abschalten. Weite Tricks und die Lösung hab ich hier gefunden. Doch mir reicht erstmals die Meta Lösung, denn ich kann nicht von einen Kunden verlangen, der keine Ahnung hat vom HTML, den Span Trick zu nutzen.

IP Range um die Statistiken nicht zu verfälschen

Januar 21, 2011

Als ich mein kleines Projekt gestartet habe, baute ich eine Statistik um die User zu zählen. Gezählt wird nach der IP. Mit der Zeit hat sich die Tabelle mit IPs gefühlt und ich stellte fest, dass manche IPs zu oft kamen. Ich hab mir schon gedacht dass es sich um Google & Co und natürlich auch um Facebook handelt. Als ich mir die IP etwas näher ansah stellte ich fest, dass jede 2 IP Facebook war. Ich beschloss eine Liste zu machen um sie aus den Statistiken zu bannen. Doch immer wieder entdeckte ich neue Facebook und Google IPs. Und mir wurde klar das meine Liste ins unendliche geführt werden müsste.

Jeder großer Anbieter wie Google, Facebook oder Microsoft bekommt eine IP Range, eine Liste von-bis IPs. Diese IP Range kann man bei Whois Services herausfinden. So baute ich eine kleine Schleife die über die IPs geht und prüft bin ich in dem Bereich oder nicht. Mit einer kleinen Funktion ip2long kann man eine IP in ein Integer Wert auflösen und mit ihm auch weiter arbeiten.

Hier ist meine mini Lösung:

 
function ipInRange($ip)
{
     $ipRangeList = array(
        'google' => array('1123631104','1123639295'), // 66.249.64.0 - 66.249.95.255
        'facebook' => array('1121751040','1121755135'), // 66.220.144.0 - 66.220.159.255
        'facebook1' => array('1161801728','1161805823'), // 69.63.176.0 - 69.63.191.255
        'yahoo' => array('1136852992','1136918527'), // 67.195.0.0 - 67.195.255.255
        'microsoft' => array('1093926912','1094189055') // 65.52.0.0 - 65.55.255.255
    );
 
    $ipNum = ip2long($ip);
 
    foreach($ipRangeList as $node) {
        if($ipNum  >= $node[0] && $ipNum <= $node[1]) return true;
    }
    return false;
}
 
if($ipInRange($_SERVER['REMOTE_ADDR']))
    echo 'Ich muss nicht in die Statistik rein';

Mit dieser Funktion kann ich schon vorab selektieren und meine Statistiken nicht verfälschen. Es gibt noch eine Möglichkeit die IP in die CIDR umzuwandeln, doch die war für mich zu kompliziert um mit ihr weiter zu beschäftigen.
Natürlich kann jeder diese Liste für sich erweitern falls er noch Anbieter findet die in Massen ihn besuchen.

Pingen mit Zend_XmlRpc_Client

September 8, 2010

Wer Wordpress nutzt, kennt die Option Update Services. Dort werden URLs der Ping Dienste eingetragen um sie bei einem neuen Eintrag zu informieren. Ping wird benutzt um der Welt zu erzählen, dass man was neues auf der Seite hat. Das wollte ich in auch meinem CMS haben und schon kam die erste Schwierigkeit wie mache ich das, was ist genau Ping und wie funktioniert er. Gefunden hab ich viel über die XML Rpc Technologie, doch wie man sie für den Ping einsetzt und was man genau braucht, da hab ich nichts gefunden und wenn ich in 15 Minuten bei Google nichts finde bleibt mir nur eine Option übrig: Wordpress Quellcode aufmachen und das Tier suchen. Nach kurzer Zeit hab ich auch die Technik raus gefunden und sie mit Zend Framework umgesetzt.

Was brauch man? Natürlich den Zend_XmlRpc_Client und ein wichtiges Parameter weblogUpdates.ping Man instantiiert einen XmlRpc Client und lässt ihn mit den Parametern spazieren gehen.
Hier ein Beispiel:

1
2
3
$client = new Zend_XmlRpc_Client('http://blogsearch.google.de/ping/RPC2');
 
$client->call('weblogUpdates.ping', array('Alexander Zerr Blog Title', 'http://www.xelaz.de'));

Und schon hat man Google mitgeteil das er vorbei kommen soll um die neuen Inhalte zu indexieren.
Wie man mehrere Pings nutzt gebe ich einen Ansatz um es in eigener Seiten schnell einzubauen und los Pingen:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$result = array();
$error = array();
 
$pingList = array(
 'http://rpc.pingomatic.com/',
 'http://ping.wordblog.de/',
 'http://blogsearch.google.de/ping/RPC2',
 'http://xmlrpc.bloggernetz.de/RPC2',
 'http://ping.blogg.de',
 'http://xmlrpc.blogg.de',
 'http://rpc.bloggerei.de/ping/'
);
 
$title = 'Titel meiner Seite';
$link = 'http://www.urlmeinerseite.de';
 
foreach($pingList as $l) {
 $client = new Zend_XmlRpc_Client($l);
 try {
  $result[] = array('ping' => $l, 'result' => $client->call('weblogUpdates.ping', array($title, $link)));
 }
 catch(Zend_Exception $e) {
  $error[] = array('ping'=> $l, 'error'=> 'Unable to Connect','message'=>$e->getMessage());
 }
 catch (Zend_XmlRpc_Client_HttpException $e) {
  $error[] = array('ping'=> $l,'error'=>$e->getCode(),'message'=>$e->getMessage());
 }
}
echo 'Ergebnis:';
var_dump($result);
echo '<br>-------------<br><br>';
echo 'Fehler:';
var_dump($error);
echo '-------------';

Dieser Schnippsel reich um seinen Eigenen Ping zu entwickeln.
Ich hab natürlich nur eine kleine Liste der Dienste die für den Deutschen Markt brauchbar ist und dir mir komplett reichen. Im Netz kann man lange Listen der Ping Dienste finden die auch mehr für den Englischen Markt zu gebrauchen sind.