⚠ In case you've missed it, we have migrated to our new website, with a brand new forum. For more details about the migration you can read our blog post for website migration. This is an archived forum. ⚠

  •     

profile picture

Default field values (for add form)



rafael84
  • profile picture
  • Member

Posted 27 December 2011 - 20:24 PM

Hello there,

I was struggling to set default field values for the add form. So here's another suggestion for the grocery CRUD.

[b]FILE: application/models/grocery_model.php[/b]

/* NEW */
protected $add_values = array();

/* NEW */
function set_add_value($field_name, $value) {
$this->add_values[$field_name] = $value;
}

/* NEW */
function get_add_values() {
return (object) $this->add_values;
}


[b]FILE: application/libraries/grocery_crud.php[/b]

/* NEW */
public function getModel() {
if($this->basic_model === null)
$this->set_default_Model();
return $this->basic_model;
}
/* NEW */
protected function get_add_values() {
$values = $this->basic_model->get_add_values();
return $values;
}
protected function showAddForm()
{
$this->set_js('assets/grocery_crud/themes/datatables/js/jquery-1.6.2.min.js');

$data = $this->get_common_data();
$data->types = $this->get_field_types();
/* NEW */ $data->field_values = $this->get_add_values(null);

$data->list_url = $this->getListUrl();
$data->insert_url = $this->getInsertUrl();
$data->validation_url = $this->getValidationInsertUrl();

// OLD // $data->input_fields = $this->get_add_input_fields();
/* NEW */ $data->input_fields = $this->get_add_input_fields($data->field_values);

$data->fields = $this->get_add_fields();
$data->hidden_fields = $this->get_add_hidden_fields();

$this->_theme_view('add.php',$data);
}


To set a default field value, you just do something like this:

$crud = new grocery_CRUD();
...
$crud->getModel()->set_add_value('order_date', date("Y-m-d"));
...
$crud->render();


Johnny, I know you have a lot of stuff to do, but could you think about it?

-Rafael

web-johnny
  • profile picture
  • Administrator
  • 1,166 posts

Posted 29 December 2011 - 23:44 PM

[quote name='rafael84' timestamp='1325017466' post='182']
Hello there,

I was struggling to set default field values for the add form. So here's another suggestion for the grocery CRUD.

[b]FILE: application/models/grocery_model.php[/b]

/* NEW */
protected $add_values = array();

/* NEW */
function set_add_value($field_name, $value) {
$this->add_values[$field_name] = $value;
}

/* NEW */
function get_add_values() {
return (object) $this->add_values;
}


[b]FILE: application/libraries/grocery_crud.php[/b]

/* NEW */
public function getModel() {
if($this->basic_model === null)
$this->set_default_Model();
return $this->basic_model;
}
/* NEW */
protected function get_add_values() {
$values = $this->basic_model->get_add_values();
return $values;
}
protected function showAddForm()
{
$this->set_js('assets/grocery_crud/themes/datatables/js/jquery-1.6.2.min.js');

$data = $this->get_common_data();
$data->types = $this->get_field_types();
/* NEW */ $data->field_values = $this->get_add_values(null);

$data->list_url = $this->getListUrl();
$data->insert_url = $this->getInsertUrl();
$data->validation_url = $this->getValidationInsertUrl();

// OLD // $data->input_fields = $this->get_add_input_fields();
/* NEW */ $data->input_fields = $this->get_add_input_fields($data->field_values);

$data->fields = $this->get_add_fields();
$data->hidden_fields = $this->get_add_hidden_fields();

$this->_theme_view('add.php',$data);
}


To set a default field value, you just do something like this:

$crud = new grocery_CRUD();
...
$crud->getModel()->set_add_value('order_date', date("Y-m-d"));
...
$crud->render();


Johnny, I know you have a lot of stuff to do, but could you think about it?

-Rafael
[/quote]

Hello Rafael,
Actually the problem that you will have with this is that everytime I have the add form and you press the button save. Then I have a JavaScript clearForm method to clear all the inputs (/assets/grocery_crud/themes/flexigrid/js/flexigrid-add.js at line 86). So if you like to add it to your project remember to have this in mind. A solution for this is to add some JavaScript to your code to make it work.

As for this it's good as idea but I have really lot of stuff to do, so I am not promising anything for the next versions. You can always fork the grocery crud project at git htub - https://github.com/scoumbourdis/grocery-crud and have a pull request if you want to share a code with the community and improve grocery crud's functionality

rafael84
  • profile picture
  • Member

Posted 02 January 2012 - 00:23 AM

Thanks Johnny, you're right. So here's another approach:

File: assets/grocery_crud/themes/flexigrid/js/Flexigrid-add.js

