Mdb-ui-kit: Floating label position with pre-filled inputs

Created on 25 Oct 2014  Â·  12Comments  Â·  Source: mdbootstrap/mdb-ui-kit

When using floating label, if an imput is pre-filled (i.e. returning to form after failed validation) then the label displays in the starting position, inside the input, instead of above the input. This causes it to clamp with input text.

label-error

bug confirmed

Most helpful comment

try this

app.directive("ngModel",["$timeout", function($timeout){
            return {
                restrict: 'A',
                priority: -1, // lower priority than built-in ng-model so it runs first
                link: function(scope, element, attr) {
                    scope.$watch(attr.ngModel,function(value){
                        $timeout(function () {
                            if (value){
                                element.trigger("change");
                            } else if(element.attr('placeholder') === undefined) {
                                if(!element.is(":focus"))
                                    element.trigger("blur");
                            }
                        });
                    });
                }
            };
        }]);

All 12 comments

There is already a fix for it, I'm not sure if I've already pushed it to develop branch

I'm very interested in the fix too :)

If you change the value with JS just trigger the change event. The coming fix is to fix the status of the label when the input is auto filled on load or when it has focus

changed through JS: check :)

auto filled? My biggest challenge is on 'edit' (and 'new' when returning to the form due to a failed validation of sorts) where most fields are filled -- and at the same time garbled due to the label

Apart from that - it is a fantastic gem!!!!

thank you for sharing

07783f3 is the fix.

It works for forms that are autofilled on load and for forms autofilled when you click the dropdown menu.

This can even work in case you autofill some forms with JS on page load.

tried the "fix" but it did not work for me :(

what worked though:


    var isEmpty = function(fld) {
      try {
        data = $(fld).val();
      } catch(exception){ 
        return true;
      }

      if(typeof(data) == 'number' || typeof(data) == 'boolean') { return false }
      if(typeof(data) == 'undefined' || data === null) { return true }
      if(typeof(data.length) != 'undefined') { return data.length == 0 }
      var count = 0;
      for(var i in data)
      {
        if(data.hasOwnProperty(i))
        {
          count ++;
        }
      }
      return count == 0;
    }

and then call this function for each field like this


            if ( isEmpty(this) ) {
                $(this).addClass("empty");
            }


I don't know what use case the :empty selector represents (textarea?) - but for regular input it will report true all the time - as input is a closed tag (as I understand it)

we definitely need to find some better way to detect changes on inputs... maybe listen for node changes and then filter them, I'll try to find a consistent solution.

there are two use cases

  1. forms prefilled from the server side - no node changes arise here
  2. forms being filled during forms manipulation - node changes are indeed pertinent here!

cheers,
Walther

Den 28/10/2014 kl. 14.09 skrev Fez Vrasta [email protected]:

we definitely need to find some better way to detect changes on inputs... maybe listen for node changes and then filter them, I'll try to find a consistent solution.

—
Reply to this email directly or view it on GitHub https://github.com/FezVrasta/bootstrap-material-design/issues/148#issuecomment-60752038.

{"@context":"http://schema.org","@type":"EmailMessage","description":"View this Issue on GitHub","action":{"@type":"ViewAction","url":"https://github.com/FezVrasta/bootstrap-material-design/issues/148#issuecomment-60752038","name":"View Issue"}}

I've fixed the problem of the OP, but the other problems are still opened and need a fix.

This is the only solution I've found...

$(".form-control").each(function() {
  function emptyListener($this) {
    requestAnimationFrame(function() {
      emptyListener($this);
    });
    if ($this.data("oldval") != $this.val()) {
      $this.data("oldval", $this.val);
      $this.trigger("change");
    }
  }
  emptyListener($(this));
})

I think it's quite horrible so I'm not going to implement it... I'm open to different solutions.

try this

app.directive("ngModel",["$timeout", function($timeout){
            return {
                restrict: 'A',
                priority: -1, // lower priority than built-in ng-model so it runs first
                link: function(scope, element, attr) {
                    scope.$watch(attr.ngModel,function(value){
                        $timeout(function () {
                            if (value){
                                element.trigger("change");
                            } else if(element.attr('placeholder') === undefined) {
                                if(!element.is(":focus"))
                                    element.trigger("blur");
                            }
                        });
                    });
                }
            };
        }]);

Josephdias92, thx that worked for me

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dandv picture dandv  Â·  8Comments

tahq69 picture tahq69  Â·  8Comments

thangchung picture thangchung  Â·  3Comments

hashvg7 picture hashvg7  Â·  4Comments

versedi picture versedi  Â·  7Comments