未解决

上次更新时间:下午4:15

我在哪里

我有三种类别供人们选择:性别,年龄,种族。每个都有自己的一组选项男/女; 35、36-64岁,65岁以上;白人,黑人,原住民,梅蒂斯人和亚洲人。

单击其中一个选项时,该数字应从var total中减去(这是MLA的数量)。我已经为数字设置了全局变量,该变量将位于我的span.number文件中的index.html更改为:“您的人口统计信息中包含X位数的MLA”。

我被困在哪里

a)我正在寻找一种使用Javascript进行数学运算的更有效方法,目前它非常简陋。如果您查看scripts.js中的“性别”选项,我创建了一个变量var resultMale = total - female,但是
当生成span.number依赖于先前选择的选项时,它变得不那么漂亮了。

b)我尝试使用管道布尔值,但是我不清楚第二个类别“年龄”的情况,其中包括var resultLow = resultMale || resultFemale -(middle + high)如何知道“性别”类别中已单击/选择的内容,以便做适当的数学。

scripts.js

$(function() {

    // Numbers
    var total = 56
    var male = 41;
    var female = 15;
    var low = {}
    var middle = {}
    var high = {}
    var white = 41
    var black = 0;
    var aboriginal = null;
    var metis = null;
    var asian = null;

    // MLAs
    var MLAs = [
      {
        "Name": "Nancy Allan",
        "Age": 62,
        "Constuency": "St. Vital",
        "Party": "NDP",
        "Gender": "Female",
        "Ethnicity": "White"
      },
      {
        "Name": "James Allum",
        "Age": null,
        "Constuency": "Fort Garry-Riverview",
        "Party": "NDP",
        "Gender": "Male",
        "Ethnicity": "White"
      },
      {
        "Name": "Rob Altemeyer",
        "Age": null,
        "Constuency": "Wolseley",
        "Party": "NDP",
        "Gender": "Male",
        "Ethnicity": "White"
      }]

    // Option #1: Gender
    $( ".G1" ).click(function() {
        $(".G2").toggleClass("disabled");
        $(".headshot").not(".Female").toggleClass("opacity");

        var resultMale = total - female;
        $(".number").html(resultMale);
    });

    $( ".G2" ).click(function() {
        $(".G1").toggleClass("disabled");
        $(".headshot").not(".Male").toggleClass("opacity");

        var resultFemale = total - male
        $(".number").html(resultFemale);
    });

    // Option #2: Age
    $( ".A1" ).click(function() {
        $(".A2").toggleClass("disabled");
        $(".A3").toggleClass("disabled");
        $(".Low").toggleClass("show");

        var resultLow = resultMale || resultFemale - (middle + high);
        $(".number").html("?");
    });

    $( ".A2" ).click(function() {
        $(".A1").toggleClass("disabled");
        $(".A3").toggleClass("disabled");
        $(".Medium").toggleClass("show");

        var resultMiddle = resultMale || resultFemale - (low + high);
        $(".number").html("?");
    });

    $( ".A3" ).click(function() {
        $(".A1").toggleClass("disabled");
        $(".A2").toggleClass("disabled");
        $(".High").toggleClass("show");

        var resultHigh = resultMale || resultFemale - (low + middle);
        $(".number").html("?");
    });

    // OLD
    $( ".E1" ).click(function() {
        $( ".White" ).toggleClass("show");

        var resultWhite = resultLow || resultMiddle || resultHigh - (black + aboriginal + metis + asian);
        $(".number").html(resultWhite);
    });

    $( ".E2" ).click(function() {
        $( ".Black" ).toggleClass("show");

        var resultBlack = resultLow || resultMiddle || resultHigh - (white + aboriginal + metis + asian);
        $(".number").html("0");
    });

    $( ".E3" ).click(function() {
        $( ".Aboriginal" ).toggleClass("show");

        var resultAboriginal = resultLow || resultMiddle || resultHigh - (white + black + metis + asian);
        $(".number").html(null);
    });

    $( ".E4" ).click(function() {
        $( ".Metis" ).toggleClass("show");

        var resultMetis = resultLow || resultMiddle || resultHigh - (white + black + aboriginal + asian);
        $(".number").html(null);
    });

    $( ".E5" ).click(function() {
        $( ".Asian" ).toggleClass("show");

        var resultAsian = resultLow || resultMiddle || resultHigh - (white + black + aboriginal + metis);
        $(".number").html(null);
    });

    // Option #3: Ethnicity
    // $("input[name='ethnicity']").on("change", function() {
    //     var $checkedbox = $("input[name='ethnicity']:checked");

    //  if($checkedbox.length >= 2)
    //  {
    //         var $uncheckedbox = $("input[name='ethnicity']:not(:checked)");
    //      $.each($uncheckedbox,function() {
    //          $(this).attr("disabled", "disabled");
    //      });
    //  }
    //     else
    //     {
    //         $("input[name='ethnicity']").removeAttr("disabled");
    //     }
    // });

    // Shows a popup with MLA information
    $(".headshot").click(function(){
        var idx = $(this).index() - 1;

        $(".tooltip").fadeIn("slow");
        $(".tooltipName").html(MLAs[idx].Name);
        $(".tooltipParty").html(MLAs[idx].Party);
        $(".tooltipConstuency").html(MLAs[idx].Constuency);
        $(".tooltipEthnicity").html(MLAs[idx].Ethnicity) + ",";
        $(".tooltipAge").html(MLAs[idx].Age);
    });

    // Bounce and show result
    $(".rect").click(function(){
            console.log("Bounce test");
           $(".others").fadeIn("slow");
           $(".others").effect( "bounce",
            {times:3}, 600 );
        });

    // This hides the footer on click
    $(".crossContainer").click(function(){
        $("footer").slideUp("slow", function(){
            console.log("No feedback makes us sad.");
        });
    });

    // This hides the credits
    $(".credits").hide();
});


