How can I dynamically change the default value for views exposed filter referencing taxonomy terms when the term weight value = 0 - drupal-views

I have an exposed filter in a view is referencing taxonomy terms from specific vocabulary. The operator (screenshot below) allows selecting a term as the default value for that filter. What I want to achieve is to dynamically select the default value when the term weight = 0.
This should allow less privileged roles like Content Contributors to set the default value for the exposed filter by changing the order (weight) of the term without the need to edit the views settings.
I tried to research this and so far, it seems the best way to achieve this is by using (hook_views_pre_build) but I just don't know how.

After extensive search and experiment, this code worked for me:
use Drupal\taxonomy\Entity\Term;
use Drupal\views\ViewExecutable;
/**
* Implements hook_views_pre_build().
*/
function YOUR_MODULE_NAME_views_pre_build(ViewExecutable $view) {
if ($view->id() == 'YOUR_VIEW_ID' && $view->current_display == 'YOUR_DISPLAY_ID') {
// Get the exposed filter for the taxonomy terms.
$filter = $view->display_handler->getHandler('filter', 'YOUR_FILTER_ID');
if ($filter) {
// Query the database for taxonomy terms with a weight of 0.
$query = \Drupal::entityQuery('taxonomy_term');
$query->condition('weight', 0);
$term_ids = $query->execute();
if (!empty($term_ids)) {
// Load the first term found with a weight of 0.
$term = Term::load(array_shift($term_ids));
if ($term) {
// Set the default value for the exposed filter to the term's ID.
$filter->options['value'] = $term->id();
}
}
}
}
}
This code will query the database for taxonomy terms with a weight of 0 when the specified view is pre-built and set the default value for the exposed filter to the ID of the first term it finds. If no terms are found with a weight of 0, it will not change the default value.

Related

ag-grid setModel equivalent of selectValue

Using ag-grid 23.2.1, it looks like our current approach to filtering is on it's way out and listed as deprecated. Reading over the setModel documentation, I don't readily see a way to replace some of our selectValue, selectNothing, etc. usage.
Example 1: we clear the selection and then pick a couple of values on some condition else we select all
let filterInstance = this.gridOptions.api.getFilterInstance('make');
this.cacheFilterModel = this.gridOptions.api.getFilterModel();
if (condition) {
filterInstance.selectNothing();
filterInstance.selectValue('thing1');
filterInstance.selectValue('thing2');
}
else {
filterInstance.selectEverything();
}
filterInstance.applyModel();
this.gridOptions.api.onFilterChanged();
Example 2: we have some filter values in a column toggle-able via checkboxes, which call a method like the below. if one of the values is checked it gets added to the existing filter, if unchecked the value is removed. There could be values already filtered and I don't really see a way to contextually select/unselect values using setModel.
filterExample (make, add) {
let filterInstance = this.gridOptions.api.getFilterInstance('make');
if (add) {
filterInstance.selectValue(make);
}
else {
filterInstance.unselectValue(make);
}
filterInstance.applyModel();
this.gridOptions.api.onFilterChanged();
}
Are there setModel equivalents for these?
I had a similar issue with setColumnFilter where I had to pass a few values. You can use filterInstance.setModel to set these values by passing an array like so:
filterInstance.setModel({ values: ['value1', 'value2'] })
filterInstance.applyModel();
gridOptions.api.onFilterChanged()
here is a link to how to do it from the docs. I found this hard to find on google so providing it here.
https://www.ag-grid.com/javascript-grid-filter-set-api/

How do i poulate a field with a parameter from previous page in a multipage form in gravityforms?

