54

このようなHandlebars.jsテンプレートを使用して...

<select>
    <option value="Completed">Completed</option>
    <option value="OverDue">OverDue</option>
    <option value="SentToPayer">SentToPayer</option>
    <option value="None">None</option>
</select>

...そしてこのようなデータ...

{
    "id"     : 1,
    "name"   : "World"
    "status" : "OverDue",
    "date"   : "2012-12-21"
}

このようにHTMLをレンダリングしたいと思います。

<select>
    <option value="Completed">Completed</option>
    <option value="OverDue" selected="selected">OverDue</option>
    <option value="SentToPayer">SentToPayer</option>
    <option value="None">None</option>
</select>

どちらが最も簡単ですか?

4

18 に答える 18

92

非常に複雑なソリューションをたくさん見つけたので、Handlebarsヘルパーを使用して独自のソリューションを作成することにしました。

この部分で(Jqueryを使用して)..。

    window.Handlebars.registerHelper('select', function( value, options ){
        var $el = $('<select />').html( options.fn(this) );
        $el.find('[value="' + value + '"]').attr({'selected':'selected'});
        return $el.html();
    });

ハンドルバーテンプレートのselectを{{#selectstatus}}でラップできます...

<select>
    {{#select status}}
    <option value="Completed">Completed</option>
    <option value="OverDue">OverDue</option>
    <option value="SentToPayer">SentToPayer</option>
    <option value="None">None</option>
    {{/select}}
</select>

そしてこれで終わる...

<select>
    <option value="Completed">Completed</option>
    <option value="OverDue" selected="selected">OverDue</option>
    <option value="SentToPayer">SentToPayer</option>
    <option value="None">None</option>
</select>

プレスト!

于 2012-10-24T09:29:29.277 に答える
36

OPと同様のニーズがありました。静的な選択オプションのセットがありますが、動的に選択された値があります。私は@janjarfalkのソリューションが本当に好きですが、node.jsを使用していて、jQueryを取り込んでいません。そこで、RegExpに基づいて独自のバリエーションをまとめました。これが他の人に役立つことを願っています。

ハンドルバーヘルパー:

hbs.registerHelper('select', function(selected, options) {
    return options.fn(this).replace(
        new RegExp(' value=\"' + selected + '\"'),
        '$& selected="selected"');
});

ハンドルバーテンプレート:

<select>
    {{#select CurrentSort}}
    <option value="1">Most Recent First</option>
    <option value="2">Most Recent Last</option>
    <option value="3">Highest Score First</option>
    <option value="4">Highest Score Last</option>
    <option value="5">Most Comments</option>
    <option value="6">Fewest Comments</option>
    <option value="7">Most Helpful Votes</option>
    <option value="8">Fewest Helpful Votes</option>
    {{/select}}
</select>

属性を使用しない場合でも、ヘルパーを調整して機能させることができますvalue。正規表現を調整して要素テキストを検索し、一致するテキストの前に文字列を置き換えます。

于 2013-06-04T22:17:52.300 に答える
20

@janjarfalkによって投稿された非常に巧妙なソリューションを見て、value属性(など<option>Value</option>)なしで定義されたオプションでは機能しないことに気付きました。私のアプリケーションはそれを必要としていました、そして私はパフォーマンスのためにバニラJavaScriptで行われるヘルパーが欲しかったので、私は次のことを思いつきました。

このソリューションは、jQueryを使用しないため<option>Both a label and a value</option>、に加えてサポートし、はるかに高速になります。<option value="aValue">A label</option>

Handlebars.registerHelper('select', function(value, options) {
    // Create a select element 
    var select = document.createElement('select');

    // Populate it with the option HTML
    select.innerHTML = options.fn(this);

    // Set the value
    select.value = value;

    // Find the selected node, if it exists, add the selected attribute to it
    if (select.children[select.selectedIndex])
        select.children[select.selectedIndex].setAttribute('selected', 'selected');

    return select.innerHTML;
});

使用法:

<select>
    {{#select status}}
    <option>Option 1</option>
    <option>Option 2</option>
    <option value="Option 3">Option 3 (extra info)</option>
    <option value="Option 4">Option 4 (more extra)</option>
    {{/select}}
</select>
于 2013-03-12T22:10:37.723 に答える
16

私のために働く

<select>
    <option value="{{status}}" hidden="hidden" selected="selected">{{status}}</option>
    <option value="Completed">Completed</option>
    <option value="OverDue">OverDue</option>
    <option value="SentToPayer">SentToPayer</option>
    <option value="None">None</option>
</select>
于 2017-06-19T09:27:01.877 に答える
10

コンテキストが原因で、「each」ヘルパーを使用して動的なものを構築するときに、「selectblock」アプローチで問題が発生しました。

これが私の解決策です:

  Handlebars.registerHelper('option', function(value, label, selectedValue) {
    var selectedProperty = value == selectedValue ? 'selected="selected"' : '';
    return new Handlebars.SafeString('<option value="' + value + '"' +  selectedProperty + '>' + label + "</option>");
  });

そしてテンプレート:

<select>
  {{#each status}}
    {{option id name ../statusId}}
  {{/each}}
</select>
于 2013-12-06T14:45:15.770 に答える
7

一致するものがない場合に最初のオプションを選択する@lazdの回答を改善しました。

Handlebars.registerHelper('select', function(value, options) {
    // Create a select element 
    var select = document.createElement('select');


// Populate it with the option HTML
$(select).html(options.fn(this));

//below statement doesn't work in IE9 so used the above one
//select.innerHTML = options.fn(this); 

    // Set the value
    select.value = value;

    // Find the selected node, if it exists, add the selected attribute to it
    if (select.children[select.selectedIndex]) {
        select.children[select.selectedIndex].setAttribute('selected', 'selected');
    } else { //select first option if that exists
        if (select.children[0]) {
            select.children[0].setAttribute('selected', 'selected');
        }
    }
    return select.innerHTML;
});

使用法は同じままです:

<select>
    {{#select status}}
    <option>Option 1</option>
    <option>Option 2</option>
    <option value="Option 3">Option 3 (extra info)</option>
    <option value="Option 4">Option 4 (more extra)</option>
    {{/select}}
</select>
于 2013-08-21T05:54:08.090 に答える
4

これにはテンプレートでより多くのコードが必要になる場合がありますが、読みやすくなります。

.js

Handlebars.registerHelper('select', function(selected, option) {
    return (selected == option) ? 'selected="selected"' : '';
});

.hbs

<select name="status">
    <option value="public" {{{select story.status 'public'}}}>Public</option>
    <option value="private" {{{select story.status 'private'}}}>Private</option>
    <option value="unpublished" {{{select story.status 'unpublished'}}}>Unpublished</option>
</select>
于 2017-10-18T04:28:09.207 に答える
2

私はちょうどこの問題に遭遇しました、これがオプションが動的であるときの解決策です。

選択ヘルパーを作成する代わりに、選択したいアイテムの値を受け入れるオプションヘルパーを作成しました。

Handlebars.registerHelper('option', function(value) {
  var selected = value.toLowerCase() === (this.toString()).toLowerCase() ? 'selected="selected"' : '';
  return '<option value="' + this + '" ' + selected + '>' + this + '</option>';
});

そして私のテンプレートで。

{{#items}}
    {{{option ../selected_value}}}
{{/items}}

selected_valueがitems配列内にある可能性は低いため、親のスコープにアクセスするために../に注意してください。

乾杯。

于 2013-04-25T06:39:02.437 に答える
2

私はテンプレートアプローチを使用することを好みます。これは、オプションタグ自体のレイアウトが、JavaScriptヘルパーではなく、ハンドルバーテンプレート(誰かがそれを探す可能性がある場所)で指定されていることを意味します。ブロックヘルパー内のテンプレートはヘルパースクリプトに渡され、options.fn()を呼び出すことで使用できます。その後、options.fn()は、ヘルパーで行ったスクリプトの変更を使用します。

レンプレート:

<select>
  {{#optionsList aStatusList sCurrentStatusCode 'statusCode'}}
    <option {{isSelected}} value="{{statusCode}}">{{statusName}}</option>
  {{/optionsList}}
</select>

わずかに変更されたデータ(必須ではありませんが、私にとってはもう少し「現実の世界」)

var myOrder = 
{
    "id"     : 1,
    "name"   : "World",
    "statusName" : "OverDue", /* status should NOT be here! */
    "statusCode" : "1",
    "date"   : "2012-12-21"
}

var sCurrentStatusCode = myOrder.statusCode;

var aStatusList =
[
    {
        "statusName"       : "Node",
        "statusCode" : 0
    },
    {
        "statusName"       : "Overdue",
        "statusCode" : 1
    },
    {
        "statusName"       : "Completed",
        "statusCode" : 2
    },
    {
        "statusName"       : "Sent to Payer",
        "statusCode" : 3
     }
]

Javascript登録ヘルパー:

Handlebars.registerHelper( 'optionsList',
function ( aOptions, sSelectedOptionValue, sOptionProperty, options )
{
  var out = "";
  for ( var i = 0, l = aOptions.length; i < l; i++ )
  {
    aOptions[ i ].isSelected = '';
    if( ( sOptionProperty != null &&  sSelectedOptionValue == aOptions[ i ][ sOptionProperty ] ) || (  sSelectedOptionValue == aOptions[ i ] ) )
    {
      aOptions[ i ].isSelected = ' selected="selected" ';
    }
    out = out + options.fn( aOptions[ i ] );
  }
  return out;
} );

optionsListは、このヘルパーに名前を付けるために選択したものです

aStatusListステータスオブジェクトの配列には、ステータス値/名前を含むいくつかのプロパティが含まれています(ほとんどの場合、これは保存されているステータス名ではなくステータスコードになります)

sCurrentStatusは、以前に選択されたステータスコード(値ではない)であり、この生成されたオプションリストで選択したいオプション値です。

statusCodeは、aStutusList[loopIndex][ statusCode ]であるmyStatusと一致するかどうかを確認するためにテストするaStatusListオブジェクト内の文字列プロパティ名です。

  • 文字列オプションプロパティ(この場合はstatusCode)はオブジェクトにのみ必要です-オプションリストは(文字列を含むオブジェクトの代わりに)文字列の配列にすることもできます。その場合、3番目のプロパティ'statusCode'を省略できます。ヘルパーは、オブジェクトのどのプロパティを再度テストするか。そのプロパティに合格しない場合は、リストアイテム自体を再度テストします。
  • sSelectedOptionValueが渡されない場合、選択された項目を設定せずにリストが作成されます。これにより、 {{#each}}ヘルパーを使用する場合とほぼ同じようにリストが生成されます
于 2015-07-16T15:48:17.490 に答える
1

オプションがほとんどなく、ヘルパーを作成したくない場合は、次のことができます。

//app.js
var data = {selectedVal: 'b'}; 

// can also use switch ... case ...
if (data.selectedVal === 'a') {
   data.optionASelected = true;
} else if (data.selectedVal === 'b') {
   data.optionBSelected = true;
}

// assuming you have a template function to handle this data
templateFunc(data);

テンプレートファイル内:

<!-- template.html -->
<select id="select-wo-helper" >
  <option value="a" {{#if optionASelected}} selected {{/if}}>A</option>
  <option value="b" {{#if optionBSelected}} selected {{/if}}>B</option>
</select>

繰り返しになりますが、これはすべての中で最善の解決策ではないかもしれませんが、非常に少数のオプションを扱っていて、迅速な修正が必要な場合は、おそらく非常に迅速な回避策です。

于 2016-08-02T21:25:35.503 に答える
1

今日、私はコンテンツ管理システムを作成しているのと同じ問題に直面し、スタックした投稿のステータスを取得して解決策を探していたところ、このページにたどり着きました。サーバーを使用しているため、関連するいくつかの回答が見つかりました。 -サイドデータで、document.createElementを使用すると、エラードキュメントがスローされます。ドキュメントが定義されていません。

正規表現ソリューションは私にとってはうまくいきましたが、それが冗長であるかどうかを簡単に理解できるようにしたいので、このソリューションを使用しました。

 Handlebars.registerHelper('getValue', function(value, options) {
   if(options.fn(this).indexOf(value) >= 1){
         return `selected='selected'`;
      }
});

テンプレートでは、このようにコードを使用します

  <select name="post-status" id="post-status">
        <option {{#getValue posts.postStatus}} value="Draft" {{/getValue}} >Draft</option>
        <option {{#getValue posts.postStatus}} value="private" {{/getValue}} >private</option>
        <option {{#getValue posts.postStatus}} value="publish" {{/getValue}} >publish</option>
</select>

どこか間違っていたら訂正してください。

于 2019-11-26T20:15:43.050 に答える
1

情報源

selectedValue: "8",
option:[
    {id_sub_proyectop: "8", clave: "021", name: "Cliclismo"},
    {id_sub_proyectop: "9", clave: "022", name: "Atletismo"},
],

ヘルパー

Handlebars.registerHelper('selected', function(value, prop) {
    if (value === undefined){ return '';};
    return value === this[prop] ? 'selected="selected"' : '';
});

レンプレート

<div class="medium-6 cell">
    <label>Sub Proyecto / Proceso:
        <select name="id_sub_proyectop" required>
            {{#each option}}
            <option value="{{id_sub_proyectop}}" {{{selected ../selectedValue 'id_sub_proyectop'}}}>{{clave}} - {{name}}</option>
            {{/each}}
        </select>
    </label>
</div>
于 2019-12-05T23:43:41.773 に答える
0

リピートを気にしない場合は、バニラハンドルバーを使用して、次のように選択したオプションを最初に配置することができます。

        <select name="ingredient">
        <option value="{{ingredient.id}}" selected>{{ingredient.name}}</option>
        {{#each ingredients}}
        <option value="{{this.id}}">{{this.name}}</option>
        {{/each}}
        </select>
于 2016-11-11T19:49:30.657 に答える
0

@lazdの答えは、<option>内の要素に対しては機能しません<optgroup>

selectedIndex<option>はすべてのsに対して単調に番号が付けられselect.childrenますが、<optgroup>sをselect.children[n].children保持し、 sをn<option>内に保持します(もちろん、番号付けは各s内で再開されます)。<optgroup><optgroup>

この代替バージョンは、s<option>内の要素に対して機能します。<optgroup>

Handlebars.registerHelper('select-optgrp', function(value, options) {
    var select = document.createElement('select'); // create a select element
    select.innerHTML = options.fn(this);           // populate it with the option HTML
    select.value = value;                          // set the value
    var g = 0, i = select.selectedIndex;           // calculate which index of which optgroup
    while (i >= select.children[g].children.length) { i -= select.children[g].children.length; g++; }
    if (select.children[g].children[i]) {          // if selected node exists add 'selected' attribute
        select.children[g].children[i].setAttribute('selected', true);
    }
    return select.innerHTML;
});
于 2016-12-09T12:22:59.457 に答える
0

express-handlebars動的オプションを使用するもう1つの解決策は、これです。

ヘルパー関数(すべてのオプションから必要なものを取得し、選択したものに変更します)。

select: function(selected, options) {
    return options.fn(this)
      .replace( new RegExp(' value=\"' + selected + '\"'), '$& selected="selected"')
      .replace( new RegExp('>' + selected + '</option>'), ' selected="selected"$&');
  }

ハンドルバーファイル(私はデータを受け取るためにselect内の#eachを使用し、チャームのように機能しました)。

<select name="justAname">
  {{#select content.campusId}}
    {{#each campus}}
      <option value="{{id}}">{{name}}</option>
    {{/each}}
  {{/select}}
</select>
于 2017-10-31T02:59:48.240 に答える
0
Handlebars.registerHelper('select', function( value, options ){
  return options.fn(this)
  .replace( new RegExp(' value=\"' + value + '\"'), '$& selected="selected"')
  .replace( new RegExp('>' + value + '</option>'), ' selected="selected"$&');
});

user.country from db session
country stored in country.json file

<select id="country" name="country" class="form-control">
<option value="" selected="selected">(please select a country)</option>
{{#select user.country}}
{{#each countries as |value key| }}
<option value="{{ value.code }}">{{ value.name }}</option>
{{/each}}
{{/select}}
</select>
于 2018-05-30T06:57:53.890 に答える
0

これは質問に直接答えないことはわかっていますが、この状況では、選択されていないhtmlオプションをテンプレートに渡し、レンダリングされた後、jqueryを使用してjsonオブジェクトが示す値を選択済みとしてマークします

于 2020-05-29T20:53:57.700 に答える
0

アレイの場合

function select(selected, options) {
    return options.fn(this).replace( new RegExp(' value=\"' + selected + '\"'), '$& selected="selected"').replace( new RegExp('>' + selected + '</option>'), ' selected="selected"$&');
  },
于 2021-05-17T03:00:17.827 に答える