Easy MODX Custom Manager Pages (CMPs) III

Making our CMP do a real search and report the results


In the last article, we set up our Custom Manager Page (CMP) to do a real search and report the results. In this one, we'll add checkboxes to let the user select which fields will be searched. We'll also update the code to make it easier to search other objects in addition to resources.

MODX logo

See the previous article to look at the namespace, menu, Tpl chunk, and the original controller. In this article, we'll modify the main Tpl chunk, and add a few more Tpl chunks. We'll also discuss a trick involving the name attribute of an input that lets us create a nested $_POST array. We'll start with the new MySearchTpl chunk.


MySearchTpl Chunk

<div class="container">
    <h2 class="modx-page-header">[[+ph._pagetitle]]</h2>

    <div class="x-panel-body shadowbox">
        <div class="panel-desc">Select Options for Search</div>

        <div class="x-panel main-wrapper">

            <form action="#" class="mysearch_form" id="mysearch_form" method="post">
                <fieldset id="mysearch_fieldset" style="padding: 50px;">
                    <div>
                        <label for="search_term"><p><b>Search For:</b></p></label>
                        <input class="x-form-text x-form-field" size=100 type="text" id="search_term" name="search_term"
                               required>
                    </div>
                    <br class="clear"/>
                    <br>
<h3>Resources</h3>

                    <div id="checkbox_div_resource" class="x-form-check-wrap">
                        <input type="checkbox" id="modResource_pagetitle" autocomplete="off"
                               class="x-form-checkbox x-form-field" name="objects[modResource][]" value="pagetitle">
                        <label for="modResource_pagetitle" class="x-form-cb-label"> pagetitle</label>
                        <br/>

                        <input type="checkbox" id="modResource_longtitle" autocomplete="off"
                               class="x-form-checkbox x-form-field" name="objects[modResource][]" value="longtitle">
                        <label for="modResource_longtitle" class="x-form-cb-label"> longtitle</label>
                        <br/>

                        <input type="checkbox" id="modResource_alias" autocomplete="off"
                               class="x-form-checkbox x-form-field" name="objects[modResource][]" value="alias">
                        <label for="modResource_alias" class="x-form-cb-label"> alias</label>
                        <br/>

                        <input type="checkbox" id="modResource_description" autocomplete="off"
                               class="x-form-checkbox x-form-field" name="objects[modResource][]" value="description">
                        <label for="modResource_description" class="x-form-cb-label"> description</label>
                        <br/>

                        <input type="checkbox" id="modResource_introtext" autocomplete="off"
                               class="x-form-checkbox x-form-field" name="objects[modResource][]" value="introtext">
                        <label for="modResource_introtext" class="x-form-cb-label"> introtext (summary)</label>
                        <br/>

                        <input type="checkbox" id="modResource_content" autocomplete="off"
                               class="x-form-checkbox x-form-field" name="objects[modResource][]" value="content">
                        <label for="modResource_content" class="x-form-cb-label"> content</label>
                        <br/>

                        <input type="checkbox" id="modResource_id" autocomplete="off"
                               class="x-form-checkbox x-form-field" name="objects[modResource][]" value="id">
                        <label for="modResource_id" class="x-form-cb-label"> id</label>
                        <br/>

                    </div>
                    <br class="clear">


                    <div class="mysearch_submit">
                        <input style="padding:5px;" type="submit" id="mysearch_submit" name="mysearch_submit"
                               value="Launch Search"/>
                    </div>

                    <div id="mysearch_results" class="mysearch_results">
                        [[+mysearch_results]]
                    </div>

                </fieldset>

            </form>

        </div> <!-- End wrapper div -->
    </div> <!-- End shadowbox div -->
</div> <!-- End container div -->

The main change here is the addition of the checkbox section that let's users select which fields to search. Otherwise the changes are minimal, with a few tweaks to improve the styling. The format of the name attribute for each checkbox input (name="objects[modResource][])deserves a little explanation.

If we had just used name="modResource[]", the resulting $_POST array would look like this if only two options were checked:

Array (
    [search_term] => test
    [modResource] => Array(
        [0] => pagetitle
        [1] => longtitle
    }
    [mysearch_submit] => Launch Search
)

In the array above, each part is the name of the form input element followed by its value. Because we added [] after the modResource elements, they appear in an array under modResource. This would be fine if we never wanted to search something other than resources, but what happens when we add a chunks section using that format for the names?

Array (
    [search_term] => test
    [modResource] => Array(
        [0] => pagetitle
        [1] => longtitle
    }
    [modChunk] => Array(
        [0] => name
        [1] => description
    }
    [mysearch_submit] => Launch Search
)

To process this, we'd like to loop through the objects to be searched. To do that, we'd have to use some inelegant code that ignored (or removed) the search term and submit items while walking through the array, or create an array of possible object types to be searched. Remember that any object type might, or might not, be present in the array, so it would be ugly code and each time we added a new type of search object(e.g., templates or plugins), it would mean rewriting the existing code. If, instead, we use name="objects[modResource][]" and name="objects[modChunk][]", for our names, we get this in the $_POST array:

Array (
    [search_term] => test
    [objects] => array(
        [modResource] => Array(
            [0] => pagetitle
            [1] => longtitle
        }
        [modChunk] => Array(
            [0] => name
            [1] => description
        }
    }
    [mysearch_submit] => Launch Search
)

Since we've moved each object type under the objects array member, all we need to do in the code that processes the results is this:

$objects = $_POST['objects'];

foreach ($objects as $objectType => $fieldsToSearch) {
   /* do something */
}

The $fieldsToSearch variable will hold an array of the fields the user checked for that object type. For every iteration of the loop, we'll have the object type (e.g. modResource), and the fields to search. In a bit, we'll use those to build our query dynamically.


New Tpl Chunks

We've added several new Tpl chunks. First we've moved the results Tpl to a chunk called MySearchResultTpl. Here's the code used for each line of the results list:

<li><a href="[[++manager_url]]?a=[[+action]]&id=[[+id]]">[[+name]] ([[+id]])</a></li>

We've added the ID field in parentheses, otherwise the Tpl is the same as before, just moved from the code of the controller into a chunk.

The other new Tpl chunk is called MySearchSectionTpl. It serves as the Tpl chunk for each section of the results. For now, it will only be used once for the resources search, but it will also work for other searches if we decide to add the option to search users, chunks, templates, or other elements. Here's the code for the MySearchSectionTpl chunk:

<div id="mysearch_[[+mysearch_id]]" style="margin-top: 30px;">
  <br>
<h3>[[+mysearch_header]]</h3>
  <ul>
    [[+mysearch_rows]]
  </ul>
</div>

The mysearch_rows placeholder will be replaced by a series of list items wrapped in li tags.

None of the stuff above will work without the new controller code in home.class.php, but that will have to wait for the next article.


Coming Up

In the next article, we'll look at the new controller code that goes with the changes above.




Looking for high-quality, MODX-friendly hosting? As of May 2016, Bob's Guides is hosted at A2 hosting. (More information in the box below.)



Comments (0)


Please login to comment.

  (Login)