
MarkE
Members-
Posts
1,098 -
Joined
-
Last visited
-
Days Won
12
Everything posted by MarkE
-
In the runtimeMarkup field settings you specify the location and names of your php and js files.
-
@jploch: Work in progress report Firstly, if you set the attrs in $(document).ready then the repeater needs to be permanently open. Otherwise you need to detect the opening event and then set them. Secondly, you need to set separate attrs for each repeater item. Thirdly, I can't get AJAX working properly in PW to update from the changed repeater inputfields. So I have done a hack to use a hidden field outside the repeater to hold a cached value. Unfortunately, because this needs to serve more than one repeater item, it needs to be prefixed so that only the relevant repeater gets updated. I'd be grateful for any improvements on this approach!! The code I have (in my context, with 'comment' as the cache field) is : In the js for the runtimeMarkup field (runtime_markup_note): $(document).ready(function () { $("[id^='Inputfield_rentalAdjustmentPage_repeater']").each(function (index, element) { var id = $(element).attr("id"); var target = id.replace('Inputfield_rentalAdjustmentPage_repeater', '#wrap_Inputfield_runtime_markup_note_repeater'); var cachePrefix= id.replace('Inputfield_rentalAdjustmentPage_repeater', ''); $(element).attr('data-action', 'form-update'); $(element).attr('data-cache', '#Inputfield_comment'); $(element).attr("data-cache-prefix", cachePrefix + ':'); $(element).attr('data-update-target', target); }); }); In the php for the same field: $pageId = $page->id; $adjPageId = $page->rentalAdjustmentPage; $adjParentTitle = $page->parent->title; $bkgPage = wire()->pages->get("title=$adjParentTitle"); $adjTypeId = $bkgPage->comment; if (strpos($adjTypeId, $pageId) == 0) { $adjTypeId = str_replace($pageId . ':', '', $adjTypeId); } $out = wire()->pages->get("id=$adjTypeId")->summary; if ($out) { echo $out; } else { echo wire()->pages->get("id=$adjPageId")->summary; } The php is especially clunky and it would be better to get the host page via the for-page url segment, I think.
-
How are you setting the data attributes for the trigger select field? AFAIK this can't be done in the usual way: $inputfield->attr(). I think it would need to be in js. Mind you, I don't have repeater matrix (pro), just the plain repeater.
-
This is a great module that I have been using for some time. However, I have one slight issue, which may be an issue with CKEditor rather than with the module itself. For any hanna code longer than about 14 characters, the dropdown box cuts them off (see pic). Is there a way of widening the box to fit the longest code (and/or making the font size for the codes smaller)?
-
Do you mean that the select field is outside the repeater field and that the runtimeMarkup is inside it? So the markup will be identical for each repeated item?
-
I've not tested that!
-
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?
-
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.
-
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) .
-
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).
-
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?
-
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; }
-
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
-
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?
-
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.
-
I have posted the js here
-
Please note that the updated version of this script and any other associated info is now at https://github.com/MetaTunes/Form-update 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()); } }); } }); });
-
I have now ? I hadn't realised that I had to install 2 modules separately. Many thanks.
-
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. ???
-
Module Module: RuntimeMarkup Fieldtype & Inputfield
MarkE replied to kongondo's topic in Modules/Plugins
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 -
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.
-
I have a template with a field 'selector' that stores a selector string built from InputfieldSelect and InputfieldSelector options. The selector field is updated by javascript. When I save the admin page, the selector field in the DB is updated and the page loads with the correct Inputfield options. I am trying to avoid having to manually save the page when the InputfieldSelect value changes, so I have a little js snippet that runs on 'change' to update the value of the selector field. I can see from the console log that see that the data is being submitted and that the post is successful, but the returned data does not have the changed value. What am I doing wrong? The js is below, followed by the html for the InputfieldSelect that triggers it. $(document).on('change', '[data-action="form-update"]', function () { console.log("Executing snippet!"); 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(); console.log("Submitted data: " + data); console.log("Method: " + method); if (!method) method = 'get'; if (!action) action = window.location.href; // I usually add a loading overlay on the update target here, that might look something like this: $(target).find('.loading').css({ display: 'block', opacity: 0 }).animate({ opacity: 1 }, 5000); // then send your request $.ajax(action, { method: method, 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) { // 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'))); } }) }); <select id="Inputfield_select_template" class="uk-select uk-form-small" name="select_template" data-action="form-update" data-update-target="#Inputfield_selector"><option value=""> </option><option value="Booking">Booking</option><option value="Mandate">Mandate</option><option selected="selected" value="Member">Member</option><option value="Membership">Membership</option><option value="MemberShop">MemberShop</option><option value="NewsItem">NewsItem</option><option value="Payment">Payment</option><option value="Profile">Profile</option><option value="Subscription">Subscription</option><option value="user">user</option></select> Console extracts: Target is #Inputfield_selector Submitted data: title=test-users&summary=&select_template=Booking&select_filter__field%5B%5D=&select_filter=&selector=template%3DBooking&edit_mode=edit&childTemplate=&templateId%5Bnew_0%5D=130&idsToDelete=&individualChildTitles%5Bnew_0%5D=&templateId%5Bnew_0%5D=130&_pw_page_name=test-users&template=141&id=8707&TOKEN1616224121X1582934644=BMPaNoSmbHI%2FbXmbxBDyQGtcOHbbYqPK&_after_submit_action= Method: post Updating value with: template=Member I haven't included the full returned data as the last log item shows the value extracted from it. As you can see, template=Booking is submitted, but template=Member is returned.
-
Module Module: RuntimeMarkup Fieldtype & Inputfield
MarkE replied to kongondo's topic in Modules/Plugins
I have been using this module successfully for some time. Now I have a more complex use case. I want to update the page (in the admin) using ajax, rather than having to manually select "save". However, in this case, the data is submitted OK but the RuntimeMarkup script does not run and so the page is not properly updated. Any ideas? Thanks. Edit. I'm not entirely sure if the problem just lies with this module since, although the ajax is returning 'success' the normal fields don't appear to update either. -
I must add my congratulations on a really great site - both the look and feel of the front end and the careful design and ui of the back end. I particularly like the rich content of the site and the dashboards. Complexity made artfully simple! I’m scratching my head about one thing, though. There seem to be a number of situations where many-many relationships exist (e.g. works - events). How did you implement that? I don’t see any use of the ConnectPageFields module.
-
Having just wasted the best part of a day debugging an access issue because I hadn't realised that page-edit-created negated any related page-edit permissions, could I suggest that a note to this effect is included in the default title. I have amended the title on my system to read: Edit only pages user has created (IMPORTANT: This will negate any related page-edit permission - including permissions granted to a user by other roles) ..although it may be possible to make it briefer while not losing clarity and impact.