Support

Account

Home Forums ACF PRO Dynamically populate select field AND data attributes? Reply To: Dynamically populate select field AND data attributes?

  • Ok, I’ve solved this crudely by putting the #SEP# separater and cost number in the label not the value field of the <option> tag. This way the label will remain unique unless changed and a change to the price will not effect which option has been preselected.

    Here’s the amended code:

    function acf_load_product_type_options($field) {
    	$field['choices'] = array();
    	if (have_rows('type_of_product', 'option')) :
    		while (have_rows('type_of_product', 'option')) : the_row();
    			$value = get_sub_field('price');
    			$label = get_sub_field('product_type');
    			$field['choices'][$label] = $label . '#SEP#' . $value;
    		endwhile;
    	endif;
    	return $field;
    }
    add_filter('acf/load_field/name=product_picker', 'acf_load_product_type_options');

    Then I use jQuery once the field has loaded to run through all select option fields on a page. If they have the #SEP# seperator in the label then I take the cost value and create a data attribute on the <option> tag:

    // ACF Select Dropdowns set up. Convert select option labels to data attributes
    	
    	$('.acf-field-select select option').each(function() {
    		var optionLabel = $(this).text();
    		// If select field has a label containing '#SEP#' string then process
    		if (optionLabel.indexOf('#SEP#') >= 0) {
    			var labelArray = optionLabel.split('#SEP#');
    			// Set 'cost-value' data attribute on <option> tag
    			var costValue = parseFloat(labelArray[1]).toFixed(2);
    			$(this).data('cost-value', costValue);
    			// Rewrite option label to remove '#SEP#' and cost figure
    			var optionDescriptionText = labelArray[0];
    			$(this).text(optionDescriptionText);
    		}
    	});

    That’s the set up. There is probably a better way to do this with PHP before the select field has been drawn. This way does show a flash of the ‘#SEP#’ and cost value in the actual select dropdown on the screen. It also seems to run twice for each field.

    Finally when a user changes the select dropdown we take the ‘cost’ value from that option’s new data attribute and use it to populate the next box:

    // ACF Form Fields Dynamically populated cost elements
    	
    	$('body').on('change', '.acf-field-select select', function() {
    		// If manually changed select dropdown has a 'cost-value' data attribute
    		if (typeof $(this).find('option:selected').data('cost-value') !== 'undefined') {
    			// Populate next box with cost value
    			var costValue = $(this).find('option:selected').data('cost-value');
    			$(this).closest('.acf-field-select').next().find('.acf-input input[type=number]').val(costValue);
    		}
    	});

    If somebody does know a safer way of doing this, maybe being able to add the data attributes to each option before the page is ‘ready’, then that would be great?

    Or suggest something else that should be triggering the data attribute creation apart from document ready to avoid what looks like duplication?

    Thanks!