I am trying to run custom Javascript code after the page is loaded completely with all the form elements/fields.
I am trying this on Magento2 Admin while adding new product.
For example:
I am trying to disable
Quantityfield inNew Productadd page in Magento2 Admin.
The page content is rendered through KnockoutJS. So, the following jQuery on load are not working:
jQuery(window).bind("load", function() { 
 // your code
});
// OR
jQuery(window).on('load', function() {
 // your code
});
How to run Javascript code in Magento 2 after KnockoutJS has completed rendering all the DOM elements?
- 
 You can check link, rakeshjesadiya.com/…Rakesh Jesadiya– Rakesh Jesadiya2018年11月18日 14:26:43 +00:00Commented Nov 18, 2018 at 14:26
- 
 @Mukesh Chapagain, could you please look at my post around the similar issue and see if you can share some tips to start with? magento.stackexchange.com/questions/313927/…CodeForGood– CodeForGood2020年06月25日 12:10:53 +00:00Commented Jun 25, 2020 at 12:10
5 Answers 5
Because Magento use async rendering it not possible to make what you ask.
But you can work with js UI component to disable field
require(['uiRegistry'], function (uiRegistry) {
 uiRegistry.get("product_form.product_form.product-details.quantity_and_stock_status_qty.qty", function (element) {
 element.disable()
 })
})
This answer is correct, however we're lacking information regarding how we know to use 'product_form.product_form.product-details.quanityt_and_stock_status_qty.qty' as the get() parameter.
.get is looking for its first parameter to be a component. So... how do you find the component, and is that language clear? No.
As an example, I wanted to add some custom javascript functionality to the customer information page within the Magento 2 admin. Specifically under, editing a user, 'Account Information' tab.
There are two ways to approach this from what I can tell...
Edit the datasource, to change values. Manipulate the field, such as visibility.
Edit the datasource:
Lets roll. Some dots are missing here, but we're on a page handled by the magento customer module, its an edit page... so we look here... /vendor/module-customer/view/adminhtml/layout/customer_index_edit.xml. Within here the content area is defined to contain 'customer_form'.
<referenceContainer name="content">
 <uiComponent name="customer_form"/>
</referenceContainer>
This means we're looking for a 'customer_form.xml' file, in this case it is found under /vendor/module-customer/view/base/ui_component/customer_form.xml. Within here we find the definition for a couple of the forms within the tabs and their fields. The datasource we're after is defined near the top.
<argument name="data" xsi:type="array">
 <item name="js_config" xsi:type="array">
 <item name="provider" xsi:type="string">customer_form.customer_form_data_source</item>
 </item>
 <item name="label" xsi:type="string" translate="true">Customer Information</item>
 <item name="reverseMetadataMerge" xsi:type="boolean">true</item>
</argument>
Note the 'provider' of 'customer_form.customer_form_data_source'. This is where all of our field data will exist within the .get call.
Our .get() would now become:
uiRegistry.get('customer_form.customer_form_data_source', function(element) {
 console.log(element.data);
});
Now, the question becomes... what can we do with this- and all you can do is adjust the data. You can turn fields true/false, manipulate values, so on. Useful.
Manipulate the field:
What if we want to hide the field and only show it under x condition... we can't do that with the datasource.
Now... this is going to be long and seem convoluted. Its because I'm teaching how to find your data... as I don't know how to find this any other way- and its going to be different per module. Teach a man to fish.
First I output my 'customer_form.customer_form_data_source' within our .get(). This will provide us a 'params' object key, within that is the definition of an 'activeArea' on the object, which is 'customer_form.areas.customer_edit_tab_view_content'.
Ok... so there are 'areas'. Areas, are the tabs on the left- each one is an area. Open up the '_elems' within your console, you'll notice 9 objects at the top. Open the second one and you'll find a label of 'Account Information'. This is the section I'm after. Then observe the 'name' value of 'customer_form.areas.customer'... ok lets try that as our get() param.
uiRegistry.get('customer_form.areas.customer', function(element) {
 console.log(element);
});
This is our fieldset wrapper, check its name value within the console under '_elems'->0->'name'. 'customer_form.areas.customer.customer'... we're drilling down. We're actually already there, check the 'name' value on the field you want to edit. You'll notice its name is 'customer[field_name]'. Making our path for get() is 'customer_form.areas.customer.customer.['field_name]'.
uiRegistry.get('customer_form.areas.customer.customer.[field_name]', function(element) {
 element.visible(false);
});
Examples: [form_name].[tab_areas].[area_name].[fieldset_name].[field_name] customer_form.areas.customer.customer.field_name
- 
 Can you please explain how to get identifier for a field in ui component?Vivek Kumar– Vivek Kumar2018年01月18日 08:15:03 +00:00Commented Jan 18, 2018 at 8:15
- 
 You can find registry-names of any KnockoutJS elements easily using the following Google Chrome-extension: Knockoutjs context debugger. Just click on the element you want to know the name of and find the 'name'-element inside the output.Daan van den Bergh– Daan van den Bergh2018年06月21日 12:37:27 +00:00Commented Jun 21, 2018 at 12:37
There is a plugin built into Require JS to handle page load, this is the preferred method as any other modules that depend on yours will also be aware of the page load requirement. If you use the jQuery method mentioned by Rajeev the other modules will not be aware of the page load requirement.
The plugin is called domReady! and can be used by adding it as a dependency like so:
require(["jquery", "domReady!"], function($){
 // Your code here
});
This will wait for page load but doesn't necessarily mean it loads after all other KO modules as they may also be waiting for page load. For that reason I think KAndy's method is the most reliable, but this answer may help others.
- 
 Ben, could you please look at my post around the similar issue and see if you can share some tips to start with? magento.stackexchange.com/questions/313927/…CodeForGood– CodeForGood2020年06月25日 12:10:14 +00:00Commented Jun 25, 2020 at 12:10
doing this works for me, it waits until ko has put the form elements in
require([
'jquery',
'Magento_Ui/js/lib/view/utils/dom-observer',
], function (,ドル$do) {
 $(document).ready(function(){
 $do.get('.class-name', function(elem){
 $(elem).addClass('test-class');
 //your code
 });
 });
});
- 
 1This works as expected and is actually quite simple. +1Akif– Akif2022年05月31日 09:47:00 +00:00Commented May 31, 2022 at 9:47
- 
 1@John, many thanks. This helped, because in my case the issue was to execute script after customer open Account Information tab. So, I've just added the block to customer_index_edit.xml and your script in phtml file and it works as I need.Sergey Uskov– Sergey Uskov2022年12月16日 15:44:08 +00:00Commented Dec 16, 2022 at 15:44
The document ready or DOM loaded events won't be fired on completion of UI form loading.
Here, either you shall have to write a function in javascript which should be called at some interval and as soon as your target element appears in DOM, process your business logic and clear the interval.
Another option could be - to execute your JavaScript business logic after completion of AJAX request which can be achieved using following code block.
$(document).ajaxComplete(function() {
// enter your code here
});
You can try something like this.
<script type="text/javascript">
require(["jquery"], function($){
 $(function() {
 //do your stuff here
 });
});
</script>
This will make sure, your code will get executed only after dom is fully loaded. If you are familiar with jquery, you will be probably know what $(function() {}); does. It makes sure code comes inside that anonymous function will get executed only after DOM is completely loaded.
- 
 4Thanks for the answer but it didn't work. The jQuery code runs before KnockoutJS renders DOM elements.Mukesh Chapagain– Mukesh Chapagain2017年02月12日 16:38:42 +00:00Commented Feb 12, 2017 at 16:38