wake-up-neo.net

Datei-Upload mit Winkelmaterial

Ich schreibe eine Web-App mit AngularJS und eckigem Material. Das Problem ist, dass es keine eingebaute Komponente für die Dateieingabe in Winkelmaterial gibt. (Ich denke, dass das Hochladen von Dateien nicht zum Materialdesign passt, aber ich brauche es in meiner App.

Haben Sie eine gute Lösung für dieses Problem? 

36
weiway

Ich finde einen Weg, um zu verhindern, dass meine Schaltfläche zum Auswählen einer Datei ausgewählt wird.

Da ich flowjs für den wiederaufladbaren Upload verwende, kann ich die Direktive " flow-btn " von ng-flow verwenden, die eine Schaltfläche zum Auswählen einer Datei mit Materialdesign-Stil gibt .

Beachten Sie, dass das Eingeben des Eingabeelements innerhalb einer MD-Taste nicht funktioniert.

6
weiway

Schöne Lösung von leocaseiro

<input class="ng-hide" id="input-file-id" multiple type="file" />
<label for="input-file-id" class="md-button md-raised md-primary">Choose Files</label>

 enter image description here

View in codepen

41
Radin Reth

Basierend auf dieser Antwort . Es hat einige Zeit gedauert, bis dieser Ansatz funktioniert hat. Ich hoffe, dass meine Antwort jemandem Zeit spart.

DEMO auf CodePen

Richtlinie: 

angular.module('app').directive('apsUploadFile', apsUploadFile);

function apsUploadFile() {
    var directive = {
        restrict: 'E',
        templateUrl: 'upload.file.template.html',
        link: apsUploadFileLink
    };
    return directive;
}

function apsUploadFileLink(scope, element, attrs) {
    var input = $(element[0].querySelector('#fileInput'));
    var button = $(element[0].querySelector('#uploadButton'));
    var textInput = $(element[0].querySelector('#textInput'));

    if (input.length && button.length && textInput.length) {
        button.click(function (e) {
            input.click();
        });
        textInput.click(function (e) {
            input.click();
        });
    }

    input.on('change', function (e) {
        var files = e.target.files;
        if (files[0]) {
            scope.fileName = files[0].name;
        } else {
            scope.fileName = null;
        }
        scope.$apply();
    });
}

upload.file.template.html

<input id="fileInput" type="file" class="ng-hide">
<md-button id="uploadButton"
           class="md-raised md-primary"
           aria-label="attach_file">
    Choose file
</md-button>
<md-input-container md-no-float>
    <input id="textInput" ng-model="fileName" type="text" placeholder="No file chosen" ng-readonly="true">
</md-input-container>
13
Juniper

von jameswyse unter https://github.com/angular/material/issues/3310

HTML

<input id="fileInput" name="file" type="file" class="ng-hide" multiple>
<md-button id="uploadButton" class="md-raised md-primary"> Choose Files </md-button>

REGLER

    var link = function (scope, element, attrs) {
    const input = element.find('#fileInput');
    const button = element.find('#uploadButton');

    if (input.length && button.length) {
        button.click((e) => input.click());
    }
}

Arbeitete für mich.

12
Chris L

Ein weiteres Beispiel für die Lösung ..__ sieht folgendermaßen aus  enter image description here

CodePen-Link dort.

  <choose-file layout="row">
    <input id="fileInput" type="file" class="ng-hide">
    <md-input-container flex class="md-block">
      <input type="text" ng-model="fileName" disabled>
      <div class="hint">Select your file</div>
    </md-input-container>
    <div>
      <md-button id="uploadButton" class="md-fab md-mini">
        <md-icon class="material-icons">attach_file</md-icon>
      </md-button>
    </div>
  </choose-file>   

.directive('chooseFile', function() {
    return {
      link: function (scope, elem, attrs) {
        var button = elem.find('button');
        var input = angular.element(elem[0].querySelector('input#fileInput'));

        button.bind('click', function() {
          input[0].click();
        });

        input.bind('change', function(e) {
          scope.$apply(function() {
            var files = e.target.files;
            if (files[0]) {
              scope.fileName = files[0].name;
            } else {
              scope.fileName = null;
            }
          });
        });
      }
    };
  });

Ich hoffe es hilft!

12

Eine andere gehackte Lösung könnte jedoch durch die Implementierung einer Proxy-Schaltfläche ein wenig sauberer sein: 

HTML:

<input id="fileInput" type="file">
<md-button class="md-raised" ng-click="upload()">
  <label>AwesomeButtonName</label>
</md-button>

JS:

app.controller('NiceCtrl', function ( $scope) {
  $scope.upload = function () {
    angular.element(document.querySelector('#fileInput')).click();
  };
};
2
Dombi Soma

Datei-Uploader mit AngularJs Material und einer MIME-Typ-Validierung:

Richtlinie:

function apsUploadFile() {
    var directive = {
        restrict: 'E',
        require:['ngModel', 'apsUploadFile'],
        transclude: true,
        scope: {
            label: '@',
            mimeType: '@',
        },
        templateUrl: '/build/html/aps-file-upload.html',
        controllerAs: 'ctrl',
        controller: function($scope) {
            var self = this;

            this.model = null;

            this.setModel = function(ngModel) {
                this.$error = ngModel.$error;

                ngModel.$render = function() {
                    self.model = ngModel.$viewValue;
                };

                $scope.$watch('ctrl.model', function(newval) {
                    ngModel.$setViewValue(newval);
                });
            };
        },
        link: apsUploadFileLink
    };
    return directive;
}

function apsUploadFileLink(scope, element, attrs, controllers) {

    var ngModelCtrl = controllers[0];
    var apsUploadFile = controllers[1];

    apsUploadFile.inputname = attrs.name;
    apsUploadFile.setModel(ngModelCtrl);

    var reg;
    attrs.$observe('mimeType', function(value) {
        var accept = value.replace(/,/g,'|');
        reg = new RegExp(accept, "i");
        ngModelCtrl.$validate();
    });

    ngModelCtrl.$validators.mimetype = function(modelValue, viewValue) {

        if(modelValue.data == null){
            return apsUploadFile.valid = true;
        }

        if(modelValue.type.match(reg)){
            return apsUploadFile.valid = true;
        }else{
            return apsUploadFile.valid = false;
        }

    };

    var input = $(element[0].querySelector('#fileInput'));
    var button = $(element[0].querySelector('#uploadButton'));
    var textInput = $(element[0].querySelector('#textInput'));

    if (input.length && button.length && textInput.length) {
        button.click(function(e) {
            input.click();
        });
        textInput.click(function(e) {
            input.click();
        });
    }

    input.on('change', function(e) {

        //scope.fileLoaded(e);
        var files = e.target.files;

        if (files[0]) {
            ngModelCtrl.$viewValue.filename = scope.filename = files[0].name;
            ngModelCtrl.$viewValue.type = files[0].type;
            ngModelCtrl.$viewValue.size = files[0].size;

            var fileReader = new FileReader();
            fileReader.onload = function () {
                ngModelCtrl.$viewValue.data = fileReader.result;
                ngModelCtrl.$validate();
            };
            fileReader.readAsDataURL(files[0]);

            ngModelCtrl.$render();
        } else {
            ngModelCtrl.$viewValue = null;
        }

        scope.$apply();
    });

}
app.directive('apsUploadFile', apsUploadFile);

hTML-Vorlage:

<input id="fileInput" type="file" name="ctrl.inputname" class="ng-hide">
<md-input-container md-is-error="!ctrl.valid">
    <label>{@{label}@}</label>
    <input id="textInput" ng-model="ctrl.model.filename" type="text" ng-readonly="true">
    <div ng-messages="ctrl.$error" ng-transclude></div>
</md-input-container>
<md-button id="uploadButton" class="md-icon-button md-primary" aria-label="attach_file">
    <md-icon class="material-icons">cloud_upload</md-icon>
</md-button>

Beispiel:

<div layout-gt-sm="row">
    <aps-upload-file name="strip" ng-model="cardDesign.strip" label="Strip" mime-type="image/png" class="md-block">
        <div ng-message="mimetype" class="md-input-message-animation ng-scope" style="opacity: 1; margin-top: 0px;">Your image must be PNG.</div>
    </aps-upload-file>
</div>
0
Ismail Moukafih

Sie können den Stil ändern, indem Sie die Eingabe in eine Beschriftung einschließen und die Eingabeanzeige in keine ändern. Anschließend können Sie den Text angeben, der in einem Spannelement angezeigt werden soll. Hinweis: Hier habe ich den Bootstrap 4-Button-Stil (btn btn-outline-primary) verwendet. Sie können jeden gewünschten Stil verwenden. 

<label class="btn btn-outline-primary">
      <span>Select File</span>
      <input type="file">
</label>

input {
  display: none;
}
0
MAhmed

Zusätzlich zu den obigen Antworten (weshalb ich es zu einem Community-Wiki gemacht habe), ist es wahrscheinlich am besten, jeden input<type="text"> mit tabindex="-1" zu kennzeichnen, insbesondere wenn readonly anstelle von disabled (und möglicherweise <input type="file">) verwendet wird, obwohl es verborgen sein sollte scheinbar noch im Dokument). Beschriftungen funktionierten nicht richtig, wenn die Tabulatortaste/Eingabetastenkombination verwendet wurde, die Schaltfläche jedoch. Wenn Sie also eine der anderen Lösungen auf dieser Seite kopieren, möchten Sie diese Änderungen möglicherweise vornehmen.

0
Guy Schalnat

Für Winkel 6+:

HTML:

<input #csvInput hidden="true" type="file" onclick="this.value=null" (change)="csvInputChange($event)" accept=".csv"/>
<button mat-flat-button color="primary" (click)="csvInput.click()">Choose Spreadsheet File (CSV)</button>

Komponentenmethode:

  csvInputChange(fileInputEvent: any) {
    console.log(fileInputEvent.target.files[0]);
  }

Hinweis: Dieses Filter filtert nur .csv-Dateien.

0
rynop