I want to build a multipage from.
The first page asks for first name and last name.
I want to greet the user with his first name in the second page.
The best way to do this is to use Live Merge Tags with Populate Anything:
https://gravitywiz.com/documentation/gravity-forms-populate-anything/#live-merge-tags
If you collected the user's first name in a Name field on page 1, you could great him in the field label for a field on page 2 like so:
Hello, #{Name (First):1.3}
(In this example, the field ID for the Name field is 1. The 3 refers to the first name input of a Name field and will always be 3).
If avoiding another plugin (as useful as that one is), you can use either the pre_submission_filter or pre_submission hooks to do this.
If their name was field 1 and lets say the field you'd like to show is field 2...
// THESE FOUR FILTERS WORK TOGETHER TO PRE-POPULATE ALL SORTS OF STUFF, AND YOU CAN ADD TO THIS AS NECESSARY. MINE IS ABOUT 1500 LINES LONG AND IS USED BY SEVERAL FORMS.
add_filter('gform_pre_render', 'populate_forms');
add_filter('gform_pre_validation', 'populate_forms');
add_filter('gform_pre_submission_filter', 'populate_forms', 10);
add_filter('gform_admin_pre_render', 'populate_forms');
function populate_forms($form) {
$form_id = $form['id'];
$current_form = 2; // pretending the form id you are working on is 2.
$future_form = 10; // imaginary form you'll create later for another purpose.
switch($form_id) {
case $current_form:
$first_name = !empty(rgpost('input_1_3')) ? rgpost('input_1_3') : null; // gets the value they entered into the first-name box of field 1.
foreach ($form['fields'] as &$field) {
if ($field->id === '2') { // Make as many of these as necessary.
if ($first_name) { // make sure there's actually a value provided from field 1.
$field->placeholder = $first_name; // not necessary, just habit since sometimes you'd need to have a placeholder to reliably populate some fields.
$field->defaultValue = $first_name; // this is the piece that will actually fill in the value like you'd expect to see in your question.
}
}
}
break;
//case $future_form: do more stuff.
//break;
}
return $form;
}
That should be a decent start for your functionality plugin where you can populate the current and future forms without much hassle. This can also be done with the gform_field_value hook; I've always found the language a bit clumsy with that one, personally.
The plugin mentioned earlier is definitely neat, but I found myself wanting to rely on that stuff less and less.

Ag-Grid QuickFilter changing programmatically searched columns

I need a quick search filter, where user can select what columns are searched. I didn't succeed to implement this behavior.
I tried this:
this.columns.forEach(column=>{
if (this.globalSearchSelectedColumns.indexOf(column.field)>-1) column.getQuickFilterText = (params)=> params.value.name;
else column.getQuickFilterText = ()=> '';
});
this.grid.api.setColumnDefs(this.columns);
this.grid.api.onFilterChanged();
this.grid.api.resetQuickFilter();
where this.columns is columns defs, this.grid is gridOptions, this.globalSearchSelectedColumns is the selected columns to search for, by column.field.
In order to selectively apply quickFilter form ag-Grid you should rewrite the property getQuickFilterText of the columnDef, by setting it to a function which returns an empty string like so:
First of all, you need to retrieve the column by a key through the gridColumnApi
Then you need to access its colDef
Lastly, all you left to do is to rewrite getQuickFilterText property
Assume, that in your class component you have a method disableFilterCol it can look something like this:
disableFilterCol = () => {
var col = this.gridColumnApi.getColumn("athlete");
var colDef = col.getColDef();
colDef.getQuickFilterText = () => "";
console.log("disable Athlete");
};
Once it called, quickFilter will be applied to your data grid excluding athlete column.
I created live demo for you on ReactJS.
You can improve the way you can select multiple columns that you want to rely on doing filtering.
I suppose that in your case you can try to add set getQuickFilterText = () => "" for either definition of colDef from the very beginning and let the user enabling particular columns, you can set getQuickFilterText property for them to undefined to provide sorting among them.
According to nakhodkiin solution I change my code like this:
this.grid.columnApi.getAllColumns().forEach(column=>{
let def = column.getColDef();
if (this.globalSearchSelectedColumns.indexOf(def.field)>-1) def.getQuickFilterText = undefined;
else def.getQuickFilterText = ()=> '';
});
this.grid.api.onFilterChanged();
And it's working;
I think the problem here lies in setting updated column defs.
Can you try this -
let newColDef= [];
this.columns.forEach(column=>{
if (this.globalSearchSelectedColumns.indexOf(column.field)>-1)
column.getQuickFilterText = (params)=> params.value.name;
else column.getQuickFilterText = ()=> '';
newColDef.push(column);
});
this.grid.api.setColumnDefs(newColDef);
this.grid.api.onFilterChanged();
this.grid.api.resetQuickFilter();
this.grid.api.refreshHeader();
Ag-grid updated its approach of detecting column changes since v19.1
More details here
As per doc -->
When new columns are set, the grid will compare with current columns and work out which > columns are old (to be removed), new (new
columns created) or kept (columns that remain will keep their state
including position, filter and sort).
Comparison of column definitions is done on 1) object reference comparison and 2)
column ID eg colDef.colId. If either the object
reference matches, or the column ID matches, then the grid treats the
columns as the same column.
Ag-grid team is also actively working on fixing this issue for v20.1. You can track it on github

