RSS

Links

On vacation till September 1st

Subj

jQuery: Novice to Ninja – what I’ve found useful

Recently I’ve read a book  jQuery: Novice to Ninja. I was using jQuery for a long time, however I felt that I was using only a small part of this library, so I decided to read some books about it. The books is rather good and easy (and interesting) to read. Here I want to write some jQuery’s tips that I didn’t know and want to store for the future.


//Selects all direct child elements specified by "child" of elements specified by "parent".
$('parent > child')

//Height toggling:
$('#bio h3').click(function(){
 $(this).next().animate(
{' height' : ' toggle' } , ' slow' , ' easeOutBounce'
 );}) ;

//Loads the selected element from AJAX result's html:
$('#biography' ).load('computadors. html div: first') ;

//Loading indicator that disappears when response comes:
$('#biography').html('loading…').load(url) ;

//Validate plugin is awesome!
$('#signup form').validate({
 rules: {
 name: {
 required: true
 }});

//Checks all checkboxes:
$('.check-all: checkbox').change(function(){
 var group = ':checkbox[name=' + $(this).attr('name') + ' ] ' ;
 $(group).attr('checked' , $(this).attr(' checked'));
}) ;

//Travers elements with an until-condition:
$('h2:first' ).nextUntil('h2') ;

//jQuery has map function!
$. map, $. slice, $. trim,

jQuery is a really great thing!

Auto trimming field value / Django forms

I don’t know why this is not done by default, but..


from django import forms

class TrimmedCharField(forms.CharField):
	def clean(self, value):
		return forms.CharField.clean(self, value.strip())

class Form1(forms.Form):
	f1 = TrimmedCharField(widget=forms.Textarea(attrs={'rows': 6}))
	f2= TrimmedCharField(widget=forms.Textarea(attrs={'rows': 6}))

django registration form custom field

In most cases when a user registers in your django application you need to know more than just user name, password and e-mail. To add custom fields to the registration form you should pass form_class parameter to the register view function – it’s easy, but saving additional data could be rather complex. There are solutions that show how to use a custom django registration backend –  http://stackoverflow.com/questions/2601487/django-registration-django-profile-using-your-own-custom-form or http://groups.google.com/group/django-users/browse_thread/thread/00389648750c5867/59eef5c315b47f9b?lnk=raot&pli=1. G! This is so complicated! Likely, django has signals that are sent during the registration process and we can use them – http://docs.b-list.org/django-registration/0.8/signals.html#signals (the version of the doc is 0.8, however, it works with 1.2). We need user_registered signal.

In my case I needed to add just one field to the registration form – user’s City.


from models import City
import strings
from registration.forms import RegistrationForm

class UserRegistrationForm(RegistrationForm):
    city = forms.ModelChoiceField(queryset=City.objects, label=strings.city, empty_label=strings.notDefined)

Then pass this form to the register view in urls.py – register records should go before (r’^accounts/’, include(regUrls)),


from registration.views import register
import registration.backends.default.urls as regUrls
import regbackend

urlpatterns = patterns('',
	url(r'^accounts/register/$', register, {'backend': 'registration.backends.default.DefaultBackend','form_class': UserRegistrationForm}, name='registration_register'),
	(r'^accounts/', include(regUrls)),
...
)

Now we need to add a subscription to the user_registered signal. Assume that we have a custom profile with city information:


# regbackend.py
import profile

def user_created(sender, user, request, **kwargs):
	form = UserRegistrationForm(request.POST)
	data = profile.Profile(user=user)
	data.city_id = form.data["city"]
	data.save()

from registration.signals import user_registered
user_registered.connect(user_created)

That’s it – much easier, right? :)

(Русский) gdestop.ru – подбор жилья для отдыха на курортах

Sorry, this entry is only available in Русский.

Draw an arrow on Google map