$(function(){
...
$("#FormLoading").ajaxStart(function(){
$(this).show();
});
$("#FormLoading").ajaxStop(function(){
$(this).fadeOut('slow');
});

clearForm(); // NEW

$('#crudForm').submit(function(){
...
}
}
...
function clearForm() {
$('#crudForm').find(':input').each(function() {
var default_value = $(this).attr('name') + '_default_value';
try { var value = eval(default_value); } catch(err) {}

switch(this.type) {
case 'password':
case 'select-multiple':
case 'select-one':
case 'text':
case 'textarea':
if (typeof(value) === 'undefined') {
$(this).val('');
} else {
$(this).val(value);
}
break;
case 'checkbox':
case 'radio':
if (typeof(value) === 'undefined') {
this.checked = Boolean(value);
} else {
this.checked = false;
}
}
});

$('.remove-all').each(function(){
$(this).trigger('click');
});
}


In my view, I have declared some javascript variables in order to define the default values for some fields. Like this:

<html>
...
<body>
<script type='text/javascript'>
var order_date_default_value = '2012-01-01';
var lenses_default_value = 'FAR';
</script>
...
<?php echo $output; ?>
...
</html>


As you can see above, there default values for two fields, the [b]order_date[/b] and the [b]lenses[/b] field.

What do you think about this solution?

wclark
  • profile picture
  • Member

Posted 01 February 2012 - 00:11 AM

I agree that the ability to set default values on forms is something that needs to be addressed to make groceryCRUD complete.

Luan
  • profile picture
  • Member

Posted 30 March 2012 - 18:22 PM

Actualy i do this using the callback_add_field function.


[b]Example:[/b]

[color=#000000][b]function[/b][/color] example_callback_add_field[color=#66cc66]([/color][color=#66cc66])[/color][color=#66cc66]{[/color]
[color=#0000ff]$this[/color]->[color=#006600]grocery_crud[/color]->[color=#006600]set_table[/color][color=#66cc66]([/color][color=#ff0000]'offices'[/color][color=#66cc66])[/color];
[color=#0000ff]$this[/color]->[color=#006600]grocery_crud[/color]->[color=#006600]set_subject[/color][color=#66cc66]([/color][color=#ff0000]'Office'[/color][color=#66cc66])[/color];
[color=#0000ff]$this[/color]->[color=#006600]grocery_crud[/color]->[color=#006600]required_fields[/color][color=#66cc66]([/color][color=#ff0000]'city'[/color][color=#66cc66])[/color];
[color=#0000ff]$this[/color]->[color=#006600]grocery_crud[/color]->[color=#006600]columns[/color][color=#66cc66]([/color][color=#ff0000]'city'[/color],[color=#ff0000]'country'[/color],[color=#ff0000]'phone'[/color],[color=#ff0000]'addressLine1'[/color],[color=#ff0000]'postalCode'[/color][color=#66cc66])[/color];

[color=#0000ff]$this[/color]->[color=#006600]grocery_crud[/color]->[color=#006600]callback_add_field[/color][color=#66cc66]([/color][color=#ff0000]'phone'[/color],[color=#000066]array[/color][color=#66cc66]([/color][color=#0000ff]$this[/color],[color=#ff0000]'add_field_callback_1'[/color][color=#66cc66])[/color][color=#66cc66])[/color];
[color=#0000ff]$this[/color]->[color=#006600]grocery_crud[/color]->[color=#006600]callback_add_field[/color][color=#66cc66]([/color][color=#ff0000]'state'[/color],[color=#000066]array[/color][color=#66cc66]([/color][color=#0000ff]$this[/color],[color=#ff0000]'add_field_callback_2'[/color][color=#66cc66])[/color][color=#66cc66])[/color];

[color=#0000ff]$output[/color] = [color=#0000ff]$this[/color]->[color=#006600]grocery_crud[/color]->[color=#006600]render[/color][color=#66cc66]([/color][color=#66cc66])[/color];

[color=#0000ff]$this[/color]->_example_output[color=#66cc66]([/color][color=#0000ff]$output[/color][color=#66cc66])[/color];
[color=#66cc66]}[/color]

[color=#000000][b]function[/b][/color] add_field_callback_1[color=#66cc66]([/color][color=#66cc66])[/color]
[color=#66cc66]{[/color]
[color=#b1b100]return[/color] [color=#ff0000]'+30 <input type="text" maxlength="50" value="YOUR VALUE" name="phone" style="width:462px">'[/color];
[color=#66cc66]}[/color]

[color=#000000][b]function[/b][/color] add_field_callback_2[color=#66cc66]([/color][color=#66cc66])[/color]
[color=#66cc66]{[/color]
[color=#b1b100]return[/color] [color=#FF0000]'<input type="text" maxlength="50" value="[/color][color=#ff0000]YOUR VALUE[/color][color=#ff0000]" name="state" style="width:400px"> ( for U.S. only )'[/color];
[color=#66cc66]}[/color]

Fouzi
  • profile picture
  • Member

Posted 24 May 2012 - 16:13 PM

We can use the default value saved in each field type, this modification require one line code modification

FILE: application/libraries/grocery_crud.php

protected function get_add_input_fields($field_values = null)
{
$fields = $this->get_add_fields();
$types = $this->get_field_types();
$input_fields = array();

foreach($fields as $field_num => $field)
{
$field_info = $types[$field->field_name];

// OLD // $field_value = !empty($field_values) && isset($field_values->{$field->field_name}) ? $field_values->{$field->field_name} : null;
/* NEW */ $field_value = !empty($field_values) && isset($field_values->{$field->field_name}) ? $field_values->{$field->field_name} : $field_info->default;




and when creating your table in SQL, change DEFAULT NULL with DEFAULT your_value


CREATE TABLE `mytable` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(25) DEFAULT NULL,
`longtext` varchar(255) DEFAULT NULL,
`icon` varchar(255) DEFAULT NULL,
`isenabled` tinyint(1) DEFAULT '1',
PRIMARY KEY (`id`)
) ;


everytime you create a new record, the field 'isenabled' will have 1 (true) as a default value

This can be done also with Database Forge Class
What do you think?

Djoudi
  • profile picture
  • Member

Posted 16 October 2012 - 07:45 AM

[quote name='rafael84' timestamp='1325463837' post='205']
Thanks Johnny, you're right. So here's another approach:

File: assets/grocery_crud/themes/flexigrid/js/Flexigrid-add.js

$(function(){
...
$("#FormLoading").ajaxStart(function(){
$(this).show();
});
$("#FormLoading").ajaxStop(function(){
$(this).fadeOut('slow');
});

clearForm(); // NEW

$('#crudForm').submit(function(){
...
}
}
...
function clearForm() {
$('#crudForm').find(':input').each(function() {
var default_value = $(this).attr('name') + '_default_value';
try { var value = eval(default_value); } catch(err) {}

switch(this.type) {
case 'password':
case 'select-multiple':
case 'select-one':
case 'text':
case 'textarea':
if (typeof(value) === 'undefined') {
$(this).val('');
} else {
$(this).val(value);
}
break;
case 'checkbox':
case 'radio':
if (typeof(value) === 'undefined') {
this.checked = Boolean(value);
} else {
this.checked = false;
}
}
});

$('.remove-all').each(function(){
$(this).trigger('click');
});
}


In my view, I have declared some javascript variables in order to define the default values for some fields. Like this:

<html>
...
<body>
<script type='text/javascript'>
var order_date_default_value = '2012-01-01';
var lenses_default_value = 'FAR';
</script>
...
<?php echo $output; ?>
...
</html>


As you can see above, there default values for two fields, the [b]order_date[/b] and the [b]lenses[/b] field.

What do you think about this solution?
[/quote]

what about datatables theme?

Djoudi
  • profile picture
  • Member

Posted 24 October 2012 - 09:53 AM

[quote name='rafael84' timestamp='1325463837' post='205']
Thanks Johnny, you're right. So here's another approach:

File: assets/grocery_crud/themes/flexigrid/js/Flexigrid-add.js

$(function(){
...
$("#FormLoading").ajaxStart(function(){
$(this).show();
});
$("#FormLoading").ajaxStop(function(){
$(this).fadeOut('slow');
});

clearForm(); // NEW

$('#crudForm').submit(function(){
...
}
}
...
function clearForm() {
$('#crudForm').find(':input').each(function() {
var default_value = $(this).attr('name') + '_default_value';
try { var value = eval(default_value); } catch(err) {}

switch(this.type) {
case 'password':
case 'select-multiple':
case 'select-one':
case 'text':
case 'textarea':
if (typeof(value) === 'undefined') {
$(this).val('');
} else {
$(this).val(value);
}
break;
case 'checkbox':
case 'radio':
if (typeof(value) === 'undefined') {
this.checked = Boolean(value);
} else {
this.checked = false;
}
}
});

$('.remove-all').each(function(){
$(this).trigger('click');
});
}


In my view, I have declared some javascript variables in order to define the default values for some fields. Like this:

<html>
...
<body>
<script type='text/javascript'>
var order_date_default_value = '2012-01-01';
var lenses_default_value = 'FAR';
</script>
...
<?php echo $output; ?>
...
</html>


As you can see above, there default values for two fields, the [b]order_date[/b] and the [b]lenses[/b] field.

What do you think about this solution?
[/quote]

Not work :(

deaconbooze
  • profile picture
  • Member

Posted 29 November 2012 - 18:24 PM

[quote name='Fouzi' timestamp='1337876018' post='1945']
We can use the default value saved in each field type, this modification require one line code modification

FILE: application/libraries/grocery_crud.php

protected function get_add_input_fields($field_values = null)
{
$fields = $this->get_add_fields();
$types = $this->get_field_types();
$input_fields = array();

foreach($fields as $field_num => $field)
{
$field_info = $types[$field->field_name];

// OLD // $field_value = !empty($field_values) && isset($field_values->{$field->field_name}) ? $field_values->{$field->field_name} : null;
/* NEW */ $field_value = !empty($field_values) && isset($field_values->{$field->field_name}) ? $field_values->{$field->field_name} : $field_info->default;




and when creating your table in SQL, change DEFAULT NULL with DEFAULT your_value


CREATE TABLE `mytable` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(25) DEFAULT NULL,
`longtext` varchar(255) DEFAULT NULL,
`icon` varchar(255) DEFAULT NULL,
`isenabled` tinyint(1) DEFAULT '1',
PRIMARY KEY (`id`)
) ;


everytime you create a new record, the field 'isenabled' will have 1 (true) as a default value

This can be done also with Database Forge Class
What do you think?
[/quote]

This is actually a good solution, but unfortunately $field_info->default does not exist in my implementation, so you may need to add it in grocer_crud_model.php -> get_field_types_basic_table() (or you can use your own model to override).


function get_field_types_basic_table()
{
$db_field_types = array();
foreach($this->db->query("SHOW COLUMNS FROM `{$this->table_name}`")->result() as $db_field_type)
{
$type = explode("(",$db_field_type->Type);
$db_type = $type[0];

if(isset($type[1]))
{
$length = substr($type[1],0,-1);
}
else
{
$length = '';
}
$db_field_types[$db_field_type->Field]['db_max_length'] = $length;
$db_field_types[$db_field_type->Field]['db_type'] = $db_type;
$db_field_types[$db_field_type->Field]['db_null'] = $db_field_type->Null == 'YES' ? true : false;
$db_field_types[$db_field_type->Field]['db_extra'] = $db_field_type->Extra;
$db_field_types[$db_field_type->Field]['default'] = $db_field_type->Default; // <------ DEFAULT FIELD
}

goFrendiAsgard
  • profile picture
  • Member

Posted 14 January 2013 - 05:37 AM

Since the first post was made on 2011, I think this is no longer relevant.
So for anyone else look for such a solution, there is already a good news
grocerycrud field-type function already has "default value" as optional third parameter
http://www.grocerycrud.com/documentation/options_functions/field_type

 

EDIT : this is only works for hidden, enum and set field


maugzoide
  • profile picture
  • Member

Posted 22 January 2013 - 16:09 PM

Actually, nothing works.
Grocery CRUD does not support default values (tell me if i am wrong).
I mean, there is something wrong with callback_before_insert.

If you make an invisible field to add action it is replicated to the edit action grid/form.

Is there any "workaround"?

I'm putting the varibles set to invisible, but it is not the better approach.

davidoster
  • profile picture
  • Member

Posted 23 January 2013 - 04:12 AM

As this page[http://www.grocerycrud.com/documentation/options_functions/field_type] says:
"
[b]Note:[/b][color=#2C575B][font=Arial, Tahoma, Helvetica, sans-serif] The third parameter ($value) only works for the hidden, enum and set field and it is not a default value for all the other types.[/font][/color]
"

goFrendiAsgard
  • profile picture
  • Member

Posted 15 February 2013 - 22:07 PM

Good point, I miss that one :p


davidoster
  • profile picture
  • Member

Posted 15 February 2013 - 22:12 PM

Good point, I miss that one :P

:P


ezgoen
  • profile picture
  • Member

Posted 27 March 2013 - 22:30 PM

Hi Folks,

 

Here's another approach - with NO Changes to the library.

 

 

I checked the library code to see what actually gets passed to the callback_field & callback_add_field callbacks when they are invoked.

 

Here's the line of code from application/libraries/grocery_crud.php:2416

 

 

 

 

$field_input = $field_info;
$field_input->input = call_user_func($this->callback_add_field[$field->field_name], $field_value, null, $field_info);
 

 


 

 

The thing I noticed is that there are three values being passed to the callback: $field_value, null and $field_info

So I prototyped my callback to receive all three and take a look whats in them (with var_dump)

 

Interesting ...here's my prototype:

 

 

 

function _cb_add_string_field($field_value, $dontcare, $field_info){
var_dump($field_value);
var_dump($dontcare);
var_dump($field_info)
return "<input id='field-MyFieldName' name='MyFieldName' type='text' value=\"we dont know yet\"/>";
}
 
 

 

 


The thing that interested me was the contents of $field_info, here's what was in there:

 

 

(object) {
->name (string) = "F_ID"
->type (string) = "int"
->default (NULL) =
->max_length (string) = "11"
->primary_key (integer) = 0
->db_max_length (string) = "11"
->db_type (string) = "int"
->db_null (boolean) = "false"
->db_extra (string) = ""
->required (boolean) = "false"
->display_as (string) = "Foreign Key  Index"
->crud_type (string) = "string"
->extras (string) = "What Have We Got Here??"
}
 

 

 

 


Look at the extras field - you wont see anything ... yet

all we need to do to see the text "What Have We Got Here??" in that extras field is this ...

In controller I added the following line :

 

 

$crud->field_type('F_ID', 'string', "What Have We Got Here??");
 

 

 

 


And Hey-Presto I have a default value to use in my callback.

 

So all I did in my controller is create a field type for an already existing field with a default value.

The field type doesn't seem to matter.

two lines of code and a REUSABLE callback prototype can give you your default values.

 

Here's my actual two lines of code:

 

 

 

$crud->field_type('F_ID', 'string', $F_ID);
$crud->callback_add_field('F_ID',array($this,'_cb_add_string_field'));
//also works with $crud->callback_field('F_ID',array($this,'_cb_add_string_field'));
 

 


 

 

Here's my actual callback:

 

 

function _cb_add_string_field($field_value, $dontcare, $field_info){
  $tmpl="<input id='field-%s' name='%s' type='text' value=\"%s\"  />";
  return sprintf($tmpl,$field_info->name,$field_info->name,$field_info->extras);
}

 

 

 

 

and if you want to display the values but still have them posted to the database (readonly)

 

 

 

$crud->field_type('F_ID', 'string', $F_ID);
$crud->callback_field('F_ID',array($this,'_cb_add_readonly_field'));
//also works with $crud->callback_add_field('F_ID',array($this,'_cb_add_readonly_field'));

 

 

 

 

and ..

 

 


function _cb_add_readonly_field($field_value, $dontcare, $field_info){
  $tmpl="<input id='field-%s' name='%s' type='hidden' value=\"%s\"  /><span>%s</span>";
  return sprintf($tmpl,$field_info->name,$field_info->name,$field_info->extras,$field_info->extras);
}
 
 

 

 


Now I hope this helps someone.

Also I would like the big boss to consider at the very least leaving this functionality as it is

OR

to give us this the field info as the default parameter

OR to give us a one-step solution

 

I suppose this could be done with Yet Another Subclass ..

 

I'll post a subclass soon.

 

I hope his helps someone .

 

Cheer's and thanks again for GroceryCrud

 

Ez


ezgoen
  • profile picture
  • Member

Posted 27 March 2013 - 22:56 PM

Hi Folks,

 

Here's the subclass I said I'd build

This will give you default values for the ADD Form

I've tested it a bit and it seems ok - I will be deploying this so if I

find any bugs I'll post fixes as I find them.

 

To use it - drop the subclass into the application/libraries folder

right beside grocery_crud.php

call the new file custom_grocery_crud.php

 

Edit application/controllers/examples.php

 

class Examples extends CI_Controller {

	function __construct()
	{
		parent::__construct();
		
		$this->load->database();
		$this->load->helper('url');
		
		//$this->load->library('grocery_Crud');	
		$this->load->library('custom_grocery_crud');	
	}

...

        function offices_management()
	{
		try{
			//$crud = new grocery_CRUD();
			$crud = new custom_grocery_crud();

			$crud->set_theme('datatables');
			$crud->set_table('offices');
			$crud->set_subject('Office');
			$crud->required_fields('city');
			$crud->columns('city','country','phone','addressLine1','postalCode');

			//our demo
                        $crud->field_set_defaults('city' , 'readonly', 'Hobart,Tasmania');

			$output = $crud->render();
			
			$this->_example_output($output);
			
		}catch(Exception $e){
			show_error($e->getMessage().' --- '.$e->getTraceAsString());
		}
	}

 

 

and run it - its that easy!

 

use field_set_defaults exactly the same way you would use field_type

 

Here's the subclass [attachment=497:custom_grocery_crud.php]

 

and here it is inline for you to peruse:

 


<?php
/**
 * PHP grocery CRUD
 *
 * A Codeigniter library that creates a CRUD automatically with just few lines of code.
 *
 * Copyright (C) 2010 - 2012  John Skoumbourdis. 
 *
 * LICENSE
 *
 * Grocery CRUD is released with dual licensing, using the GPL v3 (license-gpl3.txt) and the MIT license (license-mit.txt).
 * You don't have to do anything special to choose one license or the other and you don't have to notify anyone which license you are using.
 * Please see the corresponding license file for details of these licenses.
 * You are free to use, modify and distribute this software, but all copyright information must remain.
 *
 * @package    	grocery CRUD
 * @copyright  	Copyright (c) 2010 through 2012, John Skoumbourdis
 * @license    	https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
 * @version    	1.3
 * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
 */

// ------------------------------------------------------------------------
include_once(dirname(__FILE__)."/grocery_crud.php");


/**
 * PHP grocery CRUD - Customized
 *
 * Creates a full functional CRUD with few lines of code.
 *
 * @package    	grocery CRUD 
 * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
 * @license     https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
 * @link		http://www.grocerycrud.com/documentation
 *
 * @hacker      Ez (ezgoen@gmail.com) - email me for my real identity
 */

class custom_grocery_crud extends grocery_CRUD{

	protected $field_default_values = array();
	
	function __construct()
	{
		parent::__construct();
	}

	/**
	 * Helper Function
	 *
	 * Created by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 */
	protected function get_field_default_values($field){
		return array_key_exists($field,$this->field_default_values) ? $this->field_default_values[$field] : null;
	}

	/**
	 * Use this function exactly the same way you would use field_type()
	 * see : http://www.grocerycrud.com/documentation/options_functions/field_type
	 *
	 * Created by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				in the case of an ADD data form I want to provide default values to the fields.
	 *				I may also want to make the fields with default values readonly or completely hidden
	 *				The parent object does not allow/facilitate addidtion of default values to visible 
	 *				fields other than:
	 *					hidden
	 *					invisible
	 *					password
	 *					enum
	 *					set
	 *					dropdown
	 *					multiselect
	 *
	 *				I havent fooled around with invisible - so I cant comment on anything to do with that.
	 *				however I want my other fields - most commonly string and integer to have default values
	 *				additionally I may also want thos values to either editable OR readonly and visible at 
	 *				the same time AND I want my default values (if they are readonly) to go into the database
	 *				
	 */
	public function field_set_defaults($field,$type,$value){
		  $this->field_default_values[$field]=array('type'=>$type,'value'=>$value);
	}


	/**
	 * Work out what to do with input fields for add record
	 * 
	 *
	 * Modified/Hacked by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				in the case of an ADD data form I want to provide default values to the fields.
	 *				I may also want to make the fields with default values readonly or completely hidden
	 */
	protected function get_add_input_fields($field_values = null)
	{
		$fields = $this->get_add_fields();
		$types 	= $this->get_field_types();
		
		$input_fields = array();
		
		foreach($fields as $field_num => $field)
		{	
			$field_info = $types[$field->field_name];
			
			$field_value = !empty($field_values) && isset($field_values->{$field->field_name}) ? $field_values->{$field->field_name} : null;
	

			$field_default_values=$this->get_field_default_values($field->field_name);
			if (! empty($field_default_values) and empty($field_value) ){
				//if $field_info is not set at this point we need to construct one
				if (!isset($field_info)){
						$field_info = (object)array();
				}
				$field_info->custom_default=True; //this is what we look for to ensure we only change the behaviour we want to
				$field_info->crud_type=$field_default_values['type'];
				$field_info->type=$field_default_values['type'];
				$field_info->default=$field_default_values['value'];
				$field_info->extras=$field_default_values['value'];
				$field_value=$field_default_values['value'];
			}
			
			//no changes below here
			if(!isset($this->callback_add_field[$field->field_name]))
			{
				$field_input = $this->get_field_input($field_info, $field_value);
			}
			else
			{
				$field_input = $field_info;
				$field_input->input = call_user_func($this->callback_add_field[$field->field_name], $field_value, null, $field_info);
			}
			
			switch ($field_info->crud_type) {
				case 'invisible':
					unset($this->add_fields[$field_num]);
					unset($fields[$field_num]);
					continue;
				break;
				case 'hidden':
					$this->add_hidden_fields[] = $field_input;
					unset($this->add_fields[$field_num]);
					unset($fields[$field_num]);
					continue;
				break;
			}			
			
			$input_fields[$field->field_name] = $field_input; 
		}
		
		return $input_fields;
	}
	
	/**
	 * Get the html input for the specific field with the 
	 * current value
	 * 
	 * @param object $field_info
	 * @param string $value
	 * @return object
	 *
	 * Modified/Hacked by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				in the case of an ADD data form I want my readonly default values to go into
	 *				the database.
	 *				The default behaviour of 'readonly' fields is to not actually "be a form field"
	 *				they are instead just text in a div like this :
	 *					<div id="field-YOUR_FIELD" class="readonly_label">Your Default Value</div>
	 *				this modification adds a hidden form field that will put the default values you 
	 *				want into the database like this :
	 *					<div id="field-YOUR_FIELD" class="readonly_label">Your Default Value</div>
	 *					<input id='field-YOUR_FIELD' type='hidden' name='YOUR_FIELD' value='Your Default Value' />
	 *
	 */
	protected function get_field_input($field_info, $value = null)
	{
			$real_type = $field_info->crud_type;
			
			$types_array = array(
					'integer', 
					'text',
					'true_false',
					'string', 
					'date',
					'datetime',
					'enum',
					'set',
					'relation', 
					'relation_n_n',
					'upload_file',
					'hidden',
					'password', 
					'readonly',
					'dropdown',
					'multiselect'
			);
			if (in_array($real_type,$types_array)) {
				/* A quick way to go to an internal method of type $this->get_{type}_input . 
				 * For example if the real type is integer then we will use the method
				 * $this->get_integer_input
				 *  */
				$field_info->input = $this->{"get_".$real_type."_input"}($field_info,$value); 
				//my addition here...
				if ((property_exists($field_info,'custom_default')) and ( $real_type=="readonly" )) {
					$field_info->crud_type='hidden';
					$field_info->type='hidden';
					$field_info->input .= $this->{"get_hidden_input"}($field_info,$value); 
					$field_info->crud_type=$real_type;
					$field_info->type=$real_type;
				}
				//no changes below here
			}
			else
			{
				$field_info->input = $this->get_string_input($field_info,$value);
			}
		
		return $field_info;
	}
}
	
?>

 

 

 

I hope this actuall helps people - works for me.

 

 

Cheers everyone and thanks for Grocerycrud :)

 

 

Ez

 

davidoster
  • profile picture
  • Member

Posted 31 March 2013 - 01:48 AM

Hi Folks,

 

Here's the subclass I said I'd build

This will give you default values for the ADD Form

I've tested it a bit and it seems ok - I will be deploying this so if I

find any bugs I'll post fixes as I find them.

 

To use it - drop the subclass into the application/libraries folder

right beside grocery_crud.php

call the new file custom_grocery_crud.php

 

Edit application/controllers/examples.php

 

class Examples extends CI_Controller {

	function __construct()
	{
		parent::__construct();
		
		$this->load->database();
		$this->load->helper('url');
		
		//$this->load->library('grocery_Crud');	
		$this->load->library('custom_grocery_crud');	
	}

...

        function offices_management()
	{
		try{
			//$crud = new grocery_CRUD();
			$crud = new custom_grocery_crud();

			$crud->set_theme('datatables');
			$crud->set_table('offices');
			$crud->set_subject('Office');
			$crud->required_fields('city');
			$crud->columns('city','country','phone','addressLine1','postalCode');

			//our demo
                        $crud->field_set_defaults('city' , 'readonly', 'Hobart,Tasmania');

			$output = $crud->render();
			
			$this->_example_output($output);
			
		}catch(Exception $e){
			show_error($e->getMessage().' --- '.$e->getTraceAsString());
		}
	}

 

 

and run it - its that easy!

 

use field_set_defaults exactly the same way you would use field_type

 

Here's the subclass attachicon.gifcustom_grocery_crud.php

 

and here it is inline for you to peruse:

 


<?php
/**
 * PHP grocery CRUD
 *
 * A Codeigniter library that creates a CRUD automatically with just few lines of code.
 *
 * Copyright (C) 2010 - 2012  John Skoumbourdis. 
 *
 * LICENSE
 *
 * Grocery CRUD is released with dual licensing, using the GPL v3 (license-gpl3.txt) and the MIT license (license-mit.txt).
 * You don't have to do anything special to choose one license or the other and you don't have to notify anyone which license you are using.
 * Please see the corresponding license file for details of these licenses.
 * You are free to use, modify and distribute this software, but all copyright information must remain.
 *
 * @package    	grocery CRUD
 * @copyright  	Copyright (c) 2010 through 2012, John Skoumbourdis
 * @license    	https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
 * @version    	1.3
 * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
 */

// ------------------------------------------------------------------------
include_once(dirname(__FILE__)."/grocery_crud.php");


/**
 * PHP grocery CRUD - Customized
 *
 * Creates a full functional CRUD with few lines of code.
 *
 * @package    	grocery CRUD 
 * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
 * @license     https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
 * @link		http://www.grocerycrud.com/documentation
 *
 * @hacker      Ez (ezgoen@gmail.com) - email me for my real identity
 */

class custom_grocery_crud extends grocery_CRUD{

	protected $field_default_values = array();
	
	function __construct()
	{
		parent::__construct();
	}

	/**
	 * Helper Function
	 *
	 * Created by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 */
	protected function get_field_default_values($field){
		return array_key_exists($field,$this->field_default_values) ? $this->field_default_values[$field] : null;
	}

	/**
	 * Use this function exactly the same way you would use field_type()
	 * see : http://www.grocerycrud.com/documentation/options_functions/field_type
	 *
	 * Created by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				in the case of an ADD data form I want to provide default values to the fields.
	 *				I may also want to make the fields with default values readonly or completely hidden
	 *				The parent object does not allow/facilitate addidtion of default values to visible 
	 *				fields other than:
	 *					hidden
	 *					invisible
	 *					password
	 *					enum
	 *					set
	 *					dropdown
	 *					multiselect
	 *
	 *				I havent fooled around with invisible - so I cant comment on anything to do with that.
	 *				however I want my other fields - most commonly string and integer to have default values
	 *				additionally I may also want thos values to either editable OR readonly and visible at 
	 *				the same time AND I want my default values (if they are readonly) to go into the database
	 *				
	 */
	public function field_set_defaults($field,$type,$value){
		  $this->field_default_values[$field]=array('type'=>$type,'value'=>$value);
	}


	/**
	 * Work out what to do with input fields for add record
	 * 
	 *
	 * Modified/Hacked by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				in the case of an ADD data form I want to provide default values to the fields.
	 *				I may also want to make the fields with default values readonly or completely hidden
	 */
	protected function get_add_input_fields($field_values = null)
	{
		$fields = $this->get_add_fields();
		$types 	= $this->get_field_types();
		
		$input_fields = array();
		
		foreach($fields as $field_num => $field)
		{	
			$field_info = $types[$field->field_name];
			
			$field_value = !empty($field_values) && isset($field_values->{$field->field_name}) ? $field_values->{$field->field_name} : null;
	

			$field_default_values=$this->get_field_default_values($field->field_name);
			if (! empty($field_default_values) and empty($field_value) ){
				//if $field_info is not set at this point we need to construct one
				if (!isset($field_info)){
						$field_info = (object)array();
				}
				$field_info->custom_default=True; //this is what we look for to ensure we only change the behaviour we want to
				$field_info->crud_type=$field_default_values['type'];
				$field_info->type=$field_default_values['type'];
				$field_info->default=$field_default_values['value'];
				$field_info->extras=$field_default_values['value'];
				$field_value=$field_default_values['value'];
			}
			
			//no changes below here
			if(!isset($this->callback_add_field[$field->field_name]))
			{
				$field_input = $this->get_field_input($field_info, $field_value);
			}
			else
			{
				$field_input = $field_info;
				$field_input->input = call_user_func($this->callback_add_field[$field->field_name], $field_value, null, $field_info);
			}
			
			switch ($field_info->crud_type) {
				case 'invisible':
					unset($this->add_fields[$field_num]);
					unset($fields[$field_num]);
					continue;
				break;
				case 'hidden':
					$this->add_hidden_fields[] = $field_input;
					unset($this->add_fields[$field_num]);
					unset($fields[$field_num]);
					continue;
				break;
			}			
			
			$input_fields[$field->field_name] = $field_input; 
		}
		
		return $input_fields;
	}
	
	/**
	 * Get the html input for the specific field with the 
	 * current value
	 * 
	 * @param object $field_info
	 * @param string $value
	 * @return object
	 *
	 * Modified/Hacked by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				in the case of an ADD data form I want my readonly default values to go into
	 *				the database.
	 *				The default behaviour of 'readonly' fields is to not actually "be a form field"
	 *				they are instead just text in a div like this :
	 *					<div id="field-YOUR_FIELD" class="readonly_label">Your Default Value</div>
	 *				this modification adds a hidden form field that will put the default values you 
	 *				want into the database like this :
	 *					<div id="field-YOUR_FIELD" class="readonly_label">Your Default Value</div>
	 *					<input id='field-YOUR_FIELD' type='hidden' name='YOUR_FIELD' value='Your Default Value' />
	 *
	 */
	protected function get_field_input($field_info, $value = null)
	{
			$real_type = $field_info->crud_type;
			
			$types_array = array(
					'integer', 
					'text',
					'true_false',
					'string', 
					'date',
					'datetime',
					'enum',
					'set',
					'relation', 
					'relation_n_n',
					'upload_file',
					'hidden',
					'password', 
					'readonly',
					'dropdown',
					'multiselect'
			);
			if (in_array($real_type,$types_array)) {
				/* A quick way to go to an internal method of type $this->get_{type}_input . 
				 * For example if the real type is integer then we will use the method
				 * $this->get_integer_input
				 *  */
				$field_info->input = $this->{"get_".$real_type."_input"}($field_info,$value); 
				//my addition here...
				if ((property_exists($field_info,'custom_default')) and ( $real_type=="readonly" )) {
					$field_info->crud_type='hidden';
					$field_info->type='hidden';
					$field_info->input .= $this->{"get_hidden_input"}($field_info,$value); 
					$field_info->crud_type=$real_type;
					$field_info->type=$real_type;
				}
				//no changes below here
			}
			else
			{
				$field_info->input = $this->get_string_input($field_info,$value);
			}
		
		return $field_info;
	}
}
	
?>

 

 

 

I hope this actuall helps people - works for me.

 

 

Cheers everyone and thanks for Grocerycrud :)

 

 

Ez

 

 

This sounds interesting. I'll have a look later this week to see how it goes.


ezgoen
  • profile picture
  • Member

Posted 05 April 2013 - 04:46 AM

 

Hi again

 

I've made another enhancement to my subclass.

 

The facility to have dynamic where clauses.

 

here's an explanation :

 

Say I cave a catalogue item (table 1) that has images (table 2)

 

I want all my images - site wide - to be in my image table (table 2)

 

I may have other tables (collections) that have images

 

so clearly I need to have "image id" and "foreign_id" in my image table.

 

"Image id" identifies a unique image and "foreign_id" identifies a set of images.

 

I also have "collection_name" in my images table (table 2) so that I dont get any id collisions.

 

and I have an image title in the image table.

 

I also want to have an image id of my default image in the catalogue table

 

In this case my "foreign_id" would be the "catalogue_id" of my catalogue item.

and "collection_name" would be 'catalogue"

 

You still with me ??

 

so when I edit a catalogue item I want also to access a relationship 

show me all of the images in (table 2) where "collection_name" == 'catalogue' and "foreign_id" == "catalogue_id"

 

getting clearer??

 

we've all had to do this - in grocerycrud - using callbacks

 

because we cant set the "where part" in set_relation() to a value from the table in a controller

unless we do it in a callback - (which is fine - but this is easier)

 

so - to summarize:

 

when I edit a catalogue item - I want to be able to add images to it

I want to be able to set a default image

 

so what if for the above example we could do this :

 

for example:

   $crud->set_relation('Catalogue_Default_Image_id','Images','Images_Title',array('Images_Foreign_ID'=>'{Catalogue_ID}'));

 

The actual set_relation reads like this:

 

   $crud->set_relation('IMG_ID','Images','Title',array('F_ID'=>'{ID}'));

 

just like in the docs http://www.grocerycrud.com/documentation/options_functions/set_relation

 

You can have as many fields you like to call from the other table and
the syntax is really simple. Just at the 3rd field you will have the
symbol { and } . So it will be for example:


 
$crud->set_relation('user_id','users','{username} - {last_name} {first_name}');
 

 

you can have the system replace values that are surrounded by curly braces "{}" in the where clause.

but ONLY in the value field - it doesnt make sense to change the key field at all.

 

 

so  example    $crud->set_relation('IMG_ID','Images','Title',array('F_ID'=>'{ID}','Image_Type'=>"Catalogue"));

 

and a row in the catalogue like this

 

ID=>2, IMG_ID->11, Text->'something about a catalogue item'

 

at run time the resulting where part would end up 

 

array('F_ID'=>'2','Image_Type'=>"Catalogue") 

 

Hope my explanation make sense to everyone

 

so here's my updated subclass

note -

I make the mods in a subclass so that I NEVER have to change the underlying library.

Also, I have to do some more reading to find out if I can do all this in a model which would take the hassle out of subclassing

 

I've also made some minor changes to the set_css and set_js functionality so that I can use them in my controller and other 

libraries.

 

anyway here you go - enjoy

 

its kinda big - hope thats ok  - maybe next time I'll just post a file

<?php
/**
 * PHP grocery CRUD
 *
 * A Codeigniter library that creates a CRUD automatically with just few lines of code.
 *
 * Copyright (C) 2010 - 2012  John Skoumbourdis. 
 *
 * LICENSE
 *
 * Grocery CRUD is released with dual licensing, using the GPL v3 (license-gpl3.txt) and the MIT license (license-mit.txt).
 * You don't have to do anything special to choose one license or the other and you don't have to notify anyone which license you are using.
 * Please see the corresponding license file for details of these licenses.
 * You are free to use, modify and distribute this software, but all copyright information must remain.
 *
 * @package    	grocery CRUD
 * @copyright  	Copyright (c) 2010 through 2012, John Skoumbourdis
 * @license    	https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
 * @version    	1.3
 * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
 */

// ------------------------------------------------------------------------
include_once(dirname(__FILE__)."/grocery_crud.php");


/**
 * PHP grocery CRUD - Customized
 *
 * Creates a full functional CRUD with few lines of code.
 *
 * @package    	grocery CRUD 
 * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
 * @license     https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
 * @link		http://www.grocerycrud.com/documentation
 *
 * @hacker      Ez (ezgoen@gmail.com) - email me for my real identity
 */

class custom_grocery_crud extends grocery_CRUD{

	protected $field_default_values = array();
	protected $inline='';
	
	function __construct()
	{
		parent::__construct();
		
		//I need these BEFORE render - so we can add include files
		$this->_initialize_variables();
	}
	
	
	/**
	 * override get_layout
	 *
	 * Created by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				I've added functionality to add inline code - like 
	 *				<style type=\"text/css\" > Blah </style>
	 *				<script type=\"text/javascript\"> Blah </script>";
	 *				and so on
	 *
	 *				The gc only has this at the time of the call to render
	 *				so we have to handle it separately
	 *				This is the last function called by render()
	 *					 
	 */
	protected function get_layout()	{		
		//call the parent method
		$result = parent::get_layout();
		//add our stuff
		$result->inline=$this->inline;
		return $result;
	}
	
	/**	 * Helper Function
	 *
	 * Created by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 */
	protected function get_field_default_values($field){
		return array_key_exists($field,$this->field_default_values) ? $this->field_default_values[$field] : null;
	}

	/**
	 * Use this function exactly the same way you would use field_type()
	 * see : http://www.grocerycrud.com/documentation/options_functions/field_type
	 *
	 * Created by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				in the case of an ADD data form I want to provide default values to the fields.
	 *				I may also want to make the fields with default values readonly or completely hidden
	 *				The parent object does not allow/facilitate addidtion of default values to visible 
	 *				fields other than:
	 *					hidden
	 *					invisible
	 *					password
	 *					enum
	 *					set
	 *					dropdown
	 *					multiselect
	 *
	 *				I havent fooled around with invisible - so I cant comment on anything to do with that.
	 *				however I want my other fields - most commonly string and integer to have default values
	 *				additionally I may also want thos values to either editable OR readonly and visible at 
	 *				the same time AND I want my default values (if they are readonly) to go into the database
	 *				
	 */
	public function field_set_defaults($field,$type,$value){
		  $this->field_default_values[$field]=array('type'=>$type,'value'=>$value);
	}

	
	//for backward compatibility
	public function set_css($css_file)	{
		$this->add_include($css_file);
	}

	//for backward compatibility
	public function set_js($js_file){
		$this->add_include($js_file);
	}
	/**
	 * Use this function exactly the same way you would use set_js() or set_css
	 *
	 * Created by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				I wanted my controller to be able to do this too
	 *				I also use a menu library that I kinda adapted 
	 *				it uses some jquery as well - so its better everything uses the same function
	 *				to add js and script files so we dont :
	 *					end up with duplicates includes
	 *					degrade page load times
	 *				
	 *				This function also allows us to add files that are outside the grocerycrud 
	 *				dircetory tree
	 */
	public function add_include($inc_file){
		$fn = (strpos($inc_file,"/") === 0 ) ?  substr($inc_file, 1)  : $inc_file;
		if (strripos($fn,'.js',-3) !== False)  {  
			if (! file_exists("$fn")){
				$fn = $this->default_javascript_path."/$fn" ;
			}
			if(file_exists("$fn")){
				$this->js_files[sha1($fn)] = base_url().$fn;
			} else {
				throw new Exception("Missing JavaScript (.js) file. Tried : $inc_file and $fn");
			}
		} elseif (strripos($inc_file,'.css',-4) !== False) { 
			if (! file_exists("$fn")){
				$fn = $this->default_css_path."/$fn" ;
			}
			if(file_exists("$fn")){
				$this->css_files[sha1($fn)] = base_url().$fn;
			} else {
				throw new Exception("Missing Stylesheet (.css) file. Tried: $inc_file and $fn");
			}
		} else {
			throw new Exception("Request to include unknown file type: $inc_file");
		}
	}

	
	public function add_inline($str){
		$this->inline.="\n$str";
	}
	
	
	/**
	 * Work out what to do with input fields for add record
	 * 
	 *
	 * Modified/Hacked by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				in the case of an ADD data form I want to provide default values to the fields.
	 *				I may also want to make the fields with default values readonly or completely hidden
	 */
	protected function get_add_input_fields($field_values = null)
	{
		$fields = $this->get_add_fields();
		$types 	= $this->get_field_types();
		
		$input_fields = array();
		
		foreach($fields as $field_num => $field)
		{	
			$field_info = $types[$field->field_name];
			
			$field_value = !empty($field_values) && isset($field_values->{$field->field_name}) ? $field_values->{$field->field_name} : null;
	

			$field_default_values=$this->get_field_default_values($field->field_name);
			if (! empty($field_default_values) and empty($field_value) ){
				//if $field_info is not set at this point we need to construct one
				if (!isset($field_info)){
						$field_info = (object)array();
				}
				$field_info->custom_default=True; //this is what we look for to ensure we only change the behaviour we want to
				$field_info->crud_type=$field_default_values['type'];
				$field_info->type=$field_default_values['type'];
				$field_info->default=$field_default_values['value'];
				$field_info->extras=$field_default_values['value'];
				$field_value=$field_default_values['value'];
			}
			
			//no changes below here
			if(!isset($this->callback_add_field[$field->field_name]))
			{
				$field_input = $this->get_field_input($field_info, $field_value);
			}
			else
			{
				$field_input = $field_info;
				$field_input->input = call_user_func($this->callback_add_field[$field->field_name], $field_value, null, $field_info);
				//make our little change
				//allow default field rendering behaviour if user returns false
				//in the callback
				if ($field_input->input === False) {
					$field_input = $this->get_field_input($field_info, $field_value);
				}
			}
			
			switch ($field_info->crud_type) {
				case 'invisible':
					unset($this->add_fields[$field_num]);
					unset($fields[$field_num]);
					continue;
				break;
				case 'hidden':
					$this->add_hidden_fields[] = $field_input;
					unset($this->add_fields[$field_num]);
					unset($fields[$field_num]);
					continue;
				break;
			}			
			
			$input_fields[$field->field_name] = $field_input; 
		}
		
		return $input_fields;
	}
	
	/**
	 * Get the html input for the specific field with the 
	 * current value
	 * 
	 * @param object $field_info
	 * @param string $value
	 * @return object
	 *
	 * Modified/Hacked by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				In the case of an ADD data form I want my readonly default values to go into
	 *				the database.
	 *				The default behaviour of 'readonly' fields is to not actually "be a form field"
	 *				they are instead just text in a div like this :
	 *					<div id="field-YOUR_FIELD" class="readonly_label">Your Default Value</div>
	 *				this modification adds a hidden form field that will put the default values you 
	 *				want into the database like this :
	 *					<div id="field-YOUR_FIELD" class="readonly_label">Your Default Value</div>
	 *					<input id='field-YOUR_FIELD' type='hidden' name='YOUR_FIELD' value='Your Default Value' />
	 *
	 * Dynamic Where Clause MOD 
	 * @explanation:
	 *	 			To Facilitate a call to set_relation like: 
	 *
	 *				$crud->set_relation('OUR_ID','Other_Table','Other_Table_Field1',
	 *									array('Other_Table_Field2'=>'{This_Table_Some_Field_Value}'));
	 *																 ^^ notice the curly braces  ^^
	 *
	 *				Changed the argument lists to include current row data
	 *				that we then pass on to get_relation_input()
	 */
	protected function get_field_input($field_info, $value = null,$row_values = null)
	{
			$real_type = $field_info->crud_type;
			
			$types_array = array(
					'integer', 
					'text',
					'true_false',
					'string', 
					'date',
					'datetime',
					'enum',
					'set',
					'relation', 
					'relation_n_n',
					'upload_file',
					'hidden',
					'password', 
					'readonly',
					'dropdown',
					'multiselect'
			);
			if (in_array($real_type,$types_array)) {
				/* A quick way to go to an internal method of type $this->get_{type}_input . 
				 * For example if the real type is integer then we will use the method
				 * $this->get_integer_input
				 *  */
				 
				//Dynamic Where Clause : added $row_values  to the call to get_relation_input()
				//here I'm just handling the relation type - could do more types later
				//not sure why I'd want to tho
				if (in_array($real_type,array('relation'))){
					$field_info->input = $this->{"get_".$real_type."_input"}($field_info, $value, $row_values ); 
				} else {
					$field_info->input = $this->{"get_".$real_type."_input"}($field_info,$value ); 
				}
				//Default Value mod here...
				if ((property_exists($field_info,'custom_default')) and ( $real_type=="readonly" )) {
					$field_info->crud_type='hidden';
					$field_info->type='hidden';
					$field_info->input .= $this->{"get_hidden_input"}($field_info,$value); 
					$field_info->crud_type=$real_type;
					$field_info->type=$real_type;
				}
				//no changes below here
			}
			else
			{
				$field_info->input = $this->get_string_input($field_info,$value);
			}
		
		return $field_info;
	}


	/**
	 * get_edit_input_fields()
	 * 
	 * @param object $field_values
	 * @return object
	 *
	 * Modified/Hacked by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				extend the functionality - so that a person can do processing
	 *				using the current row data - but still alow default rendering
	 *				by returning boolean False instead of a string.
	 *
	 * Dynamic Where Clause MOD 
	 * @explanation:
	 *	 			To Facilitate a call to set_relation like: 
	 *
	 *				$crud->set_relation('OUR_ID','Other_Table','Other_Table_Field1',
	 *									array('Other_Table_Field2'=>'{This_Table_Some_Field_Value}'));
	 *																 ^^ notice the curly braces  ^^
	 *
	 *				Changed the argument lists for get_field_input() to include current row data
	 *
	 *
	 */
	protected function get_edit_input_fields($field_values = null)
	{
		$fields = $this->get_edit_fields();
		$types 	= $this->get_field_types();
		
		$input_fields = array();
		
		foreach($fields as $field_num => $field)
		{
			$field_info = $types[$field->field_name];			
			
			$field_value = !empty($field_values) && isset($field_values->{$field->field_name}) ? $field_values->{$field->field_name} : null;
			if(!isset($this->callback_edit_field[$field->field_name]))
			{			
			    // Dynamic Where Clause MOD - ADDDED $field_values to the call to get_field_input()
				$field_input = $this->get_field_input($field_info, $field_value, $field_values );
			}
			else
			{
				$primary_key = $this->getStateInfo()->primary_key;
				$field_input = $field_info;
				$field_input->input = call_user_func($this->callback_edit_field[$field->field_name], $field_value, $primary_key, $field_info, $field_values);
				//Default Values Mod
				//allow default field rendering behaviour if user returns false
				//in the callback
				if ($field_input->input === False) {
					// Dynamic Where Clause MOD - ADDDED $field_values to the call to get_field_input()
					$field_input = $this->get_field_input($field_info, $field_value, $field_values);
				}
			}
			
			switch ($field_info->crud_type) {
				case 'invisible':
					unset($this->edit_fields[$field_num]);
					unset($fields[$field_num]);
					continue;
				break;
				case 'hidden':
					$this->edit_hidden_fields[] = $field_input;
					unset($this->edit_fields[$field_num]);
					unset($fields[$field_num]);
					continue;
				break;				
			}			
			
			$input_fields[$field->field_name] = $field_input; 
		}
		
		return $input_fields;
	}	
	
	
	
	/**
	 * override get_relation_input
	 *
	 * Created by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				Dynamic Where clause Mod
	 *				This is where the magic (well, not really) happens 
	 *				we alter the where clause just before 
	 *				the call to th eparent get_relation_input()
	 *					 
	 */
	
	protected function get_relation_input($field_info, $value, $row_values){
		
		list($_field_name , $_related_table, $_related_title_field, $_where_clause , $_order_by ) = $field_info->extras;
		
		if (!empty($row_values) and !empty($_where_clause)){
			$wc=(array) $_where_clause;
			foreach ($wc as $where_key => $where_value){
				foreach ($row_values as $key => $value){
					if ($where_value=="{".$key."}") {
						$_where_clause[$where_key]=$value;
					}					
				}
			}
		}
		$field_info->extras= array($_field_name , $_related_table, $_related_title_field, $_where_clause , $_order_by ) ;
		
		//for some reason that still eludes me $value comes in as a different field value when there is a where clause
		//completely bewildered and no time to dig any deeper - is it a bug ????
		if ( !empty($row_values) ) {
			//this forces $value to be what its supposed to be
			$value = $row_values->$_field_name ;
		}
		
		return parent::get_relation_input($field_info,$value);
	}

	
	/**
	 * change_list_value
	 *
	 * Patched by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				There was a bug where images with uppercase file extensions
	 *				were'nt being displayed inline.
	 *
	 *				This, along with a change to get_upload_file_input
	 *				and /assets/grocery_crud/js/jquery_plugins/config/jquery.fileupload.config.js
	 *
	 *				fixes the behaviour					 
	 */
	protected function change_list_value($field_info, $value = null)	{
		$real_type = $field_info->crud_type;
		
		switch ($real_type) {
			case 'hidden':
			case 'invisible':
			case 'integer':
				
			break;
			case 'true_false':
				if(isset($this->default_true_false_text[$value]))
					$value = $this->default_true_false_text[$value];
			break;
			case 'string':
				$value = $this->character_limiter($value,$this->character_limiter,"...");
			break;
			case 'text':
				$value = $this->character_limiter(strip_tags($value),$this->character_limiter,"...");
			break;
			case 'date':
				if(!empty($value) && $value != '0000-00-00' && $value != '1970-01-01')
				{
					list($year,$month,$day) = explode("-",$value);
					
					$value = date($this->php_date_format, mktime (0, 0, 0, (int)$month , (int)$day , (int)$year));
				}
				else 
				{
					$value = '';
				}
			break;
			case 'datetime':
				if(!empty($value) && $value != '0000-00-00 00:00:00' && $value != '1970-01-01 00:00:00')
				{
					list($year,$month,$day) = explode("-",$value);
					list($hours,$minutes) = explode(":",substr($value,11));
					
					$value = date($this->php_date_format." - H:i", mktime ((int)$hours , (int)$minutes , 0, (int)$month , (int)$day ,(int)$year));
				}
				else 
				{
					$value = '';
				}
			break;
			case 'enum':
				$value = $this->character_limiter($value,$this->character_limiter,"...");
			break;

			case 'multiselect':
				$value_as_array = array();
				foreach(explode(",",$value) as $row_value)
				{
					$value_as_array[] = array_key_exists($row_value,$field_info->extras) ? $field_info->extras[$row_value] : $row_value;
				}
				$value = implode(",",$value_as_array);
			break;			
			
			case 'relation_n_n':
				$value = $this->character_limiter(str_replace(',',', ',$value),$this->character_limiter,"...");
			break;						
			
			case 'password':
				$value = '******';
			break;
			
			case 'dropdown':
				$value = array_key_exists($value,$field_info->extras) ? $field_info->extras[$value] : $value; 
			break;			
			
			case 'upload_file':
				if(empty($value))
				{
					$value = "";
				}
				else
				{
					//uppercase file extension fix :
					$is_image = !empty($value) &&
					(strripos($value,'.jpg',-4) !== False
							|| strripos($value,'.png',-4) !== False
							|| strripos($value,'.jpeg',-5) !== False
							|| strripos($value,'.gif',-4) !== False
							|| strripos($value,'.tiff',-5) !== False)
							? true : false;
					//: uppercase file extension fix
								
					$file_url = base_url().$field_info->extras->upload_path."/$value";
					
					$file_url_anchor = '<a href="'.$file_url.'"';
					if($is_image)
					{
						$file_url_anchor .= ' class="image-thumbnail"><img src="'.$file_url.'" height="50px">';
					}
					else
					{
						$file_url_anchor .= ' target="_blank">'.$this->character_limiter($value,$this->character_limiter,'...',true);
					}
					$file_url_anchor .= '</a>';
					
					$value = $file_url_anchor;
				}
			break;
			
			default:
				$value = $this->character_limiter($value,$this->character_limiter,"...");
			break;
		}
		
		return $value;
	}
	
	
	/**
	 * get_upload_file_input
	 *
	 * Patched by Ez (ezgoen@gmail.com) - email me for my real identity
	 *
	 * @explanation:
	 *				There was a bug where images with uppercase file extensions
	 *				were'nt being displayed inline.
	 *
	 *				This, along with a change to change_list_value
	 *				and /assets/grocery_crud/js/jquery_plugins/config/jquery.fileupload.config.js
	 *
	 *				fixes the behaviour					 
	 */
	
	protected function get_upload_file_input($field_info, $value){
		$this->set_css($this->default_css_path.'/ui/simple/'.grocery_CRUD::JQUERY_UI_CSS);
		$this->set_css($this->default_css_path.'/jquery_plugins/file_upload/file-uploader.css');
		$this->set_css($this->default_css_path.'/jquery_plugins/file_upload/jquery.fileupload-ui.css');

		$this->set_js($this->default_javascript_path.'/jquery_plugins/ui/'.grocery_CRUD::JQUERY_UI_JS);
		$this->set_js($this->default_javascript_path.'/jquery_plugins/tmpl.min.js');
		$this->set_js($this->default_javascript_path.'/jquery_plugins/load-image.min.js');

		$this->set_js($this->default_javascript_path.'/jquery_plugins/jquery.iframe-transport.js');
		$this->set_js($this->default_javascript_path.'/jquery_plugins/jquery.fileupload.js');
		$this->set_js($this->default_javascript_path.'/jquery_plugins/config/jquery.fileupload.config.js');
		
		//Fancybox
		$this->set_css($this->default_css_path.'/jquery_plugins/fancybox/jquery.fancybox.css');
		
		$this->set_js($this->default_javascript_path.'/jquery_plugins/jquery.fancybox.pack.js');
		$this->set_js($this->default_javascript_path.'/jquery_plugins/jquery.easing-1.3.pack.js');	
		$this->set_js($this->default_javascript_path.'/jquery_plugins/config/jquery.fancybox.config.js');		
		
		$unique = uniqid();
		
		$allowed_files = $this->config->file_upload_allow_file_types;
		$allowed_files_ui = '.'.str_replace('|',',.',$allowed_files);
		$max_file_size_ui = $this->config->file_upload_max_file_size;
		$max_file_size_bytes = $this->_convert_bytes_ui_to_bytes($max_file_size_ui);
		
		$this->_inline_js('
			var upload_info_'.$unique.' = { 
				accepted_file_types: /(\\.|\\/)('.$allowed_files.')$/i, 
				accepted_file_types_ui : "'.$allowed_files_ui.'", 
				max_file_size: '.$max_file_size_bytes.', 
				max_file_size_ui: "'.$max_file_size_ui.'" 
			};
				
			var string_upload_file 	= "'.$this->l('form_upload_a_file').'";
			var string_delete_file 	= "'.$this->l('string_delete_file').'";
			var string_progress 			= "'.$this->l('string_progress').'";
			var error_on_uploading 			= "'.$this->l('error_on_uploading').'";
			var message_prompt_delete_file 	= "'.$this->l('message_prompt_delete_file').'";
			
			var error_max_number_of_files 	= "'.$this->l('error_max_number_of_files').'";
			var error_accept_file_types 	= "'.$this->l('error_accept_file_types').'";
			var error_max_file_size 		= "'.str_replace("{max_file_size}",$max_file_size_ui,$this->l('error_max_file_size')).'";
			var error_min_file_size 		= "'.$this->l('error_min_file_size').'";

			var base_url = "'.base_url().'";
			var upload_a_file_string = "'.$this->l('form_upload_a_file').'";			
		');

		$uploader_display_none 	= empty($value) ? "" : "display:none;";
		$file_display_none  	= empty($value) ?  "display:none;" : "";
		
		//uppercase file extension fix :
		$is_image = !empty($value) &&
					(strripos($value,'.jpg',-4) !== False
							|| strripos($value,'.png',-4) !== False
							|| strripos($value,'.jpeg',-5) !== False
							|| strripos($value,'.gif',-4) !== False
							|| strripos($value,'.tiff',-5) !== False)
							? true : false;
		//: uppercase file extension fix
		$image_class = $is_image ? 'image-thumbnail' : '';
		
		$input = '<span class="fileinput-button qq-upload-button" id="upload-button-'.$unique.'" style="'.$uploader_display_none.'">
			<span>'.$this->l('form_upload_a_file').'</span>
			<input type="file" name="'.$this->_unique_field_name($field_info->name).'" class="gc-file-upload" rel="'.$this->getUploadUrl($field_info->name).'" id="'.$unique.'">
			<input class="hidden-upload-input" type="hidden" name="'.$field_info->name.'" value="'.$value.'" rel="'.$this->_unique_field_name($field_info->name).'" />
		</span>';
		
		$this->set_css($this->default_css_path.'/jquery_plugins/file_upload/fileuploader.css');
		
		$file_url = base_url().$field_info->extras->upload_path.'/'.$value;
		
		$input .= "<div id='uploader_$unique' rel='$unique' class='grocery-crud-uploader' style='$uploader_display_none'></div>";
		$input .= "<div id='success_$unique' class='upload-success-url' style='$file_display_none padding-top:7px;'>";
		$input .= "<a href='".$file_url."' id='file_$unique' class='open-file";
		$input .= $is_image ? " $image_class'><img src='".$file_url."' height='50px'>" : "' target='_blank'>$value";
		$input .= "</a> ";
		$input .= "<a href='javascript:void(0)' id='delete_$unique' class='delete-anchor'>".$this->l('form_upload_delete')."</a> ";
		$input .= "</div><div style='clear:both'></div>";
		$input .= "<div id='loading-$unique' style='display:none'><span id='upload-state-message-$unique'></span> <span class='qq-upload-spinner'></span> <span id='progress-$unique'></span></div>";
		$input .= "<div style='display:none'><a href='".$this->getUploadUrl($field_info->name)."' id='url_$unique'></a></div>";
		$input .= "<div style='display:none'><a href='".$this->getFileDeleteUrl($field_info->name)."' id='delete_url_$unique' rel='$value' ></a></div>";
		
		return $input;
	}
	
/*
 * /assets/grocery_crud/js/jquery_plugins/config/jquery.fileupload.config.js
 *
 * Patched by Ez (ezgoen@gmail.com) - email me for my real identity
 *
 * @explanation:
 *				There was a bug where images with uppercase file extensions
 *				were'nt being displayed inline.
 *
 *				This, along with a change to change_list_value
 *				and  get_upload_file_input
 *
 *				fixes the behaviour					 
 *
 *

function show_upload_button(unique_id, uploader_element)
{
	$('#upload-state-message-'+unique_id).html('');
	$("#loading-"+unique_id).hide();

	$('#upload-button-'+unique_id).slideDown('fast');
	$("input[rel="+uploader_element.attr('name')+"]").val('');
	$('#success_'+unique_id).slideUp('fast');	
}

function load_fancybox(elem)
{
	elem.fancybox({
		'transitionIn'	:	'elastic',
		'transitionOut'	:	'elastic',
		'speedIn'		:	600, 
		'speedOut'		:	200, 
		'overlayShow'	:	false
	});		
}

$(function(){
	$('.gc-file-upload').each(function(){
		var unique_id 	= $(this).attr('id');
		var uploader_url = $(this).attr('rel');
		var uploader_element = $(this);
		var delete_url 	= $('#delete_url_'+unique_id).attr('href');
		eval("var file_upload_info = upload_info_"+unique_id+"");
		
	    $(this).fileupload({
	        dataType: 'json',
	        url: uploader_url,
	        cache: false,
	        acceptFileTypes:  file_upload_info.accepted_file_types,
			beforeSend: function(){
	    		$('#upload-state-message-'+unique_id).html(string_upload_file);
				$("#loading-"+unique_id).show();
				$("#upload-button-"+unique_id).slideUp("fast");
			},
	        limitMultiFileUploads: 1,
	        maxFileSize: file_upload_info.max_file_size,			
			send: function (e, data) {						
				
				var errors = '';
				
			    if (data.files.length > 1) {
			    	errors += error_max_number_of_files + "\n" ;
			    }
				
	            $.each(data.files,function(index, file){
		            if (!(data.acceptFileTypes.test(file.type) || data.acceptFileTypes.test(file.name))) {
		            	errors += error_accept_file_types + "\n";
		            }
		            if (data.maxFileSize && file.size > data.maxFileSize) {
		            	errors +=  error_max_file_size + "\n";
		            }
		            if (typeof file.size === 'number' && file.size < data.minFileSize) {
		            	errors += error_min_file_size + "\n";
		            }			            	
	            });	
	            
	            if(errors != '')
	            {
	            	alert(errors);
	            	return false;
	            }
				
			    return true;
			},
	        done: function (e, data) {
				if(typeof data.result.success != 'undefined' && data.result.success)
				{
					$("#loading-"+unique_id).hide();
					$("#progress-"+unique_id).html('');
		            $.each(data.result.files, function (index, file) {
		            	$('#upload-state-message-'+unique_id).html('');
		            	$("input[rel="+uploader_element.attr('name')+"]").val(file.name);
		            	var file_name = file.name;
						//uppercase file extension fix :
		            	var is_image = (file_name.toLowerCase().substr(-4) == '.jpg'  
		            						|| file_name.toLowerCase().substr(-4) == '.png' 
		            						|| file_name.toLowerCase().substr(-5) == '.jpeg' 
		            						|| file_name.toLowerCase().substr(-4) == '.gif' 
		            						|| file_name.toLowerCase().substr(-5) == '.tiff')
							? true : false;
						//: uppercase file extension fix
		            	if(is_image)
		            	{
		            		$('#file_'+unique_id).addClass('image-thumbnail');
		            		load_fancybox($('#file_'+unique_id));
		            		$('#file_'+unique_id).html('<img src="'+file.url+'" height="50" />');
		            	}
		            	else
		            	{
		            		$('#file_'+unique_id).removeClass('image-thumbnail');
		            		$('#file_'+unique_id).unbind("click");
		            		$('#file_'+unique_id).html(file_name);
		            	}
		            	
						$('#file_'+unique_id).attr('href',file.url);
						$('#hidden_'+unique_id).val(file_name);

						$('#success_'+unique_id).fadeIn('slow');
						$('#delete_url_'+unique_id).attr('rel',file_name);
						$('#upload-button-'+unique_id).slideUp('fast');
		            });
				}
				else if(typeof data.result.message != 'undefined')
				{
					alert(data.result.message);
					show_upload_button(unique_id, uploader_element);
				}
				else
				{
					alert(error_on_uploading);
					show_upload_button(unique_id, uploader_element);
				}
	        },
	        autoUpload: true,
	        error: function()
	        {
	        	alert(error_on_uploading);
	        	show_upload_button(unique_id, uploader_element);
	        },
	        fail: function(e, data)
	        {
	            // data.errorThrown
	            // data.textStatus;
	            // data.jqXHR;	        	
	        	alert(error_on_uploading);
	        	show_upload_button(unique_id, uploader_element);
	        },	        
	        progress: function (e, data) {
                $("#progress-"+unique_id).html(string_progress + parseInt(data.loaded / data.total * 100, 10) + '%');
            }	        
	    });
		$('#delete_'+unique_id).click(function(){
			if( confirm(message_prompt_delete_file) )
			{
				var file_name = $('#delete_url_'+unique_id).attr('rel');
				$.ajax({
					url: delete_url+"/"+file_name,
					cache: false,
					success:function(){
						show_upload_button(unique_id, uploader_element);
					},
					beforeSend: function(){
						$('#upload-state-message-'+unique_id).html(string_delete_file);
						$('#success_'+unique_id).hide();
						$("#loading-"+unique_id).show();
						$("#upload-button-"+unique_id).slideUp("fast");
					}
				});
			}
			
			return false;
		});		    
	    
	});
});
*/
}
?>

 

 

 

 

 

 

Cheers

 

 

Ez


davidoster
  • profile picture
  • Member

Posted 05 April 2013 - 17:05 PM

Have you seen Image CRUD?

And maybe next time post a file if the code is that long!

 

Thanks for sharing!!!


ezgoen
  • profile picture
  • Member

Posted 11 April 2013 - 00:48 AM

 

I've seen image crud.

 

I didn't need the extra complexity and I really don't like lookup tables in databases ( relation_n_n  )

 

Cheers and I will post a file next time

 

Ez