Fetch all the values of specific property in aem using queryBuilder

I am having scenario in which i want to fetch all the values of a property under a specific path in AEM using QueryBuilder api.
This property can have single or multivalued.
Any help will be appreciated!!
Example that can help you. is below as it is just for illustration written in simple JSP scriptlets
<%
Iterator<Resource> iter = resourceResolver.findResources("/jcr:root/content/geometrixx-outdoors//element(*, nt:unstructured)[(#imageRotate = '0' or #imageRotate = '1')]","xpath");
while (iter.hasNext()) {
Resource child = iter.next();
out.println("</br>"+child.getPath());
Node node = child.adaptTo(Node.class);
Property nProp = node.getProperty("imageRotate");
if(nProp.isMultiple()) // This condition checks for properties whose type is String[](String array)
{
Value[] values = nProp.getValues();
out.println(" :: This is a multi valued property ::");
for (Value v : values) {
out.println("</br>"+"Property Name = "+nProp.getName()+" ; Property Value= "+v.getString());
}
}
else if(!nProp.getDefinition().isMultiple()){
out.println("</br>"+"Property Name = "+nProp.getName()+" ; Property Value= "+nProp.getString());
}
}
%>
Here i have used the Iterator<Resource> iter = resourceResolver.findResources(query,"xpath"); which can give you the query results which matches the imageRotate property under /content/geometrixx-outdoors/ path which consists combination of single and multivalued as shown in below screenshot.
There is no direct way to fetch the properties using query builder api. I would suggest you to create a servlet resource, which requires a path and property name.
Fetch the jcr node using the given path via QueryBuilder. Then, you need to loop through the results to check the property of the nodes. You can access the multiple property values, once you have a node.

Richfaces 4 dynamic select options when user type

I am using rich faces select component.
I want dynamic values when user manually type some thing in the select component.
<rich:select enableManualInput="true" defaultLabel="start typing for select" value="#{supplierSearchBean.userInput}">
<a4j:ajax event="keyup" execute="#this" listener="#{supplierSearchBean.userInputChange}"/>
<f:selectItems value="#{supplierSearchBean.selectOptions}" />
</rich:select>
Java code as follows
public void userInputChange(ActionEvent ae){
Map map = ae.getComponent().getAttributes();
System.out.println(map.toString());
}
public void setUserInput(String userInput) {
System.out.println("userINput = " + userInput);
this.userInput = userInput;
}
Here i found 2 issues
1st: setUserINput always print empty string when user type value
2nd: listener method never get call.
any help ?
The problem is most probably that there is no selected value while the user types, and this component restricts the allowed values to the specified select items. A partial input is thus not valid and cannot be bound to your bean.
I think you could get the expected behavior if you use a rich:autocomplete instead. However, if you want to restrict the allowed values, maybe you can keep your rich:select and listen for the selectitem event.
Override getItems function in richfaces-utils.js file in richfaces-core-impl-4.0.0.Final.jar under richfaces-core-impl-4.0.0.Final\META-INF\resources folder.
Change the condition of pushing items to be
if(p != -1)
instead of
if(p == 0)
This should fix the issue.