Yii2-mongodb: how to add database fetched items in dropdown list - mongodb

I am trying to add the team names(to be fetched from mongoDB) in the form to let user select the form name.
I am not getting how to add the database fetched form names in the dropdown list.
It should search based on organization_id first & then form_name.
what i am doing is this:
<?= $form->field($model1, 'form_name')->dropDownList(ArrayHelper::map(CreateTeam::find(array('organization_id' => Yii::$app->session['organization_id']))->all(), 'form_name')); ?>
It is showing me an error that missing the third argument. What could be the third argument in that case???

I went through issue with fetching record from country collection to serve record in state form
I got solution as below (considering as my state form)
use app\models\Countries;
use yii\helpers\ArrayHelper;
$countries=Countries::find()->all();
$listData=ArrayHelper::map(Countries::find()->all(),function ($model){return (string)$model->_id;},'name');
echo $form->field($model, 'countries_id')->dropDownList($listData, ['prompt'=>'Select...']);
Hope I was able to let you understand !

$collection2 = Yii::$app->mongodb->getCollection('teamdashboard');
$models = $collection2->find(array('organization_id' => Yii::$app- >session['organization_id']));
$items = ArrayHelper::getColumn($models, 'team_name');
return $this->render('teamdashboard', ['model1' => $model1, 'model2' => $model2, 'items' => $items]);
This one works fine for mongodb...

Yes, in ArrayHelper::map() first three parameters are required, so you are definitely calling this method wrong.
Check out official documentation for map().
The second parameter represents the actual values in database (usually they are primary keys), the third - readable text.
Assuming your primary key is id it should be:
$models = CreateTeam::find([
'organization_id' => Yii::$app->session['organization_id'],
])->all();
$items = ArrayHelper::map($models, 'id', 'form_name');
<?= $form->field($model1, 'form_name')->dropDownList($items) ?>

Related

Codeigniter 3: foreach inside form_input

