How can Grails send the edited object from a form within a template using AJAX?

I am looking to dynamically update a field in an edit form based on changes made to another field. The idea is that when field1 is modified, an AJAX script will call the controller to calculate a new value for field2 and then update the template accordingly. However, the controller requires two values: the value of field1 and the object being edited in order to render the template properly.

    <script>
        $(document).ready(function(){
            $( document ).on('change', '.availableCert', function ( event ){ 
                $.ajax({
                    url: '${g.createLink( controller:'offerDetail', action:'updatePrice' )}',
                    data: {availableCert:this.value, id:this.id},
                    type: 'get'
                }).success( function ( data ) { $( '#updatePrice' ).html( data );     });
            });
        });
    </script>

    <script>
        $(document).ready(function(){
            $( document ).on('change', '.adjustPrice', function ( event ){ 
                $.ajax({
                    url: '${g.createLink( controller:'offerDetail', action:'updatePrice' )}',
                    data: {adjustPrice:this.value, id:this.id},
                    type: 'get'
                }).success( function ( data ) { $( '#updatePrice' ).html( data );     });
            });
        });
    </script>

    <script>
        $(document).ready(function(){
            $( document ).on('change', '.volumeOffered', function ( event ){ 
                $.ajax({
                    url: '${g.createLink( controller:'offerDetail', action:'updatePrice' )}',
                    data: {volumeOffered:this.value, id:this.id},
                    type: 'get'
                }).success( function ( data ) { $( '#updatePrice' ).html( data );     });
            });
        });
    </script>

This snippet shows part of the template where the fields are displayed:

        <g:select class="availableCert" name="availableCert" from="${offerDetail.availableCert}" value="${offerDetail.choosedCert}" />    
</td>        
<td> FSC: ${offerDetail.priceFSC}</td>
<td> UC: ${offerDetail.priceUC}</td>
<td> CW: ${offerDetail.priceCW}</td>
<td> PEFC: ${offerDetail.pricePEFC}</td>
<td>  
    EndPrice:    ${offerDetail.endPrice}
</td>

Therefore, to render this field correctly, the controller needs access to the object ${offerDetail} so that the template can display it appropriately.

I'm not sure how the JavaScript code can retrieve this object, but I believe there might be a simpler solution than what I currently envision. Am I missing something?

Here is the relevant code from the controller:

def updatePrice() {
   def OfferDetail od
    if (params.id != null){
       od = OfferDetail.get(params.id)
   }
    if (params.availableCert != null) {
       od.choosedCert = params.availableCert
   } else if (params.adjustPrice != null) {
       od.priceAdjust = params.adjustPrice.toBigDecimal()
   } else if (params.volumeOffered != null) {
       od.volumeOffered = params.volumeOffered
   } else {}
   render template: "offerDData", model: [offerDetail:od]
}

Answer №1

To enhance your approach, consider implementing dropdown menus and creating a single javascript function to manage all dropdown changes. Here is an example:

<script>
    $(document).ready(function(){
        $( document ).on('change', '.odChange', function ( event ){ 
            $.ajax({
                url: '${g.createLink( controller:'offerDetail', action:'updatePrice' )}',
                data: {  updateVal :this.value, 
                         dropDownId: this.id,
                         offerDetailId: od.id
                      },
                type: 'get'
            }).success( function ( data ) { $( '#updatePrice' ).html( data );     });
        });
    });
</script>

<g:select class="odChange" name="availableCert" from="${offerDetail.availableCert}" value="${offerDetail.choosedCert}" />
<g:select class="odChange" name="adjustPrice" from="${offerDetail.adjustPrice}" value="${offerDetail.adjustPrice}" />
<g:select class="odChange" name="volumeOffered" from="${offerDetail.volumeOffered}" value="${offerDetail.volumeOffered}" />

Consider exploring alternative options for data binding

For now, you could experiment with the following:

def updatePrice() {
   def od = OfferDetail.get( params.offerDetailId )
   od."${params.dropDownId}" = params.updateVal
   od.save( flush: true, failOnError: true )
   render template: "offerDData", model: [offerDetail:od]
}

Make sure that the field names in your GSP file match those in your domain model when using the above method.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unchanging Arrays within JavaScript

Is there a way to maintain a set of unchanging values in JavaScript effortlessly? Furthermore, how can I ensure that comparisons between these constants yield accurate results? For example: const data = [5, 10, 15]; data[1] = 20; // Modifying an element ...

What steps can be taken to ensure that AngularJS does not detach a form input's value from its model if it is invalid?

While working on a form implementation in AngularJS, I encountered a baffling behavior that has left me puzzled. It seems that whenever I set ng-minlength=5 as an input attribute, AngularJS disconnects the value until it meets the length requirement. Thi ...

Adjust the width of a div based on its height dimension

