2016-08-10 7 views
0

これは典型的な問題です。列を動的に(ajaxで)追加、更新、削除できるデータ表があるとします。
データテーブルは複雑で、多くのフィールド、ドロップダウン、テキストボックスなどがあります。javascriptで複雑なHTMLを作成する

どのようにしてJavaScriptで行を作成しますか?私は現在、多くのJS/Jqueryを作成してノードを生成していますが、それは非常に醜いものであり、あまり再利用できません。コードビハインドロードは、ちょうどfacetsSerializedHiddenに現在のデータをシリアライズするとき

<!-- table to contain the data --> 
<table id="facetsTable"> 
    <thead> 
     <tr> 
      <td>&nbsp;</td> 
      <th>Label</th> 
      <th>Display type</th> 
      <th>Is filter</th> 
      <th>Sort type</th> 
      <th>&nbsp;</th> 
     </tr> 
    </thead> 
    <tbody> 
    </tbody> 
</table> 
<br /> 

<!-- dropdown containing the facets to add --> 
<asp:DropDownList runat="server" ID="facetsToAddDdl"> 
    <asp:ListItem Text="" Value=""></asp:ListItem> 
</asp:DropDownList> 
<asp:Button runat="server" ID="facetAddButton" Text="[ADD]" /> 

<!-- hidden fields to contain both the current data and all the possible data --> 
<asp:HiddenField runat="server" ID="facetsSerializedHidden" /> 
<asp:HiddenField runat="server" ID="allAttributesSerializedHidden" /> 

私のaspxのはこれです。保存するときに、逆シリアル化します。

とJavaScriptはこれです:

var allAttributes = null; 

/***************************** 
* Adds a facet to the table 
*****************************/ 
function facetAdd(data) { 
    // build the table row 
    var tr = $('<tr>'); 

    // "move" handle 
    tr.append($('<td>').addClass('handle').append($('<img/>').attr('src', 'img/drag-drop.gif'))); 

    // label 
    tr.append(
     $('<td>') 
     .addClass('label') 
     .text(data.attr.DefaultListLabel.DefaultValue + ' (' + data.attr.Code + ')') 
     .append($('<input />').attr('type', 'hidden').attr('name', 'code').val(data.attr.Code))); 

    // display type 
    var disp = $('<select>').attr('name', 'displayType'); 
    // snip: fill options of the select 
    if (data.facet && data.facet.DisplayType !== '') { disp.val(data.facet.DisplayType) } 
    disp.change(function() { serializeFacets(); }); 
    tr.append($('<td>').append(disp)); 

    // ###### snip similar logic for the other fields ###### 

    // 'remove' image button 
    var delImg = $('<img />').attr('src', 'img/delete.png'); 
    delImg.click(function() { facetRemove($(this)) }); 
    tr.append($('<td>').addClass('delete').append(delImg)); 

    // add the row to the table 
    $('#facetsTable tbody').append(tr); 
} 

/***************************** 
* Removes a facet from the table 
*****************************/ 
function facetRemove(src) { 
    var tr = src.parents('tr'); 
    var code = tr.find('[name=code]').val(); 
    var label = tr.find('td.label').text(); 

    // remove from table 
    $(tr).remove(); 

    // add back item to dropdown list 
    var drop = $('#<%= facetsToAddDdl.ClientID %>'); 
    drop.append($('<option>', { value: code, text: label })); 

    // re-serialize 
    serializeFacets(); 
} 

/***************************** 
* Serialize the facets 
*****************************/ 
function serializeFacets() { 
    var ser = []; 
    var i = 0; 
    $('#facetsTable tbody tr').each(function() { 
     var facet = new Object(); 
     facet.Code = $(this).find('[name=code]').val(); 
     facet.Id = $(this).find('[name=code]').val(); 
     facet.DisplayType = $(this).find('[name=displayType]').val(); 
     facet.IsFilter = $(this).find('[name=isFilter]').prop('checked'); 
     facet.SortType = $(this).find('[name=sortType]').val(); 
     facet.Order = i; 

     ser.push(facet); 
     i++; 
    }); 

    $('#<%= facetsSerializedHidden.ClientID %>').val(JSON.stringify(ser)); 
} 

/***************************** 
* Activate sorting on the table 
*****************************/ 
function activateSorting() { 
    $('#facetsTable tbody').sortable({ 
     stop: function() { serializeFacets(); }, 
     handle: ".handle" 
    }); 
} 

