Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/13/2021 in all areas

  1. Here's a video demonstrating a RepeaterMatrix full page builder using PageAutosave with live preview. I really want to hear your feedback if you think "non-coders", but those with decent skills, could use such a builder successfully.
    16 points
  2. Work has continued on the Page Autosave module this week and several more improvements have been made, compiled into version 2 of the module (now posted in ProDrafts and ProDevTools). The PageAutosave portion has been improved in several ways. For instance, when the page changes elsewhere, autosave disables and displays a message letting the user know about the change. An issue with CKEditor inline fields was also fixed. But the biggest addition to the Page Autosave module was Live Preview. We've got a good discussion going on in last week's post and it helped move things forward with building the live preview feature. It's functional and working well, though it's a start and there's still more to do with it. It's far enough along to begin testing so I've posted it in the ProDevTools and ProDrafts boards. If you don't have access to either of those boards but do to one of the other VIP boards and want to test it out, let me know and I'll add it there too. Since I'm not yet certain whether this module will end up in the core, as a module, or as part of an existing Pro module package, I'm keeping it in the VIP boards at least until it's more production ready. If I find that it adds a lot of value to the core and I can fully support it there, then it'll end up in the core. Here's how the live preview feature works: When live preview is enabled (it is by default), the “View” tab in the top of the page editor supports a live preview option. To see it, hover the “View” tab and it should appear. When you click the live preview link it will open a new window. Drag and size the live preview window so that you can see it at the same time as your page editor, whether side-by-side, above or below, or on another screen. As you make changes in the page editor and they are automatically saved, the live preview window will also update automatically. No development required There is no development required to use live preview, you don't have to insert anything into your template files to start using it. The live preview window updates by re-rendering the page and replacing the entire <body> markup of the page. I found this works well in several places where I tested it and it has the benefit of looking pretty seamless and keeping your scroll position, etc. But it's not going to work everywhere, and it can also lose JS events (though I'm looking into how we can improve that). This might be okay since you are just previewing content and layout, but it's something to keep in mind. If you find the default <body> replacement doesn't work well for your instance, there's a setting in the module configuration where you can tell it to reload/refresh the window for live preview instead. This will pretty much always be reliable, but it also looks like a page refresh, which somewhat reduces the live preview effect. To control and improve performance of live preview There's another option that enables you to have more control over how live preview works while also significantly improving the performance of it. The tradeoff is that you need to add class names in your markup for live preview to recognize and update. When you want live preview to just render and replace the value for the field being edited, you can edit your template file(s) and surround the field value output with a tag having the class name "pw-value-name" where "name" is the name of the field that has its value contained within. This can significantly increase performance as live preview can render and dynamically update just the changed field rather than the entire page. For example, let’s say you had the following markup: <h1><?= $page->title ?></h1> To mark it up for fast live preview, you would add a new class: <h1 class='pw-value-title'><?= $page->title ?></h1> When an update is made to the “title” field in the page editor, live preview will notice the h1.pw-value-title in your markup and it can skip rendering the entire page and instead just render the value of the “title” field for the page, and replace it directly. A few things to note about this: 1. Live preview replaces the “inner HTML” of the element directly with the formatted field value. You should not have any other markup within there, unless it’s part of the field’s formatted value already. 2. The surrounding element (<h1> in the example above) can have any other class names or attributes that you want it to have. Live preview does not replace the tag, only the contents within it. So if you add the pw-value-* class to an existing element that already has other classes or attributes, that’s fine, it's flexible. 3. When you use this option, consider also using it in other places you output the same field value (if there is more than one), otherwise live preview won’t update the ones that aren't identified with the pw-value-* class. So if your $page->title appears elsewhere, like in breadcrumbs (for example) then that breadcrumb instance of the title won’t update, unless it is also marked up with the pw-value-title class. Maybe that is fine for breadcrumbs for it not to update, but it’s just something to be aware of. 4. This pw-value-* option is just for basic text, textarea (including CKEditor) and number fields. Don't use this stuff in repeater, file/image and other more complex fields, as those will always involve generated markup beyond just the field value. For something like a blog post or other article type of page, if you want a 2 minute solution that'll give you the most return, just wrap your $page->body output and call it a day: <div class="pw-value-body"><?= $page->body ?></div> ...that way any changes to your "body" field will update more quickly and without having to re-render the page. What's remaining Like discussed in last week's thread, I'd still like to add support for "pw-field-*" classes. This will be similar to the "pw-value-*" classes, except that it'll enable replacing blocks of generated markup within the element having that class name, rather than just the field value. This'll be useful for people really getting into live preview. But I also kind of think that most people will want to use live preview without having to add anything in their markup, and it works quite well that way too. This is all I worked on this week so no core updates to report (though this may count as core updates if it ends up in the core). Thanks for reading and have a great weekend!
    9 points
  3. For anyone that is testing out the live preview feature in the PageAutosave module, if you have any trouble getting it to work, here's a few troubleshooting notes: 1. Try temporarily disabling Tracy debugger on the front-end (if using it). I found that I couldn't have Tracy debugger active on the front-end while using live preview, otherwise neither Tracy or live preview would work. I think the two conflict with each other in some way and I just haven't figured it out yet but will work with it more next week. 2. If using ProCache with HTML minify, try turning that feature off for logged-in users. You can do this in Setup > ProCache > Minify. The reason for this is that HTML minify removes a few technically unnecessary markup tags that live preview may need. I will also be able to find a workaround for this, but just haven't had a chance yet. 3. Make sure your HTML document has <head>, </head>, <body> and </body> tags present in the output. 4. If your page does a lot of its layout with Javascript and isn't working with live preview, go to the PageAutosave module settings and near the bottom are the Live Preview settings. For the "Default live preview update method" choose "Reload/refresh document". 5. If still not working, try enabling the PageAutosave debug mode. You'll find this at the bottom of the PageAutosave module settings. This makes it report verbose javascript console.log messages. Open your javascript console when using live preview and please let me know what messages you get.
    5 points
  4. @Jonathan Lahijani - speedy work on the video :) I've been thinking of doing a very similar thing with RM and Uikit to create a lot more flexibility that what I have been currently offering. I do think that with a minimal amount of training some clients will be able to do great things, but for other clients I think I would stick with more strictly defined block types. I think it comes down to a combination of what works best for the site's layout requirements and the skills of the client. Great to hear that you are planning on releasing what you've built here, because I know you've put a lot of thought into this and I am sure there's a fair bit of effort in getting everything configured so nicely!
    5 points
  5. @wbmnfktr Sounds good, those are the boards you are able to view? I've added it to the first one you mentioned (ProFields board). Thanks.
    4 points
  6. I forgot to mention earlier, but I haven't yet experimented with integrating htmx into this. Trying to start simple so right now it's all original PHP/JS. I do plan to experiment with htmx here to see what additional options it'll open up. The current version does however use server side events (SSE) like some of you guys (Ivan, Netcarver, Kongondo) suggested. @Ivan Gretsky Configurable repeater type colors I haven't yet added but will try to do that this coming week.
    3 points
  7. Hi @Ivan Gretsky - I am sorry about the delay on this and it's actually pretty stupid really because @teppo already came up with what seems to be a great solution: https://github.com/adrianbj/TracyDebugger/issues/56 I have implemented this in the latest version, so all you need to do is add this to your config.php file: $config->tracy = [ 'guestForceDevelopmentLocal' => true, 'forceIsLocal' => true, ]; Keep in mind that the "guestForceDevelopmentLocal" isn't necessary if you already have that checked in the module settings. @Robin S - does this approach also work for your needs (that you PM'd me about ages ago)? Obviously we need to be really cautious with this new option to make sure it isn't used on a live site that is accessible to the world!
    3 points
  8. I am honest here @Jonathan Lahijani... I'm more than impressed. I know what ProcessWire can do but I didn't know what some could accomplish with it and this is such a BANGER! I don't think my clients could easily work with it, maybe a few after some introduction, but that's another story. The people from this community, I know a bit more, could probably easily maintain and build a site with this setup from scratch and customize it if needed - even though at least half of them don't really use UIKIT for websites or need and want to go a more custom route however. Still shocked to witness something like this while I still try to figure out why my textarea doesn't always gets updated in the live preview. :D
    3 points
  9. Yes! Just downloaded it for tomorrow to play around with it. I have to thank you, @ryan!
    2 points
  10. In preparation for testing of the initial (alpha/early beta) release of Padloper 2, I would like to gather expressions of interest. In the past, some of you expressed a willingness to help with testing. It has been many days since and your position might have changed. In addition, I would like to do this in an organised manner so we cover as much ground as possible. The grounds I’d like to cover are usability and technical aspects with a bias towards the latter. Please also note that there are a number of planned features that will follow the initial release. Hence, we shouldn’t focus much on those. These and similar thoughts will be added to a planned features list (more on this below). The main focus of this testing is to make Padloper 2 production-ready. In order to properly organise this testing, I will need to gather some information from you. I will be doing this via Google Forms. The most important detail will be your email address. I will need this in order to inform you how to access Padloper 2 as well as for other necessary communication. I will not use your email address for any other purposes nor pass it to any third-party ?. Other information to be captured in the form would be what areas of testing you will you want to be involved in and your preference for planned features (since I will need to prioritise them). Forms are better than plain emails in this respect. Please note the following if you wish to be involved in the testing programme: Pricing and subscription will follow the model I have previously stated (similar to ProcessWire Pro Modules). However, for the testing programme, your subscription period will NOT start counting down until after the production-ready release. You will still also have VIP support (please note the nature and location of this may change). To be fair to other testers, anyone joining the programme needs to actually spend time testing the product. If you won’t have time to do this, please wait for the production release. This initial release is NOT a production release. Although it may work for some in that regard, it will not be tagged as production-ready (hence the alpha tag). Licences will be the usual three: (i) Basic/Single Site Licence, (ii) Developer Licence and (iii) Agency Licence. I can explain the different between these three if anyone needs clarity. The initial release will have the introductory prices of €150, €300, €900 for single, developer and agency licences respectively. Cooling period will be 14 days (within which a full refund can be requested, no questions asked). Please note that this time period may change for the production release. Here is the link to the Google Form to express your interest in the testing programme. The form will close in 10 days. Many thanks for your patience. Hope to see you soon in the testing programme. I trust you will enjoy Padloper 2 as much as I have had the pleasure (and honour) of developing it ?.
    1 point
  11. Hello, my Processwire family. Just minutes ago I flipped on the switch for my agency's new website. Check it out here: https://supertiny.agency/ This is a year of changes. I've finished my collab with a major studio, focused back on Supertiny, Liliana joined me for marketing, campaigns and strategy services, and over the last few months I've been working on the agency's website overhaul. Curiosities: Threejs based intro: After learning a few new tricks from the Awwwards winner Bruno Simon and his incredible course, I went oldschool and made an intro for this website. The intro runs once, the session remembers it's been played and turns to a discreet mode if users return to the homepage, allowing a replay. Using my Tiny Cookie Consent as a web component, I made an approach that I'll probably use a lot going forward. I have a text field in the CMS for all the scripts, and with some PHP find/replace that's undone on the client side, trackers and stats are being turned on only when the user allows it. As usual, repeaters and content blocks allow mix and match when building content. The design and overall vibe takes cues from 80's sci-fi. When I started designing this I was playing Control on my PS4 and overloaded with nostalgia, and attempted to convey some of that in this website. Now, there's a bit of an experiment here. All UX bibles are saying that it's a sin make an intro, lock scroll and whatnot. But this is a site users are probably only going to see once. So my approach here is more like a Yield sign. There's an intro, the scroll is locked, but you have a skip button. I'm basically trying to make the user slow down a bit and take in the concept, but let them through if they're really in a rush. Also, as a communication strategy, I'm placing my bets on case studies that will be promoted in social networks, and also new content on the Insights which will hopefully become more interesting with video content. Users coming from there will only see the intro if after seeing that content they get curious and have a lookaround. This is making sense in my head, but it's a bet. I'm curious to see how it performs and if I have to change the approach. Let me know what you think.
    1 point
  12. Thanks @ryan. All the pieces were already in place. I've been working on this concept for a while now and with live preview, everything has come together. @Ivan Gretsky That's just with custom CSS I'm loading in the admin. Like this: // assuming RM field is called 'builder' and matrix-type is called 'builder_column' #wrap_Inputfield_builder [data-typename="builder_column"].InputfieldRepeaterItem > label.InputfieldHeader { outline: 1px solid #777; outline-color: #777; background-color: #777; } @bernhard The 'options' field (powered by Mystique) has a plethora of options for each matrix-type. The 'Image' matrix-type has a 'width' and 'height' field that if set, will set it to the specified width (->width(width)), specified height (->height(height)) or size (->size(width, height)). If no values are entered, it uses the original dimensions.
    1 point
  13. I'm not sure what I was talking about back then, but you can simply do something like this: <?php namespace ProcessWire; class MyPage extends Page { public function init() { $this->addHookAfter("ProcessPageEdit::buildForm", $this, "buildForm"); } public function buildForm(HookEvent $event) { $page = $event->process->getPage(); if(!$page instanceof self) return; // $page is a MyPage object now $form = $event->return; // get the title field and add a note if we find it if($f = $form->get('title')) { // note that we use $page->foo() and not $this->foo() $f->notes = "I am a MyPage object and my foo() method says: ".$page->foo(); } } public function foo() { return 'MyPage-Foo!'; } } Note that the hook in this example never gets executed! You'd need to trigger it once. Where you do that is up to you - I'm usually doing that via RockMigrations (https://github.com/BernhardBaumrock/RockMigrations/blob/5cafb3c6c0f2004b8d4087ca243cc0d5f771dd11/RockMigrations.module.php#L377) but you could also add it in init.php <?php $tmp = new MyPage(); $tmp->init(); This adds a little overhead since we load an additional instance of MyPage on every request but I do much more prefer that over getting more and more of a hook hell on larger projects. The way I showed above is much cleaner and keeps everything where it belongs: To the MyPage class. Now once you open a MyPage in the PW backend you get the note on the title field and you know where to look for that hook: In MyPage.php - not in ready.php, or init.php, or another module, or wherever else...
    1 point
  14. This is the exact thing that I was wanting. Thanks for the share. ?
    1 point
  15. Any would do for me) But maybe a border from one side could be enough? Top or left. Another option would be a warning sign icon to the left of the TRACY label with a popup, describing why it is here (kind of like Server Type Indicator).
    1 point
  16. Thanks for making this video @Jonathan Lahijani! There is a lot to study from it. Let me ask one question right away. How did you changed the block colors? Is that already build in like Ryan said it would, or is it with custom css for now?
    1 point
  17. Welcome to the forums, @Shohan Arafat! If you want it in admin it must be a custom process module. You can learn how to make one here (for example). But I am not sure I really understood your needs. This is your 1st post, and it might be you meant something very different. Please explain your needs better if my link above is too much or completely irrelevant.
    1 point
  18. I'd really love to play around with this option to be honest. Therefore if possible... maybe you could add it to ProFields, ProCache, FormBuilder, LoginRegister Pro, Lister Pro, or ProMailer (in my case). Or... maybe add a ProLivePreview Beta for 5 USD to the modules. I'd buy it!
    1 point
  19. I think there's no way around this issue except for the developers to adapt their code a bit, have their page working without javascript, or a full page reload. I tried to check if there was a way to somehow "reset" the javascript but it seems there's none. What I like about this is how it's somehow reminiscent of front-end editing's method D. Maybe it could be something to rely on for the live preview as well ?
    1 point
  20. New module: OneTimeOnlyCode https://github.com/benbyford/OneTimeOnlyCode Use this module to create codes with urls (or any of string data) and later check a code and its data e.g. to get one time access to content. I built this to send out specific "exclusive" users codes at the end of URLs to new articles where noramlly they would have to log in -> now they can see the content only once and then have to login if they navigate away. I made it only to show the content not any user profile infomation etc when using the code, be warned not to use it to show user information unless you know what you're doing! Codes can have an expiry and uses lazy-cron to cull codes out of day at a set interval (both in checking and elapsed interval for the codes). Check it out!
    1 point
  21. I have had a play and some of the implementation is literally, trivial ?. SSE SSE is so simple it is unbelievable at first. You only need two things: in our case PHP and a modern browser...batteries included! Example adapted from w3schools. More examples at MDN. server-side <?php namespace ProcessWire; header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); $time = date('r'); echo "data: The server time is: {$time}\n\n"; flush(); client if(typeof(EventSource) !== "undefined") { var source = new EventSource("/some-processwire/url/"); source.onmessage = function(event) { document.getElementById("result").innerHTML += event.data + "<br>"; }; } else { document.getElementById("result").innerHTML = "Sorry, your browser does not support server-sent events..."; } I tested it and it works fine but was getting errors about wrong mime type if I set the headers later, but that is to be expected. Live Preview Refresh - Partial and Full - ajax - htmx I have this working nicely (will try post the demo later today). The premise is: A change happens. The editor client sends the data to the server to save the change (autosave - was just mimicking this part). Server saves and sends back a response including the name of the field that has been saved and the page ID back to the editor client. The editor client communicates with the preview client (a separate window). It sets the page ID and the name of the changed field name in its message to the preview window. The preview window client (htmx) receives the page id and the name of the field that has changed and sends a request to the server to fetch the rendered contents of that field for that page. The server sends back the html for htmx to swap in the DOM. In this simple communication, we have the field name match the html id of the element we are swapping. E.g. <h2 id='headline'>My Headline</h2> This is simple and straightforward and easily achieves partial refresh. However, it will be difficult to handle the more complex cases I mentioned in my previous post. It will also be somewhat dictating how the developer should name their html attributes. In addition, it still leaves the developer's templates with htmx attributes that will not be needed in production. This got me thinking. Live Preview Wrapper - idea #1 In this case, the live preview window would add a wrapper html element around the rendered template file markup. The wrapper html element would have the htmx attributes instead of the template file markup. This idea didn't go very far. It would inevitably lead to broken / incorrect markup in the preview window as the outermost markup of the template file would be <html> tags. In addition, while it solves the problem of unrequired htmx attributes in production, it doesn't solve the problem of selective rendering. It still wouldn't' know what parts of the markup in the preview window to swap. Live Preview Config - idea #2 What if instead of live preview / ProcessWire suggesting things like naming of elements, standard markup, etc. that are needed in a template file in order to get selective markup rendering, we implemented it the other way round? What if the developer instead, via config file(s), passed properties to live preview to implement the htmx attributes needed for a template file / page? The default would be full page refreshes. However, if live preview detected that a partial refresh config was available, it would implement those. This would offer the granularity needed for partial refreshes. If live preview did not receive / detect any configs, the default would kick in. Live preview would remain as agnostic as possible. It could be something like this (assumes use of htmx): A developer places their live preview partial refresh configs in /site/templates/live-previews/basic-page-live-preview.php (or basic-page-live-preview.json). ProcessWire detects that the template file basic-page has a partial refresh config in .../live-previews/basic-page-live-preview.php When ProcessWire loads the preview window, it injects the htmx attributes for each named element in the live preview configs in the corresponding elements in the preview window DOM. Injection is done by a ProcessWire live preview near-agnostic JavaScript script that only runs in the preview window. When the autosave happens in the editor window and the preview window gets informed, htmx kicks in, responding to an event and fires htmx.trigger(elem, event). The element in the markup with the corresponding event listener (hx-trigger='this-element-event-fired') will pick up the event fired by htmx.trigger() and query the server for the changed markup. The attributes set in #3 will ensure only the markup that has a change will fire. Server sends the response back and the element's hx-swap (or even hx-oob) picks it up and swaps the DOM. #6 is still not straightforward though. What will live preview / ProcessWire send back? Here too the config at #1 can help. E.g. it can tell ProcessWire to send <p>My Field Value</p> or just send the value of the field back, i.e. 'My Field Value'. The former is still complicated. Instead of telling ProcessWire I want <p>My Field Value</p>, how about tell it, via the configs at #1 that if requested field is field A, send me back the raw value (e.g. a plain text) but if the request is for field B, use this defined function in basic-page-live-preview.php to send me the rendered partial markup for field B? All ProcessWire would do is pass the value of field B to the said function. This value could be a Pageimages object. The function would iterate the images and send back the 'gallery' markup back to htmx to swap. example live preview config <?php namespace ProcessWire; $livePreviewConfigs = [ [ 'field' => 'headline', 'element_id' => 'my_headline_element_id', 'htmx-attributes' => ['hx-swap' => 'outerHTML', 'hx-trigger' => 'headlineevent'] ], [ 'field' => 'images', 'element_id' => 'gallery', 'handler' => 'renderGallery','htmx-attributes' => ['hx-swap' => 'innerHTML', 'hx-trigger' => 'galleryevent'] ], ]; function renderGallery(Pageimages $images) { // we only need the <li> since we are using innerHTML swap // the target element is <ul id='gallery'></ul> // -------------- $out = ""; foreach ($images as $image) { $thumb = $image->size(200, 200); $out .= "<li><img src='{$thumb->url}' alt='{$image->url}'></li>"; } // --------- // sent back to htmx to swap return $out; } When the preview window loads, ProcessWire sends $livePreviewConfigs to the browser, e.g. ProcessWire.config.LivePreview. The preview window JavaScript would consume it like this: client set htmx attributes @note: JavaScript written in the browser, not tested, could have errors. // get live preview configs const elementsConfigs = ProcessWire.config.LivePreview // loop through configs, find the corresponding element and set their htmx attributes for (const elementConfig of elementsConfigs) { const element = document.getElementById(elementConfig.element_id) if (element) { const htmxAttributes = elementConfig['htmx-attributes'] for (const [prop, value] of Object.entries(htmxAttributes)) { element.setAttribute(prop,value); } } } htmx-ready DOM changes via live preview injection (runtime only in live preview window): <h2 id="my_headline_element_id" hx-swap='outerHTML' hx-trigger='headlineevent' hx-vals='{"field":"headline"}'>My Headline</h2> <!-- gallery --> <ul id="gallery" hx-swap='innerHTML' hx-trigger='galleryevent' hx-vals='{"field":"images"}'> <li><img src='image-1-src' alt='image-1-alt'></li> <li><img src='image-2-src' alt='image-2-alt'></li> </ul> I have partly implement the above (just hard-coded configs for now) and it works nicely. Takeaways ProcessWire's live preview remains as agnostic as possible. Developer give instructions to live preview (via configs) and not the other way round. Live preview ships with minimal defaults, including full page refresh. It seems like a lot of work on the developer's part if they want partial refresh. However, this partly matches the complexity of their template files. Besides, some of the functionality (e.g. renderGallery()) could be something they already use in their template, hence reusable. Developer does not need to have additional markup in their template files in order to see live previews when editing. This means no cleaning up afterwards. Their templates remain clean. Live preview only alters the DOM (of the rendered template) at runtime. Developer can name their markup attributes as they wish. Developer can decide what needs live preview and what doesn't, even on the same page (e.g. hx-select). ProcessWire stays out of the developer's way, as usual.
    1 point
  22. Many thanks for this, @Mats var request = new Request(url, { headers: new Headers({ 'X-Requested-With': 'XMLHttpRequest' }) }); fetch(request) .then(response => response.text()) .then(data => { console.log(data); });
    1 point
  23. This works for me: $pages->addHookAfter("ProcessPageEdit::buildFormContent", function($event) { if($event->object->getPage()->id !== 1016) return; $wrapper = $event->return; if(!$wrapper->has('body')) return; $wrapper->body->collapsed = Inputfield::collapsedHidden; }); I have included a check for the ID of the page being edited. So in this case it will only hide the "body" field on a page with ID 1016. Hopefully you can modify that for your needs. BTW, I just put that code in my site/init.php file - no need for a module for something so simple.
    1 point
  24. Hey Marty - sorry for taking so long to get back to you - busy day So you could do this with Ajax calls to a PHP script like the following. It would be called whenever someone clicks on a property. This would be a toggle approach, which may or may not be appropriate depending on how the site is set up. In this case, the cookie would store an array of the property IDs. $pid = $page->id; if (!in_array($pid, $favs)) { //add to the array if not already in it $favs[] = $pid; } else { $key = array_search($pid, $favs); unset ($favs[$key]); //remove from array if already in it } $data = base64_encode(serialize($favs)); setcookie('property_favs', $data, time() + 86400 * 100, '/'); Then to read the cookie back in, something like this: $favs = unserialize(base64_decode($_COOKIE['property_favs'])); That will give you an array of page ids that you can use to populate the user's favourites. If you want to go with a combination of javascript and PHP, you can do that also. Firstly, I recommend taking a look at this jquery helper: https://github.com/carhartl/jquery-cookie You can add the property/page id to the cookie using that and then retrieve on page load using PHP. Instead of storing an encoded array, you can also store a separated list of IDs. This example is using raw javascript: if(readCookie('property_favs')){ document.cookie = 'property_favs=' + readCookie('property_favs') + escape('|' + pid) + '; path=/'; } else{ document.cookie = 'property_favs=' + escape('|' + pid) + '; path=/'; } So if the cookie exists, then read it and add on a new pid after a pipe character and escape it so it can be stored in the cookie. If the cookie doesn't exist, create it with the current pid. The jquery cookie plugin will make this cleaner. Remember to use your developer console as it will show you the current cookie contents. In Chrome it is one of the options under Resources. In Firefox I seem to remember installing a plugin for Firebug to analyze cookies. It's really pretty easy once you play around with it. Let us know if you have any specific questions.
    1 point
×
×
  • Create New...