joomla 2.5 saving multiple select lists? - joomla

I'm trying to add a multiple select list to my backend component, but I can't seem to get it to work. I've tried searching the joomla forums and have tried what they've suggested, but it still doesn't work.
Here is what I have done:
/models/fields/categories.php
foreach ($result as $item) {
$options[] = JHtml::_('select.option', $item->id, $item->title);
};
$drawField = '';
$drawField .= '<select name="'.$this->name.'" id="'.$this->name.'" class="inputbox" size="10" multiple="multiple">';
$drawField .= JHtml::_('select.options', $options, 'value', 'text', $strVal, true);
$drawField .= '</select>';
return $drawField;
/models/forms/edit.xml
<field name="catid" type="categories" multiple="true" size="40" class="inputbox" label="COM_PRODUCTS_FORM_LBL_EDIT_CATID" description="COM_PRODUCTS_FORM_DESC_EDIT_CATID" required="true" filter="safehtml" />
/models/edit.php
protected function loadFormData()
{
$data = JFactory::getApplication()->getUserState('com_products.edit.edit.data', array());
if (empty($data)) {
$data = $this->getItem();
$data->catid = explode(',',$data->catid);
}
return $data;
}
/tables/edit.php
public function check() {
if (property_exists($this, 'ordering') && $this->id == 0) {
$this->ordering = self::getNextOrder();
}
$this->catid = implode(',',$this->catid);
return parent::check();
}
It saves the field catid as "Array" in the backend. Yet when I put in manually 143,148 as the field value, it doesn't highlight those fields, so obviously my implode/explode aren't working.. Any help would be appreciated!!
Thanks :)

Ok figured it out.. The issue was this: filter="safehtml" in the xml file if anyone else is having issues with the same thing... All is good now :)

Related

Display value in view

In this codeigniter model i have this query testing if value entered in input exists in database..
function get_search_form() {
$match = $this->input->post('search1');
$this->db->where('numero',$match);
$this->db->where('inscris','non');
$q = $this->db->get('transaction');
if($q->num_rows()>0)
{
foreach($q->result() as $row)
{
$data[] = $row;
}
return $data;
}
}
Behold the controller i'd like to display value grabbed in input in view inscription.php
function search()
{
$data['row'] = $this->site_model->get_search_form();
$this->load->view('acceuil/aside');
$this->load->view('acceuil/inscription', $data);
}
My issue is how to display in that view input value and a form if this value exists in database ?
I have tried like this but i need help :
inscription view:
<?=form_open('navigation/search');?>
<input type="text" name="search1" id="search1" required />
<input type='submit' value='Display' />
<?=form_close();?>
I try to display the form like this but i don't know how to display as well the input value entered
<?php
if( $row > 0 )
{
?>
les champs du formulaire ici....
<?php
}else
{ }
?>
In your view you can check if the variable $row is not null (because it will be null when no rows are found):
if ($row !== null) {
// do stuff
}
You can modify the model function to return some other value if no rows are found, for example, by setting the $data to an empty array:
function get_search_form() {
$match = $this->input->post('search1');
$this->db->where('numero',$match);
$this->db->where('inscris','non');
$q = $this->db->get('transaction');
$data = array(); // <--- here
if($q->num_rows()>0)
{
foreach($q->result() as $row)
{
$data[] = $row;
}
return $data;
}
}
And then in the view you can simply loop the data:
foreach($row as $r) {
// do stuff
}
or you can implode the array to use as the input value:
<input type="text"
name="search1"
id="search1" required
value="<?php echo implode(' ', $row); ?>" />
You could also use html entities here, in case double quotes are possible to appear in what your model function returns (I have no idea what it returns).
you can access $data global object like this check
<?php
if( isset($row))
{
foreach($row as $v){
//Do the operations here
}
}else
{
//Do the operations here
}
?>

Codeigniter Form Helper - How to add additional parameters to "select" control?

