Всего 123 787 комментариев

Виталий Воропаев
27 декабря 2012, 16:10
1
0
Делал не давно.
Получился след. плагин:

Условия:
1) Наличие jQuery

Принцип работы:

  • Копирует ссылку из атрибута href
  • Генерирует из полученной ссылки iframe
  • Вставляет iframe в конец DOM
  • Инициирует печать

Плагин имеет ряд настроек и 2 callback функции. Сопровождается информером, который срабатывает перед печатью. Плагин нуждается в доработке, но увы нет времени.

Код плагина:

/*
 *   Name: SetPrint 0.5
 *   Dev: Voropaev Vitaliy
 */

;(function(g) {

var Print = function(options) {
	
	this._Defaults = {
		attr : "href"
		, url : false
		, message: {
			wait: "Подождите пожалуйста, идет подготовка к печати ..."
			, done: "Готово к печати"
		}
		, container_if : "b-iframe-print"
		, container_bl: "b-print-box"
		, delay: 700
		
	};
	
	options = g.extend({}, this._Defaults, options ? options : {}); 
	
	this._Elem = options.elem;
	this._Param = options;
	this._Url = false;
	this._Container = {};
	
	this.init();

}

Print.prototype = {
	
	init: function() {
		
		var th = this;
		
		this._Elem.bind("click", function(e) {
			th.load_print_document(th, e);
		});
		
	}
	, load_print_document: function(th, e) {
		
		e.preventDefault();
		
		if( typeof this._Param.beforeInit === "function" ) this._Param.beforeInit( this );
		
		g("body").append( this.message_box(this) );
		
		this._Container.block = g("#" + this._Param.container_bl)

		this._Container.block.css("opacity", 0);
		this._Container.block.animate({opacity:1}, this._Param.delay, function() {
			th.add_iframe_to_page(th);
		});
	}
	, add_iframe_to_page: function(th) {

		this._Url = this._Param.url ? this._Param.url : this._Elem.attr( this._Param.attr );
		
		if( typeof (this._Container.iframe) === "undefined" ) {
			
			g("body").append( this.iframe(th) );
			
			this._Container.iframe = g("#" + this._Param.container_if);
		
			this._Container.iframe.bind("load", function() {
				setTimeout(function() {
					th.printit(th);
				}, 2000)
				
			});
			
		} else {
			this._Container.iframe.attr("src", this._Url);
		}
	}
	, printit: function(th) {
		
		this._Container.iframe.text( this._Param.message.done );
		
		frames[ this._Param.container_if ].focus();
		frames[ this._Param.container_if ].print();
		
		this.message_box_unload();
		
	}
	, iframe: function(th) {
		
		return '<iframe id="' + th._Param.container_if + '" name="' + th._Param.container_if + '" src=' + th._Url + ' style="position:absolute;top:0px;left:0px;width:0px;height:0px;border:0px;overflow:none;z-index:-1"></iframe>';
	}
	, message_box: function(th) {
		
		return "<div id=" + th._Param.container_bl + " style='position:fixed;top:50%;left:50%;z-index:9999;opacity:0;'><span>\
		" + th._Param.message.wait + "</span></div>";
	
	}
	, iframe_unload: function() {
		this._Container.iframe.remove();
	}
	, message_box_unload: function () {
		
		this._Container.block.animate({opacity: 0}, this._Param.delay, function() {
			g(this).remove();
		});
                
                if( typeof this._Param.afterInit === "function" ) this._Param.afterInit( this );
		
	}
	, print_block_constructor: {
		
		add: function(th, callback) {
			
			var chr = {};
			    chr.w = th._Elem.parent().outerWidth(),
			    chr.h = th._Elem.parent().outerHeight();
			
			th._Elem.parent().css("position", "relative");
			th._Elem.addClass("block");
			th._Elem.after('<div style="position: absolute; top: 0px; left: 0px; height: 100%; width: 100%; z-index: 100"></div>');
			
			if( typeof callback === "function" ) callback();
			
		}
		, remove: function(th) {
			
			th._Elem.removeClass("block");
			th._Elem.next().remove();
		}
	}
}

})(jQuery);


Пример инициализации:

1) Html:

<a href="Страница для печати (ресурс в Modx)" class="print"></a>

2) JavaScript:

$(function() {
    
    p = new Print({
        elem: $(".print") 
        , beforeInit: function() {
            // Вызов callback функции, срабатывает перед генерацией DOM
        }
        , afterInit: function() {
            // Вызов callback функции, срабатывает после закрытия окна печати
        }
    });
    
});
3) Css:

(вырезано оформление)

<style type="text/css">
 #b-print-box{margin-top: -50px; margin-left: -150px; width: 300px; height: 100px; text-align: center; }
 #b-print-box span{font-size: 100%}
</style>
Yan Alex
27 декабря 2012, 15:52
0
После

$modx->resource->set('nodeShop_orderState', null);
$modx->resource->set('nodeShop_orderData', null);
Тв сразу же актуальны.
Yan Alex
27 декабря 2012, 15:51
0
В моем случае помогло вот такое ваше решение.

$modx->resource->set('nodeShop_orderState', null);
		$modx->resource->set('nodeShop_orderData', null);

		$result = array(
			$this -> resource -> setTVValue('nodeShop_orderState', json_encode($orderState)),
			$this -> resource -> setTVValue('nodeShop_orderData', json_encode($orderData))
		);

		if(array_sum($result) != 2) return;
