ProcessWire - Dynamic Backend Fields

Aus Wikizone
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

How To populate or show fields in backend depending on selection of other fields ?

Field Dependencies in ProcessWire[Bearbeiten]

https://processwire.com/docs/fields/dependencies/

Show If und Required If[Bearbeiten]

Show if Dependency[Bearbeiten]

Zeige ein Feld nur dann im Backend an, wenn eine Bedingung erfüllt ist.

Wo stellt man Show if ein ?[Bearbeiten]

1. Auf Feldebene

In den Feldeinstellungen (auch innerhalb eines Templates) unter Visibility / Sichtbarkeit.

2. Über die API auf einem beliebigen Inputfield Objekt oder Module

$inputfield->showIf = "field=value";

3. Über Module (z.B. im Formbuilder)

Require if[Bearbeiten]

Benötigt wenn - funktioniert ähnlich wie show if. Option im Backend bei den Feldeinstellungen wenn man Required bei einem Feld anhakt.

API Zugriff auf require if[Bearbeiten]

$inputfield->required = 1; // must be set
$inputfield->requiredIf = "field=value";

Selectors[Bearbeiten]

Selector string format

field=value

"field" is the name of the field you want to check, "=" is the operator you want to use for comparison, and "value" is the value you want to compare.

  • multiple conditions by separating each field=value condition with a comma, i.e.
fullname!=, items>5

Allowed operators

=   equal
!=  not equal
>   greater than
<   less than
>=  greater than or equal
<=  less than or equal
%=  contains phrase
*=  contains phrase (same as above) 

Beispiele:

categories.count>0, categories.count<3 // one or two categories selected
categories.count=0 // no categorie selected
first_name!=, last_name=
categories=1234, categories.count=1 // Nützlich bei Page Reference
checkbox=1
checkbox=0

Limitations[Bearbeiten]

OR geht nur im Selektor:

Populate Multiple Select Field depending on Single Select Field[Bearbeiten]

Ungetestet aus: https://processwire.com/talk/topic/17960-dependent-selects/

var initChildSelect = function() {

    // THE "PARENT" FIELD
    var thisID         = $(this).attr('id');
    var repeaterID     = thisID.split('_repeater')[1]; // if in repeater?
    var optID         = parseInt($(this).val()); // the selected option


    // THE "CHILD/DEPENDENT" FIELD
    childWorksSelect = $('select[name^="part_select_repeater'+repeaterID+'"]');
    var allOptions = $(childWorksSelect.children()).clone();
    var validOptions = allOptions.filter(function(){
        return $(this).data('parent') == optID;
    });
    childWorksSelect.html(validOptions);

    var options = {};
    if(!optID) {
        var options = {'placeholder': 'No Work Selected'}
    }

    if(optID && !validOptions.length) {
        var options = {'placeholder': 'No Parts For The Selected Work'}
    }

    childWorksSelect.selectize(options);

    // DEAL WITH CHANGES TO THE PARENT FIELD
    $(this).change(function() {
        var optID = parseInt($(this).val());
        var newOptions = allOptions.filter(function(){
            return $(this).data('parent') == optID;
        });
        childWorksSelect[0].selectize.destroy();

        // Re-init the select
        childWorksSelect = $('select[name^="part_select_repeater'+repeaterID+'"]');
         childWorksSelect.html(newOptions);

         var options = {};

        if(!optID) {
            var options = {'placeholder': 'No Work Selected'}
        }
         if(optID && !newOptions.length) {
             var options = {'placeholder': 'No Parts For The Selected Work'}
         }

        childWorksSelect.selectize(options);
        childWorksSelect[0].selectize.open();
    });

}

$(function(){
    $('select[name^="work_select_single"]').each(initChildSelect);

    $(document).on('reloaded opened repeateradd wiretabclick', '.InputfieldPage', function() {
        $(this).find('select[name^="work_select_single"]').each(initChildSelect);
    });

});
function initInputfieldPage($this) {
	
	$this.find("p.InputfieldPageAddButton a").click(function() {
		var $input = $(this).parent('p').next('.InputfieldPageAddItems');
		if($input.is(":visible")) $input.slideUp('fast').find(":input").val('');
		else $input.slideDown('fast').parents('.ui-widget-content').slice(0,1).effect('highlight', {}, 500)
		return false;
	});

	// support for dependent selects
	$this.find(".findPagesSelector").each(function() {
		var $repeater = $this.parents('.InputfieldRepeaterItem');
		var $t = $(this);
		var selector = $t.val();
		// if there is no "=page." present in the selector, then this can't be a dependent select
		if(selector.indexOf('=page.') == -1) return;
		var labelFieldName = $t.attr('data-label');
		var formatName = $t.attr('data-formatname');
		if(!labelFieldName.length) $labelFieldName = 'name';
		// if it doesn't contain a dynamic request from the page, then stop now

		var $wrap = $t.parents(".InputfieldPage");
		var $select = $('select#' + $wrap.attr('id').replace(/^wrap_/, ''));

		if($select.length < 1) return;

		var parts = selector.match(/(=page.[_a-zA-Z0-9]+)/g);

		for(var n = 0; n < parts.length; n++) {

			var part = parts[n];
			var name = part.replace('=page.', '');
			var $inputfield = $repeater.length === 0 ? $('#Inputfield_' + name) : $('#Inputfield_' + name + "_repeater" + $repeater.data('page'));
			if($inputfield.length < 1) return;

			// monitor changes to the dependency field
			$inputfield.off('change');
			$inputfield.on('change', function() {
				var s = selector;
				var v = $inputfield.val();
				if(v == null) {
					// no values selected
					$select.children().remove();
					$select.change();
					return;
				}
				v = v.toString();
				v = v.replace(/,/g, '|'); // if multi-value field, convert commas to pipes
				s = s.replace(part, '=' + v);
				s = s.replace(/,\s*/g, '&');
				if(s.indexOf('_LPID')) s = s.replace(/_LPID[0-9]+/g, '');
				var url = ProcessWire.config.urls.admin + 'page/search/for?' + s + '&limit=999&get=' + labelFieldName;
				if(formatName.length) url += '&format_name=' + formatName;
				$.getJSON(url, {}, function(data) {
					//$select.children().remove();
					$select.children().addClass('option-tbd'); // mark existing options as to-be-deleted
					for(n = 0; n < data.matches.length; n++) {
						var page = data.matches[n];
						// first see if we can find the existing option already present
						var $option = $select.children("[value=" + page.id + "]");
						// if that option isn't already there, then make a new one
						var selected = false;
						if($option.size() > 0) selected = $option.is(":checked");
						$option.remove();
						var label = '';
						if(formatName.length) label = page[formatName];
						if(!label.length) label = page[labelFieldName];
						if(!label.length) label = page.name;
						var $option = $("<option value='" + page.id + "'>" + label + "</option>");
						if(selected) $option.attr('selected', 'selected');
						// add the <option> to the <select>
						$select.append($option);
					}
					$blankOption = $("<option value=''></option>");
					$select.prepend($blankOption);
					$select.children(".option-tbd").remove();
					$select.change();
				});
			});
		}
	});
}


$(document).ready(function() {
	$(".InputfieldPage").each(function() {
		initInputfieldPage($(this));
	});
	$(document).on("reloaded", ".InputfieldPage", function() {
		initInputfieldPage($(this));
	});
});