1

フィルタを実行し、構造が以下のような製品を吐き出す URL があります。

/Products/Catalogue/tabid/102/andmode/1/Default.aspx?catfilter=185,223

これにはソート機能があり、上記のようにフィルタリングなしでこれを使用すると、URL は次のようになります。

/Products/Catalogue.aspx?orderby=price&desc=1&psize=9

現在、フィルター処理してから並べ替えを試行すると、並べ替えによって myfilter が上書きされるため、フィルターは null および無効になります。

だから私がする必要があるのは、フィルタがある場合、URLの「catfilter =」部分の後にソートを追加して、URLが次のようになることに注意することです

/Products/Catalogue/tabid/102/andmode/1/Default.aspx?catfilter=8,188&orderby=man&desc=0&psize=36

落とし穴は、常にフィルターが追加されるとは限らないということです。その場合、URL は次のようになります:
/Products/Catalogue.aspx

<select id="listSort" class="NormalTextBox SortCatalogue" onchange="location = this.options[this.selectedIndex].value + '&' + getElementById('listLength')[getElementById('listLength').selectedIndex].value.split('?')[1] + document.getElementById('searchstrdiv').innerHTML.replace('amp;','');">
    <option value="?orderby=name&amp;desc=0&amp;">Sort by</option>
    <option value="?orderby=price&amp;desc=0">Lowest price</option>
    <option value="?orderby=price&amp;desc=1">Highest price</option>
    <option value="?orderby=man&amp;desc=0">Brand A-Z</option>
    <option value="?orderby=man&amp;desc=1">Brand Z-A</option>
    <option value="?orderby=name&amp;desc=0">Title A-Z</option>
    <option value="?orderby=name&amp;desc=1">Title Z-A</option>
    <option value="?orderby=ref&amp;desc=0">Code asc</option>
    <option value="?orderby=ref&amp;desc=1">Code desc</option>
</select>
<span style="text-align:right">Page size</span>
<select id="listLength" class="NormalTextBox PageLength" onchange="location = this.options[this.selectedIndex].value + '&' + getElementById('listSort')[getElementById('listSort').selectedIndex].value.split('?')[1] + document.getElementById('searchstrdiv').innerHTML.replace('amp;','');">
    <option value="?psize=9&foo">Page size</option>
    <option value="?psize=6">6 per page</option>
    <option value="?psize=9">9 per page</option>
    <option value="?psize=18">18 per page</option>
    <option value="?psize=36">36 per page</option>
</select>

<script type="text/javascript">

    var searchString = window.location.search.substring(1);
    var i, val;
    var params = searchString.replace('?','&').split('&');
    var pgsize,pgorder,pdesc,searchstr; 
    pgsize = 9;
    pgorder = 'name';
    pdesc = 0;
    searchstr='';
    for (i=0;i<params.length;i++) {
        val = params[i].split('=');
        if(val[0]== "psize")
            pgsize=val[1];
        else if(val[0]== "orderby")
            pgorder=val[1];
        else if(val[0]== "desc")
            pdesc=val[1];
        else if((val[0]).toLowerCase()== "search") { 
            searchstr=val[1]; 
        }
    }
    document.getElementById('listLength').value='?psize=' + pgsize;
    document.getElementById('listSort').value ='?orderby=' + pgorder + '&desc=' + pdesc;

    if(searchstr!='') {
        searchstr =decodeURIComponent(searchstr.replace(/\+/g, '%20'));
        document.getElementById('searchstrdiv').innerHTML= '&search=' + searchstr ;
        document.getElementById('searchtxthdrleft').innerHTML= 'Results for "' ;
        document.getElementById('searchtxthdrright').innerHTML= '"' ;
        document.getElementById('searchtxt').innerHTML = searchstr;
    }
 </script>
4

2 に答える 2

1

さて、問題から一歩離れましょう。あちこちでURLコードのビットを無作為に追加したり削除したりするのではなく、もう少し構造を追加する必要があると思います:)

投稿にjQueryのタグを付けたので、投稿されたコードで実際に使用していませんが、それを使用します。

全体のアイデアは、JavaScript オブジェクトを作成し、それを軽量の辞書として使用することと、最後にそれをエンコードするjQuery .param() 関数を中心にしています。

マークアップを次のように変更します。

<select id="listSort" class="NormalTextBox SortCatalogue">
    <option value="nameDesc">Sort by</option>
    <option value="priceAsc">Lowest price</option>
    <option value="priceDesc">Highest price</option>
    <option value="manAsc">Brand A-Z</option>
    <option value="manDesc">Brand Z-A</option>
    <option value="nameAsc">Title A-Z</option>
    <option value="nameDesc">Title Z-A</option>
    <option value="refAsc">Code asc</option>
    <option value="refDesc">Code desc</option>
