locked
Radio Button for LightSwitch Html RRS feed

  • Question

  • Doe anyone have a good example of how to create a custom control for radio buttons. I have a survey which has a question which will have 6 options along with it.   Specifically how do I bind the selected value of the radio button to my field in the javascript code behind?
    Tuesday, December 29, 2015 9:04 PM

Answers

  • Hi,

    Jewel Lambert had once explained this nicely, unfortunately the link won't work but fortunately I have the source code ;).

    • Add a property "myOptions" (type integer) to your screen.
    • Create a choice list for myOptions with the options you want
    • Drag and drop the property to the screen and change its type to custom control

    Here is the render code:

    myapp.OtherControls.myOptions_render = function (element, contentItem) {
        lscontrols.radioButtons(element, contentItem, {
            isHorizontal: false
        });
    };
    
    (function () {
        function radioButtons(element, contentItem, options) {
            var rbSetName = 'rb' + contentItem.name,
                $rb,
                $rbInputs,
                $div;
    
            options = options || {};
            options.isHorizontal = options.isHorizontal || false;
            options.choiceList = options.choiceList || contentItem.choiceList;
    
            function radioButtonChoice(item) {
                var id = rbSetName + item.value,
                    html = '<input type="radio" name="' + rbSetName + '" id="' + id + '" value="' + item.value + '" />' +
                        '<label for="' + id + '">' + item.stringValue + '</label>';
                return $(html);
            }
    
            function label(text) {
                var $l = $("<label class='msls-label-text'>").text(text);
    
                // to keep this example simple, I'm hardcoding the label alignment to 'Top'
                // if you need a different alignment, you may want to look at the _addAttachedLabel
                // function in the msls js file
                var $d = $("<div class='msls-attached-label msls-label-align-top msls-clear msls-vauto'>");
                return $d.append($l);
            }
    
            $rb = $("<fieldset id='" + rbSetName + "' data-role='controlgroup' data-type='" +
                (options.isHorizontal ? "horizontal" : "vertical") + "'>");
    
            options.choiceList.forEach(function (item) {
                //DV - Sometimes LS adds an extra empty choice list item
                if (item.value.toString().length != 0) {
                    $rb.append(radioButtonChoice(item));
                }
            });
    
            if (contentItem.kind === "Details") {
                // msls doesn't auto add a label for custom group controls
                label(contentItem.displayName).appendTo(element);
    
                // msls isn't putting the leaf class on custom group controls, 
                // though it does use it on custom value controls and its own group controls
                // we have to add it in manually otherwise the alignment will be off
                $(element).addClass("msls-leaf");
            }
    
            // the classes of the div and parent are important so that things align properly
            // I'm hardcoding for top-labels to keep things simple for now
            $div = $("<div class='msls-clear msls-vauto'>").append($rb);
            $div.appendTo(element);
    
    
            // bind so that changing radio buttons changes the contentItem value
            $rbInputs = $rb.find("input");
            $rbInputs.change(function () {
                var newValue = $(this).val();
    
                if (contentItem.kind === "Details") {
                    // ids should be unique, so return the first match
                    // (note: inefficient... better would be something like underscore/lodash's find)
                    contentItem.value = options.choiceList.filter(function (choice) {
                        return choice.value.toString() === newValue;
                    })[0].entity;
                } else {
                    contentItem.value = newValue;
                }
            });
    
            // bind so that changing the contentItem value changes the radio button
            contentItem.dataBind("value", function (data) {
                if (!!data) {
                    if (contentItem.kind === "Details") {
                        data = contentItem.value.Id;
                    }
                    $rbInputs.each(function () {
                        this.checked = this.value === data.toString();
                        // make sure control has been initialized first... if so, refresh
                        if ($(this).parent().hasClass("ui-radio")) {
                            $(this).checkboxradio("refresh");
                        }
                    });
                }
            });
        }
    
        window.lscontrols = {
            radioButtons: radioButtons
        };
    
    }());
    


    Divyang Vyas

    • Marked as answer by Darn-o Wednesday, December 30, 2015 1:51 PM
    Wednesday, December 30, 2015 12:28 PM

