I am showing an array which contains JSON and am directly showing this with HTML, here you can find elem.fc + elem.cpc. It's giving NaN as an output.
Here is my HTML:
<tr ng-show="table.table1loaded" ng-repeat="elem in filteredcampaignslist" ng-init="initializepopover()">
<td ng-show="app.ostype=='iOS'"><div class="text-center">{{elem.fc+elem.cpc}}</div></td>
</tr>
Please check this: How to parseInt in Angular.js
According to the Angular docs within that post, you cannot, as of the moment, perform such operations within expressions.
The best way to go around this is to create a function that does so within a controller and then bind it to your HTML.
HTML:
<tr ng-show="table.table1loaded" ng-repeat="elem in filteredcampaignslist" ng-init="initializepopover()">
<td ng-show="app.ostype=='iOS'"><div class="text-center">{{ Total() }}</div></td>
</tr>
Inside AngularJS Controller:
$scope.Total = function() { return parseInt(elem.fc) + parseInt(elem.cpc); };
Change {{elem.fc+elem.cpc}} to {{+elem.fc + +elem.cpc}}
That should do the trick.
This is the answer for versions 2 and above of angular:
Number('1234') // 1234
Number('9BX9') // NaN
Related
There is no better way to frame the question but:
I have a button in my Application:
<div #displayDiv></div>
<button (click)="genTable()"></button>
The function call in the component is as follows:
#ViewChild('displayDiv') div: ElementRef;
.
.
genTable(): void {
this.div.nativeElement.innerHTML = ''; // clear the contents of the div
// Make some API call and get data in JSON format and store it
// in a private variable of the class called tableResult
// change content of div using innerHTML
this.div.nativeElement.innerHTML = `
<table>
<tr *ngFor="let eachProp of tableResult">
<th>{{eachProp}}</th>
</tr>
</table>
`;
}
The above code just shows {{eachProp}} as a string and not its content plus it is shown only once.
How do I make the *ngFor and the Angular templates viz. {{eachProp}} dynamically available when writing code within the innerHTML of the div?
Further Info
I already am rendering some Diagram in the displayDiv and once when the user clicks the button, the diagram is cleared off and a table is displayed based on the JSON response from a server.
JSON Response:
{"input":{"concept":"HighChair",
"parameters":["hasHeight","hasWidth"],
"filters":[{"min":3.0,"max":5.2}]},
"columns":["hasHeight","hasWidth"],
"rows":[["106.0","47.0"],["85.0","50.0"]]}
<div>
<table *ngIf="tableResult">
<tr>
<th *ngFor="let eachProp of tableResult?.columns">{{eachProp}}</th>
</tr>
<tr *ngFor="let row of tableResult?.rows">
<td *ngFor="let field of row">
{{field}}
</td>
</tr>
</table>
<div *ngIf="!tableResult">
<!-- put your initial diagram here -->
</div>
</div>
<button (click)="genTable()"></button>
And in the component, something like this:
/* typescript */
tableResult: any;
genTable(): void {
this.tableResult = this.someService.fetchResults();
}
There's no way to know from your code what's in tableResult but I suspect that's what's causing your error. A suggestion would be try to do {{ tableResult }} right below the table tag. That way you can see if its content is correct and if it is an array or collection that can be iterated by *ngFor.
** EDIT: As other users have pointed out, you are trying to insert an uncompiled element to the DOM. That's not going to fly. You need to have a template and do things in your template. see here: https://angular.io/guide/architecture#templates
hello i am trying to pass inline edited table value as a parameter to play routes can someone help me with the same
here is my html code
<table class="gradienttable">
<thead>
<tr>
<th>Task</th>
<th>TimeSheetdate</th>
<th>Hours</th>
<th>IsBilled</th>
<th>Work Place</th>
</tr>
</thead>
<tbody>
#for(element <- CurrentPage) {
<tr>
<td contenteditable="true" id="task1">#element.getTask()</td>
<td>#element.getTimeSheetDate()</td>
<td contenteditable="true" id="hours">#element.getHours()</td>
<td contenteditable="true" id="isbilled">#element.getIsBilled()</td>
<td contenteditable="true"id="workplace">#element.getWorkPlace()</td>
<td>
</tr>
}
</tbody>
</table>
routes
GET /Application/edit controllers.Application.edit(task1:String)
application.java
public static Result edit(String task1)
{
return ok(DisplayTimeSheet.render(task1));
}
It looks like you're confusing the server-side rendered Scala template with the DOM actions of the client. For #{routes.Application.edit(task1.innerHTML)}, task1 doesn't exist as far as the non-DOM template is concerned.
Your use of <a href="..."> is kind of weird, because that would make a synchronous call and if you're into inline editing then maybe that's not what you want. This answer covers an asynchronous approach using Play's JavaScript router support (which, if you haven't seen it before, is very cool).
You'll need to expose edit in the JavaScript router:
// You can also return an F.Promise<Result>
public static Result jsRoutes() {
response().setContentType("text/javascript");
return ok(Routes.javascriptRouter("appRoutes", //appRoutes will be the JS object available in our view
routes.javascript.Application.edit()));
}
And then expose that method in the routes:
GET /assets/js/routes controllers.Application.jsRoutes()
That will generate a chunk of JavaScript that you can import
<script src="#controllers.routes.Application.jsRoutes()" type="text/javascript"></script>
And finally, write some JavaScript to handle the inline editing completion.
function doInlineEdit(taskName) {
appRoutes.controllers.Application.edit(taskName).ajax( {
success : function ( data ) {
target.closest('li').remove();
}
});
}
Then you just need to wire that method to be called when your inline-editable element changes content.
You can find additional info here.
We use elastic search highlighter and get the below code from the highlighter.
<span style='font-weight:bold;color:red;'>Baskar</span> Test
We display the result in html as follows.
<tr
ng-repeat="result in searchModelResult">
<td><p ng-bind-html="result.name"></p></td>
</tr>
I have included sanitize.js and have ngSanitize in the angular module. Still i dont see the html effect like red color font and bold font.
Am i missing anything here?
Thanks,
Baskar.S
You need to do 2 things, first remove
{{result.name}}
as Daniel said... then you need to say to angular to trust in that html in your controller:
myApp.controller('MyCtrl', function ($scope, $sce) {
$scope.result.name = $sce.trustAsHtml('<span style="font-weight:bold; color:red;">Baskar</span> Test');
});
You can see the full documentation of $sce here
If you need to iterate inside a ng-repeat you can create a filter:
myApp.filter('unsafe', function($sce) { return $sce.trustAsHtml; });
And then use it in the view:
<tr ng-repeat="result in searchModelResult">
<td><p ng-bind-html="result.name | unsafe"></p></td>
</tr>
You need to remove the second binding expression:
{{result.name}}
It looks like that is overriding the binding from ng-bind-html, and the default binding will HTML escape the string.
I'm currently using razor to render some views in DotNetNuke and everything is working fine except for one thing I'm missing. I'm trying to get access to some module level methods such as EditUrl etc. but can't seem to figure out how to go about it.
This is what I have for my view, although it errors on EditUrl. I'm using RazorEngine.Render to render the view. There are some helpers that are including for basic DNN info but I can't seem to find anything like NavigateUrl or EditUrl.
Any ideas?
#inherits DotNetNuke.Web.Razor.DotNetNukeWebPage<dynamic>
<div id="items-panel">
<table>
<thead>
<tr>
<th>Title</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Items)
{
<tr>
<td>
#item.Title
</td>
</tr>
}
</tbody>
</table>
</div>
I found a way that seems to work for EditUrl by creating a helper method in the razor view shown below. It's a shame I have to do this because the ModuleInstanceContext is actually passed into the constructor of the RazorEngine but not exposed to the view. If anyone else finds a way around this I'd appreciate a comment.
#helper EditUrl(string keyName, string keyValue, string controlKey)
{
#DotNetNuke.Common.Globals.NavigateURL(Dnn.Tab.TabID, controlKey, "mid="+Dnn.Module.ModuleID, keyName + "=" + keyValue)
}
Edit: The following method also worked well for me. I added a property to the model named ItemViewUrl with a placeholder token for the ItemId and then just did a replace in the view.
In the calling page:
dynamic model = new ExpandoObject();
model.Items = ItemRepository.List();
model.ViewItemUrl = EditUrl("ItemId", "[ITEMID]", "ViewItem");
and then in the Razor view:
<td>#item.Title</td>
So I have a bunch of paragraph elements which are dynamically populated from a db. I have made the elements contenteditable. I now want to submit edits back the the db via a standard form submission. Is there a way to post the contenteditable elements back?
You have to use javascript one way or the other, it won't work as a "standard" form element as it would with a textarea or the like. If you like, you could make a hidden textarea within your form, and in the form's onsubmit function copy the innerHTML of the contenteditable to the textarea's value. Alternatively you could use ajax/xmlHttpRqeuest to submit the stuff a bit more manually.
function copyContent () {
document.getElementById("hiddenTextarea").value =
document.getElementById("myContentEditable").innerHTML;
return true;
}
<form action='whatever' onsubmit='return copyContent()'>...
If anyone is interested I patched up a solution with VueJS for a similar problem. In my case I have:
<h2 #focusout="updateMainMessage" v-html="mainMessage" contenteditable="true"></h2>
<textarea class="d-none" name="gift[main_message]" :value="mainMessage"></textarea>
In "data" you can set a default value for mainMessage, and in methods I have:
methods: {
updateMainMessage: function(e) {
this.mainMessage = e.target.innerText;
}
}
"d-none" is a Boostrap 4 class for display none.
Simple as that, and then you can get the value of the contenteditable field inside "gift[main_message]" during a normal form submit for example, no AJAX required. I'm not interested in formatting, therefore "innerText" works better than "innerHTML" for me.
Does it NEED to be standard form submission? If you cannot or do not want use a form with inputs, you may try AJAX (XMLHttpRequest + FormData), through which you could perform asynchronous requests and control better how response shows up.
If you want it even simpler, try jQuery's $.ajax function (also $.get and $.post). It sends data using simple JS objects.
Made a fully working example based on Rob's idea:
After hitting submit, the (hidden) textarea is updated with the table-data, in JSON-format.
(return true to submit)
function copyContent() {
const table = [];
$("tr").each(function() {
const row = [];
$("th, td", this).each(function() {
row.push($(this).text());
});
table.push(row);
});
$("#rows").val(JSON.stringify(table));
// return true to submit
return false;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form onsubmit='return copyContent()'>
<textarea name="rows" id="rows" rows="4"></textarea>
<button type="submit">Submit</button>
</form>
<table class="table table-striped">
<thead>
<tr>
<th>Head 1</th>
<th>Head 2</th>
</tr>
</thead>
<tbody>
<tr>
<td contenteditable="true">edit </td>
<td contenteditable="true">me</td>
</tr>
<tr>
<td contenteditable="true">please</td>
<td contenteditable="true">😊</td>
</tr>
</tbody>
</table>