CodeIgniter Forums
Generic list generator helper with templates (ul, ol, select box, etc.) - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20)
+--- Forum: Archived Libraries & Helpers (https://forum.codeigniter.com/forumdisplay.php?fid=22)
+--- Thread: Generic list generator helper with templates (ul, ol, select box, etc.) (/showthread.php?tid=13243)

Pages: 1 2


Generic list generator helper with templates (ul, ol, select box, etc.) - El Forum - 11-15-2008

[eluser]Jelmer[/eluser]
The code and explanation are in the wiki:
http://codeigniter.com/wiki/Generatic_List_Generator/

If the ul(), ol() and form_dropdown() aren't powerfull enough for you, this might do the trick. Check out the wiki post for some explanation about how it works and what it can do. I will write up some more complex examples to better show its usefullness.

UPDATE november 16: I added some examples below

I wrote it just now and I'm still testing it but it already created values for Script.aculo.us inPlaceCollectionEditor, a selectbox and multiple nested lists without any problem.

What can be done better
There's a couple of things that can possibly be done a lot better, like the alternation of values which doesn't continue within/after a nested set. Within a nested set it starts from the begining and after it continues with the value the parent had.

Also, the helper will quite happily produce non-valid code if you structure your arrays wrong - bot I don't really consider that a bug. For instance array(1,2,3,array('a','b') would produce non-valid code and array(1,2,3=>array('a','b') would produce valid code (the sublist enclosed within the LI of the '3'-node).

Some improvements I'm thinking about (last update: 12/10)
- Improve the functions within classes recognition for classes which aren't instantiated on their own name within CI
- Add arguments to the 'functions' options, so values can be passed through brackets like in the form_validation (for instance: some_method[arg1, arg2]) and maybe allow for passing the value of keys too by prefixing those with itemvalue_ (like: some_method[arg1, itemvalue_keyname])
- Prevent double $option['link'] to be added because of ignore values (now solved by removing a double found with a single at the bottom of the function)
- Add selection option
Some bugfixes and these improvements (last update: 12/10)
- Bugfix: moved the foreach loop for external functions within and outside classes, which now detects if the expected class is the current controller. Though it still wouldn’t handle a class correctly for which the classname and the variablename within CI aren’t the same. (for example: a library “Example” would be instantiated on $this->example)
- Bugfix: added a str_replace at the end that replaces any double added $option[‘link’], should be prevented but don’t have the time to figure out a decent patch. (update: 11/20)
- Remove any leftover tags at the end (update: 11/16)
- Replace the preg_replace() with str_replace() where possible (which is nearly everywhere, I just used preg_replace because I'm used to it, not because it's needed) (update: 11/16)

Any suggestions or improvements are welcome!


Generic list generator helper with templates (ul, ol, select box, etc.) - El Forum - 11-15-2008

[eluser]Colin Williams[/eluser]
http://ellislab.com/codeigniter/user-guide/helpers/html_helper.html
http://ellislab.com/codeigniter/user-guide/helpers/form_helper.html

These have functions that do produce valid code.


Generic list generator helper with templates (ul, ol, select box, etc.) - El Forum - 11-16-2008

[eluser]Jelmer[/eluser]
I know, I actually have read the User Guide. My helper function is a bit more difficult to use but so much more powerfull. Also if you had actually read my post you would have noticed this does produce valid code if you structure your array right.

The whole idea is that this can actually take an SQL resource, filesystem array or any other complex list and turn it into whatever you want with some templating options. For instance I can input a multidimensional array and turn it into a select pulldown with some added code for each level so you get an output like:
Code:
level 0
- level 1
   - level 2
   - another
- level 1

Read the wiki post before calling it redundant.

UPDATE: I updated my original post to better explain its value.


Generic list generator helper with templates (ul, ol, select box, etc.) - El Forum - 11-16-2008

[eluser]Jelmer[/eluser]
Some examples...

Let's say we do a query to the database with a function that gets everything with level 0 and then checks if each of its items has children (with their ID as 'parent'). Something like the following function:
Code:
function _get_structure($parent = 0) {
    $query = $this->db->get_where('structure', array('parent'=>$parent));
    $result = $query->result_array();
    $i = 0;
    foreach($result as $key => $item)
    {
        $result[$i]['subs'] = $this->_get_structure($item['id']);
        $i++;
    }
    return $result;
}
(the _get_structure() method is untested, it's a quick rewrite of one of my own only as an example - all the generate_list_helper output shown below was created by the helper using the array below)

Which would output something like:
Code:
array(
    1=>array(
        'id' => '3',
        'parent' => '0',
        'title' => 'Testitem',
        'description' => 'Some text to describe the contents'
    ),
    2=>array(
        'id' => '4',
        'parent' => '0',
        'title' => 'Second item',
        'description' => 'Another line of text to describe this item',
        'subs' => array(
            1=>array(
                'id' => '9',
                'parent' => '4',
                'title' => 'Childitem',
                'description' => 'Children need a description too'
            ),
            2=>array(
                'id' => '11',
                'parent' => '4',
                'title' => 'A second child',
                'description' => 'Explain the second child of the second item'
            ),
            3=>array(
                'id' => '12',
                'parent' => '4',
                'title' => 'And a third to close off',
                'description' => 'I\'m really out of ideas for placeholder text ;-)'
            )
        )
    ),
    3=>array(
        'id' => '6',
        'parent' => '0',
        'title' => 'A third item',
        'description' => 'A last description for this item, which is the third.'
    )
)

So we'll assign the aforementioned output to a variable and set some options.
Code:
$this->load->helper('generate_list');

$resource = $this->_get_structure();

$options = array(
    'template_head'=>'<ul>',
    'template_foot'=>'</ul>',
    'alternate'=>array('color: blue;', 'color: red;')
);

$template = '<li style="{ALTERNATE}"><strong>{TITLE}</strong><br />{DESCRIPTION}{SUBS}</li>';

echo generate_list($resource, $options, $template);

Which will generate the following list (I added spaces and linebreaks for readability):
Code:
<ul>
<li style="color: red;"><strong>Testitem</strong><br />
    Some text to describe the contents</li>
<li style="color: blue;"><strong>Second item</strong><br />
    Another line of text to describe this item
    <ul>
    <li style="color: red;"><strong>Childitem</strong><br />
        Children need a description too</li>
    <li style="color: blue;"><strong>A second child</strong><br />
        Explain the second child of the second item</li>
    <li style="color: red;"><strong>And a third to close off</strong><br />
         I'm really out of ideas for placeholder text ;-)</li>
    </ul></li>
<li style="color: red;"><strong>A third item</strong><br />
    A last description for this item, which is the third.</li>
</ul>

A values/text string to generate a Script.aculo.us inPlaceCollectionEditor
But from the same data we could also create values for a Script.aculo.us inPlaceCollectionEditor, by changing the $template & $options variables to:
Code:
$options = array(
    'template_head'=>'[',
    'template_foot'=>']',
    'link'=>','
);

$template = '["{ID}", "{TITLE}"]{SUBS}';

Which in turn will output:
Code:
[["3", "Testitem"],["4", "Second item"],[["9", "Childitem"],["11", "A second child"],["12", "And a third to close off"]],["6", "A third item"]]

A select/pulldown box
Or create a pulldownbox with some indentation for structure clarity:
Code:
$options = array('level'=>0,'indent'=>'   |');
$template = '<option value="edit/{ID}.htm">{INDENT}- {TITLE}</option>{SUBS}';

Which would output (again with added linebreaks):
Code:
<option value="edit/3.htm">- Testitem</option>
<option value="edit/4.htm">- Second item</option>
<option value="edit/9.htm">   |- Childitem</option>
<option value="edit/11.htm">   |- A second child</option>
<option value="edit/12.htm">   |- And a third to close off</option>
<option value="edit/6.htm">- A third item</option>
(In this last case you'd have to add the <select> tag outside this function, I thought about adding a setting that would only add a "template_head" & "tamplate_foot" to the top-list, but in my view that's only clutter - it works just as well to add it after the output was created)


Generic list generator helper with templates (ul, ol, select box, etc.) - El Forum - 11-17-2008

[eluser]hugle[/eluser]
[quote author="Jelmer" date="1226817283"]The code and explanation are in the wiki:
http://codeigniter.com/wiki/Generatic_List_Generator/

If the ul(), ol() and form_dropdown() aren't powerfull enough for you, this might do the trick. Check out the wiki post for some explanation about how it works and what it can do. I will write up some more complex examples to better show its usefullness.

UPDATE november 16: I added some examples below

I wrote it just now and I'm still testing it but it already created values for Script.aculo.us inPlaceCollectionEditor, a selectbox and multiple nested lists without any problem.

What can be done better
There's a couple of things that can possibly be done a lot better, like the alternation of values which doesn't continue within/after a nested set. Within a nested set it starts from the begining and after it continues with the value the parent had.

Also, the helper will quite happily produce non-valid code if you structure your arrays wrong - bot I don't really consider that a bug. For instance array(1,2,3,array('a','b') would produce non-valid code and array(1,2,3=>array('a','b') would produce valid code (the sublist enclosed within the LI of the '3'-node).

UPDATE 11/16: Some improvements I'm thinking about
- Add arguments to the 'functions' options, so values can be passed through brackets like in the form_validation (for instance: some_method[arg1, arg2]) and maybe allow for passing the value of certain keys too (like: some_method[arg1, -key_name-])
ANOTHER UPDATE 11/16: Some bugfixes and these improvements:
- Remove any leftover tags at the end
- Replace the preg_replace() with str_replace() where possible (which is nearly everywhere, I just used preg_replace because I'm used to it, not because it's needed)

Any suggestions or improvements are welcome![/quote]

Nice contribution Jelmer. I'm going to use it in near future I think.

Good luck!


Generic list generator helper with templates (ul, ol, select box, etc.) - El Forum - 12-05-2008

[eluser]johnwbaxter[/eluser]
Jelmer, just a thought, but if you put together a zip with your files and a sql script which would make up a working drop in demo that you could quickly run with a clean install of ci it would make it easier for people to quickly try out and see if it meets their requirements.

What do you think?

I'm going to have a little play with this right now and see how it goes! Cheers!


Generic list generator helper with templates (ul, ol, select box, etc.) - El Forum - 12-05-2008

[eluser]Jelmer[/eluser]
audiopleb,

I'd love to do that but the thing is, I just don't have the time. I wrote this for the application I'm currently developing and made it so generic that I realised I could make it public without any changes. Also the naming might be a bit off, as it's not really about lists but more like templating multiple database entries with tree parsing capability (which is what makes it actually more usefull then a normal foreach loop).

When I have a bit more time I still want to implement arguements for external function and a select option. Also, I might do some benchmarking to see if there's any use to adding a second function which can't handle trees but only does the templating for depth 1.

Let me know your experience, I haven't looked at it since the last update of my original post and there are probably still some minor bugs in it.


Generic list generator helper with templates (ul, ol, select box, etc.) - El Forum - 12-05-2008

[eluser]johnwbaxter[/eluser]
Jelmer, I've just had a little play with it and i must say that i'm very impressed. I'll let you know more when i've had more of a play!


Generic list generator helper with templates (ul, ol, select box, etc.) - El Forum - 12-09-2008

[eluser]Jelmer[/eluser]
While using the helper with some functions within my current controller I found it didn't really work as it should. I've placed the foreach loop towards the top to allow for using tags from the DB resource in the function output, also within the foreach loop for each item as the previous wiki version only executes the external functions after all the items have been generated and with the wrong level as a parameter - which is a bug.

I have updated the wiki but the current version hasn't been fully tested and might throw some unexpected behavior, though I'm using the helper extensively throughout my application and it still works everywhere as expected.


Generic list generator helper with templates (ul, ol, select box, etc.) - El Forum - 12-09-2008

[eluser]hugle[/eluser]
[quote author="Jelmer" date="1228894990"]While using the helper with some functions within my current controller I found it didn't really work as it should. I've placed the foreach loop towards the top to allow for using tags from the DB resource in the function output, also within the foreach loop for each item as the previous wiki version only executes the external functions after all the items have been generated and with the wrong level as a parameter - which is a bug.

I have updated the wiki but the current version hasn't been fully tested and might throw some unexpected behavior, though I'm using the helper extensively throughout my application and it still works everywhere as expected.[/quote]

Thanks for letting know.
thanks for contributing it