All replies

  • Hi,

    Jewel Lambert had once explained this nicely, unfortunately the link won't work but fortunately I have the source code ;).

    • Add a property "myOptions" (type integer) to your screen.
    • Create a choice list for myOptions with the options you want
    • Drag and drop the property to the screen and change its type to custom control

    Here is the render code:

    myapp.OtherControls.myOptions_render = function (element, contentItem) {
        lscontrols.radioButtons(element, contentItem, {
            isHorizontal: false
        });
    };
    
    (function () {
        function radioButtons(element, contentItem, options) {
            var rbSetName = 'rb' + contentItem.name,
                $rb,
                $rbInputs,
                $div;
    
            options = options || {};
            options.isHorizontal = options.isHorizontal || false;
            options.choiceList = options.choiceList || contentItem.choiceList;
    
            function radioButtonChoice(item) {
                var id = rbSetName + item.value,
                    html = '<input type="radio" name="' + rbSetName + '" id="' + id + '" value="' + item.value + '" />' +
                        '<label for="' + id + '">' + item.stringValue + '</label>';
                return $(html);
            }
    
            function label(text) {
                var $l = $("<label class='msls-label-text'>").text(text);
    
                // to keep this example simple, I'm hardcoding the label alignment to 'Top'
                // if you need a different alignment, you may want to look at the _addAttachedLabel
                // function in the msls js file
                var $d = $("<div class='msls-attached-label msls-label-align-top msls-clear msls-vauto'>");
                return $d.append($l);
            }
    
            $rb = $("<fieldset id='" + rbSetName + "' data-role='controlgroup' data-type='" +
                (options.isHorizontal ? "horizontal" : "vertical") + "'>");
    
            options.choiceList.forEach(function (item) {
                //DV - Sometimes LS adds an extra empty choice list item
                if (item.value.toString().length != 0) {
                    $rb.append(radioButtonChoice(item));
                }
            });
    
            if (contentItem.kind === "Details") {
                // msls doesn't auto add a label for custom group controls
                label(contentItem.displayName).appendTo(element);
    
                // msls isn't putting the leaf class on custom group controls, 
                // though it does use it on custom value controls and its own group controls
                // we have to add it in manually otherwise the alignment will be off
                $(element).addClass("msls-leaf");
            }
    
            // the classes of the div and parent are important so that things align properly
            // I'm hardcoding for top-labels to keep things simple for now
            $div = $("<div class='msls-clear msls-vauto'>").append($rb);
            $div.appendTo(element);
    
    
            // bind so that changing radio buttons changes the contentItem value
            $rbInputs = $rb.find("input");
            $rbInputs.change(function () {
                var newValue = $(this).val();
    
                if (contentItem.kind === "Details") {
                    // ids should be unique, so return the first match
                    // (note: inefficient... better would be something like underscore/lodash's find)
                    contentItem.value = options.choiceList.filter(function (choice) {
                        return choice.value.toString() === newValue;
                    })[0].entity;
                } else {
                    contentItem.value = newValue;
                }
            });
    
            // bind so that changing the contentItem value changes the radio button
            contentItem.dataBind("value", function (data) {
                if (!!data) {
                    if (contentItem.kind === "Details") {
                        data = contentItem.value.Id;
                    }
                    $rbInputs.each(function () {
                        this.checked = this.value === data.toString();
                        // make sure control has been initialized first... if so, refresh
                        if ($(this).parent().hasClass("ui-radio")) {
                            $(this).checkboxradio("refresh");
                        }
                    });
                }
            });
        }
    
        window.lscontrols = {
            radioButtons: radioButtons
        };
    
    }());
    


    Divyang Vyas

    • Marked as answer by Darn-o Wednesday, December 30, 2015 1:51 PM
    Wednesday, December 30, 2015 12:28 PM
  • Thanks so much.  Worked perfectly.
    Wednesday, December 30, 2015 1:51 PM
  • Jewel Lambert had once explained this nicely, unfortunately the link won't work but fortunately I have the source code ;).

    If you're still interested in viewing Jewell's great website, it can still be accessed by using the Internet Archive's Wayback Machine (going back to April 2015): -

    http://web.archive.org/web/20150424222407/http://jewellambert.com/

    HTH,

    Chris



    • Edited by ChrisCookDev Wednesday, December 30, 2015 2:20 PM
    Wednesday, December 30, 2015 2:08 PM