【问题标题】:Dynamically add or remove input fields as they're required根据需要动态添加或删除输入字段
【发布时间】:2013-02-10 15:45:49
【问题描述】:

我设置了多个文件输入,我通过隐藏输入来设置样式,在 html/css 中创建自己的输入,然后通过 jQuery 控制原始输入以获得功能。

如果所有输入都已填满,我希望能够添加另一个输入和关联的 HTML,如下所示:

  • 从 1 个输入开始
  • 如果它被填充/使用,添加另一个输入
  • 重复
  • 移除已清除的输入,只留下 1 个空输入以供使用。

我尝试用我的代码创建一个 js fiddle,但它似乎无法通过它,所以这是我网站上的测试链接:LINK

还有代码,JS:

$('.file-browse').click(function(){
    var thisone = $(this).attr('id');
    $('input[name="input-'+ thisone+'"]').click();
});

$('input[type="file"]').on('change', function(){
    var thetext = $(this).val();
    var thetextsplit = thetext.split('\\').pop();
    var thisone = $(this).attr('name').split('-').pop();
    if($('div[id^="info-file"]').text() == thetextsplit){
        alert('you have already selected this file');
        $(this).replaceWith( $(this).val('').clone( true ) );
    }
    else{
        $('#info-'+ thisone).text(thetextsplit);
        $('#clear-'+ thisone).fadeIn(100);
    }
});

$('.file-clear').click(function(){
    var thisone = $(this).attr('id').split('-').pop();
    $('input[name="input'+ thisone +'"]').replaceWith( $('input[name="input'+ thisone +'"]').val('').clone( true ) );
    $('#info-'+ thisone).text('');
    $(this).fadeOut(100);
});

HTML:

    <div class="file-container">
      <div class="file-info" id="info-file1"></div>
      <div class="file-browse" id="file1">Browse</div>
      <div class="file-clear" id="clear-file1">X</div>
    </div>

    <div class="file-container">
      <div class="file-info" id="info-file2"></div>
      <div class="file-browse" id="file2">Browse</div>
      <div class="file-clear" id="clear-file2">X</div>
    </div>


    <div class="file-container">
      <div class="file-info" id="info-file3"></div>
      <div class="file-browse" id="file3">Browse</div>
      <div class="file-clear" id="clear-file3">X</div>
    </div>

    <form action="" method="POST" enctype="multipart/form-data">
  <input type='file' name="input-file1" class="file-input-hidden" />
      <input type='file' name="input-file2" class="file-input-hidden" />
      <input type='file' name="input-file3" class="file-input-hidden" />   
  <input type="submit" style="clear:both; float:left;"/>
    </form>

CSS:

.file-container{
clear:both;
float:left;
width:445px;
height:40px;
overflow:hidden;
padding:0;
margin:0;
}

.file-info{
float:left;
width:250px;
height:15px;
padding:5px;
border-radius:5px;
-webkit-border-radius:5px;
border:1px solid #95d2d2;
margin:0 20px 0 0;
font-family:Verdana, Geneva, sans-serif;
font-size:14px;
color:#373737;
overflow:hidden;
}

.file-browse{
float:left;
width:100px;
height:15px;
padding:3px 5px 8px 5px;
border-radius:5px;
-webkit-border-radius:5px;
border:1px solid #95d2d2;
background-color:#02b3b3;
color:#ffffff;
font-family:Arial, Gadget, sans-serif;
font-size:16px;
font-weight:bold;
letter-spacing:normal;
text-align:center;  
cursor:pointer;
}

.file-input-hidden{
opacity:0;
visibility:hidden;
float:left;
}

.file-clear{
display:none;
float: left;
width: 18px;
height: 18px;
padding: 5px;
color: #ffffff;
background-color: #CC0000;
font-family: Verdana, Geneva, sans-serif;
font-size: 14px;
font-weight: bold;
margin-left: 20px;
text-align: center;
border-radius: 5px;
cursor:pointer;
}

