I'm trying to add extra HTML attributes to some select options in a dropdown list in Joomla 2.5, and want to use the built-in HTML helpers rather than write the HTML by myself. The current output is:
<select>
<option value="Red">Red</option>
</select>
but I would like it to be something like:
<select>
<option value="Red" data-img="red.jpg">Red</option>
</select>
so that I can access the data-img attribute using Javascript when the selected option changes.
I'm creating the select options like so:
$select = JHtml::_('select.option', "Red", "Red");
and then passing them to JHTML to create the generic list HTML:
$html = JHTML::_('select.genericlist', ...);
I've looked through the documentation and tried passing various different parameter to the functions, but it's very confusing in terms of all the options (option.attr, attr etc) that the functions use, and Google has turned up nothing either.
Can anyone tell me what extra parameters I need to pass to the functions to get it properly add the extra attributes to the <option> elements?
Thanks in advance!
I was struggling on this exact scenario today, needing to add some extra data with the select's options. After a thorough analyze of the joomla/libraries/joomla/html/html/select.php file, I succeeded to do this with a few downside...
First, in my case, the data used for the select is coming from the database, and need some preparation for this scenario :
$db =& JFactory::getDBO();
$sql = 'SELECT nom AS value , nom AS text, prix FROM #__reservation_nourritures order by `ordering` asc';
$db->setQuery($sql);
$nourritures = $db->loadObjectList();
foreach ($nourritures as $nourriture){
//the data to use MUST be in an array form for the extra html attributes...
$nourriture->data = array('data'=>$nourriture->prix);
}
Once the data is ready, you can pass it to the JHTML function to build the select :
echo JHTML::_('select.genericlist',$nourriture,'myId',array('class'=>'nourritures','option.attr'=>'data'));
In short, the 'option.attr' must be used to insert attributes into the options. Note : The select.genericlist function MUST have only 3 arguments for this to work. From what I understand from the function, attributes only get merged into the options if you pass exactly 3 arguments to the function, otherwise it just ignores it. So if you want, as exemple, to define a preselected option with the additional parameters, you are out of luck. Here is the part regarding this in the function :
if (is_array($attribs) && func_num_args() == 3)
{
// Assume we have an options array
$options = array_merge($options, $attribs);
}
To my understanding, this is a bug and/or a bad behavior. I'll fill in a bugg in the joomla tracker when I get time.
You can do something like this
$option = JHtml::_('select.option', "Red", "Red", array('option.attr' => 'optionattr', 'attr' => array('data-img' => "red.jpg")));
or like this
$option = JHtml::_('select.option', "Red", "Red");
$option->optionattr = array(
'data-img' => "red.jpg"
);
Related
I am working in gravityforms to pre-populate a form with database values dynamically, which is working. I need to be able to specity which of these options is selected by default when the form is built, but I can't find the option to do so. I have seen the placeholder, but I presume this doesnt actualy select anything on the dropdown. I have been unable to find any docs or references that allow me to set the "selected" options once I have built all the text/value pairs in the array and set the choices.
The function (which I have redacted here) works fine and populates the field, I just need to populate a placeholder and/or default selected value.
add_filter('gform_pre_render_1', 'getFieldValues');
add_filter('gform_pre_validation_1', 'getFieldValues');
add_filter('gform_pre_submission_filter_1', 'getFieldValues');
function getFieldValues($form) {
global $wpdb;
foreach ($form['fields'] as $field) {
if ($field->id == '40') {
// get the list of values from the Database
$list1Q = "SELECT <data> FROM <table> WHERE <params> = <value>";
$list1R = $wpdb->get_results($list1Q);
// Generate a nice array that Gravity Forms can understand
if (!empty($list1R)) {
$list1A[] = array();
foreach ($list1A as $listItem) {
// Add current value to the array for dropdown choices
$list1C[] = array('text' => $listItem->variable, 'value' => $listItem->variable);
}
}
// Set choices to field
$field->choices = $List1C;
***** THIS IS WHERE I WOULD LIKE TO SET THE SELECTED VALUE *****
}
}
return $form;
}
If there is a better way to go about populating this field, I am open to suggestions at it seems that the form loads a bit slow using this method. Otherwise, I would love to know how to set a selected choice value after populating the choices.
the quick answer is, there is an option that i found for "isSelected" that can be included in the array when defining choices. I added a ternary operation to match on what I wanted selected and it set the "selected value for me.
$isSelected = ($listItem->variable == "value I want to select") ? true : false;
$list1C[] = array('text' => $listItem->variable, 'value' => $listItem->variable, 'isSelected' => $isSelected);
Adding the ternary choice and changing the array push allowed me to set a value as selected.
I know there are better ways to do it, but I really need to create a multiple parameter filter with PHP only in order to filter items by from a json.
The categories are separated by Gender, type of Item, colors etc... I want to be able to select multiple categories, and if only gender is set to show all products, call them using the $_GET method and be able to filter using IFs.
The problem is that my amateur coding skills are not helping much, and I am also not sure if without AJAX there is a better way to do this.
This is what part of my filter looks like:
<ul class="category-menu" name="categoria">
<li><a href="page.php?genid=<?php echo $genid;?>&cat=remeras&col=<?php echo ($_GET["col"]);?>&mar=<?php echo ($_GET["mar"]);?>" name="campera" >Remeras</a></li>
<li>Camperas</li>
<li>Pantalones</li>
<li>Shorts</li>
<li>Vestidos</li>
</ul>
And I have my ifs looking like this:
<?php
}elseif ( !empty($_GET["genid"]) && !empty($_GET["cat"]) && $datosArray[$i]["sex_id"] == $_GET["genid"] && $datosArray[$i]["categoria"] == $_GET["cat"]){
?>
<!-- Individual Product full Code -->
...
<!-- /Individual Product full Code -->
<?php
}elseif (!empty($_GET["genid"]) && $datosArray[$i]["sex_id"] == $_GET["genid"]){
?>
<!-- Individual Product full Code -->
...
<!-- /Individual Product full Code -->
<?php
}} ?>
Right now the only "filter" it recognizes is the Gender one and its displaying all products even if the $_GET is set and displayed properly.
Thank you all in advance.
If I turn your code into psuedo-code, it reads like this.
if we have the following: a genid, cat
and the genid is the same as $datosArray[$i]["sex_id"]
and the datosArray[$i]["categoria"] is the same as $_GET["cat"]
then display the product
Otherwise, if we have a genid
and that genid is the same as $datosArray[$i]["sex_id"]
then display the product
If that is what you where intending to have happen, then you might want to var_dump or print_r all of your variables, and make sure nothing unexpected is happening.
You talked about wanting to use multiple categories. There are two ways of doing this that I can think of right now. The first is to have a comma separated list of categories href="...cat=pantelones,vestidos,shorts, and then turn that into an array $cats = explode(',', $_GET['cat']). You would then check for a specific category with in_array('pantelones', $cats).
The second is to create an HTML form that uses a checkbox to select multiple categories, and then if you simply add brackets to the end of the checkbox's name, then when the user submits the form, PHP will automatically convert $_GET['cat'] into an array for you See this SO question for more info about what I mean.
I would do things more like this.
function display_product($productData){
/* Add code here to display your product */
}
foreach($datosArray as $productData){
/* Always display the product if the gender ID was not set */
if ( empty($productData['genid']) ){
display_product($productData);
}
/* Otherwise only display the product if it matches what is in $_GET[] */
if (
isset($_GET["genid"]) && $_GET["genid"] == $productData['sex_id']
&& isset($_GET["cat"]) && $_GET["cat"] == $productData['categoria']
&& isset($_GET["mar"]) && $_GET["mar"] == $productData['Marca']
){
display_product($productData);
}
}
I know you already said you knew that there where better ways of filtering data, I just want to add that once it comes time to add/edit/delete data, databases become super useful. They are also speedier at filtering out the data you want.
You introduced an XSS vulnerability. You should always escape your variables before outputting them, like so. (I like to use <?= which is just a shorthand for <?php echo.)
<ul class="category-menu" name="categoria">
<li><a href="page.php?genid=<?= (int)$genid ?>&cat=remeras&col=<?= htmlspecialchars($_GET["col"]) ?>&mar=<?= htmlspecialchars($_GET["mar"]) ?>" name="campera" >Remeras</a></li>
<li>Camperas</li>
<li>Pantalones</li>
<li>Shorts</li>
<li>Vestidos</li>
</ul>
PHP offers a http_build_query($arrayOrObject) function which is useful on its own. Check the docs.
I made myself a tiny wrapper for the function that I normally use for such things.
/**
* Build query parameters string from given arrays ($_GET by default)
* #param array $newGet
* #param null|array $currentGet
* #return string
*/
function new_build_query(array $newGet = [], ?array $currentGet = null)
{
if (!isset($currentGet))
$currentGet = $_GET;
$newGet = array_merge($currentGet, $newGet);
ksort($newGet);
return http_build_query($newGet);
}
Given the current URL being https://example.com/?page=2his can be used like this:
$params = new_build_query([
'sort' => 'asc',
'filter' => 'female',
]);
// $params === 'filter=female&page=2&sort=asc'
$redirectUrl = "https://example.com/?{$params}";
your code is a bit confusing in the way it is displaying the results. So I mean you want to filter a product, from there the genre and following specific details such as color, size etc. on request by ajax is possible yes. but I advise to leave these parameters in database and from this make the filters. If you are based only on json use json_decode ($ data, true) to make it an array so you can do the filters more simply. I also advise using a template engine (twig for example) to separate php code from html. that would be better for you
I am trying following to make a dropdown readonly:
$element = $this->CreateElement('select', 'type');
$element->addMultiOptions( $Types );
$element->setRequired(true);
$element->setAttrib('readonly',true);
$element->setLabel('Type');
$elements[] = $element;
A dropdown is shown but I am able to select other values.
How to make a dropdown readonly ?
Thanks
You can use the read only attribute. You could avoid outputting a dropdown at all if it is not the best element to use in your particular case.
$element->setAttrib('disabled','disabled');
If you mean to only have one value selected, you could always disable it. Using your current framework, you might do something like:
$element->setAttrib('disabled', true);
I have a template file that I want to print a the cck user reference form field on.
Is this possible? Note, this is not the field value, but the field form. Also asking for just the field, not creating a form first and then using drupal_get_form()
Thanks!
Edit: If this is not possible that's fine too, I just would like to know
Edit2: i just need the autocomplete mechanism so I can grab the uid in js from searching for the username
If you just need autocomplete mechanism I would suject you to use jQuery autocomplete plugin - http://docs.jquery.com/Plugins/autocomplete.
you can just output in the template something like that:
print '<input type="text" id="user-autocomplete">';
Then in javascript code
$(document).ready('function(){
$('#user-autocomplete').autocomplete(some-ajax-url-here)
}');
you also will need to create an ajax callback page somewhere in your module:
function YOUR_MODULE_NAME_menu(){
$items = array();
$items['user-autocomplete-ajax-page'] = array(
'title' => 'AJAX:get user',
'page callback' => 'get_user'
);
}
function get_user(){
$sql = 'SELECT uid, name FROM {users} WHERE name LIKE ("%s")';
$result = db_query($sql,$_GET['request']);
$res_str = '';
while($object = db_fetch_object($result)){
$res_str .= $object->name.' ['.$object->uid."]\n";
}
print $res_str;
}
I didn't test the code, but I guess it should work, may be with some minor changes.
I am generating options for my dropdown using
// view.php
foreach ($plants as $row):
$options[$row->plant_id] = $row->plant_name;
endforeach;
and then lower in the HTML part of view.php
//view.php
$js = 'onChange = "plantDateDelete(\'/size/get_dates_for_plant/\'+this.value);"';
echo form_dropdown('plant_id', $options, 'Select', $js);
The dropdown show options OK, but it does NOT show 'Select' as the "selected"/default value. It shows up with the first option of the array instead.
The HTML source also shows 'Select' in form_dropdown was ignored.
I really need this dropdown to show up with 'Select' as default so as to force the user to activate the onChange function.
Any idea what is going on here or how to solve this issue?
You need to have the default option in your $options array...
So before your foreach, do:
$options = array('Select');
I should add, this will have the value of 0 in the dropdown, but as its the first element in the array it will be selected by default, unless another option is passed as the default value.
If you wanted to explicitly set this value as the default you would pass 0 as the default argument.