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.
Related
I am reading input from the user (in Laravel) and have rules associated to each of those inputs. If the user selects a checkbox (for that specific table), I would like to remove all the rules from the $rules associative array for that table.
To better illustrate, I have created two arrays mimicking the behaviour.
My input array is as follows:
$input = array("TB1_course" => ['0'=>'CHEM 1E03', '1'=>'ENG 1D04'
],
"TB1_section" => ['0'=>'CHEM 1E03', '1'=>'ENG 1D04'
],
"TB1_checkbox" => "1",
"TB2_course" => ['0'=>'CHEM 1E03', '1'=>'ENG 1D04'
],
"TB2_checkbox" => "0"
);
$rules= array(
'TB1_course.*' => 'required_with',
'TB1_section.*' =>'required_with',
'TB2_course.*' =>'required_with'
);
You can see from the input array that TB1_checkbox has a value of 1. If it has a value of 1, I would like to remove all the rules associated with TB1 (i.e. remove the elements in $rules with a key containing 'TB1').
I attempted to do as such, and was partially successful. My code looks like:
foreach ($input as $key=>$value){//go thru every element of the inputs
if ((strpos($key, 'checkbox')!==false) && $value==1){//if it contains 'checkbox'
//and checkbox is selected
$table_name= substr($key, 0,3);//name of table
//now go thru $rules and remove all elements which contain a word of $table_name
$rules=array_filter($rules, function($x){
return strpos($x, $table_name)!==0;//problem lies here
}, ARRAY_FILTER_USE_KEY);
}
}
However my code isn't working. The strpos() function is unable to read the $table_name variable, and leads to problems. If I manually pass in a string, it ends up working (i.e. 'TB1' instead of $table_name), but I have to have the flexibility of checking all my tables (so the rules containing 'TB2' have to be removed if "TB2_checkbox" has a value of 1). Is there any way to solve this issue?
Thank you for the help.
I have a table which contains a set of templates. These templates have placeholders which need to be replaced at runtime given a key,value pair array. Here's my code for making the replacements:
function replace_placeholders(&$input_values) {
$result = execute_pdo_query("SELECT name,value FROM templates");
foreach($result as $currow) {
$varname = $currow[name];
$varvalue = $currow['value'];
foreach($input_values as $key => $value) {
$key = '{'.strtolower($key).'}';
$varvalue = str_replace($key,trim($value),$varvalue);
}
$input_values[$varname] = $varvalue;
}
}
The issue is that there are a large number of templates and many key,value pairs. So, this nested loop gets executed many many times taking up almost half a second. Is there a way to optimize this replacement? I have searched for an optimization but it's mostly said that str_replace is the best that can be done.
You don't show us what $input_values contains, but I assume this is a global list of all possible tags to be replaced.
This being the case, one obvious weakness is that you loop over this for each template. If a template happened to have only one tag in it, this is wasteful.
I would be tempted to try changing it up so that, rather than loop over all possible tags for each template, you act only on the tags mentioned in the template, via preg_replace_callback. I can't guarantee this will be faster, but it would be my first thing to try.
Here's a simplified example:
$transformations = array(
'name' => 'John',
'pronoun' => 'you'
'animal' => 'dog'
'building' => 'house'
'food' => 'chocolate'
'friend' => 'Kelvin'
/* etc, potentially many more */
);
$template = "hello, {name}, how are {pronoun}?";
$transformed_template = preg_replace_callback('/\{(\w*)\}/', function($match) {
global $transformations;
if (isset($transformations[$match[1]]))
return trim($transformations[$match[1]]);
}, $template);
The template contains only two placeholders, and we act only on those, rather than looping through all the possible tag replacements in $transformations.
(Note I use an anonymous function as the callback to preg_replace_callback(). If you're on PHP < 5.3 you'll need a named function instead.)
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).
public function dcr() {
$query = $this->db->query("SELECT * FROM church_repo");
foreach ($query->result() as $row) {
$data = array('churchName' => $row->church_name,
'streetAddress' => $row->street_address,
'locationalState' => $row->locational_state,
'locationalZIP' => $row->locational_zip,
'locationalCountry' => $row->locational_country,
'locationalCity' => $row->locational_city,
'overseerAccountId' => $row->overseer_account_id,
'taxExemptionNumber' => $row->tax_exemption_number,
'accountStatus' => $row->status,
);
$this->load->view('admin-request', $data);
}
}
In my Html I am outputting the above Php. Also in my Html, I have two buttons that have id's of 'pass' and 'fail'. What the script is doing when I have multiple rows is output those two buttons with the same id's on each outputted row. That's good, because it is doing what it needs to be doing, but now I'm not able to identify the outputted rows. So I need to be able to match each button set with the outputted Php. Any ideas?
The way i typically do what you are attempting is by creating new forms for each row. and including a hidden input field in each row with the id.
<input type="hidden" name="row_id" value="<?= $overseerAccountId;?>"/>
when the user clicks pass/fail you simply use CI/PHP to get that value
<?php
echo $this->input->post('row_id');
//do work son.
?>
the only difference between your code and what i typically do, is i move my foreach into the view and iterate through each row creating new <tr><td> instead of creating new tables like you are doing. But this could be considered against the MVC standard
I am working with a hook_form_alter on a CCK type (for you drupal-ers). I have a field that is normally a select list in my node form. However, in this instance, I want to hide the select list, and populate its value in the form with an SQL query.
Everything was going nicely. I could see that my desired value was showing up in the HTML source, so I knew my query was executing properly. However, when I submit the form, it only inserts the first character of the value. A few of my tests were values of 566, 784, 1004 - the column values were 5,7,1, respectively.
At first I thought it had to be the DB column attributes, but when I removed my form_alter that makes the field hidden and select the value manually, the correct value is inserted?!?
<?php
function addSR_form_service_request_node_form_alter(&$form, $form_state) {
if (arg(0) == 'user' && is_numeric(arg(1))) {
$account = arg(1);
$club = 2589;
$form['field_sr_account'] = array( '#type' => 'hidden',
'#value' => $club
);
}
}
?>
Can anyone see why only the first character would be inserted??
Note: I have tried deleting and recreating the column, using #value & #default_value, and it is still submitting only the first character of the integer. Also, I eliminated the submit handler as a possible cause by removing it, which still resulted in only one character being submitted
More Updates - Still Searching!
Okay, some good questions. Allow me to answer them:
The DB column type is integer(4)
The HTML the hook produces is :
input type="hidden" name="field_sr_account" id="edit-field-sr-account" value="2589"
Latest Update: I think the issue has been narrowed to the structure of the array. When I do var_dump on this field after the form alter has been processed, this is what I get..
[43] => Array
(
[#type] => hidden
[#default_value] => 2589
[#post] => Array
(
)
[#programmed] =>
[#tree] =>
[#parents] => Array
(
[0] => field_sr_account
)
[#array_parents] => Array
(
[0] => field_sr_account
)
[#weight] => 0.016
[#processed] => 1
[#description] =>
[#attributes] => Array
(
)
[#required] =>
[#input] => 1
[#process] => Array
(
[0] => form_expand_ahah
)
[#name] => field_sr_account
[#id] => edit-field-sr-account
[#value] => 2589
[#defaults_loaded] => 1
[#sorted] => 1
)
What is the structure of the field that I can set the form value to. It's gotta be something like what abhaga is suggesting..
Since the field you are trying to change was originally using a select widget, CCK will be looking for $form_state['values']['field_sr_account'][0]['value']. By setting the field to a #hidden type and setting #value, you will get its value in $form_state['values']['field_sr_account']. CCK will try to access the first element of that and end up with the first character of the value.
Updated: The easiest way to achieve what you need would be to do something:
function addSR_form_service_request_node_form_alter(&$form, $form_state) {
if (arg(0) == 'user' && is_numeric(arg(1))) {
$account = arg(1);
$club = 2589;
// Use this property to store the value to restore back
$form['#field_sr_account'] = $club;
$form['field_sr_account'] = array( '#type' => 'hidden','#value' => $club);
}
}
/*in your submit handler, restore the value in the proper format*/
$form_state['values']['field_sr_account'] = array('0' => array('value' => $form['#field_sr_account']));
Old Answer
One way of accomplishing what you are
trying to do is to copy the whole
$form['field_sr_account'] into
$form['#field_sr_account'] and then
provide the value through the SQL
query in the right format in the
submit handler itself.
Ok take a look at http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html#hidden versus http://api.drupal.org/api/drupal/developer--topics--forms_api_reference.html#value
It is also recommended you use value instead of hidden. You can find this info on http://api.drupal.org/api/drupal/developer--topics--forms_api.html/6
Also, type hidden is not allowed to have properties your assigning to it so this may be causing a problem. Any usage problems you may be having with the forms API should be answer in those resources as I"m still a little unclear on what you're trying to accomplish... specifically with the submit button.
Old answer:
Ok if I understand this correctly
$club is not being set correctly. If
the first result from your query is
the number your looking for then this
should work.
Try calling
<?php print_r(db_fetch_array($result)) ?>
to get a look at everything returned
from the query.
I'm a little unclear as to what is
being set incorrectly. If it's
#value inside your associated array
then the culprit must be the query.
If #value is being set correctly and
whatever your doing with it later may
be the culprit (not shown here). If
its the values in your $form_state I
don't see that your using $club here
at all.
Also, in your addSR_submit_function
you don't seem to be using the $form
variable, or using $club for anything
except for setting the message which
appears at the top of the page your on
when it's called.
I may need some further clarification
as to what exactly is going wrong.
Also, when you're calling
drupal_set_message function, are you
just doing this for debugging
purposes?
Shouldn't you check
drupal_set_message($form_state['values']['field_sr_account']);
instead of
drupal_set_message($club);
in addSR_submit_function ?
OK, just a quess: not sure what type db_result returns for your query, may be it has something to do with types conversions? So this is to make sure value is int.
'#value' => (int)$club
cinqoTimo, Out of curiosity what kind of CCK field is this? Is it a Integer, Decimal, Float? and do you have any special parameters on that field not normally on by default? What is the column type in the db?
Can you post the html output of the form. That might give a clue as to what might be going on.
Are you using any javascript to edit any values for this field?
Have you tried outputting the value results from addSR_form_service_request_node_submit hook? Any difference there.
Sorry for all the questions. Just thinking out loud as it seems you have covered most of your bases.