Jump to content

MarkE

Members
  • Content Count

    180
  • Joined

  • Last visited

Community Reputation

36 Excellent

About MarkE

  • Rank
    Sr. Member

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I have created a custom admin page which uses InputfieldPageListSelect. It works very nicely (see image), especially with a bit of css to modify the appearance within a MarkupAdminDataTable and some js with AJAX to interactively update each row. However, I would also like to be able to "view" the selected tariffs. When using a normal InputfieldPageListSelect in the admin, you can set "Enable view/edit links on selected pages" (and "Enable link to create new pages"). I can't see how to pass a parameter for that in the API. Any ideas?
  2. As always, it's never simple. When I used the GET method, I linked to the action page via a data-href attribute in the InputfieldButton. It also had class="pw-modal". Now, with the POST method (working!), I have had to remove the data-href and have the action in the form element. That means I can no longer use pw-modal. So how do I get the action page in a modal? Update: I gave up and went back to using GET. I could not find a way of getting POST and pw-modal to work together.
  3. Well that is true, but $this->input->post['param'] is filled correctly! Sorry for the slight red herring. I obviously misunderstood in thinking I could use $_POST (as $_GET was OK) .
  4. Yes Submit on click. No AJAX here (ironically, elsewhere, I got AJAX posts working). The action page is loaded fine on submit. The dev tools show the POST params are there. But the ___execute() function in the module sees nothing. (All in Superuser, BTW).
  5. Sorry if I'm being a bit dim, but I'm struggling with a form submission. I have a form (InputfieldForm) with values, which are set programmatically, in hidden inputfields and a submit button. The action is an admin page with a custom process. Previously, I just had the button (no form) and a data-href with url parameters which the custom admin page picked up via $_GET - this worked fine. Then I wanted to add a load more parameters and decided to change to the post method. However, the POST parameters do not seem to be available to the custom page ($_POST is empty and $this->input->post->submit is null too). I can see from the developer tools that the POST has worked and that the parameters are there. Any ideas what I might be doing wrong?
  6. Updated version here - works with more field types - just make sure you have at least 3.0.148 if you want to use it with autocomplete /* Script to refresh a form content when an element gets changed To work across all admin pages, this script needs to be loaded in admin.php – add the line $config->scripts->add($config->urls->templates . "scripts/form-update.js"); before the final require in templates/admin.php. Typical use is to modify other elements based on a select drop-down change The trigger element can have the following data attributes assigned to it (typically set these with $myInputfield->attr() in a module or hook): * data-action="form-update" : Required to run the script. * data-update-target="#myid1" : Required - the element to change. Note that this should not be the whole form, otherwise .find(target) will not find it. * data-confirm="Some confirmation text": Optional - if you want to show a confirmation before the update, this holds the text to display. If absent, there will be no confirmation dialogue. If the user chooses ‘cancel’, the script will revert the change and terminate. * data-alert="Some alert text": Optional – if you want to warn the user that the update cannot happen for some reason (the script will then revert the change and terminate). * data-cache="#myid2" : Optional - if you want to cache the (changed) value, this element stores it. * data-cache-prefix="Some prefix string" : Optional (requires data-cache) - a prefix to prepend the value stored in the cache This currently works with the following trigger elements: * select options * select page (single and multiple) * page list select (single and multiple) * asm select * page autocomplete (but note that data attributes must be set in the wrapper element - e.g. $myInputfield->wrapAttr() ) Note also that autocomplete only works fully with the latest master 3.0.148 * checkboxes (set attributes in wrapper as above) * checkbox (set attributes in wrapper as above; also, if you need to set or get the value (0 or 1) you may need to use getParent() ) * toggle (but only with 0,1 formatting and 'select' input type; plus see the comments for checkbox above) but not with: * toggle other than as described above * radio buttons NOTE: If you are using this with other js scripts (e.g. in a module) that listen for events in the target, you must use event delegation (e.g. $(document).on("change","#myid", function(){}); NOT $("#myid").onchange(function(){}); ) because #myid is dynamic if it is inside the target) */ $(document).on('change focusin', '[data-action="form-update"]', formUpdate); // need 'change' to catch normal select fields and 'mouseenter' for others function formUpdate(event) { console.log("event type = " + event.type); value = inputVal(this); if (event.type != 'change') { // if the input has not changed, just get the value now so that we can revert if necessary when it is changed console.log("Saving prev value " + value); $(this).data('prevVal', value); return; } console.log("Saving current value " + value); $(this).data('currVal', value); var prev = $(this).data('prevVal'); var current = $(this).data('currVal'); console.log("Prev value " + prev); console.log("New value " + current); // if trigger element has data-confirm attribute, confirm or revert and exit var confirmText = $(this).data('confirm'); if (confirmText) { if (!confirm(confirmText)) { $(this).val(inputVal(this, prev)); return; } } // if trigger element has data-alert attribute, show alert and exit var alertText = $(this).data('alert'); if (alertText) { alert(alertText); $(this).val(inputVal(this, prev)); return; } // cache the value before proceeding (if data-cache set) var cache = $(this).data('cache'); var cachePrefix = ($(this).data('cache-prefix')) ? $(this).data('cache-prefix') : ''; $(cache).val(cachePrefix + current); var $form = $(this).closest('form'); var target = $(this).data('update-target'); console.log("Target is " + target); var method = $form.attr('method'); var action = $form.attr('action'); var data = $form.serialize(); var encodedName; // .serialize() will omit select elements that do not have a 'null' option (e.g. asm select, page list select) // or checkboxes with nothing selected // so find them and add empty parameters to the data string, otherwise the page field will not be updated $($form.find('select, input').each(function(index){ console.log('Select element no. ' + index + ' with name ' + $(this).attr("name") + ' has serialize = ' + $(this).serialize()); encodedName = encodeURI($(this).attr("name")); if (data.search(encodedName) === -1) { data += ('&' + encodeURI($(this).attr("name")) + '='); } })); console.log("Submitted data: " + data); if (!method) method = 'get'; if (!action) action = window.location.href; // If you want to fade the affected inputfields then assign the loading class to their wrappers with method wrapClass(loading) $(target).find('.loading').css({ display: 'block', opacity: 0.2 }).animate({ opacity: 1 }, 5000); // then send your request $.ajax(action, { type: method, // type used, not method, for older versions of jquery data: data, // you can also add an error handler here if required, in case the server returns an error on the request success: function (data) { // Initial ajax just returns an array with message. Need to GET the form data. $.ajax(window.location.href, { type: 'GET', cache: false, success: function (data) { // then just take the target, and replace it with the target div from the returned data $(target).html($(data).find(target).html()); console.log("Returned data: " + data); console.log("Updating html with: " + $(data).find(target).html()); } }); } }); } function inputVal(el, val=null) { var value = $(el).val(); var inputfield = $(el); if ($(el).hasClass('InputfieldCheckbox')) { console.log("checkbox"); inputfield = $(el).find("input[type='checkbox'], input[type='radio']").first(); if (val === 1) { $(inputfield).attr('checked', 'checked'); } else if (val === 0) { $(inputfield).removeAttr('checked'); } value = ($(inputfield).attr('checked') === 'checked') ? 1 : 0; } else if ($(el).hasClass('InputfieldToggle')) { console.log("toggle"); inputfield = $(el).find("option[selected='selected']").first(); if (val === '1') { $(inputfield).attr('selected', 'selected'); } else if (val === '0') { $(inputfield).removeAttr('selected'); } value = ($(inputfield).attr('selected') === 'selected') ? '1' : '0'; } else if ($(el).hasClass('InputfieldPage') && $(el).find(".InputfieldPageAutocompleteData")) { console.log("page autocomplete"); inputfield = $(el).find(".InputfieldPageAutocompleteData").first(); value = $(inputfield).val(); } else { console.log("other selector type"); if (val) { $(el).val(val); } value = $(el).val(); } console.log("returning value = " + value); return value; }
  7. I had upgraded to 3.0.148 successfully on my dev machine and used it without problems for a couple of weeks. So I decided to upgrade the production environment. The front end works OK and so does some of the back end. However, on attempting to edit certain pages in the back end, I get the following error message: Fatal error: Uncaught TypeError: Argument 1 passed to ProcessWire\Modules::setModuleConfigData() must implement interface ProcessWire\Module, string given, called in /home/highmoss/public_html/processwire/wire/core/Wire.php on line 383 and defined in /home/highmoss/public_html/processwire/wire/core/Modules.php:3685 Stack trace: #0 /home/highmoss/public_html/processwire/wire/core/Wire.php(383): ProcessWire\Modules->setModuleConfigData('ProcessVersionC...') #1 /home/highmoss/public_html/processwire/wire/core/WireHooks.php(823): ProcessWire\Wire->_callMethod('setModuleConfig...', Array) #2 /home/highmoss/public_html/processwire/wire/core/Wire.php(450): ProcessWire\WireHooks->runHooks(Object(ProcessWire\Modules), 'setModuleConfig...', Array) #3 /home/highmoss/public_html/processwire/site-ncog/modules/VersionControl-2.0/ProcessVersionControl.module(75): ProcessWire\Wire->__call('setModuleConfig...', Array) #4 /home/highmoss/public_html/processwire/wire/core/Modules.php(553): ProcessWire\ProcessVersionControl->__construct() #5 in /home/highmoss/public_html/processwire/wire/core/Modules.php on line 3685 I refreshed the modules and cleared the FileCompiler, but it persists. Any ideas? EDIT: Uninstalled version control and it works OK
  8. Whoops, I was getting tripping myself up. Originally I put the selector in the field admin page, then later added a hook without deleting the original selector. The hook over-rides the selector, so adding a sort to the original selector has no effect. As a matter of practice, I'll try and remember to delete selectors if I add a hook, but it's an easy thing to forget. Then later, you see the selector and think that's where the criteria are applied 😞 Perhaps it's better to just use hooks in the first place, so everything is consistently in the same place?
  9. How do I get the sort order of a dropdown (in a page reference field using asmselect) to be how I want it. It seems to be the original order of creation, no matter what I specify. Changing the sort order in the pages or using a selector sort= on the field seems to have no effect.
  10. I have posted the js here
  11. I had a need to interactively update the page choices in a multi-choice page select field. I chose to do this with a general-purpose piece of jQuery. By combining it with a InputfieldPage::getSelectablePages hook, you can get the trigger field to alter the selectable pages interactively. I have also found this to be useful in a number of other situations - e.g. updating a RuntimeMarkup field for changes on a page. There may be more elegant ways of achieving this (I'm open to suggestions), but in case it is useful to others, I'll post it here. Hopefully the comments in the script are self-explanatory and describe how to use it. Note that there are several console.log statements to help with debugging, which you can remove once happy with its operation. Happy to answer any questions (if I can 😉 ). Also, if anyone can explain how to get it working fully with checbox/toggle ad radio buttons, I would be grateful. /* Script to refresh a form content when an element gets changed To work across all admin pages, this script needs to be loaded in admin.php – add the line $config->scripts->add($config->urls->templates . "scripts/form-update.js"); before the final require in templates/admin.php. Typical use is to modify other elements based on a select drop-down change The trigger element can have the following data attributes assigned to it (typically set these with $myInputfield->attr() in a module or hook): * data-action="form-update" : Required to run the script. * data-update-target="#myid1" : Required - the element to change. Note that this should not be the whole form, otherwise .find(target) will not find it. * data-confirm="Some confirmation text": Optional - if you want to show a confirmation before the update, this holds the text to display. If absent, there will be no confirmation dialogue. If the user chooses ‘cancel’, the script will revert the change and terminate. * data-alert="Some alert text": Optional – if you want to warn the user that the update cannot happen for some reason (the script will then revert the change and terminate). * data-cache="#myid2" : Optional - if you want to cache the (changed) value, this element stores it. * data-cache-prefix="Some prefix string" : Optional (requires data-cache) - a prefix to prepend the value stored in the cache This currently works with the following trigger elements: * select options * select page (single and multiple) * page list select (single and multiple) * asm select * page autocomplete (but note that data attributes must be set in the wrapper element - e.g. $myInputfield->wrapAttr() ) * checkboxes (set attributes in wrapper as above) but not with: * toggle * checkbox * radio buttons (These partly work - the attributes need to be in the wrapper -, but doesn't work completely as wrapper 'value' attribute is not updated by PW (always 0) ) NOTE: If you are using this with other js scripts (e.g. in a module) that listen for events in the target, you must use event delegation (e.g. $(document).on("change","#myid", function(){}); NOT $("#myid").onchange(function(){}); ) because #myid is dynamic if it is inside the target) */ $(document).on('focusin', '[data-action="form-update"]', function(){ // get the value before the element is changed console.log("Saving value " + $(this).val()); $(this).data('val', $(this).val()); }).on('change','[data-action="form-update"]', function(event){ var prev = $(this).data('val'); var current = $(this).val(); console.log("Prev value " + prev); console.log("New value " + current); // if trigger element has data-confirm attribute, confirm or revert and exit var confirmText = $(this).data('confirm'); if (confirmText) { if (!confirm(confirmText)) { $(this).val(prev); return; } } // if trigger element has data-alert attribute, show alert and exit var alertText = $(this).data('alert'); if (alertText) { alert(alertText); $(this).val(prev); return; } // cache the value before proceeding (if data-cache set) var cache = $(this).data('cache'); var cachePrefix = ($(this).data('cache-prefix')) ? $(this).data('cache-prefix') : ''; $(cache).val(cachePrefix + current); var $form = $(this).closest('form'); var target = $(this).data('update-target'); console.log("Target is " + target); var method = $form.attr('method'); var action = $form.attr('action'); var data = $form.serialize(); var encodedName; // .serialize() will omit select elements that do not have a 'null' option (e.g. asm select, page list select) // or checkboxes with nothing selected // so find them and add empty parameters to the data string, otherwise the page field will not be updated $($form.find('select, input').each(function(index){ console.log('Select element no. ' + index + ' with name ' + $(this).attr("name") + ' has serialize = ' + $(this).serialize()); encodedName = encodeURI($(this).attr("name")) if (data.search(encodedName) === -1) { data += ('&' + encodeURI($(this).attr("name")) + '='); } })); console.log("Submitted data: " + data); if (!method) method = 'get'; if (!action) action = window.location.href; // If you want to fade the affected inputfields then assign the loading class to their wrappers with method wrapClass(loading) $(target).find('.loading').css({ display: 'block', opacity: 0.2 }).animate({ opacity: 1 }, 5000); // then send your request $.ajax(action, { type: method, // type used, not method, for older versions of jquery data: data, // you can also add an error handler here if required, in case the server returns an error on the request success: function (data) { // Initial ajax just returns an array with message. Need to GET the form data. $.ajax(window.location.href, { type: 'GET', cache: false, success: function (data) { // then just take the target, and replace it with the target div from the returned data console.log("Returned data: " + data); console.log("Updating html with: " + $(data).find(target).html()); $(target).html($(data).find(target).html()); } }); } }); });
  12. I have now 🙂 I hadn't realised that I had to install 2 modules separately. Many thanks.
  13. This may seem a really dim question, but here goes: I've just upgraded to 3.0.148 and installed the "Toggle" inputfield. I now want to add a new field with type "Toggle", but it does not appear in the drop-down for type on the new field page. I've checked that it is installed and have logged out and back in, but it's still not there. ???
  14. Solved now - the problem is in the jquery ajax call - using method: with version 1.8.3 - it should be type: prior to 1.9. See
  15. Aha - mostly solved this now - I am using method: in the ajax, but jquery is version 1.8.3, so I should use type: EDIT: Spoke too soon. Needed to modify the success: function(data) as follows success: function (data) { $.ajax(window.location.href, { type: 'GET', cache: false, success: function (data) { // then just take the target, and replace it with the target div from the returned data console.log("Returned data: " + data); // modified below to use .attr('value', ...) rather than .html console.log("Updating value with: " + $(data).find(target).attr('value')); $(target).attr('value', ($(data).find(target).attr('value'))); } }); but the returned data has not been updated by the posted data. EDIT2: Finally solved. I'll post the JS when I've tidied it up, in case it is useful to anyone else.
×
×
  • Create New...