Grails - splitting raw json into an object - json

I am trying to receive json from a url and then display it in a g:select on my page and everything seems to work fine except that each object is displayed as raw json (e.g. {id=1, regionCode=EC, regionName=EasternCape} instead of proper objects with 'id', 'name', etc. Here's the json I'm trying to split:
[{"regionCode":"EC","regionName":"Eastern Cape","id":1},
{"regionCode":"FS","regionName":"Free State","id":2},
{"regionCode":"GA","regionName":"Gauteng","id":3},
{"regionCode":"KZN","regionName":"Kwa-Zulu Natal","id":4},
{"regionCode":"LI","regionName":"Limpopo","id":5},
{"regionCode":"MP","regionName":"Mpumalanga","id":6},
{"regionCode":"NW","regionName":"North West","id":8},
{"regionCode":"NC","regionName":"Northern Cape","id":7},
{"regionCode":"WC","regionName":"Western Cape","id":9}]
Here's the service I'm using to receive the above json:
class GetRegionService {
def getRegion(){
try{
//I'm not using the actual URL in this example
def regionList = new JsonSlurper().parseText(new URL('http:url/regions/list/ZA/').text)
return regionList
}catch (all){
all.printStackTrace()
return false
}
}
}
Here's how my controller that puts the json on the gsp page:
class MainController {
def getRegionService
def index() {
def regions = getRegionService.getRegion()
[regions: regions]
}
}
And here's the html snippet where the select is displayed:
<div class="jumbotron">
<label for="setRegion" style="margin: 0 10px 0 50px">Region: </label>
<g:select name="setRegion" from="${regions}"/>
</div

I figured it out. The problem was in my html. The select is supposed to look like this:
<g:select name="setRegion" from="${regions}" optionValue="regionName" optionKey="regionCode"/>

Looking at this from three years later, I'd take another approach. I haven't tested this or anything, I'm just adding this here in case anyone else ever finds themselves in the same situation:
<html>
<head></head>
<body>
<!-- Stuff here -->
<select id="setRegion" name="setRegion"></select>
<!-- More stuff here -->
<script>
$(document).ready(function() {
$('#setRegion').html('').append(
$('<option/>').text('-- Select Region')
);
JSON.parse('${regions}').forEach(function(region, i) {
$('#setRegion').append(
$('<option/>').attr({ value:region.regionCode }).text(region.regionName)
);
});
});
</script>
</body>
</html>
And seeing as nobody else has tried to answer this question, I guess I'll have to give myself the "accepted answer" xD

Related

Dynamic pass value in a Play2 scala template

I try to dynamically change value of its variable. Once onclick (Change Ticket ID ) button then execute onClickSendEmail and variable value should be change of tickedId.
Its unable to update with newTickedId. I tried while create variable using #defining and individual calling by function also.
So, Basically I got stuck. how it will be solve.
#(sender: String)
<!--#{var tickedId = "tickedId"}-->
#defining(sender.contains("#")) {isEmail =>
#main((if(isEmail) "Email" else "Chat") + " Messages - " + sender) {
...
...
...
<div>
<a onclick="onClickSendEmail();return false;">
Change Ticket ID
</a>
</div>
#defining("getTicketId()") { tickedId =>
#views.html.common.form.panel("Reply",controllers.routes.ChatMessageController.sendEmail(tickedId,sender),"Send"){
<textarea id="emailArea" cols="100" rows="4" name="emailArea"></textarea>
}
<script type="text/javascript">
function onClickSendEmail() {
tickedId= "NewUpdatedTicketId";
}
function getTicketId() {
return "NewUpdatedTicketId";
}
</script>
}
}
}
You should not mix Twirl templating with Javascript. It's a bad approach.
The role for Twirl is to render HTML blocks. You can define conditions and variables here in order to dynamically change the HTML output. While with Javascript you can modify this rendered HTML output without reloading the page.
There are cases where you need to use a Twirl variable in Javascript, then you can do something like:
#(chartData: Html)
<script>
let jsData = #twirlData; // where twirlData is an existing variable
console.log(jsData)
</script>
Here's a link where you can read more.

Issue with ng-bind-html

