AJAX навигация по меткам

Итак задача, нужно сохранять состояние страницы после ajax запроса. Для этого приспособили метки у ссылок, URL будет вот такого вида http://site.ru/#/key:val/key1:val1/keyN:valN/

В js далеко не гуру, но все работает и нативно.

var Navigation = function()
{
this.isHash = function(){return (window.location.href.indexOf('#') !== -1 && window.location.hash.length > 1);};

/**
* Возвращает все параметры из url в виде объекта
*/
this.getQueryParams = function(){
if(this.isHash())
{
var _ar = window.location.hash.replace('#', '').split('/');
var _ob = {};

for(var i=0; i < _ar.length; i++){
if(_ar[i] !== "")
_ob[i] = _ar[i];
}

var returnObject = {};
for(var j in _ob){

if (_ob.hasOwnProperty(j)) {
var _ar_params = _ob[j].split(':');
returnObject[_ar_params[0]] = _ar_params[1];
}
}

return returnObject;
}

return false;
};

/**
* Устанавливает строку параметров, если есть сотрет что было
*/
this.setHash = function(objectParsms){

var ar = [], j = 0;
for(var i in objectParsms){
j++; ar[j] = i + ':' + objectParsms[i];
}

var hashString = ar.join('/');

if(hashString.length > 0)
window.location.hash = '#' + hashString + '/';
};

this._isEmptyObject = function(Obj)
{
var i = 0;
for(var o in Obj){
i++;
}

return i;
};

this._isKeyObject = function(obj, key){

for(var o in obj)
{
if(o === key)
return true;
}

return false;
};

/**
* Добавляет параметр в url, если параметр уже есть то заменит значение на новое
*/
this.addHashParam = function(objectParams){

if(this.isHash())
{
var params = this.getQueryParams();

for(var o in objectParams){
if(this._isKeyObject(params, o)){
params[o] = objectParams[o];
}
}

var arRes = [], k = 0;
for(var or in params){
k++;arRes[k] = or + ':' + params[or];
}

var str_hash = arRes.join('/');

var ar = [], j = 0;
for(var i in objectParams){
if(!this._isKeyObject(params, i)){
j++; ar[j] = i + ':' + objectParams[i];
}
}

if(ar.length > 0){
str_hash += ar.join('/') + '/';
}
else{
str_hash += '/';
}

window.location.hash = str_hash;
}
else
{
this.setHash(objectParams);
}
};

/**
* Удаляет параметр из url можно указывать несколько, принимает массив ключей
*/
this.delHashParams = function(arParams){
if(this.isHash())
{
var params = this.getQueryParams();

for(var a = 0; a <= arParams.length; a++){
delete params[arParams[a]];
}

if(this._isEmptyObject(params) > 0)
this.setHash(params);
else
window.location.hash = '';
};
};
};

Делать такую навигацию весьма трудоемко, но позволяет немного шире использовать ajax.

Предзагрузка изображений js [snippets]

2 рабочие функции для пред загрузки картинок, нативная и jQuery.

	

function preload(images) {
   if (typeof document.body == "undefined") return;
 	    try {

 	        var div = document.createElement("div");
 	        var s = div.style;
 	            s.position = "absolute";
 	        s.top = s.left = 0;
 	        s.visibility = "hidden";
 	        document.body.appendChild(div);
         div.innerHTML = "";
 	        var lastImg = div.lastChild;
 	        lastImg.onload = function() { document.body.removeChild(document.body.lastChild); };
 	     }
 	     catch(e) {
 	        // Error. Do nothing.
     }
 	}
 	});

	jQuery.preloadImages = function () {
	    var images = (typeof arguments[0] == 'object') ? arguments[0] : arguments;
	    for (var i = 0; i < images.length; i++) {
	        jQuery("").attr("src", images[i]);
	    }
	}

Найдено на просторах.
http://clip2net.com/clip/m11386/1304961837-clip-11kb.png

Конвертер валют для Bitrix [php, js]

Конвертер валют Битрикс

Конвертер валют Битрикс

Я редко что-то выкладываю готовое, но вот просто захотелось. Я не жадный, просто нет времени. Итак задача была сделать конвертер на js, для этого нам нужно иметь данные для подсчета, принципиально не захотел делать пересчет на аяксе так как это был бы не совсем js конвертер. Вариантов получения данных несколько, вот как сделал я.

В битриксе есть модуль «Валюты» он нам нужен для back-end нашего конвертера. Для автоматического обновления есть скрипт который обновляет курс, его можно запускать кроном или агентом, я выбрал крон. Там же в модуле валюты есть список курсов, с названиями и значениями курса по умолчанию, по большому счету нам нужны только названия валют оттуда. Его пришлось собирать ручками, по этому в архиве положу csv файл, загрузите его сами. Теперь когда back-end готов можно перейти к компоненту.

Компонент обрабатывает данные из модуля, он должен быть постоянно кэшированным так как при вычислении коэффициента для каждой валюты, создается большой кол-во запросов, благо они мелкие и легкие. Кэш компонента очищается при отработки скрипта на кроне, в коде это можно найти. Логика компонента возвращает 2 json объекта с которыми мы в дальнейшем работаем в шаблоне. В общем смотрим что получилось, улучшать там есть что, буду раз замечаниям.

Скачать архив

В папке cron скрипт для пересчета валюты, в flag флаги, их нужно положить в upload или поправить пути. Не забудьте подключить jQuery.

 

Send mail with attachment php

