如何使用angularjs在ng-click中触发另一个元素的click事件?

时间:2014-07-08 09:33:55

标签: angularjs

我正在尝试触发<input type="file">button元素的点击事件。

<input id="upload"
    type="file"
    ng-file-select="onFileSelect($files)"
    style="display: none;">

<button type="button"
    ng-click="angular.element('#upload').trigger('click');">Upload</button>

通常的做法是隐藏被称为<input type=file>的uglified beast并通过其他方式触发它的click事件。

12 个答案:

答案 0 :(得分:35)

如果您的输入和按钮是兄弟姐妹(并且它们在您的情况下是OP):

<input id="upload"
    type="file"
    ng-file-select="onFileSelect($files)"
    style="display: none;">

<button type="button" uploadfile>Upload</button>

使用指令将按钮的单击绑定到文件输入,如下所示:

app.directive('uploadfile', function () {
    return {
      restrict: 'A',
      link: function(scope, element) {

        element.bind('click', function(e) {
            angular.element(e.target).siblings('#upload').trigger('click');
        });
      }
    };
});

答案 1 :(得分:14)

所以这是一个简单的修复。只需将ng-click移动到范围单击处理程序:

<input id="upload"
    type="file"
    ng-file-select="onFileSelect($files)"
    style="display: none;">

<button type="button"
    ng-click="clickUpload()">Upload</button>



$scope.clickUpload = function(){
    angular.element('#upload').trigger('click');
};

答案 2 :(得分:6)

我有同样的问题,这个小提琴是shizzle :)它使用一个指令来正确设置文件字段的样式,你甚至可以把它变成一个图像或其他什么。

http://jsfiddle.net/stereosteve/v5Rdc/7/

&#13;
&#13;
/*globals angular:true*/
var buttonApp = angular.module('buttonApp', [])

buttonApp.directive('fileButton', function() {
  return {
    link: function(scope, element, attributes) {

      var el = angular.element(element)
      var button = el.children()[0]

      el.css({
        position: 'relative',
        overflow: 'hidden',
        width: button.offsetWidth,
        height: button.offsetHeight
      })

      var fileInput = angular.element('<input type="file" multiple />')
      fileInput.css({
        position: 'absolute',
        top: 0,
        left: 0,
        'z-index': '2',
        width: '100%',
        height: '100%',
        opacity: '0',
        cursor: 'pointer'
      })

      el.append(fileInput)


    }
  }
})
&#13;
<div ng-app="buttonApp">

  <div file-button>
    <button class='btn btn-success btn-large'>Select your awesome file</button>
  </div>

  <div file-button>
    <img src='https://www.google.com/images/srpr/logo3w.png' />
  </div>

</div>
&#13;
&#13;
&#13;

答案 3 :(得分:3)

如果您收到$ scope绑定错误,请确保将click事件代码包装在setTimeout函数上。

查看

<input id="upload"
    type="file"
    ng-file-select="onFileSelect($files)"
    style="display: none;">

<button type="button"
    ng-click="clickUpload()">Upload</button>

<强> CONTROLLER

$scope.clickUpload = function(){
    setTimeout(function () {
      angular.element('#upload').trigger('click');
    }, 0);
};

答案 4 :(得分:2)

对于jqLit​​e,只需将triggerHandler与事件名称一起使用,即可模拟&#34;点击&#34;试试:

&#13;
&#13;
angular.element("tr").triggerHandler("click");
&#13;
&#13;
&#13;

Here's the list of jQLite commands

答案 5 :(得分:1)

只需将它们放在同一个控制器中,然后执行以下操作:

<强> HTML:

<input id="upload"
    type="file"
    ng-file-select="onFileSelect($files)"
    style="display: none;">

<button type="button"
    ng-click="startUpload()">Upload</button>

<强> JS:

var MyCtrl = [ '$scope', '$upload', function($scope, $upload) {
  $scope.files = [];
  $scope.startUpload = function(){
    for (var i = 0; i < $scope.files.length; i++) {
      $upload($scope.files[i]);
    } 
  }
  $scope.onFileSelect = function($files) {
     $scope.files = $files;
  };
}];

在我看来,这是在角度方面做到这一点的最好方法。使用jQuery查找元素并触发事件不是最佳实践。

答案 6 :(得分:1)

我刚遇到这个问题,并为那些使用Angular的人编写了一个解决方案。您可以编写由容器,按钮和带有类型文件的输入元素组成的自定义指令。使用CSS,然后将输入放在自定义按钮上,但不透明度为0.您可以将容器的高度和宽度设置为按钮的偏移宽度和高度,输入的高度和宽度设置为容器的100%。

