Yii2 DropDownList Onchange change Autocomplete Widget "source" attribute? - php

I have already tried this : yii2 dependent autocomplete widget
but i don't know why it's not working.
here my html with script:
<?= $form->field($model, 'lbt_holder_type')->dropDownList(['prompt' => '--- Select Holder Type ---', 'S' => 'Student', 'E' => 'Employee'],
['onChange' => 'JS: var value = (this.value);
if(value == "S"){$(#libraryborrowtransaction-name).autoComplete({source: '. $s_data.');}
if(value == "E"){$(#libraryborrowtransaction-name).autoComplete({source: '. $e_data.');}
'])?>
Autocomplete:
<?= $form->field($model, 'name')->widget(\yii\jui\AutoComplete::classname(), [
'options' => ['class' => 'form-control', 'placeholder' => 'Enter Name/ID'],
'clientOptions' => [
'source' => $s_data,
'autoFill' => true,
'minLength' => '1',
'select' => new yii\web\JsExpression("function( event, ui ) {
$('#libraryborrowtransaction-lbt_holder_id').val(ui.item.id);
}")
],
])?>
i want to change autocomplete source according to dropdownlist value, if S then load $s_data else load $e_data.
Any help with this. Thanks.
Here's my data,
$s_data = (new \yii\db\Query())
->select(["CONCAT(stu_unique_id,' - ',stu_first_name,' ',stu_last_name) as value","CONCAT(stu_unique_id,' - ',stu_first_name,' ',stu_last_name) as label","s_info.stu_info_stu_master_id as id"])
->from('stu_master stu')
->join('join','stu_info s_info','s_info.stu_info_id = stu_master_stu_info_id')
->where('is_status = 0')
->all();
and,
$e_data = (new \yii\db\Query())
->select(["CONCAT(emp_unique_id, ' - ',emp_first_name,' ',emp_last_name) as value","info.emp_info_emp_master_id as id"])
->from('emp_master emp')
->join('join', 'emp_info info', 'info.emp_info_id = emp_info_emp_master_id')
->where('is_status = 0')
->all();

Well, I've added your code snippets to my test yii2 environment to test what's wrong. So there are some problems with your code:
[
'onChange' =>
'JS: var value = (this.value);
if(value == "S"){$(#libraryborrowtransaction-name).
autoComplete({source: '. $s_data.');}
if(value == "E"){$(#libraryborrowtransaction-name).
autoComplete({source: '. $e_data.');}
']
First of all I noticed what yii apply some escaping for quotation mark symbols for your "S" and "E", and your code in browser looks like "S".
Next, jui autocomplete plugin adds a property to jquery prototype with name "autocomplete" but not "autoComplete". As for as js is case sensitive, this two names looks different for it.
So my solution was to move all js from onchange property to separate js script, as it shown below (for testing purposes you can add it right in your yii view file where you use code provided in your question)
<script>
function holderTypeChangeHandler(ev) {
var value = (this.value);
if(value == 'S'){
$('#libraryborrowtransaction-name').autocomplete({source: ' . $s_data . '});
}
if(value == 'E'){
$('#libraryborrowtransaction-name').autocomplete({source: ' . $e_data . '});
}
}
window.onload = function(){
$('#libraryborrowtransaction-lbt_holder_type').on('change', holderTypeChangeHandler);
};
</script>
And paste name of this new event handler to your dropdownList's onchange property like this:
['onChange' => 'holderTypeChangeHandler']
UPDATE: ---------------------
Since Yii2 Autocomplete based on JQuery UI autocomplete widget and Yii2 Autocomplete clientOptions contains settings for JUI autocomplete widget, then we can refer to JUI API docs for explanation of the source option. As you can see, this option can be a string (in this case it used as URI to JSON data), a function or an js array of data or js array of objects.
In your question you are using \yii\db\Query to fetch some data from db with help of method all(), which returns an array of data. So finally you need to convert the array of data which you get with \yii\db\Query->all to js array of objects. To do it, use php json functions, particulary for your case you need to use json_encode() function:
// Let's say this is a result of your query to db with use of `\yii\db\Query->...->all();`
$some_array = [
[
"value" => "Val 1",
"label" => "Label 1",
"id" => 1
],
[
"value" => "Val 2",
"label" => "Label 2",
"id" => 2
]
]
// Just convert it to json string
$s_data = json_encode($some_array);
...
// When concat this json string as a value of source attribute for Yii Autocomplete
$('#libraryborrowtransaction-name').autocomplete({source: <?= $s_data ?> });
The same if for your $e_data. Just pay attention, your get your data from db with PHP, but use it with JS, so php array needs to be converted to a string presentation js array of objects, and this conversion you can do with json_encode.

Related

Laravel custom each directive

I am working on a custom package for one of my projects and came up with an idea to create a custom blade directive for the elements that I want to loop through.
I made a sample code that does not work:
// WIRES
\Blade::directive('startWire', function($params) {
$wires = [
0 => [
'name' => 'test1',
'image' => 'http://image.jpg'
],
];
return "<?php foreach($wires as $wire): ?>";
});
\Blade::directive('endWire', function() {
return "<?php endforeach; ?> ";
});
And in the Blade file I wan to use it like:
#startWire()
#endWire
But I got the following error:
Array to string conversion
I tried to escape the string but nothin seems to be a good choice. Shall I extend the default Blade #foreach directive or how it supposed to work?
Thank you for your answers!
Gábor

Zendesk API using PHP: dynamic content updateMany gives invalid attribute error

I try to update a dynamic content field via Zendesk API using PHP API client (https://developer.zendesk.com/rest_api/docs/api-clients/php):
// auth and config goes here...
$itemId = 123;
$variantId = 456;
$data = [
'id' => $variantId,
'content' => 'my example content'
];
$zendesk->dynamicContent()->items($itemId)->variants()->updateMany(['variants' => $data]);
I get an UnknownAttributeError ("Invalid attribute: missing variants parameter"). What did I miss? I tried different ways to give the variant parameter but still the same error. Thanks!
must follow the Format as like Ticket -> updateMany()
Refer Ticket Update Many Test File
$itemId = 12345;
$variantIds = [456,787];
$this->assertEndpointCalled(function () use ($itemId, $variantIds) {
$this->client->dynamicContent()->items($itemId)->variants()->updateMany(
[
'ids' => $variantIds
'content' => 'My Example Content'
]
);
}, "dynamic_content/items/$itemId/variants/update_many.json");

Default value in ActiveDropDownList

I've inherited a piece of code from an old developer and currently trying to figure out the method behind how it submits.
I'm currently trying to get a quick fix in place where I hide one of his fields to get the form submitting, the issue I'm having is that I can't seem to set the dropdownlist to a default value, which should be United Kingdom, with the id 826 in the database.
echo CHtml::ActiveDropDownList($address, 'country_id', CHtml::listData(Country::model()->findAll(), 'id', 'name', 'continent'), array(
'class' => 'col-md-5 hidden',
'prompt' => 'Select Country',
'label' => 'something here',
'ajax' => array(
'type' => 'POST',
'url' => CController::createUrl('/user/UpdateRegions'),
'dataType' => 'json',
'data' => array('country_id' => 'js:this.value', 'YII_CSRF_TOKEN' => Yii::app()->request->csrfToken),
'success' => 'function(data) {
$("#Address_country_region_id").html(data.country_id);
$("#Address_country_region_id").removeClass(\'hidden\');
if($("#venue_id").val() === "") {
$("#Address_country_region_id").addClass(\'hidden\');
}
}',
)));
$path = CController::createUrl('/admin/user/UpdateRegions');
$id = $address->id;
// On Load
Yii::app()->clientScript->registerScript('ready', '
$.ajax({
type: \'POST\',
dataType : \'json\',
data: {\'country_id\': $(\'#Address_country_id\').val(), \'update_id\' : "' . $id . '"},
url: "' . $path . '",
success: function(data){
$(\'#Address_country_region_id\').html(data.country_id);
}
})
');
How do I get this dropdownlist pointing towards the country_id of 826 as the page loads so I can hide the field and pass the validation of the form.
regards.
this code you pasted does this:
the first part renders a dropdown which does an ajax request on change to /user/UpdateRegions to fill the dependent dropdown for the regions.
the second part does also an ajax request when the page is "ready". So that the region select is filled when the page is ready.
Your script should output the id 826 if you printout the current set id.
If not the value isn't correctly set to the address model.
echo $address->country_id;
If you want to set the default value you can do this at multiple places. e.g. in the controller 'before' the actual submitted value is set or in the model code itself (depends on your code e.g. if you have an additional form model which is extended from your activerecord model).
The correct line in your controller could be before something like this:
$address->country_id= 826;
before one of these lines in your controller
$address->attributes=Yii::app()->request->getQuery(get_class($address));
or
$address->attributes=Yii::app()->request->getPost(get_class($address));
or
$address->attributes=$_POST['address']; // or $_GET
If you have difficulties to find the correct position post some controller code.
I guess you could find some help also here
Yii 1.1: An Easy Solution for Dependent dropDownList Using AJAX
To set default value for $address model, put
$address->country_id = Yii::app()->request->getParam(get_class($address).'[country_id]', 816);
before
echo CHtml::ActiveDropDownList($address, 'country_id', CHtml::listData(Country::model()->findAll(), 'id', 'name', 'continent'), array(

Yii 2 - CreateForm that pull info&value from a search of another model

i've a little problem with yii 2. This is my case:
I manage two tables, Customer and Order, and any Order has a Customer. I've created the relational data and the normal view to create, update, view and delete data from DB. Now i would use the search model of customer in the Order's _form view (to create and update data) to select the customer and pull customer.id that i want to save in my order.id_customer.
With my solution i can see the gridview with customer search in the create view, but (with RadioColumn) it doesn't return customer.id and when i try to filter the data the form doesn't filter anything but it tries to submit my input in to the db.
The old "_form"'s code is on pastebin.
Any suggestion?
Thank you!
-----------------------UPDATE-----------------------------
After many hours of work i fixed my problem.
Now my gridview is out from activeform, where i copy the radio's returnament through a javascript function.
This is the code:
<script type="text/javascript">
var agente = document.getElementById('agente');
var radioSelAgente = document.getElementsByName('radioAgenteId');
function aggiungiAgente(){
for (var i = 0, length = radioSelAgente.length; i < length; i++) {
if (radioSelAgente[i].checked) {
document.getElementById('contrattoformativo-id_agente_iscritto').value=radioSelAgente[i].value;
alert(radioSelAgente[i].value);
break;
}
}
}
<form id="formAddAgente" onclick="aggiungiAgente()">
<?php
$agenteModel = new \backend\models\Agente();
$agenteSearchModel = new \backend\models\AgenteSearch();
$agenteDataProvider = $agenteSearchModel->search(Yii::$app->request->queryParams);
$agenteDataProvider->pagination->pageSize=5;
?>
<?php
echo \kartik\grid\GridView::widget([
'dataProvider' => $agenteDataProvider,
'filterModel' => $agenteSearchModel,
'id'=>'agente',
'columns' => [
[
'class' => '\kartik\grid\RadioColumn',
'width'=>'36px',
'name' => 'radioAgenteId',
'showClear' => false,
'radioOptions' => function($agenteModel, $key, $index, $column) {
return ['value' => $agenteModel->id];
},
],
'nome',
'cognome',
],
'export'=>false,
'pjax'=>true,
'pjaxSettings'=>[
'neverTimeout'=>true,
],
]);
?>
</form>
And in the active form i have:
<?= Html::activeHiddenInput($model, 'id_agente_iscritto') ;?>
Bye!

jQuery html elements dynamically, adding event handlers?

Ive spent several hours trying to resolve an issue with very limited experience with jQuery which is not helping me.
I am wanting to search a database for a list of results using a few input fields and then a submit button, when you click submit the values are passed to a .php script which returns the results and these are displayed in a table within a div container which works perfect.
Each record is then displayed in its own row within the table, with columns for different data.
record number name town etc
What i want is for the record number to be a click link of some kind, which when clicked, it then passes that value and does a different mysql request displaying that unique records data in more detail in a different div container. This is the part i cant get to work as i believe its something to do with BINDING, or the .ON which i dont really know anything or understand how it works, as my experience is very limited.
I have provided some sample code which consists of two files, jQuery.php and db.php, db.php is just simulating a database lookup for now (crude i know), to make it easier to show my code and what i am trying to do.
if you run jQuery.php and either enter a town (sheffield,rotherham) followed by click "get data" you get a refined list of results, if you just click get data you get all the results, you will see each results as a 4 dig ID Number, what i want to happen here is when you click that number it then loads just that record in a different div container, but its not working due to the dynamic content as i have read but don't understand.
You will see i have made an example of the reference number 1005 at the top of the page, and if you click on this, it loads that unique record fine, but i just can't get it to work with the ones in the table.
jquery.php
<script type="text/javascript" src="https://ajax.microsoft.com/ajax/jQuery/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$(".click").click(function() {
var recordid = $(this).attr("id");
$('#2').load("db.php?id=" +recordid);
});
$("#get").click(function() {
var town = $("#town").val();
$('#1').load("db.php?town="+town
);
});
});
</script>
OUTSIDE OF DYNAMIC HTML RECORD ID : - <a class = 'click' id = '1005'>1005</a><br>
<br>
Town <input type="textbox" id="town" ><br>
<button id="get">Get Data</button>
<br>
----<br>
*<div id="1" name='records_all'></div>
----<br>
*<div id="2" name='record_unique'></div>
----<br>
db.php ( crude code to simulate a db lookup, just for purpose of this problem )
<?php
$id = $_GET['id'];
$town = $_GET['town'];
echo "<pre>";
$data[]= array('id' => '1001', 'town' => 'sheffield', 'street' => 'national av', 'name' => 'neil');
$data[]= array('id' => '1002', 'town' => 'rotherham', 'street' => 'maple drive', 'name' => 'steve');
$data[]= array('id' => '1003', 'town' => 'leeds', 'street' => 'poplar drive', 'name' => 'john');
$data[]= array('id' => '1004', 'town' => 'rotherham', 'street' => 'exchange st', 'name' => 'claire');
$data[]= array('id' => '1005', 'town' => 'sheffield', 'street' => 'main street', 'name' => 'sarah');
$data[]= array('id' => '1006', 'town' => 'rotherham', 'street' => 'holderness rd', 'name' => 'jo');
if ($id) {
foreach ((array)$data as $key => $value) {
if ($data[$key]['id'] == $id) {
echo $data[$key]['id']."<br>";
echo $data[$key]['name']."<br>";
echo $data[$key]['street']."<br>";
echo $data[$key]['town']."<br>";
}
}
} else {
if ($town) {
foreach ((array)$data as $key => $value) {
if ($data[$key]['town'] == $town) {
$link = "<a class = 'click' id = '{$data[$key]['id']}'>{$data[$key]['id']}</a>";
echo "{$link} {$data[$key]['town']} {$data[$key]['name']}<br>";
}
}
} else {
foreach ((array)$data as $key => $value) {
$link = "<a class = 'click' id = '{$data[$key]['id']}'>{$data[$key]['id']}</a>";
echo "{$link} {$data[$key]['town']} {$data[$key]['name']}<br>";
}
}
}
You need to use event delegation to solve this issue. Look at the jQuery docs for .on here under the "Direct and delegated events" section
Try something like
$('#1').on('click', '.click', function() {
var recordid = $(this).attr("id");
$('#2').load("db.php?id=" +recordid);
});
This will work as long as the #1 element is in the DOM when the jQuery event bindings are run. Essentially you're binding the click event to the #1 element instead of having to bind it to elements after loading them in. The jQuery docs do a good job of explaining this.
If the elements are not in the DOM at the time of their jQuery selection then the events will not be added with the way you wrote your code. However alternatively you can write your code like this
$(document).ready(function() {
$(document).on('click', '.click', function() { //this is the only thing that changed
var recordid = $(this).attr("id");
$('#2').load("db.php?id=" +recordid);
});
$("#get").click(function() {
var town = $("#town").val();
$('#1').load("db.php?town="+town
);
});
});
This code should completely replace your javascript. It creates a live listener for all future elements in the document with the class click.

Categories