抱歉,这篇文章太长了!到目前为止,我不确定展示我的作品的最佳方式。

【问题讨论】:

    标签: jquery forms dynamic input


    【解决方案1】:

    Rpsep,

    我认为从模板开始事情会更简单:

    <div id="input_template" style="display:none;">
        <div class="file-container">
            <div class="file-info"></div>
            <div class="file-browse">Browse</div>
            <div class="file-clear">X</div>
        </div>
        <input type='file' name="input-file[]" class="file-input-hidden" />
    </div>
    

    注意事项:

    • 只有外层容器有id;其他所有东西都有一个类。
    • 不用担心输入元素和其他元素在同一个容器中;克隆后将其放置在适当的位置。

    然后将功能附加到模板:

    $("#input_template").find('.file-browse').on('click', function() {
        $(this).closest(".file-container").data('hidden').click();
    });
    
    $("#input_template").find('.file-clear').on('click', function(){
        $container = $(this).closest(".file-container");
        $container.data('hidden').remove();
        $container.remove();
    });
    
    $('#input_template').find(".file-input-hidden").on('change', function(){
        var val = $(this).val().split('\\').pop();
        var $visible = $(this).data('visible');
        var $matches = $(".file-info").filter(function() {
            return $(this).text() === val;
        });
        if($matches.length > 0) {
            alert('You have already selected this file');
            var $clone = $this.val('').clone(true);
            $visible.data('hidden', $clone);
            $this.replaceWith( $clone );
        }
        else{
    /*
            $visible.find(".file-info").text(val);
            $visible.find(".file-clear").fadeIn(100);
            makeInputSet();
    */
            var $fi = $visible.find(".file-info");
            if(!$fi.text()) 
                makeInputSet();
            $fi.text(val).end().find(".file-clear").fadeIn(100);
        }
    });
    

    将事件处理委托给容器可能会更好,但根据问题中的代码,这段代码更容易编写。

    使用以下函数调用模板,然后立即调用它来创建第一个实例:

    function makeInputSet() {
        var $visible = $("#input_set").find(".file-container").clone(true, true).appendTo("#...");//appropriate selector required
        var $hidden = $("#input_set").find(".file-input-hidden").clone(true, true).appendTo("#...");//appropriate selector required
        $visible.data('hidden', $hidden);
        $hidden.data('visible', $visible);
    }
    
    makeInputSet();
    

    注意事项:

    • 然后,只要填充了现有输入字段(及其可见对应项),就会从“更改”处理程序内部调用 makeInputSet()
    • 两个.data() 调用确保隐藏元素和可见元素具有相互通信的方式,而无需字符串处理 id 或形成效率低下的闭包。

    一切都未经测试,因此可能需要调试

    【讨论】:

    • 这很好用!谢谢。唯一不检查的部分是检查文件是否已被选择: if($visible.find(".file-info").text() == val) { alert('You have already have选择了这个文件'); $(this).replaceWith($(this).val('').clone(true));但在我的脑海中阅读它似乎应该?有什么想法吗?
    • 啊,是的,测试不正确。新的val 需要针对每个 现有.file-info div 的文本进行测试。您的原始方法(如果可行的话)可能是最好的,但我刚刚用不同的方法编辑了我的答案;即使用.map() 循环通过现有的.file-info div 寻找匹配项,然后测试生成的jQuery obj 的长度。
    • 刚刚开始测试这个,它是.filter(),而不是.map()
    • 刚看了又发现另一个问题。就目前而言,如果输入被“重新浏览”,并且成功选择了不同的文件,那么即使已经存在空白输入,也会进行进一步的新输入。我认为您的原始代码的行为方式相同。只有在填充了空白输入时,才可以通过调用makeInputSet() 来克服这个问题。请参阅上面的修改后的代码。
    猜你喜欢
    • 2013-05-12
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 2023-01-26
    • 1970-01-01
    • 2021-05-21
    • 2014-10-20
    相关资源
    最近更新 更多