指令

angular.module('myCoolApp')
  .directive('fileButton', function () {
    return {
      templateUrl: 'components/directives/fileButton/fileButton.html',
      restrict: 'E',
      link: function (scope, element, attributes) {

        var container = angular.element('.file-upload-container');
        var button = angular.element('.file-upload-button');

        container.css({
            position: 'relative',
            overflow: 'hidden',
            width: button.offsetWidth,
            height: button.offsetHeight
        })

      }

    };
  });

如果您使用的是玉石模板

div(class="file-upload-container") 
    button(class="file-upload-button") +
    input#file-upload(class="file-upload-input", type='file', onchange="doSomethingWhenFileIsSelected()")  
如果您使用的是html

,请使用html中的相同模板
<div class="file-upload-container">
   <button class="file-upload-button"></button>
   <input class="file-upload-input" id="file-upload" type="file" onchange="doSomethingWhenFileIsSelected()" /> 
</div>

css

.file-upload-button {
    margin-top: 40px;
    padding: 30px;
    border: 1px solid black;
    height: 100px;
    width: 100px;
    background: transparent;
    font-size: 66px;
    padding-top: 0px;
    border-radius: 5px;
    border: 2px solid rgb(255, 228, 0); 
    color: rgb(255, 228, 0);
}
.file-upload-input {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}

答案 7 :(得分:0)

正如其他答案所指出的,解决方案是使用

angular.element(element).trigger(event);

以下是我如何随机选择多个select元素的示例:

$scope.randomize = function(){
    var games = [].slice.call(document.querySelectorAll('.games select'));

    games.forEach(function(e){
        // Logically change the element (Angular won't know about this)
        e.selectedIndex = parseInt(Math.random() * 100, 10) < 50 ? 1 : 2;

        // Manually tell Angular that the DOM has changed
        angular.element(e).trigger('change');
    });
};

答案 8 :(得分:0)

我接受了Osiloke发布的答案(这是最容易和最完整的imho),我添加了一个更改事件监听器。效果很好!谢谢Osiloke。如果您有兴趣,请参阅下文:

HTML:

  <div file-button>
        <button class='btn btn-success btn-large'>Select your awesome file</button>
   </div>

指令:

app.directive('fileButton', function() {
  return {
    link: function(scope, element, attributes) {

      var el = angular.element(element)
      var button = el.children()[0]

      el.css({
        position: 'relative',
        overflow: 'hidden',
        width: button.offsetWidth,
        height: button.offsetHeight
      })

      var fileInput = angular.element('<input id='+scope.file_button_id+' type="file" multiple />')
      fileInput.css({
        position: 'absolute',
        top: 0,
        left: 0,
        'z-index': '2',
        width: '100%',
        height: '100%',
        opacity: '0',
        cursor: 'pointer'
      })

      el.append(fileInput)
      document.getElementById(scope.file_button_id).addEventListener('change', scope.file_button_open, false); 
    }
  }
});

控制器:

$scope.file_button_id = "wo_files";    
$scope.file_button_open = function() 
{
  alert("Files are ready!");
}

答案 9 :(得分:0)

另一个指令

<强> HTML

<btn-file-selector/>

<强>码

.directive('btnFileSelector',[function(){
  return {
    restrict: 'AE', 
    template: '<div></div>', 
    link: function(s,e,a){

      var el = angular.element(e);
      var button = angular.element('<button type="button" class="btn btn-default btn-upload">Add File</button>'); 
      var fileForm = angular.element('<input type="file" style="display:none;"/>'); 

      fileForm.on('change', function(){
         // Actions after the file is selected
         console.log( fileForm[0].files[0].name );
      });

      button.bind('click',function(){
        fileForm.click();
      });     


     el.append(fileForm);
     el.append(button);
    }
  }  
}]); 

答案 10 :(得分:0)

使用本机java脚本的最佳和最简单的方法,这是一个班轮代码。

document.querySelector('#id').click();

只需添加&#39; id&#39;你的html元素,如

<button id="myId1" ng-click="someFunction()"></button>

检查javascript代码中的条件

if(condition) { document.querySelector('#myId1').click(); }

答案 11 :(得分:-2)

我认为你有点过于复杂的事情。你真的需要触发按钮输入的点击吗?

我建议您只对输入应用一个合适的样式,ngFileSelect指令将完成剩下的工作并在提交文件时调用onFileSelect函数:

input.file {
    cursor: pointer;
    direction: ltr;
    font-size: 23px;
    margin: 0;
    opacity: 0;
    position: absolute;
    right: 0;
    top: 0;
    transform: translate(-300px, 0px) scale(4);
}