index.html(包括span.number)

<!-- Three options readers can click -->
        <section class="interactive clearfix">
            <section class="selection" id="selection">
                <div class="gender">
                    <p class="category">Gender</p>
                    <div class="options">
                        <p class="rect G1">Male</p>
                        <p class="rect G2">Female</p>
                    </div><!-- /.options -->
                </div><!-- /.gender -->

                <div class="age">
                    <p class="category">Age</p>
                    <div class="options">
                        <p class="rect A1">Under 35</p>
                        <p class="rect A2">36-64</p>
                        <p class="rect A3">65+</p>
                    </div><!-- /.options -->
                </div><!-- /.age -->

                <div class="ethnicity">
                    <p class="category">Ethnicity<span>*<span></p>
                    <div class="options">
                        <p class="rect E1 E">White</p>
                        <p class="rect E2 E">Black</p>
                        <p class="rect E3 E">Aboriginal</p>
                        <p class="rect E4 E">Metis</p>
                        <p class="rect E5 E">Asian</p>
                    </div><!-- /.options -->
                </div><!-- /.ethnicity -->
</section>

        <section class="others">
            <h2>There are <span class="number">56</span> MLAs that fit in your demographic</h2>
            <figcaption class="special">(Does not include the single vacant seat for the Pas.)</figcaption>
        </section>

最佳答案

如果我对它的理解正确,则以下演示应按照您的要求进行。您可以在下面和此处的jsFiddle中找到代码。 (旧版本的jsfiddle,新版本请参见下面的编辑。)

基本上是在做Andi建议的事情。对于“计算”,我已使用UnderscoreJS使用where方法为当前单击的选择找到匹配的键/值对。这样很容易获得带有长度的选择总数。

在演示中,我针对男性,女性和种族进行了演示。它应该与其他选项完全一样。



编辑07.02.2015

我已经改进了代码。现在,您可以在列表中激活多个过滤器。减法也被删除,因为过滤后的列表始终具有length属性的项数。

该代码正在运行,但是仍有一些要改进的地方:


