Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 12/25/2022 in all areas

  1. This isn't the first star rating module for ProcessWire, but I wanted some particular config options and to have the inputfield be usable within FormBuilder. FieldtypeStars The inputfield of FieldtypeStars uses a star rating interface to set a float value. The fieldtype extends FieldtypeFloat. The inputfield has no external dependencies such as jQuery or Font Awesome and can be used in FormBuilder. Config Using InputfieldStars in FormBuilder In order to add a Stars field to a FormBuilder form you must first enable "Stars" in the "Allowed Input Types" field in the FormBuilder module config. https://github.com/Toutouwai/FieldtypeStars https://processwire.com/modules/fieldtype-stars/
    1 point
  2. Merry Christmas, Happy Hanukkah, and Happy Holidays! The plan is to release a newyear main/master core version. I'm not currently aware of any showstopper issues specific to the current dev branch, but if you are aware of any, please report them in the GitHub issues repo (or reply to an existing issue report), as the dev branch will soon become the master branch. There's not yet a hard deadline, so whether it's end of December or the 1st week of January, we'll have a new release out shortly. The dev branch is very stable right now (likely more stable than the master branch) so it's a good time to get a new version out. I've also been holding off on several larger updates to the dev branch in anticipation of this merge to master and new release, so I've likewise been holding back on any commits that would add more to test. Once we get a new main/master release out there, the dev branch will then get InputfieldTinyMCE merged into it and there will be some JS library updates, along with other larger updates, and those that would need dev branch testing. Thanks for reading and I hope that you have a great holiday weekend and week ahead
    1 point
  3. $config->ajax works exactly the same for POST and GET requests. It tells you whether the request is a "normal" or an XMLHttpRequest , independent of the request type. Why would you think that those URLs are stupid? They are a conventional way of telling PW which set of pages to retrieve. Other frameworks are using this convention, too. They consist of 2 parts: {pagNumPrefix}: configured through $config->pageNumUrlPrefix, defaults to "page"; tells PW that this is not a regular URL but a "paginated" one {pageNum}: number of page, in other words: number of set of pages to retrieve; setStart() is using this number From these 2 PW is able to figure out which pages from a PaginatedArray it should return. Let's look at your example code in posts.php and see how that relates to PW terms and conventions: /** @var WireInput $input */ // Default limit $limit = isset($_GET['limit']) ? $_GET['limit'] : 12; // $_GET['limit'] translates to the limit= partof the $pages->find selector // Default offset $offset = isset($_GET['offset']) ? $_GET['offset'] : ($input->pageNum - 1) * $limit; // $_GET['offset'] translates to $input->pageNum -1 * $limit // $queried_posts = array_slice($posts, $offset, $limit); // translates to /** @var PaginatedArray $posts */ $posts = $pages->find("template=video, limit={$limit}, start={$offset}, sort=-date"); // if URL is /page2, $posts will contain 12 pages starting from page at 12th index You can already see how much simpler the code becomes when using "stupid" URLs :-) Now let's look at the etymology of the word "stupid": It originates from the Latin word "stupere" which means "to be amazed or stunned". Isn't it amazing how simple pagination can become when doing it the PW way? I personally am really stunned by that fact :-) Of course you could do it in a less amazing way. PW is flexible enough to allow that. But then you would have to calculate and pass the information about $limit and $offset back and forth manually in your ajax call. You can pass this inside an object, just like your example code does: let queries = { 'offset' : offset, 'limit' : limit }; jLoad.get('<?php echo $config->urls->templates ?>posts.php', queries, function(data)... Actually jQuery translates this to a request URL with GET parameters like /site/templates/posts.php?offset=0&limit=2 In PW this URL would not work because you cannot call site/templates/posts.php directly (see https://processwire.com/talk/topic/20300-run-independent-php-files-within-processwire/ ) You can solve that by including posts.php for AJAX calls inside your template (videos.php) if($config->ajax) include_once("posts.php"); This is not all there is to do. Inside your JS you would have to keep track of the offset. How would your JS know which offset we are on? You could pass the offset as data attribute somewhere in your HTML and then retrieve it in JS. You could also send it together with the response as JSON. You could store it as cookie. Many possibilities here. But still making everything more complicated than it has to be. When using a #load-more button with an amazing URL like /videos/page2, in your JS you just have to update the "2" to "3" so the amazing URL reads /videos/page3. By the way, the infinite-scroll plugin does exactly that. If you want to do it yourself and you have a link that points to the next page like <a id="load-more" href="/videos/page2">Load more</> You could use this JS to update href to 'videos/page3' var elem = $("#load-more"); var path = elem.attr('href'); var pathParts = path.split('/'); var thisPage = pathParts.pop(); var pageNum = parseInt(thisPage.match(/[0-9]+$/)); var pagePrefix = thisPage.slice(0, thisPage.match(/[0-9]+$/).index); var nextPage = pagePrefix.concat('', pageNum + 1); pathParts.push(nextPage); var newPath = pathParts.join('/'); elem.attr('href', newPath); Is this nice? No. Could it be improved? Certainly. While in the above there certainly are some code samples that you could use to achieve what you want, my intention was more to show that it is a lot more work to go this route. Look at my initial example to use with infinite-scroll plugin and how simple and intuitive that is. Sorry if I cannot (or rather don't want to) supply you with a readymade copy/paste solution and sorry if I might sound sarcastic. I'm just not seeing the point in reinventing the wheel of pagination for the xth time over. I don't see the advantage of a custom implementation for your use case over that which PW provides out of the box. If it is just the amazing URLs like page2, page3 that bug you, try to think of them like a tool that you can use to your advantage. And neither the site visitor nor search engines need to see them. As for site visitors, they would only see them in the browsers' dev tools. And search engines only if you allow them to (think of rel=nofollow). If you still want to do it your own way then I wish you the best of luck and happy coding :-)
    1 point
  4. Merry Christmas @ryan, and all the Processwire community!
    1 point
  5. 1 point
  6. You can set breakpoints in your javascript using Firefox’s Debugger tab. You can also look at the response bodies in both places you screenshotted, to see if they are what you expect. Likely something in your javascript is going wrong and this happens:
    1 point
  7. @Ivan Gretskygreat news. I contributed to the module many years ago with leaflet providers and marker cluster integration. It definitely needs some attention and love. Upgrading assets etc. I think that leaflet.js in general is still a viable solution for open source maps in general. Mapbox have changed their subscription model few years ago that is why I still prefer Leaflet over Mapbox. As for geocoding addresses this is still an issue with the open source provider that sits behind InputfieldLeafletMapMarker (Nominatim). They have improved a lot over time. But still failing on more exotic addresses where the Google Maps geocoder is doing a better job. There's quite a few open source geocoding services out there, but most of them use data from OSM's Nominatim. So you can't expect better results than you get with Nominatim. If looking for closed source geocoding APIs, one that might be worth looking into is https://positionstack.com/ . They have a free tier and seem to have a huge address pool. And I'd rather trust my data with an Austrian Company then sending it to Google. Just sayin... It could be used a s a fallback in case Nominatim returns garbage or nothing. It is not. At least with v3.0.3 of InputfieldLeafletMapMarker. You can make seperate inputfields that hold address data work together with the InputfieldLeafletMapMarker. I once wrote a module for a specific use case where I have 3 inputfields, address, postcode, city. The module loads some JS that first hides the default InputfieldLeafletMapMarker inputs, adds a button which takes the values from those fields, geocodes them through Nominatim, adjusts the marker on the map in the InputfieldLeafletMapMarker and fills the (now hidden) fields with the lat lng and name. Although I have done this about 4 years ago or so, it is still working. Here's the module code for reference in case anyone wants to go a similar route. Not a very clean and portable integration but it is doing the job and is here mainly to serve as an example how you could tackle this scenario. EDIT: short screencast to show UI AddressToMap.module.php (just loads the necessary JS) <?php use ProcessWire\HookEvent; class AddressToMap extends WireData implements Module { /** * getModuleInfo is a module required by all modules to tell ProcessWire about them * * @return array * */ public static function getModuleInfo() { return array( // The module'ss title, typically a little more descriptive than the class name 'title' => 'AddressToMap', // version number 'version' => 001, // summary is brief description of what this module is 'summary' => 'Geocode an Address and put a Pin on the Leaflet Map', // singular=true: indicates that only one instance of the module is allowed. // This is usually what you want for modules that attach hooks. 'singular' => true, // autoload=true: indicates the module should be started with ProcessWire. // This is necessary for any modules that attach runtime hooks, otherwise those // hooks won't get attached unless some other code calls the module on it's own. // Note that autoload modules are almost always also 'singular' (seen above). 'autoload' => "template=admin", // Optional font-awesome icon name, minus the 'fa-' part 'icon' => 'map', ); } public function init() { $this->wire->addHookAfter('ProcessPageEdit::loadPage', $this, 'loadAssets'); } public function loadAssets(Hookevent $event) { $id = $event->arguments(0); $page = $this->pages->get($id); if($page->template == 'member') { $this->config->scripts->add($this->config->urls->siteModules . $this->className . "/{$this->className}.js"); } } } AddressToMap.js var AddressToMap = { init: function () { // $(window).on('map:init', function (e) { // map = e.originalEvent.detail.map; // console.log(map); // }); var coder = window.L.Control.Geocoder.nominatim(); // console.log(AddressToMap.geocoder); var address = $('p.InputfieldLeafletMapMarkerAddress').css({ 'display': 'none' }); var setAddress = $('<p></p>').addClass('InputfieldLeafletMapMarkerSetAddress'); var button = $($.parseHTML("<button class='btn btn-primary btn-block' id='setAddress'><i class='fa fa-arrow-down fa-fw'></i>" + ProcessWire.config.strings.addresstomap + "<i class='fa fa-arrow-down fa-fw'></i></button>")); setAddress.append(button); setAddress.insertAfter(address); var inputfieldName = $('.Inputfield.InputfieldLeafletMapMarker').attr('id').replace('wrap_', ''); button.on('click', function (event) { event.preventDefault(); var combAddress = $('#Inputfield_address').val() + ', ' + $('#Inputfield_postcode').val() + ', ' + $('#Inputfield_city').val(); coder.geocode(combAddress, function (results) { if(results[0] !== undefined) { var map = window.leafletmap; map.eachLayer(function(layer){ if(layer.options.draggable === true) { var latlng = L.latLng(results[0].center.lat, results[0].center.lng); layer.setLatLng(latlng); $('#_' + inputfieldName + '_lat').val(results[0].center.lat); $('#_' + inputfieldName + '_lng').val(results[0].center.lng); $('input#' + inputfieldName).val(results[0].name); map.fitBounds(results[0].bbox); } }); } else { alert('Could not geocode this address'); } }); }); } } $(document).ready(function () { AddressToMap.init(); });
    1 point
×
×
  • Create New...