ProcessWire - Dynamic Backend Fields: Unterschied zwischen den Versionen
| (Eine dazwischenliegende Version desselben Benutzers wird nicht angezeigt) | |||
| Zeile 39: | Zeile 39: | ||
Beispiele: | Beispiele: | ||
| − | categories.count>0, categories.count<3 | + | categories.count>0, categories.count<3 // one or two categories selected |
| − | categories.count=0 | + | categories.count=0 // no categorie selected |
first_name!='', last_name='' | first_name!='', last_name='' | ||
categories=1234, categories.count=1 // Nützlich bei Page Reference | categories=1234, categories.count=1 // Nützlich bei Page Reference | ||
checkbox=1 | checkbox=1 | ||
checkbox=0 | checkbox=0 | ||
| + | === Limitations === | ||
| + | OR geht nur im Selektor: | ||
== Populate Multiple Select Field depending on Single Select Field == | == Populate Multiple Select Field depending on Single Select Field == | ||
| + | Ungetestet aus: https://processwire.com/talk/topic/17960-dependent-selects/ | ||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript"> | ||
var initChildSelect = function() { | var initChildSelect = function() { | ||
| Zeile 112: | Zeile 115: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<syntaxhighlight lang="javascript"> | <syntaxhighlight lang="javascript"> | ||
| + | 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)); | ||
| + | }); | ||
| + | }); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Aktuelle Version vom 15. Dezember 2019, 18:30 Uhr
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));
});
});