0

I am saving all my data in map and now having trouble accessing them from a separate JS file.

On my (index) page I have 2 tables. The LHS table displays the list of available Instructions, and the RHS will display all the detail information of selected Instructions.

enter image description here

In other words, when the user clicks on the ID#1 on the LHS table, the RHS table will display all the Instructions info for ONLY that ID number.

I've added a onclick function to the ID in my LHS table. Code in index.gsp:

<tbody>
        <g:each in="${deliveryInstructions}">                           
            <tr>
                <td id="instruction_ID">
                    <a href="#" onclick="display_DI_details(${it.id})">${it.id}</a>
                </td>
                <td>${it.deliveryName}</td>
                <td>${it.bankName}</td>
                ...
                ...
                ...
            </tr>
        </g:each>
</tbody>

And in my JS file i have (got the JSON idea from here):

function display_DI_details(id) {
    var deliveryID = id; 
    var deliveryInstructions = ${deliveryInstructions.encodeAsJson()};

    document.getElementById('diName').innerHTML = ${deliveryInstructions.deliveryName}
    document.getElementById('diID').innerHTML = ${deliveryInstructions.id}
    document.getElementById('fundingAccount').innerHTML = ${deliveryInstructions.fundingAccountNumber}
    ...
    ...
    ...
    document.getElementById('beneficiary').innerHTML = ${deliveryInstructions.beneficiary}
    document.getElementById('comments').innerHTML = ${deliveryInstructions.comments}
}

document.getElementById("display-di-list").innerHTML = display_DI_details(id);

Again in index.gsp this is what I have for the RHS table...

<div id="display-di-list">
    <!-- <g:each in="${deliveryInstructions}"> -->
        <label>Delivery Name: <p class="receiptData" id="diName"></p></label>
        <label>Delivery ID: <p class="receiptData" id="diID"></p></label>
        <label>Funding Account: <p class="receiptData" id="fundingAccount"></p></label>
        ...
        ...
        ...
        <label>Beneficiary: <p class="receiptData" id="beneficiary"></p></label>
        <label>Comments: <p class="receiptData" id="comments"></p></label>
    <!-- </g:each> -->
</div>

Finally in the controller file:

def index() {
    [deliveryInstructions: DeliveryInstruction.list()]
}

Now I am having trouble to connect few dots to finish this. In my JS file, how do I make it only grab the param values of the passed ID (lets say in this case the ID number is 1)? Thanks a lot for your help & time!!

1 Answer 1

1

Grails object into Javascript variable:

var deliveryInstructions = ${deliveryInstructions.encodeAsJson()};

Produces invalid json for me, I believe the difference (if your way is working) has to do with the grails version used. I had luck surround the encodeAsJson with a tag instructing grails to not escape the quotation marks:

<g:applyCodec encodeAs="none">
    var deliveryInstructions = ${deliveryInstructions.encodeAsJson()};
</g:applyCodec>

Disregard this if your way is already working, you can verify by looking at the produced html.


Within your function, if you have the id and the array of objects, deliveryInstructions, you can just use a javascript function to get the matching element within the array

var matchingDeliveryInstruction = deliveryInstructions.find(function(element){
    return element.id == id;
});

Now, just use the matchingDeliveryInstruction to set the right hand side's html:

document.getElementById('diName').innerHTML = matchingDeliveryInstruction.deliveryName;
document.getElementById('diID').innerHTML = matchingDeliveryInstruction.id;
...
etc.

I'm a big fan of using .js libraries for things like this, but depending on how much larger your project is it might be overkill.


Additional: After looking at your question again, you mention a separate .js file. The ${...} will only work within your gsp. You can leave your external .js file (a good practice) but you will need to have this within your gsp:

<script>
    var deliveryInstructions = ${deliveryInstructions.encodeAsJson()};
</script>

Based on what is generated, you may need to still wrap this with <g:applyCodec encodeAs="none">. Now, this will create a global deliveryInstructions variable that will be accessible within your external file.

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for the replay. I am using Grails 3.0.9 & Groovy 2.4.5. I am DEFINITELY doing something wrong, 'coz no matter what i'm trying, the var deliveryInstructions in JS file if not generating anything...therefore all the elements in the RHS table are empty. not sure what to do :<
What is the html look like where you have var deliveryInstructions declared?
it's blank, nothing is in it. I tried to assign the as var deliveryInstructions = ${deliveryInstructions};, var deliveryInstructions = ${deliveryInstructions as JSON}, var deliveryInstructions = ${deliveryInstructions.encodeAsJson()} and even ur way, but nothing prints out. the only error i get is Unexpected token { If i remove the { then it complains the id is not defined in document.getElementById("display-di-list").innerHTML = display_DI_details(id);
I updated my answer to include what I think is happening.
Thank you so much for the update, but unfortunately i can not make the variable global :( I think i'm going to do the try something different...handle all these from the controller somehow. But thank you SO much for everything :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.