Javascript でJSONデータを扱う。日付の加算をする。JSでフォームを生成する

日付の加算
旅行プラン（料金、オプション）
HTMLサンプル

```sample.html
<html>
<head>
<title>AggregateJs</title>
<link rel='stylesheet' id='crayon-css'  href='css/default.css' type='text/css' media='all' />
<script src="js/jquery-1.11.1/jquery.min.js" ></script>
<style>
*{
 margin:0px;
}
ol{
    margin:1em;
}
.message_box{
    width:auto;
    border:1px solid #aaa;
    padding:1em;    

}
.input_messsage{
    width:auto;
    border:1px solid #aaa;
    padding:1em;    

}
.disp_button{
 width:200px;
 padding: 6px;

}
.message{
    width:200px;
    border:1px solid #aad;
    margin:0.5em ;
}
.optionForm{
    margin: 0.5em;
   
}
.optionForm select{
    padding: 0.4em;
  
}

</style>


<script>

// サンプル日付データ
var DateRage = [
 {'date' :'2019/08/12' }
,{'date' :'2019/08/11' }
,{'date' :'2019/08/13' }
];

// プランマスタテーブル
var PlanMaster = [
 {'date_label' :'','normal_price' :1200, 'special_price':null,'valid':true,'wd' :'2' }
,{'date_label' :'','normal_price' :1100, 'special_price':null,'valid':true,'wd' :'1' }
,{'date_label' :'','normal_price' :1300, 'special_price':null,'valid':true,'wd' :'3' }
,{'date_label' :'','normal_price' :1400, 'special_price':null,'valid':true,'wd' :'4' }
,{'date_label' :'','normal_price' :1500, 'special_price':null,'valid':true,'wd' :'5' }
,{'date_label' :'','normal_price' :1600, 'special_price':null,'valid':true,'wd' :'6' }
,{'date_label' :'','normal_price' :1700, 'special_price':null,'valid':true,'wd' :'7' }
,{'date_label' :'20190818','normal_price' :1100, 'special_price':2110,'valid':true,'wd' :'0' }
,{'date_label' :'20190819','normal_price' :1400, 'special_price':2410,'valid':true,'wd' :'0' }

];

// 個数、追加コース種別・金額：画面にフォームを表示する
var PlanOpts=[
    {
       "Title":"オプション1：カルチャー", 
       "Code":"1001", 
        "OptQty" : [1,2,3,4,5], 
        "Activities":[
            {"label":"1-A 特別コース","code":"12000"},
            {"label":"1-B 特別コース","code":"15000"},
            ],
        "Tags":[
            {"label":"音楽","code":"1000"},
            {"label":"書籍","code":"5000"},
            {"label":"イベント","code":"2000"},
            ],
    },
    {
        "Title":"オプション2:スポーツ", 
        "Code":"1002", 
        "OptQty" : [1,5,10,15], 
        "Activities":[
            {"label":"2-A 特別コース","code":"13000"},
            {"label":"2-B 特別コース","code":"16000"},
            {"label":"2-C 特別コース","code":"18000"},
            ],
        "Tags":[
            {"label":"野球","code":"1000"},
            {"label":"サッカー","code":"5000"},
            {"label":"卓球","code":"2000"},
            {"label":"ラグビー","code":"3000"},
            {"label":"バスケットボール","code":"4000"},
        ],
    },

];

//リストをもとにselectフォームを生成
var genOptQtyForm=function(list, name){
    var html ="<select >";
    list.forEach(el=>{
        html +="<option value=\"" + el + "\">";
        html += el ;
        html +="</option>"; 
    })    ;
    html +="</select>"; 
    return html ;

}


//----------------------------------------------

//リストをもとにselectフォームを生成
var genActivityForm=function(list, name){
    var html ="<select >";
    list.forEach(el=>{
        html +="<option value=\"" + el.code + "\">";
        html += el.label +" " ;
        html +="</option>"; 
    })    ;
    html +="</select>"; 
    return html ;

}

//リストをもとにcheckboxフォームを生成
var genTagForm=function(list, course_code){
    var html ="<span class=\"tags_group\">";
    list.forEach(el=>{
        html +="<input type=\"checkbox\" value=\"" + el.code +"\"";
        html +=" id=\"" + course_code +"_"+ el.code ;
        html +="\">";
        html +="<label for=\"" + course_code +"_"+ el.code + "\" >"; 
        html += el.label +" " ;
        html +="</label>"; 
    })    ;
    html +="</span>"; 
    return html ;

}

var dispOptionForm=function(){
    var html ="";
    PlanOpts.forEach(el => {
        html +="<span class='optionForm'>" ;
        html +="<h3>" + el.Title +"</h3>" ;
        html +="コース" + genActivityForm(el.Activities) ; 
        html +="個数" + genOptQtyForm(el.OptQty) ; 
        html +="タグ" + genTagForm(el.Tags,el.Code ) ; 
        html +="</div>"  ; 
        
    });
    $('#options').html(html);
}
//日付、曜日番号から料金、予約可能フラグを取得する
var resolveInfo = function(date_str,wday_num)
{
    var buf ;
    var price ;
    var wd ;
    for(var i=0 ; i < PlanMaster.length ; i++)
    {
        row=PlanMaster[i];
        if( parseInt(row.wd) === wday_num) { price=row.normal_price; wd=row.wd; }
        if( row.date_label === date_str.replace(/\//g,'') ) {price=row.special_price; wd=row.wd;}
        buf={ 'date_str':date_str, 'price' : price, 'wd' : wd }   ;
    }
    //list.push(buf);
    return buf;
}

//表示する
var disp = function()
{
    var res ="";
    var dt ;//
    var buf;
    var wd;

    //月曜は1～日曜日は7

    for(var i=0 ; i < DateRage.length ; i++)
    {
        x = DateRage[i] ;
        dt = new Date(x.date);
        wd = (dt.getDay())? dt.getDay() : 7;

        res += x.date ;
        res += "(" ;
        res += wd ;
        res +=")" ;
        buf = resolveInfo(x.date, wd);

        res += buf.wd + ":" + "(price:" + buf.price + ")" ;
        res += "<br/>" ;
    }
    //console.log(res);
    $('#res').html(res);
}


</script>

<script>
$(document).ready(function(){
    $('#res').html('');

});

function hc(ch){
    ch = ch.replace(/&/g,"&amp;") ;
    ch = ch.replace(/"/g,"&quot;") ;
    ch = ch.replace(/'/g,"&#039;") ;
    ch = ch.replace(/</g,"&lt;") ;
    ch = ch.replace(/>/g,"&gt;") ;
    return ch ;
}

//HTMLタグは実体参照、ただし改行は有効にしたい
note_check=function(){
    var val = $('#note').val();
    
    //すべてのhtmlタグが無効化され表示(実体参照)
    $('#note_text').text(val );

    //brタグ(改行)のみ有効 1)/の有無は許容、2)閉じタグ前の空白は許可
    $('#note_html').html(hc(val).replace(/&lt;br\/? *&gt;/g,"<br/>") );


}

$(function() {

    dispOptionForm();

    DateRage=[];

    var dtFmt;
    var row ;
    for(var i=0 ; i<14;i++)
    {
        var dt = new Date('2019/08/12')
        dt.setDate(dt.getDate() + i);
        dtFmt= dt.getFullYear() +"/" 
        dtFmt +=( dt.getMonth() +1  <10) ? "0" + (dt.getMonth() +1)  : dt.getMonth() + 1 ;
        dtFmt +="/" ; 
        dtFmt +=(dt.getDate() < 10)?  "0" +dt.getDate() : dt.getDate();
        console.log (dtFmt);
        row={'date':dtFmt}
        DateRage.push(row) ;
    }
    console.log(DateRage);
    
    
    var sortOrder=1 ;//1:昇順,-1:降順
    DateRage.sort(function(a,b){
        if( a.date < b.date ) return -1 * sortOrder;
        if( a.date > b.date ) return sortOrder;
        return 0;
    });

    disp();
    /*
    var result = $('li[id$="text"]');
    console.log( result );
 
    var result = $('a[id^="x_t"]');
    console.log( result );

    result.each(function(i, elem) {
        console.log( elem.id );
        console.log( elem.id.slice( -2 ) ); 
    });
    */


});


$(document).on("click", ".message", function(){
    alert($(this).text());
});

</script>
</head>
<body>
<h1>AggregateJs</h1>

<div id="options" class="message_box"  >xxx</div>
<br/>

<button class="disp_button" onclick="disp()">recalculate</button>


<div id="res" class="message_box"  >xxx</div>

<textarea id="note" onchange="note_check()" style="width:400px; height:300px;"><b>ああ
    １：<br/>
    ２：<br/>
    ３：<br/>
    ４：<br/>
    </textarea>
<br/>
<h3>Html:</h3><div id="note_html"></div>
    <h3>Text:</h3><div id="note_text"></div>
<button class="note_button" onclick="note_check()">check</button>

```