Tags, errores solucionados

This commit is contained in:
Juan Ferrer Toribio 2017-11-16 15:53:20 +01:00
parent f9c002f08a
commit 7658a5680d
29 changed files with 375 additions and 497 deletions

View File

@ -5,6 +5,20 @@ var View = {
GRID: 1
};
var orderBy = [
{way: 'DESC', id: 'relevancy', name: 'Relevancy'},
{way: 'ASC', id: 'name', name: 'Name'},
{way: 'ASC', id: 'price', name: 'Lower price'},
{way: 'DESC', id: 'price', name: 'Higher price'},
{way: 'ASC', id: 'available', name: 'Available'},
{way: 'ASC', id: 'size', name: 'Lower size'},
{way: 'DESC', id: 'size', name: 'Higher size'},
{way: 'ASC', id: 'color', name: 'Color'},
{way: 'ASC', id: 'producer', name: 'Producer'},
{way: 'ASC', id: 'origin', name: 'Origin'},
{way: 'ASC', id: 'category', name: 'Category'}
];
Hedera.Catalog = new Class
({
Extends: Hedera.Form
@ -36,7 +50,7 @@ Hedera.Catalog = new Class
,activate: function ()
{
this.$.items.setInfo ('a', 'Articles', 'vn2008', ['item_id']);
this.$.items.setInfo ('i', 'item', 'vn', ['id']);
document.body.appendChild (this.$.rightPanel);
if (localStorage.getItem ('hederaView'))
@ -44,7 +58,11 @@ Hedera.Catalog = new Class
else
this.setView (View.GRID);
this.onRealmChange ();
this.$.orderBy.model = new Vn.Model ({
data: orderBy
});
this.onCategoryChange ();
this.refreshTitle ();
this.onParamsChange ();
}
@ -96,11 +114,10 @@ Hedera.Catalog = new Class
Vn.Node.setText (this.$.method, _('Warehouse'));
}
,onOrderChange: function (e)
,onOrderChange: function (combo)
{
var value = e.target.value;
var sortField = value.substr (2);
var sortWay = value.charAt (0) === 'A' ?
var sortField = combo.$.id;
var sortWay = combo.$.way === 'ASC' ?
Db.Model.SortWay.ASC : Db.Model.SortWay.DESC;
if (sortField)
@ -113,34 +130,37 @@ Hedera.Catalog = new Class
{
var params = this.params.$;
var shouldRefresh = params.search ||
params.realm && params.type;
params.category && params.type;
Vn.Node.removeChilds (this.$.tagFilters);
if (shouldRefresh)
{
var filterSql = this.$.filter.render (params);
var modelParams = {
filter: new Sql.String ({query: filterSql})
};
this.$.items.refresh (modelParams);
this.$.items.query = this.buildQuery ('CALL catalogGetItems ()');
this.$.items.refresh ();
var tagsQuery = this.buildQuery ('CALL catalogGetTags ()');
this.conn.execQuery (tagsQuery, this.onTagsReady.bind (this));
this.hideMenu ();
}
else
this.$.items.clean ();
this.showFilters (params.search || params.realm);
this.showFilters (params.search || params.category);
}
,showFilters: function (show)
{
this.$.filters.style.display = show ? 'block' : 'none';
this.$.realmMsg.style.display = show ? 'none' : 'block';
this.$.categoryMsg.style.display = show ? 'none' : 'block';
this.$.order.style.display = show ? 'block' : 'none';
}
,onRemoveFiltersClick: function ()
{
this.params.$ = {};
this.tagFilter = {};
}
,tagFilter: {}
@ -149,13 +169,36 @@ Hedera.Catalog = new Class
{
tagFilter[tag.id] = tag.value;
}
,buildQuery: function (query, params)
{
var query = new Sql.MultiStmt ({
stmts: [
this.$.preQuery,
new Sql.String ({query: query}),
this.$.postQuery
]
});
var qParams = {
joins: this.buildTagFilter (),
filter: this.buildMainFilter ()
};
Object.assign (qParams, params);
return this.conn.renderStmt (query, qParams)
}
,buildMainFilter: function ()
{
var filterSql = this.$.filter.render (this.params.$);
return new Sql.String ({query: filterSql});
}
,buildTagFilter: function (excludeTag)
{
var Type = Sql.Operation.Type;
var join = new Sql.Join ({
target: Sql.Table ({
target: new Sql.Table ({
schema: 'vn',
name: 'item',
alias: 'i'
@ -165,19 +208,19 @@ Hedera.Catalog = new Class
join.push (new Sql.JoinItem ({
target: new Sql.Table ({
schema: 'vn',
name: 'family',
alias: 'f'
name: 'itemType',
alias: 't'
}),
condition: new Sql.Operation ({
type: Type.EQUAL,
exprs: [
new Sql.Field ({
target: 'f',
target: 't',
name: 'id'
}),
new Sql.Field ({
target: 'i',
name: 'familyFk'
name: 'typeFk'
})
]
})
@ -206,7 +249,7 @@ Hedera.Catalog = new Class
})
});
join.push (joinItem);
joinItem.condition.exprs = [
new Sql.Operation ({
type: Type.EQUAL,
@ -247,46 +290,60 @@ Hedera.Catalog = new Class
})
];
}
return join;
}
,onTagsReady: function (resultSet)
{
var tags = resultSet.fetchArray ();
var filters = this.$.tagFilters;
var tags = resultSet.results[2].data;
tags.forEach (function (tag) {
var model = new Db.Model ({
autoLoad: false,
query: query
});
var query = this.buildQuery (
'CALL catalogGetTagValues (#tag)', {tag: tag.id});
var combo = new Vn.Combo ({
name: tag.name,
lot: lot,
placeholder: tag.description,
model: model
});
var label = this.createElement ('label');
label.appendChild (this.createTextNode (tag.name));
filters.appendChild (label);
div.appendChild (combo);
});
var combo = new Htk.Combo ({
valueField: 'value',
showField: 'value',
model: new Db.Model ({
autoLoad: true,
resultIndex: 2,
query: query,
conn: this.conn
})
});
combo.on ('changed', this.onComboChange, this);
filters.appendChild (combo.node);
}, this);
}
,onRealmChange: function ()
,onComboChange: function (combo)
{
console.log (combo.value);
}
,onCategoryChange: function ()
{
this.refreshTitleColor ();
}
,refreshTitleColor: function ()
{
var realms = this.$.realms;
var realm = this.params.$.realm;
var categories = this.$.categories;
var category = this.params.$.category;
var color = null;
if (realm)
if (category)
{
var row = realms.search ('id', realm);
var row = categories.search ('id', category);
if (row != -1)
color = '#'+ realms.get (row, 'color');
color = '#'+ categories.get (row, 'color');
}
this.gui.$.navbar.style.backgroundColor = color;
@ -294,18 +351,8 @@ Hedera.Catalog = new Class
,refreshTitle: function ()
{
var types = this.$.types;
var type = this.params.$.type;
var title = _('Catalog');
if (type)
{
var row = types.search ('tipo_id', type);
if (row != -1)
title = types.get (row, 'name');
}
var type = this.$.type.$.name;
var title = type ? type : _('Catalog');
Vn.Node.setText (this.$.title, title);
}
@ -370,7 +417,7 @@ Hedera.Catalog = new Class
this.onEraseClick ();
var lot = button.lot;
this.$.card.row = lot.row;
this.$.cardLot.assign ({item: lot.$.item_id});
this.$.cardLot.assign ({item: lot.$.id});
this.$.cardPopup.show ();
}
@ -441,221 +488,4 @@ Hedera.Catalog = new Class
}
});
Vn.Filter = new Class
({
Extends: Htk.Field
,Tag: 'vn-filter'
,Properties:
{
model:
{
type: Db.Model
,set: function (x)
{
this._model = x;
this._select.model = x;
this._refreshModelLot ();
}
,get: function ()
{
return this._model;
}
},
placeholder:
{
type: String
,set: function (x)
{
this._select.placeholder = x;
this._placeholder = x;
}
,get: function ()
{
return this._placeholder;
}
},
filter:
{
type: Sql.Filter
,set: function (x)
{
this._filter = x;
this._modelLot.assign ({filter: x});
this._refreshModelLot ();
}
,get: function ()
{
return this._filter;
}
},
lot:
{
type: Vn.LotIface
,set: function (x)
{
this._modelLot.source = x;
this._setLot (x);
}
,get: function ()
{
return this._lot;
}
},
name:
{
type: String
,set: function (x)
{
this._modelLot.fields = [x];
this._setName (x);
}
,get: function ()
{
return this._name;
}
}
}
,_valueColumnIndex: 0
,_showColumnIndex: 1
,initialize: function (props)
{
var node = this.createRoot ('div');
node.className = 'vn-filter';
this._select = new Htk.Combo ();
this._select.on ('mousedown', this._onMouseDown, this);
this._select.on ('changed', this._onChange, this);
this._select.on ('ready', this._onReady, this);
this.node.appendChild (this._select.node);
this._ul = this.createElement ('ul');
this.node.appendChild (this._ul);
this._modelLot = new Vn.LotQuery ();
this.parent (props);
}
,_refreshModelLot: function ()
{
if (this._model && this._filter)
this._model.lot = this._modelLot;
}
,_onMouseDown: function ()
{
if (this._model && this._model.status === Db.Model.Status.CLEAN)
{
var params = {
filter: this._filter
};
this._model.refresh ();
}
}
,_onUnselectClick: function ()
{
this._removeSelectionNode ();
this.valueChanged (undefined);
}
,_removeSelectionNode: function ()
{
if (this._lastLi)
{
Vn.Node.remove (this._lastLi);
this._lastLi = null;
this._label = null;
}
}
,_onChange: function ()
{
if (this._select.value === null
|| this._select.value === undefined)
return;
var value = this._select.value;
this._selectValue (value);
this.valueChanged (value);
}
,_onReady: function ()
{
if (this._emptyLabel)
this._refreshLabel ();
}
,_onTimeout: function ()
{
this._select.value = null;
}
,putValue: function (value)
{
this._selectValue (value);
}
,_selectValue: function (value)
{
this._removeSelectionNode ();
if (value === null || value === undefined)
return;
var li = this._lastLi = this.createElement ('li');
this._ul.appendChild (li);
var button = this.createElement ('button');
button.addEventListener ('click',
this._onUnselectClick.bind (this, li));
li.appendChild (button);
var icon = new Htk.Icon ({
icon: 'close',
alt: _('Close')
});
button.appendChild (icon.node);
var text = this._label = this.createTextNode ('');
li.appendChild (text);
setTimeout (this._onTimeout.bind (this));
this._refreshLabel ();
}
,_refreshLabel: function ()
{
if (!this._label)
return;
var row = -1;
if (this._model && this._model.ready)
row = this._model.searchByIndex (this._valueColumnIndex, this._value);
if (row != -1)
{
var label = this._model.getByIndex (row, this._showColumnIndex);
this._label.nodeValue = label;
this._emptyLabel = false;
}
else
{
this._emptyLabel = true;
this._label.nodeValue = _('Loading...');
}
}
,_destroy: function ()
{
this._select.unref ();
this._modelLot.unref ();
this.parent ();
}
});
})();

