Symfony2 Formlarini Ozellestirmek ve Bootstrap CSS

Hazırladığım bir projede Symfony2 formlarını özelleştirerek Bootstrap CSS ile entegre etmek istedim. Bunu başarmak için tabii ki Symfony2’de bir formül var: Form Themes. Symfony2 ile oluşturulan formlardaki tüm elemanların formatlarının tutulduğu bir dosya bulunuyor. Bu formatlarda istediğimiz gibi değişiklik yaparak, örneğin <div> tag’leri ekleyerek ve ya sınıflar atayarak Bootstrap ile uyumlu hale getirebiliyoruz.

Bu yazıda Bootstrap CSS’in detayından bahsetmeyeceğim, fakat genel olarak ön yüz tasarımcılarının işini kolaylaştıran, daha da önemlisi yazılım geliştiricileri tasarım yapmaktan kurtaran bir CSS framework’u olduğunu söyleyebiliriz. Twitter tarafından tasarlanan bu framework, kullanım kolaylığı, tarayıcılarla uyumu ve estetik güzellik gibi çok iyi özelliklere sahip.

Boostrap Kurulumu

Öncelikle Bootstrap CSS indirip uygulamamıza dahil edelim. Şu adresten Bootstrap için gerekli dosyaları indirdikten sonra web klasörü altına açıyoruz. Daha sonra kullandığımız layout içerisinde bootstrap için gerekli dosyaları dahil ediyoruz.

# app/Resources/views/base.html.twig
<head><link href="{{ asset('css/bootstrap.min.css') }}" rel="stylesheet"></head>
<body>
<script type="text/javascript" src="{{ asset('js/bootstrap.min.js') }}"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script></body>

Bootstrap ile birlikte kullanabileceğiniz bazı javascript eklentileri de bulunuyor, bunlar jQuery gerektirdiğinden bu kütüphaneyi de dahil ediyoruz.

Symfony2 Formlarını Özelleştirmek

Symfony2’de oluşturduğumuz formları sayfada gösterirken bazı fonksiyonlar kullanıyoruz. Örneğin integer tipinde bir alanı integer_widget metodundan faydalanıyoruz. Fakat oluşan çıktının formatını değiştirmek istersek, iki yöntem kullanabiliriz. Birisi sadece ilgili fom için bu metodun çıktısını değiştirmek. Bu her ne kadar daha basit gibi görünse de, aynı işleme başka yerde ihtiyacımız olduğunda eziyet olacaktır. Bu yüzden bu yönteme ek olarak tüm formlarda bir metodun çıktısını değiştirmek için de bir yöntem bulunuyor.

Önce sadece ilgili formda form_row metodunu değiştirelim:

#src\Dubluve\NewBundle\Default\new.html.twig
{% extends '::base.html.twig' %}
{% form_theme form _self %}
{% block form_row %}
{% spaceless %}
    <div class="control-group">
        {{ form_label(form) }}
        {{ form_errors(form) }}
        <div class="controls">{{ form_widget(form) }}</div>
    </div>
  {% endspaceless %}
{% endblock form_row %}
{% block content %}
    {{ form_row(form.email) }}
{% endblock %}

Bu sayfada kullanılan form için form_row metodu farklı bir çıktı oluşturacak, fakat diğer sayfalardaki formlar için çıktı aynı olacaktır.

Eğer bu değişikliğin tüm formlar için geçerli olmasını istiyorsak kendi formatlarımızın bulunduğu bir dosya oluşturmamız gerekiyor. Yeni dosyada çıktısını değiştirmek istediğimiz metodlar olacak, diğerleri ise eskisi gibi çıktı oluşturmaya devam edecek. Yeni dosyayı proje klasörü içerisinde src\Dubluve\NewBundle\Resources\views\Form\bootstrap.html.twig  dosyasını yaratıyoruz.

#src\Dubluve\NewBundle\Resources\views\Form\bootstrap.html.twig
{% extends 'form_div_layout.html.twig' %}
 {% block form_row %}
{% spaceless %}
    <div>
        {{ form_label(form) }}
        {{ form_errors(form) }}
        <div>{{ form_widget(form) }}</div>
    </div>
  {% endspaceless %}
{% endblock form_row %}

Dosyadaki extends ifadesi, form_div_layout.html.twig dosyasını baz aldığımızı belirtiyor. Dolayısıyla değiştirilmeyen form elemanları form_div_layout.html.twig dosyasındaki gibi kalacaktır. Yeni dosyayı  oluşturduktan sonra config.yml dosyasını da aşağıdaki şekilde güncelliyoruz ve bu dosyanın global olarak kullanılacağını belirtiyoruz.

# Twig Configuration
twig:
    form:
      resources:
        - 'DubluveNewBundle:Form:bootstrap.html.twig'

Bootstrap İle Entegrasyon

Yukarıdaki yöntemleri anlattıktan sonra aslında sadece bootstrap ile değil herhangi bir CSS framework ile entegrasyon oldukça basit. Aslında sadece bootstrap dosyalarını sisteme entegre etmek bile güzel bir görünüm sağlıyor 🙂 Hazırladığım projede tüm formların bootstrap dokümantasyonunda anlatılan horizontal-form formatında olmasını ve hata mesajlarının bootstrap formatında çıkmasını istemiş ve dosyayı buna göre düzenlemiştim. Aşağıda kullandığım dosyayı görebilirsiniz.

