Повесить обработчик событий onClick на элемент
От: DmitryScaletta Беларусь  
Дата: 15.03.15 08:44
Оценка:
При запуске программы создаю элемент:
dom::element root = dom::element::root_element(window::get_hwnd());
dom::element table = root.find_first("#table");

dom::element my_div = dom::element::create("div", L"");
my_div.set_attribute("class", L"my_div");
table.append(my_div);


Как мне на "my_div" повесить обработчик событий onClick?
Отредактировано 15.03.2015 8:47 DmitryScaletta . Предыдущая версия . Еще …
Отредактировано 15.03.2015 8:47 DmitryScaletta . Предыдущая версия .
Re: Повесить обработчик событий onClick на элемент
От: flаt  
Дата: 15.03.15 14:21
Оценка: 2 (1) +1
Здравствуйте, DmitryScaletta, Вы писали:

DS>Как мне на "my_div" повесить обработчик событий onClick?

Приаттачиться к my_div или его предку и обрабатывать HANDLE_BEHAVIOR_EVENT (event_handler::handle_event) с BUTTON_CLICK. Это если в С++.
Re: Повесить обработчик событий onClick на элемент
От: c-smile Канада http://terrainformatica.com
Дата: 15.03.15 19:20
Оценка: 3 (1)
Здравствуйте, DmitryScaletta, Вы писали:

DS>Как мне на "my_div" повесить обработчик событий onClick?


Все DOM событиия всплывают по цепочке контейнеров к окну поэтому если у тебя окно отнаследовано от sciter::event_handler то все DOM events туда приходят.
Поэтому ты можешь написать нечто типа:
bool my_window::on_event(HELEMENT he, HELEMENT target, BEHAVIOR_EVENTS type, UINT_PTR reason) {
  if( type == BUTTON_CLICK && dom::element(target).test("#table > .my_div") )
    on_my_div_clicked();
}


Если у тебя таких обработчиков много то имеет смысл нарисовать вокруг on_event что-то типа DOM_EVENT_MAP :

BEGIN_DOM_EVENT_MAP
  ON_BUTTON_CLICK( "#table > .my_div" , on_my_div_clicked )
  ...
END_DOM_EVENT_MAP


Да, и для того чтобы элемент генерировал BUTTON_CLICKs нужно в CSS написать

#table > .my_div { behavior:button; } // focusable
#table > .my_div { behavior:clickable; } // non-focusable


Но вообще-то ведущие собаководы рекомендуют более высокоуровневый UI/backend обмен, т.е. event handlers находятся и обрабатываются в скрипте
и вызывают native functions по результатам обработки:

include "decorators.tis"

@click @on "#table > .my_div" 
  function(evt) {  
    if( isValidSomehow(evt.target) ) 
      view.backendDoSomething(); 
  }


Смысл такой организации в том что дизайнер может поменять markup поэтому вшивать в native код селекторы можно лишь в том случае если ты сам и дизайнер и программер.
Со скриптом DOM structure refactoring проще.
Re[2]: Повесить обработчик событий onClick на элемент
От: DmitryScaletta Беларусь  
Дата: 16.03.15 07:42
Оценка:
c-smile,
Спасибо за ответ. С этим разобрался.

Возник еще вопрос.
Есть такая форма:
<div>
    <form>
        <button|checkbox name="checkbox1">checkbox1</button>
        <button|checkbox name="checkbox2">checkbox2</button>
        <button|checkbox name="checkbox3">checkbox3</button>
    </form>
</div>
<pre#out></pre>


В скрипте прописан код:
var checkbox1 = $(button[name=checkbox1]);
var checkbox2 = $(button[name=checkbox2]);
var checkbox3 = $(button[name=checkbox3]);
checkbox3.state.disabled = true;


