selecting an option from the list

Post Reply
Natter
Posts: 1402
Joined: Mon May 14, 2007 9:49 am

selecting an option from the list

Post by Natter »

Hi,

On someone else's site, the drop-down list is implemented something like this

Code: Select all | Expand

<div class="main-ui-control main-ui-select" data-name="UF_CRM_1768552906866"
 data-params='{"isMulti":false,"fieldName":"UF_CRM_1768552906866"}'
 data-items='[{"NAME":"Option 1","VALUE":"","IS_SELECTED":true},
              {"NAME":"Option 2","VALUE":1853,"IS_SELECTED":false},
              {"NAME":"Option 3";"VALUE":1854,"IS_SELECTED":false},
              {"NAME":"Option 4","VALUE":1855,"IS_SELECTED":false},
              {"NAME":"Option 5","VALUE":1856,"IS_SELECTED":false}]'
 data-value='{"NAME":"Option 1","VALUE":1853,"IS_SELECTED":false}'
  <span class="main-ui-select-name">Option 1</span>
  <span class="main-ui-square-search"><input type="text" tabindex="undefined" class="main-ui-square-search-item"></span>
</div>

I open this website via Webview and want to make a script for selecting an option from the list. How do I build a script in this case?

User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: selecting an option from the list

Post by Antonio Linares »

This is a custom dropdown (looks like Bitrix24 CRM), not a native <select>. You need to simulate the click interaction
via JavaScript. Here's how:

Step 1: Click the dropdown to open it

// First, click the dropdown to open the options popup

Code: Select all | Expand

oWebView:ExecuteScript( ;
     'document.querySelector(''[data-name="UF_CRM_1768552906866"]'').click()' )

Step 2: Wait briefly, then click the desired option

The popup is dynamically created. After clicking, Bitrix renders a menu with main-ui-select-inner-item elements. You
need a small delay:

Code: Select all | Expand

// Select "Option 3" (VALUE=1854) after a short delay
  oWebView:ExecuteScript( ;
     'setTimeout(function() {' + ;
     '  var items = document.querySelectorAll(".main-ui-select-inner-item");' + ;
     '  for (var i = 0; i < items.length; i++) {' + ;
     '    if (items[i].textContent.trim() === "Option 3") {' + ;
     '      items[i].click();' + ;
     '      break;' + ;
     '    }' + ;
     '  }' + ;
     '}, 300)' )

  Alternative: Select by VALUE instead of text

  If you know the value (e.g. 1854), you can set it directly via the data attributes:

  // Programmatically set the value by manipulating the data-value attribute
  // and dispatching the change event
  local cJS := ;
     'var el = document.querySelector(''[data-name="UF_CRM_1768552906866"]'');' + ;
     'var items = JSON.parse(el.getAttribute("data-items"));' + ;
     'var target = items.find(function(i) { return i.VALUE == 1854; });' + ;
     'if (target) {' + ;
     '  items.forEach(function(i) { i.IS_SELECTED = false; });' + ;
     '  target.IS_SELECTED = true;' + ;
     '  el.setAttribute("data-items", JSON.stringify(items));' + ;
     '  el.setAttribute("data-value", JSON.stringify(target));' + ;
     '  el.querySelector(".main-ui-select-name").textContent = target.NAME;' + ;
     '  el.click();' + ;
     '  setTimeout(function() {' + ;
     '    var popup = document.querySelectorAll(".main-ui-select-inner-item");' + ;
     '    for (var i = 0; i < popup.length; i++) {' + ;
     '      if (popup[i].textContent.trim() === target.NAME) {' + ;
     '        popup[i].click(); break;' + ;
     '      }' + ;
     '    }' + ;
     '  }, 300);' + ;
     '}'

  oWebView:ExecuteScript( cJS )

Complete helper function:

Code: Select all | Expand