I need to modify a site that was written in Codeigniter but I'm no expert.
One thing I'd like to do is modify a select control in a form to use ms-dropdown for a drop-down list including pictures.
However, I can't work out how to make the Codeigniter form helper render parameters other than ID and Value in each option. In this case, to make ms-dropdown work, it would need to also render data-image="..." in each option.
The current code looks like:
$dropdown = array(
'name'=>'MyDropDown',
'options' => array('Op1'=>'First Option', 'Op2' =>'Second Option')
);
echo form_dropdown($dropdown['name'],$dropdown['options']);
This renders as
<select name="MyDropDown">
<option value='Op1'>First Option</option>
<option value='Op2'>Second Option</option>
</select>
Is there a way for me to make Codeigniter render
<select name="MyDropDown">
<option value='Op1' data-image="filepath1">First Option</option>
<option value='Op2' data-image="filepath2">Second Option</option>
</select>
You can't. You would need to extend CI's Form Helper and modify
form_dropdown to accept other attributes like ID's
you will have to extend the helper .
to extend the native Form Helper you'll create a file named
application/helpers/MY_form_helper.php, and add or override
functions:
if you want to override function form_dropdown
simply write the function the way you want in MY_form_helper.php
here is the base function
if ( ! function_exists('form_dropdown'))
{
function form_dropdown($name = '', $options = array(), $selected = array(), $extra = '')
{
if ( ! is_array($selected))
{
$selected = array($selected);
}
// If no selected state was submitted we will attempt to set it automatically
if (count($selected) === 0)
{
// If the form name appears in the $_POST array we have a winner!
if (isset($_POST[$name]))
{
$selected = array($_POST[$name]);
}
}
if ($extra != '') $extra = ' '.$extra;
$multiple = (count($selected) > 1 && strpos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : '';
$form = '<select name="'.$name.'"'.$extra.$multiple.">\n";
foreach ($options as $key => $val)
{
$key = (string) $key;
if (is_array($val) && ! empty($val))
{
$form .= '<optgroup label="'.$key.'">'."\n";
foreach ($val as $optgroup_key => $optgroup_val)
{
$sel = (in_array($optgroup_key, $selected)) ? ' selected="selected"' : '';
$form .= '<option value="'.$optgroup_key.'"'.$sel.'>'.(string) $optgroup_val."</option>\n";
}
$form .= '</optgroup>'."\n";
}
else
{
$sel = (in_array($key, $selected)) ? ' selected="selected"' : '';
$form .= '<option value="'.$key.'"'.$sel.'>'.(string) $val."</option>\n";
}
}
$form .= '</select>';
return $form;
}
}
you have to edit this part ,
foreach ($options as $key => $val)
{
$key = (string) $key;
if (is_array($val) && ! empty($val))
{
$form .= '<optgroup label="'.$key.'">'."\n";
foreach ($val as $optgroup_key => $optgroup_val)
{
$sel = (in_array($optgroup_key, $selected)) ? ' selected="selected"' : '';
$form .= '<option value="'.$optgroup_key.'"'.$sel.'>'.(string) $optgroup_val."</option>\n";
}
$form .= '</optgroup>'."\n";
}
else
{
$sel = (in_array($key, $selected)) ? ' selected="selected"' : '';
$form .= '<option value="'.$key.'"'.$sel.'>'.(string) $val."</option>\n";
}
}
as you can see , only the option's value attribute is set by the function , you can edit this code and
do the thing you want ,
try it , if you could not do it , tell me i ll help you , but first give it a try :)
Consider doing something like this:
<script type="text/javascript">
var filepath = <?=json_encode($dropdown['filepath'])?>;
</script>
$dropdown['filepath'] would use the option value as keys and store the filepath as the value. Then you can simply access filepath[$(this).val()] upon change event.
Example output:
<script type="text/javascript">
var filepath = { 'Op1' : 'filepath1', 'Op2' : 'filepath2' };
$('select').bind('change', function() {
console.log(filepath[$(this).val()]);
});
</script>
As much as I love using data- attributes, one must not forget other ways to achieve their goals.
In case it helps anyone, I found a work-around using JQuery.
I made a javascript function that applied the data-image attribute to each option field once the page was ready, then called the msDropdown function afterwards.
function PiccifyShowDropdown(){
var Diagrams = new Array(
"/assets/images/icons/SixtyToHundredPercent.png",
"/assets/images/icons/LessThanThirtyPercent.png",
"/assets/images/icons/ThirtyToSixtyPercent.png",
"/assets/images/icons/SixtyToHundredPercent.png"
);
$("#Show > option").each(
function() {
$(this).attr("data-image",Diagrams[this.index]);
}
);
$("#Show").msDropdown({visibleRows:2});
}
This seems to have worked, so now I just need someone to solve the same problem as this guy...

