void checkall (dom::element& table, bool onOff )
    {
      if( !is_multiple(table) ) return;

      struct unchecker_cb: dom::callback 
      {
          bool on_element(HELEMENT he) 
          { 
            htmlayout::dom::element el = he; if( el.get_state(STATE_CHECKED)) el.set_state(0,STATE_CHECKED,false ); return false; /*continue enumeration*/ 
          }
      };
      struct checker_cb: dom::callback 
      {
          bool on_element(HELEMENT he) 
          { 
            htmlayout::dom::element el = he; if( !el.get_state(STATE_CHECKED)) el.set_state(STATE_CHECKED,0,false ); return false; /*continue enumeration*/ 
          }
      };

      if(onOff) 
      {
        checker_cb checker;
        table.find_all(&checker,"tr");
      }
      else
      {
        unchecker_cb unchecker;
        table.find_all(&unchecker,"tr:checked");
      }
	  }
/** Get values of all "controls" contained inside the DOM element. 
 *  Function will gather values of elements having name attribute defined
 *  and recognized by get_ctl_type() function.
 * \param[in] el \b dom::element&, The element.
 * \param[out] all \b named_values&, Collection.
 * \return \b bool, \c true if there are any value was harvested.
 **/
  inline bool get_values(const dom::element& el, named_values& all )
  {
    selected_cb selected;
    el.find_all(&selected, "[name]" ); // select all elements having name attribute
    for( unsigned int n = 0; n < selected.elements.size(); ++n )
    {
      const dom::element& t = selected.elements[n];
      //if( !t.get_style_attribute("behavior") )
      //  continue; - commented out to support input type="hidden" that does not have behavior assigned
      const wchar_t* pn = t.get_attribute("name");
      if( !pn )
      {
        assert(false); // how come?
        continue;
      }
      std::wstring name = pn;
      if( all.find(name) != all.end()) 
        continue; // element with this name is already there, 
                  // checkboxes and radios are groups in fact,
                  // we are returning here only cumulative group value
      int ctl_type = get_ctl_type(t);
      if( ctl_type == CTL_NO/*|| ctl_type == CTL_BUTTON*/)
        continue;
      all[name] = get_value(selected.elements[n]);
    }
    return all.size() != 0;
  }
    static BOOL process_key( dom::element& container, const char* keyname )
    {
        // find all callback 
        struct:public htmlayout::dom::callback 
        {
          htmlayout::dom::element hot_key_element;
          virtual bool on_element(HELEMENT he) 
          {
            htmlayout::dom::element t = he; 
            if( t.enabled() && t.visible())
            {
              hot_key_element = t;
              return true; // found, stop;
            }
            return false;
          }
        } cb;
        
        //Original version was:
        //  container.find_all(&cb, "[accesskey=='%s']", keyname);
        
        //By request of Christopher Brown, the Great, from Symantec this became as: 
        container.find_all(&cb, "[accesskey=='%s'],[accesskey-alt=='%s']", keyname, keyname);

        if( cb.hot_key_element.is_valid())
        {
          METHOD_PARAMS prm; prm.methodID = DO_CLICK; 
          if(cb.hot_key_element.call_behavior_method(&prm))
            return true;
        }
        return false;
    }
  // selects all options in multiselect.
  inline void select_all_options(dom::element& select_el )
  {
    selected_cb all_options;
    select_el.find_all(&all_options, "option"); // select all currently selected <option>s

    for( int n = int(all_options.elements.size()) - 1; n >= 0 ; --n )
       all_options.elements[n].set_state(STATE_CHECKED,0, false); // set state
    select_el.update();
  }
  // clear checked states in multiselect <select>.
  // this simply resets :checked state for all checked <option>'s
  inline void clear_all_options(dom::element& select_el )
  {
    selected_cb selected;
    select_el.find_all(&selected, "option:checked,[role='option']:checked"); // select all currently selected <option>s

    for( int n = int(selected.elements.size()) - 1; n >= 0 ; --n )
      selected.elements[n].set_state(0, STATE_CHECKED, false); // reset state

    select_el.update();
  }
 // the same as above but for arbitrary root/name 
 inline void set_radio_index( dom::element root, const char* name, unsigned int idx  )
 {
   selected_cb selected;
   root.find_all(&selected, "[type='radio'][name='%S']", name);
   for( unsigned int n = 0; n < selected.elements.size(); ++n )
   {
     dom::element& e = selected.elements[n];
     if ( n == idx)
     {
       e.set_value(json::value(true));
       break;
     }
   }
 }
예제 #7
0
    static BOOL process_key( dom::element& container, const char* keyname )
    {
        // find all callback 
        struct:public htmlayout::dom::callback 
        {
          htmlayout::dom::element hot_key_element;
          virtual bool on_element(HELEMENT he) 
          {
            htmlayout::dom::element t = he;
            if( !t.enabled() )
              return false;
            if( t.test("menu>li") )
            {
              hot_key_element = t;
              return true; // found, stop;
            }
            if(t.visible())
            {
              hot_key_element = t;
              return true; // found, stop;
            }
            return false;
          }
        } cb;
        
        //Original version was:
        //  container.find_all(&cb, "[accesskey=='%s']", keyname);
        
        //By request of Christopher Brown, the Great, from Symantec this became as: 
        container.find_all(&cb, "[accesskey=='%s'],[accesskey-alt=='%s']", keyname, keyname);

        if( cb.hot_key_element.is_valid())
        {
          METHOD_PARAMS prm; prm.methodID = DO_CLICK; 
          //cb.hot_key_element.set_state(STATE_FOCUS);
          if(cb.hot_key_element.call_behavior_method(&prm))
            return true;
          
          // accesskey is defined for the element but it does not
          // handle DO_CLICK. Ask parents to activate it.
          // See behavior_tabs.cpp...
          htmlayout::dom::element hot_element_parent = cb.hot_key_element.parent();
          
          return hot_element_parent.send_event(ACTIVATE_CHILD,0, cb.hot_key_element);
        }
        return false;
    }
    //toggles checkmark
    void toggle_checkmark( dom::element select, dom::element item )
    {
      const wchar_t* _old_state = item.get_attribute(CHECK_ATTR);
      std::wstring  old_state = _old_state?_old_state:L"";

      if( streq(item.get_element_type(), "options"))
      {
        // non-terminal node case 
        
        // inner function
        struct child_toggler: dom::callback
        {
          const wchar_t* state;
          child_toggler(const wchar_t* st): state(st) {}
          inline bool on_element(HELEMENT he) 
          { 
            htmlayout::dom::element item = he; 
            item.set_attribute( CHECK_ATTR, state );
            return false;
          }
        };
        
        const wchar_t* new_state;
        NODE_STATE old_state = get_state(item);
        if(old_state == NODE_OFF)
          new_state = L"on";
        else 
          new_state = L"off";

        child_toggler ct( new_state );
        // do it for all children
        item.find_all(&ct, "option,options");
        // and for itself
        item.set_attribute( CHECK_ATTR, new_state );
        item.update();
      }
      else if( streq(item.get_element_type(), "option"))
      {
        // terminal node
        const wchar_t* new_state;
        if(wcseq(item.get_attribute("check"),L"on"))
        {
          new_state = L"off";
        }
        else 
          new_state = L"on";

        item.set_attribute( CHECK_ATTR, new_state );
        item.update();
      }
      
      // as state was changed we need to update parent chain here too.
      dom::element p = item.parent();
      while( p.is_valid() && p != select )
      {
        if( streq(p.get_element_type(),"options" ))
        {
          setup_node(p);
        }
        p = p.parent();
      }

    }