-1

How could I combine the two models which i have kept for two different purpose. One is to for file upload and the other is for render data from different object.Below is the respective html and JS i tried.

HTML section

     <div class="well" data-bind="fileDrag: fileData">
        <div class="form-group row">
           <div class="col-md-6">
              <img style="height: 125px;" class="img-rounded  thumb" data-bind="attr: { src: fileData().dataURL }, visible: fileData().dataURL">
              <div data-bind="ifnot: fileData().dataURL">
                 <label class="drag-label">Drag file here</label>
              </div>
           </div>
           <div class="col-md-6">
              <input type="file" data-bind="fileInput: fileData, customFileInput: {
                 buttonClass: 'btn btn-success',
                 fileNameClass: 'disabled form-control',
                 onClear: onClear,
                 }" accept="application/pdf,image/*">
           </div>
        </div>
     </div>
     <button class="btn btn-default" data-bind="click: debug">Upload</button>
  </div>
  <div id="notification" style="display: none;">
     <span class="dismiss"><a title="dismiss this notification">X</a></span>
  </div>

     <!-- Collapsible Panels - START -->
     <div class="container">
        <div class="row">
           <div class="col-md-12">
              <div class="panel panel-primary">
                 <div class="panel-heading">
                    <h3 class="panel-title">Plan Details</h3>
                 </div>
                 <div class="panel-body">
                    <span class="glyphicon glyphicon-plus clickable" id="addPlanBtn"></span>
                    <span class="glyphicon glyphicon-remove clickable" id="removePlanBtn"></span>
                    <span class="glyphicon glyphicon-edit clickable" id="editPlanBtn"></span>
                    <table id="docsDataTable" class="table table-striped display" width="100%">
                       <thead>
                          <tr>
                              <th></th>
                              <th>Contract Document ID</th>
                              <th>Contract ID</th>
                              <th>Document Name</th>
                              <th>File Path</th>
                              <th>Comments</th>

                          </tr>
                       </thead>
                    </table>                        
                    <div class="modal fade" id="notificationDialog" role="dialog">
                       <div class="modal-dialog modal-sm">
                          <div class="modal-content">
                             <div class="modal-header">
                                <button type="button" class="close" data-dismiss="modal" \>&times;</button>
                                <h4 class="modal-title">Notification</h4>
                             </div>
                             <div class="modal-body" id="notificationBody">


                             </div>
                             <div class = "modal-footer">
                                <button type = "button" class = "btn btn-primary" data-dismiss = "modal">
                                   Ok
                                </button>
                             </div>
                          </div>
                       </div>
                    </div>
                    <div class="modal fade" id="confirmBox" role="dialog">
                       <div class="modal-dialog modal-sm">
                          <div class="modal-content">
                             <div class="modal-header">
                                <button type="button" class="close" data-dismiss="modal" \>&times;</button>
                                <h4 class="modal-title">Confirmation</h4>
                             </div>
                             <div class="modal-body" id="confirmBody">
                                   Selected rows will be made inactive.
                             </div>
                             <div class = "modal-footer">
                                <button type = "button" class = "btn btn-default" data-dismiss = "modal" id="confirmNoBtn">
                                   Cancel
                                </button>
                                <button type = "button" class = "btn btn-primary" data-dismiss = "modal" id="confirmYesBtn">
                                   Ok
                                </button>
                             </div>
                          </div>
                       </div>
                    </div>
                 </div>
              </div>
           </div>
        </div>
     </div>

Javascript section to bind the data

     var dataset;
     var docsModel;
     var docsTable;
     var vasTypes;
     $(function(){
       var viewModel = {};
       viewModel.fileData = ko.observable({
         dataURL: ko.observable(),
         // base64String: ko.observable(),
       });
       viewModel.onClear = function(fileData){
         if(confirm('Are you sure?')){
           fileData.clear && fileData.clear();
         }                            
       };
       viewModel.debug = function(){
         window.viewModel = viewModel;
         //console.log(ko.toJSON(viewModel));
     fileUpload(viewModel);
         debugger; 
       };
       ko.applyBindings(viewModel);
     });

     $(document).ready(function(){
        docsModel = new $.cordys.model({
              context: document.getElementById("addPanelForm"),
              objectName: "CONTRACT_DOCUMENT",

              fields: ["CONTRACT_DOCUMENT_ID" , "CONTRACT_ID" , "DOCUMENT_NAME" , "FILE_PATH" , "COMMENTS"],
              defaults: {
                 namespace: "http://services.vw.com/lpms/1.0/wsapp"
              },/*
              update: {
                 method: "UpdatePlanVas"
              },*/
              read: {
                 method: "GetContractDocumentObjectsForContractId",
                 parameters: {
                         CONTRACT_ID: "CONTRACT_1000"                           
                         },
              }
        });      

        GetContractDocumentObjectsForContractId();

        docsTable = $('#docsDataTable').DataTable({
           data: dataset,
           columnDefs: [ {
              orderable: false,
              className: 'select-checkbox',
              defaultContent: "",
              targets: 0},
           { data: "CONTRACT_DOCUMENT_ID",
              targets: 1,
              visible: false},
           { data: "CONTRACT_ID",
              targets: 2},

           { data: "DOCUMENT_NAME",
              targets: 3},
                { data: "COMMENTS",
              targets: 5},
           { data: "FILE_PATH",
              targets: 4}],
           select: {
              style:    'multi',
              selector: 'td:first-child'
           },

           order: [[ 1, 'asc' ]],
           "searching": false,
           "lengthChange": false
        });
     });



     function fileUpload(data){
     dataObject=ko.toJS(viewModel);
     fileName=dataObject.fileData.file.name;
     fileContent=dataObject.fileData.dataURL.split(',')[1];
           $.cordys.ajax({
               method: "WriteFile",
     parameters: {
     filename: fileName,
     encoded: "true",
     data:fileContent
     },
               namespace:"http://schemas.cordys.com/1.0/ac/FileConnector",
               dataType: "* json",
               async: false,
               success: function(e){
     $.notify("Yeah ! File Uploaded", "success");

               }
            });
        }
