javascript in MVC Application? - javascript

I have written javascript function in my view page but it is giving me an error.I wnat to set the selected value of dropdown in the label.Please tell me where am I going wrong??
function OnSelect()
{
var label = document.getElementById("<%= lblSelection.ClientID %>");
label .Text= "You selected <b>";
}
Above is the script function

There is no text property on an element. Assuming the element refered to using label is something like a div or span, use:
function OnSelect()
{
var label = document.getElementById("<%= lblSelection.ClientID %>");
label.innerHTML = "You selected <b>";
}

Mixing Server and Client
Property Text is only available on the server Label control, but not on the client DOM element. You've mixed this a bit.
Avoid server controls in MVC
Even though you shouldn't use Asp.net web server controls with a MVC application. It's not recommended. They can be used but with caution. In your case where you don't distinguish between server and client controls I assume you're rather a beginner. No offence but I suggest you rather start and learn pure and clean MVC applications first before doing this kind of mix.

You seem to be confusing an asp:Label control on the server-side with a DOMElement on the client side. Take some time to learn the JavaScript environment and the DOM API. Then learn jQuery, which wraps the different DOM implementations with a very nice and consistent API.
Also When using MVC you shouldn't use WebForms controls unless you need to. This makes it much easier to understand what's going on in the client-side of things when your JavaScript is running.

As others have pointed out, Text is not a valid DOM property. You may be thinking of the text method that jQuery provides to set the innerHTML of an element as plain text.
However, you also end your string in with the bold tag, which leads me to believe that you plan on building out an HTML string with more content. If this is the case, you should use the following approach and build out the entire HTML string, and then update the DOM element.
var OnSelect = function() {
var html = "You selected <b>";
if ( someCondition ) {
html += "some value";
}
html += "</b>";
$("<%= lblSelection.ClientID %>").html(html);
};
On the other hand, if you mean to literally display You have selected <b>, and <b> is not supposed to be an HTML tag, then you'll need to do the following:
var OnSelect = function() {
$("<%= lblSelection.ClientID %>").text("You selected <b>");
};
Notice the use of text rather than html.

Related

how to check if html or script tags exist in input in javascript using RegEx