Codeigniter validation, passing form data from controller function recipient to another

Im currently, exploring the validation library that is offered by ci.. and im currently having some trouble. ive tried to do some workarounds but to my disappoint it further messed up my codes. So ill just ask the pro's what i should do.
My view:
<?php echo validation_errors(); ?>
<?php echo form_open('bookstore/validateinsert');?>
<table cellpadding='4' align='center'>
<th>Title</th>
<tr>
<td><input type="text" name="bkname" value="<?php echo set_value('bkname');?>"/></td>
</tr>
<th>Author</th>
<tr>
<td><input type="text" name="bkauthor" value="<?php echo set_value('bkauthor'); ?>"/></td>
</tr>
<th>Released Year</th>
<tr>
<td><input type="text" name="bkyear" value="<?php echo set_value('bkyear'); ?>"/></td>
</tr>
<th>ISBN</th>
<tr>
<td><input type="text" name="bkisbn" value="<?php echo set_value('bkisbn'); ?>"/></td>
</tr>
<tr>
<td><input type='submit' value='insert'/></td>
</tr>
<?php echo form_close();?>
</table>
My controller:
public function validateinsert()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('bkname', 'Book Name', 'required|is_unique[books.book_name]');
$this->form_validation->set_rules('bkauthor', 'Book Author', 'required');
$this->form_validation->set_rules('bkyear', 'Year Published', 'required|max_length[4]');
$this->form_validation->set_rules('bkisbn', 'Book ISBN', 'required');
if ($this->form_validation->run() == FALSE)
{
$this->insertbook();
}
else
{
$this->load->view('showbooks');
}
}
public function insertbook()
{
if($_POST)
{
$data = array(
'book_id' => null,
'book_name' => $_POST['bkname'],
'book_author' => $_POST['bkauthor'],
'book_year' => $_POST['bkyear'],
'book_isbn' => $_POST['bkisbn']
);
$duplicate = $this->_searchbook('book_name',$data['book_name']);
if(!$duplicate)
{
$insertid = $this->books_model->insert_books($data);
if($insertid)
{
$data['success'] = TRUE;
$data['message'] = "The book title was successfully added.";
}
else
{
$data['success'] = FALSE;
$data['message'] = "An error was encountered.";
}
}
else
{
$data['success'] = FALSE;
$data['message'] = "The book title is already in the system";
}
}
$this->load->view('book_entry');
}
I think that is all there is a need to know about..
The validations work perfect, although i have a question, what is the syntax for all numbers only as i want it included on my isbn and bkyear rules.(P.S. I still prefer javascript with its onblur feature)
THE PROBLEM:
The validations work as i said above, but my insert does not. If there are no rules broken, i calIed the insertbook function but it inserted nothing, as i assumed when i first made the validationfunction as the recipient of the form and i was right, the insertbook probably did not recieve the data in the form. What should i do? P.S. I have an idea in mind that i should just merge those 2 functions together but that would make a mess(or does it matter?). Ill just consult ur opinion on this.
Your php logic is wrong:
if ($this->form_validation->run() == FALSE)
{
// If validation fails load view
// $this->insertbook();
$this->load->view('showbooks');
}
else
{
//If validation pass insert book
// $this->load->view('showbooks');
$this->insertbook();
}
Also this $duplicate = $this->_searchbook('book_name',$data['book_name']); you can replace with validation rule:
$this->form_validation->set_rules('book_name', 'Name of book', 'is_unique[table.column]');
For your "only numbers problem" ->
$this->form_validation->set_rules('bkyear', 'Year', 'numeric');
Furthermore you can find a lot of build-in rules here:
http://ellislab.com/codeigniter/user-guide/libraries/form_validation.html#rulereference
If you need some custom rule you can write your own function. See manual here:
http://ellislab.com/codeigniter/user-guide/libraries/form_validation.html#callbacks
try this
public function validateinsert()
{
$this->load->library('form_validation');
if($this->input->post()) {
$this->form_validation->set_rules('bkname', 'Book Name', 'required|is_unique[books.book_name]');
$this->form_validation->set_rules('bkauthor', 'Book Author', 'required');
$this->form_validation->set_rules('bkyear', 'Year Published', 'required|max_length[4]');
$this->form_validation->set_rules('bkisbn', 'Book ISBN', 'required');
if ($this->form_validation->run() != FALSE)
{
$data = array(
'book_id' => null,
'book_name' => $this->input->post('bkname'),
'book_author' => $this->input->post('bkauthor'),
'book_year' => $this->input->post('bkyear'),
'book_isbn' => $this->input->post('bkisbn')
);
$this->insertbook($data);
}
}
else
{
$this->load->view('showbooks');
}
}
public function insertbook($data)
{
$duplicate = $this->_searchbook('book_name',$data['book_name']);
if(!$duplicate)
{
$insertid = $this->books_model->insert_books($data);
if($insertid)
{
$data['success'] = TRUE;
$data['message'] = "The book title was successfully added.";
}
else
{
$data['success'] = FALSE;
$data['message'] = "An error was encountered.";
}
}
else
{
$data['success'] = FALSE;
$data['message'] = "The book title is already in the system";
}
$this->load->view('book_entry');
}
you should look at the other answers because they have pointed out a number of mistakes. if you are doing a database operation - you always have to error check. databases are volatile. its also very easy to make a mistake so you want to isolate database methods.
just wrap an IF around it. whenever possible check for the negative condition first.
if ( $this->insertbook() == false )
{ echo 'omg there is an error something is wrong with my insert code' ;
$this->showError() ;
}
else
{ // no problem
$this->showSuccess() ; }
another way to do this is to return the id of the newly created record.
if ( ! $id = $this->insertbook() ) { echo 'insert failure' ; }
else { echo 'my new id is:' . $id ; }