eshaa
  • 386
  • 2
  • 7
  • 26
  • It helps if you make it easy for us to read through your code by paying some extra attention to formatting (there's a preview on the editor), and it would also help if you make the repro of your situation as minimal as reasonably possible (there's *a lot* of code in the post that seems irrelevant to the question). Currently, the question is rather unclear (though I *suspect* that if it *were* clear, it would probably be a duplicate of [this one](http://stackoverflow.com/q/9293761/419956)). – Jeroen Jun 13 '16 at 05:15

1 Answers1

1

You're getting the error

You cannot apply bindings multiple times to the same element

Because Knockout only permits one view-model to be bound to a DOM element.

In your case, you need to somehow combine the two view-models into one. While you could simply add the properties from one view-model into the other, perhaps creating a third view-model with a new name so you can continue using the original form of these view-models elsewhere, my suggestion would be to create a new super view-model, and reference the two existing view-models as properties on this new view-model.

At this point I would normally create an example from the code in the OP but in this case, as @Jeroen has pointed out, it's rather difficult to make out what's going on in the OP. As far as I can see, there's only one view-model in there while your question revolves around having two view-models. So the following example is unfortunately very generic.

var ViewModel1 = function() {
    var self = this;
    self.obs1_1 = ko.observable();
    self.obs1_2 = ko.observableArray([]);

    // some initialisation stuff
},
ViewModel2 = function() {
    var self = this;
    self.obs2_1 = ko.observable();
    self.obs2_2 = ko.observableArray([]);

    // some initialisation stuff
},
SuperViewModel = function() {
    var self = this;
    self.vm1 = new ViewModel1();
    self.vm2 = new ViewModel2();

    // some initialisation stuff
};

You would then instantiate and data-bind SuperViewModel, and reference the observables like so

<input type="text" data-bind="textInput: vm1.obs1_1" />
<div data-bind="foreach: vm1.obs1_2">
    <span data-bind="html: $data"></span>
</div>

or to make typing a little bit easier

<!-- ko with: vm1 -->
    <input type="text" data-bind="textInput: obs1_1" />    <!-- this time without "vm1." -->
    <div data-bind="foreach: obs1_2">                      <!-- this time without "vm1." -->
        <span data-bind="html: $data"></span>
    </div>
<!-- /ko -->

You now have a single view-model, SuperViewModel, referencing your unchanged existing view-models. This solution allows you to leave existing JavaScript and views while offering an easy method of data-binding the functionality of multiple view-models inside a single view-model.

It's technically possible to achieve a similar result by doing some referencing at the prototype level, but that could quickly cause complications and the only advantage would be saving you from typing the name of a property.

awj
  • 7,482
  • 10
  • 66
  • 120