Monaco-Editor Single String From Database - html

Been researching for the last couple of days and still no result. I have a back-end database that saves text entered in the Monaco-Editor. However, text will not display/load if there are new line returns (\r\n) in the string. The only I can get the text to display is to remove the line returns.
Here is some client-side code.
<div id="container" style="width:590px;height:400px;border:1px solid grey;white-space:pre-wrap;"></div>
//saving to hidden value
<input type="hidden" runat="server" id="editorValue" />
require.config({ paths: { 'vs': '../node_modules/monaco-editor/min/vs' } });
require(["vs/editor/editor.main"], function () {
var editor = monaco.editor.create(document.getElementById('container'), {
value: ['<%=MyJSText%>'].join('\n'),
language: 'javascript'
});
jQuery(document).ready(function ($) {
jQuery("#<%=linkOK.ClientID%>").on('click', function () {
getVal = editor.getValue();
document.getElementById("<%=editorValue.ClientID%>").value = getVal;
});
});
Some server side code
protected string MyJSText
{
get
{
if (EnableIDEditor)
{
return Server.HtmlDecode(TemplateRevision.JsScripts.Replace(Environment.NewLine, " "));
}
else
{
return Server.HtmlDecode(TemplateRevision.JsScripts);
}
}
}
I'd like the text entered into the monaco-editor box to display with line-breaks. Any help would be greatly appreciated.

Finally solved the problem by adding the following code on the server-side.
protected string MyJSText
{
get
{
if (EnableIDEditor)
{
return Server.HtmlDecode(TemplateRevision?.JsScripts?.Replace(System.Environment.NewLine, "\\\r\\n"));
}
else
{
return Server.HtmlDecode(TemplateRevision.JsScripts);
}
}
}
The trick was to use .Replace(System.Environment.NewLine, "\\r\n")) and the line breaks showed appropriately. Hope this helps someone who is looking to dynamically insert text into the monaco-editor.

Related

How to use one request to local JSON file to populate multiple dropdowns, using jQuery?

I am trying to use Country/City dropdowns in multiple places of my project, however I am getting stuck with an unusual behaviour - when I am changing the countries. How can I make one request to get the local JSON file and populate multiple dropdowns?
Here is my code:
$(document).ready(function() {
fetch('assets/test.json').then(response => {return response.json()}).then(selectData => {
console.log(selectData)
function updateSelectsBirth() {
let citiesBirth = selectData[this.value].map((key, val) => {
return $("<option />").text(key).val(key);
});
$("#cityBirth, #cityBirth1").empty().append(citiesBirth);
}
let stateBirth;
$countryBirth = $("#countryBirth, #countryBirth1").on("change", updateSelectsBirth);
for (stateBirth in selectData) {
$("<option />").text(stateBirth).val(stateBirth).appendTo($countryBirth);
}
$countryBirth.change();
})
});
And the HTML
<select id="countryBirth"></select>
<select id="cityBirth"></select>
<br/>
<select id="countryBirth1"></select>
<select id="cityBirth1"></select>
Here's also a link to the demo project: link to the demo
The unexpected behaviour comes from
$("#cityBirth, #cityBirth1").empty().append(citiesBirth);
Because, when it's updating the cities, it's updating all the dropdowns instead of just one.
So you can try:
$(document).ready(function() {
fetch('assets/test.json').then(response => {return response.json()}).then(selectData => {
// console.log(selectData)
function updateSelectsBirth(event) {
let citiesBirth = selectData[this.value].map((key, val) => {
return $("<option />").text(key).val(key);
});
// console.log(event.data.target)
$(event.data.target).empty().append(citiesBirth);
}
let stateBirth;
$countryBirth = $("#countryBirth").on("change", {target: "#cityBirth"}, updateSelectsBirth);
$countryBirth1 = $("#countryBirth1").on("change", {target: "#cityBirth1"}, updateSelectsBirth);
// $countryBirth1 = $("#countryBirth1").on("change", updateSelectsBirth("#cityBirth1"));
for (stateBirth in selectData) {
$("<option />").text(stateBirth).val(stateBirth).appendTo($countryBirth);
$("<option />").text(stateBirth).val(stateBirth).appendTo($countryBirth1);
}
$countryBirth.change();
$countryBirth1.change();
})
});
I apologize this is not a complete answer, as I'm not generalizing to multiple dropdowns, however I am not able to leave comments yet. I hope this can still be helpful.

Limiting the adding of rows in a form to a certain number

I am working on adding and deleting a set of fields in a row, i am able to do this via the following code,
but will have to limit it to a certain number, how would i be able to do that? Thanks in advance
The below is the code.
I am using an array and then using add and delete function for
Component File
`
get formArr(){
return this.finDetailsForm.get('itemRows') as FormArray;
}
initItemRows(){
return this.fb.group({
acc_name: '',
inv_amt: '',
v_inv_date: '',
});
}
addNewRow(){
this.formArr.push(this.initItemRows());
}
deleteRow(index: number) {
this.formArr.removeAt(index);
}
Attaching an image below of it
you can count length of array before push element.
addNewRow(){
if(this.formArr.lenght < 5){
this.formArr.push(this.initItemRows());
}
}
You have 2 solutions:
Update your component function as below:
class YourComponent {
private static MAX_ITEMS = << a number >>;
// ... constructor and rest ...
addNewRow(): void {
if (this.formArr.length < YourComponent.MAX_ITEMS) {
return;
}
this.formArr.push(this.initItemRows());
}
or you simply hide the button "+" when you reached the maximum item you want:
your-component.ts
get maxItemsReached(): boolean {
return this.formArr.length >= YourComponent.MAX_ITEMS;
}
your-component.html
<input type="button" *ngIf="!maxItemsReached">Add</input>

AngularJS display specific String in HTML

I'm still in process learning Angular.
For my current project I need to display HTML (eg: <h1>note1</h1><span>my first note</span><br><h1>note2</h1><span>my second note</span>) in my view. I know everyone will suggest to use ng-bind-html, but that is not what I want.
What I want is, i want to do checking if string HTML have note2 then display my second note.
In controller I know how to find string note2 which is use .match.
JSON
items =
[
{
"description": "<h1>note1</h1><span>my first note</span><br><h1>note2</h1><span>my second note</span>"
}
]
In controller find String note2
angular.forEach(items, function(value, key) {
if (value.description.match("note2")) {
console.log(value.description);
// will output HTML <h1>note1</h1><span>my...
}
else {
console.log("string not found");
}
});
I can do till find String note2, but to display my second note I don't have any idea.
Can someone help me with this,
thanks..
I haven't test this, but maybe you can use split function
angular.forEach(items, function(value, key){
if(items.description.match("note2")){
console.log(items.description);
var noteValues = items.description.split("<h1>note2</h1>");
$scope.mySecondNote = noteValues[1]; // value is <span>my second note</span>
}else{
console.log("string not found");
}
});
EDIT
Plunker DEMO here
It should be value.description., because items is an array
angular.forEach(items, function(value, key) {
if (value.description.match("note2")) {
}
DEMO
var app = angular.module('todoApp', []);
app.controller("dobController", ["$scope",
function($scope) {
items = [{
"description": "<h1>note1</h1><span>my first note</span><br><h1>note2</h1><span>my second note</span>"
}];
angular.forEach(items, function(value, key) {
if (value.description.match("note2")) {
console.log(value.description);
// will output HTML <h1>note1</h1><span>my...
} else {
console.log("string not found");
}
});
}
]);
<!DOCTYPE html>
<html ng-app="todoApp">
<head>
<title>To Do List</title>
<link href="skeleton.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<script src="MainViewController.js"></script>
</head>
<body ng-controller="dobController">
</body>
</html>
Change to
if (items[0].description.match("note2")) {
console.log(items[0].description);
// will output HTML <h1>note1</h1><span>my...
}
else {
console.log("string not found");
}

Remove Double Quotes around the String in CSV file

I am using Angular UI-grid to display data in tabular form and i also added a functionality to export the visible data in CSV file but my problem is that in exported file all the string are enclose with double quotes.
Can anyone tell me how to remove those unnecessary double-quotes ?
Any help is appreciated
The behavior that you are referring to comes from the function formatFieldAsCsv(field) within the uiGridExporterService service. There is no API that will allow you to change this with a setting.
What we can do however is use a decorator to override this default behavior without having to modify the ui-grid module itself.
I have demonstrated this in a working plunker.
In the snippet below, I have assigned qualifier to replace the quotations that were initially in use. With this, you can either leave the function as is and have no qualifier at all, or you can change it's value to whatever you like, and that will become the prefix/suffix of each field.
app.config(['$provide', function ($provide) {
$provide.decorator('uiGridExporterService', [
'$delegate',
function myServiceDecorator($delegate) {
$delegate.formatFieldAsCsv = formatFieldAsCsv;
return $delegate;
}
]);
function formatFieldAsCsv(field) {
var qualifier = '';
if (field.value === null) { // we want to catch anything null-ish, hence just == not ===
return '';
}
if (typeof(field.value) === 'number') {
return field.value;
}
if (typeof(field.value) === 'boolean') {
return (field.value ? 'TRUE' : 'FALSE');
}
if (typeof(field.value) === 'string') {
return qualifier + field.value.replace(/"/g, '""') + qualifier;
}
return JSON.stringify(field.value);
}
}]);
http://plnkr.co/edit/8qskcFt7EHSlTQFo4ZUG?p=preview

How to change the mode dynamically in codemirror on encounter of a particular expression?

In the textarea whenever '<' is encountered the mode should be html and for '<#' or '<#' or '$', the mode should be ftl. In the code that I have written
function determineCodeMirrorType(cm) {
if (cm.getOption('mode') == 'text/ftl') {
checkAndSwitchToHTML(cm, cm.getValue());
} else if (cm.getOption('mode') == 'text/html') {
checkAndSwitchToFTL(cm, cm.getValue());
}
}
function checkAndSwitchToHTML(cm, val) {
if (/^\s*</.test(val)) {
cm.setOption("mode", "text/html");
}
}
function checkAndSwitchToFTL(cm, val) {
if (/[<#|<#|$]/.test(val)) {
cm.setOption("mode", "text/ftl");
}
}
function buildCMInstance(mode, value) {
var cm = CodeMirror.fromTextArea(document.getElementById("code"), {
mode:mode,
value:value,
lineNumbers:true,
onChange:function(cmInstance){
determineCodeMirrorType(cmInstance); //The call to this function is not made.
})
});
return cm;
}
$(document).ready(function(){
var cm = buildCMInstance("text/ftl")
});
I want to know is there any option that can be initiated which allows the code to change dynamically by making a call to the function "determineCodeMirrorType".
onChange does not exist in recent CodeMirror versions. You have to register the event handler by calling cm.on("change", function(cm, change) { .... }).