I have a div called #slideshow that contains images with a 2:1 aspect ratio. To set the height of the image using jQuery, I use the following function: Keep in mind that the Slideshow Div is always 100% wide in relation to the browser window. If the use ...

Tips for indicating which content to display on template literals

Utilizing template literals to showcase some fetched data, I've successfully displayed all the necessary information on the frontend. However, certain content is hidden and meant to be toggleable. Yet, I'm struggling to figure out how to link eac ...

When the visitor is browsing a particular page and comes across a div element, carry out a specific action

I am trying to determine if I am currently on a specific page and, if so, check if a certain div exists in that page. Here is what I know: To check if a specific page exists, I can use the code if('http://'+location.hostname+location.pathname+& ...

Implementing Ajax for displaying panels in Apache Wicket framework

I am currently learning the Wicket framework and I encountered an issue while working with AJAX. I attempted to display a panel with the selected radio button's company name, but unfortunately, I'm experiencing an error. I have included all the r ...

What is the best way to export an object that is exclusively accessible within an asynchronous callback function?

In my project, I have a db.js file that handles establishing a connection to a MongoDB database. My goal is to export the database object from db.js to be used in my main app.js file: // Inside db.js require('mongodb').MongoClient.connect(/* the ...

Bcrypt installation continues to be problematic, despite trying multiple solutions

I have spent months troubleshooting, but I cannot seem to npm install bcrypt no matter what methods I try. Attempts include sudo npm install bcrypt, brew install bcrypt, reinstalling node, modifying JSON files, and even trying alternatives like bcryptjs. ...

NextJS was throwing a warning at me, while Firebase hosting was giving me an error regarding the absence of unique keys for children in lists, even though I

I've been troubleshooting this warning for quite some time, but I can't seem to resolve it. The warning reads as follows: Warning: Each child in a list should have a unique "key" prop. Check the top-level render call using <ul>. ...

Unable to access res.name due to subscription in Angular

Right now, I am following a tutorial on YouTube that covers authentication with Angular. However, I have hit a roadblock: The code provided in the tutorial is not working for me because of the use of subscribe(), which is resulting in the following messag ...

The Selenium Action class is failing to perform a second mouse hover on the same web element

Actions action = new Actions(Driver); action.MoveToElement(webelement).ClickAndHold().Perform(); The code snippet above is used to perform a mouse hover on a Web Element, and it works perfectly the first time. However, when attempting to do the mouse hove ...

The quantity addition and subtraction function is malfunctioning

I have implemented a quantity plus/minus feature in HTML which is embedded from a jQuery script provided below. jQuery.ajax({ type: "POST", url: "http://ayambrand-com-my-v1.cloudaccess.host/index.php?option=com_echa ...

Animate the sliding of divs using the JavaScript animation function

I've designed some boxes that function similar to notifications, but now I want to smoothly slide them in from the left instead of just fading in. I know that I need to use .animate rather than .fadeIn to achieve this effect. The code snippet I&apos ...

An error occurred while attempting to create-react-app, with the message "npm ERR! cb() never called!" popping up during the process

Encountering difficulties when attempting to create a React app PS D:\Projects\Test> npx create-react-app my-app Creating a new React app in D:\Projects\Test\my-app. Installing packages. This may take a few minutes. Installing ...

Using a navigation bar as a structural component in React

I have a new app in development that features a search bar on every page as part of the layout. When a user conducts a search, the results are displayed and they can click on a result to view more details in a separate component. My main question is regar ...

Removing a Node in VisJs in Real Time

function activateAddEdgeMode(nodeId){ network.addEdgeMode(); } /**looking to implement a method similar to network.addEdgeMode(); that will allow for node deletion. For instance: network.deleteNodeMode()*/ ...

Setting the navigation bar <li> elements to active in PLAY framework using Twitter Bootstrap

Hey, I currently have a navbar in my home.scala.html that looks like this: <ul class="nav nav-justified"> <li><a href="@routes.Application.apps()">@Messages("views.main.apps")</a></li> <li ><a href="#">@Messages( ...

Is there a way to enable scrolling on the page upon loading, without moving the embedded PDF object itself?

After embedding a PDF object on my webpage, I noticed that when loading the page and scrolling using the mouse wheel, it actually scrolls up and down inside the PDF instead of moving through the entire page. To fix this issue, I have to first click in a bl ...

Tips for parsing a JSON object efficiently

Javascript var obj = { "name" : ["alex","bob","ajhoge"], "age" : [30,31,33] }; To display the value "alex," you can use: document.write(obj["name"][0]) But how can we filter through 'obj' to retrieve all data like this? html <ul ...

Loop through the last modified file

I am currently working on a webpage that displays the "last-modified" date of each file it loads: Have you noticed how the dates are loaded one by one as the page makes calls to the header? If not, try hitting F5 to refresh the page. Is there a way to im ...