repopulating the select list generated from database in codeigniter

Hi. I have the form in which I use form_validation If the user make any mistake (leave some required fields empty), user is redirected back to the form, and the form has been re-populated. All works, except my select , which is generated from the database.
Here is my code from the view:
echo "<select name='parentid'" . set_value("parentid"). ">";
echo '<option value = "0">None</option>';
foreach ($faq_categories as $row => $option) {
echo "<option value=" . $option['catid'] . ">" . $option['categoryname']. "</option>";
}
echo '</select>';
Here is my controller code:
public function displayAddFaqCategoryForm($error = null)
{
$data['title'] = "Add new FAQ Category";
$data['main_content'] = 'addFaqCategory';
$selectWhat = array('tname' => 'faq_categories',
'sortby'=> 'catid',
'how' => 'asc'
);
$this->load->model('selectRecords');
$data['faq_categories'] = $this->selectRecords->selectAllRecords($selectWhat);
$this->load->vars($data);
$this->load->view('backOffice/template');
} // end of function displayAddFaqCategoryForm
And here is the model code:
public function selectAllRecords($selectWhat = array())
{
$data = array();
$tname = $selectWhat['tname'];
$sortby = $selectWhat['sortby'];
$how = $selectWhat['how'];
$this->db->order_by($sortby,$how);
$query = $this->db->get($tname);
if($query->num_rows() > 0)
{
foreach($query->result_array() as $row)
{
$data[] = $row;
}
}
$query->free_result();
return $data;
} // end of function selectAllRecords
I am not getting any error messages, just the select is not repopulated with last used. Any help will be deeply appreciated.
You're using set_value() incorrectly
echo "<select name='parentid'" . set_value("parentid"). ">";
It's meant to output the actual value (for text inputs). This would produce something like:
<select name='parentid'ActualValue>
Which is not how a <select> element is populated, and is invalid HTML. See the correct usage in the Form Helper docs.
You can use set_select(), and it goes on your <option>:
foreach ($faq_categories as $row => $option) {
echo "<option value=".form_prep($option['catid']).'"';
echo set_select('parentid', $option['catid']); // outputs selected="selected"
echo ">".html_escape($option['categoryname'])."</option>";
}
I've taken a few other liberties with your code here as you can see, to be on the safe side (always).
If this is too much of a mess, you might be interested in the form_dropdown() function.