I wrote a simple javascript function that draws an arrow on a Google Map (based on http://wtp2.appspot.com/BdccArrowedPolyline.js):


function drawArrow(pt1, pt2, color)
{
	var lineWidth = 10;
	var lineOpacity = 0.7;
	var arrowSize = 50;

	function addHead(point, theta, zoom, color)
	{
		var p = prj.fromLatLngToPixel(point,  zoom)
		var x = p.x, y = p.y;
		var t = theta + (Math.PI/4) ;
		if(t > Math.PI)
			t -= 2*Math.PI;
		var t2 = theta - (Math.PI/4) ;
		if(t2 <= (-Math.PI))
			t2 += 2*Math.PI;
		var pts = new Array();
		var headLength = arrowSize;
		var x1 = x-Math.cos(t)*headLength;
		var y1 = y+Math.sin(t)*headLength;
		var x2 = x-Math.cos(t2)*headLength;
		var y2 = y+Math.sin(t2)*headLength;
		pts.push(prj.fromPixelToLatLng(new GPoint(x1,y1), zoom));
		pts.push(prj.fromPixelToLatLng(new GPoint(x,y), zoom));
		pts.push(prj.fromPixelToLatLng(new GPoint(x2,y2), zoom));
		var head = new GPolygon(pts, color, 0, 1, color, 1);
		map.addOverlay(head);
	}

	var polyline = new GPolyline([pt1, pt2], color, lineWidth, lineOpacity);
	var zoom = map.getZoom();
	var p1 = prj.fromLatLngToPixel(pt1,  zoom);
	var p2 = prj.fromLatLngToPixel(pt2,  zoom);
	var dx = p2.x-p1.x;
	var dy = p2.y-p1.y;
	var theta = Math.atan2(-dy,dx);

	addHead(pt2, theta, zoom, color);
	map.addOverlay(polyline);
}

Where pt1, pt2 are GLatLng instances, map is GMap2 and color is a string representation of color. Unfortunately, this function does not support map’s zooming – arrows heads grow bigger when zooming in.

The result looks like:
Читать далее: Draw an arrow on Google map

django add bitwise logics to the filter query

Django has a great ORM, but it has some limitations while performing queries, e.g. it does not allow to do bitwise operation. Likely, django’s QuerySet has extra method (http://docs.djangoproject.com/en/dev/ref/models/querysets/#extra-select-none-where-none-params-none-tables-none-order-by-none-select-params-none). This method allows developers to write raw sql that will be included into the generated by ORM query. The tricky part is that all fields included in that raw sql must present in filter function.
For example:


res.filter(table__flags__isnull=False).extra(where=['NOT ("applicationName_table"."flags" | %s <> "applicationName_table"."flags")' %  condition])

Here we have a datatable with name table with a mask field called flags and an application called applicationName. If there was not filter(table__flags__isnull=False) this query would fail with “applicationName_table”.”flags” is unknown column. I could write any lookup expression with this filed that does not affect the result (checking that this filed is not null is quite OK for that).

Hope, this will help you!

Твиттер – первые впечатления

Около месяца я активно использую твиттер и успел сформировать свое мнение о данном сервисе, коим и хочу поделиться.

Как я вышел на твиттер

На конференции i-Community, на которой я не был, но информации с нее так или иначе стала доступна, в частности упоминалось, что за последний год число русскоязычных пользователей твиттера возросло в десятки раз и на данный момент составляет примерно 200 тысяч пользователей (http://www.interfax.ru/society/news.asp?id=126437). Мне, как активному человеку, было бы глупо не посмотреть на так бурно развивающийся в рунете тренд. Надо сказать, что аккаунт на твиттере у меня был зарегистрирован давно, но пребывал в заброшенном состоянии.

Начало

Начал я с того, что зафолловил Константина Рыкова (http://twitter.com/rykov) – известного интернет-деятеля и политика, который в тот же день начал свой (очередной) уход из твиттера и вся лента была засорена обсасывванием этой темы.  Затем я прошелся по тем, кого фолловит Максим Спиридонов (http://twitter.com/MaximSpiridonov), подкасты которого я нахожу очень полезными и интересными. В общем, дня за 3 я сформировал свою ленту.

Что понравилось

  • Формат. Много говорилось про эти 140 символов и плохого и хорошего, но мне он однозначно подходит! Потому как не всегда нахожу время писать объемные посты в блог, а некоторые мысли хочется оставить где-то: твиттер для этого более чем приспособен.
  • Скорость.  Главные новости распространяются с очень большой скоростью – ретвитты рулят. Вчера во второй половине дня я поймал себя на том, что написал “Боян” на видео про русских, выражающихся про iPad, хотя узнал об этом сам только сутра.
  • Интересная информация. Некоторые пишут про действительно интересные вещи.
  • Новые контакты. Сама неформальная атмосфера твиттера позволяет создавать связи с людьми, с которыми в реальной жизни пересечься либо очень трудно, либо нереально.

Что не понравилось

  • Достаточно много спама – постоянно добавляются / удаляются аккаунты содержащие один спам.
  • Много мусора – некоторые очень дословно переводят “What’s happening?” и пишут всякую муть: “Поел”, “Поспал”, “Пошел в туалет”, “Выхожу на улицу” и т.п. Я уже и сам начал замечать у себя такие посты – так что периодически бью себя по рукам!

Чего я жду от твиттера

  • Мне как разработчику интересно привлечь новых пользователей на мои проекты и получить обратную связь от них. Однако, пока я не совсем понял, как в 140 символах объяснить, что это не спам, я не бот, а сам проект на данном этапе вообще некоммерческий. Соответственно, как только разберусь – напишу.
  • Знакомства с интересными людьми.

Продолжение следует..

Мой твиттер: http://twitter.com/dmitko

Why dmitko.ru was down

For almost the whole day this blog was down with fatal error Cannot allocate memory. After changing php.ini and setting memory_limit=32М instead of previous 8M the site became working.
Sorry for the inconvenience.

What’s new in my geo-tracking service

Recently there were several changes to my little sweet tracking service:)
1. It has been moved from http://1adg.ru to http://location.dmitko.ru/ – just check this out!
2. Now it has registration support – feel free to register!
3. Now it has new client for Windows mobile kindly developed by http://www.softexpanse.com – visit the download page for more information.