I'm just starting with CodeIgniter and I can't output the value of my form_input. Here's my code:
<?= form_input('gender','','type="text" class="form-control form-input" value="'.foreach($profile as $prof){echo $prof->gender;}.'" disabled id="name" style="cursor:default"');?>
is my syntax even correct?
No, your syntax is not correct. Your arguments to form_input are wacky and, as you have it, only one input field is created. The "value" of that input might be something like
value='malefemalefemalemalemalemalsemalefemale',
Pretty sure that's not what you want.
Actually, from the code you post it's hard to know what you do want. My guess is this
<?php
//create an array with attribute values that don't change
$attributes = [
'class' => "form-control form-input",
'style' => "cursor:default",
];
//create a counter
$i = 0;
foreach($profile as $prof)
{
//inputs need a unique "name" and "id", use the counter for that purpose
$attributes['name'] = 'gender'.$i;
$attributes['id'] = "name".$i;
//add the 'value' of each profile to the array
$attributes['value'] = $prof->gender;
//send the array to form_input
echo form_input($attributes, NULL, 'disabled');
echo "<br>"; //new line
$i++; //increase value of counter by one for next loop run
}
The above will output a text field (each on a separate line) for each profile.
Documentation on `form_input'.
The "name" of the inputs will be "gender0", "gender1", etc, which will work. That is not the only way to do it. You could also use input arrays. That syntax is name='gender[]'. Either approach will work for the "name" but it won't work for the "id" attributes which must be unique.

Adding columns to a Web2py table in a form

In my web2py application, in the controller I read from an external DB the names of students I want to take a register for. I loop through the resulting list adding the list elements to a new list.
for student in pupils_query:
attendance_list.insert(counter, [student[0], student[1], student[2], student[3]])
counter += 1
counter = 0
Then for each student I read their attendance codes for the day so far from another table, and append them to attendance_list:
for attendance_code in attendance_result:
attendance_list[counter].append(attendance_code)
Now, I'm going to want to make a form from all this, using a table which will show each students' attendance code in a text input (so they can be updated if wrong), then have a dropdown for input of the current lesson code.
I'm using a FORM and TABLE helper to create the table in the form:
form=FORM(TABLE(*[TR(*rows) for rows in attendance_list]))
but can't seem to be able to add a new 'row' form item with something like:
select = "SELECT("+ main_reg_list +")"
attendance_list[counter].append(select)
where main_reg_list is dictionary of acceptable attendance codes (or of course, any other form input element).
In summary, I'm stuck adding new TDs to a table made with a TABLE helper from a list of lists. I bet I'm not the first person to overcome this problem.
I am still not clear about what you want. I think you want table of student information and in one column you want dropdown. Something similat to following image
Above form is created from following code.
I hope following code will help you:
# controller/default.py
def index():
# Dummy attendance list, list after appending attendance code
attendance_list = [['stud_id_1', 'first_name_1', 'last_name_1', 'attendance_code_1'],
['stud_id_2', 'first_name_2', 'last_name_2', 'attendance_code_2'],
['stud_id_3', 'first_name_3', 'last_name_3', 'attendance_code_5'],
['stud_id_4', 'first_name_4', 'last_name_4', 'attendance_code_4']]
possible_att_code = ['attendance_code_1', 'attendance_code_2', 'attendance_code_3', 'attendance_code_4', 'attendance_code_5']
# initialise form_rows with Table heading
form_rows = [THEAD(TR(TH('ID'), TH('First Name'), TH('Last Name'), TH('Attendence Code')))]
for attendance in attendance_list:
attendance_code_dropdown = _get_dropdown(attendance[0], attendance[3], possible_att_code)
td_list = [TD(attendance[0]), TD(attendance[1]), TD(attendance[2]),
TD(attendance_code_dropdown)]
table_row = TR(td_list, _id='row_' + attendance[0])
form_rows.append(table_row)
# Form submit button
form_rows.append(TR(INPUT(_type='submit')))
form = FORM(TABLE(*form_rows), _name='student_attendance',
_id='student_attendance')
if form.accepts(request, session):
# Write code to update record
pass
return dict(form=form)
def _get_dropdown(stud_id, att_code, possible_att_code):
option_list = []
for pac in possible_att_code:
if pac == att_code:
option_list.append(OPTION(pac, _value=pac, _selected='selected'))
else:
option_list.append(OPTION(pac, _value=pac))
return SELECT(*option_list, _name=stud_id)
<!-- views/default/index.html -->
{{extend 'layout.html'}}
{{=form}}
Are my assumptions correct? or you want any thing else? Comment if didn't understood code.

button in a nested table that has dynamic id

I am trying to click on a button in a table cell that has a dynamic name with a prefix of button_keep
this is the unique path that firebug has pointed out for the table cell.
#mergePatientsSelectedTable > tbody:nth-child(2) > tr:nth-child(1) > td:nth-child(2) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1)
I'm trying to get there using the following but it does not find the button.
b.table(:id => "mergePatientsSelectedTable").tbody{2}.tr{1}.td{2}.table{1}.tbody{1}.tr{1}.td{1}.button(:index => 0).button(:name => /button_keep/).click
I have tried to flash on the cells and use IRB yet it continues to give me an assert that cannot find the button.
Any suggestions . thank you
You do not need to write out the whole path. Each method/locator looks in all descendents, not just direct children. Using entire paths can make the code quite brittle.
So why not just locate the button based on the known attributes:
b.table(:id => "mergePatientsSelectedTable").button(:name => /button_keep/).click
But to explain why you were having problems with your solution, doing tbody{2} actually returns the first tbody element (not the second). The {2} is a block that gets ignored.
For example, consider the html:
<div>hi</div>
<div>bye</div>
You can see the first div gets returned when using a block:
b.div{2}.text
#=> "hi"
To get the second div, you can either use the index locator or get the second element of the collection:
b.div(:index => 1).text
#=> "bye"
b.divs[1].text
#=> "bye"
So if you really wanted to do the entire path, you could have done:
b.table(:id => "mergePatientsSelectedTable").tbody(:index => 1).tr.td(:index => 1).table.tbody.tr.td.button(:name => /button_keep/).click
Note that:
nth-child is 1-based index while Watir uses a 0-based index.
If you want the first match, you do not need to include the index - :index => 0 is assumed.

In Yii, how best to POST both search results selection & previously entered form model back to form controller?

To complete a Yii form field, users often need to search for a referenced model record (like searching for a friend's profile in a social app). I'm sure other Yii apps are doing this elegantly. But in my dirty approach, in the search results page, I use a CHtml::submitButton to POST two models back to the form containing:
the "found" record (a user id associated with one of the profiles from the search results)
the previously entered form field contents (relationship characterization fields)
Alternatively, the autocomplete widget works well, but doesn't do the detailed search that I need (e.g. search based on a partial name and city or state or other user profile content).
Alternatively, you'd think that within the search results view I might be able to modify the form member to contain the found record (new friend's user id) and just POST/submit the modified model from the search results page . But for that to work each of the search results in the list needs a unique user id populated in that form field, and I can't figure out how to duplicate the form model before modifying that one member server-side for each of the search results' "submit" or "select" buttons, and it just doesn't seem right to create all those form models.
So what seems to work is to submit two separate models using subforms (within the search results view) , with the submitButton POSTing a model and the extra parameter (user id) separately.
Is there a better way? ...to link to and from a search results page and a form field, retaining already-entered data and populating the searched for field with a selected record from the search results.
Here's controllers/SiteController:
public function actionBefriend() {
$model=new BefriendForm;
if(isset($_POST['BefriendForm'])) {
$model->attributes=$_POST['BefriendForm'];
if ($model->validate()) {
$model->createFriendship();
$this->redirect('Index'); }
else
$er=$model->getErrors(); }
if(isset($_POST['idfriend'])) {
$model->idfriend=$_POST['idfriend']; }
if(isset($model->idfriend)) {
$model->friend_name=Bio::model()->findByPk($model->idfriend)->name; }
$this->render('newFrienship', array('model' =>$model)); // newFriendship is the form view }
Here's controllers/Bio.php (Profile)
public function actionIndex() {
$criteria = new CDbCriteria();
$model=new BefriendForm;
if(isset($_GET['q']))
$q = $_GET['q'];
elseif (isset($_POST['BefriendForm'])) {
$model->attributes=$_POST['BefriendForm'];
$q = $model['friend_name']; }
if(isset($q)) {
$criteria->compare('name', $q, true, 'OR');
$criteria->compare('city', $q, true, 'OR');
$criteria->compare('state', $q, true, 'OR');
$criteria->compare('bio_text', $q, true, 'OR'); }
else
$q = '';
$dataProvider=new CActiveDataProvider('Bio', array('criteria'=>$criteria));
$this->render('index',array('dataProvider'=>$dataProvider, 'q'=>$q, 'model'=>$model )); }
Here's the start of views/site/newFriendship (form view)
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'newFriendship-BefriendForm',
'enableAjaxValidation'=>true,)); ?>
Here's the core of views/bio/index.php (search results index page):
<?php $this->widget('zii.widgets.CListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
'viewData'=>array('model'=>$model) )); ?>
Here's the search result row in views/bio/_view.php that links back to BefriendForm (SiteController) that sends the id of the user to populate the friend field in the form (which gets a name from the id):
<form method="POST">
<input type="hidden" name="idfriend" value="<?php echo $data->idfriend ?>" />
// Here's that submit button that I can't get to send both the model
//and the idfriend back to the form to repopulate it
// without manually writing HTML to submit all the fields individually
// or creating 2 subforms to submit together with a signle submitButton.
<?php echo CHtml::submitButton('Befriend', array('submit' => array('site/Befriend'),'model'=$model);
</form>
The best alternative I can see is to imbibe the searcher widget within the form.
Turns out you can just replace the form field containing the primary key with the appropriate value before POSTing back to the NewFriendship form when the user clicks the "Select" or "Befriend" button. So only one model is posted back to the original form from the search results page.
Replace the section from views/bio/_view.php in the question with...
<?php
foreach($model->attributeNames() as $name)
if($name != 'friend_id')
echo CHtml::activeHiddenField($model,$name);
else
echo CHtml::activeHiddenField($model,$name,array('value'=>$data->getPrimaryKey()));
echo CHtml::submitButton('Befriend', array('submit' => array('site/Befriend')));
?>

Help needed formatting Doctrine Query in Zend Framework

Can anyone tell me how to format the query below correctly in my controller.
Currently it gives me nothing in my FilteringSelect. However if I change it to >= I get back all the kennelIDs which is incorrect also but at least I'm getting something.
I've tested that the session variable is set and can confirm that there are kennels with the matching capacity.
// Create autocomplete selection for the service of this booking
public function servkennelAction()
{
$sessionKennelBooking = new Zend_Session_Namespace('sessionKennelBooking');
// disable layout and view rendering
$this->_helper->layout->disableLayout();
$this->getHelper('viewRenderer')->setNoRender(true);
// get list of grooming services for dogs from the table
$qry= Doctrine_Query::create()
->from('PetManager_Model_Kennels k');
//This should be set by default and narrows down the search criteria
if(isset($sessionKennelBooking->numPets)){
$b=(int)$sessionKennelBooking->numPets;
$qry->addWhere('k.capacity = ?','$b');
}
$result=$qry->fetchArray();
//generate and return JSON string using the primary key of the table
$data = new Zend_Dojo_Data('kennelID',$result);
echo $data->toJson();
}
Many thanks in Advance.
Graham
I think that addWhere condition is wrong. It has to be:
$qry->addWhere('k.capacity = ?', $b);
i.e. $b without quotes.