View File

@ -57,11 +57,11 @@
{
display: none;
}
.right-panel .realm-msg
.right-panel .category-msg
{
margin-top: 1em;
}
.right-panel .realm-msg > h1
.right-panel .category-msg > h1
{
font-weight: normal;
text-align: center;
@ -75,19 +75,19 @@
color: #777;
font-size: 1.1em;
}
.right-panel .realms
.right-panel .categories
{
width: 95%;
margin: .2em auto;
}
.right-panel .realms a
.right-panel .categories a
{
display: block;
float: left;
width: 33.33%;
border-radius: .1em;
}
.right-panel .realms a > img
.right-panel .categories a > img
{
display: block;
padding: 0;

View File

@ -3,12 +3,12 @@
<vn-lot-query id="params" on-change="onParamsChange">
<vn-spec name="search" type="String"/>
<vn-spec name="itemId" type="Number"/>
<vn-spec name="realm" type="Number"/>
<vn-spec name="category" type="Number"/>
<vn-spec name="type" type="Number"/>
</vn-lot-query>
<sql-filter type="AND" id="filter">
<sql-filter-item type="EQUAL"
target="i" field="familyFk"
target="i" field="typeFk"
param="type"/>
<sql-filter type="OR">
<sql-filter-item type="LIKE"
@ -22,41 +22,22 @@
param="itemId"/>
</sql-filter>
</sql-filter>
<vn-string id="pre-query">
<sql-string id="pre-query">
DROP TEMPORARY TABLE IF EXISTS tItems;
CREATE TEMPORARY TABLE tItems
(INDEX (id))
ENGINE = MEMORY
SELECT i.id
FROM #joins
WHERE #filter;
</vn-string>
<vn-string id="post-query">
DROP TEMPORARY TABLE tItems;
</vn-string>
CREATE TEMPORARY TABLE tItems
(INDEX (id))
ENGINE = MEMORY
SELECT i.id
FROM #joins
WHERE #filter
</sql-string>
<sql-string id="post-query">
DROP TEMPORARY TABLE tItems
</sql-string>
<db-model
id="items"
result-index="2"
auto-load="false">
CREATE TEMPORARY TABLE tmp.bionic_calc
(INDEX (item_id))
ENGINE = MEMORY
SELECT i.id item_id
FROM vn.item i
JOIN vn.family f ON f.id = i.familyFk
WHERE #filter;
CALL bionic_calc ();
SELECT a.Id_Article item_id, a.description, b.available, b.price,
b.producer, a.Foto, a.Article, a.Categoria, a.Medida,
IF(a.Tallos > 1, a.Tallos, NULL) Tallos, c.str color
FROM tmp.bionic_item b
JOIN vn2008.Articles a ON a.Id_Article = b.item_id
LEFT JOIN vn2008.producer p ON p.producer_id = a.producer_id
LEFT JOIN vn_locale.color_view c ON c.color_id = a.Color
LEFT JOIN vn_locale.origin_view o ON o.origin_id = a.id_origen
WHERE b.available > 0
ORDER BY a.relevancy DESC, a.Article, a.Medida
LIMIT 40;
</db-model>
<db-form id="basket" on-ready="onBasketReady">
<db-model property="model">
@ -102,8 +83,7 @@
ORDER BY warehouse_id, grouping;
</db-model>
<vn-lot id="card-lot"/>
<vn-param lot="params" name="realm" on-changed="onRealmChange"/>
<vn-param lot="params" name="type" on-changed="refreshTitle"/>
<vn-param lot="params" name="category" on-changed="onCategoryChange"/>
</vn-group>
<h1 id="title">
_Catalog
@ -136,36 +116,34 @@
directory="catalog"
subdir="200x200"
lot="item"
name="Foto"
name="image"
full-dir="900x900"/>
<div class="item-info">
<htk-button
lot="item"
value="{{item.item_id}}"
value="{{item.id}}"
tip="_AddToBasket"
icon="add"
on-click="onAddItemClick"
class="add-button"/>
<h2>{{item.Article}}</h2>
<h2>{{item.name}}</h2>
<p class="producer">
{{item.producer}}
</p>
<p>
@{{item.item_id}}
@{{item.id}}
</p>
<p>
<span>_Size</span> {{item.Medida}}
<span>_Category</span> {{item.Categoria}}
<span>_Size</span> {{item.size}}
<span>_Category</span> {{item.category}}
</p>
<p class="color">
<span>_Color</span> {{item.color}}
<htk-text lot="item" name="Tallos" format="_, %.0d Units"/>
<span>_Color</span> {{item.inkFk}}
<htk-text lot="item" name="stems" format="_, %.0d Units"/>
</p>
<div class="aval-price">
{{item.available}}
<span class="from">
_from
</span>
<span class="from">_from</span>
<span class="price">
<htk-text lot="item" name="price" format="%.2d€"/>
</span>
@ -190,21 +168,21 @@
</div>
<div class="filter">
<div class="categories">
<div class="realms">
<div class="categories">
<htk-repeater
class="realms-box">
class="categories-box">
<db-model
id="realms"
id="categories"
property="model"
on-status-changed="refreshTitleColor">
SELECT r.id, l.str name, r.color
FROM vn2008.reinos r
LEFT JOIN vn_locale.realm_view l ON l.realm_id = r.id
WHERE r.display != FALSE
ORDER BY name
SELECT c.id, l.name, c.color
FROM vn.itemCategory c
JOIN vn.itemCategoryL10n l ON l.id = c.id
WHERE c.display > 0
ORDER BY l.name
</db-model>
<custom>
<a class="clickable" href="#!form={{hash.form}}&amp;realm={{id}}">
<a class="clickable" href="#!form={{hash.form}}&amp;category={{id}}">
<img
src="image/family/light/{{id}}.svg"
title="{{name}}"
@ -215,73 +193,46 @@
<div class="clear"/>
</div>
</div>
<div id="realm-msg" class="realm-msg">
<h1>_Choose a realm</h1>
<div id="order" class="order">
<h2>_Order by</h2>
<htk-combo
id="order-by"
on-change="onOrderChange"
value="relevancy"
not-null="true"/>
</div>
<div id="category-msg" class="category-msg">
<h1>_Choose a category</h1>
</div>
<div id="filters" class="filters">
<h2>_Filter by</h2>
<label>_Family</label>
<htk-combo
id="type"
name="type"
on-change="refreshTitle"
lot="params">
<db-model
id="types"
property="model"
lot="params"
result-index="1"
on-status-changed="refreshTitle">
result-index="1">
CALL item_available ();
SELECT DISTINCT t.tipo_id, l.str name
FROM vn2008.Tipos t
JOIN vn2008.Articles a ON a.tipo_id = t.tipo_id
LEFT JOIN vn_locale.family_view l ON l.family_id = t.tipo_id
JOIN tmp.item_available i ON i.item_id = a.Id_Article
WHERE t.reino_id = #realm
SELECT DISTINCT t.id, l.name
FROM vn.itemType t
JOIN vn.item i ON i.typeFk = t.id
JOIN tmp.item_available a ON a.item_id = i.id
JOIN vn.itemTypeL10n l ON l.id = t.id
WHERE t.categoryFk = #category
ORDER BY name
</db-model>
</htk-combo>
<button on-click="onRemoveFiltersClick">
<div id="tag-filters">
</div>
<button on-click="onRemoveFiltersClick" class="thin">
_Remove filters
</button>
</div>
<div id="order" class="order">
<h2>_Order by</h2>
<select on-change="onOrderChange">
<option value="D|relevancy" selected="true">
_Relevancy
</option>
<option value="A|Article">
_Name
</option>
<option value="A|price">
_Lower price
</option>
<option value="D|price">
_Higher price
</option>
<option value="A|available">
_Available
</option>
<option value="A|Medida">
_Lower size
</option>
<option value="D|Medida">
_Higher size
</option>
<option value="A|color">
_Color
</option>
<option value="A|producer">
_Producer
</option>
<option value="A|Abreviatura">
_Origin
</option>
<option value="A|Categoria">
_Category
</option>
</select>
</div>
</div>
</div>
<htk-popup id="desc-popup">
@ -301,23 +252,23 @@
directory="catalog"
subdir="200x200"
lot="card"
name="Foto"
name="image"
full-dir="900x900"
conn="conn"
editable="true"/>
<div class="item-info">
<h2>
{{card.Article}}
{{card.name}}
</h2>
<p class="producer">
{{card.producer}}
</p>
<p>
<span>_Size</span> {{card.Medida}},
<span>_Category</span> {{card.categoria}}
<span>_Size</span> {{card.size}},
<span>_Category</span> {{card.category}}
</p>
<p class="color">
<span>_Color</span> {{card.color}}
<span>_Color</span> {{card.inkFk}}
<htk-text lot="card" name="Tallos" format="_, %.0d Units"/>
</p>
<p>
@ -356,22 +307,4 @@
</div>
</div>
</htk-popup>
<!--
<htk-combo on-change="onOrderChange">
<vn-json-model property="model">
<array>
<object way="A" field="Article" desc="_Name"/>
<object way="A" field="price" desc="_Lower price"/>
<object way="D" field="price" desc="_Higher price"/>
<object way="A" field="available" desc="_Available"/>
<object way="A" field="Medida" desc="_Lower size"/>
<object way="D" field="Medida" desc="_Higher size"/>
<object way="A" field="color" desc="_Color"/>
<object way="A" field="producer" desc="_Producer"/>
<object way="A" field="Abreviatura" desc="_Origin"/>
<object way="A" field="Categoria" desc="_Category"/>
</array>
</vn-json-model>
</htk-combo>
-->
</vn>

View File

@ -109,6 +109,7 @@
id="agency"
lot="lot"
name="agency"
show-field="description"
on-changed="onFieldChange"
model="agencies"/>
</div>
@ -120,6 +121,7 @@
id="warehouse"
lot="lot"
name="agency"
show-field="description"
on-changed="onFieldChange"
model="agencies"/>
</div>

View File

@ -104,11 +104,14 @@ module.exports = new Class
}
,_editable: true
,_lockEntry: false
,_setValue: function (newValue)
{
Vn.ParamIface.prototype._setValue.call (this, newValue);
this.putValue (newValue);
if (!this._lockEntry)
this.putValue (newValue);
if (this.conditionalFunc)
this.conditionalFunc (this, newValue);
@ -122,7 +125,9 @@ module.exports = new Class
*/
,valueChanged: function (value)
{
this._lockEntry = true;
this._setValue (value);
this._lockEntry = false;
}
/**

View File

@ -125,24 +125,48 @@ module.exports = new Class
return this._params;
}
}
,valueField:
{
type: String,
value: 'id'
}
,showField:
{
type: String,
value: 'name'
}
}
,_row: -1
,_model: null
,valueColumnIndex: 0
,valueColumnName: null
,showColumnIndex: 1
,showColumnName: null
,_notNull: true
,_webkitRefresh: false
,_notNull: false
,render: function ()
{
var button = this.createRoot ('button');
var node = this.createRoot ('div');
node.className = 'htk-combo';
var clearButton = this.createElement ('htk-icon');
clearButton.className = 'clear';
clearButton.icon = 'close';
clearButton.on ('click', this._onClearClick, this);
node.appendChild (clearButton.node);
var button = this.createElement ('button');
button.type = 'button';
button.className = 'htk-select input';
button.className = 'htk-combo input';
button.addEventListener ('mousedown',
this._onButtonMouseDown.bind (this));
node.appendChild (button);
this.button = button;
this.clearButton = clearButton;
this._refreshShowText ();
}
,_onClearClick: function ()
{
this.value = null;
}
,_setRow: function (row)
@ -150,7 +174,6 @@ module.exports = new Class
this._row = row;
this._refreshShowText ();
this.rowChanged ();
this.changed ();
}
,_onButtonMouseDown: function (e)
@ -164,7 +187,7 @@ module.exports = new Class
var model = this._model;
var menu = this.createElement ('div');
menu.className = 'htk-select-menu';
menu.className = 'htk-combo-menu';
var grid = new Htk.Grid ({showHeader: false});
menu.appendChild (grid.node);
@ -173,7 +196,7 @@ module.exports = new Class
gridNode.addEventListener ('click',
this._onGridClicked.bind (this, grid));
var column = new ColumnText ({columnIndex: this.showColumnIndex});
var column = new ColumnText ({column: this.showField});
grid.appendColumn (column);
grid.model = model;
@ -199,7 +222,7 @@ module.exports = new Class
var row = target.rowIndex - 1;
if (row >= 0)
value = this._model.getByIndex (row, this.valueColumnIndex);
value = this._model.get (row, this.valueField);
else
value = null;
@ -221,7 +244,7 @@ module.exports = new Class
var model = this._model;
if (this._row !== -1)
var showText = model.getByIndex (this._row, this.showColumnIndex);
var showText = model.get (this._row, this.showField);
else if (model && model.status === Db.Model.Status.LOADING)
var showText = _('Loading...');
else if (this._placeholder)
@ -229,7 +252,18 @@ module.exports = new Class
else
var showText = '';
Vn.Node.setText (this.node, showText);
if (this.node)
{
var visibility;
if (this._value && !this._notNull)
visibility = 'visible';
else
visibility = 'hidden';
this.clearButton.node.style.visibility = visibility;
Vn.Node.setText (this.button, showText);
}
}
,_onModelChange: function ()
@ -259,7 +293,7 @@ module.exports = new Class
var row;
if (this._model && this._model.ready)
row = this._model.searchByIndex (this.valueColumnIndex, this._value);
row = this._model.search (this.valueField, this._value);
else
row = -1;

View File

@ -134,35 +134,60 @@ td.cell-image .htk-image
/* Select */
.htk-select
.htk-combo
{
position: relative;
}
.htk-combo > button
{
max-width: 100%;
height: 2em;
text-align: left;
z-index: 1;
}
.htk-select-menu
.htk-combo > .clear
{
position: absolute;
right: 0;
margin: .2em;
padding: .3em;
cursor: pointer;
z-index: 2;
border-radius: .1em;
visibility: hidden;
}
.htk-combo:hover > .clear
{
visibility: visible;
}
.htk-combo > .clear:hover
{
background-color: rgba(0, 0, 0, 0.1)
}
.htk-combo-menu
{
max-width: 100%;
}
.modal > .htk-select-menu
.modal > .htk-combo-menu
{
min-width: 14em;
}
.htk-select-menu tbody > tr
.htk-combo-menu tbody > tr
{
border-top: none;
height: 2.5em;
}
.htk-select-menu td.message
.htk-combo-menu td.message
{
padding: 1em;
}
.htk-select-menu tr:hover
.htk-combo-menu tr:hover
{
background-color: rgba(1, 1, 1, 0.1);
cursor: pointer;
}
.htk-select-menu td
.htk-combo-menu td
{
max-width: 0;
overflow: hidden;

View File

@ -11,13 +11,9 @@ module.exports = new Class
,render: function (params)
{
var sql = 'DELETE FROM '
+ this.renderTarget (params);
if (this.where)
sql += ' WHERE ' + this.where.render (params);
sql += this.renderLimit(params);
return sql;
return 'DELETE FROM'
+ this.renderTarget (params)
+ this.renderIfSet (this.where, 'WHERE', params)
+ this.renderLimit (params);
}
});

