Disabled/ReadOnly CSS

10 posts, 1 answers
  1. Keith
    Keith avatar
    35 posts
    Member since:
    Sep 2013

    Posted 03 Feb 2014 Link to this post

    I have a requirement to disable the ComboBox under certain conditions (or make readOnly). Part of the requirement is the appearance of the ComboBox; the dispaly area must have a light Grey background and the Text must be black. However, while I can make the background lightgray, nothing I do works for setting the text to Black.

    I also have the same problem with DatePicker widgets.

    So how do I go about keeping the text color black when the a widget is disabled?
  2. Keith
    Keith avatar
    35 posts
    Member since:
    Sep 2013

    Posted 03 Feb 2014 in reply to Keith Link to this post

    Here's the CSS I'm using:

    input[readonly="readonly"], input[readonly] {
        color: black;
        font-color: black;
        background-color: #dddddd;
    }

    input[type="text"][disabled="disabled"]{
        color: black;
        font-color: black;
        background-color: #dddddd;
    }
  3. Kendo UI is VS 2017 Ready
  4. Dimo
    Admin
    Dimo avatar
    8333 posts

    Posted 04 Feb 2014 Link to this post

    Hi Keith,

    Internet Explorer 9- does not allow changing the text color of disabled elements, so you may need to reconsider your requirements. Another possible cause of the problem in other browsers is insufficient speicificity of your selectors. You can use any DOM inspector (Firebug, etc) to verify this.

    http://coding.smashingmagazine.com/2007/07/27/css-specificity-things-you-should-know/

    Regards,
    Dimo
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  5. Keith
    Keith avatar
    35 posts
    Member since:
    Sep 2013

    Posted 04 Feb 2014 in reply to Dimo Link to this post

    I should have also clarified that to achieve that requirement for other inputs we are setting the input to readOnly, which allows us to set the color of the text. We are also attempting to do the same for kendo widgets. However, I do not see a way to set a kendo widget to readOnly. We created a custom binding to determine when it should be set to readOnly, using a custom "disabled" for styling. You'll see I'm trying to use the "aria-" attributes, but I'm not sure if I'm setting them properly, or if I should even be modifying them at all. Perhaps there is some other attribute,property, or class that would work?

    However, setting the readonly attribute does not seem to work for widgets. I'm still able to edit them in everyway,

    I attempt to retrieve the _list input that is created and set that to readonly as well. However, the binding only executes the "refresh" method once for widgets. The binding does not refresh at all for widgets after binding when the method updates.

    CSS:

    .disabled{
        color: black;
        font-color: black;
        font-weight: bold;
        background-color: #dddddd;
    }


    binding:

    //Custom binding in place of ENABLED that uses readOnly instead - also adds/removed disabled class.
        kendo.data.binders.readOnlyDisable = kendo.data.binders.widget.readOnlyDisable = kendo.data.Binder.extend({
            refresh: function() {
                var that = this,
                    value = this.bindings["readOnlyDisable"].get(),//get the value from the View-Model
                    $element = $(that.element);
                var $comboTextBox = $("input[aria-owns='"+$element.prop('id')+"_listbox']")
                if (value) {
                    $element.prop('readOnly', false);
                    $element.removeClass('disabled');

                    $comboTextBox.prop('readOnly', false);
                    $comboTextBox.removeClass('disabled');

                } else {
                    $element.prop('readOnly', true);
                    $element.addClass('disabled');

                    $comboTextBox.prop('readOnly', false);
                    $comboTextBox.removeClass('disabled');
                }
            }
  6. Keith
    Keith avatar
    35 posts
    Member since:
    Sep 2013

    Posted 04 Feb 2014 in reply to Keith Link to this post

    Just noticed that the second "else" had an error in it. Should be

                    $comboTextBox.prop('readOnly', true);
                    $comboTextBox.addClass('disabled');

    A typing error on my part.

    Side question: Is there a way to edit posts instead of having to reply with a new post?
  7. Keith
    Keith avatar
    35 posts
    Member since:
    Sep 2013

    Posted 04 Feb 2014 in reply to Keith Link to this post

    I did find the readonly method that is available on the widgets, but I'm now experiencing a different problem; the binding does not refresh if it is on a widget (such as ComboBox or DatePicker). Here's the updated binding:

    //Custom binding in place of ENABLED that uses readOnly instead - also adds/removed disabled class.
        kendo.data.binders.allowEdit = kendo.data.binders.widget.allowEdit = kendo.data.Binder.extend({
            refresh: function() {
                var that = this,
                    value = this.bindings["readOnlyDisable"].get(),//get the value from the View-Model
                    $element = $(that.element),
                    dataList = ["kendoPSSComboBox","kendoDatePicker", "kendoGrid"];


                $.each(dataList,function(index,name){

                    var widget = $element.data(name);
                    if($element.prop("id") == "myWidgetID"){
                           // This is just here to verify that the code is being called.
                           // I get the alert box twice when the page loads, but not when I change the datamodel
                        alert("Publication Number")
                    }
                    if(widget && $.isFunction(widget.readonly)){

                        widget.readonly(!value);
                    }

                });

                if (value) {
                    $element.prop('readOnly', false);
                    $element.removeClass('disabled');

                } else {
                    $element.prop('readOnly', true);
                    $element.addClass('disabled');
                }
            }
        });
  8. Keith
    Keith avatar
    35 posts
    Member since:
    Sep 2013

    Posted 05 Feb 2014 in reply to Keith Link to this post

    I figured it out. First, I discovered the readonly method that most widgets have, but even using that the binding on widgets would only execute once when the model was bound. I then discovered that for widgets, you need to implement an "init" function to be called when binding. My bindings now look like this:

    (function($){<br><br>    function refresh(){<br>    <br>        /*do general stuff here*/<br>    }<br>    function elementRefresh(){<br>    <br>        refresh.call(this);<br>        /*Do element stuff here*/<br>    }<br>    function widgetRefresh(){<br>        <br>        refresh.call(this);<br>        /*Do widget stuff here*/<br>    }<br>    var elementSchema = {<br>        refresh:elementRefresh<br>    };<br>    var widgetSchema = {<br>        init: function(widget, bindings, options) {<br>            //call the base constructor<br>            kendo.data.Binder.fn.init.call(this, widget.element[0], bindings, options);<br>        },<br>        refresh:widgetRefresh<br>    };<br>    <br>    kendo.data.binders.allowEdit = kendo.data.Binder.extend(elementSchema);<br>    kendo.data.binders.widget.allowEdit = kendo.data.Binder.extend(widgetSchema);<br><br>})(jQuery)<br>


    What I am wondering now though, is how having an chained assignment on binding would work? As in, how does kendo handle the init method when doing a general binding, as opposed to a widget binding?

    Example:

    (function($){<br><br>    function refresh(){<br>    <br>        /*do general stuff here*/<br>    }<br>    var widgetSchema = {<br>        init: function(widget, bindings, options) {<br>            //call the base constructor<br>            kendo.data.Binder.fn.init.call(this, widget.element[0], bindings, options);<br>        },<br>        refresh:refresh<br>    };<br>    //Chained assignment for general binders and widget binders<br>    kendo.data.binders.allowEdit = kendo.data.binders.widget.allowEdit = kendo.data.Binder.extend(elementSchema);<br>     <br><br>})(jQuery)
  9. Keith
    Keith avatar
    35 posts
    Member since:
    Sep 2013

    Posted 05 Feb 2014 in reply to Keith Link to this post

    Yikes ... I tried using the code block formatting option in that last post. Here's the examples without it:


    How I have it:

    (function($){

        function refresh(){
        
            /*do general stuff here*/
        }
        function elementRefresh(){
        
            refresh.call(this);
            /*Do element stuff here*/
        }
        function widgetRefresh(){
            
            refresh.call(this);
            /*Do widget stuff here*/
        }
        var elementSchema = {
            refresh:elementRefresh
        };
        var widgetSchema = {
            init: function(widget, bindings, options) {
                //call the base constructor
                kendo.data.Binder.fn.init.call(this, widget.element[0], bindings, options);
            },
            refresh:widgetRefresh
        };
        
        kendo.data.binders.allowEdit = kendo.data.Binder.extend(elementSchema);
        kendo.data.binders.widget.allowEdit = kendo.data.Binder.extend(widgetSchema);

    })(jQuery)

    Chained assignment:


    (function($){

        function refresh(){
        
            /*do general stuff here*/
        }
        var widgetSchema = {
            init: function(widget, bindings, options) {
                //call the base constructor
                kendo.data.Binder.fn.init.call(this, widget.element[0], bindings, options);
            },
            refresh:refresh
        };
        //Chained assignment for general binders and widget binders
        kendo.data.binders.allowEdit = kendo.data.binders.widget.allowEdit = kendo.data.Binder.extend(elementSchema);
         

    })(jQuery)
  10. Answer
    Dimo
    Admin
    Dimo avatar
    8333 posts

    Posted 06 Feb 2014 Link to this post

    Hello Keith,

    I am not sure I understood what all the parts if your code do, but it seems that the implementation is more complex than necessary. Please refer to our documentation, which provides an example about how to use custom MVVM binding, which executes a Kendo UI widget method, depending on a viewModel value.

    http://docs.telerik.com/kendo-ui/getting-started/framework/mvvm/bindings/custom

    See "Example: custom widget binding (the widget will be updated when the view-model changes)". In your case, you will replace the widget's max() method with readonly(). You will notice that the widget type is hard-coded in the refresh() method. In your case you will be using the different widget types, so you can utilize the following approach to get the correct one:

    http://docs.telerik.com/kendo-ui/getting-started/widgets#getting-reference-to-an-unknown-kendo-ui-widget

    You can even simplify things, because that.element will always be the element, which has the widget object attached to it.

    refresh: function() {
        var that = this,
            $element = $(that.element),
            value = !!that.bindings["readonly"].get();
         
        $element.data("kendo" + kendo.widgetInstance($element).options.name).readonly(value);
    }
     

    Regards,
    Dimo
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  11. Keith
    Keith avatar
    35 posts
    Member since:
    Sep 2013

    Posted 07 Feb 2014 in reply to Dimo Link to this post

    Thanks for the help. The methods for getting the widget instance really simplified things.
Back to Top
Kendo UI is VS 2017 Ready