为公共类隐藏的字段设置唯一数据属性和ID

时间:2013-08-07 02:49:32

标签: jquery html5 backbone.js backbone-views

这个问题有一个不合适的小提琴,它可能会告诉你我正在努力做的比下面的解释更好。 http://jsfiddle.net/mjmitche/RRXnK/330/

我有一个带有可见表单标签的表单,以及每个标签下方的按钮,用户应该能够单击该按钮以显示使用css隐藏的表单字段。每个表单字段都隐藏在类

I love to play the piano. <-this is a form label
Click to Open Form <- this is a button that opens invisible form field

I practice five hours every day. <-this is a form label
Click to Open Form  <- this is a button that opens invisible form field

这是隐藏表单字段的css

.span5.invisiblekey {
    display: none;
}

我想点击每个标签下方的按钮,并显示与每个标签相关联的表单字段。这是JavaScript(使用Backbone),但我无法弄清楚如何将按钮与每个特定表单字段链接,以便在单击每个相应按钮时仅显示一个表单字段。

如果可能的话,请帮助我弄清楚在表单的id和数据属性中设置什么,以便showForm方法中的JavaScript可以显示正确的表单字段?

var FormView = Backbone.View.extend({

    el: '#formscript', 

    events: {
        'click .fix': 'showForm'
    },

    showForm: function () {
        alert("form clicked");
    }

});

var form_view = new FormView();

这是html。我可以设置数据属性和ID

的灵活性
<div id="formscript">
<div class="row">
    <p class="span3">
        <label for="title">I love to play the piano.</label> 
       <a class="btn btn-small btn-warning fix" data-i-love-to-play-the-piano="i-love-to-play-the-piano" href="#">Click to Open Form</a> 
    </p>
    <p class="span3">
        <input class="span5 invisiblekey" data-i-love-to-play-the-piano="i-love-to-play-the-piano" id="i-love-to-play-the-piano" name="i-love-to-play-the-piano" type="text" value="">
    </p>
</div>

    <div class="row">
       <p class="span3">
         <label for="I_practice_five_hours_every_day.">I practice five hours every day.</label>
          <a class="btn btn-small btn-warning fix" data-i-practice-five-hours-every-day="i-practice-five-hours-every-day" href="#">Click to Open Form</a>  
         </p>
         <p class="span3">
            <input class="span5 invisiblekey" id="i-practice-five-hours-every-day"  name="i-practice-five-hours-every-day" type="text" value="I practice five hours every day.">
         </p>             
    </div>        
 </div>//formscript id

更新

注意,如果它有所不同,在我的实际(Rails)应用程序中,html位于一个id为#new_group

的表单中
<form accept-charset="UTF-8" action="/entries/11/corrections" class="nifty_form" id="new_group" method="post"><div style="margin:0;padding:0;display:inline">

4 个答案:

答案 0 :(得分:2)

以下是一个关于如何使用当前HTML结构执行此操作的示例:

showForm: function (e) {
    $(e.currentTarget).closest(':has(.invisiblekey)').find('.invisiblekey').removeClass('invisiblekey');
} 

然而,效率不高,您可以做的是将data-name-of-the-field="name-of-the-field"属性重命名为data-field-id="id-of-the-field",然后您可以这样做:

$('#' + $(e.target).attr('data-field-id')).removeClass('invisiblekey');

编辑:你应该强烈考虑在@Sushanth的解决方案中使用这种方法。

答案 1 :(得分:2)

我觉得使用Backbone并使用jQuery逻辑来操作数据是一种不好的做法,因为这会导致视图和DOM之间的紧密耦合,这不是一个好习惯。首选方法是使用显示相应数据的模板,以便特定于该特定视图。

如果您可以将它们分隔到每个视图中,那么您首先不需要数据属性,因为您可以搜索特定视图本身中的元素。而你的起始HTML足迹将非常小。

<强>模板

    <div id="formscript">
    </div>

   <!-- Created a template for each form view -->
    <script type="text/template" id="row-template">
            <p class="span3">
                <label for="title"><%= name %></label> 
                <a class="btn btn-small btn-warning fix" href="#">Click to Open Form</a> 
            </p>
            <p class="span3">
                <input class="span5 invisiblekey" type="text" value="<%= name %>" />
            </p>
    </script>

<强>的Javascript

 // Model that holds the data for the view
    var Form = Backbone.Model.extend({
        idAttribute: 'id'
    });

    var Forms = Backbone.Collection.extend({
        model: Form
    });

    // Add the models to the collection
    var forms = new Forms([{
        name: "I love to play the piano",
        id: 1
    }, {
        name: "I practice five hours every day",
        id:2
    }]);

   // This is the view for each form Item
    var FormItemView = Backbone.View.extend({
        className: 'row',
        events: {
            'click .fix': 'showForm'
        },
        // Template structure for the view
        template : _.template($('#row-template').html()),
        // This is the only code required for the input 
        // to be shown                                  
        showForm: function () {
            $('.span5.invisiblekey', this.$el).toggle();
        },
        // Rendering the View for each model passed
        render: function () {
            this.$el.append(this.template(this.model.toJSON()));
            return this;
        }
    });

    // This will be the main view
    var FormView = Backbone.View.extend({
        el: '#formscript',
        // Method that initializes each view for a model
        // and renders it
        renderFormItem: function(form) {
            var formItemView = new FormItemView({
                model: form
            });
            this.$el.append(formItemView.el);
            formItemView.render();
        },
        render: function() {
            // Iterate over the collection and render a view
            // for each model in the collection
            var thisView = this;
            this.$el.empty();
            _.each(this.collection.models, function (form) {
                thisView.renderFormItem(form);
            });
            return this;
        }
    });


    // Initialize the form and call render
    var form_view = new FormView({
        collection: forms
    });
    form_view.render();

Check Fiddle

可以通过多种方式使用jQuery来实现相同的功能。但是当你专门使用主干时,为什么不使用Backbone必须提供的选项,而不是纯粹的DOM操作,这将导致views and the DOM之间的紧密耦合,如果你想编写可伸缩的应用程序,这不是一个好兆头。

答案 2 :(得分:1)

我不确定如何使用主干,但您可以通过在按钮上添加data-form属性并根据此字段中包含的ID选择表单来执行您所要求的操作。

我已经编辑了你的输入id,所以id没有空格(在id属性中无效)。您仍然需要删除name属性上的空格。

HTML

<a class="btn btn-small btn-warning fix" data-form="i-love-the-rain" href="#">Fix It</a>
<input class="invisiblekey" id="i-love-the-rain" name="correction[data][I love the rain.]" type="text" value="">

的JavaScript

$('a').click(function (e) {
    id = $(this).data('form');
    // Three methods to show element
    // $('#' + id).show();
    // $('#' + id).toggleClass('invisiblekey');
    $('#' + id).removeClass('invisiblekey');
});

小提琴:http://jsfiddle.net/BqGK7/1/

答案 3 :(得分:1)

如果您的标记始终是已知的,您可以使用诸如previousElementSibling(或previousSibling取决于兼容性需求)之类的东西导航dom:

Working fiddle

丑陋的版本,但它适用于chrome / safari(不跨所有浏览器/版本)...

showForm: function (evt) {
    evt.target.parentElement.nextElementSibling.firstElementChild.classList.remove('invisiblekey');
}