#src\Dubluve\NewBundle\Resources\views\Form\bootstrap.html.twig
{% extends 'form_div_layout.html.twig' %}
{% block form_row %}
{% spaceless %}
{% if not form.children %}
<div class="control-group">
{{ form_label(form) }}
{{ form_errors(form) }}
<div class="controls">{{ form_widget(form) }}</div>
</div>
{% else %}
{{ form_errors(form) }}
{{ form_widget(form) }}
{% endif %}
{% endspaceless %}
{% endblock form_row %}
{% block form_label %}
{% spaceless %}
{% if not compound %}
{% set label_attr = label_attr|merge({'for': id}) %}
{% endif %}
{% if required %}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required control-label')|trim}) %}
{% endif %}
{% if label is empty %}
{% set label = name|humanize %}
{% endif %}
<label {% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %} >{{ label|trans({}, translation_domain) }}</label>
{% endspaceless %}
{% endblock form_label %}
{% block form_errors %}
{% spaceless %}
{% if errors|length > 0 %}
{% for error in errors %}
<div class="alert alert-error">{{
error.messagePluralization is null
? error.messageTemplate|trans(error.messageParameters, 'validators')
: error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'validators')
}}</div>
{% endfor %}
{% endif %}
{% endspaceless %}
{% endblock form_errors %}

jquery tarayıcı motorunu öğrenme

Bazı durumlarda , genelde tasarım ile ilgili konularda, kullanıcının browser’ına göre değişik gereksinimler oluşabilmektedir.
Bu özellikle internet explorer ile çok sıkça yaşanmaktadır. Bu sebeple browser bilgisini öğrenip buna göre işlem yaptıran bir çok css html veya javascript örneği bulabiliriz.

Yine de küçük bir örnek de biz verecek olursak ;

head taglarımızın arasında

< script src="http://code.jquery.com/jquery-latest.js">

yazıp jquery’yi include edelim.

Aşağıdaki kısmı body tagları arasına yerleştirirseniz, kod hatasız çalışacaktır.

< script>
    jQuery.each(jQuery.browser, function(i, val) {
      jQuery("
" + i + " : " + val +"").appendTo( document.body ); }); jQuery('Browser Ana Versiyonu : '+parseInt(jQuery.browser.version, 10)+'').appendTo(document.body); //jQuery('Browser Ana Versiyon : '+parseInt(jQuery.browser.version, 10)).appendTo(document.body); if ($.browser.webkit) { jQuery('
Browser Webkit desteklemektedir.').appendTo(document.body); }else{ jQuery('
Browser Webkit desteklememektedir.').appendTo(document.body); } < /script>

Veya aynısı $. diye yazılan hali

< script> $.each($.browser, function(i, val) { $("
" + i + " : " + val + "").appendTo( document.body ); }); $('Browser Ana Versiyonu : '+parseInt($.browser.version, 10)+'').appendTo(document.body); if ($.browser.webkit) { $('
Browser Webkit desteklemektedir.').appendTo(document.body); }else{ $('
Browser Webkit desteklememektedir.').appendTo(document.body); } < /script>

Not : Chrome için safari : true diye bir sonuç alınmakta. Bu noktada sizi jquerynin kendi sayfasına davet ediyorum, buyrunuz.

jQuery, AJAX and Internet Explorer

The issue:

Internet Explorer won’t parse XML quite as easily as every other browser on the internet (I assume). You have to change what you pass it as through jQuery. In IE it has to be passed as text, while the rest can handle it as XML. You also have to pass it through a separate function that brings in ActiveX before you can navigate your way through the XML and use it in your application.

The solution:

Set the type to “text” for IE and “xml” for the rest.

dataType: ($.browser.msie) ? "text" : "xml"

Use a function to “fix” the XML for IE

function parseXml(xml) {
 if (jQuery.browser.msie) {
    var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
    xmlDoc.loadXML(xml);
    xml = xmlDoc;

    }

 return xml;
}

Reference the function in your .ajax()

success: function(xml) {

var newXML = parseXml(xml);

$(newXML).find()....

here we go!

jquery.post internet explorer hata (error)

I want to make an ajax request to the URL which I am currently in. For that reason, I did not write the URL again and assign there “”.

But in internet explorer 9, if you make that empty like me, IE9 gives an error in jquery.js in line blabla.. (at the beginnig of the code, x=open(….. )

//the wrong one
jQuery.post("",{"AjaxRequest":1 ,"defaultParams":defaultParams,"searchParams":searchParams},function(responseText,status,response){
    //success doSomething
}

So rewrite your wrong code like this,

//the right one
jQuery.post("http://write.down.your.url.here?with=params",{"AjaxRequest":1 ,"defaultParams":defaultParams,"searchParams":searchParams},function(responseText,status,response){
    //success doSomething
}

That resolved my problem.
Some other errors can raise, but here it is not the post to write solutiouns to the other failures.