需要更改removeFilter以轻松删除过滤器,而无需指定过滤器参数
setFilter即兴:实际上并不需要if ( index == -1 ) {,因为在添加新过滤器之前始终会删除过滤器。
为每个无线电组添加重置按钮。目前,只有一个“全部重置”按钮。
使用AngularJS更新DOM会更好,因为脚本总是在每次过滤器更改时重新创建DOM。
也许使用AngularJS,您可以检查是否存在用于ng-repeat的过滤器以执行类似的行为。


我也可能没有测试过过滤器的任何组合是否正常工作,因为我只有三个列表项。因此,您必须对代码进行更多测试。

我将代码更新为最新版本,这是jsFiddle



更多代码说明16.02.2015

函数refreshListsetTotal用于更新DOM。

应用过滤器后,过滤器功能genderethnicityage返回新数组。

数组activeFilters存储当前选择的过滤器。它存储过滤器函数,以便可以通过遍历此数组来调用它们。稍后对此有更多详细信息。

setFilter方法正在设置过滤器。它将过滤器添加到activeFilters数组,然后应用过滤器。

applyFilter函数可能是最难理解的。遍历activeFilters数组的每个项目。如果您有两个活动的过滤器(此处为性别和种族),则数组activeFilters将如下所示:

activeFilters = [{
   method: function(array, gender){...},
   param: 'male'
   }, {
   method: function (array, ethnic){...},
   param: 'white'
   }];


使用activeFilters[0].method(MLAs,'male'),您可以手动调用性别过滤器。这就是$ .each循环在this循环内所做的就是{method: ..., param: ...}。因此,对于this.method(filtered, this.param),过滤器将应用于变量filtered
循环之后,每个活动的过滤器都将应用于阵列。



var $total = $('#total');
var $MLA_List = $('#MLA_List');

// MLAs
var MLAs = [{
    "Name": "Nancy Allan",
        "Age": 62,
        "Constuency": "St. Vital",
        "Party": "NDP",
        "Gender": "Female",
        "Ethnicity": "White"
}, {
    "Name": "James Allum",
        "Age": 34,
        "Constuency": "Fort Garry-Riverview",
        "Party": "NDP",
        "Gender": "Male",
        "Ethnicity": "Black"
}, {
    "Name": "Rob Altemeyer",
        "Age": 36,
        "Constuency": "Wolseley",
        "Party": "NDP",
        "Gender": "Male",
        "Ethnicity": "White"
}];

var filteredMLAs = MLAs.slice(0); // copy MLAs
var total = filteredMLAs.length;

var refreshList = function () {
    var list = filteredMLAs;
    setTotal(list.length);

    $MLA_List.empty();
    $.each(list, function (index, value) {
        $MLA_List.append($('<li/>').text(list[index].Name));
    });
};
var setTotal = function (value) {
    $total.text(value);
};

// filter methods
var gender = function (array, gender) {
    //console.log('gender filter called!', gender);
    return _.where(array, {
        "Gender": gender
    });
};

var ethnicity = function (array, ethnic) {
    //console.log('ethnic filter called!', array, ethnic);
    return _.where(array, {
        "Ethnicity": ethnic
    });
};

var age = function(array, ageRange) {
    //under 35, 36-64, 65+
    return _.filter(array, function(MLA) {
        //console.log(MLA.Age);
        switch(ageRange) {
            case 35:
                return ( MLA.Age <= 35 );
            case 36:
                return ( MLA.Age >= 35 && MLA.Age <= 64);
            case 65:
                return ( MLA.Age >= 65 );
        };
        return false;
    });
};

var activeFilters = [];
var setFilter = function (method, param) {
    var newFilter = {
        method: method,
        param: param
    };

    var matchedFilter = _.find(activeFilters, newFilter),
        index = activeFilters.indexOf(matchedFilter);

    if ( index == -1 ) {
        activeFilters.push(newFilter);
    }

    applyFilter();
};

var removeFilter = function(method, param) {
    var filter = {
        method: method,
        param: param
    };

    var index = activeFilters.indexOf(_.find(activeFilters, filter));

    if (index > -1) {
        activeFilters.splice(index, 1);
    }

    applyFilter(); // re-apply filter to update list
};

var applyFilter = function () {
    var filtered = MLAs.slice(0);
    $.each(activeFilters, function () {
        filtered = this.method(filtered, this.param);
    });
    filteredMLAs = filtered ? filtered: [];
    refreshList();
};

$('#Male, #Female').click(function () {
    //console.log(this.id);
    removeFilter(gender, this.id=='Male'? 'Female': 'Male'); // remove not active filter
    setFilter(gender, this.id);
});

$('#White, #Black').click(function () {
    //console.log(this.checked);
    if ( this.checked )
        setFilter(ethnicity, this.id); //'White');
    else
        removeFilter(ethnicity, this.id); //'White');
});

$('.Age').click(function() {
    removeFilter(age, 35); // improvement of remove filter required, e.g. remove all age filters
    removeFilter(age, 36);
    removeFilter(age, 65);
    setFilter(age, parseInt(this.value));
});

$('#reset').click(function(){
    //console.log('reset form');
    activeFilters = [];
    $(':checkbox, :radio').attr('checked', false);
    applyFilter();
});

$(function () {
    refreshList();
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
There are <span id="total"></span> MLAs matching.
<ul id="MLA_List"></ul>
<hr/>
<p>click to filter:</p>
<input type="radio" id="Male" name="gender">male</input>
<input type="radio" id="Female" name="gender">female</input>
<input type="checkbox" id="White">white</input>
<input type="checkbox" id="Black">black</input>
<input type="radio" class="Age" name="age" value="35">under 35</input>
<input type="radio" class="Age" name="age" value="36">36-64</input>
<input type="radio" class="Age" name="age" value="65">65+</input>
<button id="reset">reset</button>
<!-- <a href="#" id="male">male</a>
<a href="#" id="female">female</a>
<a href="#" id="white">white</a>
-->

10-07 14:39