</select>
<span style="text-align:right">Page size</span>
<select id="listLength" class="NormalTextBox PageLength">
    <option value="9">Page size</option>
    <option value="6">6 per page</option>
    <option value="9">9 per page</option>
    <option value="18">18 per page</option>
    <option value="36">36 per page</option>
</select>
<input type="text" id="searchstr">
<button id="searchbutton">Search!</button>

searchstrご覧のとおり、コードで参照しているように、テキストボックスとボタンも投入しました。

エンコードして抽出する代わりに、解析可能な値を選択オプションに保存するだけです。また、javascript をマークアップに挿入するのではなく、ID を使用して onchange ハンドラーをアタッチすることにより、目立たない JavaScript 手法を使用します (これは後で追加されます)。

ここで、クエリ文字列を作成できる JavaScript コードを記述する必要があります。ただし、クエリ文字列を直接作成する代わりに、javascript オブジェクトを作成します。その後、それがクエリ文字列の生成に使用されます。

ユーザーをリダイレクトするのではなく、生成したクエリ文字列を表示するだけの検索関数を作成しました。

また、いくつかのイベント ハンドラーを追加したので、これはコードがトリガーされたときにトリガーされます。

function getFiltersAsQueryString() {
    var $listSort = $("#listSort"),
        $listLength = $("#listLength"),
        $searchQuery = $("#searchstr");
        queryStringDict = {};

    // extract page size
    queryStringDict["psize"] = $listLength.find("option:selected").val();    

    // extract sort order and direction
    var selectedItem = $listSort.find("option:selected").val();    
    queryStringDict["orderby"] = /^[a-z]*/.exec(selectedItem)[0];
    queryStringDict["desc"] = /Desc$/.exec(selectedItem) == "Desc" ? 1 : 0;

    // extract search
    queryStringDict["search"] = $searchQuery.val();

    return $.param(queryStringDict);
}

function searchWithFilters() {
    // normally you would do a window.location here to redirect
    alert(getFiltersAsQueryString());
}

$(document).ready(function () {
    // wire up our handlers
    $("#listSort").change(searchWithFilters);
    $("#listLength").change(searchWithFilters);
    $("#searchbutton").click(searchWithFilters);
});

そして、一日の終わりにこれらすべてをまとめると、次のようになります。

これはまだ完全な解決策ではないと思います。

  1. 猫フィルターを追加する必要があります
  2. おそらく、クエリ文字列に基づいてコントロールを事前に選択したいですか?

これを投稿して、正しい方向に進んでいるかどうかを確認したかっただけです。

于 2013-07-23T14:41:22.883 に答える
1

非常に役に立ちました。最終的には、このいくつかの JS と Jquery を使用して、完全なソリューションを考え出しました。

<script type="text/javascript">
var searchString = window.location.search.substring(1);
var i, val;
var params = searchString.replace('?','&').split('&');
var pgsize,pgorder,pdesc,searchstr,catfilter;
pgsize = 9;
pgorder = 'name';
pdesc = 0;
searchstr='';
for (i=0;i<params.length;i++) {
val = params[i].split('=');
if(val[0]== "psize")
pgsize=val[1];
else if(val[0]== "orderby")
pgorder=val[1];
else if(val[0]== "desc")
pdesc=val[1];
else if(val[0]== "catfilter")
catfilter=val[1];
else if((val[0]).toLowerCase()== "search")
{ searchstr=val[1]; }
}
document.getElementById('listLength').value='?psize=' + pgsize;
document.getElementById('listSort').value ='?orderby=' pgorder '&desc=' + pdesc;
if(searchstr!='')
{
searchstr =decodeURIComponent(searchstr.replace(/\+/g, '%20'));
document.getElementById('searchstrdiv').innerHTML= '&search=' + searchstr ;
document.getElementById('searchtxthdrleft').innerHTML= 'Results for "' ;
document.getElementById('searchtxthdrright').innerHTML= '"' ;
document.getElementById('searchtxt').innerHTML = searchstr;
}

if(catfilter)
{
document.getElementById('searchstrdiv').innerHTML=                 document.getElementById('searchstrdiv').innerHTML + '&catfilter=' + catfilter ;
}

</script>

<script type="text/javascript"> 
$(document).ready(function(){

$('.SortCatalogue').removeAttr('onchange');
$('.SortCatalogue').change(function() {newURL();});
$('.PageLength').removeAttr('onchange');
$('.PageLength').change(function() {newURL();});

function newURL()
{

var newParams = document.getElementById('listSort')    [document.getElementById('listSort').selectedIndex].value + '&amp;' +     document.getElementById('listLength')    [document.getElementById('listLength').selectedIndex].value.split('?')[1] +     document.getElementById('searchstrdiv').innerHTML.replace('amp;','');

var oldPathname = location.pathname;
oldPathname = oldPathname.replace('/desc/','/').replace('/orderby/', '/');

document.location.href = oldPathname + newParams;

}

});
</script>
于 2013-07-26T03:14:33.547 に答える