I have a Seaside application that is almost 100% AJAX driven to
replace the visual components (no call/answer involved). I plan to to use history.pushState() and history.replaceState() My plan is to update the browser url after replacing some components, but using the URL building of the existing #updateUrl: (including _s/_k parameters and whatnot). Is it possible to obtain the URL of the session presenter within the ajax response? Thanks in advance, Esteban A. Maringolo _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Hi Esteban,
I’m interested in this too. We have the same kind of application (I guess… using mostly Ajax updates, I mean) but I have just been postponing a retry to address the inconsistency with ajax, server state and the back button for years…. Within a callback, you can get at the #actionUrl on the renderer. Is that what you want? I’m trying to dive into what would be required here… trying to understand what you need: Ajax requests always update the same continuation state in Seaside (i.e. they do not create a new continuation)… so if you push that url to the history after each ajax update, the back button will essentially request the same but updated continuation from Seaside, meaning you should see the state as it is in on the server, and not how it was before you made the ajax request (which is what happens now). Does that correspond to what you are trying to fix? Johan > On 12 Apr 2019, at 15:17, Esteban Maringolo <[hidden email]> wrote: > > I have a Seaside application that is almost 100% AJAX driven to > replace the visual components (no call/answer involved). > > I plan to to use history.pushState() and history.replaceState() > > My plan is to update the browser url after replacing some components, > but using the URL building of the existing #updateUrl: (including > _s/_k parameters and whatnot). > > Is it possible to obtain the URL of the session presenter within the > ajax response? > > Thanks in advance, > > Esteban A. Maringolo > _______________________________________________ > seaside mailing list > [hidden email] > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Hi,
Not really answering your questions, but I think this is what Iliad is for. There you have access to a restful URL on every (xhr) request and every WAComponent is transparently updated via xhr, including when you use call-answer. Just FYI. :) Siemen Sent from my iPhone > On 12 Apr 2019, at 17.23, Johan Brichau <[hidden email]> wrote: > > Hi Esteban, > > I’m interested in this too. > We have the same kind of application (I guess… using mostly Ajax updates, I mean) but I have just been postponing a retry to address the inconsistency with ajax, server state and the back button for years…. > > Within a callback, you can get at the #actionUrl on the renderer. > Is that what you want? > > I’m trying to dive into what would be required here… trying to understand what you need: > Ajax requests always update the same continuation state in Seaside (i.e. they do not create a new continuation)… so if you push that url to the history after each ajax update, the back button will essentially request the same but updated continuation from Seaside, meaning you should see the state as it is in on the server, and not how it was before you made the ajax request (which is what happens now). > > Does that correspond to what you are trying to fix? > > Johan > >> On 12 Apr 2019, at 15:17, Esteban Maringolo <[hidden email]> wrote: >> >> I have a Seaside application that is almost 100% AJAX driven to >> replace the visual components (no call/answer involved). >> >> I plan to to use history.pushState() and history.replaceState() >> >> My plan is to update the browser url after replacing some components, >> but using the URL building of the existing #updateUrl: (including >> _s/_k parameters and whatnot). >> >> Is it possible to obtain the URL of the session presenter within the >> ajax response? >> >> Thanks in advance, >> >> Esteban A. Maringolo >> _______________________________________________ >> seaside mailing list >> [hidden email] >> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside > > _______________________________________________ > seaside mailing list > [hidden email] > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Oh man if only our past selves knew we really wanted Iliad apps what a world
this would be.... In my apps I use $.fn.updateUrl = function(anId){ if (typeof(window.history.pushState) == 'function') { var relativeUrl = $(this).attr('href'); if(typeof(relativeUrl) =='undefined'){ relativeUrl = document.location.pathname+document.location.search; }; if(relativeUrl!=='javascript:void(0)' && relativeUrl !== window.history.state){ window.history.pushState(relativeUrl, document.title, relativeUrl); } } }; and call it as part of the onClick: script on anchors and buttons BEFORE loading content via ajax. So the onClick: is onClick: html jQuery this updateUrl, (self doContentLoadingMagicOn: html) Also it doesn't need to be a jQuery function but is because it was different when I initially made it. Not sure its what you want to do but it definitely sets the window location (url) to something that when you hit refresh gives you the same page you see before you hit refresh (with updated server content, if anything there has changed in the interim). Siemen Baader wrote > Hi, > > Not really answering your questions, but I think this is what Iliad is > for. There you have access to a restful URL on every (xhr) request and > every WAComponent is transparently updated via xhr, including when you use > call-answer. > > Just FYI. :) > > Siemen > > Sent from my iPhone > >> On 12 Apr 2019, at 17.23, Johan Brichau < > johan@ > > wrote: >> >> Hi Esteban, >> >> I’m interested in this too. >> We have the same kind of application (I guess… using mostly Ajax updates, >> I mean) but I have just been postponing a retry to address the >> inconsistency with ajax, server state and the back button for years…. >> >> Within a callback, you can get at the #actionUrl on the renderer. >> Is that what you want? >> >> I’m trying to dive into what would be required here… trying to understand >> what you need: >> Ajax requests always update the same continuation state in Seaside (i.e. >> they do not create a new continuation)… so if you push that url to the >> history after each ajax update, the back button will essentially request >> the same but updated continuation from Seaside, meaning you should see >> the state as it is in on the server, and not how it was before you made >> the ajax request (which is what happens now). >> >> Does that correspond to what you are trying to fix? >> >> Johan >> >>> On 12 Apr 2019, at 15:17, Esteban Maringolo < > emaringolo@ > > wrote: >>> >>> I have a Seaside application that is almost 100% AJAX driven to >>> replace the visual components (no call/answer involved). >>> >>> I plan to to use history.pushState() and history.replaceState() >>> >>> My plan is to update the browser url after replacing some components, >>> but using the URL building of the existing #updateUrl: (including >>> _s/_k parameters and whatnot). >>> >>> Is it possible to obtain the URL of the session presenter within the >>> ajax response? >>> >>> Thanks in advance, >>> >>> Esteban A. Maringolo >>> _______________________________________________ >>> seaside mailing list >>> > seaside@.squeakfoundation >>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside >> >> _______________________________________________ >> seaside mailing list >> > seaside@.squeakfoundation >> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside > _______________________________________________ > seaside mailing list > seaside@.squeakfoundation > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside -- Sent from: http://forum.world.st/Seaside-General-f86180.html _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Oh and I forgot that the onClick: is housed in another function that allows
the ajax pushState anchors to work even if JS is disabled or there is no session and looks like this: WAAnchorTag>>#pjaxCallback: aBlockClosure on: html withSuccessScript: aScript self onClick: (self processCallback: aBlockClosure onSuccess: self setBodyJs , aScript return: false thenUpdateBodyOn: html); callback: aBlockClosure & processCallback: aCallback onSuccess: aJSFunction return: aBoolean thenUpdateBodyOn: html self hasSession ifTrue: [ | scr | scr := html jQuery ajax html: [ :h | aCallback value. self renderUpdatedBodyContentFor: self session pjaxBody on: h ]; onSuccess: aJSFunction. aBoolean notNil ifTrue: [ scr return: aBoolean ]. ^ html jQuery this updateUrl , ((html jQuery class: 'active') removeClass: 'active') , scr ] ifFalse: [ ^ nil ] So its html anchor pjaxCallback:[ self doSomethingYourClientsLove ] on: html withSuccessScript: (JSStream on:'alert("I don't believe that worked")'); with: 'Click me' Paul DeBruicker wrote > Oh man if only our past selves knew we really wanted Iliad apps what a > world > this would be.... > > > > In my apps I use > > $.fn.updateUrl = function(anId){ > > if (typeof(window.history.pushState) == 'function') { > var relativeUrl = $(this).attr('href'); > if(typeof(relativeUrl) =='undefined'){ > relativeUrl = > document.location.pathname+document.location.search; > }; > if(relativeUrl!=='javascript:void(0)' && relativeUrl !== > window.history.state){ > window.history.pushState(relativeUrl, document.title, > relativeUrl); > } > } > }; > > and call it as part of the onClick: script on anchors and buttons BEFORE > loading content via ajax. > > So the onClick: is > > > onClick: html jQuery this updateUrl, (self doContentLoadingMagicOn: html) > > > Also it doesn't need to be a jQuery function but is because it was > different > when I initially made it. > > > > Not sure its what you want to do but it definitely sets the window > location > (url) to something that when you hit refresh gives you the same page you > see > before you hit refresh (with updated server content, if anything there has > changed in the interim). > > > > > > > Siemen Baader wrote >> Hi, >> >> Not really answering your questions, but I think this is what Iliad is >> for. There you have access to a restful URL on every (xhr) request and >> every WAComponent is transparently updated via xhr, including when you >> use >> call-answer. >> >> Just FYI. :) >> >> Siemen >> >> Sent from my iPhone >> >>> On 12 Apr 2019, at 17.23, Johan Brichau < > >> johan@ > >> > wrote: >>> >>> Hi Esteban, >>> >>> I’m interested in this too. >>> We have the same kind of application (I guess… using mostly Ajax >>> updates, >>> I mean) but I have just been postponing a retry to address the >>> inconsistency with ajax, server state and the back button for years…. >>> >>> Within a callback, you can get at the #actionUrl on the renderer. >>> Is that what you want? >>> >>> I’m trying to dive into what would be required here… trying to >>> understand >>> what you need: >>> Ajax requests always update the same continuation state in Seaside (i.e. >>> they do not create a new continuation)… so if you push that url to the >>> history after each ajax update, the back button will essentially request >>> the same but updated continuation from Seaside, meaning you should see >>> the state as it is in on the server, and not how it was before you made >>> the ajax request (which is what happens now). >>> >>> Does that correspond to what you are trying to fix? >>> >>> Johan >>> >>>> On 12 Apr 2019, at 15:17, Esteban Maringolo < > >> emaringolo@ > >> > wrote: >>>> >>>> I have a Seaside application that is almost 100% AJAX driven to >>>> replace the visual components (no call/answer involved). >>>> >>>> I plan to to use history.pushState() and history.replaceState() >>>> >>>> My plan is to update the browser url after replacing some components, >>>> but using the URL building of the existing #updateUrl: (including >>>> _s/_k parameters and whatnot). >>>> >>>> Is it possible to obtain the URL of the session presenter within the >>>> ajax response? >>>> >>>> Thanks in advance, >>>> >>>> Esteban A. Maringolo >>>> _______________________________________________ >>>> seaside mailing list >>>> > >> seaside@.squeakfoundation > >>>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside >>> >>> _______________________________________________ >>> seaside mailing list >>> > >> seaside@.squeakfoundation > >>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside >> _______________________________________________ >> seaside mailing list > >> seaside@.squeakfoundation > >> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside > > > > > > -- > Sent from: http://forum.world.st/Seaside-General-f86180.html > _______________________________________________ > seaside mailing list > seaside@.squeakfoundation > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside -- Sent from: http://forum.world.st/Seaside-General-f86180.html _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by Johan Brichau-2
Hi Johan,
Hi reply below. On Fri, Apr 12, 2019 at 12:23 PM Johan Brichau <[hidden email]> wrote: > > Hi Esteban, > > I’m interested in this too. > We have the same kind of application (I guess… using mostly Ajax updates, I mean) but I have just been postponing a retry to address the inconsistency with ajax, server state and the back button for years…. I've been postponing this for a while but will need it sooner than later :) > Within a callback, you can get at the #actionUrl on the renderer. > Is that what you want? I can't tell really, the actionUrl now, only has something like this `/?_s=...&_k=...`, so certainly it doesnt. > I’m trying to dive into what would be required here… trying to understand what you need: > Ajax requests always update the same continuation state in Seaside (i.e. they do not create a new continuation)… so if you push that url to the history after each ajax update, the back button will essentially request the same but updated continuation from Seaside, meaning you should see the state as it is in on the server, and not how it was before you made the ajax request (which is what happens now). I have a tree of nested component, which where working without using AJAX, and had all the "#updateUrl:" methods in place, so if for instance, I had a root component and opened a project ABCD, I added the `/project/ABCD' to the URL. So when the user came back later for that URL, I could lookup for that project and initialize the proper "tree" of components to show it (or show an error if not found, etc.). I then moved to everything as AJAX to make things faster and simplify the state management... and lost this capability. I drive most AJAX interactions by means of "script" AJAX responses, so my idea is to change the component tree structure at the server side (as I'm doing now), and at the end of some "top level" loading/reload push the URL that would have been generated by means of a regular visitor transversal to browser history stack. Let's suppose we have a common CRUD like UI very much like the ones used by REST APIs, so we have the following components UsersComponent -> 'users' UserComponent -> 'admin' UserSectionComponent -> 'settings' So if the app is showing aUsersComponent as its main component (I call it `bodyComponent`) then the url would be `/users`, when some user is selected, the bodyComponent (aUsersComponent) "shows" (#show:) aUserComponent, this adds the userId component to the URL, and if within that component I access a particular section of the user (e.g. 'settings' or 'preferences'), then that gets added to the URL as well. I want that when I call `scriptReplaceOn: aScript` of a particular one of these components they do something like this: `UserComponent>>scriptReplaceOn: aScript aScript << ((aScript jQuery id: self ajaxId) replaceWith: [:h | self renderContentOn: h]). aScript << ((JSStream on: 'window.history') call: 'pushState' with: self historyState). And `historyState` would have this "resolved" WAUrl instance, that I guess would be initialized using a WAUpdateUrlVisitor from current component (e.g. UserSectionComponent) to the root (although in the inverse order). > Does that correspond to what you are trying to fix? I guess it does. But I'm not sure whether I'm using the states and continuations the canonical way. Things work, causing a full page reload shows the exact same content as it was before, but backbutton does nothing (it behaves as a full page reload). I feel like I have not answered your question, but since there is no "recommended" way to work with components with AJAX (e.g. replacing the instVar, using show/call/answer, etc.), I don't know whether a "suitable" solution might be found. Esteban A. Maringolo _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by Paul DeBruicker
Hi Paul,
I've seen that code before ;-) and maybe setting the URL **before** is the way to go. In your case you always replace the "body" component of your page, I might need to adapt it in a way that could replace any DOM element. Regarding this: "Not sure its what you want to do but it definitely sets the window location (url) to something that when you hit refresh gives you the same page you see before you hit refresh (with updated server content, if anything there has changed in the interim)." I don't remember how you consumed that in #initialRequest and whether you specified #updateUrl: (and kept it in sync on each "pjaxCallback:..." call). Regards, Esteban A. Maringolo On Fri, Apr 12, 2019 at 1:47 PM Paul DeBruicker <[hidden email]> wrote: > > Oh and I forgot that the onClick: is housed in another function that allows > the ajax pushState anchors to work even if JS is disabled or there is no > session and looks like this: > > > WAAnchorTag>>#pjaxCallback: aBlockClosure on: html withSuccessScript: > aScript > self > onClick: > (self > processCallback: aBlockClosure > onSuccess: self setBodyJs , aScript > return: false > thenUpdateBodyOn: html); > callback: aBlockClosure > > > & > > processCallback: aCallback onSuccess: aJSFunction return: aBoolean > thenUpdateBodyOn: html > self hasSession > ifTrue: [ > | scr | > scr := html jQuery ajax > html: [ :h | > aCallback value. > self renderUpdatedBodyContentFor: self session pjaxBody on: h > ]; > onSuccess: aJSFunction. > aBoolean notNil > ifTrue: [ scr return: aBoolean ]. > ^ html jQuery this updateUrl > , ((html jQuery class: 'active') removeClass: 'active') , scr ] > ifFalse: [ ^ nil ] > > > So its > > html anchor > pjaxCallback:[ self doSomethingYourClientsLove ] on: html > withSuccessScript: (JSStream on:'alert("I don't believe that worked")'); > with: 'Click me' > > > > > Paul DeBruicker wrote > > Oh man if only our past selves knew we really wanted Iliad apps what a > > world > > this would be.... > > > > > > > > In my apps I use > > > > $.fn.updateUrl = function(anId){ > > > > if (typeof(window.history.pushState) == 'function') { > > var relativeUrl = $(this).attr('href'); > > if(typeof(relativeUrl) =='undefined'){ > > relativeUrl = > > document.location.pathname+document.location.search; > > }; > > if(relativeUrl!=='javascript:void(0)' && relativeUrl !== > > window.history.state){ > > window.history.pushState(relativeUrl, document.title, > > relativeUrl); > > } > > } > > }; > > > > and call it as part of the onClick: script on anchors and buttons BEFORE > > loading content via ajax. > > > > So the onClick: is > > > > > > onClick: html jQuery this updateUrl, (self doContentLoadingMagicOn: html) > > > > > > Also it doesn't need to be a jQuery function but is because it was > > different > > when I initially made it. > > > > > > > > Not sure its what you want to do but it definitely sets the window > > location > > (url) to something that when you hit refresh gives you the same page you > > see > > before you hit refresh (with updated server content, if anything there has > > changed in the interim). > > > > > > > > > > > > > > Siemen Baader wrote > >> Hi, > >> > >> Not really answering your questions, but I think this is what Iliad is > >> for. There you have access to a restful URL on every (xhr) request and > >> every WAComponent is transparently updated via xhr, including when you > >> use > >> call-answer. > >> > >> Just FYI. :) > >> > >> Siemen > >> > >> Sent from my iPhone > >> > >>> On 12 Apr 2019, at 17.23, Johan Brichau < > > > >> johan@ > > > >> > wrote: > >>> > >>> Hi Esteban, > >>> > >>> I’m interested in this too. > >>> We have the same kind of application (I guess… using mostly Ajax > >>> updates, > >>> I mean) but I have just been postponing a retry to address the > >>> inconsistency with ajax, server state and the back button for years…. > >>> > >>> Within a callback, you can get at the #actionUrl on the renderer. > >>> Is that what you want? > >>> > >>> I’m trying to dive into what would be required here… trying to > >>> understand > >>> what you need: > >>> Ajax requests always update the same continuation state in Seaside (i.e. > >>> they do not create a new continuation)… so if you push that url to the > >>> history after each ajax update, the back button will essentially request > >>> the same but updated continuation from Seaside, meaning you should see > >>> the state as it is in on the server, and not how it was before you made > >>> the ajax request (which is what happens now). > >>> > >>> Does that correspond to what you are trying to fix? > >>> > >>> Johan > >>> > >>>> On 12 Apr 2019, at 15:17, Esteban Maringolo < > > > >> emaringolo@ > > > >> > wrote: > >>>> > >>>> I have a Seaside application that is almost 100% AJAX driven to > >>>> replace the visual components (no call/answer involved). > >>>> > >>>> I plan to to use history.pushState() and history.replaceState() > >>>> > >>>> My plan is to update the browser url after replacing some components, > >>>> but using the URL building of the existing #updateUrl: (including > >>>> _s/_k parameters and whatnot). > >>>> > >>>> Is it possible to obtain the URL of the session presenter within the > >>>> ajax response? > >>>> > >>>> Thanks in advance, > >>>> > >>>> Esteban A. Maringolo > >>>> _______________________________________________ > >>>> seaside mailing list > >>>> > > > >> seaside@.squeakfoundation > > > >>>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside > >>> > >>> _______________________________________________ > >>> seaside mailing list > >>> > > > >> seaside@.squeakfoundation > > > >>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside > >> _______________________________________________ > >> seaside mailing list > > > >> seaside@.squeakfoundation > > > >> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside > > > > > > > > > > > > -- > > Sent from: http://forum.world.st/Seaside-General-f86180.html > > _______________________________________________ > > seaside mailing list > > > seaside@.squeakfoundation > > > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside > > > > > > -- > Sent from: http://forum.world.st/Seaside-General-f86180.html > _______________________________________________ > seaside mailing list > [hidden email] > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
I fully believe there is a better/less hackish way to do this if its going to be a seaside feature. But what I have does to the partial page update/back button/shareable links stuff well enough for me for now. You're right I do generally use it for navigation toreplace the content of a div with the id 'body' but I also use it to - update the page title - load on page help for the current view - move the person along in the guided tour if they're taking one - update other indicators/notifications if they've changed. e.g. "You have a new message from ..." I think that the DOM editing code could easily be adapted to also replace an arbitrary collection of specific DOM components like you'd prefer without too much trouble. If you had an id for every DOM element you wanted to replace in the real DOM and a matching div with the content in the Seaside ajax response then you could itereate of the received divs putting their contents into the target ids in the real DOM. The duplicated ids would only exist in the response handling code. And you could update multiple spots on the page at once for a given round trip to the server. The setBodyJs code just searches the received div's putting them in the correct spots and then runs the scripts that were included in the response. Anyway that code is MyComponent>>#setBodyJs ^ (JSStream on: '$("#body").setBody(resp, status, xhr);') asFunction: #('resp' 'status' 'xhr') $.fn.setBody = function (response, txtStatus, jqXhr) { var content, body = $('#body'), newElement, target; newElement=document.createElement('div'); newElement.innerHTML = response; content = newElement.querySelector('#b'); if(content){ body.empty().append(content.innerHTML); } else { window.location.href = window.location.href.split("?")[0]; }; content = newElement.querySelector('#h'); if(content){ $('#helpBarContent').empty().append(content.innerHTML); }; content = newElement.querySelector('#t'); if(content){ $('#tour').empty().append(content.innerHTML); }; content = newElement.querySelector('#tp'); if(content){ $('#tourProgress').empty().append(content.innerHTML); }; $(response).filter('script').each(function () { $.globalEval(this.text || this.textContent || this.innerHTML || ''); }); document.title = newElement.querySelector('#ti').innerHTML; $viewport.scrollToTop(); }; So you can see that its just finding elements by id ('#b' '#h' '#t' '#tp' '#ti') in the Seaside response and replacing others in the DOM and could be generalized into a loop if you wanted to spend the time to do it (if you were making it part of an open source package others could use for example ;) ) . For keeping the URL in sync I do not use updateUrl: because it only (I think?) edits the response URL & instead I just edit the url for the anchor before the pjaxCallback: e.g. html anchor backEndUrl:'mypage'; pjaxCallback:[self showMyPage] on: html; with: 'click me to see my page'. and WAAnchorTag>>#backEndUrl: is backEndUrl: anExtraPath self useBaseUrl; extraPath: MyApp appName; extraPath: anExtraPath By editing the url for the anchor it can be copy and pasted among users both from the anchor on the page and the url bar in the browser once they've arrived on the page of interest. It is only dissected and used in #initialRequest: when people share links and when the back button is clicked as described below. I use cookies for sessions so there isn't a _s parameter in the urls that are created. To handle the back button I'm overriding the browser's native back button handling. There is some js where I add a header when the back button is clicked, and then look for that in my session class and handle it. The JS that adds the header is is window.onpopstate = function (event) { // console.log(event.state); if ($('body.back').length && event.state) { $.ajax({url: event.state, success: function(data, textStatus, jqXhr) {$('body').setBodyAfterBackButton(data, textStatus, jqXhr);}, beforeSend: function(xhr){xhr.setRequestHeader("X-Requested-With", "pjaxBB");}}); } }; and the setBodyAfterBackButton replaces the existing page with the Seaside ajax response. $.fn.setBodyAfterBackButton = function (data, status, jqXhr) { var newDoc = document.open("text/html", "replace"); newDoc.write(data); newDoc.close(); }; Then in the session I override #handleFiltered: like this MySession>>#handleFiltered: aRequestContext (self isBackButtonPjaxRequest: aRequestContext) ifTrue: [ self handleBackButtonRequest: aRequestContext ] ifFalse: [ super handleFiltered: aRequestContext ] MySession>>#isBackButtonPjaxRequest: aRequestContext ^ (aRequestContext request headers at: 'x-requested-with' ifAbsent: [ nil ]) = 'pjaxBB' MySession>>#handleBackButtonRequest: aRequestContext | bdy path | path := aRequestContext request uri path allButFirst. bdy := self bodyFromBackButtonPath: path. self body: bdy. aRequestContext request uri addField: '_n'. super handleFiltered: aRequestContext MySession>>#bodyFromBackButtonPath: path "App specific code to find which page of the app should be shown and what content should be in it just like in #initialRequest: " Thats it I think. It works. Could be clearer/cleaner/more general. I'd prefer it to be more automatic (evidenlty like Iliad I guess) but I'm not creating so many new things that setting the urls & adding the lookup code for the #bodyFromBackButtonPath:/#initialRequest: is a burden. And like you remember I really only use this for navigation among areas of the app. It doesn't remember if you had a modal open or a few accordions expanded and others collapsed or were editing a thing on one page and another thing on another page. And I don't know how to go back to prior server states with this. It will take you back ten screens in order but that screen will have the most recently edited data. Not be in the same state it was when you first looked at it. Unlike the counter demo I'm not sure it should in a multi user app where others might've seen it or been affected by the changes. Hope this helps Paul Esteban A. Maringolo wrote > Hi Paul, > > I've seen that code before ;-) and maybe setting the URL **before** is > the way to go. > > In your case you always replace the "body" component of your page, I > might need to adapt it in a way that could replace any DOM element. > > Regarding this: > "Not sure its what you want to do but it definitely sets the window > location > (url) to something that when you hit refresh gives you the same page you > see > before you hit refresh (with updated server content, if anything there has > changed in the interim)." > > I don't remember how you consumed that in #initialRequest and whether > you specified #updateUrl: (and kept it in sync on each > "pjaxCallback:..." call). > > Regards, > > Esteban A. Maringolo > > On Fri, Apr 12, 2019 at 1:47 PM Paul DeBruicker < > pdebruic@ > > wrote: >> >> Oh and I forgot that the onClick: is housed in another function that >> allows >> the ajax pushState anchors to work even if JS is disabled or there is no >> session and looks like this: >> >> >> WAAnchorTag>>#pjaxCallback: aBlockClosure on: html withSuccessScript: >> aScript >> self >> onClick: >> (self >> processCallback: aBlockClosure >> onSuccess: self setBodyJs , aScript >> return: false >> thenUpdateBodyOn: html); >> callback: aBlockClosure >> >> >> & >> >> processCallback: aCallback onSuccess: aJSFunction return: aBoolean >> thenUpdateBodyOn: html >> self hasSession >> ifTrue: [ >> | scr | >> scr := html jQuery ajax >> html: [ :h | >> aCallback value. >> self renderUpdatedBodyContentFor: self session pjaxBody on: >> h >> ]; >> onSuccess: aJSFunction. >> aBoolean notNil >> ifTrue: [ scr return: aBoolean ]. >> ^ html jQuery this updateUrl >> , ((html jQuery class: 'active') removeClass: 'active') , scr ] >> ifFalse: [ ^ nil ] >> >> >> So its >> >> html anchor >> pjaxCallback:[ self doSomethingYourClientsLove ] on: html >> withSuccessScript: (JSStream on:'alert("I don't believe that worked")'); >> with: 'Click me' >> >> >> >> >> Paul DeBruicker wrote >> > Oh man if only our past selves knew we really wanted Iliad apps what a >> > world >> > this would be.... >> > >> > >> > >> > In my apps I use >> > >> > $.fn.updateUrl = function(anId){ >> > >> > if (typeof(window.history.pushState) == 'function') { >> > var relativeUrl = $(this).attr('href'); >> > if(typeof(relativeUrl) =='undefined'){ >> > relativeUrl = >> > document.location.pathname+document.location.search; >> > }; >> > if(relativeUrl!=='javascript:void(0)' && relativeUrl !== >> > window.history.state){ >> > window.history.pushState(relativeUrl, document.title, >> > relativeUrl); >> > } >> > } >> > }; >> > >> > and call it as part of the onClick: script on anchors and buttons >> BEFORE >> > loading content via ajax. >> > >> > So the onClick: is >> > >> > >> > onClick: html jQuery this updateUrl, (self doContentLoadingMagicOn: >> html) >> > >> > >> > Also it doesn't need to be a jQuery function but is because it was >> > different >> > when I initially made it. >> > >> > >> > >> > Not sure its what you want to do but it definitely sets the window >> > location >> > (url) to something that when you hit refresh gives you the same page >> you >> > see >> > before you hit refresh (with updated server content, if anything there >> has >> > changed in the interim). >> > >> > >> > >> > >> > >> > >> > Siemen Baader wrote >> >> Hi, >> >> >> >> Not really answering your questions, but I think this is what Iliad is >> >> for. There you have access to a restful URL on every (xhr) request and >> >> every WAComponent is transparently updated via xhr, including when you >> >> use >> >> call-answer. >> >> >> >> Just FYI. :) >> >> >> >> Siemen >> >> >> >> Sent from my iPhone >> >> >> >>> On 12 Apr 2019, at 17.23, Johan Brichau < >> > >> >> johan@ >> > >> >> > wrote: >> >>> >> >>> Hi Esteban, >> >>> >> >>> I’m interested in this too. >> >>> We have the same kind of application (I guess… using mostly Ajax >> >>> updates, >> >>> I mean) but I have just been postponing a retry to address the >> >>> inconsistency with ajax, server state and the back button for years…. >> >>> >> >>> Within a callback, you can get at the #actionUrl on the renderer. >> >>> Is that what you want? >> >>> >> >>> I’m trying to dive into what would be required here… trying to >> >>> understand >> >>> what you need: >> >>> Ajax requests always update the same continuation state in Seaside >> (i.e. >> >>> they do not create a new continuation)… so if you push that url to >> the >> >>> history after each ajax update, the back button will essentially >> request >> >>> the same but updated continuation from Seaside, meaning you should >> see >> >>> the state as it is in on the server, and not how it was before you >> made >> >>> the ajax request (which is what happens now). >> >>> >> >>> Does that correspond to what you are trying to fix? >> >>> >> >>> Johan >> >>> >> >>>> On 12 Apr 2019, at 15:17, Esteban Maringolo < >> > >> >> emaringolo@ >> > >> >> > wrote: >> >>>> >> >>>> I have a Seaside application that is almost 100% AJAX driven to >> >>>> replace the visual components (no call/answer involved). >> >>>> >> >>>> I plan to to use history.pushState() and history.replaceState() >> >>>> >> >>>> My plan is to update the browser url after replacing some >> components, >> >>>> but using the URL building of the existing #updateUrl: (including >> >>>> _s/_k parameters and whatnot). >> >>>> >> >>>> Is it possible to obtain the URL of the session presenter within the >> >>>> ajax response? >> >>>> >> >>>> Thanks in advance, >> >>>> >> >>>> Esteban A. Maringolo >> >>>> _______________________________________________ >> >>>> seaside mailing list >> >>>> >> > >> >> seaside@.squeakfoundation >> > >> >>>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside >> >>> >> >>> _______________________________________________ >> >>> seaside mailing list >> >>> >> > >> >> seaside@.squeakfoundation >> > >> >>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside >> >> _______________________________________________ >> >> seaside mailing list >> > >> >> seaside@.squeakfoundation >> > >> >> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside >> > >> > >> > >> > >> > >> > -- >> > Sent from: http://forum.world.st/Seaside-General-f86180.html >> > _______________________________________________ >> > seaside mailing list >> >> > seaside@.squeakfoundation >> >> > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside >> >> >> >> >> >> -- >> Sent from: http://forum.world.st/Seaside-General-f86180.html >> _______________________________________________ >> seaside mailing list >> > seaside@.squeakfoundation >> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside > _______________________________________________ > seaside mailing list > seaside@.squeakfoundation > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside -- Sent from: http://forum.world.st/Seaside-General-f86180.html _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
This could be a better way for instance:
https://dockyard.com/blog/2018/12/12/phoenix-liveview-interactive-real-time-apps-no-need-to-write-javascript Paul DeBruicker wrote > I fully believe there is a better/less hackish way to do this if its going > to be a seaside feature. But what I have does to the partial page > update/back button/shareable links stuff well enough for me for now. > > You're right I do generally use it for navigation toreplace the content of > a > div with the id 'body' but I also use it to > > - update the page title > - load on page help for the current view > - move the person along in the guided tour if they're taking one > - update other indicators/notifications if they've changed. e.g. > "You > have a new message from ..." > > I think that the DOM editing code could easily be adapted to also replace > an > arbitrary collection of specific DOM components like you'd prefer without > too much trouble. If you had an id for every DOM element you wanted to > replace in the real DOM and a matching div with the content in the Seaside > ajax response then you could itereate of the received divs putting their > contents into the target ids in the real DOM. The duplicated ids would > only > exist in the response handling code. And you could update multiple spots > on > the page at once for a given round trip to the server. > > > The setBodyJs code just searches the received div's putting them in the > correct spots and then runs the scripts that were included in the > response. > Anyway that code is > > MyComponent>>#setBodyJs > ^ (JSStream on: '$("#body").setBody(resp, status, xhr);') asFunction: > #('resp' 'status' 'xhr') > > > $.fn.setBody = function (response, txtStatus, jqXhr) { > var content, body = $('#body'), newElement, target; > newElement=document.createElement('div'); > newElement.innerHTML = response; > > content = newElement.querySelector('#b'); > if(content){ > body.empty().append(content.innerHTML); > } else { > window.location.href = window.location.href.split("?")[0]; > }; > > content = newElement.querySelector('#h'); > if(content){ > $('#helpBarContent').empty().append(content.innerHTML); > }; > > content = newElement.querySelector('#t'); > if(content){ > $('#tour').empty().append(content.innerHTML); > }; > > content = newElement.querySelector('#tp'); > if(content){ > $('#tourProgress').empty().append(content.innerHTML); > }; > > $(response).filter('script').each(function () { > $.globalEval(this.text || this.textContent || this.innerHTML > || > ''); > }); > document.title = newElement.querySelector('#ti').innerHTML; > $viewport.scrollToTop(); > }; > > So you can see that its just finding elements by id ('#b' '#h' '#t' '#tp' > '#ti') in the Seaside response and replacing others in the DOM and could > be > generalized into a loop if you wanted to spend the time to do it (if you > were making it part of an open source package others could use for example > ;) ) . > > > For keeping the URL in sync I do not use updateUrl: because it only (I > think?) edits the response URL & instead I just edit the url for the > anchor > before the pjaxCallback: e.g. > > html anchor > backEndUrl:'mypage'; > pjaxCallback:[self showMyPage] on: html; > with: 'click me to see my page'. > > > and WAAnchorTag>>#backEndUrl: is > > backEndUrl: anExtraPath > self > useBaseUrl; > extraPath: MyApp appName; > extraPath: anExtraPath > > By editing the url for the anchor it can be copy and pasted among users > both > from the anchor on the page and the url bar in the browser once they've > arrived on the page of interest. It is only dissected and used in > #initialRequest: when people share links and when the back button is > clicked as described below. I use cookies for sessions so there isn't a > _s > parameter in the urls that are created. > > > To handle the back button I'm overriding the browser's native back button > handling. There is some js where I add a header when the back button is > clicked, and then look for that in my session class and handle it. > > The JS that adds the header is is > > window.onpopstate = function (event) { > // console.log(event.state); > if ($('body.back').length && event.state) { > $.ajax({url: event.state, > success: function(data, textStatus, jqXhr) > {$('body').setBodyAfterBackButton(data, textStatus, jqXhr);}, > beforeSend: > function(xhr){xhr.setRequestHeader("X-Requested-With", "pjaxBB");}}); > } > }; > > and the setBodyAfterBackButton replaces the existing page with the Seaside > ajax response. > > $.fn.setBodyAfterBackButton = function (data, status, jqXhr) { > var newDoc = document.open("text/html", "replace"); > newDoc.write(data); > newDoc.close(); > }; > > > Then in the session I override #handleFiltered: like this > > > MySession>>#handleFiltered: aRequestContext > (self isBackButtonPjaxRequest: aRequestContext) > ifTrue: [ self handleBackButtonRequest: aRequestContext ] > ifFalse: [ super handleFiltered: aRequestContext ] > > > MySession>>#isBackButtonPjaxRequest: aRequestContext > ^ (aRequestContext request headers at: 'x-requested-with' ifAbsent: [ nil > ]) = 'pjaxBB' > > > MySession>>#handleBackButtonRequest: aRequestContext > | bdy path | > path := aRequestContext request uri path allButFirst. > bdy := self bodyFromBackButtonPath: path. > self body: bdy. > aRequestContext request uri addField: '_n'. > super handleFiltered: aRequestContext > > > MySession>>#bodyFromBackButtonPath: path > "App specific code to find which page of the app should be shown and > what > content should be in it just like in #initialRequest: " > > > > > Thats it I think. It works. Could be clearer/cleaner/more general. I'd > prefer it to be more automatic (evidenlty like Iliad I guess) but I'm not > creating so many new things that setting the urls & adding the lookup code > for the #bodyFromBackButtonPath:/#initialRequest: is a burden. > > > And like you remember I really only use this for navigation among areas of > the app. It doesn't remember if you had a modal open or a few accordions > expanded and others collapsed or were editing a thing on one page and > another thing on another page. And I don't know how to go back to prior > server states with this. It will take you back ten screens in order but > that > screen will have the most recently edited data. Not be in the same state > it > was when you first looked at it. Unlike the counter demo I'm not sure it > should in a multi user app where others might've seen it or been affected > by > the changes. > > Hope this helps > > Paul > > > > > > Esteban A. Maringolo wrote >> Hi Paul, >> >> I've seen that code before ;-) and maybe setting the URL **before** is >> the way to go. >> >> In your case you always replace the "body" component of your page, I >> might need to adapt it in a way that could replace any DOM element. >> >> Regarding this: >> "Not sure its what you want to do but it definitely sets the window >> location >> (url) to something that when you hit refresh gives you the same page you >> see >> before you hit refresh (with updated server content, if anything there >> has >> changed in the interim)." >> >> I don't remember how you consumed that in #initialRequest and whether >> you specified #updateUrl: (and kept it in sync on each >> "pjaxCallback:..." call). >> >> Regards, >> >> Esteban A. Maringolo >> >> On Fri, Apr 12, 2019 at 1:47 PM Paul DeBruicker < > >> pdebruic@ > >> > wrote: >>> >>> Oh and I forgot that the onClick: is housed in another function that >>> allows >>> the ajax pushState anchors to work even if JS is disabled or there is no >>> session and looks like this: >>> >>> >>> WAAnchorTag>>#pjaxCallback: aBlockClosure on: html withSuccessScript: >>> aScript >>> self >>> onClick: >>> (self >>> processCallback: aBlockClosure >>> onSuccess: self setBodyJs , aScript >>> return: false >>> thenUpdateBodyOn: html); >>> callback: aBlockClosure >>> >>> >>> & >>> >>> processCallback: aCallback onSuccess: aJSFunction return: aBoolean >>> thenUpdateBodyOn: html >>> self hasSession >>> ifTrue: [ >>> | scr | >>> scr := html jQuery ajax >>> html: [ :h | >>> aCallback value. >>> self renderUpdatedBodyContentFor: self session pjaxBody >>> on: >>> h >>> ]; >>> onSuccess: aJSFunction. >>> aBoolean notNil >>> ifTrue: [ scr return: aBoolean ]. >>> ^ html jQuery this updateUrl >>> , ((html jQuery class: 'active') removeClass: 'active') , scr ] >>> ifFalse: [ ^ nil ] >>> >>> >>> So its >>> >>> html anchor >>> pjaxCallback:[ self doSomethingYourClientsLove ] on: html >>> withSuccessScript: (JSStream on:'alert("I don't believe that worked")'); >>> with: 'Click me' >>> >>> >>> >>> >>> Paul DeBruicker wrote >>> > Oh man if only our past selves knew we really wanted Iliad apps what a >>> > world >>> > this would be.... >>> > >>> > >>> > >>> > In my apps I use >>> > >>> > $.fn.updateUrl = function(anId){ >>> > >>> > if (typeof(window.history.pushState) == 'function') { >>> > var relativeUrl = $(this).attr('href'); >>> > if(typeof(relativeUrl) =='undefined'){ >>> > relativeUrl = >>> > document.location.pathname+document.location.search; >>> > }; >>> > if(relativeUrl!=='javascript:void(0)' && relativeUrl !== >>> > window.history.state){ >>> > window.history.pushState(relativeUrl, document.title, >>> > relativeUrl); >>> > } >>> > } >>> > }; >>> > >>> > and call it as part of the onClick: script on anchors and buttons >>> BEFORE >>> > loading content via ajax. >>> > >>> > So the onClick: is >>> > >>> > >>> > onClick: html jQuery this updateUrl, (self doContentLoadingMagicOn: >>> html) >>> > >>> > >>> > Also it doesn't need to be a jQuery function but is because it was >>> > different >>> > when I initially made it. >>> > >>> > >>> > >>> > Not sure its what you want to do but it definitely sets the window >>> > location >>> > (url) to something that when you hit refresh gives you the same page >>> you >>> > see >>> > before you hit refresh (with updated server content, if anything there >>> has >>> > changed in the interim). >>> > >>> > >>> > >>> > >>> > >>> > >>> > Siemen Baader wrote >>> >> Hi, >>> >> >>> >> Not really answering your questions, but I think this is what Iliad >>> is >>> >> for. There you have access to a restful URL on every (xhr) request >>> and >>> >> every WAComponent is transparently updated via xhr, including when >>> you >>> >> use >>> >> call-answer. >>> >> >>> >> Just FYI. :) >>> >> >>> >> Siemen >>> >> >>> >> Sent from my iPhone >>> >> >>> >>> On 12 Apr 2019, at 17.23, Johan Brichau < >>> > >>> >> johan@ >>> > >>> >> > wrote: >>> >>> >>> >>> Hi Esteban, >>> >>> >>> >>> I’m interested in this too. >>> >>> We have the same kind of application (I guess… using mostly Ajax >>> >>> updates, >>> >>> I mean) but I have just been postponing a retry to address the >>> >>> inconsistency with ajax, server state and the back button for >>> years…. >>> >>> >>> >>> Within a callback, you can get at the #actionUrl on the renderer. >>> >>> Is that what you want? >>> >>> >>> >>> I’m trying to dive into what would be required here… trying to >>> >>> understand >>> >>> what you need: >>> >>> Ajax requests always update the same continuation state in Seaside >>> (i.e. >>> >>> they do not create a new continuation)… so if you push that url to >>> the >>> >>> history after each ajax update, the back button will essentially >>> request >>> >>> the same but updated continuation from Seaside, meaning you should >>> see >>> >>> the state as it is in on the server, and not how it was before you >>> made >>> >>> the ajax request (which is what happens now). >>> >>> >>> >>> Does that correspond to what you are trying to fix? >>> >>> >>> >>> Johan >>> >>> >>> >>>> On 12 Apr 2019, at 15:17, Esteban Maringolo < >>> > >>> >> emaringolo@ >>> > >>> >> > wrote: >>> >>>> >>> >>>> I have a Seaside application that is almost 100% AJAX driven to >>> >>>> replace the visual components (no call/answer involved). >>> >>>> >>> >>>> I plan to to use history.pushState() and history.replaceState() >>> >>>> >>> >>>> My plan is to update the browser url after replacing some >>> components, >>> >>>> but using the URL building of the existing #updateUrl: (including >>> >>>> _s/_k parameters and whatnot). >>> >>>> >>> >>>> Is it possible to obtain the URL of the session presenter within >>> the >>> >>>> ajax response? >>> >>>> >>> >>>> Thanks in advance, >>> >>>> >>> >>>> Esteban A. Maringolo >>> >>>> _______________________________________________ >>> >>>> seaside mailing list >>> >>>> >>> > >>> >> seaside@.squeakfoundation >>> > >>> >>>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside >>> >>> >>> >>> _______________________________________________ >>> >>> seaside mailing list >>> >>> >>> > >>> >> seaside@.squeakfoundation >>> > >>> >>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside >>> >> _______________________________________________ >>> >> seaside mailing list >>> > >>> >> seaside@.squeakfoundation >>> > >>> >> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside >>> > >>> > >>> > >>> > >>> > >>> > -- >>> > Sent from: http://forum.world.st/Seaside-General-f86180.html >>> > _______________________________________________ >>> > seaside mailing list >>> >>> > seaside@.squeakfoundation >>> >>> > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside >>> >>> >>> >>> >>> >>> -- >>> Sent from: http://forum.world.st/Seaside-General-f86180.html >>> _______________________________________________ >>> seaside mailing list >>> > >> seaside@.squeakfoundation > >>> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside >> _______________________________________________ >> seaside mailing list > >> seaside@.squeakfoundation > >> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside > > > > > > -- > Sent from: http://forum.world.st/Seaside-General-f86180.html > _______________________________________________ > seaside mailing list > seaside@.squeakfoundation > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside -- Sent from: http://forum.world.st/Seaside-General-f86180.html _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Hello,
Is there something inside that allows me to trigger a smalltalk action as a validation before anything else. I do something like this: (html anchor) attributeAt: 'href' put: ’Somefile' ; class: 'pure-button pure-button-primary'; attributeAt: 'download' put: ’some download file'; callback: [self getInventoryFile]; with: [(html tag: 'i') class: 'fas fa-download'; style: 'font-size: 14px;'. html space. html space. html text: 'Download counter’] The callback is not executed now as the anchor directly responds to the download attribute. Thanks in advance. Maarten _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Maarten,
What do you mean with ‘validation’ ? What do you want to validate? The download attribute only tells the browser to download the url contents rather than open it in the browser [1] If you want to produce the contents of the file from within Seaside, you will need to control the response in the callback, rather than execute an ‘action’. The return value of an action callback is never what Seaside answers to the browser. This is what you seem to expect in your code snippet. You need something like: callback:[ self requestContext respond: [:response | self writeYourFileOnTheResponse: response ] ] You can also check it here: http://book.seaside.st/book/fundamentals/forms/fileupload Mind that #callback: sets (and overwrites) the href attribute on the anchor. That means the first statement that sets the href manually does not have any effect (and is, in fact, not correct). If you want to put a href manually, use #url: Hope this helps Johan
_______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
In reply to this post by Paul DeBruicker
Hi Paul, Yes, such alternative was presented in the "Combining Seaside with React" thread some weeks ago. However it seems to be a big leap from the basic updating of URL using traditional request/response XHR requests. The morphdom(), however, seems trivial to implement as an alternative to jQuery's replace(). Regards! ps: I haven't pursued the PJAX approach not because I chose something else, but because my backlog got filled with more important things :) Esteban A. Maringolo On Mon, Apr 29, 2019 at 2:58 PM Paul DeBruicker <[hidden email]> wrote: This could be a better way for instance: _______________________________________________ seaside mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside |
Free forum by Nabble | Edit this page |