Smalltalk Seaside - jQuery Ajax Callback

So, I have a non-Ajax callback that works fine using this code (the "convert" method calculates the new value for the instance variable "result"):

html form: [ html text: 'Number to convert: '. html textInput callback: [ :value | self setNumtoconvert: value ]; value: numtoconvert. html break. html text: 'Result: '. html text: result. html break. html submitButton value: 'Convert'; callback: [ self convert ] ]. 

... and now I'm trying to use Ajax-ify using jQuery. I tried something in this direction:

 (html button) onClick: ((html jQuery ajax) callback: [ self convert]); id: 'calclink'; with: 'Convert'. 

... which does not work, since I obviously missed some secret sauce. Can a Seaside expert call back and give me a quick tutorial on converting β€œregular” callback code to jQuery Ajax callback code?

UPDATE I am very close to understanding this; After cleaning the Web and reviewing the draft chapters in the Seaside book, I changed my Ajax-ified button to this:

 (html button) onClick: ((html jQuery ajax) callback:[:val | self setNumtoconvert: val. self convert. Transcript show: self getResult.] value:(html jQuery: '#txtNumToConvert') value; onComplete: ((html jQuery: '#txtResult') value: self getResult) ); id: 'calclink'; with: 'Convert'. 

Now the only question is how to set the value of the text field '#txtResult'; Transcript show: self getResult displays the correct value, but I cannot get the string "onComplete" to update the value of "#txtResult". I can use onComplete: ((html jQuery: '#txtResult') value: 'hello there') to insert a string constant into a text field, but self getResult does not provide a value for the text field, although, again, I get the correct value when displaying self getResult in the transcript window.

UPDATE TWO My line "onComplete" works, but only after clicking the button (to calculate the value), refresh the page, and then click the button again (to display the calculated value in the "txtResult" text box. How to fix it?

MY ANSWER

I finally came up with a solution that is easier to understand (for me) and less detailed that I really like:

 renderContentOn: html html form:[ html textInput id: #txtNumToConvert; callback: [ :value | self setNumtoconvert: value ]; value: numtoconvert. html break. html span id: #result; with: result. html break. html anchor url: 'javascript:void(0)'; onClick: ((html jQuery id: #result) load serializeForm; html: [self convert. html span with: result]); with: 'Convert to Decimal'. ] 
+6
source share
2 answers

First, you need to activate callbacks for the fields inside the form. The following code attaches a click event handler to a button that executes an ajax request that will serialize the entire form and then call the button back.

 (html button) onClick: ((html jQuery ajax) serializeForm; callback: [ self convert ]); id: 'calclink'; with: 'Convert'. 

When you use the regular form submission, Seaside will call callbacks for all fields within the form for you. When you want to initiate form submission as an ajax request, the Seaside-jQuery #serializeForm method will also serialize the contents of all input fields inside the form and call their server side callbacks in the ajax request, as in the standard presentation form. No need to change the implementation of the form!

Then you will need to disable the default behavior of the browser by clicking the submit button, which submits the form in the POST request and forces the browser to make a full-page request, which will cause Seaside to (re) display the page. There are several ways to do this, but simply changing the button type is an easy way:

 (html button) bePush; ... 

Finally, you need to refresh the contents of the page. Your use of #onComplete: is correct, except that this javascript code is generated the first time the page is displayed. Therefore, it displays the value of self getResult at the time the page is displayed. What you want is the value after the form submission is complete. This requires another callback:

 (html button) bePush; onClick: ((html jQuery ajax) serializeForm; callback: [ self convert ]; onComplete: ((html jQuery: '#txtResult') load html: [:r | self renderTextResultContentsOn: r])); id: 'calclink'; with: 'Convert'. 

UPDATE The above code makes two server calls, which you can optimize by combining callbacks into a single ajax request:

 (html button) bePush; onClick: ((html jQuery ajax) serializeForm; script: [:s | self convert. s << ((s jQuery: '#txtResult') html: [:r | self renderTextResultContentsOn: r])]); id: 'calclink'; with: 'Convert'. 

Or, more elegantly:

  (html button) bePush; onClick: ((html jQuery id: #count) load serializeForm; html: [:r | self convert. self renderTextResultContentsOn: r]); with: 'Convert'. 

The above code generates an ajax request that serializes the form (performs callbacks on the server side) and generates a script to modify the result on the page. The reason I put self convert in the script callback is Seaside-gotcha: you can only specify one response for each ajax request (for example, only one script, html, json callback per request). This is a logical limitation since a single request can only generate one response. However, you can add a few β€œsecondary” callbacks (for example, serialization form callback:json: , callback:json: etc.), but the callback specified with #callback: is also the main callback in the marine code. Therefore, I needed to put self convert in the script callback, and not in my own callback block.

+4
source

"Nothing happens," because everything you do sends an AJAX request to the image. However, it seems to you that you need to start updating the DOM node. This requires an AJAX request with an additional handler that updates the DOM element with the result of some rendering.

What you are missing on the image side is basically:

  • What is the identifier of the item you want to update?
  • What visual code should be executed to generate HTML for replacement?

I do not use jQuery, but look at the jQuery code on the coast. I think your fragment should look something like this:

 (html button) onClick: (html jQuery ajax "pass the id of the element to update" id: 'calclink'; callback: [ self convert]; "specify the method to call for rendering" html: [ :canvas | self basicRenderMyDivOn: canvas ]; yourself); id: 'calclink'; with: 'Convert'. 
+2
source

Source: https://habr.com/ru/post/985545/


All Articles