Dynamic Dropdown in Quoted line item

I want to populate the drop-down values dynamically based on other field value selected in Quoted Line Item. I have add ed my changes in following path: custom/modules/Products/clients/base/fields/enum/enum.js.

OnChange of product_template_id field, i want to display Status (custom field) drop-down options in Quoted Line Item.

for ex. if i am selecting product_tempalte_id as "Lindsay Gadget" and same value should be auto selected in Status and few other additional options should be shown based on certain conditions in Quoted Line Item. I am getting the dd values from api and trying to populate those results as dropdown options for Status field.

The below changes are working fine for first two line items, but if i am adding third one, 1st line item option value is changed to blank and its displaying the same (line Item 3) dd option list for all the line-items.

({
extendsFrom:'EnumField',
initialize: function(options){
this._super('initialize',[options]);
this.type ='enum';
this.listenTo(this.model,"sync",function(model){
this.loadOptions();
});
this._initEvents();

},

_initEvents:function(){
//console.log('_initEvents');
this._updateStatus();
},

_updateStatus:function(){
this.model.on('change:product_template_name',this.loadOptions, this);
},


loadOptions: function(callback) {
var product_template_id = this.model.get('product_template_id')
if(this.name === 'status_c'){
var options = {};
var self = this;
var request;
var _itemsKey = 'cache:' + this.module + ':' + this.name + ':items';
var _key = 'request:' + this.module + ':' + this.name;
if (!this.context.get(_key)) {
//if(this.model.get('product_template_id')){
dataArray ={'product_template_id':product_template_id}
app.api.call('create', app.api.buildURL('Products/getStatus'), dataArray, {
success: function(o) {
if (self.disposed) {
return;
}
if (self.items !== o) {
self.items = o;
self.context.set(_itemsKey, self.items);
//self.context.unset(_key);
//if (callback) callback.call(self);
if (!_.isUndefined(self.items)) {
if (Object.keys(self.items).length == 1) {
self.model.set(self.name, Object.keys(self.items)[0]);
} else if (!(self.model.get(self.name) in self.items)) {
self.model.set(self.name, product_template_id);
}
}
}
},
error: function(e) {
if (self.disposed) {
return;
}

if (error) {
error(e);
}

// Continue to use Sugar7's default error handler.
if (_.isFunction(app.api.defaultErrorHandler)) {
app.api.defaultErrorHandler(e);
}

self.items = {'': app.lang.get('LBL_NO_DATA', self.module)};
},
complete: function() {
if (!self.disposed) {
self.context.unset(_key);
callback.call(self);
}
}
});
//}//product template ends
}
}//uom_c ends
},

loadEnumOptions:function(fetch, callback){
var self=this;
var _itemsKey = 'cache:'+this.module+':'+this.name+':items';
this.items = this.context.get(_itemsKey);
if(!this.items){
this.isFetchingOptions = true;
var _key = 'request:'+this.module+':'+this.name;
if(this.context.get(_key)){
var request = this.context.get(_key);
request.xhr.done(_.bind(function(data){
if(this.items !== data){
this.items = data;
callback.call(this);
}
},this));

}else{
this.loadOptions(callback);
}
}
},
})

Any help is appreciated,

Thanks,

