Question: Can we read-only an element in a repeat group after a value is entered and saved?

navjinder

New Member
Hi

Does anyone have done this successfully. You want the users to use repeat group to add in the value. Once it is added make the field read-only? Any help would be greatly appreciated.

Thanks
Nav
 
Last edited:
No. You can set add and delete access on groups, but not edit. Might be something we add one day, but it's not trivial.

-- hugh
 
Thanks Hugh

But can I add some validation? I have tried adding the not empty validation but it do not work. It either makes all the fields disabled or none? Any direction would be helpful.
 
You could maybe do it with some custom coding with the PHP validation, but it wouldn't be trivial.

You might have more luck with some Javascript to set that element to read-only if it has a value on page load.

-- hugh
 
Hi Hugh

Yes I have tried it this is the Javascript I have used but it just makes all the new one which I add also disabled for e.g. I am looking for all the ids of all the added row locked element which is hidden and using that to make the quantity field disabled but you can see in the image it is doing it everything even new records.
JavaScript:
jQuery('[id*=tc_repairs_22_repeat___locked]').each(function(){
 
    var ids = jQuery(this).attr('id');
    ids = ids.substr(ids.length - 1);
    jQuery('#tc_repairs_22_repeat___quantityused_'+ids).eq(0).prop('disabled',true);

 
   });
 

Attachments

  • repeat-disabled.png
    repeat-disabled.png
    22.5 KB · Views: 235
Well, that code isn't testing the value of the locked element, which I presume you set to a value on submission. So in the each function you need to test its value and only disable your other element if it has that value.

Sent from my HTC One using Tapatalk
 
Thanks for the reply. Yes I have checked even that too but it is doing strange things i.e even though the default value is 0 in the source code it shows as 1 which is why JavaScript is disabling it as well. Thanks for your help once again.

JavaScript:
jQuery('[id*=tc_repairs_22_repeat___quantityused]').each(function(){
  
      if(jQuery(this).val() > '0'){jQuery(this).closest('tr').find('input').attr('disabled', true);}
   
    });
 

Attachments

  • repeat-group2.png
    repeat-group2.png
    132.4 KB · Views: 236
It's always best to use the Fabrik object to get an element's value. Search for formElements and you'll find some examples.


Sent from my HTC One using Tapatalk
 
Hi Hugh

I tried this but still the same issue it just disables all the elements even the new one which I add?
JavaScript:
// The block you want to use
  var blockRef = 'form_10';
  // Should we use an exact match for the blockRef?
  var exact = false;
  var form = Fabrik.getBlock(blockRef, exact, function (block) {
    // This callback function is run once the block has been loaded.
    // The variable 'block' refers to Fabirk.blocks object that controls the form.
   // var v = block.elements.get('tablename___elementname').get('value');
    // If your element is in a repeat group its name is prefixed with _0, _1, _2 etc - to get all element values in an array....
    var values = [];
    Object.each(block.elements, function (element, key) {
          if (key.contains('tc_repairs_22_repeat___quantityused')) {
            //values.push(element.get('value'));
           
            if(element.get('value') > 0) {element.element.disabled=true; }
          }
        
    });
  });
 
You're running into a bug in the bootstrap template when the group layout is set to table. Added groups don't get inserted in the right place in the table and it throws everything off. Maybe one day it will get fixed.

I've had to do the same thing in a form with repeat groups. This code (put in the form_#.js file) does the trick - if the bootstrap template group layout is set to 'list' rather than 'table'. Just replace '480' with your group number and 'fb_products___quantity' with tableName___elementName you want to control.

What this does, if not the first row(s) being added, is set the element in all rows to disabled when the form loads - then enable the element in any new rows added.
Code:
requirejs(['fab/fabrik'], function () {

    if(jQuery('#fb_products___id_0').val()=='')
    {  
        window.startCount = 0;
    }
    else
    {  
        window.startCount = jQuery("fieldset#group480 div.fabrikSubGroup").length;  
        jQuery('input[id^=fb_products___quantity_]').prop('disabled',true);
    }  
  
    Fabrik.addEvent('fabrik.form.elements.added', function (block) {
        var repeatCount = jQuery("fieldset#group480 div.fabrikSubGroup").length;
        if(repeatCount > window.startCount && window.startCount>0){
            var idx = 0;
            while (idx < window.startCount) {
                jQuery('#fb_products___quantity_'+idx).prop('disabled',true);
                idx++;
            }
            while (idx < repeatCount) {          
                jQuery('#fb_products___quantity_'+idx).removeProp('disabled');
                idx++;
            }  
        }
    });  

});
 