$(form).subscribe("change", function() {    
    if (checkbox1.state.checked && checkbox2.state.checked)
        checkbox3.state.disabled = false;
    else 
        checkbox3.state.disabled = true;
    
    // if (checkbox4) ...

    $(pre#out).text = String.printf("%V",this.value).replace("\t","  ");
});


В процессе работы программы форма будет меняться, т.е. могут добавляться и (или) удаляться некоторые элементы (checkbox, radio, select и т.д.).
Условия, по которым некоторые элементы мне нужно будет делать выключенными (disabled) тоже будут меняться.

Если бы все условия были известны, я бы их просто добавил в скрипт.

Как в процессе работы программы можно менять эти условия?
Re[3]: Повесить обработчик событий onClick на элемент
От: c-smile Канада http://terrainformatica.com
Дата: 16.03.15 17:42
Оценка: 3 (1)
Здравствуйте, DmitryScaletta, Вы писали:

DS>Как в процессе работы программы можно менять эти условия?


Если я правильно понял мысль ...

Есть такая функция eval(text, globals). С её помощью можно интерпретировать скрипты. Например так:

<html>
  <head>
    <script type="text/tiscript">
    
    var formItems = {};
    
    function self.ready() 
    {
      var form = $(form);
      var rule = $(textarea#rule);
    
      // formItems is a name/element collection 
      for( var el in form.$$(button,input,select) ) 
      {
        var name = el.attributes["name"];
        formItems[symbol(name)] = el;
      }
      
      form.on("change", function() {
        eval( rule.value, formItems ); // passing formItems as global items
      });
    }
    
    </script>
  </head>
<body>
  <p>Form</p>
  <form>
    <button|checkbox name="checkbox1">checkbox1</button>
    <button|checkbox name="checkbox2">checkbox2</button>
    <button|checkbox name="checkbox3">checkbox3</button>
  </form>
  <p>Rule</p>
<textarea #rule>
  if (checkbox1.value && checkbox2.value)
      checkbox3.state.disabled = false;
  else 
      checkbox3.state.disabled = true;
</textarea>
  <p>Form value</p>
  <pre#out></pre>

</body>
</html>


Обрати внимание что правила берутся из textarea, т.е. могут меняться на ходу.
Можно также текст из textarea#rule компилировать в функцию и уже её вызывать вместо eval.
Так имеет смысл делать если правило меняется редко а его интерпретация — часто.
Re[4]: Повесить обработчик событий onClick на элемент
От: DmitryScaletta Беларусь  
Дата: 17.03.15 05:54
Оценка:
c-smile,

Т.е. можно сделать невидимую textarea, программно изменять в ней текст скрипта, и он будет выполняться?
Re[5]: Повесить обработчик событий onClick на элемент
От: c-smile Канада http://terrainformatica.com
Дата: 17.03.15 06:03
Оценка: 3 (1)
Здравствуйте, DmitryScaletta, Вы писали:

DS>c-smile,


DS>Т.е. можно сделать невидимую textarea, программно изменять в ней текст скрипта, и он будет выполняться?


Зачем обязательно textarea для этого? Переменную заведи и функцию.

    <script type="text/tiscript">
    
    var formItems = {};
    var rules = "";
    
    function self.ready() 
    {
      var form = $(form);
    
      // formItems is a name/element collection 
      for( var el in form.$$(button,input,select) ) 
      {
        var name = el.attributes["name"];
        formItems[symbol(name)] = el;
      }
      
      form.on("change", function() {
        if( rules )  
          eval( rules, formItems ); // passing formItems as global items
      });
    }

    function setRules(text) {
      rules = text; 
    }
    
    </script>


И зови ту функцию из C++:

  sciterWnd->call_function("setRules", sciter::value(L"........"));


делов-то
Re[6]: Повесить обработчик событий onClick на элемент
От: DmitryScaletta Беларусь  
Дата: 17.03.15 06:10
Оценка:
c-smile,

CS>Зачем обязательно textarea для этого? Переменную заведи и функцию.

То, что нужно! Спасибо.

Еще вопрос:
В коде C++ JSON строку можно парсить?
Через скрипт нашел примеры парсинга.
Re[7]: Повесить обработчик событий onClick на элемент
От: flаt  
Дата: 17.03.15 06:46
Оценка: 2 (1)
Здравствуйте, DmitryScaletta, Вы писали:

DS>В коде C++ JSON строку можно парсить?

json::value result = json::value::from_string(src)?
Re[8]: Повесить обработчик событий onClick на элемент
От: DmitryScaletta Беларусь  
Дата: 17.03.15 09:58
Оценка:
Здравствуйте, flаt, Вы писали:

F>json::value result = json::value::from_string(src)?


А как дальше с результатом работать?

Например как сделать что-то типа этого
string s = result["key"];


Документацию нигде не могу найти.
Re[9]: Повесить обработчик событий onClick на элемент
От: flаt  
Дата: 17.03.15 14:50
Оценка: 3 (1) +1
Здравствуйте, DmitryScaletta, Вы писали:

DS>А как дальше с результатом работать?

// по шагам
json::value v = result.get_item(L"key"); // в общем случае
json::string s = v.get(L""); // L"" - значение по-умолчанию


// если value константный, value[] возвращает так же value, у которого можно звать его методы
json::string s = result[L"key"].get(L"");

// если не константный, то value[] возвращает прокси value_idx или value_key, которые используются для записи:
result[L"key2"] = json::value(42);


DS>Документацию нигде не могу найти.

Документация — методы json::value в value.hpp.
Re[8]: Повесить обработчик событий onClick на элемент
От: c-smile Канада http://terrainformatica.com
Дата: 17.03.15 18:02
Оценка:
Здравствуйте, flаt, Вы писали:

DS>>В коде C++ JSON строку можно парсить?


F>json::value result = json::value::from_string(src)?


На самом деле

value result = value::from_string(str, CVT_JSON_LITERAL);


CVT_JSON_LITERAL — в том случае если str это JSON текст.
Re[9]: Повесить обработчик событий onClick на элемент
От: c-smile Канада http://terrainformatica.com
Дата: 18.03.15 04:22
Оценка:
Здравствуйте, DmitryScaletta, Вы писали:

DS>Например как сделать что-то типа этого

DS>
string s = result["key"];


DS>Документацию нигде не могу найти.


Или как flat сказал или вот

// sciter::string - alias of std::wstring
sciter::string s = result["key"].get<sciter::string>();
Re[10]: Повесить обработчик событий onClick на элемент
От: DmitryScaletta Беларусь  
Дата: 26.03.15 19:51
Оценка:
c-smile,

Можно подробнее рассказать про функцию eval?

Как она работает?

Насколько я понял, первым параметром передается код, а вторым — массив элементов, которые будут глобальными для кода, который передан первым параметром.
Re[11]: Повесить обработчик событий onClick на элемент
От: c-smile Канада http://terrainformatica.com
Дата: 27.03.15 01:18
Оценка:
DS>Можно подробнее рассказать про функцию eval?

DS>Как она работает?


Re[2]: Повесить обработчик событий onClick на элемент
От: DmitryScaletta Беларусь  
Дата: 16.07.15 17:55
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, DmitryScaletta, Вы писали:


DS>>Как мне на "my_div" повесить обработчик событий onClick?


CS>Все DOM событиия всплывают по цепочке контейнеров к окну поэтому если у тебя окно отнаследовано от sciter::event_handler то все DOM events туда приходят.

CS>Поэтому ты можешь написать нечто типа:
CS>
CS>bool my_window::on_event(HELEMENT he, HELEMENT target, BEHAVIOR_EVENTS type, UINT_PTR reason) {
CS>  if( type == BUTTON_CLICK && dom::element(target).test("#table > .my_div") )
CS>    on_my_div_clicked();
CS>}
CS>


Добавил в класс окна метод

bool on_event(HELEMENT he, HELEMENT target, BEHAVIOR_EVENTS type, UINT_PTR reason) {
    if (type == BUTTON_CLICK && sciter::dom::element(target).test("button#message"))
    {
        MessageBox(_hwnd, L"test", L"", 0);
    }
    return true;
}


Нажимаю на кнопку button#message.

Метод вызывается 2 раза.

Первый раз значение type — 32769, второй — 65537
А BUTTON_CLICK = 0

В итоге код не работает.

  screens
http://i.imgur.com/TvA1RrQ.png
http://i.imgur.com/fAKwQBO.png
Отредактировано 16.07.2015 18:00 DmitryScaletta . Предыдущая версия .
Re[3]: Повесить обработчик событий onClick на элемент
От: c-smile Канада http://terrainformatica.com
Дата: 16.07.15 18:40
Оценка:
Здравствуйте, DmitryScaletta, Вы писали:

DS>Добавил в класс окна метод


DS>
DS>bool on_event(HELEMENT he, HELEMENT target, BEHAVIOR_EVENTS type, UINT_PTR reason) {
DS>    if (type == BUTTON_CLICK && sciter::dom::element(target).test("button#message"))
DS>    {
DS>        MessageBox(_hwnd, L"test", L"", 0);
DS>    }
DS>    return true;
DS>}
DS>


DS>Нажимаю на кнопку button#message.


DS>Метод вызывается 2 раза.


DS>Первый раз значение type — 32769, второй — 65537

DS>А BUTTON_CLICK = 0

Поменяй
return true;

на это
return false; // event not handled


и будет тебе шастя.

В твоем коде ты получаешь событие (BUTTON_CLICK | SINKING) и возвращаешь true что значит "consumed".
Engine честно выполняет твое пожелание поэтому дальше это событие уже идет под кодом (BUTTON_CLICK | HANDLED) что ты и наблюдаешь.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.