Yan Alex
27 декабря 2012, 15:42
0
Блин, да это мой косяк, извиняюсь, глаз замылился, действительно это атрибут на время выполнения скрипта. Видимо Боб до сих пор мучается =)
Василий Наумкин
27 декабря 2012, 15:36
0
Да. Приходить должно в любом случае, хотя бы с одной темой, без тела письма.

Если не приходит вообще — разбирайтесь с почтой, может спаморезка не пускает, или еще что.
Василий Наумкин
27 декабря 2012, 15:34
0
Тогда, я бы попробовал плагином на OnWebPageInit или OnLoadWebDocument менять шаблон ресурса при его загрузке.

Реагировать можно на параметр в $_GET;
Василий Наумкин
27 декабря 2012, 15:31
0
Ну — щас через админку смотрел, не сохраняется.

Хотя, уже ничему не удивлюсь =)
Василий Наумкин
27 декабря 2012, 15:29
0
А как сохранить новое значение в ТВ?

$modx->resource->save() не помогает, конечно. А если значение нужно только на время работы скрипта, и сохранять его не надо — то и ТВ ни к чему, можно любое имя написать.
Yan Alex
27 декабря 2012, 15:26
0
Странно я проверял, потому что тоже думал что будет во время выполнения скрипта, и у меня писалось, то есть сперва я выставлял через сет а потом брал через гет закомментировав сет и у меня все показывалось как будто значение сохранилось.
Василий Наумкин
27 декабря 2012, 15:23
0
У меня оно и не сохраняется.

Это поле будет работать только во время выполнения скрипта. То есть, методом set мы выставляем любое поле с любым значением, потом можем его использовать как хотим, а после работы оно пропадает — ибо сохранить его некуда, в модели то его нет.

Если же ничего туда не писать, а просто print_r($modx->resource->get('test')); — то будут данные ТВ параметра.

Всё это очень интересно, но мне надо работать, так что не буду копать «почему всё именно так, а не иначе». Вообще, стараюсь не использовать ТВ, если это возможно.
Andrey Grachov
27 декабря 2012, 15:16
0
Чуть выше привел более эстетичное решение. Какое бы оно некрасивое не было, без него страница не увидит новое значения tv-параметра, если оно будет изменено, к примеру, сниппетом :)
Yan Alex
27 декабря 2012, 15:16
0
Хороший хак, спасибо, это позволит не уходить от стандартного АПИ модэкса, но как говорил Безумкин — выглядит не очень красиво, но думаю да и Х* с ним, хотя я сам тот еще эстет в этом плане )
Yan Alex
27 декабря 2012, 15:14
0
Вот и я так думал пока не залз в БД и не увидел что там НЕТ этого значения =). Что то огонь какой то с этим API у них.
Andrey Grachov
27 декабря 2012, 15:13
0
После этой строки вашего первоначального кода:
$modx->resource->setTVValue(11, 1);
надо добавить
$modx->resource->set('tv_name', null);
или
$tv = $modx->resource->get('tv_name');
if (is_array($tv)) {
	$tv[1] = 1;
	$modx->resource->set('tv_name', $tv);
}
где tv_name — имя tv-параметра с id равным 11. Это позволит дальше на странице использовать новое значение tv-параметра, если оно необходимо.
Василий Наумкин
27 декабря 2012, 15:12
0
Судя по тому, что пишет Боб Рей — оно сохраняется в ТВ, а не в объект.
Василий Наумкин
27 декабря 2012, 15:09
0
Да, так и есть. А выводит он 22 потому, что 2 было сохранено в прошлый раз.
Если по очереди комментировать вызовы setTVValue — хорошо видно.

А ваш хак отлично работает, хоть и выглядит это некрасиво.
if ($res = $modx->getObject('modResource', $modx->resource->id)) {
	$modx->resource->set('test', null);
	$res->setTVValue(1, 1);
	echo $res->getTVValue(1);

	$modx->resource->set('test', null);
	$res->setTVValue(1, 2);
	echo $res->getTVValue(1);
	die;
//12
}
Denys Butenko
27 декабря 2012, 15:08
0
Попробуй сниппет вызывать плагином до рендера страницы
Yan Alex
27 декабря 2012, 15:06
0
А можно полный код, а то я не понял к какому варианту применимо.
Yan Alex
27 декабря 2012, 15:04
0
Да да, первый вариант, как раз вызывается на той самой странице, которую должен обновить, второй вариант, глючит, а третий вот как раз ждал от вас, спасибки огромное, он работает! Как в воду глядел, хотел на чистом xPDO написать. Кстати я еще нашел такой вариант, учудил тип с форума
$modx->resource->set('SendTestEmail', $fields);
у него такая же проблема была Ссылка на ветку, главное что во первых работает, но во вторых непонятно где он хранит эти данные у объекта, облазив БД не нашел никаких значений даже близко, что думаешь об этом методе?
Andrey Grachov
27 декабря 2012, 15:00
0
В ходе обработки запроса modx загружает ресурс и все его tv-параметры, и потом при получении значений tv-параметров обращается к первоначальным данным. После установки нового значения надо выполнить что-то вроде:
$modx->resource->set('tv_name', null);