MVC UIHint/Parital view with JQuery multiselect, d

2019-09-06 14:10发布

I've been using this tutorial to create a screen where a user can add additional input fields on a given screen

Instead of using all textboxes Iv'e created a UIHint/Partial view that'll render a multi-select JQuery widget (I'm using this component)

ViewModel for each row item

 public class Micros
    {
        [UIHint("JsonComboBox")]
        [AdditionalMetadata("id", "Lab_T_ID")]
        [AdditionalMetadata("description", "Description")]
        [AdditionalMetadata("action", "LabTestOptions")]
        [AdditionalMetadata("controller", "Micro")]
        [AdditionalMetadata("noneSelectedText", "Test")]
        [AdditionalMetadata("comboboxWidth", "200")] 
        [DisplayName("Test")]
        public Nullable<int> Lab_T_ID { get; set; }

        [UIHint("JsonComboBox")]
        [AdditionalMetadata("id", "Lab_SD_ID")]
        [AdditionalMetadata("description", "Description")]
        [AdditionalMetadata("action", "LabSampleDetailOptions")]
        [AdditionalMetadata("controller", "Micro")]
        [AdditionalMetadata("noneSelectedText", "Sample Details")]
        [AdditionalMetadata("comboboxWidth", "300")]
        [DisplayName("Sample Details")]
        public Nullable<int> Lab_SD_ID { get; set; }

        [DisplayName("Result")]
        public string Result { get; set; }
    }

Partial View/UIHint

@model int?
@{
    var values = ViewData.ModelMetadata.AdditionalValues;
}
<select id="@values["id"]" multiple="multiple" style="width:@values["comboboxWidth"]px" > </select>
<script type="text/javascript">

        $.getJSON('@Url.Action((string)values["action"], (string)values["controller"])', 
                     null,
                    function (j) {
                        var options = '';

                    for (var i = 0; i < j.length; i++) {
                        options += '<option value="' + j[i].@values["id"] + '">' + j[i].@values["description"] + '</option>';
                    }
                    $('#@values["id"]').html(options);
                    $('#@values["id"] option:first').attr('selected', 'selected');
        });


    setTimeout(function () {

     $("#@values["id"]").multiselect({
       multiple: false,
       header: "Select an option",
       noneSelectedText: '@values["noneSelectedText"]',
       selectedList: 1
    });

    }, 300);

</script>

The components render fine on the initial page load, but when add the items, they get added... but it seems that the javascript doesn't execute/get added..

enter image description here

Any ideas? Still debugging this issue, will post the fix as soon as I find it, but I'm hoping someone can point me in the right direction

Update

So far I've discovered that (We'll it looks like), the UIHint/Partials don't get rendered at all when the user clicks to add another item. (Otherwise the select will be populated with items, and the JQuery widget will be applied)

enter image description here

1条回答
做自己的国王
2楼-- · 2019-09-06 14:52

I would recommend you to remove all javascript from your partial. Javascript shouldn't be mixed with markup. So your editor template should contain only markup:

@model int?
@{
    var values = ViewData.ModelMetadata.AdditionalValues;
}


<span>
    <select multiple="multiple" style="width:@values["comboboxWidth"]px" data-url="@Url.Action((string)values["action"], (string)values["controller"])" data-noneselectedtext="@values["noneSelectedText"]" data-value="@values["id"]" data-text="@values["description"]"></select>
</span>

and then in a separate javascript file you will have a function which will be used when the Add another... button is clicked as shown in Steven Sanderson's article:

$('#addItem').click(function() {
    $.ajax({
        url: this.href,
        cache: false,
        success: function(html) { 
            // Here's the place to attach any plugins to the given row:

            var select = $('select', html);
            $.getJSON(select.data('url'), function(options) {
                $.each(options, function() {
                    select.append(
                        $('<option/>', {
                            value: this[select.data('value')],
                            text: this[select.data('text')]
                        })
                    );
                });

                select.multiselect({
                    multiple: false,
                    header: 'Select an option',
                    noneSelectedText: select.data('noneselectedtext'),
                    selectedList: 1
                });

                $('#editorRows').append(select);

            });
        }
    });
    return false;
});
查看更多
登录 后发表回答