вторник, 30 июня 2009 г.

Почему disabled input элементы формы не передаются?

Сегодня столкнулся с одной особенностью INPUT элементов с атрибутом disabled. Как оказалось - они не передаются серверу при сабмите формы.
Вышел из положения вот таким изящным способом на jQuery:


$(function(){
$("form").submit(function(){
$("input").attr("disabled", ""); $("select").attr("disabled", "");
});
});

Таким образом, при действии submit у всех input и select элементов убирается атрибут disabled. Один минус - не работает при отключенных скриптах. Но в моём случае без JavaScript и jQuery не работает вообще всё приложение, так что это не так страшно.

четверг, 25 июня 2009 г.

jQuery Serialize - PHP like serialize function for JavaScript

ENG: I've addapted a JavaScript serialize function by Kevin van Zonneveld to jQuery. Function works like the same named function in PHP. Be free to use it in your projects. It is especially needed when you want to post Object in AJAX (in jQuery "$.ajax()").
RUS: Я адаптировал JavaScript serialize функцию, написанную Kevin van Zonneveld, для использования с jQuery. Serialize работает также как и одноименная функция в PHP. Она хорошо выручит Вас, если Вы захотите передать в AJAX запросе Объект (JavaScript object).

Example of using: $.serialize({data: 'value'});

Source code(UPDATE-1):

