I know this has been asked before, but I just cant seem to find an answer... or solution.
I have many select boxes using 'multiselect'. The dropdowns are being populated from the database, and the first value in the array is always 'Select One'. This I cannot change, I am rewriting an app and am not changing the database at all.
Everything works just fine, but they always come out as 'optgroup' tags with a label, which always puts a '0' at the top of the list. The boxes always say 'Select One', which is great, but when expanded you see the '0' at the top... which is the 'label' attribute to the optgroup tag.
I do it all somehting like this...
$Criteria = new Criteria();
$Criteria->add( DictionaryPeer::CATEGORY, 'Progress Notes: Program Status' );
$Criteria->addAscendingOrderByColumn( 'Ordinal' );
$ProgramStatuses = DictionaryPeer::doSelect($Criteria);
$ProgramStatusList = array();
foreach ($ProgramStatuses as $ProgramStatus) {
$ProgramStatusList [ $ProgramStatus->getDictionaryID() ] = $ProgramStatus->getWord();
}
$form->programstatus->addMultiOptions( array(
$ProgramStatusList ));
echo $form->programstatus->renderLabel() . $form->programstatus->renderViewHelper();
I just want to remove the '0' for presentation purposes only...
Any help is always appreciated...
Thanks!
If you want to get rid of the OPTGROUP, you just need to pass a simple array as parameter to addMultiOptions() as follows:
$form->programstatus->addMultiOptions($ProgramStatusList);
Because if you pass a multidimensional array, Zend_Form will indirectly consider each index of the parent array as a group of options (using the FormElement View Helper).
Related
I've been using the wonderful MultiSelectField add-on http://addons.silverstripe.org/add-ons/fullscreeninteractive/silverstripe-multiselectfield on a front-end form.
This form is used to edit entries that have already been added via another form. The issue I'm having is that when retrieving an array ($FeedbackCategorySelected) to populate the field with previous selection(s) it doesn't seem to take the argument. For instance if the array was (1,3) it will only display the record for 1 and not 3.
As this field is extending the CheckboxFieldSet I would have assumed it would work in exactly the same way.
Can anyone shed any light on what could be wrong here? Code below.
Many thanks
...
$urlID = $this->request->param('ID');
if(is_numeric($urlID)){
$CallEvent = DataObject::get_by_id("CallEvent", Convert::raw2sql($this->request->param('ID')));
$Feedback = DataObject::get_by_id("Feedback", $CallEvent->FeedbackID);
$FeedbackCategorySelected = $Feedback->FeedbackCategories;
$FeedbackCategory = FeedbackCategoryData::get()->map('ID', 'Title')->toArray();
}
...
$fields = new FieldList(
new MultiSelectField(
'FeedbackCategories',
'Select feedback categories to add or remove',
$FeedbackCategory,
$FeedbackCategorySelected
)
...
I believe the forth parameter, $value, of the MultiSelectField constructor should be an array:
$FeedbackCategorySelected = $Feedback->FeedbackCategories()->map('ID', 'Title')->toArray();
I have a lot of 'h2' elements with 'a' inside.
All I want is just get all the 'a' in the 'h2'
when I try something like this:
public function testBreakingNewsH2(){
$this->url('index.php');
$h2Elements = $this->byCssSelector('h2')->byCssSelector('a')->text();
$this->assertEquals('Breaking News', $h2Elements);
}
I get only the first 'a' inside 'h2'.
I need to check that all 'h2' links are exists (get all 'h2' elements that contains 'a')
I tried something like this:
public function testHomePgaeH2(){
$this->url('index.php');
$h2Elements = $this->elements($this->using('css selector')->value('h2'));
$this->assertContains('Breaking News', $h2Elements);
$this->assertContains('Analysis', $h2Elements);
$this->assertContains('Calendar', $h2Elements);
$this->assertContains('Studies', $h2Elements);
}
this not works, this is the best example that I found for my issue.
of course I can try something like this:
$this->assrtRegExp('/xxxx/i', $this->source());
but I want make it clean as possible without taking all the source.
please advise,
thanks.
You get a list of elements by css selector with this code:
$elements = $this->elements($this->using('css selector')->value('h2 a'));
foreach ($elements as $i=>$element){
echo $element->text() . "\n";
}
If you want to check that all h2 contain a, you can find all elements by css selector h2 and count them then find by h2 a and count again. Then compare. Also you can iterate all h2 a elements and check their urls by array or regexp. It depends on what you want.
If I have a plugin in my server account which has this code:
function script_options() {
$scripts = array(
'Forum' => array(
'403' => 'phpBB2',
'5' => 'phpBB3',
'417' => 'Simple Machines Forum',
),
'Blog' => array(
'410' => 'b2evolution',
'418' => 'Movable Type',
'409' => 'Textpattern',
'400' => 'WordPress',
),
'Wiki' => array(
'413' => 'DokuWiki',
),
);
$result = '<option value="">'.__rp('none','none').'</option>';
foreach ($scripts as $group => $list) {
$result .= "<optgroup label=\"$group\">";
foreach ($list as $script_key => $script_value) {
$result .= "<option value=\"$script_key\"".($script_key == isset($_GET['script'])?$_GET['script']:false ? ' selected="selected"':'').">$script_value</option>";
}
$result .= '</optgroup>';
}
return $result;
}
How can I make the first choice be ('400' 'Wordpress'); if the user did not choose anything it chooses Wordpress by itself.
It looks like you don't fully understand what this code does, so let me boil it down for you.
Let's start at the end and work our way backwards: When the function returns, the $result variable contains an HTML fragment with a bunch of <optgroup> tags in it, and those contain <option> tags. I assume this HTML gets pasted into a <select> tag somewhere outside this function (BTW, <select> is an HTML thing; PHP has a select() function that is completely unrelated to this, so to avoid confusion, don't refer to HTML's <select> as "select option in PHP").
The foreach loops right before that construct the $result value by concatenating individual chunks of HTML, and those are in turn derived from the nested associative array declared at the beginning of the function. If you follow those loops carefully, you'll see that the tree structure of the resulting HTML follows that of the nested array: each top-level element becomes an <optgroup>, and the name is derived from the array key; each second-level element becomes an <option>, where the key goes into the value attribute (which determines the value used when the containing form is submitted), and the value goes into the user-visible tag content. The array elements are visited in order, so what comes first in the array also comes first in the resulting HTML.
There are two things you need to know about <select> in this context: first, you can define which option is selected by default by adding a selected tag to it (the standard way to express this is <option selected="selected">...</option>); there should be at most one selected option in your <select>. And second, if none of your options has a select attribute, the first one becomes the default.
Now, what does this mean for you? Simple: you can either make it so that your code sets the selected attribute on the WordPress entry; this way, your options remain ordered exactly as they are now, optgroups and all, but WordPress will be preselected. Or you can put the WordPress one as the very first element, which puts it first in the <select>, and should get it preselected because no option has a selected attribute.
I have created a form in which i embed another form. My question is about this embedded form - I'm using a sfWidgetFormDoctrineChoice widget with option multiple set to true. The code for this embedded form's configure method:
public function configure()
{
unset($this['prerequisite_id']);
$this->setWidget('prerequisite_id', new sfWidgetFormDoctrineChoice(array(
'model' => 'Stage',
'query' => Doctrine_Query::create()->select('s.id, s.name')->from('Stage s')->where('s.workflow_id = ?', $this->getOption('workflow_id') ),
'multiple' => true
)));
$this->setValidator('prerequisite_id', new sfValidatorDoctrineChoice(array(
'model' => 'Stage',
'multiple' => true,
'query' => Doctrine_Query::create()->select('s.id, s.name')->from('Stage s')->where('s.workflow_id = ?', $this->getOption('workflow_id') ),
'column' => 'id'
)));
}
I unset the prerequisite_id field because it is included in the base form, but I want it to be a multiple select.
Now, when I added the validator, everything seems to work (it passes the validation), but it seems like it has problems saving the records if there is more than one selection sent.
I get this PHP warning after submitting the form:
Warning: strlen() expects parameter 1 to be string, array given in
D:\Development\www\flow_dms\lib\vendor\symfony\lib\plugins\sfDoctrinePlugin\lib\database\sfDoctrineConnectionProfiler.class.php
on line 198
and more - I know, why - in symfony's debug mode I can see the following in the stack trace:
at Doctrine_Connection->exec('INSERT INTO stage_has_prerequisites
(prerequisite_id, stage_id) VALUES (?, ?)', array(array('12', '79'),
'103'))
So, what Symfony does is send to Doctrine an array of choices - and as I see in the debug sql query, Doctrine cannot render the query correctly.
Any ideas how to fix that? I would need to have two queries generated for two choices:
INSERT INTO stage_has_prerequisites (prerequisite_id, stage_id) VALUES (12, 103);
INSERT INTO stage_has_prerequisites (prerequisite_id, stage_id) VALUES (79, 103);
stage_id is always the same (I mean, it's set outside this form by the form in which it is embedded).
I have spend 4 hours on the problem already, so maybe someone is able to provide some help.
Well, I seem to have found a solution (albeit not the best one, I guess). Hopefully it'll be helpful to somebody.
Finally, after much thinking, I have concluded that if the problem comes from the Doctrine_Record not being able to save the record if it encounters an array instead of a single value, then the easiest solution would be to overwrite the save() method of the Doctrine_Record. And that's what I did:
class StageHasPrerequisites extends BaseStageHasPrerequisites
{
public function save(Doctrine_Connection $conn = null)
{
if( is_array( $this->getPrerequisiteId() ) )
{
foreach( $this->getPrerequisiteId() as $prerequisite_id )
{
$obj = new StageHasPrerequisites();
$obj->setPrerequisiteId( $prerequisite_id );
$obj->setStageId( $this->getStageId() );
$obj->save();
}
}
else
{
parent::save($conn);
}
}
(...)
}
So now if it encounters an array instead of a single value, it just creates a temporary object and saves it for each of this array's values.
Not an elegant solution, definitely, but it works (keep in mind that it is written for the specific structure of the data and it's just the effect of my methodology, namely See What's Wrong In The Debug Mode And Then Try To Correct It Any Way Possible).
I want the user to be able to choose a restaurant from a dropdown list. I'm achieving this by the simple:
echo $this->Form->input(
'Restaurant', array('multiple'=>false, array('empty' => true)));
The issue I have is: some restaurants have duplicate names, and I need a way for the user to know which is which. I'd like to have the ID and/or address within the select options like:
<li value='62'>McDonalds (1234 Happy St) - #62</li>
<li value='63'>McDonalds (9876 French Fry Ln) - #63</li>
...etc
Is there a way to do this? I'm obviously capable of doing it w/ normal HTML, but... would be nice to stay in CakePHP.
Thanks ahead of time for any thoughts/suggestions/direction!
When you load your restaurants you're actually getting an array like this
array (
ID => NAME,
ID => NAME
)
Basically, it's an associated array with the ID as the key and the display field as the value. So as long as you modify that array via the find operation or via normal PHP array iteration, you can achieve your goal.
EDIT
So your answer is CakePHP VirtualFields
In your model you define it as
var $virtualFields = array(
'rest_unique_name' => 'CONCAT(Restaurant.first_name, " ", Restaurant.address)'
);
In your controller you do this
$opts = array(
'fields' => array('id', 'rest_unique_name')
);
$restaurants = $this->Restaurant->find('list', $opts);