we want to prevent user to enter scrips or html tags input to avoid cross site script attack
for this i am writing this code but its seems not working
var preventScriptsRegEx = new RegExp("[^<>]*");
function getValue() {
return document.getElementById("myinput").value;
}
function test() {
alert(preventScriptsRegEx.test(getValue()));
}
this is inspired from this post : Prevent html tags entries in mvc textbox using regular expression
You can try creating a temporary element, set the input's value to the element's innerHTML property, and check the element's childElementCount:
function checkForHTML(text){
var elem = document.createElement('div')
elem.innerHTML = text;
return !!elem.childElementCount;
}
button.addEventListener('click', function(){
console.log(checkForHTML(input.value))
})
<input id="input">
<button id="button">Check</button>
Please don't do this. You can't just use some nifty RegExp to check for script injection. There are plenty of attack vectors where you can trick injections where RegExp simply cannot match well. This involves for example, using \u0001 UTF8 encodings or HTML entity encoding (< becomes & lt;, or & # 60; or & # x003C;) (lol in original post it even worked here...) which will pass your validation but automatically transformed so that execution is possible. I've been writing such exploits for fun, so I can guarantee you that there are almost as many ways to exploit such algorithms as there is creativity in a hackers/crackers mind.
The right way to protect yourself from such script injections/XSS is, to not trust user generated content in the first place. Do not trust "validation logic" as well. You shouldn't just accept HTML, JS or CSS code when it is somehow generated on the client side. Never. You should never save such content in a database, or transfer it by any other means and render it again. User generated content that is or could be in form of CSS, HTML or JS is evil and should be treated like a ticking nuclear bomb.
Every content that the client is sending to the server and that is re-rendered on client side in some way must not be sanitized but explicitly rendered via (htmlElement).innerText = user content (pseudo code); innerText is guaranteed to not create DOM nodes than TextNodes which is the only way to be sure that you're safe Never ever in-place render into HTML or CSS. Remark: I can also make CSS code XSS e.g. using vendor-specific CSS addons.
Example: behavior:url(script.htc); -moz-binding: url(script.xml#mycode);
Just never use .innerHTML = as well. Never let user generated code directly affect the DOM at all, never do < div > render($content) </ div > or anything like that.
For content that should be styled, use a DSL. It could be a JSON or any other DSL like Markdown etc. if you need a simple one, that splits text content from context information. Then, by code you trust, loop thru that data structure and render the HTML / DOM elements and always use .innerText or guaranteed .innerText use to render the user generated content (React for example is guaranteed to use that API except you're explicitly using innerHTML or dangerouslySetInnerHTML which is just sabotage). Also don't allow user generated content to set HTML element attributes. I can XSS that too.
Example: < a href="javascript:alert('XSS!')" / >

AngularJS with MVC dynamically get html, append to body, and bind a controller

I am new to AngularJS with a jQuery background. For what I thought would be a simple task I am just finding it to be increasingly difficult. I have looked around on how to dynamically add html and bind to a controller but I just have not found my particular situation.
This is what I am trying to accomplish. I'll want to keep it simple for now with a simple dialog box. Basically, suppose I want to create my own custom dialog box. Suppose based on a button click I want to display the message "Are you sure you want to so and so" with the buttons yes, no, cancel. Then based on the button click, I'd like to perform a specific operation, users with windows development will be familiar with this.
First I must construct my message and my dialog box html based on the button clicked, append that output html to the document body as position absolute, and then once done with this remove the html from the document body.
In jQuery I can simply do this
...somewhere in code
var html = "<div id='123' class='dialog-box'><button id='yesButton'></button>
...elements for no and cancel</div>";
DisplayDialog("123", html);
...
function DisplayDialog(elementId, html) {
$(document.body).append(html);
var dElement = $(document.body).find("#" + elementId);
$(dElement).find("#yesButton").on("click" function () {
...code
$(dElement).remove();
});
...code for no, and cancel events
}
I just can't understand how to do this simply the angular way. Basically, I want to be able to get html, append it somewhere (whether in the body, or in a div element etc), and be able to interact with it using the $scope. I kept it simple for now for a dialog box, if I can understand this I can apply to much more complex operations where I might need to retrieve partial views in my MVC application and append it to a div
Its pretty straightforward in angular, this shouldn't be to hard for you given the jquery background:
var myEl = angular.element( document.querySelector( '#divID' ) );
myEl.append('Hi<br/>');
https://docs.angularjs.org/api/ng/function/angular.element
Another way:
You then use ng-bind in the html and set it to a $scope variable that represents the html:
<div ng-bind-html="divHtmlVar"></div>
$scope.divHtmlVar = '<b>main html</b>';
Relevant blog post:
http://blog.sodhanalibrary.com/2014/08/append-or-prepend-html-to-div-using.html

How to optimize the creation of long html code to be used in javascript string

I need to define javascript variables containing very long html code.
Here is a short example:
var text = "Select one item:<br>";
text += "<ul class='thumbnails'><li class='span3'><a href='#' class='thumbnail'><img src='http://placehold.it/260x180' alt=''></a></li></ul>";
Since the html is going to be much much longer, I would rather work in pure html rather than append text to a javascript string.
I thought of creating a separate html file, but I guess that would require an Ajax call to fetch its content.
What is the best way to deal with this?
As N.Zakas said on "maintainable javascript" book, you should «keep html out of javascript» to promote high mantainability of the code through loose coupling of UI layers.
Beside the ajax solution you could also place the markup as a comment in the html file and read it via javascript (as a regular DOM node) or you could use some kind of microtemplating system (e.g. handlebars) and place your markup in a script block (the idea is to put markup where is expected to be found and not into javascript logic)
One possible solution is to use templates. There are a few JavaScript libraries that provide templating, underscore.js is one: http://underscorejs.org/#template, or more details on how to use it for templating http://www.headspring.com/blog/developer-deep-dive/an-underscore-templates-primer/
Plus underscore is great for a number of other things.
You could break up the text into actual HTML objects.
var thumbnailsUL = document.createElement('ul');
for (index in {your-thumbnails-list}) {
var thumbnail = document.createElement('li');
thumbnail.innerHTML = {whatever you need, more objects or html as text};
thumbnailsUL.appendChild(thumbnail);
}
Ideally though, there is no reason to build this IN JavaScript - can you not emit it from the server?
Instead of constructing HTML in Javascript as a string, I would rather suggest you to emit those html elements in the page itself and hide while loading. Then in Javascript, you could select that container and display it.

Can you mix ASP.Net and Unobtrusive JavaScript

Is it possible to mix the concept of Unobtrusive JavaScript with the event model of ASP.Net?
ASP.NET makes it very difficult, as every server side control requires a postback via the __doPostback javascript function.
You can make sure you are not using any server side controls, but this means you loose most of the benefits of ASP.NET.
Another option is to override the OnRender event and output different controls/javascript, but this is also quite a lot of work and defeats the purpose of ASP.NET.
You have much greater control when using ASP.NET-MVC.
yes, to a point. discounting standard controls and how they are built, there's not much stopping your from offloading all your own javascript to a separate file. the big hangup that comes to mind is referencing myControl.ClientID to render an element id in the middle of a script block. with a little planning, you can still minimize the amount of script you have to render in the page to work around this.
I realize that this question has already been answered but for anybody surfing in, I somewhat disagree with the accepted answer.
It depends on what controls you are using.
Not all the controls require JavaScript. The biggest culprit for me was always LinkButton. A regular button control does not use JavaScript at all however. On my pages, I actually use regular buttons and use CSS and JavaScript to make them into LinkButtons. The first step is to use CSS to make them look like links. If you really want to get fancy, you can detach the button, add an HTML anchor, and associate all the event handlers for the button with the anchor. This means that a user without JavaScript sees a regular button (HTML input) that is styled with CSS. Anybody using JavaScript will see an HTML link (
Also, if you use JQuery, it is very easy to select ASP.NET elements without worrying about all the extra mumbo-jumbo that ASP.NET adds to the IDs.
Example:
<asp:Button id='theButton' text='Click here' cssclass='linkbutton' runat='server' />
You can select this individual button using JQuery:
var theButton = $("input[name$='theButton']");
You can also replace everything of class 'linkbutton' with HTML anchors:
$(function() {
var buttons = $(".linkbutton");
buttons.each(function() {
var button = $(this);
var id = button.attr('id');
/*
* If a link button is not working
* it is likely because it does not
* have an ID attribute - check that
*/
if (id)
{
var text = button.attr('value');
var cssclass = button.attr('class');
button
.before("<a id='"+id+"' class='"+cssclass+"' href=''>"+text+"</a>")
.hide()
.detach();
$("a[id='"+id+"']").live('click', function(event) {
$(this).after(button);
button.click();
event.preventDefault();
});
}
});
});
Things like GridViews are a bit more work but also doable. I found that, after the initial honeymoon, I avoided those kinds of controls and just used repeaters anyway. Repeaters do not impose any nasty JavaScript either.
Anyway, it is certainly possible to do unobtrusive JavaScript with ASP.NET WebForms.

Reference ASP.NET control by ID in JavaScript?

When ASP.NET controls are rendered their ids sometimes change, like if they are in a naming container. Button1 may actually have an id of ctl00_ContentMain_Button1 when it is rendered, for example.
I know that you can write your JavaScript as strings in your .cs file, get the control's clientID and inject the script into your page using clientscript, but is there a way that you can reference a control directly from JavaScript using ASP.NET Ajax?
I have found that writing a function to parse the dom recursively and find a control that CONTAINS the id that I want is unreliable, so I was looking for a best practice rather than a work-around.
This post by Dave Ward might have what you're looking for:
http://encosia.com/2007/08/08/robust-aspnet-control-referencing-in-javascript/
Excerpt from article:
Indeed there is. The better solution
is to use inline ASP.NET code to
inject the control’s ClientID
property:
$get('<%= TextBox1.ClientID %>')
Now the correct client element ID is
referenced, regardless of the
structure of the page and the nesting
level of the control. In my opinion,
the very slight performance cost of
this method is well worth it to make
your client scripting more resilient
to change.
And some sample code by Dave from the comment thread of that post:
<script>
alert('TextBox1 has a value of: ' + $get('<%= TextBox1.ClientID %>').value);
</script>
The comment thread to the article I linked above has some good discussion as well.
You can change to ClientIDMode property of the control to 'Static' that will result the same ID that you give the control in the .NET code.
<asp:TextBox ID="TextBox1" ClientIDMode="Static" runat="server"></asp:TextBox>
will result:
<input name="ctl00$MainContent$TextBox1" type="text" id="TextBox1">
so you have the same ID.
Couple of thoughts on this:
1) I've had a lot of luck getting elements by css class instead of id because asp.net ids are not reliable as you stated. I use this function and it performs reasonably well:
function getElementsByClass(searchClass,node,tag) {
var classElements = new Array();
if ( node == null )
{
node = document;
}
if ( tag == null )
{
tag = '*';
}
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
for (i = 0, j = 0; i < elsLen; i++)
{
if ( pattern.test(els[i].className) )
{
classElements[j] = els[i];
j++;
}
}
return classElements;
}
2) jQuery helps here alot. Using jQuery you can reliably get elements where the id ends with a certain string. While this is not "the" reason to use jQuery it's definitely a plus.
3) This will be fixed in asp.net 4.0 so hang in there :-) http://weblogs.asp.net/asptest/archive/2009/01/06/asp-net-4-0-clientid-overview.aspx
I prefer data bound tags in the markup document.getElementById('<%#TextBox1.ClientID %>').value, over the use of the server side tag implementation <% = TextBox1.ClientID %>.
Server side tags prohibit you from adding controls to the dom in the code behind. This need commonly arises as you build out your application and the databound approach may save you from major rewrites.
When using server side tags also know as 'code blocks' performing this common operation
this.Form.Controls.Add(myContorl);
generates this error at run time:
The Controls collection cannot be modified because the control
contains code blocks (i.e. <% ... %>).
Unfortunately this often only become inherently obvious after you have built out your web site.
When implementing data bound control '<%#TextBox1.ClientID %>' resolve the value of control properties referenced in the markup, in the appropriate place such as the end of Page_Load data bind like this:
Page.DataBind()
Keep in mind Page.DataBind() causes child controls on the page to also DataBind, this may be an unwanted side effect if the page handles the data binding of certain child controls separately. If this is the case, data binding can be performed on the individual control like this:
TextBox1.DataBind()
An applications evolution eventually leads to some sort of base site wide functionality where you may want to add base controls, once you've peppered you website application with server side tags replacing them with databinds becomes problematic, especially when pages have been coded to handle databinding on their own.
I don't think there's a single "best practice" for doing this. There's plenty of different pretty good practices. Here's ours:
Every control which has client-side functionality renders a script block inline, directly below the markup for the control:
<span id="something_crazy_long">
control markup
</span>
<script type="text/javascript">new CustomControl('something_crazy_long');</script>
Each control has an accompanying JS like:
var CustomControl = function(id) {
this.control = document.getElementByID(id);
this.init();
};
CustomControl.prototype.init = function() {
//do stuff to wire up relevant events
};
In the codebehind, we do something like:
class CustomControl : Control
override void Render(HtmlTextWriter writer)
{
writer.WriteBeginTag("span");
writer.WriteAttribute("id", this.ClientID);
writer.Write(HtmlTextWriter.TagRightChar);
//write control markup
writer.WriteEndTag("span");
writer.WriteBeginTag("script");
writer.WriteAttribute("type", "text/javascript");
writer.Write(HtmlTextWriter.TagRightChar);
writer.Write(
string.Format("new CustomControl('{0}');", this.ClientID)
);
writer.WriteEndTag("script");
}
I do something similar to Rex M except to avoid multiple script tags I use a function in my page base class to register the controls I am going to use clientside, then spit them out to html inside 1 script tag.
You could even subclass your controls to automatically register with the function or use a boolean property to set whether you are going to use them clientside.
For 'ctl00_ContentMain_Button1' - In asp.net when page renders in the browser, first part remains same 'ctl00'. Second part is ID of ContentPlaceHolder used 'ContentMain'. Third is ID of a control 'Button1'
I liked this http://codedotnets.blogspot.in/2012/01/how-get-id-server-control-javascript.html
Oh, and I also found this, in case anyone else is having this problem.
Use a custom jQuery selector for asp.net controls:
http://john-sheehan.com/blog/custom-jquery-selector-for-aspnet-webforms/
You can get the ID by using document.getElementById method as well.

Categories

Resources