Joomla onContentBeforeSave Data to xml not working

I've set up a plugin that should retrieve some data from the form and save it to an xml file. I had tried the code by itself and it worked, but then when I've inserted it into a plugin with the method onContentBeforeSave, it doesn't work anymore.
Here's the code of the plugin, I've no idea of what's not working!
defined('_JEXEC') or die();
jimport('joomla.plugin.plugin');
class plgContentsave2xml extends JPlugin
{
public function __construct($subject, $config)
{ parent::__construct($subject, $config);
}
function onContentBeforeSave($context, &$article, $isNew)
{ global $mainframe;
if(isset($_POST['create_xml']))
{
$doc = new DOMDocument('1.0');
// Formatting the file
$doc->formatOutput = true;
$doc->encoding = "Utf-8";
$field = $_POST['field'];
$field = utf8_encode($field);
$part = $doc->createElement('part');
$part = $doc->appendChild($part);
$field = $doc->createElement('field');
$field = $part->appendChild($field);
$text = $doc->createTextNode($field);
$text = $field->appendChild($text);
}
echo $doc->save('xmlf/' . 'test' . '.xml');
}
return true;
}
}
?>
I think you shouldn't output anything from within your code, and you have a line where you output (or might output) data.
Another point is that you are not checking the context, do you want the code to be execute for articles, categories, etc., or only for articles?
If it's only for articles, you should check if context equals "com_content.article":
if ( $context != "com_content.article" ) { return; }
One last thing. Are you adding fields to your article/category form via the "onContentPrepareForm" event?
If so, you should get your data like this:
function onContentBeforeSave( $context, &$row, $isNew ) {
if ( $context != "com_content.article" ) {
return;
}
jimport( 'joomla.html.parameter' );
$params = new JParameter( $row->attribs );
$create_xml = $params->get( 'create_xml', false );
if ( $create_xml ) {
$field = $params->get( 'field', '');
// The rest of your code here...
//If you don't want these fields to be stored with the params of the article:
$params->set( 'field', '' );
$params->set( 'create_xml', '' );
}
$row->attribs = (string)$params;
return;
}
Besides, if you're not using the "onContentPrepareForm", you can implement it like this:
function onContentPrepareForm($form, $data)
{
$return = true;
if (!($form instanceof JForm))
{
$this->_subject->setError('JERROR_NOT_A_FORM');
$return = false;
} elseif ( $form->getName() != 'com_content.article' ) {
$return = true;
} else {
// Add the registration fields to the form.
JForm::addFormPath( __DIR__ . DIRECTORY_SEPARATOR . 'form' );
$form->loadFile('your_file', false);
$return = true;
}
return $return;
}
You should have a file inside your plugin folder: plugin_folder/form/your_file.xml, with this form:
<?xml version="1.0" encoding="utf-8"?>
<form>
<fields name="attribs">
<fieldset name="create_xml" label="Create XML">
<field name="create_xml" [...]>
<field name="field" [...]>
</fieldset>
</fields>
</form>
I hope it helped!

Resources