2

I am making a custom module before adding a product on cart with 3 options :

enter image description here

The upload option should display an upload form like :

enter image description here

My initial idea was to make two knockout components :

  • Component to display options
  • Component to show the download form

Each component should be independent just communicating with passed variables :

My first component looks like :

JS component to display options:

define([
  'jquery',
  'uiComponent',
  'mage/validation',
  'mage/url',
  'mage/translate',
  'ko',
  ], function ($, Component, validation, url, $t, ko, loadAction) {
      'use strict';
      var optionActive = ko.observable("");

      return Component.extend({
          defaults: {
              template: 'Sebfie_Prescription/prescription'
          },
          options: {

          },
          initialize: function () {
              this._super();
              this.initButtons();
              optionActive.subscribe(this.onOptionChange.bind(this));
          },

          initButtons: function() {
            this.options.addToCartBtn = $("#product-addtocart-button");
            this.options.nextBtn = $(".wizard-footer .btn-next");
            this.disableAddButton();
            this.options.nextBtn.click(function() {
                $("#itoris_dynamicoptions_add_to_cart").click();
            });
          },

          onOptionChange: function(value) {
            if (value == "upload_prescription") {
                this.onUploadPrescription();
            }
            if (value == "user_prescription") {
                this.onUserPrescription();
            }
            if (value == "later_prescription") {
                this.onLaterPrescription();
            }
          },

          onLaterPrescription: function() {
            this.enableAddButton();
          },

          onUserPrescription: function() {
            this.disableAddButton();
          },

          onUploadPrescription: function() {
            this.disableAddButton();
          },

          disableNextButton: function() {
            this.options.nextBtn.addClass("disabled").attr("aria-disabled","true");
          },

          enableNextButton: function() {
            this.options.nextBtn.removeClass("disabled").removeAttr("aria-disabled");
          },

          disableAddButton: function() {
            this.options.addToCartBtn.addClass("disabled").attr("aria-disabled","true");
          },

          enableAddButton: function() {
            this.options.addToCartBtn.removeClass("disabled").removeAttr("aria-disabled");
          },

          userImage: function() {
            return window.prescription_images.use_previous;
          },
          uploadImage: function() {
            return window.prescription_images.upload;
          },
          laterImage: function() {
            return window.prescription_images.do_it_later;
          },
          setActive: function (value) {
              optionActive(value);
          },
          getOptionActive: function() {
              return optionActive();
          },
          getOptionActiveKo: function() {
            return optionActive;
          }
      });
  }
)

Template Sebfie_Prescription/prescription.html :

<div class="prescription-upload-wrapper">
  <h3>PROVIDE YOUR PRESCRIPTION DETAILS</h3>
  <input name="prescription_type" type="hidden" data-bind="attr: {value: getOptionActive()}"/>
  <!-- ko if: getOptionActive() != 'upload_prescription' -->
  <div class="row">
    <div class="col-md-4">
      <div class="choice" data-bind="click: setActive('user_prescription'), css: { active: getOptionActive() == 'user_prescription' }">
        <div class="img">
          <img data-bind="attr: { src: userImage() }" />
        </div>
        <div class="description">
          <strong>Use a previous prescription</strong>
          Please sign-in here
        </div>
      </div>
    </div>
    <div class="col-md-4">
      <div class="choice" data-bind="click: setActive('upload_prescription'), css: { active: getOptionActive() == 'upload_prescription' }">
        <div class="img">
          <img data-bind="attr: { src: uploadImage() }" />
        </div>
        <div class="description">
          <strong>Upload a prescription</strong>
          Take a picture of your prescription of upload it into your portal by choosing this option.
        </div>
      </div>
    </div>
    <div class="col-md-4">
        <div class="choice" data-bind="click: setActive('later_prescription'), css: { active: getOptionActive() == 'later_prescription' }">
          <div class="img">
            <img data-bind="attr: { src: laterImage() }" />
          </div>
          <div class="description">
            <strong>DO IT LATER</strong>
            You will receive an e-mail explaining how you can provide your prescription, after you have placed the order.
          </div>
        </div>
    </div>
  </div>
  <!-- /ko -->
  <!-- ko if: getOptionActive() == 'upload_prescription' -->
  <div data-bind='scope: "prescriptionUpload", mageInit: {"prescriptionUpload": {option: getOptionActiveKo()}}'>
    <!-- ko template: getTemplate() --><!-- /ko -->
  </div>
  <!-- /ko -->
</div>

Component Sebfie_Prescriotion/type/upload.html

define([
  'jquery',
  'uiComponent',
  'mage/validation',
  'mage/url',
  'mage/translate',
  'mage/template',
  'ko',
  ], function ($, Component, validation, url, $t, template, ko, loadAction) {
      'use strict';
      var photoUrl = ko.observable();

      return Component.extend({
          defaults: {
              template: 'Hellooptical_Prescription/type/upload',
              select_option: null
          },
          initialize: function (params) {
              this.select_option = params.option;
              this._super();
          },

          fileUpload: function(data, e) {
            var file    = e.target.files[0];
            var reader  = new FileReader();

            reader.onloadend = function (onloadend_e)
            {
                var result = reader.result; // Here is your base 64 encoded file. Do with it what you want.
                photoUrl(result);
            };

            if(file)
            {
                reader.readAsDataURL(file);
            }
          },

          photoUrl: function() {
              return photoUrl();
          }
      });
  }
)

Template type/upload.html

<input name="prescription_file" data-bind="event: {change: fileUpload}" type="file" accept="image/*" class="fileChooser"/>
<img class="myImage" data-bind="attr: {src: photoUrl() }"/>

But with this I got error :

Uncaught RangeError: Unable to process binding "template: function(){return getTemplate() }"

In fact the scope of :

<div data-bind='mageInit: {"prescriptionUpload": {option: getOptionActiveKo()}}'>
    <!-- ko template: getTemplate() --><!-- /ko -->
</div>

Keeps to be the parent scope.

0

change your code like this.

define([
  'jquery',
  'uiComponent',
  'mage/validation',
  'mage/url',
  'mage/translate',
  'mage/template',
  'ko',
  ], function ($, Component, validation, url, $t, template, ko) {
      'use strict';
      var photoUrl = ko.observable();

      return Component.extend({
          defaults: {
              template: 'Hellooptical_Prescription/type/upload',
              select_option: null
          },
          initialize: function (params) {
              this.select_option = params.option;
              this._super();
          },

          fileUpload: function(data, e) {
            var file    = e.target.files[0];
            var reader  = new FileReader();

            reader.onloadend = function (onloadend_e)
            {
                var result = reader.result; // Here is your base 64 encoded file. Do with it what you want.
                photoUrl(result);
            };

            if(file)
            {
                reader.readAsDataURL(file);
            }
          },

          photoUrl: function() {
              return photoUrl();
          }
      });
  }
)
  • What have you changed? Copying and pasting doesn't help anybody learn. – Ben Crook Oct 9 '18 at 13:54
  • I remove addition parameter called "loadAction". Kindly check the code. – Dhiren Vasoya Oct 9 '18 at 13:56
  • after making above change, run caching, upgrade and deploy command and then check. – Dhiren Vasoya Oct 9 '18 at 13:56
  • Changing nothing, the error was not here. It's an issue about scope. – Sebastien Oct 9 '18 at 15:35
  • @DhirenVasoya A better idea? – Sebastien Oct 10 '18 at 12:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.