Page MenuHomeIn-Portal Phabricator

modern-store
No OneTemporary

File Metadata

Created
Sat, Feb 1, 11:47 AM

modern-store

Index: branches/1.0.x/inc/js/list_manager.js
===================================================================
--- branches/1.0.x/inc/js/list_manager.js (revision 14910)
+++ branches/1.0.x/inc/js/list_manager.js (revision 14911)
@@ -1,240 +1,257 @@
function ListManager() {}
ListManager.containerSelector = ''; // selector id of container
ListManager.url = ''; // url to template with list contents
ListManager.urlParams = {layout: 'list'};
ListManager.filters = {};
ListManager.xhrRequests = [];
ListManager.reloadTimer = null;
ListManager.reloadTimeout = 1000;
ListManager.firstLoad = true;
ListManager.getUrl = function () {
var $url = this.url;
}
ListManager.cancelXHRRequests = function () {
while ( this.xhrRequests.length > 0 ) {
this.xhrRequests.shift().abort();
}
}
ListManager.reload = function ($now) {
this.cancelXHRRequests();
if ( $now === undefined || $now === false ) {
this.updateAnchor();
return;
}
var $container = $(this.containerSelector);
$container.fadeTo('fast', 0.7);
var $request = $.post(
this.url,
this.urlParams,
function ($data) {
$container.html($data).fadeTo('fast', 1.0);
}
);
this.xhrRequests.push($request);
}
ListManager.scheduleReload = function () {
var $me = this;
clearTimeout(this.reloadTimer);
this.reloadTimer = setTimeout(function() { $me.reload(); }, this.reloadTimeout);
}
ListManager.setParam = function ($name, $value, $reload) {
if ( $value === undefined || $value === '' ) {
// don't pass empty parameters
delete this.urlParams[$name];
}
else {
this.urlParams[$name] = $value;
}
if ( $reload === true ) {
this.reload();
}
}
ListManager.getParam = function ($name) {
return this.urlParams[$name] !== undefined ? this.urlParams[$name] : false;
}
ListManager.updateAnchor = function () {
var $query_string = [],
$url_params = sort_object(this.urlParams);
for (var $param_name in $url_params) {
$query_string.push( $param_name + '=' + encodeURIComponent(this.urlParams[$param_name]) );
}
window.location.hash = '#' + $query_string.join('&');
}
ListManager.parseAnchor = function ($anchor) {
var $query_string = {};
$anchor.replace(
new RegExp('([^?=&]+)(=([^&]*))?', 'g'),
function($0, $1, $2, $3) {
$query_string[$1] = decodeURIComponent($3);
}
);
this.urlParams = $query_string;
// sync values from url params into empty filters on first page with anchor load
this.initFilters();
this.reload(true);
}
ListManager.registerFilter = function ($field) {
var $manager = this,
$form = $('#filter-form-' + $field);
$manager.filters[$field] = {'type': $form.attr('filter_type')};
$('h2:first a', $form).click(
function ($e) {
var $header = $(this).parent(),
$active = $header.hasClass('active');
$header.toggleClass('active', !$active);
$header.next().toggleClass('noactive', $active);
return false;
}
);
switch( $manager.filters[$field].type ) {
case 'radio':
$("input[type='radio']", $form).click(
function ($e) {
$manager.updateFilterParams();
}
);
break;
case 'checkbox':
$("input[type='checkbox']", $form).click(
function ($e) {
var $checkbox = $(this),
$hidden_id = $checkbox.attr('id').replace(/_([\d\w-=]|)+$/, ''),
$regexp = new RegExp(jq($hidden_id) + '_([\\d\\w-=]+)');
if ( $checkbox.val() == '' ) {
// "All" checkbox
$("input[type='checkbox']", $form).not($checkbox).attr('checked', false);
}
else if ( $checkbox.is(':checked') ) {
$("input[type='checkbox'][value='']", $form).attr('checked', false);
}
update_checkbox_options($regexp, $hidden_id, $form);
$manager.updateFilterParams();
}
);
break;
}
}
ListManager.initFilters = function () {
if ( !this.firstLoad ) {
return;
}
for (var $filter_field in this.filters) {
this.initFilter($filter_field);
}
this.firstLoad = false;
}
ListManager.initFilter = function ($field) {
var $values = '',
$form = $('#filter-form-' + $field),
$param_name = 'filters[' + $field + ']',
$param_value = this.getParam($param_name);
if ( $param_value === false || $param_value === '' ) {
return;
}
switch( this.filters[$field].type ) {
case 'radio':
$('#' + jq($param_name + '_' + $param_value) ).attr('checked', true);
break;
case 'checkbox':
$values = $param_value.substring(1, $param_value.length - 1).split('|');
for (var $i = 0; $i < $values.length; $i++) {
$('#' + jq($param_name + '_' + $values[$i]) ).attr('checked', true);
}
$('#' + jq($param_name + '_') ).attr('checked', false);
$('#' + jq($param_name) ).val($param_value);
break;
case 'range':
+ var $slider = $('#' + jq($param_name + '_slider') ),
+ $slider_options = {
+ min: $slider.slider('option', 'min'),
+ max: $slider.slider('option', 'max'),
+ step: $slider.slider('option', 'step')
+ };
+
$values = $param_value.split('-');
+ $values = this.invertRange($slider_options, $values[0], $values[1]);
- $('#' + jq($param_name + '_slider') ).slider('option', 'values', $values);
+ $slider.slider('option', 'values', $values);
$('#' + jq($param_name) ).val($param_value);
break;
}
this.syncChecked( $("input[type=checkbox], input[type=radio]", '#filter-form-' + $field) );
}
+ListManager.invertRange = function ($options, $min, $max) {
+ var $min_value = $options.min + (($options.max - $max) / $options.step) * $options.step,
+ $max_value = $options.max - (($min - $options.min) / $options.step) * $options.step;
+
+ return [$min_value, $max_value];
+}
+
ListManager.syncChecked = function ($checkboxes) {
$checkboxes.each(
function () {
var $me = $(this),
$checked = $me.is(':checked'),
$dt = $me.parent(),
$dd = $dt.next();
$dt.toggleClass('active', $checked);
$dd.toggleClass('active', $checked);
}
);
}
ListManager.updateFilterParams = function () {
var $form_fields;
for (var $field in this.filters) {
$form_fields = $('#filter-form-' + $field).serializeArray();
for (var $i = 0; $i < $form_fields.length; $i++) {
this.setParam($form_fields[$i].name, $form_fields[$i].value);
}
this.syncChecked( $("input[type=checkbox], input[type=radio]", '#filter-form-' + $field) );
}
this.scheduleReload();
}
ListManager.init = function () {
var $manager = this;
+ this.firstLoad = window.location.hash.length > 1;
+
$('body').bind(
'anchorchanged',
function ($e, $anchor) {
$manager.parseAnchor($anchor);
}
);
}
\ No newline at end of file
Index: branches/1.0.x/elements/filters.elm.tpl
===================================================================
--- branches/1.0.x/elements/filters.elm.tpl (revision 14910)
+++ branches/1.0.x/elements/filters.elm.tpl (revision 14911)
@@ -1,119 +1,125 @@
<inp2:m_DefineElement name="filter_text_block" PrefixSpecial="item-filter" filter_type="text" is_list="0">
<input type="text" name="<inp2:FilterInputName/>" id="<inp2:FilterInputName/>" value="<inp2:FilterField/>"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="filter_select_block" PrefixSpecial="item-filter" filter_type="select" is_list="0">
<select name="<inp2:FilterInputName/>" id="<inp2:FilterInputName/>">
</select>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="filter_radio_element">
<dt<inp2:m_if check="m_Param" name="selected"> class="active"</inp2:m_if>>
<input type="radio"<inp2:m_if check="m_Param" name="selected"> checked</inp2:m_if> name="<inp2:FilterInputName/>" id="<inp2:FilterInputName/>_<inp2:m_param name='key'/>" value="<inp2:m_param name='key'/>"/>&nbsp;<label for="<inp2:FilterInputName/>_<inp2:m_param name='key'/>"><inp2:m_Param name="title"/></label>
</dt>
<dd<inp2:m_if check="m_Param" name="selected"> class="active"</inp2:m_if>>(<inp2:m_Param name="count"/>)</dd>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="filter_radio_block" PrefixSpecial="item-filter" filter_type="radio" is_list="0">
<dl class="manufacturer">
<inp2:ListFilterOptions render_as="filter_radio_element" pass_params="1"/>
</dl>
<div class="clear"></div>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="filter_checkbox_element" form_id="">
<dt<inp2:m_if check="m_Param" name="selected"> class="active"</inp2:m_if>>
<input type="checkbox"<inp2:m_if check="m_Param" name="selected"> checked</inp2:m_if> id="<inp2:FilterInputName/>_<inp2:m_param name='key'/>" value="<inp2:m_param name='key'/>"/>&nbsp;<label for="<inp2:FilterInputName/>_<inp2:m_param name='key'/>"><inp2:m_Param name="title"/></label>
</dt>
<dd<inp2:m_if check="m_Param" name="selected"> class="active"</inp2:m_if>>(<inp2:m_Param name="count"/>)</dd>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="filter_checkbox_block" PrefixSpecial="item-filter" filter_type="checkbox" is_list="0">
<dl class="manufacturer">
<inp2:ListFilterOptions render_as="filter_checkbox_element" form_id="filter-form-{$filter_field}" pass_params="1"/>
</dl>
<div class="clear"></div>
<input type="hidden" name="<inp2:FilterInputName/>" id="<inp2:FilterInputName/>" value="<inp2:FilterField/>"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="filter_range_value_element">
<li>
<!--##<inp2:m_param name='key'/>; ##--><inp2:m_Param name="title"/>
</li>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="filter_range_count_element">
<li>(<inp2:m_Param name="count"/>)</li>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="filter_range_block" PrefixSpecial="item-filter" filter_type="range" is_list="0">
<div class="range-block">
<ul class="range">
<inp2:ListFilterOptions render_as="filter_range_value_element" pass_params="1"/>
</ul>
<div class="slider-vertical" id="<inp2:FilterInputName/>_slider" style="height:260px;"></div>
<ul class="range2">
<inp2:ListFilterOptions render_as="filter_range_count_element" pass_params="1"/>
</ul>
<div class="clear"></div>
</div>
<script type="text/javascript">
$(document).ready(
function() {
- $( '#' + jq('<inp2:FilterInputName/>_slider') ).slider({
- orientation: 'vertical',
- range: true,
- min: <inp2:m_Get name="min_range_value"/>,
- max: <inp2:m_Get name="max_range_value"/>,
- step: <inp2:m_Get name="range_step"/>,
- values: [<inp2:m_Get name="selected_from_range"/>, <inp2:m_Get name="selected_to_range"/>],
- change: function(event, ui) {
- // jQuery UI slider has inverted range - fix that here
- var $range_step = <inp2:m_Get name="range_step"/>,
- $range_min = <inp2:m_Get name="min_range_value"/>,
- $range_max = <inp2:m_Get name="max_range_value"/>,
- $min_value = $range_min + (($range_max - ui.values[1]) / $range_step) * $range_step,
- $max_value = $range_max - ((ui.values[0] - $range_min) / $range_step) * $range_step;
+ var $slider_options = {
+ min: <inp2:m_Get name="min_range_value"/>,
+ max: <inp2:m_Get name="max_range_value"/>,
+ step: <inp2:m_Get name="range_step"/>
+ },
+ $options = {
+ orientation: 'vertical',
+ range: true,
+ values: [<inp2:m_Get name="selected_from_range"/>, <inp2:m_Get name="selected_to_range"/>],
+ change: function(event, ui) {
+ // jQuery UI slider has inverted range - fix that here
+ var $selected_range = ListManager.invertRange($slider_options, ui.values[0], ui.values[1]);
+
+ $('#' + jq('<inp2:FilterInputName/>')).val($selected_range[0] + '-' + $selected_range[1]);
+ ListManager.updateFilterParams();
+ }
+ },
+ $values = ListManager.invertRange($slider_options, $options.values[0], $options.values[1]);
- $('#' + jq('<inp2:FilterInputName/>')).val($min_value + '-' + $max_value);
- ListManager.updateFilterParams();
- }
- });
+ $options.values[0] = $values[0];
+ $options.values[1] = $values[1];
+
+ $.extend($options, $slider_options);
+
+ $( '#' + jq('<inp2:FilterInputName/>_slider') ).slider($options);
}
);
</script>
<input type="hidden" name="<inp2:FilterInputName/>" id="<inp2:FilterInputName/>" value="<inp2:FilterField/>"/>
</inp2:m_DefineElement>
<inp2:m_DefineElement name="filter_element" PrefixSpecial="item-filter" prefix="" filter_field="" filter_type="" is_list="0">
<inp2:m_IFDataExists>
<inp2:m_ifnot check="m_Param" name="is_list">
<inp2:ReloadItem prefix="$prefix" field="$filter_field"/>
</inp2:m_ifnot>
<form action="<inp2:m_FormAction/>" id="filter-form-<inp2:m_Param name='filter_field'/>" method="post" class="filter-form" filter_field="<inp2:m_Param name='filter_field'/>" filter_type="<inp2:m_Param name='filter_type'/>">
<div class="block alt-block">
<h2 class="active"><a href="#">Filter by <inp2:m_Phrase name="lu_fld_{$filter_field}"/></a></h2>
<div class="block-content">
<inp2:m_RenderElement name="filter_{$filter_type}_block" pass_params="1"/>
</div>
</div>
<script type="text/javascript">
$(document).ready(
function () {
ListManager.registerFilter('<inp2:m_Param name="filter_field"/>');
}
);
</script>
</form>
</inp2:m_IFDataExists>
</inp2:m_DefineElement>

Event Timeline