Search code examples
javascriptractivejs

Ractive.js dynamically choose a Select option when a checkbox value changes


I have a checkbox which toggles state - giving a true or false value.

If the value is false, I'd like to hide the select box. If the value is true, I'd like to show the select box. This is all working 'out of the box' with just some template stuff - I simple do:

     {{#if fooState }}
    <select class="form-control" id="addFoo" value='{{selectedFoo}}'>
      <option selected disabled>Select Foo</option>
      {{#foo}}
      <option value="{{_id}}|{{title}}">{{title}}</option>
      {{/foo}}
    </select>
      {{/if}}

However, if I select a Foo option... this option remains selected when I set the fooState to false. I'd like to reset this - so the first option (select Foo) is selected - emptying the {{selectedFoo}} value.

I've tried doing stuff with observe, and events - but cant quite seem to grok this. When I punch my code into the console - I'm able to change the select option... but cant seem to trigger it from when the state changes.


Solution

  • Ok - so I finally figured it out... to do this, I don't lean on the data binding... I create a new on-change event and add that to the select.

    <select class="form-control" id="addFoo" on-change='selectedFoo' >
      <option></option>
    </select>
    
    ractive.on('selectedFoo' , function (event) {
        var resourceArray = event.node.options[event.node.options.selectedIndex].value // Get our selected Foo option
        resourceArray = resourceArray.split('|') 
         var FooData = {
         a1: resourceArray[0],
         a2: resourceArray[1],
         a3: 'foo'
        }
         data.foo.push(resourceData);
       });
    

    So grab the data from the event - and then manually push it onto the array. This is completely self contained - it only affects this single select. Now does everything that I need to it to.

    * Scrub this... it appears to break two way data binding. Please see above *

    So I was watching a Ractive video - and had an epiphany! I was sort of stabbing around in the right area - but doing it all wrong:

    ractive.on('fooStateToggle', function(event) {
        console.log(event)
            if (data.fooState) {
            // Reset our select box! This took me ****ing ages to figure out... but its so, so, simple!
            var addFooElem = ractive.nodes.addFoo;
            addFooElem.selectedIndex = 0;
        } else {
        .....
        }
    });
    

    So I needed to add some code in the event that's fired when the checkbox is clicked (fooStateToggle). Then if fooState is true... we grab the select box from the Ractive node list (not the dom - this is a virtual dom, so doing a direct selection wasn't going to work) and select the the first option by index. One gotcha... when the elem is hidden, its no longer available in the ractive.node list (makes perfect sense as its not being rendered to the page) so you have to catch it as soon as its rendered. You cant act upon it when its hidden - as it doesn't exist. I must say, I'm loving Ractive... I'm finding it so much quicker to pick up than React / Angular or any of the others. I love it! (thats probably going to get edited out by someone - but the guys who made this are awesome. Its made my dev so much easier!!)