Yii2 Autocomplete Widget Categories - jquery-ui

JQuery's Autocomplete supports categories in the autocomplete results. Like in the link below (just type the letter 'a'):
https://jqueryui.com/resources/demos/autocomplete/categories.html
Yii2's jQuery Autocomplete widget has a source parameter that can take in an array for the results of the Autocomplete. But when I give it a multi-dimensional array, trying to get categories like the link above, it breaks the Autocomplete. See below:
AutoComplete::widget([
'name' => 'search_terms',
'options' => [
'style' => 'width:100%;',
],
'clientOptions' => [
'source' => ['NA' => ['USA', 'CAN'], 'EUR' => ['RUS', 'SPN']],
],
])
How do I get categories working in Yii2's Autocomplete widget?

This type of widgets is just a wrapper of Javascript plugin allowing you to register it using PHP code (configure properties using PHP arrays instead of Javascript objects, etc.). If you investigate the sources of AutoComplete widget and parent classes, you will not find any special processing of source property. That means you need to follow jQuery UI plugin docs, click the "view source" link here to show code. JS part looks like this:
<script>
$( function() {
$.widget( "custom.catcomplete", $.ui.autocomplete, {
_create: function() {
this._super();
this.widget().menu( "option", "items", "> :not(.ui-autocomplete-category)" );
},
_renderMenu: function( ul, items ) {
var that = this,
currentCategory = "";
$.each( items, function( index, item ) {
var li;
if ( item.category != currentCategory ) {
ul.append( "<li class='ui-autocomplete-category'>" + item.category + "</li>" );
currentCategory = item.category;
}
li = that._renderItemData( ul, item );
if ( item.category ) {
li.attr( "aria-label", item.category + " : " + item.label );
}
});
}
});
var data = [
{ label: "anders", category: "" },
{ label: "andreas", category: "" },
{ label: "antal", category: "" },
{ label: "annhhx10", category: "Products" },
{ label: "annk K12", category: "Products" },
{ label: "annttop C13", category: "Products" },
{ label: "anders andersson", category: "People" },
{ label: "andreas andersson", category: "People" },
{ label: "andreas johnson", category: "People" }
];
$( "#search" ).catcomplete({
delay: 0,
source: data
});
} );
</script>
As you can see, you are passing categories wrong. Try this instead:
'source' => [
['label' => 'USA', 'category' => 'NA'],
['label' => 'CAN', 'category' => 'NA'],
['label' => 'RUS', 'category' => 'EUR'],
['label' => 'RUS', 'category' => 'SPN'],
],
Also for this case maybe you need to include additional JS (above plugin registration) to completely reproduce example.

Related

nested dataIndex in Table of Ant Design