Last edited:
Thanks Hugh!
So now this js code should work for navjinder, or as an example for anyone needing to do this in a repeat group using a 'table' layout. (Just replace 'group480' with the correct ID of the group)...
Code:
requirejs(['fab/fabrik'], function () {

    if(jQuery('#tc_repairs_22_repeat___id_0').val()=='')
    {
        window.startCount = 0;
    }
    else
    {
        window.startCount = jQuery("fieldset#group480 table tbody tr.fabrikSubGroup").length;
        jQuery('input[id^=tc_repairs_22_repeat___quantityused_]').prop('disabled',true);
    }

    Fabrik.addEvent('fabrik.form.elements.added', function (block) {
        var repeatCount = jQuery("fieldset#group480 table tbody tr.fabrikSubGroup").length;
        if(repeatCount > window.startCount && window.startCount>0){
            var idx = 0;
            while (idx < window.startCount) {
                jQuery('#tc_repairs_22_repeat___quantityused_'+idx).prop('disabled',true);
                idx++;
            }
            while (idx < repeatCount) {
                jQuery('#tc_repairs_22_repeat___quantityused_'+idx).removeProp('disabled');
                idx++;
            }
        }
    });

});

This should also work for multiple elements in the same row by including a comma separated list of the full element names. e.g.
jQuery('input[id^=tc_repairs_22_repeat___quantityused_]')
would be...
jQuery('input[id^=tc_repairs_22_repeat___stockid_], input[id^=tc_repairs_22_repeat___quantityused_]')
...AND...
jQuery('#tc_repairs_22_repeat___quantityused_' + idx)
would be...
jQuery('#tc_repairs_22_repeat___stockid_' + idx + ', #tc_repairs_22_repeat___quantityused_' + idx)
assuming navjinder also wants to disable changing selection in the 'Part' column.

From navjinder's screen snips, I assume he'd also want to hide the 'RMA' button in new rows. To do that...
Code:
            while (idx < repeatCount) {
                jQuery('#tc_repairs_22_repeat___quantityused_'+idx).removeProp('disabled');
                idx++;
            }
would change to...
Code:
            while (idx < repeatCount) {
                jQuery('#tc_repairs_22_repeat___quantityused_'+idx).removeProp('disabled');
                jQuery('#tc_repairs_22_repeat___rma_'+idx).css('display','none');
                idx++;
            }
Isn't jQuery just wonderful?:)
 
Last edited:
Thanks for the code.

jQuery is cool, but it's just as easy in Mootools. And that's a touchy subject, as J! have decided to deprecate Mootools and no longer even provide a standard distribution, so we're now engaged in rewriting about 50k lines of JS from Moo to jQuery. Hence the jQuery branch on github.

I can understand why, jQuery won the battle for hearts and minds years ago, but for long standing J! components like us, who simply followed the roadmap and the "best practices" at the time ... not much fun.

-- hugh
 
Wonderful just wonderful Thanks a million Hugh and Bauer for the solution it worked perfectly; yes you are right changing it back to list layout rather than table layout did the trick and yes you are right Bauer I also need to disable the part drop down; however, I would like to mention if I use disable property then when I save the form the quantity and stock ids becomes empty. Therefore, I used readonly instead of disable. As per RMA is concerned I need to do the opposite i.e. do not show the RMA button for newly added rows but rather for the saved rows here is my code.

Note: I have also added JS for element delete otherwise it remained readonly. Thanks once again for your solutions. Here is my code

JavaScript:
    if(jQuery('#tc_repairs_22_repeat___id_0').val()=='')
    {
        window.startCount = 0;
    }
    else
    {
        window.startCount = jQuery("fieldset#group22 div.fabrikSubGroup").length;
        jQuery('input[id^=tc_repairs_22_repeat___quantityused_]').prop('readonly',true);
        jQuery('[id^=tc_repairs_22_repeat___stockid_]').prop('readonly',true);
    }
    Fabrik.addEvent('fabrik.form.elements.added', function (block) {
        var repeatCount = jQuery("fieldset#group22 div.fabrikSubGroup").length;
        console.log(repeatCount+' '+window.startCount);
        if(repeatCount > window.startCount && window.startCount>0){
            var idx = 0;
            while (idx < window.startCount) {
                jQuery('#tc_repairs_22_repeat___quantityused_'+idx).prop('readonly',true);
                 jQuery('#tc_repairs_22_repeat___stockid_'+idx).prop('readonly',true);
                idx++;
            }
            while (idx < repeatCount) {       
                jQuery('#tc_repairs_22_repeat___quantityused_'+idx).removeProp('readonly');
                jQuery('#tc_repairs_22_repeat___stockid_'+idx).removeProp('readonly');
                jQuery('#tc_repairs_22_repeat___stockid_'+idx+'-auto-complete').removeProp('readonly');
jQuery('label[for=tc_repairs_22_repeat___check_'+idx+']').hide();
                idx++;
            }
        }
    });
 
    Fabrik.addEvent('fabrik.form.group.delete', function (block) {
        var repeatCount = jQuery("fieldset#group22 div.fabrikSubGroup").length;
        console.log(repeatCount+' '+window.startCount);
        if(repeatCount < window.startCount || repeatCount == window.startCount){
        window.startCount=     repeatCount - 1;     
        }
    });
 

Attachments

  • working_fabrikar.png
    working_fabrikar.png
    41.3 KB · Views: 231
Yes, when you "disable" something in a form, it doesn't get submitted with the form data. That's an HTML thing, not a Fabrik thing.

-- hugh
 
We are in need of some funding.
More details.

Thank you.

Members online

Back
Top