inline snippet to enable/disable field(s) in a popup - works, but only after field changed

  • 2
  • Question
  • Updated 5 years ago
  • Answered
I have some inline JS that enables/disables one field (toggles between "read" and "readonly") based on the value of another field. The fields are both in a popup.

The code works, but only once the popup has come up and I've set/reset the controlling field. I can't get it to initially enable/disable the controlled field. Here is the code, taken from a sample that Zach gave me. It works perfectly elsewhere, but doesn't work initially for my popup.

---------- snip, snip ----------
(function(skuid){

var $ = skuid.$,
$M = skuid.model.map();
$(function(){

var AccountModel = $M.NewAccount,
Account = AccountModel.getFirstRow();

// Register a listener on the Status field.
// When it is changed, we may need to rerender some fields
// to make them read-only.
var listener = new skuid.ui.Field(Account,AccountModel,null,{
fieldId: 'Status__pc',
register: true
});

var fieldsToDisable = ['Death__pc'];

var deathHandleChange = function(newValue){
$.each(AccountModel.registeredLists,function(){
$.each(this.renderedItems,function(){
$.each(this.fields,function(){
if ($.inArray(this.id,fieldsToDisable)!==-1){
if (newValue == 'Deceased') this.mode = 'edit';
else {
this.mode = 'readonly';
}
AccountModel.updateRow(Account,this.id,'',{initiatorId: this._GUID});
this.element.empty();
this.render();
}
});
});
});
};

listener.handleChange = function(newValue){
deathHandleChange(newValue);
};

// Run the handle change initially
deathHandleChange(
AccountModel.getFieldValue(Account,'Status__pc',true)
);

});

})(skuid);
---------- snip, snip ----------
Photo of Ken Neff

Ken Neff

  • 408 Points 250 badge 2x thumb

Posted 5 years ago

  • 2
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,004 Points 20k badge 2x thumb
Official Response
First note, for anyone reading this, we are working to make it easier to accomplish behaviors like this without writing a ton of JavaScript code. Currently, however, this is the only way to accomplish this.

So, back to Ken's question:

To get this to work in a popup, you'll need to force the "deathHandleChange" function to run after the popup is loaded. The way that this code is currently, the "deathHandleChange" function will be run when the page is initially loaded (note: not when the popup is loaded), as well as whenever the Status__pc field is updated after that.

So, the challenge is to get the function to run as soon as the popup is opened.

As of right now, there are a couple ways to do this, but the simplest way would be to write a Custom Component that runs the function, and place this Custom Component in the popup after all other components.

To do this, just add the following JavaScript to your Inline JavaScript right after the line that runs the deathHandleChange initially:



/**** (current stuff) ******/

// Run the handle change initially
deathHandleChange(
AccountModel.getFieldValue(Account,'Status__pc',true)
);

/***** NEW STUFF *****/

// Define a custom component,
// whose sole purposes is to run our handle change for us
// whenever its parent DOM element is rendered
skuid.componentType.register('DeathHandleChangeInitiator',function(){
// Run the handle change
deathHandleChange(
AccountModel.getFieldValue(Account,'Status__pc',true)
);
});

/***** end NEW STUFF *****/



THEN, here's the annoying part, as of Skuid 3.14, you can't drag the "Custom" Component into your Popups. We're changing this as I write this, as there's absolutely no reason for this not to be includable in a Popup.

So, go into your XML, find the Popup's "components" node, and at the very end of it, add in the following node:



<components>

.... other components, like Field Editor / Wizard, etc.

<custom name="DeathHandleChangeInitiator"/>

</components>



That should do it!