форматирование значений input type='number'
От:
PM
Дата: 02.10.12 12:38
Оценка:
Всем привет!
Cразу к сути вопроса — есть поле ввода <input type='number'>, хочется форматировать по разному его значения. Например, показывать число в 16-ричной с/с, или строку "нет" для значения 0.
Я правильно понимаю что мне нужно написать собственный behavior и реализовать функцию on_draw() для отрисовки? Я могу как-то при этом унаследовать стандартный behavior number?
Re: форматирование значений input type='number'
Здравствуйте, PM, Вы писали:
PM>Всем привет!
PM>Cразу к сути вопроса — есть поле ввода <input type='number'>, хочется форматировать по разному его значения. Например, показывать число в 16-ричной с/с, или строку "нет" для значения 0.
Редактировние и представление (форматирование) это две разные сущности в том смысле что представление данных в этих двух режимах должно выполняться по разному.
В самом общем случае можно делать так:
<form>
Fancy 16-bit number <input type=text filter="0~9A~F" class="for-edit"><span class=for-view />
</form>
И переключать form в режим отображения и режим редактирования пряча/показывая соотв. элементы. В span class=for-view выводить значение в твоем отформатированном виде.
Про: строку "нет" для значения 0.
Значение 0 это значение 0. Пустая строка это значение нет или undefined.
Если так, то попробуй:
<html>
<head>
<style>
input[type=number]:empty { color:red; }
</style>
</head>
<body>
<input type=number novalue="неопределено" >
</body>
</html>
Re[2]: форматирование значений input type='number'
От:
PM
Дата: 03.10.12 13:08
Оценка:
Здравствуйте, c-smile, Вы писали:
CS>Редактировние и представление (форматирование) это две разные сущности в том смысле что представление данных в этих двух режимах должно выполняться по разному.
CS>В самом общем случае можно делать так:
CS><form>
CS> Fancy 16-bit number <input type=text filter="0~9A~F" class="for-edit"><span class=for-view />
CS></form>
CS>И переключать form в режим отображения и режим редактирования пряча/показывая соотв. элементы. В span class=for-view выводить значение в твоем отформатированном виде.
Сейчас так и сделано — рядом с input type='number' лежит span показывающий значение из поля ввода в 16-ричной системе. Но захотелось получить полноценный hexadecimal редактор
CS>Про: строку "нет" для значения 0.
CS>Значение 0 это значение 0. Пустая строка это значение нет или undefined.
CS>Если так, то попробуй:
Я имел ввиду аналог
property specialValueText из QAbstractSpinBox
Cпасибо, можно попробовать выкрутиться с novalue, забивая undefined вместо 0 и поставив minvalue = 1.
В результате хотелось бы получить нечто похожее на QSpinBox из Qt, с префиксом, суффиксом и текстом для спец. значения.
Я сегодня попробовал добавить собственный behavior для input type='number', но без особых успехов. Пока вижу выход только в дублировании функциональности и стиля из behavior: number в собственном hexnumber
Re[3]: Пример того как это делается
Вот пример для Sciter. Портирование в HTMLayout — на совести вопрошающего.
Три файла:
test.htm , <input type="hex-number"> там это оно.
<html>
<head>
<style>
@import url(hex-editor.css);
</style>
<script type="text/tiscript">
$(button#show).onClick = function()
{
var v = $(input#hex).value;
$(pre).text = String.printf("%d %x",v,v);
}
</script>
</head>
<body>
<input type="hex-number" value="0xAFED" id="hex" />
<button id="show">Show value</button>
<pre> </pre>
</body>
</html>
Файл hex-editor.css
input[type="hex-number"]
{
style-set: "hex-edit";
}
@set hex-edit
{
:root
{
prototype:HexEditor url(hex-editor.tis);
font-rendering-mode:snap-pixel;
font-family:monospace;
color:windowtext;
background-image:url(theme:edit-normal);
background-repeat:stretch;
padding:system-border-width;
width: 6em;
height: min-intrinsic;
cursor:default;
white-space: nowrap;
text-align:right;
flow:"1 2"
"1 3" ;
//context-menu:url(res:menu-edit.htm);
}
:root:rtl
{
flow:"2 1"
"3 1";
}
:root > caption
{
display:block;
flow:text;
behavior: edit;
height:*; width:*;
padding:2px;
cursor:text;
white-space:pre;
overflow-x:hidden-scroll;
-filter:"0~9A~Fa~f";
text-selection: windowtext threedface;
}
:root > caption:focus {
text-selection: highlighttext highlight;
}
:root:disabled
{
background-image:url(theme:edit-disabled);
color:graytext;
}
:root:invalid
{
color:red;
}
:root > button
{
display:block;
behavior:clickable;
cursor:default;
height:0.5*;
min-height:10dip;
}
:root > button.minus
{
padding:0;
margin: 0 -2px -2px 0;
background-image:url(theme:v-spin-minus-normal);
background-repeat:stretch;
width:system-scrollbar-width;
height:50%%;
}
:root > button.minus:hover
{
transition:none;
background-image:url(theme:v-spin-minus-hover);
}
:root > button.minus:active
{
background-image:url(theme:v-spin-minus-pressed);
}
:root > button.minus:disabled
{
background-image:url(theme:v-spin-minus-disabled);
}
:root > button.plus
{
padding:0;
margin: -2px -2px -1 0;
background-image:url(theme:v-spin-plus-normal);
background-repeat:stretch;
width:system-scrollbar-width;
height:50%%;
}
:root > button.plus:hover
{
transition:none;
background-image:url(theme:v-spin-plus-hover);
}
:root > button.plus:active
{
background-image:url(theme:v-spin-plus-pressed);
}
:root > button.plus:disabled
{
background-image:url(theme:v-spin-plus-disabled);
}
}
и файл hex-editor.tis с нашим behavior:
class HexEditor : Behavior {
function attached() {
// create structure:
this .caption = new Element("caption" ); this .append(this .caption);
this .inc = new Element("button" ); this .inc.attributes["class" ] = "plus" ; this .append(this .inc);
this .dec = new Element("button" ); this .dec.attributes["class" ] = "minus" ; this .append(this .dec);
var initialVal = this .attributes["value" ];
if ( initialVal ) this .value = initialVal.toInteger();
}
property value(v)
{
get {
var va = (this .caption.value || "" ).scanf("%x" )
return typeof va == #array && va.length == 1 ? va[0]: undefined;
}
set {
this .caption.value = String .printf("%X" ,v);
}
}
function onControlEvent(evt)
{
if ( evt.type == Event.BUTTON_CLICK && evt.target == this .inc )
this .doInc();
else if ( evt.type == Event.BUTTON_CLICK && evt.target == this .dec )
this .doDec();
}
function onMouse(evt)
{
if ( evt.type == Event.MOUSE_WHEEL )
{
if ( evt.wheelDelta < 0 ) this .doDec(); else this .doInc();
}
}
function doInc()
{
var v = this .value;
if ( typeof v == #integer ) this.value += 1;
else this .value = 0;
}
function doDec()
{
var v = this .value;
if ( typeof v == #integer ) this.value -= 1;
else this .value = 0xFFFF;
}
}
Re[4]: Пример того как это делается
От:
PM
Дата: 04.10.12 13:27
Оценка:
Здравствуйте, c-smile, Вы писали:
CS>Вот пример для Sciter. Портирование в HTMLayout — на совести вопрошающего.
Спасибо! попробую сделать это в HTMLayout
Re[5]: Пример того как это делается
От:
PM
Дата: 30.10.12 05:49
Оценка:
56 (2)
Здравствуйте, PM, Вы писали:
PM>Здравствуйте, c-smile, Вы писали:
CS>>Вот пример для Sciter. Портирование в HTMLayout — на совести вопрошающего.
Вот, портировал, вдруг кому еще пригодится. Спасибо c-smile, все оказалось не так страшно
#include "behavior_aux.h"
namespace htmlayout {
/** behavior:hexnumber, hexadecimal number edit.
* Behaves like number, size attribute defines width of value
*
* <input type="hex-number" size="4" step="1 minvalue="0" maxvalue="65535" />
*
**/
class hexnumber : public behavior
{
public :
hexnumber()
: behavior(HANDLE_MOUSE | HANDLE_KEY | HANDLE_BEHAVIOR_EVENT | HANDLE_METHOD_CALL, "hexnumber" )
{
char const css[] = " input[type=\"hex-number\"] { style-set: \"hex-edit\"; }"
"@set hex-edit {"
" :root {"
" behavior:hexnumber;"
" font-rendering-mode:snap-pixel; font-family:monospace;"
" background-image:url(theme:edit-normal); background-repeat:stretch; "
" padding:system-border-width; width: 6em; height: min-intrinsic;"
" color:windowtext; cursor:text; white-space: nowrap; text-align:right;"
" flow:\"1 2\""
" \"1 3\"; }"
" :root:rtl {"
" flow:\"2 1\""
" \"3 1\"; }"
" :root > caption {"
" display:block; flow:text; behavior: edit; size:*; padding:2px; cursor:text;"
" white-space:pre; overflow-x:hidden-scroll; -filter:\"0~9A~Fa~f\";"
" text-selection: windowtext threedface; }"
" :root > caption:focus { text-selection: highlighttext highlight; }"
" :root:disabled { background-image:url(theme:edit-disabled); color:graytext; }"
" :root:invalid { color:red; }"
" :root > button { display:block; padding:0; behavior:clickable; cursor:default; height:0.5*; min-height:10dip; }"
" :root > button.minus { margin: 0 -2px -2px 0;"
" background-image:url(theme:v-spin-minus-normal); background-repeat:stretch; width:system-scrollbar-width; }"
" :root > button.minus:hover { transition:none; background-image:url(theme:v-spin-minus-hover); }"
" :root > button.minus:active { background-image:url(theme:v-spin-minus-pressed); }"
" :root > button.minus:disabled { background-image:url(theme:v-spin-minus-disabled); }"
" :root > button.plus { margin: -2px -2px -1 0;"
" background-image:url(theme:v-spin-plus-normal); background-repeat:stretch; width:system-scrollbar-width; }"
" :root > button.plus:hover { transition:none; background-image:url(theme:v-spin-plus-hover); }"
" :root > button.plus:active { background-image:url(theme:v-spin-plus-pressed); }"
" :root > button.plus:disabled { background-image:url(theme:v-spin-plus-disabled); }"
"}" ;
::HTMLayoutAppendMasterCSS((LPCBYTE)css, sizeof (css));
}
private :
// behavior implementation
virtual void attached(HELEMENT he)
{
dom::element self = he;
dom::element caption = dom::element::create("caption" );
self.append(caption);
if ( step(self) )
{
dom::element inc = dom::element::create("button" );
inc.set_attribute("class" , L"plus" );
self.append(inc);
dom::element dec = dom::element::create("button" );
dec.set_attribute("class" , L"minus" );
self.append(dec);
}
int const val = self.get_attribute_int("value" , -1);
if ( val >= 0 )
{
set_value(self, val);
}
}
virtual BOOL handle_event(HELEMENT he, BEHAVIOR_EVENT_PARAMS& params)
{
if ( params.cmd == BUTTON_CLICK )
{
if ( params.heTarget == inc(he) )
{
do_inc(he);
return true ;
}
else if ( params.heTarget == dec(he) )
{
do_dec(he);
return true ;
}
}
return false ;
}
virtual BOOL handle_mouse(HELEMENT he, MOUSE_PARAMS& params)
{
if ( params.cmd == MOUSE_WHEEL )
{
int const wheel_delta = params.button_state;
if ( wheel_delta < 0 && dec(he) )
{
do_dec(he);
return true ;
}
else if ( wheel_delta > 0 && inc(he) )
{
do_inc(he);
return true ;
}
}
return false ;
}
virtual BOOL handle_key(HELEMENT he, KEY_PARAMS& params)
{
if ( params.cmd == KEY_DOWN )
{
if ( params.key_code == VK_UP && inc(he) )
{
do_inc(he);
return true ;
}
else if ( params.key_code == VK_DOWN && dec(he) )
{
do_dec(he);
return true ;
}
}
return false ;
}
virtual BOOL handle_method_call(HELEMENT he, METHOD_PARAMS& params)
{
if ( params.methodID == GET_VALUE )
{
static_cast <VALUE_PARAMS&>(params).val = get_value(he);
return true ;
}
else if ( params.methodID == SET_VALUE )
{
set_value(he, static_cast <VALUE_PARAMS&>(params).val);
return true ;
}
return false ;
}
private :
static void set_value(dom::element self, json::value val)
{
dom::element caption = self.find_first("caption" );
if ( caption )
{
if ( val.is_int() )
{
int const width = max(self.get_attribute_int("size" , 1), 1);
std::vector<wchar_t > buf(width + std::numeric_limits<unsigned >::digits / 4 + 1);
swprintf(&buf[0], buf.size(), L"%.*X" , width, val.get(0));
val = &buf[0];
}
caption.set_value(val);
}
}
static json::value get_value(dom::element self)
{
json::value result;
dom::element caption = self.find_first("caption" );
if ( caption )
{
int val = 0;
json::string const str = caption.get_value().get(L"" );
if ( swscanf(str.c_str(), L"%x" , &val) == 1 )
{
val = max(min_value(self), min(val, max_value(self)));
result = val;
}
}
return result;
}
static int step(dom::element self)
{
return self.get_attribute_int("step" , 0);
}
static int min_value(dom::element self)
{
return self.get_attribute_int("minvalue" , 0);
}
static int max_value(dom::element self)
{
return self.get_attribute_int("maxvalue" , 0xFFFF);
}
static dom::element inc(dom::element self)
{
return self.find_first("button[class='plus']" );
}
static dom::element dec(dom::element self)
{
return self.find_first("button[class='minus']" );
}
static void do_inc(dom::element self)
{
json::value val = get_value(self);
val = val.is_int()? min(val.get(0) + step(self), max_value(self)) : min_value(self);
set_value(self, val);
}
static void do_dec(dom::element self)
{
json::value val = get_value(self);
val = val.is_int()? max(val.get(0) - step(self), min_value(self)) : max_value(self);
set_value(self, val);
}
};
// instantiating and attaching it to the global list
hexnumber hexnumber_instance;
} // htmlayout namespace
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить