how to use grails ${createLink} in javascript - javascript

i have a javascript function as follows
function GetSelectedItem()
{
var e = document.getElementById("country");
var strSel = e.options[e.selectedIndex].value;
alert(strSel);
var url = "${createLink(controller:'country', action: 'wholeTestUnits', id: strSel)}"
alert(url);
}
i want to go to that url action when i click the submit button like
<button class="submit_small" onClick="GetSelectedItem();">
<span><g:message code="default.button.submit.label" /></span>
</button>
This ${createLink} is not working.

A better way of doing this which doesn't require the JavaScript code be in your GSP would be the following:
<button class="submit_small" onClick="GetSelectedItem();" data-url="${createLink(controller:'country', action: 'wholeTestUnits')}">
<span><g:message code="default.button.submit.label" /></span>
</button>
function GetSelectedItem() {
var button = event.target;
var e = document.getElementById("country");
var strSel = e.options[e.selectedIndex].value;
var url = button.getAttribute("data-url") + "/" + strSel;
}

I think you have a serverside/clientside problem. The createLink is run on the server, the JS is run on the client...
Try:
var url = '${createLink(controller:'country', action: 'wholeTestUnits')}' + strSel ;

As I think , you are not getting value of strSel in your link.
You can try this.
function GetSelectedItem()
{
var e = document.getElementById("country");
var strSel = e.options[e.selectedIndex].value;
alert(strSel);
var url = "${grailsApplication.config.grails.serverURL}/country/wholeTestUnits/" + strSel
alert(url);
}

Instead of using the createLink you could build your own URL and use that one instead. You have to pay attention to capital letters in the controller name, though.
var url="${ createLink(controller:'testcontroller', action:'getData') }";
is equivalent to
var url = "/testcontroller/getData;
If you want to pass in arguments from javascript to the controller you can do like this.
var url = "/testcontroller/getData?arg0=" + arg0 + "&arg1=" + arg1;
To extract the arguments in the controller you do use the params keyword.
So to print the parameters in the controller you do this:
println params.arg0
println params.arg1

--in gsp file--
<a href="#" onclick="callAjax('${createLink(controller:'shift',action: 'addShift')}');" >Add/Edit Shift</a>
--in js file--
function callAjax(path){
//path->/shift/addShift
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("updateContent").innerHTML = this.responseText;
}
};
xmlhttp.open("GET", path, true);
xmlhttp.send();
}

try this:
var url = "${createLink(controller:'country', action: 'wholeTestUnits', params:[id: strSel], absolute: true)}"

Related

JavaScript Handlebars give no error but does not work

I am trying to replace text in my page using handlebars. But its not working and i am not getting any errors either.
The following code kicks in when the user presses the submit button
<button type="submit" id="add_lunch" class="button button-contactForm boxed-btn" onclick="addToCart()">Submit</button>
this then
function addtoCart() {
var request = new XMLHttpRequest();
var base_id = $("input[name='base_id']:checked").val();
var protein_id = $("input[name='protein_id']:checked").val();
var dessert_id = $("input[name='dessert_id']:checked").val();
var side_id = $("input[name='dessert_id']:checked").val();
request.open('POST', '/cart');
request.onload = () => {
// Extract JSON data from request
var template = Handlebars.compile(document.querySelector('#js_result').innerHTML);
var data_response = JSON.parse(request.responseText);
var content = template({'base_name': data_response.base.name});
console.log("****" + data_response.base.name)
document.addEventListener('DOMContentLoaded', () => {
document.querySelector('#add_lunch').onclick = () => {
document.querySelector('#media_js_body').innerHTML += content;
};
});
}
var data = new FormData();
data.append('base_id', base_id);
data.append('protein_id', protein_id);
data.append('side_id', side_id);
data.append('dessert_id', dessert_id);
// Send request
request.send(data);
return false;
}
plus the template
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.11/handlebars.min.js"></script>
<script id="js_result" type="text/x-handlebars-template">
{{ base_name }}
</script>
<script src="{{ url_for('static', filename='js/util.js') }}"></script>
What i have figured out so far is that it has something to do with DOM state? and onclick even.
Any suggestions and corrections?
i do not know if it was the coffee i drank, but after a few sips and few changes it seems to work partially now. i am getting the text being placed in the right place.
Now i only have to make sure that the values from data_response gets transferred in content as well
This is what i changed.
function addToCart() {
var request = new XMLHttpRequest();
var limit=2;
var base_id = $("input[name='base_id']:checked").val();
var protein_id = $("input[name='protein_id']:checked").val();
var dessert_id = $("input[name='dessert_id']:checked").val();
var side_id = [];
$.each($("input[name='side_id']:checked"), function(){
side_id.push($(this).val());
});
if(side_id.length==limit) {
request.open('POST', '/cart');
request.onload = () => {
// Extract JSON data from request
var data_response = JSON.parse(request.responseText);
var templateInfo=document.querySelector('#js_result').innerHTML
console.log("TempInfo:" + templateInfo)
var template = Handlebars.compile(templateInfo);
var content = template({'base_name': data_response.base.name});
console.log("DataResponse:" + data_response.base.name);
console.log("Content:" + data_response.base.name);
document.querySelector('#media_js_body').innerHTML += content;
}
var data = new FormData();
data.append('base_id', base_id);
data.append('protein_id', protein_id);
data.append('side_id', side_id);
data.append('dessert_id', dessert_id);
// Send request
request.send(data);
} else {
alert("Kindly select "+limit+" sides")
}
return false;
}

How to bind parameter to URL

This is my jsp code. I want to bind the catid parameter to url when I call getproductsub() and send ajax request.
r.open("GET", "url?catid=" + catid,true);
above line seems an error of my code.How can I fix it.
<select class="form-control" id="pcategory" name="pcategory" onchange="getproductsub();">
<script>
function getproductsub() {
var catid = document.getElementById('pcategory').value;
var url = window.location.href;
var r = new XMLHttpRequest();
r.onreadystatechange = function() {
if (r.readyState === 4 && r.status === 200) {}
};
r.open("GET", "url?catid=" + catid, true);
r.send();
}
</script>
Note that window.location.href gives the complete location including the parameters in the url at the current time. So ? might be included in it.
You can either use
var url = window.document.location.pathname;
And concat the url to the String passed to open().
r.open("GET", url + "?catid=" + catid, true);
OR
Use getRequestURL() as you are coding in jsp.
r.open("GET", "<%= request.getRequestURL()%>?catid=" + catid, true);

Changing url using javascript and jquery

Hello there
I am developing a jQuery plugin that loads files through ajax. When user clicks on a button which is:
<button class='btn btn-info' data-load="ajax" data-file="ajax/login.html" >Login</button>
When user clicks on button it generates following url:
http://localhost//plugins/ajaxLoad/index.html#ajax/Login
I want to change it to
http://localhost//plugins/ajaxLoad/index.html/ajax/Login
My javascript is:
(function ($) {
$.fn.ajaxLoad = function (options) {
var settings = $.extend({
fileUrl : 'null',
loadOn : '.em'
}, options);
$('[data-load="ajax"]').each(function(index, el) {
$(this).click(function () {
var file = $(this).attr('data-file');
var loadOn = $(this).attr('data-load-on');
var permission = $(this).attr("data-ask-permission");
settings.fileUrl = file;
settings.loadOn = loadOn;
if (permission == 'yes') {
var ask = confirm("Do you want to load file");
if (ask == true) {
$.fn.loadFile();
}
}else {
$.fn.loadFile();
}
});
});
$.fn.loadFile = function () {
// setting location;
var a = settings.fileUrl.split(".");
location.hash = a[0];
$.post(settings.fileUrl, function(response) {
$(settings.loadOn).html(response);
});
}
}
}(jQuery))
Can anyone tell me how to change url in jquery and Javascript.
You need to use history.pushstate() to do this.
var stateObj = { foo: "bar" };
history.pushState(stateObj, "page 2", "bar.html");
Have a look at this article on MDN for more details
https://developer.mozilla.org/en-US/docs/Web/API/History_API#The_pushState()_method
This article gives some nice jQuery examples.
https://rosspenman.com/pushstate-jquery
Added another attribute title to button
<button data-title="login" class='btn btn-info' data-load="ajax" data-file="ajax/login.html" >Login</button>
In Js (after $(this).click line):
var title = $(this).attr('data-title');
settings.title = title
Just replace
location.hash = a[0];
With
history.pushState('','',"?"+settings.title);
Change
location.hash = a[0];
to:
location.pathname += '/' + a[0];
Just replace the hash with a blank using .replace()
Example .
settings.fileUrl.replace('.' , ' ');
Updated above also
UPDATE :
Don't hash the URL
Example :
$.fn.loadFile = function () {
// setting location;
var a = settings.fileUrl.replace("." , "/");
location.href = a;
$.post(settings.fileUrl, function(response) {
$(settings.loadOn).html(response);
});
}
}

Load a JavaScript event the last in CRM form

I have one image saved in Notes with every form in my CRM Online 2013 custom entity. I am using the following code to query the image and show it in an Image tag in a Web Resource on the form. For debugging purposes I was calling the following code through a button, but I want this process of querying the Notes and displaying the image in the web resource to be automatic when the form load. Here is my code:
<html><head><meta charset="utf-8"></head>
<body>
<img id="image" src="nothing.jpg" style="width: 25%; height: auto;" />
<script type="text/javascript">
$(windows).load(function()
{
var recordId = window.parent.Xrm.Page.data.entity.getId();
var serverUrl = Xrm.Page.context.getServerUrl().toString();
var ODATA_ENDPOINT = "XRMServices/2011/OrganizationData.svc";
var objAnnotation = new Object();
ODataPath= serverUrl+ODATA_ENDPOINT;
var temp= "/AnnotationSet?$select=DocumentBody,FileName,MimeType,ObjectId&$filter=ObjectId/Id eq guid'" + recordId + "'";
var result =serverUrl + ODATA_ENDPOINT + temp;
var retrieveRecordsReq = new XMLHttpRequest();
retrieveRecordsReq.open('GET', ODataPath + temp, false);
retrieveRecordsReq.setRequestHeader("Accept", "application/json");
retrieveRecordsReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
retrieveRecordsReq.onreadystatechange = function ()
{
if (this.readyState == 4 /* complete */)
{
if (this.status == 200)
{
this.onreadystatechange = null; //avoids memory leaks
var data = JSON.parse(this.responseText, SDK.REST._dateReviver);
if (data && data.d && data.d.results)
{
SuccessFunc(JSON.parse(this.responseText, SDK.REST._dateReviver).d.results);
}
}
else
{
alert(SDK.REST._errorHandler(this));
}
}
};
var x = new XMLHttpRequest();
x.open("GET", result, true);
x.onreadystatechange = function ()
{
if (x.readyState == 4 && x.status == 200)
{
var doc = x.responseXML;
var title = doc.getElementsByTagName("feed")[0].getElementsByTagName("entry")[0].getElementsByTagName("content")[0].getElementsByTagName("m:properties")[0].getElementsByTagName("d:DocumentBody")[0].textContent;
document.getElementById('image').src ="data:image/png;base64,"+title;
}
};
x.send(null);
});
</script>
</body></html>
I have removed the button tag..now I want this the query to happen on page Load, but nothing happens when I refresh the form. In my opinion the function loads before the annotation loads. Is there a way to make it wait and load the last?
If you want to wait for the parent window to load I think $(windows).load(myFunction); should do the trick.
Maybe $ is undefined because you did not add jQuery to your webressource.
There are also a few little mistakes and unattractive things:
First:
You will get a wrong server url.
If you want to access the Xrm-object in a webresource you always have to use window.parent.Xrm or you put it in a variable var Xrm = window.parent.Xrm;
For example:
var Xrm = window.parent.Xrm;
var recordId = Xrm.Page.data.entity.getId();
var serverUrl = Xrm.Page.context.getServerUrl().toString();
Second:
The ODataPath variable is not declared. Use var ODataPath= serverUrl+ODATA_ENDPOINT; instead. By the way the value of the ODataPath has nothing to do with OData. It is more the REST-Endpoint of Dynamics CRM.
My script would look like this:
var Xrm, recordId, serverUrl, restEndpointUrl, odataQuery, fullRequestUrl, xmlRequest;
Xrm = window.parent.Xrm;
recordId = Xrm.Page.data.entity.getId();
serverUrl = Xrm.Page.context.getServerUrl().toString();
restEndpointUrl = serverUrl + "/XRMServices/2011/OrganizationData.svc";
^ I think a '/' was missing there
odataQuery = "/AnnotationSet?$select=DocumentBody,FileName,MimeType,ObjectId&$filter=ObjectId/Id eq guid'" + recordId + "'";
fullRequestUrl = restEndpointUrl + odataQuery;
I also dont understand why you use the second HttpRequest.
All of this code is not tested.

Use jQuery to insert a script which includes a function?

I am trying to append a line of JavaScript to a div dynamically, but it seems that when I run the .append() call, the browser sees a function() call within that line as an actual function instead of an actual string:
var startDate = 0
...
function insertCalendar(){
var divName = "div[name=StartDate" + startDateNum + "]";
$(divName).append("<script>Calendar.setup({ trigger : 'StartDate" + startDateNum + "', inputField : 'StartDate" + startDateNum + "', onSelect : function() { this.hide() } });</script>");
startDateNum++;
}
At the call to .append() the JavaScript console returns "Uncaught SyntaxError: Unexpected end of input," and it seems to mess with the function insertCalendar. I'm fairly certain I'm not missing a quote...
Let me know if this is too vague as this is my first question here. Thanks!
You can create a script tag, and then add the javascript.
var jstag=document.createElement('script');
jstag.setAttribute("type","text/javascript");
jstag.appendChild(document.createTextNode(" Javascript code goes here "));
document.appendChild(jstag);
Got the answer thanks to Anzz, mixed it with some AJAX:
var startDateNum = 0;
...
function setNewCal(){
var url = "getCal.php?startDate=" + startDateNum;
xmlHttp.open("GET", url, true);
xmlHttp.onreadystatechange = addCalendar;
xmlHttp.send(null);
}
function addCalendar(){
var divName = "StartDate" + startDateNum + "Div";
var response = xmlHttp.responseText;
if (xmlHttp.readyState == 4){
var calscript = document.createElement("script");
calscript.setAttribute("type", "text/javascript");
calscript.appendChild(document.createTextNode(response));
document.getElementById(divName).appendChild(calscript);
startDateNum++;
}
}

Categories