0

There is a website that I want to simulate user clicks on. In this website, there is the following div, let's call it div1, where there is a dropdown menu. There are actually other two similar divs (lets call them div2 and div3) following but I didn't place here for the simplicity. When you select one of the item in the dropdown menu in div1, the div2 is enabled (disabled by default in the beginning) and its menu content is fetched from database based on the item selected from the div1.

I can select the menu item using following script.

Code:

function setSelectedValue(selectObj, valueToSet) { 
    for (var i = 0; i < selectObj.options.length; i++) { 
        if (selectObj.options[i].value== valueToSet) {
            selectObj.options[i].selected = true;
            return;
       }
      }
     }

var number = document.getElementById('level1-option');
setSelectedValue(number,  "p3");

However, when I do this, the div2 is never enabled. I tried jQuery code to emit change signal on the dropdown menu but it doesn't work. When I was debugging the below html code, I saw the button tag there and I immediately thought that it submits when there is click. However, I don't see any form. If I debug the website using chrome, I see that the code jumps different js files when I select an item in the menu. Could anyone guide me how I can find out which signal is triggered when an item is selected? Apparently they do some tricks in the website to prevent normal ways of clicking

Code:

<div data-custom-select="" class="custom-select focus">
  <label for="level1-option" class="has-hidden-label label-text">Sections</label>
  <span class="btn-select icon-down_thin">Choose a section</span>
  <select class="categories-options" data-level="1" name="level1-option" id="level1-option" required="">
    <option value="">Choose a section</option>
    <option value="p1" data-href="/callback/discovery/p1/">P1</option>
    <option value="p2" data-href="/callback/discovery/p2/">P2</option>
    <option value="p3" data-href="/callback/discovery/p3/">P3</option>
    <option value="p4" data-href="/callback/discovery/p4/">P4</option>
  </select>
<span class="icon-down_thin"></span>
<button type="submit" class="category-submit ui-button-secondary ">Choose</button>

4 Answers 4

1

Usually you could use:

$("#level1-option").val(valueToSet).trigger("click")

or

$("#level1-option").val(valueToSet).trigger("change")

but it might depend on the rest of the code on the webpage.

Sign up to request clarification or add additional context in comments.

3 Comments

I tried this as well. It doesn't work. If you have some time, please have a look at: fiddle.jshell.net/#&togetherjs=EtECitIIxi
The thing is, that page has a label that covers the dropdown listbox, which has the original value as the label text. So the dropdown value is actually changing, the label isn't. So do you need the lable to change, or just to set the dropdown value?
Hi Sean, The issue is fixed by following snippet: $(function(){ $(".btn-select.icon-down_thin").remove(); $(".custom-select").removeClass("custom-select"); }); However, it is not exactly what I want. What I do now is that, When I select the dropdown using JQuery, I also send a change or click signal to label. I was expecting that the second dropdown will be enabled by this way. However, it isn't. I have prepared another minimal example in fiddle. fiddle.jshell.net/#&togetherjs=GCMVafpqyR Can you have a look if you have some time?
1

Try ...

$(element).trigger('click');

... from jQuery.

1 Comment

Actually, it does answer the question. Not 100% right and in significant depth, but the author showed some good knowledge of programming so I made the assumption that I did not need to get more detailed.
1

Try dispatching onchange event once you have changed its value:

var number = document.getElementById('level1-option');
setSelectedValue(number,  "p3");
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
number.dispatchEvent(evt);

6 Comments

Thanks a lot for your reply but is doesn't seem to work. I have a fiddle example. Could you please have a look at it? fiddle.jshell.net/#&togetherjs=EtECitIIxi
@Dundar Your jsFiddle gave me headhache, try using in console command debugger; and see what's going on when clicking/changing element value. Or check in dev tool Event Listeners tab or post more minimalistic sample on jsFiddle
Awesome help in fiddle. Thank you very much. The issue was that there was an overlay on top of the dropdown which makes it not visible if there is change. we removed that overlay and now it works.
Hi @Dundar. I think that was me that helped you, see the mention of the overlay in the comment on my answer. Anyway, glad you got it sorted.
@Sean For sure it wasn't me ;)
|
1