jQuery.extend({
serialize: function ( mixed_value ) {
// Returns a string representation of variable (which can later be unserialized)
//
// version: 906.1807
// discuss at: http://phpjs.org/functions/serialize
// + original by: Arpad Ray (mailto:arpad@php.net)
// + improved by: Dino
// + bugfixed by: Andrej Pavlovic
// + bugfixed by: Garagoth
// + input by: DtTvB (http://dt.in.th/2008-09-16.string-length-in-bytes.html)
// + bugfixed by: Russell Walker (http://www.nbill.co.uk/)
// % note: We feel the main purpose of this function should be to ease the transport of data between php & js
// % note: Aiming for PHP-compatibility, we have to translate objects to arrays
// * example 1: serialize(['Kevin', 'van', 'Zonneveld']);
// * returns 1: 'a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}'
// * example 2: serialize({firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'});
// * returns 2: 'a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}'
var _getType = function( inp ) {
var type = typeof inp, match;
var key;
if (type == 'object' && !inp) {
return 'null';
}
if (type == "object") {
if (!inp.constructor) {
return 'object';
}
var cons = inp.constructor.toString();
match = cons.match(/(\w+)\(/);
if (match) {
cons = match[1].toLowerCase();
}
var types = ["boolean", "number", "string", "array"];
for (key in types) {
if (cons == types[key]) {
type = types[key];
break;
}
}
}
return type;
};
var type = _getType(mixed_value);
var val, ktype = '';

switch (type) {
case "function":
val = "";
break;
case "boolean":
val = "b:" + (mixed_value ? "1" : "0");
break;
case "number":
val = (Math.round(mixed_value) == mixed_value ? "i" : "d") + ":" + mixed_value;
break;
case "string":
val = "s:" + encodeURIComponent(mixed_value).replace(/%../g, 'x').length + ":\"" + mixed_value + "\"";
break;
case "array":
case "object":
val = "a";
/*
if (type == "object") {
var objname = mixed_value.constructor.toString().match(/(\w+)\(\)/);
if (objname == undefined) {
return;
}
objname[1] = serialize(objname[1]);
val = "O" + objname[1].substring(1, objname[1].length - 1);
}
*/
var count = 0;
var vals = "";
var okey;
var key;
for (key in mixed_value) {
ktype = _getType(mixed_value[key]);
if (ktype == "function") {
continue;
}

okey = (key.match(/^[0-9]+$/) ? parseInt(key, 10) : key);
vals += $.serialize(okey) +
$.serialize(mixed_value[key]);
count++;
}
val += ":" + count + ":{" + vals + "}";
break;
case "undefined": // Fall-through
default: // if the JS object has a property which contains a null value, the string cannot be unserialized by PHP
val = "N";
break;
}
if (type != "object" && type != "array") {
val += ";";
}
return val;
}
});

UPDATES:
#1 - Patched version for working correctly with null, undefined values, subobjects.


NJoy

среда, 24 июня 2009 г.

Яндекс.Метрика - Демография - DailySnap

Установил себе на сайт бета версию счетчика Яндекс.Метрика. Сегодня покопавшись, нашёл интересную страничку.
Как Яндекс определяет пол и возраст посетителей?
Кликабельно


Интересно, Как Яндекс определяет пол и возраст посетителей?

пятница, 29 мая 2009 г.

Yii - создание своих типов Action-ов

Пишу одно прлиожение на Yii Framework. Структура приложения такова, что необходимо разграничить экшены контроллеров(CController) по папкам и сделать их типовыми.
Экшены разграничиваются легко.
Предположим, что у нас есть ряд экшенов для администрирования. Всем им надо установить какие-либо свойства или же сделать при их вызове какие-то типовые действия.
Рассмотрим на примере изменения титла страницы.
Вот код моего базового экшена:
[code]
class dotPlantAdminAction extends CAction
{
     /**
      * Constructor.
      * Runs CAction constructor and makes some changes for Admin action type
      */
     public function  __construct($controller,$id)
     {
     parent::__construct($controller,$id);
         $this->controller->pageTitle       = dotPlant::getName() . " - Admin ";
        
     }    
     
     public function run()
     {
       
     }
}

[/code]

В конструкторе мы сначала вызываем parent::__construct с необходимыми параметрами. Это грубо-говоря идёт инициализация базового CAction.

Допустим у нас есть контроллер SettingsController. И нам нужно сделать его на основе нашего экшена. Создаем папку  protected/controllers/Settings/. В ней создаем файл ActionAdmin.php с таким вот кодом:
[code]

class ActionAdmin extends dotPlantAdminAction

{

    public function run()

    {

    $this->controller->render('admin');    

    }

}

[/code]

Видите? Нам достаточно только объявить run() и уже всё готово. При загрузке запустится необходимый нам конструктор базового контроллера с нашими действиями.

Вот по такому принципу я разграничиваю например админку в своей CMS dotPlant на Yii Framework. Слава PHP пятому!

вторник, 19 мая 2009 г.

Вечерне-утренний обход

С недавнего времени я работаю в новой компании. Для консперации буду называть её DDD.
Компания не маленькая, весьма интересная и как полагается, со своими особенностями.
Утро каждого работника начинается с обходняка по кабинету всех уже пришедших, дабы одарить их своим теплым рукопожатием.
День проходит весьма однообразно. Сидишь, работаешь, пьешь чай/кофе/что-либо-другое и заедаешь печеньками/вафлями/зефиром/чем-либо-ещё.
И вот приходит вечер и ты из последних сил с львиным желанием побыстрее пойти по своим делам делаешь очередной обходняк.
Порой складывается ощущение, что никому из сидящих это не так уж и критически необходимо, ибо все заняты своими делами, ну или пытаются себя ими занять.

На днях, пришел в DDD новый веб-программист - Леонидий. Обычный интеллегент с красным носом, постоянно просящий ему что-то объяснить или помочь.
В первый же день ему поставили Ubuntu Linux. Через пару часов веб-программист Леонидий его убил вместе с винчестером. Весь оставшийся день Леонидий провёл в чтении достояния DDD - различной литературы, дабы расширить своё "я и так всё знаю" видимо до уровня "АААа! Точно! Как же это я?!".
На следующий день плотность заполнения его мозга новыми знаниями увеличилась до предела и под напором длительного отсутствия общения с компьютером Леонидий отправился домой.

Сегодня - день третий. Леонидий получил новый комп с новой системой. Пару раз прибегал с просьбой поставить ему Gimp и *программу для PHP*. На данный момент всё *вроде бы* без проишествий...

... И все снова в ожидании обходняка!

четверг, 26 марта 2009 г.

Как легально увеличить количество сайтов на хостинге

Здравствуйте. Вот решил поделиться легальным способом обхода ограничений на количество сайтов на хостинге.


Всё что нужно - иметь хостинг хотя бы на один сайт и возможность создавать несколько(или даже неограниченное количество) алиасов для сайта.


Метод основывается на возможностях mod_rewrite Apache.


Вот пример .htaccess файла:


RewriteEngine on

# Главный узел
RewriteCond %{HTTP_HOST} ^mysite\.ru$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# Допустим тут всё перенаправляется на index.php
RewriteRule . index.php

RewriteCond %{HTTP_HOST} ^example\.ru$
RewriteCond %{REQUEST_URI} !^/example\.ru/
RewriteRule (.*) /example\.ru/$1

Таким образом, в главной папке нашего сайта лежит содержимое mysite.ru. В этой же папке есть папка example.ru, в которой находится содержимое второго сайта.


Такой метод прошёл на Хостинге "ТаймВэб". К примеру, там можно взять минимальный хостинг на 2 сайта стоимостью всего 120 руб./мес., объемом дискового пространства 1000 Мб и радоваться жизни!


PS: А хостинг, кстати, хороший. Рекомендую!