In the following block, why do we need the //<![CDATA[ ... //]]> block?
#using(Script.Foot()) {
<script type ="text/javascript">
//<![CDATA[
$(document).ready(function () {
alert('page loaded');
});
//]]>
</script>
}
Related Questions:
What is the meaning of CDATA
Why CDATA sections? CDATA sections tell the XML parser to read the characters without interpreting them as element or entity markup.
Why leading // marks? We introduce the CDATA opening and closing tags with // marks, so the JavaScript parser ignores the CDATA tags.
Why .cshtml but not .html? The .cshtml pages, which ASP.NET MVC uses, are XML based whereas .html pages are not.
References
CData Sections (MSDN)
What is the meaning of CDATA
Related
I have user-generated data I'm displaying in a Vue app, so the default Vue behavior of html-escaping the data is perfect. Except, now I'd like users to be able to search that data, and I'd like to highlight the matching text in the search result. That means I need my own styling to not be escaped, even though all the original data should still be escaped.
In other words I need to apply my styling after the data has been html-escaped, eg:
1. user inputs data:
some original data that has special characters like > and <
2. Vue html-escapes this for safe display:
some original data that has special characters like > and <
3. dynamically style the search results
Eg if user searched for "original data" it becomes:
some <span class="my-highlight-style">original data</span> that has special characters like > and <
Notice how my dynamic styling was not html escaped even though the user input was.
I could of course just use v-html to bypass the html escape entirely, but then I lose all the safety and benefit of html escaping which I don't want to lose. Ideally I want to explicitly call Vue's html escape routine, then apply my styling so that it does not get escaped, then finally render all of that unescaped (since I already applied appropriate escaping programmatically).
Does Vue offer programmatic access to its html escape routine? (And I'm not talking about $sanitize which strips out special characters entirely, I want to preserve them just like normal Vue templating does). I could of course write my own escape routine, just wondered if I could leverage Vue's instead.
Vue uses the Browser's API for encoding HTML content, as mentioned here: https://v2.vuejs.org/v2/guide/security.html#HTML-content.
So, something like this should offer you the same kind of protection as Vue would from the raw user input. In the computed property, we pass the user data through the p element to encode it. Then we chain on top of that our own highlight computed property where we can inject our own HTML, and then show that with v-html.
<template>
<div id="app">
<div><label>Raw text:<br /><textarea v-model="text" cols="50" rows="10" /></label></div>
<div><label>Search for: <input type="text" v-model="search" /></label></div>
<p><label>v-html: <span v-html="text" /></label></p>
<p><label>Highlighted: <span v-html="highlight" /></label></p>
</div>
</template>
<script>
export default {
data() {
return {
text: "some original data that has special characters like > and <",
search: "original data"
}
},
computed: {
highlight() {
const html = this.safeHtml;
return html.replace(this.search, "<span class='my-highlight-style'>$&</span>");
},
safeHtml() {
var p = document.createElement("p");
p.textContent = this.text;
return p.innerHTML;
}
}
}
</script>
<style>
.my-highlight-style {
background: orange;
padding: 5px;
}
</style>
building html page using kotlinx.html
lots of content built without problems, but stumbling on adding json script tag with an id so the code on the client can retrieve the json data.
what to have the code something like..
<script id="jsondata" type="application/json">
{ "jsondata": "is here" }
</script>
using kotlinx.html i can have
script(type="application/json"){
+"""{ "jsondata": "is here"}"""
}
but unlike other tags, script does not seem to have an id property. Any ideas on how to get set the id for the script tag?
All you need is Tag.attributes (mutable map with tag attributes).
script(type = "application/json") {
attributes["id"] = "jsondata"
unsafe { +"""{ "jsondata": "is here" }""" }
}
will give you this result:
<script type="application/json" id="jsondata">{ "jsondata": "is here" }</script>
I'm using the riot for the system. but I have a problem using the common tag in every place. because I have to copy the all common tag each page.
I added all tags like this. Does anyone have the solution for this ?
<st-service>
<st-alert></st-alert>
<st-header></st-header>
<st-body></st-body>
<st-footer></st-footer>
</st-service>
<st-profile>
<st-alert></st-alert>
<st-header></st-header>
<st-body></st-body>
<st-footer></st-footer>
</st-profile>
I found a solution, I'm using this method to handle these common tags. like this
<st-common>
<st-alert></st-alert>
<st-header></st-header>
<yeild></yeild>
<st-footer></st-footer>
</st-common>
service-page.tag // page
<st-service-page>
<st-common>
<st-service></st-service>
</st-common>
<st-service-page>
profile-page.tag // page
<st-profile-page>
<st-common>
<st-profile></st-profile>
</st-common>
<st-profile-page>
service-view.tag
<st-service>
// html / code body related to module
</st-service>
profile-view.tag
<st-profile>
// html / code body related to module
</st-profile>
If needed in details about this I can explain.
I'd have to know more about how you're routing to say for sure, but I think you should avoid using a different outer tag for each page. If your HTML looks something like this:
<body>
<st-app />
<script>
const pages = {
"/": "st-home",
"/about/": "st-about",
}
const content_tag = pages[window.location.pathname] || "st-notfound"
riot.mount("st-app", {
content_tag: content_tag
})
</script>
</body>
Then <st-app> would be defined something like:
<st-app>
<st-alert></st-alert>
<st-header></st-header>
<div data-is={this.opts.content_page}></div>
<st-footer></st-footer>
</st-app>
The important thing here being that you're controlling which tag should be used via the data-is attribute and the mounting options for <st-app>. In this example <st-home>, <st-about>, and <st-notfound> are riot components defined elsewhere.
I am working with knockout in MVC application. I am using knockout validation for validating the input. Everything is just fine,my problem is,I have a range validator for that input ll be coming from server view model.
how can I make that as my range validators minimum and maximum validation criteria?
since I am having all my code in separate js file I cant use # attribute.
Depending on how your code set up, you can use the # attribute (Razor code) as you said. Simply set a local variable on the page, then run your code that's in the external file, like this, where in your external js file, you can access min and max.
#* This is your razor .cshtml page *#
<script type="text/javascript">
var min = #ViewBag.Min;
var max = #ViewBag.Max;
</script>
<script type="text/javascript" src="../js/your-external-js"/>
Or, to keep things clean, you could use an initialize function:
#* This is your razor .cshtml page *#
<script type="text/javascript" src="../js/your-external-js"/>
<script type="text/javascript">
$(function() {
var min = #ViewBag.Min;
var max = #ViewBag.Max;
myExternalJs.Initialize(min, max);
});
</script>
I am not able to display Dojo Combobox as explained in this fiddle. I have added references of Dijit.js, Dojo.js, Ready.js and memory.js. My script gets executed as I verified by putting an alert but the Combobox simply doesn't show up. What am I missing?
Following is my html:
<div id="stateSelect"></div>
Following is my JS script
<script>
require(["dojo/store/Memory", "dijit/form/ComboBox", "dojo/ready"],function(Memory, ComboBox){
var ss = 'Abas Store, Accounts';
ss = ss.split(',');
var data = [];
dojo.forEach(ss, function(item, idx) {data.push({id: idx,name: item});});
var stateStore = new Memory({data: data});
var comboBox = new ComboBox({name: "select",value: "Select...",store: stateStore,searchAttr: "name"},"stateSelect");
});
</script>
Following JS references are added and each one of them is accessible:
<script type="text/javascript" src="/webapp/js/dojo/1.9.2/dojo/dojo.js"></script>
<script type="text/javascript" src="/webapp/js/dojo/1.9.2/dojo/ready.js"></script>
<script type="text/javascript" src="/webapp/js/dojo/1.9.2/dojo/store/memory.js></script>
<script type="text/javascript" src="/webapp/js/dojo/1.9.2/dijit/form/ComboBox.js"></script>
Edited to show snapshot after "Dimitri M" reply(referred from my comments):
I'm seeing several things here that are not right:
The first thing is that you only need to load the AMD loader (dojo.js), all other files are loaded automatically by it, so this means you can remove:
<script type="text/javascript" src="/webapp/js/dojo/1.9.2/dojo/ready.js"></script>
<script type="text/javascript" src="/webapp/js/dojo/1.9.2/dojo/store/memory.js></script>
<script type="text/javascript" src="/webapp/js/dojo/1.9.2/dijit/form/ComboBox.js"></script>
The second thing I notice (also in the example you're referring to) is that it's missing the proper event to wait for the DOM to load. You should replace dojo/ready by dojo/domReady!. This will make sure that the callback is only loaded if the DOM is loaded.
If you don't wait for the DOM, then your script might not find the div #stateSelect, and then the grid won't load (I think this is your problem).
I also have a recommendation (not a bug), you should not use dojo.forEach() if you're using a new version of Dojo, that syntax is actually deprecated and should be replace by the dojo/_base/array module which has a similar forEach() function.
But what you need is not the forEach() function, but the map() function to map your array of Strings to an array of objects.
I updated the example you used with the recommendations I gave, which you can find here.