View File

@ -15,14 +15,14 @@ module.exports = new Class
,addSet: function (fieldName, value)
{
this.expr.push (new Value ({value: value}));
this.field.push (new Field ({name: fieldName}));
this.expr.push (new Value ({value: value}));
}
,addExpr: function (fieldName, expr)
{
this.expr.push (expr);
this.field.push (new Field ({name: fieldName}));
this.expr.push (expr);
}
,delSet: function ()

View File

@ -32,12 +32,7 @@ module.exports = new Class
,render: function ()
{
var sql = '';
if (this.target)
sql += this.renderIdentifier (this.target) +'.';
sql += this.renderIdentifier (this.name);
return sql;
return this.renderPreIdent (this.target)
+ this.renderIdent (this.name);
}
});

View File

@ -36,7 +36,7 @@ module.exports = new Class
this.exprs.forEach (function (expr) {
if (expr.isReady (params))
newExprs.push (exprs[i]);
newExprs.push (expr);
})
if (newExprs.length > 0)

View File

@ -47,15 +47,10 @@ module.exports = new Class
,render: function (params)
{
var sql = '';
if (this.schema)
sql += this.renderIdentifier (this.schema) +'.';
sql += this.renderIdentifier (this.name)
return this.renderPreIdent (this.schema)
+ this.renderIdent (this.name)
+ '('
+ this.renderListWs (this.list, params, ', ')
+ ')';
return sql;
}
});