this is my code below
const columns = [
{
key: '1',
title: 'id',
dataIndex: 'id'
},
{
key: '2',
title: 'status',
dataIndex: 'status',
render: (text) => <a> {text} </a>
},
];
I wanna display data ( text/id ) like below code
const columns = [
{
key: '1',
title: 'id',
dataIndex: 'id'
},
{
key: '2',
title: 'status',
dataIndex: ['status', 'id'],
render: (text) => <a> {text} / {id} </a>
},
];
I tried to like this samples
1. dataIndex: ['status', 'id']
2. dataIndex: 'status.id'
but that doesn`t work. (version 4.14.0)
how can I display like that? please reply here. thanks.
I'll answer assuming what you pass to the dataSource is an array of objects which looks like below.
interface DataModel {
id: number;
status: string;
}
If so, you can use the second parameter in the render method which will have the record. Hence record.id will give you the id.
const columns = [
{
key: '1',
title: 'id',
dataIndex: 'id'
},
{
key: '2',
title: 'status',
dataIndex: ['status'],
render: (text: any, record: any) => <a> {text} / {record.id} </a>
},
];
try this solution
{
title: 'Name',
dataIndex: 'address',
key: 'name',
render: ({ city, street }) => (
<Typography>{`${city} ${street}`}</Typography>
),
},
try this
{
title: "Task",
dataIndex: ["task","name"]
},

filter the ui grid value based on the row check box is selected

This is the ui grid code( minimal)
//js file
vm.gridOptions1 = {
enableColumnResizing: true,
enableAutoResizing: false,
columnDefs: [
{
field: 'createdDate',
displayName: 'Created Date',
type: 'date',
cellFilter: 'date:"dd-MM-yyyy"',
enableHiding: false, headerTooltip: 'Created Date'
},{
name: 'Refer',
displayName: 'Refer', enableSorting: false, headerTooltip: 'Refer',
cellTemplate: '<input type="checkbox" ng-model="row.entity.isReferred" />'
}
]});
On click of this byutton I need to filter, get only rows which check box is selected(isReferred = true)
//html file
<button type="button" class="btn btn-primary-joli " ng-click="srchctrl.send">Send</button>
This is the file trying to get the filtered list based on the redeffered check box value, but its not working.
//JS file
vm.send = function () {
if (vm.gridApi.selection.data != null && vm.gridApi.selection.data != undefined) {
vm.referredList = filterFilter(vm.gridApi.selection.data, {
isReferred: true
});
console.log("referredList :"+JSON.stringify(referredList));
}
};
How can I get all the value ticked. I don't want to invoke method on each click event on check box.
I think the easiest way to achieve this is by using the gridApi.grid.registerRowsProcessor function. I have adapted a Plunker to show what I mean:
http://plnkr.co/edit/lyXcb90yQ0ErUJnSH7yF
Apps.js:
var app = angular.module('plunker', ['ui.grid']);
app.controller('MainCtrl', ['$scope', 'uiGridConstants', function($scope, uiGridConstants) {
$scope.gridOptions = {
columnDefs: [
{field: 'col1', displayName: 'Column 1', width: 175},
{field: 'col2', displayName: 'isReferred', width: '*'}
],
data: [
{ col1: "Hello 1",col2: true},
{ col1: "Hello 2", col2: false},
{ col1: "Hello 3", col2: true},
{ col1: "Hello 4", col2: false},
{ col1: "Hello 5", col2: true}
],
enableFiltering: true,
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
}
};
$scope.Filter = Filter;
$scope.ShowAll = ShowAll;
function ShowAll() {
$scope.gridApi.grid.removeRowsProcessor(myFilter);
$scope.gridApi.core.queueGridRefresh();
}
function Filter() {
$scope.gridApi.grid.registerRowsProcessor(myFilter, 150);
$scope.gridApi.core.queueGridRefresh();
}
function myFilter(renderableRows) {
renderableRows.forEach( function(row) {
row.visible = row.entity.col2;
});
return renderableRows;
}
}]);
Clicking the Filter button will register the myFilter RowsProcessor, which will iterate through all rows to alter the visible attribute.
Clicking the ShowAll button will remove the RowsProcessor, thus showing all previously hidden rows again.
Whenever an isReferred value changes, the filter will cause the grid to automatically update this change.

antd Table with switch component

Is it possible to get row information by switching the switch in ant design table?
https://codesandbox.io/s/mmvrwy2jkp
Yes, the second argument of the render function is the record.
you can do this
{
title: 'switch',
dataIndex: 'age',
key: 'age',
render: (e, record) => (< Switch onChange={() => handleSwitchChange(record)} defaultChecked={e} />)
}
This is how I dealed with the switch component on each row item when using Ant design. Maybe this could give you some hints.
Table Columns
const COLUMN =
{
title: 'Status',
key: 'status',
dataIndex: 'status',
// status is the data from api
// index is the table index which could be used to get corresponding data
render: (status, record, index) => {
const onToggle = (checked) => {
status = checked;
onActiveUser(index, status);
};
return (
<Space>
<Switch defaultChecked={status} onChange={onToggle} />
</Space>
);
},
},
const onActiveUser = (index, status) => {
axios.patch({ id: users[index].id }, { is_active: status })
.then((response) => {
console.log(response);
})
.catch(() => {
console.log('Failed!');
});
};

Ignore ad groups belonging to REMOVED campaigns with Adwords API

I am working on an adwords script to grab a list of all AD Groups which have a specified label, and are in the status PAUSED. My code is working, however I am running into one issue, which is that I am getting ad groups which belong to campaigns that have been REMOVED.
Is there any way to filter on campaign status as part of the adgroup service?
ad_group_service = client.GetService('AdGroupService', version='v201806')
selector = {
'fields': ['Id', 'Name', 'Status', 'Labels'],
'predicates': [
{
'field': 'Labels',
'operator': 'EQUALS',
'values': 'MY LABEL'
},
{
'field': 'Status',
'operator': 'EQUALS',
'values': 'PAUSED'
}
],
'paging': {
'startIndex': str(0),
'numberResults': str(9999)
}
}
adgroups = ad_group_service.get(selector)
Through testing, I found out there is an undocumented field 'CampaignStatus' that can be used to achieve this.
selector = {
'fields': ['Id', 'Name', 'Status', 'Labels'],
'predicates': [
{
'field': 'Labels',
'operator': 'EQUALS',
'values': 'MY LABEL'
},
{
'field': 'Status',
'operator': 'EQUALS',
'values': 'PAUSED'
},
{
'field': 'CampaignStatus',
'operator': 'NOT_EQUALS',
'values': 'REMOVED'
}
],
'paging': {
'startIndex': str(0),
'numberResults': str(9999)
}
}

Yii2 - input search with auto-complete

I am using default Yii2 library for auto-complete. How can I make it, so it is reading values from DB while user is typing?
This is code I have so far, but query is done when the page is created:
echo AutoComplete::widget([
'name' => 'tradeName',
'model' => TradeNames::find()->select('name')->all(),
'options' => [
'class' => 'form-control'
],
'clientOptions' => [
'source' => array_column(TradeNames::find()->select('name')->asArray()->all(), 'name'),
},
],
]);
I followed this advice
jqueryui.com/autocomplete/#multiple and have written next code
<div id="autocomplete" class="ui-widget">
<?= \yii\jui\AutoComplete::widget([
'attribute' => 'attribute',
'name' => 'tradeName',
'clientOptions' => [
'source' => \Yii::$container->get('JsExpression',['function(request, response) {
response( $.ui.autocomplete.filter( window.dataAsArray, extractLast( request.term ) ) );
}']),
'select' => \Yii::$container->get('JsExpression',['function(event, ui) {
var terms = split( this.value );
terms.pop();
terms.push( ui.item.value );
terms.push( "" );
this.value = terms.join( ", " );
return false;
}']),
'focus' => \Yii::$container->get('JsExpression',['function() {
return false;
}']),
]
]) ?>
</div>
<script>
window.dataAsArray = ['item1', 'item2', 'item3'];
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$(document).ready( function() {
$('#autocomplete').on('keydown', function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB && $( this ).autocomplete( "instance" ).menu.active ) {
event.preventDefault();
}
});
});
</script>
maybe it help to someone
try this
use yii\jui\AutoComplete;
use yii\web\JsExpression;
<?php
$data = TradeNames::find()
->select(['name as value', 'name as label','id as id'])
->asArray()
->all();
echo 'Trade Names' .'<br>';
echo AutoComplete::widget([
'name' => 'tradeName',
'id' => 'trade_name',
'clientOptions' => [
'source' => $data,
// 'minLength'=>'3',
'autoFill'=>true,
'select' => new JsExpression("function( event, ui ) {
$('#memberssearch-family_name_id').val(ui.item.id);//#memberssearch-family_name_id is the id of hiddenInput.
}")],
]);
?>
<?= Html::activeHiddenInput($model, 'tradeName')?>

Resources