I'm trying to create a website using angular-js .I'm using rest api calls for getting data. I'm using ngSanitize as the data from rest call includes html character. Even if i use ng-bind-html in my view the html tags are not removed .What is the mistake in my code.Can anyone help me
var app = angular.module('app',['ngSanitize','ui.bootstrap']);
app.controller("ctrl",['$scope','$http','$location','$uibModal',function($scope,$http,$location,$uibModal,){
//here im making my rest api call and saving the data in to $scope.items;
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-sanitize.js"></script>
<body ng-app="app" ng-controller="ctrl">
<div class="hov" ng-repeat ="item in items">
<br/>
<div>
<hr class="divider" style="overflow:auto;">
<ul>
<li style="font-family: Arial, Helvetica, sans-serif;font-weight:900px;">
<h3>Name<span style="color:#0899CC;" ng-model="id2" ng-bind-html="item.name"></span></h3>
</li>
<li>
<h4>Description: <span ng-bind-html="item.description"></span></h4>
</li>
</ul>
</div>
</div>
</body>
So you want to allow HTML tags or deny them ?
If you want the html to be escaped in the data coming from your server, just use ng-bind. It will replace < with < and > with > thus showing the HTML tags instead of computing them.
If you want to completely remove any HTML tags
Try this filter
filter('htmlToPlaintext', function() {
return function(text) {
return text ? String(text).replace(/<[^>]+>/gm, '') : '';
};
}
);
then in your HTML :
<h3>Name<span style="color:#0899CC;" ng-model="id2" ng-bind-html="item.name | htmlToPlaintext"></span></h3>
If you trust the source and want to compute the HTML it send you
You can use this filter
app.filter('trusted', function($sce){
return function(html){
return $sce.trustAsHtml(html)
}
});
then in your HTML :
<h3>Name<span style="color:#0899CC;" ng-model="id2" ng-bind-html="item.name | trusted"></span></h3>
And
<h4>Description: <span ng-bind-html="item.description | trusted"></span></h4>
I have the same problem before some time , then i created a filter for this problem, You can use this filter to do sanitize your html code:
app.filter("sanitize", ['$sce', function($sce) {
return function(htmlCode) {
return $sce.trustAsHtml(htmlCode);
}
}]);
in html you can use like this:
<div ng-bind-html="businesses.oldTimings | sanitize"></div>
businesses.oldTimings is $scope variable having description of strings or having strings with html tags , $scope.businesses.oldTimings is the part of particular controller that you are using for that html.
see in the snapshot:
you can use limitHtml filter to do the same:
app.filter('limitHtml', function() {
return function(text, limit) {
var changedString = String(text).replace(/<[^>]+>/gm, ' ');
var length = changedString.length;
return changedString.length > limit ? changedString.substr(0, limit - 1) : changedString;
}
});
Then you can add bothe filter in your html like that:
<p class="first-free-para" ng-bind-html="special.description| limitHtml : special.description.length | sanitize">
Hope it will work for you.

How to add a link <a> to the content inside of $scope.var of AngularJS

I have got my data from my controller like below.
controller:
$http.get('json/projects.json').success(function(data) {
$scope.projects = data;
});
my data in json file is something like this:
json:
{
...
projects = ['hello world', 'www.google.com', 'hello world.']
}
html:
<div ng-repeat='p in projects'> {{p}} </div>
My question is how to display 'www.google.com' as a link rather than a simple text?
You can use the liky filter from the ngSanitize module: https://docs.angularjs.org/api/ngSanitize/filter/linky
I am afraid you will have to change your 'www.google.com' to 'http://www.google.com'

AngularJS - Sharing Data between controllers from json

actually I get stucked since several days with following problem. I like to create a small app which loads data from a json file. The app should consist of 3 views !
Show a list of data
Edit view for changing current data
add view to store new data
Now I learned to use a service which provides data to each controller for each view.
But for the time my service works only with generated data within my variable thing.
How Can I change this that my service will provide data from .json file which may be edited and updated with any controller !
Thanks
Here is my code and plnker
<!doctype html>
<html ng-app="project">
<head>
<title>Angular: Service example</title>
<script src="http://code.angularjs.org/angular-1.0.1.js"></script>
<script>
var projectModule = angular.module('project',[]);
projectModule.factory('theService', function() {
return {
thing : [{"DATE" : "2014","IATA":"DUS","DUTY":"10:12"},
{"DATE" : "2015","IATA":"MIA","DUTY":"10:12"},
{"DATE" : "2017","IATA":"JFK","DUTY":"10:12"}]
};
/*
return {
thing:[function($http) {
return $http.get('data.json').then(function(response) {})
return response.data;
}]
};
*/
});
function FirstCtrl($scope, theService) {
$scope.thing = theService.thing;
$scope.name = "First Controller";
}
function SecondCtrl($scope, theService) {
$scope.someThing = theService.thing;
$scope.name = "Second Controller!";
}
</script>
</head>
<body>
<div ng-controller="FirstCtrl">
<h2>{{name}}</h2>
<div ng-repeat="show in thing">
<p>
<b>DATE </b>{{show.DATE}}
<b>IATA </b>{{show.IATA}}
<b>DUTY </b>{{show.DUTY}}
</p>
</div>
<div ng-controller="SecondCtrl">
<h2>{{name}}</h2>
<div ng-repeat="edit in someThing">
<p>
<input ng-model="edit.DATE"/>
<input ng-model="edit.IATA"/>
<input ng-model="edit.DUTY"/>
</p>
</div>
</div>
</body>
</html>
All you have to do is use $http service and return it:
getJson: function() {
return $http.get('data.json')
}
Then in your controller you use it like this:
service.getJson(function(data) {
$scope.thing = data;
})
To convert object to json you need to use angular.fromJson i angular.toJson
Angular Docs
After that you do:
$http.post('yourjson);
to replace your current json (save changes).
You should also redownload it (to have everything in sync) using $http.get as I described above.
I have found an example example. I hope it helps.

Why is Html.Raw escaping ampersand in anchor tag in ASP.NET MVC 4?

I have a URL I would like to render in an anchor tag as-is in a Razor view. I would have thought Html.Raw would be the way to go:
#{
string test = "http://someurl.com/someimage.png?a=1234&b=5678";
}
<div>
Test
</div>
But this doesn't work. The ampersand gets encoded and the HTML is rendered as:
<div>
Test
</div>
The strange thing is that if I do the Html.Raw call outside of the anchor tag, the HTML output is as expected:
<div>
#Html.Raw(test)
<div>
is rendered as:
<div>
http://someurl.com/someimage.png?a=1234&b=5678
</div>
Can anyone explain why this is?
Edit:
Tried a few other things out, and found that the following works as expected:
<div data-url="#Html.Raw(test)"></div>
outputs:
<div data-url="http://someurl.com/someimage.png?a=1234&b=5678"></div>
To add a little more context, my goal is not actually to use the URL in an anchor tag, since hrefs can be HTML encoded and still work (I just used the anchor tag case as an example). Rather I wish to use the URL in an <object> <param> value tag for a Flash object. The Flash object doesn't properly recognize the HTML encoded URL, but I can't get the raw URL to output correctly.
I am at a loss. Time to break out the MVC source code I guess...
This is happening because something in the pipeline (I'd guess razor but I'd need to look it up) attribute encodes all attribute values. This should not affect the browser from reaching your desired location however.
You can test this with the #Html.ActionLink(text, action, routeAttributes) overload.
#Html.ActionLink("Test", "Index", new { tony = "1", raul = 2 })
outputs
Test
In regards to your edit, you just need to make the entire <param> part of your raw value.
#{
var test = "<param src=\"http://someurl.com/someimage.png?a=1234&b=5678\">";
}
<div>
<object>
#Html.Raw(test)
</object>
</div>
Like this:
#{
string test = "http://someurl.com/someimage.png?a=1234&b=5678";
}
<div>
Test
</div>
produces valid markup:
<div>
Test
</div>
But this doesn't work. The ampersand gets encoded and the HTML is
rendered as:
But that's exactly how a valid markup should look like. The ampersand must be encoded when used as an attribute. Don't worry, the browser will perfectly fine understand this url.
Notice that the following is invalid markup, so you don't want this:
<div>
Test
</div>
Try
<div>
Test
</div>
just try below...
It works perfect.
#{
string test = "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token="+#ViewBag.Token;
}
<div>
#Html.Raw(System.Web.HttpUtility.HtmlDecode(test))
</div>
why don't you use jquery to post the url:
$(function () {
$('form').submit(function () {
$.ajax({
url: this.action,
type: this.method,
data: { a:'firstvalue', b: 'secondvalue'},
success: function (result) {
//code for successful result
}
});
return false;
});
});
in controller
public ActionResult Fetch(string a, string b)
{
//write required codes here
return View();
}