function XMailAttach($from, $to, $subj, $text, $ar_File)  
{  
	$un        = strtoupper(uniqid(time()));  
	$head      = "From: $from\n";  
	$head     .= "To: $to\n";  
	$head     .= "Subject: $subj\n";  
	$head     .= "X-Mailer: PHPMail Tool\n";  
	$head     .= "Reply-To: $from\n";  
	$head     .= "Mime-Version: 1.0\n";  
	$head     .= "Content-Type:multipart/mixed;";  
	$head     .= "boundary=\"----------".$un."\"\n\n";  
	$zag       = "------------".$un."\nContent-Type:text/html;\n";  
	$zag      .= "Content-Transfer-Encoding: 8bit\n\n$text\n\n";  
								 
	foreach ($ar_File as $file)
	{
		$f         = fopen($file, "rb");  
		$zag      .= "------------".$un."\n";  
		$zag      .= "Content-Type: application/octet-stream;";  
		$zag      .= "name=\"".basename($file)."\"\n";  
		$zag      .= "Content-Transfer-Encoding:base64\n";  
		$zag      .= "Content-Disposition:attachment;";  
		$zag      .= "filename=\"".basename($file)."\"\n\n";  
		$zag      .= chunk_split(base64_encode(fread($f,filesize($file))))."\n";  
	}
								 
	if (!mail($to, $subj, $zag, $head))  
	 	return false;  
	else  
		return true;  
}

Сколько лет пользователю сайта?

Немного лениво выглядит профиль пользователя на сайте, когда вместо надписи о количестве лет выводится дата его рождения. Снипед, для Битрикса, жаль что нету API функции.

if(strlen($ar_UserCabinet['PERSONAL_BIRTHDAY']) > 0)
{
	$ar_UserDateTo  = explode('.', $ar_UserCabinet['PERSONAL_BIRTHDAY']);
	$s_MetaDateTo   = mktime(0, 0, 0, $ar_UserDateTo[1], $ar_UserDateTo[0], $ar_UserDateTo[2]);
	$s_MetaDateFrom = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
	$i_Meta = ($s_MetaDateFrom - $s_MetaDateTo) / 31276800;

	# проверим был ли у пользователя день рождения, если еще небыло то -1
	$s_DateRog = mktime(0, 0, 0, $ar_UserDateTo[1], $ar_UserDateTo[0], date('Y'));
	if($s_DateRog > $s_MetaDateFrom)
		$i_Meta -= 1;

	$arResult['USER_BIRTHDAY'] = intval($i_Meta);
}

Немного о bash

По умолчанию команды сохраняются после закрытия терминала, причем файл не дописывается, а переписывается, чтобы это исправить нужно в файл ~/.bashrc добавить:

shopt -s histappend
PROMPT_COMMAND='history -a'

bash попытается исправить неправильный пусть указанный в команде cd если прописать в тот же файл это:

shopt -s cdspell

Можно запретить писать в историю подряд идущие одинаковые команды:

export HISTCONTROL="ignoredups"

Заперт логирования команд:

export HISTIGNORE="&:ls:[bf]g:exit"

Не разрывать многострочные команды:

shopt -s cmdhist

Перед командой можно писать дату ее выполнения:

export HISTTIMEFORMAT='%h %d %H:%M:%S '

оригинал статьи

Вывод в заголовок диапазона элементов [c 10 по 20]

Задача, вывести в пагинацию и в заголовок диапазон в котором находится пользователь в текущий момент т.е.  в конец добавлять текущую позицию в списке,  список [c 10 по 20]

Вот наброски кода который решает эту задачу $rs_Element объект типа arResult

if(is_array($ar_Navigatonparams))
{
    $ar_NavParams = array(
        'NavPageNomer'    => $rs_Element->NavPageNomer,
        'NavPageSize'     => $rs_Element->NavPageSize,
        'NavRecordCount'  => $rs_Element->NavRecordCount,
        'nEndPage'        => $rs_Element->nEndPage
    );

    function navigationIntervalList($ar_NavParams)
    {
        if(isset($_REQUEST['PAGEN_1']) && intval($_REQUEST['PAGEN_1']) > 0)
        {
            if(intval($ar_NavParams['NavPageNomer'])  > 1)
            {
                $_s = ($ar_NavParams['NavPageNomer'] * $ar_NavParams['NavPageSize']) - $ar_NavParams['NavPageSize'] + 1;
                $_p = $ar_NavParams['NavPageNomer'] * $ar_NavParams['NavPageSize'];

                if($ar_NavParams['nEndPage'] == $ar_NavParams['NavPageNomer'])
                    $_p = $ar_NavParams['NavRecordCount'];

                return 'список с '.$_s.' по '.$_p;
            }
        }
    }

    $s_nav = navigationIntervalList($ar_NavParams);
    $s_Nav = (!empty($s_nav)) ? ' / '.$s_nav : '';
    $s_Tit = (!empty($s_nav)) ? ', '.$s_nav : '';

    $APPLICATION->AddChainItem($s_TitleNavchain.$s_Nav);
    $APPLICATION->SetTitle($s_TitleNavchain.$s_Tit);
}

Python. Самое необходимое [книга]

Последнее время меня потянуло на что-то новое и я решил поковырять питон. Для этой благой цели я прикупил на озоне книжку  Python. Самое необходимое (+ DVD-ROM).

Как книжка, расскажу как прочитаю, брал специально чтобы получить базовые знания, а там видно будет что с ним делать.

GNOME Commander, не запонимает ftp/ssh аккаунты?

Очень достойная замена Total Commander это GNOME Commander, но есть одна ошибка в нем которая легко обходится. Когда вы добавляете новое соединение ftp или ssh и по каким либо причинам программа падает, то соединение не сохраняется, по этому чтобы не добавлять постоянно одно и тоже соединения добавьте его и перезагрузите Commander. Может это старая версия, но этот способ на ней работает gnome-commander 1.2.8.2, в новой возможно уже и поправили.