View File

@ -10,7 +10,7 @@ module.exports = new Class
,render: function (params)
{
return 'INSERT INTO '
return 'INSERT INTO'
+ this.renderTarget (params)
+ ' ('
+ this.renderListWs (this.field, params, ', ')

View File

@ -3,7 +3,12 @@ var Target = require ('./target');
var Expr = require ('./expr');
var SqlObject = require ('./object');
var Type = require ('./join').Type;
var TypeSql = require ('./join').TypeSql;
var TypeSql = [
'INNER',
'LEFT',
'RIGHT'
];
/**
* The equivalent of a SQL join.

View File

@ -14,16 +14,9 @@ var Type = {
RIGHT : 2
};
var TypeSql = [
'INNER',
'LEFT',
'RIGHT'
];
Klass.extend
({
Type: Type,
TypeSql: TypeSql
Type: Type
});
Klass.implement
@ -52,7 +45,9 @@ Klass.implement
,render: function (params)
{
return '('+ this.target.render (params) +' '
return '('
+ this.target.render (params)
+ ' '
+ this.renderList (this.list, params)
+ ')';
}

View File

@ -5,6 +5,7 @@ module.exports = new Class
({
Properties:
{
/*
list:
{
type: Array
@ -17,13 +18,14 @@ module.exports = new Class
return this._list;
}
}
*/
}
,_list: []
,list: []
,appendChild: function (child)
{
this._list.push (child);
this.list.push (child);
}
/**
@ -33,7 +35,7 @@ module.exports = new Class
*/
,push: function (element)
{
this._list.push (element);
this.list.push (element);
}
/**
@ -43,7 +45,7 @@ module.exports = new Class
*/
,splice: function (i)
{
this._list.splice (i);
this.list.splice (i);
}
/**
@ -53,6 +55,6 @@ module.exports = new Class
*/
,get: function (i)
{
return this._list[i];
return this.list[i];
}
});