Sorry, that I couldn't help with the overlay issue. Your markup is pretty complex.

Anyway, I coded a bit for the updating/fetching data from database. Please find below a demo of it. The demo is also here at jsFiddle

The JSON data looks like this {"data": ["1st_1", "1st_2", "1st_3"]}

During my work I had one issue that wasn't that easy to solve, but another SO question helped here. If you'd only use the change event you can't trigger the first element to fetch your next data. The counter trick works pretty well.

var dynamicOptions = (function () {

    var url; // here you can add your url to the backend script
    // urlList only required for demo because no backend available
    var urlList = ['http://www.mocky.io/v2/54839e2a2f4b84a0041bba49',
        'http://www.mocky.io/v2/54839e4c2f4b84a5041bba4a',
        'http://www.mocky.io/v2/54839e6a2f4b84a9041bba4b'];
    
    var cc = 0; // click counter

    // e.g. $optionEl = $('#firstSelection');
    // $nextOptionEl = $('#secondSelection');
    function Selector($optionEl, $nextOptionEl) {
        this.$optionEl = $optionEl;
        this.$nextOptionEl = $nextOptionEl;
       
        this.ajaxRequest = function (optionValue) {
            return $.ajax({
                type: 'GET', // later 'POST'
                //data: {'data': optionValue}, // for posting
                url: url,
                contentType: "application/json",
                dataType: 'jsonp',
                context: this,
            });
        };
      
        this.getData = function(value) {
            url = urlList[value]; // simulating backend returns based on this value
            var ajaxReq = this.ajaxRequest(value); // this.value not used in this demo
            ajaxReq.success(this.jsonCallback)
                .fail(function (xhr) {
                alert("error" + xhr.responseText);
            });
        };
        // handle click and change event. Source from here: https://stackoverflow.com/questions/11002421/jquery-event-to-fire-when-a-drop-down-is-selected-but-the-value-is-not-change
        this.clickHandler = function ($element) {
            //console.log($element);
            var that = this;
            return $element.click(function () {
                //console.log('clicked');
                cc++;
                if (cc == 2) {
                    $(this).change();
                    cc = 0;
                }
            }).change(function (e) {
                cc = -1; // change triggered
                //console.log(this.value);
                that.getData(this.value);
            });
        }

        this.clickHandler($optionEl);

        this.jsonCallback = function (json) {
            var $nextEl = this.$nextOptionEl;
            $nextEl.empty();                    // clear selection
            $nextEl.prop('disabled', false);    // enable 2nd select
           
            this.triggerChangeEvent(); // maybe a check if they really changed would be good
            $.each(json.data, function (index, value) {
                $('<option/>')
                    .val(index)
                    .text(value)
                    .appendTo($nextEl);
            });
        };

        this.triggerChangeEvent = function () {
            var event = jQuery.Event("optionsChanged");
            event.context = this;
            event.message = "Options changed, update other depending options";
            event.time = new Date();

            $.event.trigger(event);
        };
    }

    return {
        Selector: Selector
    }; // make Selector public
})();

$(function () {
    var $first = $('#firstSelection');
    var $second = $('#secondSelection');
    var $third = $('#thirdSelection');

    // use our dynamic options selector class
    var options12 = new dynamicOptions.Selector($first, $second);
    var options23 = new dynamicOptions.Selector($second, $third);

    $(document).on('optionsChanged', function (e) {
        console.log("options changed", e);
        var obj_id = e.context.id;
        //console.log(obj_id);
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<div>
    <form role="form">
        <div class="form-group">
            <label>Please select first value:</label>
            <select id="firstSelection" class="form-control">
                <option value="0">0</option>
                <option value="1">1</option>
                <option value="2">2</option>
            </select>
        </div>
        <div class="form-group">
            <label>Please select second value:</label>
            <select id="secondSelection" class="form-control" disabled="true">
                <!-- fetched from server -->
            </select>
        </div>
        <div class="form-group">
            <label>Please select third value:</label>
            <select id="thirdSelection" class="form-control" disabled="true">
                <!-- fetched from server -->
            </select>
        </div>
    </form>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.