/***************************** 
* Get the facet data from the attributes list 
*****************************/ 
function getFacetData(code, existingFacet) { 
    if (allAttributes === null) { return null; } 

    for (var i = 0; i < allAttributes.length; i++) { 
     if (allAttributes[i].Code === code) { 
      var facet = {}; 
      if (existingFacet === null) { 
       facet.Code = code; 
       facet.Id = code; 
       facet.Order = -1; 
      } else { 
       facet = existingFacet; 
      } 

      return { attr: allAttributes[i], facet: facet }; 
     } 
    } 

    return null; 
} 

$(function() { 
    // read attributes list 
    var allAttributesSerialized = $("#<%= allAttributesSerializedHidden.ClientID %>").val(); 
    if (allAttributesSerialized !== '' && allAttributesSerialized !== null) { 
     allAttributes = JSON.parse(allAttributesSerialized); 
    } 

    // activate sorting on the table 
    activateSorting(); 

    /***************************** 
    * Initialize facets on load 
    *****************************/ 
    var currentFacetsSerialized = $('#<%= facetsSerializedHidden.ClientID %>').val(); 
    if (currentFacetsSerialized !== '' && currentFacetsSerialized !== null) { 
     var currentFacets = JSON.parse(currentFacetsSerialized); 
     for (var i = 0; i < currentFacets.length; i++) { 
      facetAdd(getFacetData(currentFacets[i].Code, currentFacets[i])); 
     } 
    } 

    /***************************** 
    * Add a facet to the table on button click 
    *****************************/ 
    $("#<%= facetAddButton.ClientID %>").click(function() { 
     var code = $('#<%= facetsToAddDdl.ClientID %>').val(); 

     if (code === null || code === '') { return false; } 

     facetAdd(getFacetData(code, null)); 
     $('#<%= facetsToAddDdl.ClientID %> option:selected').remove(); 
     activateSorting(); 
     serializeFacets(); 

     return false; 
    }); 
}); 

私は行を作成できるように、私は、私が(例えばサービスを通じて)アヤックスに呼び出すことができますユーザーコントロールに私の行のHTMLを持っているのが大好きですJSと.netの両方で、私はどのように進むのかは分かりません。

+2

スタート、および_you_合ったものを選びますベスト。 –

+1

現在、「醜い」とは何ですか? (たぶん、これは、スタックオーバーフローの代わりにコードレビューサイトに属しています)私はちょうど与えられた値のセットで行を作成し、ちょうど私が行を追加する必要があるときにその関数を呼び出すJavaScriptでいくつかのテンプレート関数を作成すると思います。 – David

+0

これは非常に未解決の問題です。私が間違っていない限り(それを無視してください) – evolutionxbox

答えて

1

フロントエンドのテンプレート技術を使用できます。私は以下のバニラのJSソリューションを提供しましたが、jQueryプラグインを入手できます(質問にjQueryタグがあることがわかります)。テンプレート言語を使用してテンプレートにデータバインディングロジックを組み込みます。 Angular.jsもチェックアウトするのに興味があるかもしれません。

var templateText, 
 
    generatedEl, 
 
    anchorEl, 
 
    obj; 
 

 
// "JSON" data (could be loaded via AJAX) 
 
obj = { 'text': 'Hello World', 'href': '#' }; 
 

 
// Get template text 
 
templateText = document.getElementById('my-template').text.trim(); 
 

 
// Create a DIV and generate HTML within it 
 
generatedEl = document.createElement('div') 
 
generatedEl.innerHTML = templateText; 
 

 
// Modify the HTML content with obj data 
 
anchorEl = generatedEl.getElementsByTagName('a')[0]; 
 
anchorEl.text = obj.text; 
 
anchorEl.href = '#'; 
 

 
// Insert generated HTML (assumes only one top-level element exists) 
 
document.getElementById('my-container').appendChild(generatedEl.childNodes[0]);
<!-- Container --> 
 
<div id="my-container"> 
 
    
 
    <!-- HTML Template --> 
 
    <script id="my-template" type="text/template"> 
 
     <div class="item"> 
 
      <a></a> 
 
     </div> 
 
    </script> 
 
    
 
</div>

0

私は前に同様の問題を持っていました。私のために働いた解決策は、現在のテーブルの行数を取得し、その行のすべてのHTML要素を作成してテーブルに追加するテンプレートJS関数を用意することでした。 ASP生成テーブルでこれを行うか、リテラルを使用してstringbuilder(私の好み)を使ってバックエンドでテーブルを生成することができます。

1

jQuery(html, attributes)からの読み込み:

あなたはその場で要素を作成するPlainObjectを使用することができます:テンプレートシステムを研究

$(function() { 
 
    var obj = { 'id': 'anchor1', 'text': 'Hello World', href: '#' }; 
 
    
 
    $('<a>',obj).appendTo(document.body) 
 

 
    console.log(document.getElementById('anchor1').outerHTML); 
 
});
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>

関連する問題