将表中的所有选择元素设置为与其列中最宽的元素相同的宽度

时间:2014-11-27 01:28:51

标签: jquery angularjs ngtable

作为设计要求,我需要确保给定列中的所有选择元素的宽度相同,使用该列中最宽的选择来设置它们。

示例:

enter image description here

宽度应仅匹配同一列中的其他宽度,并且不匹配整个表格中最宽的<select>


我已经编写了一个似乎应该可以工作的功能(见下文),但是在页面数据重新加载之前它正在执行,无论我在哪里坚持它。

对该功能的调用目前位于getDatangTableParams功能的末尾。


功能:

$scope.resizeInputs = function(table, inputType) {
    var cols = [],
        rows = table+" tbody tr";

    angular.forEach($(rows), function(element, key, obj) {
        $(element).find('td').each(function(i, el) {
            var thisInput = $(el).find(inputType),
                currentWidth = cols[i] == null ? null : cols[i],
                maxWidth = Math.max(currentWidth, $(thisInput).width());

            if (thisInput.length > 0 && maxWidth > 0) {
                cols[i] = maxWidth;
            }
        });
    });

    $.each(cols, function(index, el) {
        if (el != undefined) {
            var x = index + 1;
            $(rows).children('td:nth-child('+x+')').find(inputType).width(el);
        }
    });
}


编辑: getData函数:

$scope.searchTable = function(){
    $scope.doSelectFunctions = true;
    $scope.copySendDate = null;
    var today = new Date();
    todayStr = (today.getMonth() + 1) + "/" + today.getDate() + "/" + today.getFullYear();
    searchCriteria = {
//                startDate: toStartTimeStamp(todayStr),
            startDate: toStartTimeStamp("11/01/2014"),
            endDate: toEndTimeStamp(todayStr)
    };

    $scope.tableParams = new ngTableParams({
        count: 100,            // Default results per page, down from 1000!
        sorting: {
            pending: 'desc',
            campaignId: 'desc',
            }
        },{
        getData: function($defer, params) {
            // ajax request to api
            $timeout(function() {
                Report.search(searchCriteria, function(data) {
                    angular.forEach(data, function(v,k) {
                        $scope.doCampaignInfo(v);

                        if (pageData.bulkProfileData.length == 0) {
                            pageData.bulkProfileData.push({ioOfferId:v.ioOfferId, profileId:v.profileId});
                        }
                        else if (v.ioOfferId != null && v.profileId != null) {
                            var stop = pageData.bulkProfileData.length,
                                ioOfferIdFound = false,
                                profileIdFound = false;

                            for (var i = 0; i< stop; i++) {
                                if (pageData.bulkProfileData[i].ioOfferId == v.ioOfferId) {
                                    ioOfferIdFound = true;
                                }
                                if (pageData.bulkProfileData[i].profileId == v.profileId) {
                                    profileIdFound = true;
                                }
                            }

                            if (!ioOfferIdFound || !profileIdFound) {
                                pageData.bulkProfileData.push({ioOfferId:v.ioOfferId, profileId:v.profileId})
                            }
                        }
                    });

                    $scope.campaignData = data;
                    $scope.doProfileAssetStats($scope.campaignData);                        
                    $scope.searchDone = true;
                    $scope.dataLoading  = false;

                    // Sort the data
                    var orderedData = params.sorting ? $filter('orderBy')(data, params.orderBy()) : data;

                    // Filter the data
                    orderedData = $filter('campaignStatusFilter')(orderedData, $scope.campaignStatusForFilter);
                    orderedData = $filter('filter')(orderedData, $scope.tblSearch);

                    // Update table params
                    params.total(orderedData.length);

                    // Slice off the data for the current page
                    $scope.campaignData = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count());

                    // Set the lastPage
                    $scope.lastPage = Math.ceil($scope.tableParams.total() / $scope.tableParams.count());

                    // Resize all the select elements
                    $scope.resizeInputs('#search-results', 'select');

                    // Do the stuff
                    $defer.resolve($scope.campaignData);
                });
            }, 50);
        }
    });
};


如果我可以使用纯粹的Angular解决方案,我更喜欢这样。有没有办法绑定每列中的选择元素,以便它们共享相同的宽度?如果可能的话,那将是最好的,因为当选择不同的值时<select>的宽度会改变!

谢谢!

1 个答案:

答案 0 :(得分:4)

我想这可以通过简单的CSS指令来完成。

select {
   display: block;
   width: 100%;
}

如果没有,那么可能是您自己代码的这个版本:

$scope.resizeInputs = function(table, inputType) {
    var cols = [],
        rows = table + " tbody tr";
    $(rows).each(function(i, tr) {
        $(tr).find('td').each(function(i, td) {
            cols[i] = Math.max(cols[i] || 0, $(td).find(inputType).width() || 0);
        });
    }).each(function(i, tr) {
        $(tr).find('td').each(function(i, td) {
            $(td).find(inputType).width(cols[i]);
        });
    });
}

似乎工作 - http://jsfiddle.net/Lenkhvvp/

编辑...

要从摘要周期触发该功能,请按如下所示进行编写:

function resizeInputs(table, inputType) {
    var cols = [],
        rows = table + " tbody tr";
    $(rows).each(function(i, tr) {
        $(tr).find('td').each(function(i, td) {
            cols[i] = Math.max(cols[i] || 0, $(td).find(inputType).width() || 0);
        });
    }).each(function(i, tr) {
        $(tr).find('td').each(function(i, td) {
            $(td).find(inputType).width(cols[i]);
        });
    });
}

并建立$watch

$rootScope.$watch(resizeInputs.bind(null, '#myTable', 'select'));

编辑2 ...

你应该能够将功能从中间切成一个观察者&#34;一半和一个&#34; resizer&#34;半。

根据我的理解,观察者将每次摘要运行一次,但是通过返回正在观察的值,可以使调整器每次观察到的变化运行一次&#34;来自守望者。但是,与角度文档中的示例不同,我们的&#34;值正在被观看&#34;是一个数组 - 即cols。我们可以简单地返回cols,但返回cols.join()会更友善,这将更容易与之前的值进行比较。

同样,据我理解,返回值的比较是通过角度自动执行的,只需要手动oldValue !== newValue比较来抑制对初始化的不良影响。但是,如果您不愿意对其进行编码,那么进行比较并没有什么坏处。

把所有这些放在一起,我得到以下结论:

function watcher(table, inputType) {
    var cols = [],
        rows = table + " tbody tr";
    $(rows).each(function(i, tr) {
        $(tr).find('td').each(function(i, td) {
            cols[i] = Math.max(cols[i] || 0, $(td).find(inputType).width() || 0);
        });
    });
    return cols.join();
}
function resizer(table, inputType, oldValue, newValue) {
    if(newValue !== oldValue) {
        var cols = newValue.split(','),
            rows = table + " tbody tr";
        $(rows).each(function(i, tr) {
            $(tr).find('td').each(function(i, td) {
                $(td).find(inputType).width(cols[i]);
            });
        });
    }
}

现在,我们可以提供&#34; $ watch&#34;声明它的两个参数,每个参数都是一个绑定值的函数。

$rootScope.$watch(
    watcher.bind(null, '#search-results', 'select'), 
    resizer.bind(null, '#search-results', 'select')
);