Kumar

  • See if this helps:

    When the product is selected I use a Custom API call to populate the applicable_promos_c enum field's dropdown with applicable promotions (promos) for this product.

     

    When a promotion is selected, I apply the discount (note that promotions can be a percentage discount or an amount) which complicates this code a bit, but you should be able to follow along. The loadEnumOptions function is where the applicable promos are loaded into the applicable_promos_c dropdown, it extends the same function in 

    <your_sugar_root>/clients/base/fields/enum/enum.js

    Note that this fires for EVERY enum in your Quoted Line Items, the if on the name field is what keeps it from executing on every enum field. .

    ({
      extendsFrom: 'EnumField',
      initialize: function(options){
        this._super('initialize',[options]);
        this.promoDiscountChange()
      },
      _render:function(){
        this._super('_render');
      },
      promoDiscountChange: function() {
        if(this.name == 'applicable_promos_c'){
          //apply the Discounts selected from the dropdown
          this.model.on('change:applicable_promos_c', this.triggerAppliedDiscountChange, this);
        }
      },
      triggerAppliedDiscountChange: function() {
        var selected_promos = this.model.get('applicable_promos_c'),
            promos = selected_promos.toString();
        this.model.set('discounts_c', promos);
        this.calculateDiscount();
      },
      calculateDiscount: function(){
        var self = this,
           discount_tot = 0,
           other_discount_amount = 0;
           unit_price = self.model.get('discount_price'),
           selected_promos = this.model.get('applicable_promos_c');
        _.each(selected_promos, function(promo){
          var discount = promo.replace( /(^.*\[|\].*$)/g, '' ); //strip everything but what's inside the [ ]
          var  is_pct_discount = discount.match(/%/);
          if(is_pct_discount){
            //it's a percentage
            //strip the % sign
            var pct_discount = discount.replace('%',''); //strip the percent sign to leave the amount
            discount_tot = +discount_tot + (+unit_price * (+pct_discount/100));
          }else{
            discount_tot = +discount_tot + +discount.replace(' ','');
          }
        });
        this.model.set('discount_amount', discount_tot);
        this.model.set('discount_select', 0);
      },
      loadEnumOptions: function(fetch, callback){
        var self = this;
        if(this.name == 'applicable_promos_c'){
          //always fetch the values, either from cache or from API
          fetch = true;
          var  currency_id = self.model.get('currency_id'),
               part_num = self.model.get('mft_part_num'),
               _module = this.getLoadEnumOptionsModule(),
               _record = this.model.id,
               _itemsKey = 'cache:' + _module + ':' + part_num + currency_id + _record + ':items';
          //cache the for this specific record so that it won't requery ERP at every panel refresh
          this.items = this.context.get(_itemsKey);
          if(!this.items){
            //try getting the items from cache
            this.isFetchingOptions = true;
            var _key = 'cache:' + _module + ':' + part_num + currency_id + _record;
            if (this.context.get(_key)) {
              var request = this.context.get(_key);
              request.xhr.done(_.bind(function(o) {
                if (this.items !== o) {
                  this.items = o;
                  callback.call(this);
                }
              }, this));
            } else {
              //rebuild the items from ERP and any currently set values
              var discount_url = app.api.buildURL('ERPDiscountProgramsLookup/'+part_num+'/'+currency_id);
              if(!_.isEmpty(part_num) && !_.isEmpty(currency_id)){
                app.api.call('GET', discount_url, null, {
                  success: function (data){
                    if (self.disposed){ return; }
                    if(!_.isEmpty(data) && self.items !== data){
                      self.items = data; //set the individual items for the dropdown
                      //check if any of the discounts previously selected are no longer in the list
                      var selected_discounts = self.model.get('discounts_c');
                      if(!_.isEmpty(selected_discounts)){
                        var selected_discount_list = self.model.get('discounts_c').replace(/^/g,'').split(',');
                        _.each(selected_discount_list, function(discount){
                          var exists = false;
                          _.each(self.items, function(item){
                            if(item == discount) exists = true;
                          });
                          if(exists == false){
                            //selected discount not in the current list from ERP, must be an expired discount
                            //add it to the list marked as Expired and selected so that the user can see it
                            var expired_discount = 'Expired-'+discount;
                            self.items[discount] = expired_discount;
                           }
                        });
                      }
                      self.context.set(_itemsKey, self.items);
                      self.context.unset(_key);
                      callback.call(self);
                    }else{
                      self.items = {"":""};
                    }
                  },
                  error: function(e){
                     console.log(e);
                     callback.call(self);
                  },
                });
              }else{
                self.items = {"":""};
              }
            }
          }
        }else{
          self._super('loadEnumOptions',[fetch, callback]);
        }
      },
    })

     

    And don't forget to add your custom field to the Quotes record.php under product_bundle_items

    custom/modules/Quotes/clients/base/views/record/record.php

    FrancescaS

     

    A quick note: it helps if you format your code so that it's more readable to the reader.

     

    To do this you select "More" in the menu at the top of the compose window, there you can use the "Syntax Highlighter"

     

     

    and paste your code in there. Select the language so it can be correctly highlighted.

     

     

    If you need to edit the code after you saved it, you can click in the box with the code and go back to the Syntax Highlighter to edit it.

     

    You can also edit an old post by going to Edit, selecting the code you already pasted in and THEN going to Syntax Highlighter and choosing the format.