View File

@ -31,12 +31,6 @@ module.exports = new Class
,render: function (params)
{
var sql = '';
this._list.forEach (function (stmt) {
sql += stmt.render (params) +";\n";
});
return sql;
return this.renderListWs (this.list, params, ";\n");
}
});

View File

@ -76,10 +76,24 @@ module.exports = new Class
* @param {String} identifier The identifier
* @return {string} The quoted identifier
*/
,renderIdentifier: function (identifier)
,renderIdent: function (identifier)
{
return '`'+ identifier +'`';
}
/**
* Renders a quoted SQL identifier.
*
* @param {String} identifier The identifier
* @return {string} The quoted identifier
*/
,renderPreIdent: function (identifier)
{
if (identifier)
return this.renderIdent (identifier) +'.';
else
return '';
}
/**
* Renders the object if it's defined.

View File

@ -18,6 +18,16 @@ var Type =
,AND : 2
,OR : 3
,REGEXP : 4
,LOWER : 5
,UPPER : 6
,LE : 7
,UE : 8
,PLUS : 9
,MINUS : 10
,MULT : 11
,DIV : 12
,NE : 13
,MOD : 14
};
var Operators =
@ -27,6 +37,16 @@ var Operators =
,'AND'
,'OR'
,'REGEXP'
,'<'
,'>'
,'<='
,'>='
,'+'
,'-'
,'*'
,'/'
,'<>'
,'MOD'
];
Klass.extend
@ -47,6 +67,11 @@ Klass.implement
enumType: Type
,value: -1
},
target:
{
type: String
,value: null
},
exprs:
{
type: Array

View File

@ -18,15 +18,11 @@ module.exports = new Class
,render: function (params)
{
var sql = 'SELECT '
return 'SELECT '
+ this.renderListWs (this.expr, params, ', ')
+ ' FROM '
+ this.renderTarget (params);
if (this.where)
sql += ' WHERE ' + this.where.render (params);
sql += this.renderLimit (params);
return sql;
+ ' FROM'
+ this.renderTarget (params)
+ this.renderIfSet (this.where, 'WHERE', params)
+ this.renderLimit (params);
}
});

View File

@ -32,15 +32,15 @@ module.exports = new Class
,renderTarget: function (params)
{
if (this.target.length > 0)
return this.renderListWs (this.target, params, ', ');
return ' '+ this.renderListWs (this.target, params, ', ');
else
return 'DUAL';
return ' DUAL';
}
,renderLimit: function ()
{
if (this.limit != null)
return 'LIMIT '+ parseInt (this.limit);
return ' LIMIT '+ parseInt (this.limit);
else
return '';
}

View File

@ -8,6 +8,7 @@ var Holder = require ('./holder');
module.exports = new Class
({
Extends: Stmt
,Tag: 'sql-string'
,Properties:
{
query:
@ -19,6 +20,12 @@ module.exports = new Class
,regexp: /#\w+/g
,appendChild: function (child)
{
if (child.nodeType === Node.TEXT_NODE)
this.query = child.textContent;
}
,render: function (params)
{
if (!this.query)

View File

@ -28,15 +28,11 @@ module.exports = new Class
,render: function ()
{
var sql = '';
if (this.schema)
sql += this.renderIndentifier (this.schema) +'.';
sql += this.renderIndentifier (this.name);
var sql = this.renderPreIdent (this.schema)
+ this.renderIdent (this.name);
if (this.alias)
sql += ' AS '+ this.renderIndentifier (this.alias);
sql += ' AS '+ this.renderIdent (this.alias);
return sql;
}

View File

@ -10,17 +10,18 @@ module.exports = new Class
,render: function (params)
{
var sql = 'UPDATE '
var sql = 'UPDATE'
+ this.renderTarget (params)
+ ' SET ';
this.field.forEach (function (field, i) {
if (i > 0)
sql += ', ';
sql += field.render (params)
+ ' = '
+ this.expr[i].render(params);
});
}, this);
sql += this.renderIfSet (this.where, 'WHERE', params)
+ this.renderLimit(params);

View File

@ -6,9 +6,11 @@ var kebabToCamel = require ('./string-util').kebabToCamel;
var CompilerObject = require ('./compiler-object');
var CompilerElement = require ('./compiler-element');
var CompilerText = require ('./compiler-text');
var CompilerString = require ('./compiler-string');
var CompilerInterpolable = require ('./compiler-interpolable');
var regCompilers = [
CompilerString,
CompilerObject,
CompilerElement,
CompilerText

23
js/vn/compiler-string.js Normal file
View File

@ -0,0 +1,23 @@
var Compiler = require ('./compiler');
/**
* Compiles a string from text node.
*/
module.exports = new Class
({
Extends: Compiler
,compile: function (builder, node, tagName)
{
if (tagName !== 'string')
return null;
return {string: node.firstChild.textContent};
}
,instantiate: function (doc, context)
{
return context.string;
}
});

View File

@ -78,15 +78,13 @@ module.exports = new Class
,rowChanged: function ()
{
this._rowLock = true;
var row;
if (this._model)
row = this._model.getObject (this._row);
this._rowLock = true;
this.params = row != null ? row : {};
this._rowLock = false;
}
});

View File

@ -218,13 +218,17 @@ Klass.implement
,_sort: function (columnName, way)
{
var status = this._status;
this._setStatus (Status.LOADING);
this._realSort (columnName, way);
this._setStatus (Status.READY);
this._setStatus (status);
}
,_realSort: function (columnName, way)
{
if (!this._data)
return;
if (columnName !== this._sortColumn)
{
if (way === SortWay.DESC)

View File

@ -21,6 +21,7 @@ Vn = module.exports = {
,ParamIface : require ('./param-iface')
,Param : require ('./param')
,Spec : require ('./spec')
,Model : require ('./model')
,ModelIface : require ('./model-iface')
,ModelProxy : require ('./model-proxy')
,IteratorIface : require ('./iterator-iface')