Page 1 of 1

Change Object Label Text based on value in table

Posted: Tue Mar 22, 2022 5:18 pm
by mvdm
Hi all,

I'm quite new to nuBuilder, but picking it up fast. Quite easy to pickup, I have to say ;)
I just built a form with a multi-tier dependent drop down (at least how you would call it in Excel / Access) with select objects, I hope to record an instruction video how to achieve this soon as it took me a bit of tinkering to get it working correctly, maybe it's worth sharing?

I would like to know if there is an easy way to change the select object's label based on another object's value?
In each of my tier tables, I have stored the consequent tier label text under a unique ID. So if you select a unique ID, I want the consequent select object's label to get it's text from a table according to the selected unique ID.

I know its probably a strange request, but thanks in advance.

Re: Change Object Label Text based on value in table

Posted: Wed Mar 23, 2022 7:31 am
by kev1n
Hi,
If you use nuRefreshSelectObject() to refresh the select objects, you can make use of the callback function nuSelectObjectRefreshed(). It is triggered after the select object has been refreshed.

In there, you can call a procedure which retrieves the select's label from the db and by using nuJavascriptCallback(), you can update it with JavaScript.

Code: Select all

function nuSelectObjectRefreshed(formId, selectId, count) {
   // run procedure
}
Let me know if something is unclear.

PS: We'd love to see your video :D

Re: Change Object Label Text based on value in table

Posted: Mon Mar 28, 2022 3:39 pm
by mvdm
Dear kev1n,

Thank you for the response, I am actually already making use of nuSelectObjectRefreshed to hide / unhide the consequent select object's.
I am almost ready with the video, I was hoping to include the label part in there as an extra bonus because it makes it more responsive and I already have to have code in there to make it run. BTW, where can I send the video to? I know you guys already have your own YouTube channel.

Could you please let me know if there are any nuBuilder recommended JS procedures to get the value from the table?
I know I can set the label text via

Code: Select all

nuSetLabelText('t2_id', strLabelFromDB);

Is there a nuBuilder js method for reading the relevant value from tblTier1.t2_label?
I'm guessing for this I will have to run the SQL from js.

Code: Select all

SELECT
   tblTier1_id,
   tblTier1.t2_label
FROM
   tblTier1
WHERE
    ((tblTier1_id = '#t1_id#'))
But is there an existing connection to the DB or do I have to create a new mysql connection?

Thanks in advance!

Re: Change Object Label Text based on value in table

Posted: Mon Mar 28, 2022 3:55 pm
by kev1n
Use nuRunQuery() to retrieve data from a table. There's no need to create a separate db connection.

Upload the video to a service like this and share the link.

Re: Change Object Label Text based on value in table

Posted: Mon Mar 28, 2022 4:43 pm
by kev1n
Another idea is to select both the caption + label in the select object and separate them with a delimiter (e.g. |)

Code: Select all

SELECT
   id,
   CONCAT(caption,'|', label);
FROM
   your_table
In the form's custom code, replace the caption|label with the caption and attach the label to data()

Code: Select all

$('#'your_select_id').find('option').each(function() {

	var txt = $(this).text().split('|');

	$(this).text(txt[0]).data({
		label: txt[1],
	})

});
In the select's custom code (onchange), retrieve the label with

Code: Select all

$(this).find(":selected").data().label;

Re: Change Object Label Text based on value in table

Posted: Mon Mar 28, 2022 5:26 pm
by mvdm
Thank you for both, I didn't get to the PHP section yet, but I really like your second suggestion.
I am going to try both.

Re: Change Object Label Text based on value in table

Posted: Tue Apr 12, 2022 8:37 pm
by mvdm
Hi Kev1n,

Thanks again for the help, I managed get the depended dropdown form to work exactly as desired with the updating labels. :thumb:
I think at the end to CONCAT the Caption|Label and dealing with it through JS was an elegant and easily scalable solution, many thanks for pointing that out.

I ended up having the following under the form's Custom Code > Edit:

Code: Select all

//Replace the Caption|Label with the caption and attach the Label to data()
function splitSelectLabel(id){
   $('#'+id).find('option').each(function() {
      var txt = $(this).text().split('|');
	  $(this).text(txt[0]).data({
	     label: txt[1],
      });
   });
}

//Sets a Select Object tier label based on the label saved in the previous Select Object tier's data
function setTierLabel(prevTierId, curTierId = undefined){
   if(curTierId === undefined) { // Check if curTierId is undefined and then calculates it
      //Split the selectId string and calculate the previous / next tier IDs 
      var NumTier = prevTierId.match(/\d/g);
      NumTier.join("");
      curTierId = 't' + (Number(NumTier) + 1) + '_id';
   }
  // Check if the previous tier ID object has a label defined under its data
  let objTierIdData = $('#'+prevTierId).find(":selected").data();
  if(objTierIdData.hasOwnProperty('label')){
      //Set the next Tier ID Select's label 
      nuSetLabelText(curTierId, objTierIdData.label);
  }
}

//On start loop through all the Select Object ids and check if they have a value (Populated on Edit)
//Then hide / unhide all Select objects, split Caption|Label, and assign Tier labels
var arrTierSelectObjects = ['t1_id','t2_id','t3_id','t4_id','t5_id','t6_id'];
arrTierSelectObjects.forEach(function (item) {
    if(nuGetValue(item) == ""){
      nuHide(item);
    }else{
      nuShow(item);
      splitSelectLabel(item);
      setTierLabel(item);
    }
});

//On Select Object Refresh
function nuSelectObjectRefreshed(formId, selectId, count) {
  //Split the selectId string and calculate the previous tierId
  var NumTier = selectId.match(/\d/g);
  NumTier.join("");
  var prevTierId = 't' + (Number(NumTier) - 1) + '_id';

  //Check if there is less than one element in the select or if the previous tier ID is blank
  //Then hide / unhide the Refreshed tierId Select Object, split Caption|Label, and assign Tier labels
  if ( (count < 1) || (nuGetValue(prevTierId) == "") ) {
     nuHide(selectId);
  } else {
    nuShow(selectId);
    splitSelectLabel(selectId);
    setTierLabel(prevTierId,selectId);
  }
}
Under each Select Object (t2_id~t5_id)> Select I have the following SQL based on the previous Select's value:

Code: Select all

SELECT
 tblT2.tblT2_id,
    CONCAT(COALESCE(tblT2.t2_name,''),'|',COALESCE(tblT2.t3_label,''))
FROM
    tblT2
WHERE
    ((tblT2.t1_id = '#t1_id#'))
I ended up having to use COALESCE as well because CONCAT inserts "null" in the Select Object when a field in the table is empty.

Under each Select Object (t2_id~t5_id)>Custom Code I have a onchange routine refreshing each of the consequent Select objects:

Code: Select all

nuRefreshSelectObject('t3_id');
nuRefreshSelectObject('t4_id');
nuRefreshSelectObject('t5_id');
nuRefreshSelectObject('t6_id');