Jump to content

MarkE

Members
  • Posts

    1,098
  • Joined

  • Last visited

  • Days Won

    12

Everything posted by MarkE

  1. That's probably better than what I did which was to render the hanna explicitly. So that the user can see the help at the same time, I added a button after the edit pencil in AdminHelpTab.module line 150: $body .= " <span><a href='{$docLink}{$doc->id}' target='_blank' title='Edit'><i class='fa fa-pencil'></i></a></span>"; $body .= " <span><a class='popout-help' href='{$doc->url}' title='Pop-out'><i class='fa fa-external-link'></i></a></span></h1>"; and then the following in AdminHelpTab.js: $(document).on('click', 'a.popout-help', popOut); function popOut(event) { var link = $(this).attr('href'); window.open(link, 'popup', 'resizable= 1, height = 600, width=800, scrollbars=1'); return false; } That would be good. However, what I would also like to be able to do is to have 2 fields - one with the developer-supplied help and the other which the client can edit to add their own aides-memoire - so I was going to just hack the code for that ? Correct, but since neither the help-index or help-doc templates allow children, it has no effect. Easy enough to edit the templates though. With the css, my main issue was with .cbp-ntaccordion h3.cbp-nttrigger {} where I changed the font size to 1.2em (from 2.2em). Especially with these changes, I think this is actually quite a powerful help system - if all you want is help - without needing the full ProcessDocumentation (which, in any case does not have the accordion) - though I may want to add a few more things (e.g to produce a complete pdf).
  2. Thanks. I've hacked my copy as follows: To allow use of Hanna codes in the body To add a pop-out button next to the edit button in the tab Let me know if you are interested in incorporating these very simple changes. Also, as I said earlier, I changed the help-index template to allow recursion. P.S. I might look at re-styling the accordion, which occupies a lot of screen real-estate.
  3. Hi @Macrura. I just found this module and it looks very much like what I was going to do from scratch for my current development - i.e. have a help file for each template but also as part of a general help page. I installed it and made a minor mod - to allow help-index pages to have help-index children (plus a body field). This works nicely in the accordion as a hierarchical drop-down. However, it seems like the module is no longer supported and you are suggesting ProcessDocumentation instead. I also note that there seems to be another module - ContextHelpTemplate - that is more up-to-date than AdminHelpTab in allowing more options for display. So I am a bit confused. What do you recommend for my help pages (it would be nice to use pw-panel)?
  4. It's actually a bit more complicated than that at the moment, because a urlencode(serialize($array)) is the get parameter with all the data for the lister session bookmark, as the latter is general-purpose (there is more than one 2-dim table and they have different features). I don't see that tabulator replaces the 2-dim display I showed in the image, but it might make for a better drill-down display instead of the lister. I'll take a look into that while the client is user-testing the current version.
  5. Thanks @bernhard. Tabulator certainly looks interesting. My use case is slightly different from the standard table, however. It is a 2-dimensional tabulation of summary data (each cell based on the sum of values meeting the criteria of both column and row). Each cell than has a link to a process module which takes the criteria and turns them into a Lister session bookmark, to which it redirects, thus providing a drill down for the components of each cell. I'm not sure that tabulator handles this, but it does look like a potential enhancement of the standard MarkupAdminDataTable. See image:
  6. I guess the alternative is to put the call in Process module so that the Listers are created on the fly. However, the load time for a table of 300+ cells is currently 1.5 sec, of which I suspect only a fraction is for creating the Listers. I may give it a try to see which is best. Update: using the module cuts the time to 1.4 sec on my dev m/c (there's a lot of processing to produce the table anyway) and makes no appreciable difference to the time to open the drill-down lister (if anything, it's a bit faster). So I can ditch my mod to ProcessPageLister, but I'm still curious about the limit.
  7. Done that, thanks. Any views on whether this should be raised as a fix, or if the hard-coded max is there for a good reason? The fix is very simple - just add an argument $max=30 to the method and set $maxBookmarks = $max;
  8. I have been making use of the ProcessPageLister::addSessionBookmark() method to create drill-downs of financial data in a table - so that the user can see the pages comprising the amount in the table cell. This works really well and has been well-received by the client. However, I soon ran into a problem in that the method sets $maxBookmarks = 30; hard-coded just like that. I changed the code to $maxBookmarks = 400; and haven't noticed any ill-effects so far, so some questions arise: Why is it hard-coded rather than modifiable? If the answer to (1) is because too many bookmarks cause a problem, what is the problem? If there is no particular problem with more than 30 bookmarks, is there any other practical limit? Clearly changing the code in my copy of PW is not a good idea as it will get over-written at the next update. Is there a way of dealing with this until (if ever) the variable can be modified through the API?
  9. Here's what I did: $wire->addHookAfter('HannaCodeDialog::buildForm', function(HookEvent $event) { // The Hanna tag that is being opened in the dialog $tag_name = $event->arguments(0); // The form rendered in the dialog /* @var InputfieldForm $form */ $form = $event->return; if($tag_name === 'BusinessProcess') { $modules = $event->wire('modules'); // Generate page list $f = $modules->InputfieldPageListSelect; $f->set('parent_id', 6199); $f->name = 'businessProcess'; $f->id = 'businessProcess'; $f->label = 'businessProcess'; $form->add($f); } });
  10. Regarding attributes of type pagelistselect, it would be really useful to be able to specify the parent page to restrict the selection. I assume it may be possible to do this in a hook somehow, but might it also be a useful enhancement - something like attribute__parent=id?
  11. Many thanks - didn't spot that!
  12. This is a nice module and I've added a number of panels successfully. However, I have a problem with the chart panel. My code is below (the data is just a test and will be replaced by integer variables): $reports->add([ 'panel' => 'chart', 'title' => 'Contact bookings for ' . $property->title, 'data' => [ 'chart' => [ 'type' => 'bar', 'data' => [ 'labels' => [4, 6], 'datasets' => [ 'label' => 'count', 'data' => [1, 1], ], ], ], ] ]); I get a js error: DashboardPanelChart.js?v=0.6.14:121 Uncaught TypeError: e.data.datasets.forEach is not a function at Object.beforeUpdate (DashboardPanelChart.js?v=0.6.14:121) at Object.notify (chart.js@2.9.3:7) at Qe.update (chart.js@2.9.3:7) at Qe.construct (chart.js@2.9.3:7) at new Qe (chart.js@2.9.3:7) at n (DashboardPanelChart.js?v=0.6.14:123) at HTMLCanvasElement.<anonymous> (DashboardPanelChart.js?v=0.6.14:123) at Function.each (JqueryCore.js?v=1585265024:2) at init.each (JqueryCore.js?v=1585265024:2) at c (DashboardPanelChart.js?v=0.6.14:123)
  13. That's the idea. However, I have decided to use ProcessPageLister::addSessionBookmark() now I've got it working, as it doesn't suffer from the problem of altering the default filters. All works fine now and I have a lovely drill-down effect ? EDIT - actually the default lister settings are still affected ?
  14. Some progress: looks like you can use the properties listed in the ProcessPageLister module as the keys in the bookmark array - certainly initSelector works.
  15. Context: I have a (html) table of financial data in a back-end dashboard. Each element of the table is the sum of values from certain pages (for which a selector has been constructed). What I want to do is add a link for each element to a lister page showing the pages that go to make up the element. i.e. a link to a lister page which uses the constructed selector. This sounds like it ought to be easy, but I've been chasing around for a while now and can't seem to crack it. What I've tried: supply a GET var with a csv of the required page ids - /?open=1,2,3 - this seems to have no effect; use ProcessPageLister::addSessionBookmark() - I can't find much documentation about this, particularly regarding the format of the $bookmark array to be supplied. I tried the array structure I inferred from the code, viz: ['id' => , 'title' => , 'desc' => , 'selector' => , 'columns' => , 'sort' => , 'share' => ] but the selector seems not to be recognised (all pages are selected); use a session var to communicate the selector to a hook before ProcessPageLister::renderResults - at least with this, the selector gets recognised, but it will be messy to operate because multiple selectors would be required to handle all the table elements (or some js would need to be added to see which one was clicked) I really feel it ought to be easier than this and that I'm missing something obvious. Can anyone shed some light please?
  16. Thanks for the ideas. I decided to use a class for the template (MailConditional) and put the method in there. This simplifies things a bit for me - just need to call $mailPage->evaluate_condition(). <?php namespace ProcessWire; class MailConditionalPage extends DefaultPage { /** * Create a new MailConditional page in memory. * * @param Template $tpl Template object this page should use. */ public function __construct(Template $tpl = null) { if(is_null($tpl)) $tpl = $this->templates->get('MailConditionalPage'); parent::__construct($tpl); } /** * @param $codes * @return bool * @throws WireException */ public function evaluate_condition($codes=[]) { ... }
  17. Maybe for whizzos like you @bernhard, but I have only ever built simple process modules, using your excellent tutorial, and have struggled to find clear instructions for building Inputfield modules. It looks like there also needs to be a Fieldtype module, but I'm not sure why, or what should go in each.
  18. I built the following function which seems to work (borrowing heavily from the Hanna code approach). Not sure if its worth building a module around it. /** * @param $condition * @param $pageId - page id holding the condition * @return bool * @throws WireException */ function evaluate_condition($condition, $pageId) { if ($condition and $pageId) { bd($condition, 'raw expression'); $condition = html_entity_decode(strip_tags($condition), ENT_QUOTES | ENT_XML1, 'UTF-8'); // need extra params to catch &nbsp; so that it can be removed by str_replace bd($condition, 'orig expression decoded'); $condition = str_replace('&nbsp;', ' ', $condition); $condition = str_replace(' ', '', $condition); $cachePath = wire('config')->paths->cache . 'MailCondition/'; $name = 'condition' . $pageId; if(!is_dir($cachePath)) if(!wireMkdir($cachePath)) { throw new WireException("Unable to create cache path: $cachePath"); } $file = $cachePath . $name . '.php'; $code = 'if (' . $condition . ') {echo "Y";} else {echo"N";}'; $openPHP = '<' . '?php'; $firstLine = 'if(!defined("PROCESSWIRE")) die("no direct access");'; if(substr($code, 0, strlen($openPHP)) !== $openPHP) { // prepend open PHP tag to code if not already present $code = "$openPHP\n$firstLine\n$code"; } else { // otherwise insert our $firstLine security check $code = str_replace($openPHP, "$openPHP\n$firstLine\n", $code); } if(is_file($file) && file_get_contents($file) === $code) { // file already there and same as what's in the DB } else { // write new file or overwrite existing if(!file_put_contents($file, $code, LOCK_EX)) throw new WireException("Unable to write file: $file"); if(wire('config')->chmodFile) chmod($file, octdec(wire('config')->chmodFile)); } $t = new TemplateFile($file); try { $result = $t->render(); return ($result == "Y"); } catch (\Error $e) { throw new WireException("Error in condition - cannot evaluate"); } } else { throw new WireException("Incomplete parameters (condition, pageId) supplied - cannot evaluate"); } }
  19. I'm looking for an inputfield module that might allow the entry and evaluation of a conditional expression (following php syntax). My use case is an admin function for writing pro-forma emails/letters where some components of the pro-forma are dependent on conditions determined by an admin user. The pro-forma is then cloned for use and the relevant components are included depending on the runtime value of the conditions. The conditions usually include hanna codes as the items to be compared. This is implemented in a parent-child structure, where the main mail body is in the parent and each child then has a condition (textarea) field and a body textarea field for the optional text relating to that condition. As an interim solution on my dev machine, I am just using eval() to evaluate the conditions, but I really don't want to use this in the live environment. My idea is to use an approach similar to that for hanna codes to store the php and render it. This would be (somehow) wrapped in a new inputfield module (extending InputfieldTextarea?) with an evaluate() method that would return true or false as appropriate. It would be placed inside a try...except structure to catch syntax errors etc. It seemed to me that this might be quite a useful utility module and that someone might have developed something similar, but I can't find anything. Does anyone have any pointers, or will I need to start from scratch? If the latter, then I'd appreciate some help along the way as I am a bit of a novice in these matters.
  20. I don’t seem to have that problem. My host page has several children.
  21. Per PHP manual If needle is not a string, it is converted to an integer and applied as the ordinal value of a character. This behavior is deprecated as of PHP 7.3.0, and relying on it is highly discouraged. Depending on the intended behavior, the needle should either be explicitly cast to string, or an explicit call to chr() should be performed.
  22. Hmm - I don't get that error. What arguments are being supplied? BTW, a better way of finding the host page: $bkgPageId = str_replace('for-page-', '', $page->parent->name); $bkgPage = wire()->pages->get("id=$bkgPageId");
  23. That looks correct to me
  24. As I said, that code is in my context - i.e. with my field names. You will need to change those to suit your context. The field 'comment' is on the host page (outside the repeater) - just a plain text field for the cache. rentalAdjustmentPage is my trigger field inside the repeater (a page select field).
  25. Also, the solution to not being able to access the attrs in the repeater items is to turn off "Repeater dynamic loading (AJAX) in editor" on the details tab of the repeater field. Then everything works whether or not the repeater items are initially shown closed.
×
×
  • Create New...