function SelectUIOption( oWebView, cFieldName, xValue )

 local cJS

 // xValue can be numeric (VALUE) or string (NAME)
 if ValType( xValue ) == "N"
    cJS := 'var el = document.querySelector(''[data-name="' + cFieldName + '"]'');' + ;
           'el.click();' + ;
           'setTimeout(function() {' + ;
           '  var items = JSON.parse(el.getAttribute("data-items"));' + ;
           '  var t = items.find(function(i){ return i.VALUE == ' + LTrim(Str(xValue)) + '; });' + ;
           '  if (t) {' + ;
           '    var popup = document.querySelectorAll(".main-ui-select-inner-item");' + ;
           '    for (var i = 0; i < popup.length; i++) {' + ;
           '      if (popup[i].textContent.trim() === t.NAME) { popup[i].click(); break; }' + ;
           '    }' + ;
           '  }' + ;
           '}, 300)'
 else
    cJS := 'document.querySelector(''[data-name="' + cFieldName + '"]'').click();' + ;
           'setTimeout(function() {' + ;
           '  var popup = document.querySelectorAll(".main-ui-select-inner-item");' + ;
           '  for (var i = 0; i < popup.length; i++) {' + ;
           '    if (popup[i].textContent.trim() === "' + xValue + '") { popup[i].click(); break; }' + ;
           '  }' + ;
           '}, 300)'
 endif

 oWebView:ExecuteScript( cJS )

  return nil

Usage:
// By value

Code: Select all | Expand

SelectUIOption( oWebView, "UF_CRM_1768552906866", 1854 )

// By name

Code: Select all | Expand

SelectUIOption( oWebView, "UF_CRM_1768552906866", "Option 3" )

The key insight is that these Bitrix custom dropdowns require two clicks: one to open the popup, then one on the
option. The setTimeout gives the popup time to render. If 300ms isn't enough, increase to 500.

regards, saludos

Antonio Linares
www.fivetechsoft.com
Natter
Posts: 1402
Joined: Mon May 14, 2007 9:49 am

Re: selecting an option from the list

Post by Natter »

Antonio, thank you very much!!!This is really a Bitrix24 CRM, I have to transfer some data from my FWH program to it.

Natter
Posts: 1402
Joined: Mon May 14, 2007 9:49 am

Re: selecting an option from the list

Post by Natter »

Bitrix24 CRM has all sorts of internal methods. For example, the "Add a deal" (crm.deal.add) method.
Is it possible to call it via WebView, or is it easier to use Curl?

User avatar
Antonio Linares
Site Admin
Posts: 44515
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: selecting an option from the list

Post by Antonio Linares »

Dear Yuri,

Code: Select all | Expand

  #include "hbcurl.ch"

  FUNCTION Main()

 LOCAL hCurl
 LOCAL cUrl      := "https://your-domain.bitrix24.com/rest/1/your-webhook-token/crm.deal.add"
 LOCAL cPayload  := '{"fields":{"TITLE":"New Deal","STAGE_ID":"NEW","CURRENCY_ID":"USD","OPPORTUNITY":5000}}'
 LOCAL cResponse := ""
 LOCAL nError

 hb_curl_global_init()

 hCurl := curl_easy_init()

 IF ! Empty( hCurl )

    curl_easy_setopt( hCurl, HB_CURLOPT_URL, cUrl )
    curl_easy_setopt( hCurl, HB_CURLOPT_POST, .T. )
    curl_easy_setopt( hCurl, HB_CURLOPT_POSTFIELDS, cPayload )
    curl_easy_setopt( hCurl, HB_CURLOPT_HTTPHEADER, { "Content-Type: application/json" } )
    curl_easy_setopt( hCurl, HB_CURLOPT_DL_BUFF_SETUP )

    nError := curl_easy_perform( hCurl )

    IF nError == HB_CURLE_OK
       cResponse := curl_easy_dl_buff_get( hCurl )
       ? "Response:", cResponse
    ELSE
       ? "Error:", curl_easy_strerror( nError )
    ENDIF

    curl_easy_cleanup( hCurl )

 ENDIF

 hb_curl_global_cleanup()

  RETURN NIL
regards, saludos

Antonio Linares
www.fivetechsoft.com
Natter
Posts: 1402
Joined: Mon May 14, 2007 9:49 am

Re: selecting an option from the list

Post by Natter »

Thanks, I get it !
Probably, if I can do this via CMD, it will also work.

Code: Select all | Expand

curl -X POST ^
-H "Content-Type: application/json" ^
-d "{\"fields\":{\"TITLE\":\"New_CRM\",\"STAGE_ID\":\"NEW\",\"OPPORTUNITY\":150000,\"CURRENCY_ID\":\"RUB\",\"TYPE_ID\":\"SALE\"}}" ^
"https://b24-xyz.bitrix24.ru/rest/1/vov4i...l09/crm.deal.add"
Natter
Posts: 1402
Joined: Mon May 14, 2007 9:49 am

Re: selecting an option from the list

Post by Natter »

Is it possible to create an incoming webhook programmatically ?

Post Reply