1998 lines
78 KiB
PHP
1998 lines
78 KiB
PHP
<style>
|
|
#allTableContainer {
|
|
max-width: 100%;
|
|
overflow-x: auto;
|
|
display: block;
|
|
}
|
|
|
|
table {
|
|
width: 1200px;
|
|
table-layout: fixed;
|
|
margin-bottom: 20px;
|
|
border-collapse: collapse;
|
|
word-wrap: break-word;
|
|
}
|
|
|
|
th,
|
|
td {
|
|
font-size: smaller !important;
|
|
}
|
|
|
|
.table th.sticky,
|
|
.table td.sticky {
|
|
position: sticky;
|
|
left: 0;
|
|
background-color: #bfe0e2;
|
|
z-index: 2;
|
|
width: 10px;
|
|
}
|
|
|
|
th:nth-child(1),
|
|
td:nth-child(1) {
|
|
width: 110px;
|
|
/* Adjust first column width */
|
|
}
|
|
|
|
th:nth-child(2),
|
|
td:nth-child(2) {
|
|
width: 720px;
|
|
/* Adjust first column width */
|
|
}
|
|
|
|
|
|
|
|
th:nth-last-child(1),
|
|
td:nth-last-child(1) {
|
|
width: 200px;
|
|
/* Adjust last column width */
|
|
}
|
|
|
|
th,
|
|
td {
|
|
border: 1px solid #000;
|
|
padding: 8px;
|
|
}
|
|
|
|
th {
|
|
background-color: #f2f2f2 !important;
|
|
position: relative !important;
|
|
}
|
|
|
|
.three-dot-menu {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.dropdown-content {
|
|
display: none;
|
|
position: absolute;
|
|
background-color: #f9f9f9;
|
|
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.2);
|
|
z-index: 1;
|
|
}
|
|
|
|
.dropdown-content button {
|
|
display: block;
|
|
width: 100%;
|
|
padding: 8px;
|
|
text-align: left;
|
|
border: none;
|
|
background: none;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.dropdown-content button:hover {
|
|
background-color: #ddd;
|
|
}
|
|
|
|
/* Dropdown container */
|
|
.simple-dropdown {
|
|
position: absolute;
|
|
background: white;
|
|
border: 1px solid #ccc;
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
z-index: 1000;
|
|
}
|
|
|
|
/* Individual dropdown options */
|
|
.dropdown-option {
|
|
padding: 8px 16px;
|
|
cursor: pointer;
|
|
min-width: 80px;
|
|
user-select: none;
|
|
}
|
|
|
|
/* Hover effect for options */
|
|
.dropdown-option:hover {
|
|
background-color: #f0f0f0;
|
|
}
|
|
|
|
/* Optional: Add transition for smoother hover effect */
|
|
.dropdown-option {
|
|
transition: background-color 0.2s ease;
|
|
}
|
|
|
|
/* Optional: Style the TD when it's clickable */
|
|
td[onclick] {
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* Optional: Style for selected state */
|
|
.selected-option {
|
|
background-color: #f8f9fa;
|
|
}
|
|
|
|
.table-collapsible-bar {
|
|
background-color: #f1f1f1;
|
|
padding: 10px;
|
|
cursor: pointer;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px 4px 0 0;
|
|
font-weight: bold;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.table-collapsible-bar .collapse-icon {
|
|
transition: transform 0.3s ease;
|
|
}
|
|
|
|
.table-collapsible-bar.collapsed .collapse-icon {
|
|
transform: rotate(-90deg);
|
|
}
|
|
|
|
/*
|
|
.table-container {
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.table-content {
|
|
transition: max-height 0.3s ease-out;
|
|
overflow: hidden;
|
|
} */
|
|
|
|
.table-content.collapsed {
|
|
max-height: 0;
|
|
overflow: hidden;
|
|
}
|
|
</style>
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
|
|
<div class="row" style="margin-bottom:1rem;">
|
|
<div class="col-6" style="align-self: center;">
|
|
<h4 style="position: relative;" id="rfq_qcr_page_title"> <?= isset($page_name) ? $page_name : 'RFQ Non-EB' ?></h4>
|
|
</div>
|
|
</div>
|
|
<div class="row" style="margin-bottom:1rem;margin-left:1px">
|
|
<div class="col-md-2">
|
|
<button class="btn btn-primary" id="addProposal"> Add Proposal</button>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<button class="btn btn-primary" id="saveRFQ">Save RFQ</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="allTableContainer">
|
|
<div id="tablesContainer"></div>
|
|
<!-- <div id="excessContainer"></div> -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
var tableCount = 0;
|
|
const policies = [
|
|
|
|
{
|
|
name: "Fire",
|
|
description: "All Buildings and civil structures including Super Structure, plinth & foundation, other Civil Structures, Roads, gates, pavements,internal Pathways, stone works, stone arts etc., Street Lights, Landscaping, Play Area, Culvert, drainage, retaining walls, etc. Compound Wall including utility, admin block, security office and all other similar structures pertaining to insured within the premises, Kutcha Constructions, Temporary Sheds, parking Sheds, Shelters, Civil Structure / bed for DG set / Genset, Interlocking Pathways, LVP Pathway Widening, Roads including internal roads, Mini Conference, Swimming pool, rest areas, shelters, Kitchen-Exhaust System Work, Red Earth for Garden, Arch Wall , Retaining Wall, Boundry,compound walls, Water, Vetrified Tiles, Capital Additions related to Building. All other civil structures related to insured at the covered premises.",
|
|
quote_asked: "100"
|
|
},
|
|
{
|
|
name: "Burglary",
|
|
description: "Contents, AC & Accessories, FFF, P & M & Accessories, Electronic Equipments & Assessories, Electrical Items & Fittings, Plumbing Items, Structural Products, Structures, Leasehold Work including Civil Works, Interiors Temporary Structures including Sheds and Containers, Interiors, Plate Glass, Workstations, Office Equipments, Consumables, Goods held in commission / Trust, Trading Goods, Other contents / Items related to Insured's trade, Other Contets related to Insured's Trdae",
|
|
quote_asked: "1000"
|
|
},
|
|
{
|
|
name: "All Risk",
|
|
description: "Laptops, Notebooks Computers, Tablets, Mobile Phones & Cameras, projectors, and other portable equipments.",
|
|
quote_asked: "900"
|
|
},
|
|
{
|
|
name: "MBD",
|
|
description: "Plant & Machinieries including and not limited to DG Set, Lifts, Refrigerator, Cooler, Air Condiitoner, Pump, Water Dispenser, Freezer, Oven, Motor, Transformer, etc. and other P&M related to Insured ",
|
|
quote_asked: "100"
|
|
},
|
|
{
|
|
name: "EEI",
|
|
description: "Various electronic Items including and not limited to Computer, Printer, CCTV, Telephone Instruments, Control System, Router, Switches, BMS System, DVD Player, Music Systems, Scanner, Photo Copier and Electronic Lock System, and other electronic items.",
|
|
quote_asked: "0"
|
|
},
|
|
{
|
|
name: "Fidelity",
|
|
description: "Dishonesty of Employees",
|
|
quote_asked: "8800"
|
|
},
|
|
{
|
|
name: "Money",
|
|
description: "Money in transit",
|
|
quote_asked: "200"
|
|
},
|
|
{
|
|
name: "Plate Glass",
|
|
description: "Glass items, including frames and fititngs ",
|
|
quote_asked: "10055"
|
|
},
|
|
{
|
|
name: "Neon Sign",
|
|
description: "Neon Tubes, Frame, Electrical Components, Glass Panels, Lettering and Graphics",
|
|
quote_asked: "102220"
|
|
},
|
|
{
|
|
name: "Public Liability",
|
|
description: "As per Public Liability including extensions such as Lift Liability & Food & Beverage: AOA : AOY - 1:4",
|
|
quote_asked: "1000000"
|
|
},
|
|
|
|
];
|
|
|
|
const child_table_data = {
|
|
|
|
"fire": [{
|
|
table_type: "new",
|
|
table_id: "fire_addOnCoverage",
|
|
table_editable: true,
|
|
table_name: "Fire Inbuilt Coverage",
|
|
table_row_contents: [{
|
|
"fire_designated_property_clause": {
|
|
"display_value": "Designated Property Clause",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"fire_bank_clause": {
|
|
"display_value": "Agreed Bank Clause",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"fire_reinstatement_value": {
|
|
"display_value": "Reinstatement Value Clause",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
|
|
{
|
|
table_type: "new",
|
|
table_id: "fire_coverage",
|
|
table_editable: true,
|
|
table_name: "Fire Additional Coverage",
|
|
table_row_contents: [{
|
|
"fire_allied_perls": {
|
|
"display_value": "Fire and Allied Perils, Including STFI ",
|
|
"answer_type": 'free-text'
|
|
},
|
|
},
|
|
{
|
|
"fire_removal_debres": {
|
|
"display_value": "Costs for Removal of debris upto 2 % of the claim amount ",
|
|
"answer_type": 'free-text'
|
|
},
|
|
},
|
|
{
|
|
"fire_alteration_extension ": {
|
|
"display_value": "Additions, alterations or extensions upto 15% of the Sum Insured for that item (excluding stocks)",
|
|
"answer_type": 'free-text'
|
|
},
|
|
},
|
|
{
|
|
"fire_temp_removal_stocks": {
|
|
"display_value": "Temporary removal of stocks upto 10% of value",
|
|
"answer_type": 'free-text'
|
|
},
|
|
},
|
|
{
|
|
"fire_start_up_expense": {
|
|
"display_value": "Start-Up Expenses upto 5 Lakhs",
|
|
"answer_type": 'free-text'
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
table_type: "append",
|
|
table_name: "Excess",
|
|
table_id: "excess",
|
|
table_editable: true,
|
|
table_row_contents: [{
|
|
'policy_fire_excess': {
|
|
"display_value": "Policy Fire",
|
|
"answer_type": 'free-text'
|
|
}
|
|
}]
|
|
}
|
|
],
|
|
"burglary": [{
|
|
table_type: "new",
|
|
table_name: "Burglary Additional Coverage",
|
|
table_id: "burglary_addOnCoverage",
|
|
table_editable: true,
|
|
table_row_contents: [{
|
|
"burglary_loss_limit": {
|
|
"display_value": "First Loss Limit ",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
},
|
|
},
|
|
{
|
|
"burglary_theft_rmsd": {
|
|
"display_value": "Theft & RSMD",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
],
|
|
},
|
|
},
|
|
{
|
|
"burglary_waiver_FIR": {
|
|
"display_value": " Waiver of FIR, NTC and Final Investigation reports",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
},
|
|
}
|
|
]
|
|
},
|
|
|
|
{
|
|
table_type: "append",
|
|
table_name: "Excess",
|
|
table_editable: true,
|
|
table_id: "excess",
|
|
table_row_contents: [{
|
|
"burglary_excess": {
|
|
"display_value": "Policy Burglary",
|
|
"answer_type": 'free-text'
|
|
}
|
|
}]
|
|
}
|
|
],
|
|
|
|
"all_risk": [{
|
|
table_type: "new",
|
|
table_name: "All Risk Additional Coverage",
|
|
table_id: "all_risk_addOnCoverage",
|
|
table_editable: true,
|
|
table_row_contents: [{
|
|
"all_risk_rsmd": {
|
|
"display_value": "RSMD",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"all_risk_terrorism": {
|
|
"display_value": "Terrorism",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"all_risk_reistatement": {
|
|
"display_value": "Reinstatement value clause",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
table_type: "append",
|
|
table_name: "Excess",
|
|
table_id: "excess",
|
|
table_editable: true,
|
|
table_row_contents: [{
|
|
"money_excess": {
|
|
"display_value": "Policy All Risk ",
|
|
"answer_type": 'free-text'
|
|
}
|
|
}]
|
|
}
|
|
],
|
|
"mbd": [{
|
|
table_type: "new",
|
|
table_name: "MBD Additional Coverage",
|
|
table_id: "mbd_addOnCoverage",
|
|
table_editable: true,
|
|
table_row_contents: [{
|
|
"mbd_accidental_breakdown": {
|
|
"display_value": "Accidental / Mechanical breakdown",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"mbd_terrorism_express_freight": {
|
|
"display_value": "Express Freight",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"mbd_reistatement_air_freight": {
|
|
"display_value": "Air Freight",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}],
|
|
|
|
"eei": [{
|
|
table_type: "new",
|
|
table_name: "EEI Additional Coverage",
|
|
table_id: "eei_addOnCoverage",
|
|
table_editable: true,
|
|
table_row_contents: [{
|
|
"eei_electronic_equipment": {
|
|
"display_value": "As per Electronic Equipment Policy including STFI, EQ, Terrorism",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"eei_accidental_breakdown": {
|
|
"display_value": "Accidental / Electrical Breakdown",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"eei_electrical_damage": {
|
|
"display_value": "Damage to electronic equipment incl. systems software, cost of external data media, cost of reconstruction of data",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}],
|
|
"fidelity": [{
|
|
table_type: "new",
|
|
table_name: "Fidelity Additional Coverage",
|
|
table_id: "fidelity_addOnCoverage",
|
|
table_editable: true,
|
|
table_row_contents: [{
|
|
"fidelity_any1_person": {
|
|
"display_value": "Any One Person",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"fidelity_contract_employee": {
|
|
"display_value": " Including contract Employees",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"fidelity_unnamed_bias": {
|
|
"display_value": "Un-named Basis",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
}],
|
|
"money": [{
|
|
table_type: "new",
|
|
table_name: "Money Additional Coverage",
|
|
table_id: "money_addOnCoverage",
|
|
table_editable: true,
|
|
table_row_contents: [{
|
|
"money_rsmd": {
|
|
"display_value": "RSMD",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"money_terrorism": {
|
|
"display_value": "Terrorism",
|
|
"answer_type": 'free-text'
|
|
}
|
|
},
|
|
{
|
|
"money_by_vehicle": {
|
|
"display_value": " Cash by Public Transport/Vehicle",
|
|
"answer_type": 'free-text'
|
|
}
|
|
},
|
|
{
|
|
"money_by_two_wheeler": {
|
|
"display_value": "Cash by Two Wheeler",
|
|
"answer_type": 'free-text'
|
|
}
|
|
},
|
|
|
|
]
|
|
},
|
|
{
|
|
table_type: "append",
|
|
table_name: "Excess",
|
|
table_id: "excess",
|
|
table_editable: true,
|
|
table_row_contents: [{
|
|
"money_excess": {
|
|
"display_value": "Policy Money ",
|
|
"answer_type": 'free-text'
|
|
}
|
|
}]
|
|
}
|
|
],
|
|
"plate_glass": [{
|
|
table_type: "new",
|
|
table_name: "Plate Glass Coverage",
|
|
table_id: "plate_glass_addOnCoverage",
|
|
table_editable: true,
|
|
table_row_contents: [{
|
|
"plate_glass_accidental_damage": {
|
|
"display_value": "Accidental Damage",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"plate_glass_rsmd": {
|
|
"display_value": "RSMD",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"plate_glass_waiver_of_survey": {
|
|
"display_value": "Waiver of Survey upto INR 2 Lacs",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
]
|
|
},
|
|
|
|
{
|
|
table_type: "append",
|
|
table_name: "Excess",
|
|
table_id: "excess",
|
|
table_editable: true,
|
|
table_row_contents: [{
|
|
"plate_glass_excess": {
|
|
"display_value": "Policy Plate Glass ",
|
|
"answer_type": 'free-text'
|
|
}
|
|
}]
|
|
}
|
|
],
|
|
"neon_sign": [{
|
|
table_type: "new",
|
|
table_name: "Neon Sign Coverage",
|
|
table_id: "neon_sign_addOnCoverage",
|
|
table_editable: true,
|
|
table_row_contents: [{
|
|
"neon_sign_accidental": {
|
|
"display_value": "Accidental/Physical/Electronic Damage",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"neon_sign_rsmd": {
|
|
"display_value": "RSMD",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"neon_sign_waiver": {
|
|
"display_value": "Waiver of Survey upto INR 2 Lacs",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
]
|
|
},
|
|
|
|
{
|
|
table_type: "append",
|
|
table_name: "Excess",
|
|
table_id: "excess",
|
|
table_editable: true,
|
|
table_row_contents: [{
|
|
"neon_sign_excess": {
|
|
"display_value": "Policy Neon",
|
|
"answer_type": 'free-text'
|
|
}
|
|
}]
|
|
}
|
|
],
|
|
"public_liability": [{
|
|
table_type: "new",
|
|
table_name: "Public Liability Coverage",
|
|
table_id: "public_liability_addOnCoverage",
|
|
table_editable: true,
|
|
table_row_contents: [{
|
|
"public_liability_aog": {
|
|
"display_value": "AOG Perils Extention",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"public_liability_3rdparty": {
|
|
"display_value": "Third Party Includes visitors",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"public_liability_owners": {
|
|
"display_value": "Owners / Tenants occupying the premises",
|
|
"answer_type": 'dropdown',
|
|
"default_answer": [{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}],
|
|
"answers": [{
|
|
"key": "1",
|
|
"display_value": "Agreed"
|
|
},
|
|
{
|
|
"key": "0",
|
|
"display_value": "Not Agreed"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
|
|
|
|
]
|
|
}],
|
|
|
|
};
|
|
|
|
const policyOrder = [{
|
|
'fire': {
|
|
"priority": 1
|
|
}
|
|
},
|
|
{
|
|
'burglary': {
|
|
"priority": 2
|
|
}
|
|
},
|
|
{
|
|
'all_risk': {
|
|
"priority": 3
|
|
}
|
|
},
|
|
{
|
|
'mbd': {
|
|
"priority": 4
|
|
}
|
|
},
|
|
{
|
|
'eei': {
|
|
"priority": 5
|
|
}
|
|
},
|
|
{
|
|
'fidelity': {
|
|
"priority": 6
|
|
}
|
|
},
|
|
{
|
|
'money': {
|
|
"priority": 7
|
|
}
|
|
},
|
|
{
|
|
'plate_glass': {
|
|
"priority": 8
|
|
},
|
|
},
|
|
{
|
|
'neon_sign': {
|
|
"priority": 9
|
|
}
|
|
},
|
|
{
|
|
'public_liability': {
|
|
"priority": 10
|
|
}
|
|
}
|
|
];
|
|
|
|
let selectedPolicies = new Set();
|
|
|
|
let proposalCount = 1;
|
|
let quotesConfig = {
|
|
1: ['Quote asked']
|
|
}; // Stores quote columns for each proposal
|
|
|
|
// Generate a random quote code (e.g., abc123)
|
|
function generateRandomCode() {
|
|
const chars = 'abcdefghijklmnopqrstuvwxyz';
|
|
const nums = '0123456789';
|
|
return Array.from({
|
|
length: 3
|
|
}, () => chars[Math.floor(Math.random() * 26)]).join('') +
|
|
Array.from({
|
|
length: 3
|
|
}, () => nums[Math.floor(Math.random() * 10)]).join('');
|
|
}
|
|
|
|
// Add a new quote column to a specific proposal
|
|
function addNewQuote(proposalNumber) {
|
|
let increaseBy = 50;
|
|
increaseTableWidth(increaseBy)
|
|
console.log('ADD NEW QUOTE proposalNumber' + proposalNumber);
|
|
console.log('ADD NEW QUOTE overall quotesConfig');
|
|
console.log(quotesConfig);
|
|
if (!quotesConfig[proposalNumber]) {
|
|
quotesConfig[proposalNumber] = ['Quote asked']; // Initialize with default quote
|
|
}
|
|
const newQuote = generateRandomCode();
|
|
quotesConfig[proposalNumber].push(newQuote); // Add new quote to the proposal
|
|
|
|
// Update all tables (parent and child) with the new quote column
|
|
updateAllTables(proposalNumber, newQuote);
|
|
// hideProposalOptionsForChild();
|
|
|
|
}
|
|
|
|
// Update all tables with the new quote column
|
|
function updateAllTables_old(proposalNumber, newQuote) {
|
|
const tables = document.querySelectorAll('table');
|
|
tables.forEach(table => {
|
|
const headerRow1 = table.querySelector('thead tr:first-child');
|
|
const headerRow2 = table.querySelector('thead tr:last-child');
|
|
|
|
// Update proposal header colspan
|
|
const proposalHeader = headerRow1.querySelector(`th[data-proposal="${proposalNumber}"]`);
|
|
if (proposalHeader) {
|
|
proposalHeader.colSpan = quotesConfig[proposalNumber].length;
|
|
}
|
|
|
|
// Calculate the position to insert the new quote column
|
|
let insertPosition = 2; // Start after Particulars column
|
|
for (let i = 1; i < proposalNumber; i++) {
|
|
insertPosition += quotesConfig[i]?.length || 0;
|
|
}
|
|
insertPosition += quotesConfig[proposalNumber].length - 1;
|
|
let table_id = table.id ? table.id : 'parent';
|
|
console.log('insert position of ' + table.id + ' - ' + insertPosition);
|
|
// Add new quote sub-header
|
|
const newQuoteHeader = document.createElement('th');
|
|
newQuoteHeader.textContent = newQuote;
|
|
headerRow2.insertBefore(newQuoteHeader, headerRow2.children[insertPosition]);
|
|
|
|
// Add new editable cells to all rows
|
|
table.querySelectorAll('tbody tr').forEach(row => {
|
|
const newCell = document.createElement('td');
|
|
newCell.contentEditable = true; // Make cell editable
|
|
row.insertBefore(newCell, row.children[insertPosition]);
|
|
});
|
|
});
|
|
}
|
|
|
|
// Generate the table (parent or child)
|
|
|
|
// Show dropdown menu
|
|
function showDropdown(event) {
|
|
const dropdown = event.target.nextElementSibling;
|
|
dropdown.style.display = dropdown.style.display === 'block' ? 'none' : 'block';
|
|
event.stopPropagation();
|
|
}
|
|
|
|
// Remove a proposal column
|
|
function removeProposal(proposalNumber) {
|
|
|
|
console.log('removeProposal');
|
|
console.log(quotesConfig);
|
|
if (!quotesConfig[proposalNumber]) return; // If proposal doesn't exist, exit
|
|
|
|
// Remove all child columns for the proposal
|
|
const tables = document.querySelectorAll('table');
|
|
tables.forEach(table => {
|
|
const headerRow1 = table.querySelector('thead tr:first-child');
|
|
const headerRow2 = table.querySelector('thead tr:last-child');
|
|
|
|
// Find the proposal header and calculate its colspan
|
|
const proposalHeader = headerRow1.querySelector(`th[data-proposal="${proposalNumber}"]`);
|
|
if (proposalHeader) {
|
|
const colspan = parseInt(proposalHeader.getAttribute('colspan'), 10);
|
|
|
|
// Remove the proposal header
|
|
proposalHeader.remove();
|
|
|
|
// Remove corresponding sub-headers in the second header row
|
|
const subHeaders = headerRow2.querySelectorAll(`th`);
|
|
let startIndex = 2; // Start after the first two columns (checkbox and Particulars)
|
|
for (let i = 1; i < proposalNumber; i++) {
|
|
startIndex += quotesConfig[i]?.length || 1;
|
|
}
|
|
for (let i = 0; i < colspan; i++) {
|
|
headerRow2.removeChild(headerRow2.children[startIndex]);
|
|
}
|
|
|
|
// Remove corresponding cells in all rows
|
|
table.querySelectorAll('tbody tr').forEach(row => {
|
|
for (let i = 0; i < colspan; i++) {
|
|
row.removeChild(row.children[startIndex]);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
// Remove the proposal from quotesConfig
|
|
delete quotesConfig[proposalNumber];
|
|
}
|
|
|
|
// Add a new row
|
|
function addRow(event) {
|
|
console.log(' event ', event);
|
|
const button = event.target;
|
|
const row = button.closest('tr');
|
|
const table = row.closest('table');
|
|
const newRow = row.cloneNode(true);
|
|
// console.log("New Row ",newRow);return false;
|
|
var tableID = table.id;
|
|
|
|
let nextSNO = getSNO(tableID);
|
|
// Clear input values and generate new IDs
|
|
newRow.querySelectorAll('td').forEach((td, index) => {
|
|
if (index === 0) {
|
|
td.innerHTML = `${nextSNO}`;
|
|
}
|
|
if (index !== 0 && index !== row.cells.length - 1) td.textContent = '-';
|
|
});
|
|
|
|
table.querySelector('tbody').appendChild(newRow);
|
|
updateSNO(table.id);
|
|
}
|
|
|
|
// Remove a row
|
|
function removeRow(event) {
|
|
const button = event.target;
|
|
const row = button.closest('tr');
|
|
const table = row.closest('table');
|
|
if (row && row.parentElement.children.length > 1) {
|
|
row.remove();
|
|
updateSNO(table.id);
|
|
}
|
|
}
|
|
|
|
//function to hide all the 3 dot actions for the child table
|
|
function hideProposalOptionsForChild() {
|
|
// console.log('function called');
|
|
const parentTable = document.querySelector("table");
|
|
const tables = document.querySelectorAll('table');
|
|
|
|
// console.log('parentTable : ',parentTable);
|
|
tables.forEach(table => {
|
|
if (table !== parentTable) {
|
|
// Hide .three-dot-menu in all other tables
|
|
$(table).find(".three-dot-menu").hide();
|
|
// console.log("hided 3 dot menu in the table",table);
|
|
}
|
|
});
|
|
}
|
|
// Add a new proposal
|
|
document.getElementById('addProposal').addEventListener('click', () => {
|
|
proposalCount++;
|
|
quotesConfig[proposalCount] = ['Quote asked']; // Initialize with default quote
|
|
const tables = document.querySelectorAll('table');
|
|
let increaseBy = 150;
|
|
increaseTableWidth(increaseBy);
|
|
|
|
// console.log('parentTable : ',parentTable);
|
|
tables.forEach(table => {
|
|
const headerRow1 = table.querySelector('thead tr:first-child');
|
|
const headerRow2 = table.querySelector('thead tr:last-child');
|
|
|
|
// Add new proposal header
|
|
const newProposalHeader = document.createElement('th');
|
|
newProposalHeader.setAttribute('data-proposal', proposalCount);
|
|
newProposalHeader.colSpan = 1;
|
|
newProposalHeader.innerHTML = `
|
|
Proposal ${proposalCount}
|
|
<span class="three-dot-menu" onclick="showDropdown(event)">⋮</span>
|
|
<div class="dropdown-content">
|
|
<button onclick = "addOrRemoveIcon(this,event)"class="qcrProposal" style="background-color: rgb(221, 221, 221);">QCR <i
|
|
class="fa fa-check-square"
|
|
style="color: green; margin-left: 8px;"></i></button>
|
|
<button class="sendClientProposal" onclick = "addOrRemoveIcon(this,event)"
|
|
style="background-color: rgb(221, 221, 221);">Send to Client <i
|
|
class="fa fa-check-square"
|
|
style="color: green; margin-left: 8px;"></i></button>
|
|
<button onclick="removeProposal(${proposalCount})">Remove Proposal</button>
|
|
<button onclick="addNewQuote(${proposalCount})">Add New Quote</button>
|
|
</div>
|
|
`;
|
|
headerRow1.insertBefore(newProposalHeader, headerRow1.lastElementChild);
|
|
|
|
// Add new quote sub-header
|
|
const newQuoteHeader = document.createElement('th');
|
|
newQuoteHeader.textContent = 'Quote asked';
|
|
headerRow2.insertBefore(newQuoteHeader, headerRow2.querySelector('th:last-child'));
|
|
|
|
// Add new cells to all rows
|
|
table.querySelectorAll('tbody tr').forEach(row => {
|
|
// console.log(row);
|
|
|
|
// const newCell = document.createElement('td');
|
|
const lastCell = row.querySelector('td:nth-child(3)');
|
|
const newCell = lastCell.cloneNode(true);
|
|
newCell.contentEditable = true;
|
|
newCell.onclick = () => getAnswer(table.id, row.id);
|
|
row.insertBefore(newCell, row.querySelector('td:last-child'));
|
|
});
|
|
// console.log('table ',table);
|
|
|
|
});
|
|
hideProposalOptionsForChild();
|
|
});
|
|
|
|
// #################################################################################
|
|
|
|
function addNewQuote(proposalNumber) {
|
|
if (!quotesConfig[proposalNumber]) return;
|
|
const newQuote = generateRandomCode();
|
|
quotesConfig[proposalNumber].push(newQuote);
|
|
updateAllTables(proposalNumber, newQuote);
|
|
hideProposalOptionsForChild();
|
|
}
|
|
|
|
function removeQuote(event, proposalNumber, quoteCode) {
|
|
event.stopPropagation();
|
|
if (!quotesConfig[proposalNumber]) return;
|
|
|
|
// Remove quote from config
|
|
const quoteIndex = quotesConfig[proposalNumber].indexOf(quoteCode);
|
|
if (quoteIndex !== -1) {
|
|
quotesConfig[proposalNumber].splice(quoteIndex, 1);
|
|
if (quotesConfig[proposalNumber].length === 0) {
|
|
delete quotesConfig[proposalNumber];
|
|
}
|
|
}
|
|
|
|
// Remove from all tables
|
|
document.querySelectorAll('table').forEach(table => {
|
|
const headerRow1 = table.querySelector('thead tr:first-child');
|
|
const headerRow2 = table.querySelector('thead tr:last-child');
|
|
|
|
// Find and remove quote header
|
|
const targetIndex = Array.from(headerRow2.children).findIndex(th =>
|
|
th.textContent.includes(quoteCode) &&
|
|
th.getAttribute('data-proposal') === proposalNumber.toString()
|
|
);
|
|
|
|
if (targetIndex !== -1) {
|
|
// Remove from header row 2
|
|
headerRow2.removeChild(headerRow2.children[targetIndex]);
|
|
|
|
// Update proposal header colspan
|
|
const proposalHeader = headerRow1.querySelector(`th[data-proposal="${proposalNumber}"]`);
|
|
if (proposalHeader) {
|
|
const newColspan = parseInt(proposalHeader.colSpan) - 1;
|
|
if (newColspan > 0) {
|
|
proposalHeader.colSpan = newColspan;
|
|
} else {
|
|
proposalHeader.remove();
|
|
}
|
|
}
|
|
|
|
// Remove from data rows
|
|
table.querySelectorAll('tbody tr').forEach(row => {
|
|
const cellIndex = targetIndex; // No need to add 2 since we're using children array
|
|
if (row.children[cellIndex]) {
|
|
row.removeChild(row.children[cellIndex]);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
function updateAllTables(proposalNumber, newQuote) {
|
|
document.querySelectorAll('table').forEach(table => {
|
|
const headerRow1 = table.querySelector('thead tr:first-child');
|
|
const headerRow2 = table.querySelector('thead tr:last-child');
|
|
const proposalHeader = headerRow1.querySelector(`th[data-proposal="${proposalNumber}"]`);
|
|
|
|
// Create new quote header
|
|
const newQuoteHeader = document.createElement('th');
|
|
newQuoteHeader.textContent = newQuote;
|
|
newQuoteHeader.innerHTML = `
|
|
${newQuote}
|
|
<span class="three-dot-menu" onclick="showDropdown(event)">⋮</span>
|
|
<div class="dropdown-content">
|
|
<button onclick="removeQuote(event, ${proposalNumber}, '${newQuote}')">Remove Quote</button>
|
|
</div>
|
|
`;
|
|
newQuoteHeader.dataset.proposal = proposalNumber;
|
|
newQuoteHeader.dataset.quote = newQuote;
|
|
|
|
// Find insert position
|
|
let insertPosition = 2;
|
|
for (let i = 1; i < proposalNumber; i++) {
|
|
insertPosition += quotesConfig[i]?.length || 0;
|
|
}
|
|
insertPosition += quotesConfig[proposalNumber].length - 1;
|
|
|
|
// Update headers
|
|
headerRow2.insertBefore(newQuoteHeader, headerRow2.children[insertPosition]);
|
|
if (proposalHeader) proposalHeader.colSpan = quotesConfig[proposalNumber].length;
|
|
// console.log("insert position insertPosition",insertPosition);
|
|
// Add new cells
|
|
table.querySelectorAll('tbody tr').forEach(row => {
|
|
const lastCell = row.querySelector(`td:nth-child(${insertPosition})`);
|
|
const newCell = lastCell.cloneNode(true);
|
|
newCell.contentEditable = true;
|
|
newCell.onclick = () => getAnswer(table.id, row.id);
|
|
row.insertBefore(newCell, row.children[insertPosition]);
|
|
});
|
|
});
|
|
}
|
|
|
|
function generateTable(container, isChildTable = false, parentRowId = null, tableData = null) {
|
|
const tableContainer = document.createElement('div');
|
|
tableContainer.className = 'table-container';
|
|
|
|
// Create collapsible bar
|
|
const collapsibleBar = document.createElement('div');
|
|
// collapsibleBar.className = 'table-collapsible-bar';
|
|
collapsibleBar.innerHTML = `
|
|
${tableData ? tableData.table_name : "Particulars"}
|
|
<span class="collapse-icon">▼</span>
|
|
`;
|
|
|
|
// Create table content wrapper
|
|
const tableContent = document.createElement('div');
|
|
tableContent.className = 'table-content';
|
|
|
|
// Create actual table
|
|
const table = document.createElement('table');
|
|
if (tableData) table.id = tableData.table_id;
|
|
// table_name = tableData.table_name
|
|
|
|
tableName = tableData ? tableData.table_name : "Particulars";
|
|
collapsibleBar.className = `table-collapsible-bar ${tableName}`;
|
|
|
|
// console.log("table Name ",tableName);
|
|
// Header setup
|
|
const thead = document.createElement('thead');
|
|
const headerRow1 = document.createElement('tr');
|
|
headerRow1.innerHTML =
|
|
`
|
|
${isChildTable ? '<th>S.NO</th>' : '<th><input type="checkbox"></th>'}
|
|
<th> ${tableName}</th>
|
|
${Object.keys(quotesConfig).map(proposal => `
|
|
<th data-proposal="${proposal}" colspan="${quotesConfig[proposal].length}">
|
|
Proposal ${proposal}
|
|
<span class="three-dot-menu" onclick="showDropdown(event)">⋮</span>
|
|
<div class="dropdown-content">
|
|
<button onclick = "addOrRemoveIcon(this,event)"class="qcrProposal" style="background-color: rgb(221, 221, 221);">QCR <i
|
|
class="fa fa-check-square"
|
|
style="color: green; margin-left: 8px;"></i></button>
|
|
<button class="sendClientProposal" onclick = "addOrRemoveIcon(this,event)"
|
|
style="background-color: rgb(221, 221, 221);">Send to Client <i
|
|
class="fa fa-check-square"
|
|
style="color: green; margin-left: 8px;"></i></button>
|
|
<button onclick="removeProposal(${proposal})">Remove Proposal</button>
|
|
<button onclick="addNewQuote(${proposal})">Add New Quote</button>
|
|
</div>
|
|
</th>
|
|
`).join('')}
|
|
<th>Action</th>`;
|
|
|
|
const headerRow2 = document.createElement('tr');
|
|
headerRow2.innerHTML = `
|
|
<th>-</th>
|
|
<th>-</th>
|
|
${Object.entries(quotesConfig).flatMap(([proposal, codes]) =>
|
|
codes.map(code => `
|
|
<th data-proposal="${proposal}" data-quote="${code}">
|
|
${code}
|
|
<span class="three-dot-menu" onclick="showDropdown(event)">⋮</span>
|
|
<div class="dropdown-content">
|
|
<button onclick="removeQuote(event, ${proposal}, '${code}')">Remove Quote</button>
|
|
</div>
|
|
</th>
|
|
`)
|
|
).join('')}
|
|
<th>-</th>`;
|
|
|
|
thead.append(headerRow1, headerRow2);
|
|
table.appendChild(thead);
|
|
let latestWidth = $("table").last().width();
|
|
// console.log('Latest width', latestWidth);
|
|
if (tableData) {
|
|
// console.log("table ",$(table));
|
|
$(table).width(latestWidth); // Convert to jQuery object using $(table)
|
|
// console.log('table data',tableData);
|
|
}
|
|
$(collapsibleBar).width(latestWidth);
|
|
// Body setup
|
|
const tbody = document.createElement('tbody');
|
|
const rowsData = tableData ? tableData.table_row_contents : policies;
|
|
rowsData.forEach((policy, index) => {
|
|
var row_fields = rowsData[index];
|
|
let rowID = Object.keys(row_fields)[0];
|
|
// console.log('row id ? ', rowID);
|
|
const row = document.createElement('tr');
|
|
row.id = isChildTable ? `${parentRowId}_child_${index}` : policy.name.replace(/\s+/g, '_').toLowerCase();
|
|
row.id = isChildTable ? `${rowID}` : policy.name.replace(/\s+/g, '_').toLowerCase();
|
|
|
|
// Set data attribute for excess table rows
|
|
if (tableData && tableData.table_id === 'excess') {
|
|
row.setAttribute('data-excess-row-parent', parentRowId);
|
|
// $('.three-dot-menu').hide();
|
|
}
|
|
var policy_question = row_fields[rowID].display_value;
|
|
var answer_type = row_fields[rowID].answer_type;
|
|
var tableID = tableData?.table_id ?? null;
|
|
// console.log('table id ', tableID);
|
|
var SNO = getSNO(tableID);
|
|
if (tableData) {
|
|
|
|
if (answer_type == 'dropdown') {
|
|
default_answers_array = row_fields[rowID].default_answer;
|
|
// createDropdown(default_answers_array);
|
|
default_value = default_answers_array[0].key;
|
|
default_answer = default_answers_array[0].display_value;
|
|
|
|
} else {
|
|
default_value = "-"
|
|
}
|
|
// console.log("Default Answer ", default_value);
|
|
}
|
|
row.innerHTML = `
|
|
${isChildTable
|
|
? `<td>${SNO}</td>`
|
|
: `<td><input type="checkbox" class="sno-checkbox"> ${policy.name}</td>`
|
|
}
|
|
|
|
|
|
<td contenteditable="true">${tableData ? policy_question : policy.description}</td>
|
|
${Object.values(quotesConfig).flatMap(codes =>
|
|
codes.map(() => `<td onblur="setValueForHiddenField(this,'${answer_type}')" onclick = "getAnswer('${tableID}','${rowID}')" contenteditable="true">${tableData ? (default_value === '-' ? `${default_value} <input type="hidden" value='${default_value}' />` : `${default_answer} <input type="hidden" value='${JSON.stringify(default_answers_array[0])}' />`)
|
|
: policy.quote_asked}</td>`)
|
|
).join('')}
|
|
<td>
|
|
${isChildTable ? `
|
|
<input checked type="checkbox" class="qcr-checkbox">QCR
|
|
<input checked type="checkbox" class="client-checkbox">Client
|
|
<button class="btn btn-danger btn-sm" onclick="removeRow(event)">-</button>
|
|
<button class="btn btn-primary btn-sm" onclick="addRow(event)">+</button>
|
|
` : ''}
|
|
</td>`;
|
|
tbody.appendChild(row);
|
|
});
|
|
table.appendChild(tbody);
|
|
container.appendChild(table);
|
|
collapsibleBar.addEventListener('click', function() {
|
|
this.classList.toggle('collapsed');
|
|
tableContent.classList.toggle('collapsed');
|
|
});
|
|
|
|
// Assemble components
|
|
tableContent.appendChild(table);
|
|
tableContainer.appendChild(collapsibleBar);
|
|
tableContainer.appendChild(tableContent);
|
|
container.appendChild(tableContainer);
|
|
// Checkbox functionality
|
|
if (!isChildTable) {
|
|
table.querySelectorAll('.sno-checkbox').forEach(checkbox => {
|
|
checkbox.addEventListener('change', function() {
|
|
const rowId = this.closest('tr').id;
|
|
if (this.checked) {
|
|
const childContainer = document.createElement('div');
|
|
selectedPolicies.add(rowId);
|
|
child_table_data[rowId]?.forEach(childTable => {
|
|
if (childTable.table_type == "append") {
|
|
var tableName = childTable.table_id;
|
|
// Handle excess table
|
|
const excessContainer = document.createElement('div');
|
|
excessContainer.setAttribute('data-parent-row', tableName);
|
|
excessContainer.setAttribute(`data-${tableName}-container`, 'true');
|
|
|
|
var result = generateExcessTable(childTable, rowId, tableName);
|
|
if (result) {
|
|
generateTable(excessContainer, true, rowId, childTable);
|
|
container.appendChild(excessContainer);
|
|
// console.log('Row id for excess table',rowId);
|
|
$("#excess .three-dot-menu").hide();
|
|
moveExcessTableLast();
|
|
}
|
|
} else {
|
|
// Handle regular table
|
|
childContainer.setAttribute('data-parent-row', rowId);
|
|
generateTable(childContainer, true, rowId, childTable);
|
|
// console.log('Row id for excess table', rowId);
|
|
$(childContainer).find(".three-dot-menu").hide();
|
|
moveExcessTableLast();
|
|
}
|
|
});
|
|
|
|
// Only append regular container if it has content
|
|
if (childContainer.hasChildNodes()) {
|
|
container.appendChild(childContainer);
|
|
}
|
|
|
|
arrangeTables();
|
|
} else {
|
|
console.log('UNCHECKED:', rowId);
|
|
selectedPolicies.delete(rowId);
|
|
// Remove regular child tables
|
|
const regularContainers = container.querySelectorAll(`div[data-parent-row="${rowId}"]:not([data-excess-container])`);
|
|
regularContainers.forEach(container => {
|
|
console.log(" contaitner ", container);
|
|
|
|
container.remove();
|
|
});
|
|
console.log("row id ", rowId);
|
|
// Handle excess table rows
|
|
const excessTable = document.getElementById('excess');
|
|
if (excessTable) {
|
|
// Remove rows associated with this checkbox
|
|
const excessRows = excessTable.querySelectorAll(`tbody tr[data-excess-row-parent="${rowId}"]`);
|
|
excessRows.forEach(row => row.remove());
|
|
|
|
// Check if excess table is empty
|
|
const remainingRows = excessTable.querySelector('tbody').children;
|
|
// console.log(remainingRows);
|
|
if (remainingRows.length === 0) {
|
|
// Remove the entire excess table container
|
|
// const excessContainer = excessTable.closest('div[data-excess-container]');
|
|
const excessCollapseBar = document.querySelector('.table-collapsible-bar.Excess');
|
|
const excessContainer = $('#excess');
|
|
if (excessContainer) {
|
|
excessContainer.remove();
|
|
excessCollapseBar.remove();
|
|
}
|
|
} else {
|
|
updateSNO('excess')
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
function generateExcessTable(tableData, parentRowId, tableName) {
|
|
var excessTable = document.getElementById(tableName);
|
|
|
|
if (excessTable) {
|
|
// If table exists, append new rows to it
|
|
const tbody = excessTable.querySelector('tbody');
|
|
// console.log("table data ",tableData);
|
|
// Add new rows from tableData
|
|
tableData.table_row_contents.forEach((rowData, index) => {
|
|
let rowID = Object.keys(rowData)[0];
|
|
var question = rowData[rowID].display_value;
|
|
|
|
const row = document.createElement('tr');
|
|
// Add data attribute to track which parent checkbox created this row
|
|
row.setAttribute('data-excess-row-parent', parentRowId);
|
|
let SNO = getSNO(tableName);
|
|
row.innerHTML = `
|
|
<td>${SNO}</td>
|
|
<td contenteditable="true">${question}</td>
|
|
${Object.values(quotesConfig).flatMap(codes =>
|
|
codes.map(() => `<td contenteditable="true">-</td>`)
|
|
).join('')}
|
|
<td>
|
|
<input checked type="checkbox" class="qcr-checkbox">QCR
|
|
<input checked type="checkbox" class="client-checkbox">Client
|
|
<button class="btn btn-danger btn-sm" onclick="removeRow(event)">-</button>
|
|
<button class="btn btn-primary btn-sm" onclick="addRow(event)">+</button>
|
|
</td>`;
|
|
tbody.appendChild(row);
|
|
});
|
|
moveExcessTableLast();
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
// Initialize the parent table
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
generateTable(document.getElementById('tablesContainer'));
|
|
});
|
|
|
|
// Close dropdown when clicking outside
|
|
window.addEventListener('click', () => {
|
|
document.querySelectorAll('.dropdown-content').forEach(dropdown => {
|
|
dropdown.style.display = 'none';
|
|
});
|
|
});
|
|
|
|
function getAnswer(table_id, rowID) {
|
|
// console.log("Function called");
|
|
var policy = table_id.split('_').slice(0, -1).join('_');
|
|
// var policy = 'policy_' + table;
|
|
// console.log('policy ', table_id);
|
|
|
|
Object.entries(child_table_data).forEach(([key, value]) => {
|
|
if (key == policy) {
|
|
var table_data = value;
|
|
|
|
// Loop through all available table data (removing hardcoded [0])
|
|
table_data.forEach(table => {
|
|
var table_row = table['table_row_contents'];
|
|
|
|
Object.entries(table_row).forEach(([key, value]) => {
|
|
var question_id = Object.keys(value)[0];
|
|
if (question_id == rowID) {
|
|
let questionData = value[question_id];
|
|
// console.log("question data", questionData);
|
|
if (questionData.answer_type == 'dropdown') {
|
|
|
|
var answerAndValues = questionData.answers;
|
|
createDropdown(answerAndValues);
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
function createDropdown(answerAndValues) {
|
|
// console.log(answerAndValues);
|
|
const originalTd = event.target;
|
|
const dropdown = document.createElement("div");
|
|
dropdown.classList.add("simple-dropdown");
|
|
|
|
answerAndValues.forEach(answer => {
|
|
const option = document.createElement("div");
|
|
option.classList.add("dropdown-option");
|
|
option.textContent = answer.display_value;
|
|
option.dataset.key = answer.key;
|
|
|
|
option.addEventListener("click", function(e) {
|
|
e.stopPropagation();
|
|
originalTd.innerHTML = `${this.textContent}
|
|
<input type="hidden" value='${JSON.stringify({ key: answer.key, display_value: answer.display_value })}' />`;
|
|
|
|
// originalTd.dataset.selectedKey = this.dataset.key;
|
|
dropdown.remove();
|
|
});
|
|
|
|
dropdown.appendChild(option);
|
|
});
|
|
|
|
const rect = originalTd.getBoundingClientRect();
|
|
dropdown.style.top = rect.bottom + window.scrollY + 'px';
|
|
dropdown.style.left = rect.left + window.scrollX + 'px';
|
|
|
|
const existingDropdown = document.querySelector('.simple-dropdown');
|
|
if (existingDropdown) {
|
|
existingDropdown.remove();
|
|
}
|
|
|
|
document.body.appendChild(dropdown);
|
|
|
|
document.addEventListener("click", function(e) {
|
|
if (!dropdown.contains(e.target) && e.target !== originalTd) {
|
|
dropdown.remove();
|
|
}
|
|
});
|
|
|
|
originalTd.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
if (this.getAttribute('contenteditable') === 'true') {
|
|
this.setAttribute('contenteditable', 'false');
|
|
}
|
|
});
|
|
}
|
|
|
|
function moveExcessTableLast() {
|
|
const excessTable = document.getElementById("excess");
|
|
const tableContentDiv = document.createElement("div");
|
|
tableContentDiv.className = 'table-content';
|
|
const excessCollapseBar = document.querySelector('.table-collapsible-bar.Excess');
|
|
const overallContainer = document.getElementById('allTableContainer');
|
|
if (excessTable) {
|
|
overallContainer.appendChild(excessCollapseBar); // Move it to the end of the <body>
|
|
overallContainer.appendChild(tableContentDiv);
|
|
tableContentDiv.appendChild(excessTable);
|
|
|
|
excessCollapseBar.addEventListener('click', function() {
|
|
this.classList.toggle('collapsed');
|
|
tableContentDiv.classList.toggle('collapsed');
|
|
});
|
|
// console.log("Table moved:", document.body.lastElementChild === excessTable);
|
|
} else {
|
|
// console.log("Excess table not found.");
|
|
}
|
|
}
|
|
// Global object to track SNO for each table
|
|
let tableSNOTracker = {};
|
|
|
|
function getSNO(tableID) {
|
|
if (!tableID) {
|
|
return 1;
|
|
}
|
|
|
|
// Initialize counter if not present
|
|
if (!tableSNOTracker[tableID]) {
|
|
tableSNOTracker[tableID] = 1;
|
|
} else {
|
|
tableSNOTracker[tableID]++;
|
|
}
|
|
|
|
return tableSNOTracker[tableID];
|
|
}
|
|
|
|
function updateSNO(tableID) {
|
|
const table = document.getElementById(tableID);
|
|
if (!table) return;
|
|
|
|
const rows = table.querySelectorAll("tbody tr");
|
|
let sno = 1; // Start numbering from 1
|
|
|
|
rows.forEach(row => {
|
|
const firstCell = row.querySelector("td:first-child"); // Get SNO cell
|
|
if (firstCell) {
|
|
firstCell.innerHTML = `<input type="checkbox" class="sno-checkbox"> ${sno}`;
|
|
sno++; // Increment SNO for the next row
|
|
}
|
|
});
|
|
|
|
// ✅ Reset the tracker based on remaining rows
|
|
tableSNOTracker[tableID] = sno;
|
|
}
|
|
|
|
function increaseTableWidth(increaseBy) {
|
|
$('.table-collapsible-bar').each(function() {
|
|
let currentWidth = ($(this).width());
|
|
// console.log('table width ', typeof (currentWidth));
|
|
let increaseTableWidth = (currentWidth + increaseBy);
|
|
// console.log(increaseTableWidth);
|
|
$(this).width(currentWidth + increaseBy);
|
|
});
|
|
|
|
$("table").each(function() {
|
|
let currentWidth = ($(this).width());
|
|
// console.log('table width ', typeof (currentWidth));
|
|
let increaseTableWidth = (currentWidth + increaseBy);
|
|
// console.log(increaseTableWidth);
|
|
$(this).width(currentWidth + increaseBy);
|
|
});
|
|
}
|
|
|
|
function arrangeTables() {
|
|
// Target the container
|
|
const container = document.getElementById('tablesContainer');
|
|
if (!container) {
|
|
console.error('Error: tablesContainer not found');
|
|
return;
|
|
}
|
|
|
|
// Select divs with data-parent-row (your containers)
|
|
const divContainers = container.querySelectorAll('div[data-parent-row]');
|
|
|
|
const containerArray = Array.from(divContainers).map(div => {
|
|
const policyName = div.getAttribute('data-parent-row').toLowerCase();
|
|
const policyDetails = policyOrder.find(policy =>
|
|
Object.keys(policy)[0] === policyName
|
|
);
|
|
return {
|
|
element: div, // Work with the div, not the table
|
|
policyName: policyName,
|
|
priority: policyDetails ? policyDetails[policyName].priority : Infinity
|
|
};
|
|
});
|
|
|
|
// Filter to only selected policies
|
|
const selectedContainers = containerArray.filter(container =>
|
|
selectedPolicies.has(container.policyName)
|
|
);
|
|
// console.log('container selected ',selectedContainers);
|
|
// Sort by priority
|
|
selectedContainers.sort((a, b) => a.priority - b.priority);
|
|
|
|
// Reorder the divs in the container
|
|
selectedContainers.forEach(containerData => {
|
|
container.appendChild(containerData.element);
|
|
});
|
|
}
|
|
|
|
function setValueForHiddenField(element, answer_type) {
|
|
|
|
if (answer_type != 'dropdown') {
|
|
// console.log(element);
|
|
const hiddenInput = element.querySelector("input[type='hidden']");
|
|
const updatedText = element.textContent.trim();
|
|
var updated_Text = element.textContent.trim();
|
|
// console.log('updated text ',updated);
|
|
if (hiddenInput) {
|
|
|
|
hiddenValue = updated_Text;
|
|
|
|
// Convert it back to a JSON string and set the value
|
|
hiddenInput.value = JSON.stringify(hiddenValue);
|
|
|
|
console.log("Updated Hidden Input Value:", hiddenInput.value);
|
|
} else {
|
|
console.warn("No hidden input found inside the element.");
|
|
}
|
|
}
|
|
}
|
|
|
|
function addOrRemoveIcon(element, event) {
|
|
event.stopPropagation();
|
|
let icon = element.querySelector('.fa-check-square');
|
|
if (element.classList.contains('qcrProposal')) {
|
|
var client_proposal_element = document.querySelector('.sendClientProposal');
|
|
var icon2 = client_proposal_element.querySelector('.fa-check-square');
|
|
if (icon) {
|
|
if (icon2) {
|
|
client_proposal_element.removeChild(icon2);
|
|
}
|
|
} else {
|
|
if (!icon2) {
|
|
createIcon(client_proposal_element);
|
|
}
|
|
}
|
|
}
|
|
if (!icon) {
|
|
createIcon(element);
|
|
// console.log("checkbox added");
|
|
} else {
|
|
element.removeChild(icon);
|
|
// console.log("checkbox removed");
|
|
}
|
|
}
|
|
|
|
function createIcon(element) {
|
|
let icon = document.createElement('i');
|
|
icon.classList.add('fa', 'fa-check-square');
|
|
icon.style.color = 'green';
|
|
icon.style.marginLeft = '8px';
|
|
element.appendChild(icon);
|
|
}
|
|
|
|
$('#saveRFQ').click(() => saveRFQ());
|
|
// $("#saveRFQ").click(function (){
|
|
// console.log("Hello the save req button is clicked");
|
|
// })
|
|
|
|
function saveRFQ() {
|
|
const rfqData = {
|
|
table_data: {
|
|
headers: [],
|
|
data: []
|
|
}
|
|
};
|
|
|
|
// Get all tables
|
|
const tables = document.querySelectorAll('table');
|
|
if (tables.length === 0) return;
|
|
|
|
// Extract headers from the first table
|
|
const headerRow1 = tables[0].querySelector('thead tr:first-child');
|
|
const headerRow2 = tables[0].querySelector('thead tr:last-child');
|
|
const headers = [];
|
|
|
|
headerRow1.querySelectorAll('th').forEach((th, index) => {
|
|
const parentHeader = th.textContent.trim();
|
|
const subHeaders = [];
|
|
const subHeaderTh = headerRow2.children[index];
|
|
if (subHeaderTh) {
|
|
subHeaders.push(subHeaderTh.textContent.trim());
|
|
}
|
|
headers.push({
|
|
parentHeader,
|
|
subHeaders
|
|
});
|
|
});
|
|
rfqData.table_data.headers = headers;
|
|
|
|
// Process all tables
|
|
tables.forEach(table => {
|
|
const rows = table.querySelectorAll('tbody tr');
|
|
rows.forEach(row => {
|
|
const cells = row.querySelectorAll('td');
|
|
const rowData = {
|
|
SNO: '',
|
|
items: '',
|
|
data: []
|
|
};
|
|
|
|
// Extract SNO (first cell)
|
|
if (cells[0]) {
|
|
rowData.SNO = cells[0].textContent.replace(/\D/g, '') || '1';
|
|
}
|
|
|
|
// Extract items (row ID)
|
|
rowData.items = row.id || '';
|
|
|
|
// Process each cell
|
|
cells.forEach((cell, cellIndex) => {
|
|
const header = headers[cellIndex];
|
|
if (!header) return;
|
|
|
|
const parentHeader = header.parentHeader;
|
|
const subHeader = header.subHeaders[0] || '-';
|
|
|
|
// Get displayed value
|
|
const value = cell.textContent.trim();
|
|
|
|
// Get input value (hidden field or checkbox state)
|
|
let inputValue = value;
|
|
const hiddenInput = cell.querySelector('input[type="hidden"]');
|
|
if (hiddenInput) {
|
|
inputValue = hiddenInput.value;
|
|
}
|
|
|
|
// Handle Action column checkboxes
|
|
if (parentHeader === 'Action') {
|
|
const qcrChecked = cell.querySelector('.qcr-checkbox')?.checked ?? false;
|
|
const clientChecked = cell.querySelector('.client-checkbox')?.checked ?? false;
|
|
inputValue = {
|
|
qcr: qcrChecked ? 1 : 0,
|
|
stc: clientChecked ? 1 : 0
|
|
};
|
|
}
|
|
|
|
rowData.data.push({
|
|
parentth: parentHeader,
|
|
subth: subHeader,
|
|
value,
|
|
input_value: inputValue
|
|
});
|
|
});
|
|
|
|
rfqData.table_data.data.push(rowData);
|
|
});
|
|
});
|
|
|
|
console.log(JSON.stringify(rfqData, null, 2));
|
|
}
|
|
</script>
|