I am generating html through C#
myStr = "<span class='red'>September 1980</span><br /><div>abcdef\nhijklm</div>";
shtml = "<span class='red' title='<pre>" + HttpUtility.JavaScriptStringEncode(myStr, false) + "</pre>' id='" + jc.FirstOrDefault().UserId + "'>" + content + "</span>" + after;
... snip snip ...
<%= shtml %>
And my jquery script for initializing qtip is:
$('[title!=""]').each(function(){
$(this).qtip({
hide: {
fixed: true, delay: 300
}, show: 'mouseover',
position: {
my: 'top center',
at: 'bottom center',
viewport: $(window),
adjust: {
method: 'shift shift'
, screen: true
}
}, style: {
classes: 'qtip-light', // Inherit from preset style
tip: 'topCenter'
}
});
});
Now the tooltip is showing:
\u003cspan class=\u0027abcd\u0027 title=\u0027September 05, 2013 12:06\u0027\u003e\u003ci
How can I render the html in tooltip?
this has been eating my time and brains... please help!
Note: please read the following before marking this question as duplicate:
I searched all the related posts, but none of the soutions worked for me. My use case is different as I am using qtip to show the string generated by javascriptstringencode.
I could not find any built in function to decode the data which is encoded using HttpUtility.JavaScriptStringEncode. So I created a JS function after some research in various sites.
String.prototype.replaceAll = function(str1, str2, ignore) {
return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g, "\\$&"), (ignore ? "gi" : "g")), (typeof(str2) == "string") ? str2.replace(/\$/g, "$$$$") : str2);
}
function decodeJs(encodedString) {
var decodedString = encodedString;
decodedString = decodedString.replaceAll("\\u0026", "&");
decodedString = decodedString.replaceAll("\\u0027", "\'");
decodedString = decodedString.replaceAll("\\u003c", "<");
decodedString = decodedString.replaceAll("\\u003e", ">");
return decodedString;
}
function replaceText() {
$("*").each(function() {
if (!$(this).children().length) {
$(this).text(decodeJs($(this).text())).val(decodeJs($(this).val()));
}
});
}
$(document).ready(replaceText);
$("html").ajaxStop(replaceText);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Related
I am using Web Api, and I have a controller class for each entity. For the main page in my application, however, I need to do some stuff with most of the entities. I am using jQuery & Ajax to make calls to the relevant controller class. This has created already ~400 lines of code, and it may go up to ~1000. For example, I need to write a jquery script to loop through the returned items, and build a table to list the items properly in my page.
To organize it better, I am thinking about moving the jquery code for different entities to separate *.js files. I wonder if there is a better way of doing this. What is the best (but not very complicated) method for this?
UPDATE
Here is an example of one of the lengthy jquery ajax functions:
/////////////////////////////////////////////////////////
//Functions -- Retriving posts and then displaying
function LoadPostsByDiscussionWall(currDiscussionWallId) {
jQuery.support.cors = true;
$.ajax({
url: '/api/post/GetPostsByDiscussionWall?dwId=' + currDiscussionWallId,
type: 'GET',
contentType: "application/json; charset=utf-8;",
dataType: 'json',
success: function (response) {
var posts = response["$values"];
DisplayPosts(posts);
},
error: function (x, y, z) {
alert(x + '\n' + y + '\n' + z);
}
});
}
function DisplayPosts(posts) {
if (posts.length) {
$('#div_ListOfPosts').html('');
$.each(posts, function (index, post) {
var photo = ''; var displayname = 'Anonymous';
if (post.IsAnonymous == true) {
if (post.Person.AnonymousPhoto.length)
photo = post.Person.AnonymousPhoto;
if (post.Person.AnonymousName.length)
displayname = post.Person.AnonymousName;
} else {
if (post.Person.ProfilePhoto.length)
photo = post.Person.ProfilePhoto;
displayname = post.Person.FirstName + ' ' + post.Person.LastName;
}
var curruserid = $("#hdn_currUserId").val();
var displayDeleteButton = "";
if (curruserid === post.Person.Id)
var displayDeleteButton = '<a href="#" style="float:right;" data-postid=' + post.PostId + ' class="small text-muted">'
+ '<span class="small glyphicon glyphicon-remove"></span></a>';
var p = '<div>';
p = p + '<img style="height:37px;float:left;" src=' + photo.replace('~', '') + ' />'
+ '<div style="float:left;margin-left:5px;">'
+ displayname
+ "<br/><span class='small text-muted'>" + post.DatePosted + "</span>"
+ '</div>'
+ displayDeleteButton
+ '</div>';
p = p + '<div style="float:right;width:100%;margin-top:3px;"><a href="#" data-postid="'
+ post.PostId
+ '" class="text-primary postitem" style="font-family:arial;">'
+ post.Title + "</a>";
var postContent = post.Content;
if (post.Content.length > 180) {
postContent = post.Content.substring(0, 180) + '...';
}
p = p + '<br/><p style="margin-top:3px;padding-bottom:7px;border-bottom:solid 1px #ebebeb;font-family:arial;" class="small">'
+ postContent + "</p></div>";
$('#div_ListOfPosts').append(p);
});
} else {
$("#div_ListOfPosts").html("No posts were found. Select another discussion wall.");
}
}
//END Functions -- Retriving posts and then displaying
////////////////////////////////////////////////////////
Code re-usability is key.
For your specific purpose, I would look into creating a custom jQuery plugin, or maybe even a jQuery UI - Custom Widget Factory.
In a blog, for example, there may be many different locations you want to return a user's posts - not just on their home or main page. You might want to make the post look differently in different areas of the site.
You can use a custom jQuery plugin function to build your post entity, and to accept "settings/options" as parameters. This way you have your default post entity "widget" but can also change the look and feel without having to re-write lines of code.
Here is an example snippet using $.extend () - but it's not far removed from the practice of creating a custom plugin.
$(function() {
var tar = $('#parent');
tar.createPost(); // default "Post"
// settings for a new post
var settings = {
"postWidth": "400px",
"postContent": "Here's a new post!",
"postBgColor": "yellow",
"postData": "foo",
"postTitle": "Oh no! Not another Post!",
"postTitleBgColor": "pink"
};
tar.createPost(settings);
});
//---------------------------------------------------
// using extend() as an example
// you probably want to author your own plugin
$.fn.extend({
// o = options
createPost: function(o) {
// d = defaults
var d = {
postContent: "No post content found! :(",
postData: "na",
postHeight: "100%",
postWidth: "100%",
postBgColor: "#d2d2d2",
postTitleWidth: "100%",
postTitleBgColor: "#fff",
postTitleBorder: "solid 2px #ebebeb",
postTitle: "NA",
postTitleLink: "#",
postContentFont: "Arial"
};
o = $.extend(d, o);
// Set your function
this.each(function() {
// Post and post title elements
var post = $('<div>');
var postTitle = $('<a>');
var postContent = $('<p>');
// Build components
post.attr("data-postid", o.postData);
post.css({
"height": o.postHeight,
"width": o.postWidth,
"background-color": o.postBgColor,
"margin-top": "15px",
"border": "dashed 2px lightblue"
});
postTitle.attr("href", o.postTitleLink);
postTitle.text(o.postTitle);
postTitle.css({
"display": "inline-block",
"background-color": o.postTitleBgColor,
"border": o.postTitleBorder,
"width": o.postTitleWidth
});
postContent.css({
"font": o.postContentFont
});
postContent.html(o.postContent);
post.append(postTitle);
post.append(postContent);
post.appendTo(this);
});
return this;
}
});
.container {
width: 800px;
height: 500px;
border: solid 1px #d2d2d2;
margin-top: 25px;
background-color: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div id="parent"></div>
</div>
How can I iterate over the images in JSON of following format? Length of images collection can be arbitrary. Can I manipulate it to make it a list, or what options do I have to parse this?
images: {
0: {
filename: "image1.jpg"
},
1: {
filename: "image2.jpg"
},
2: {
filename: "image3.jpg"
},
}
One possible solution would be to create a dynamic representation of your json:
dynamic jsonData = JsonConvert.DeserializeObject(#"{
images: {
0: {
filename: ""image1.jpg""
},
1: {
filename: ""image2.jpg""
},
2: {
filename: ""image3.jpg""
}
}
}");
foreach(var item in jsonData["images"])
{
//Do something
}
If you have a read of this SO question, you'll notice that JSON.NET is a recommended library to use for situations like this.
You could try using the DataContractJsonSerializer to create objects from JSON input, but when I tried it just now, I couldn't get it to work with a collection of items in the JSON string.
You can do this with vanilla javascript like this:
for (objectName in data["images"]) {
html += data["images"][objectName]["filename"] + "<br />"
}
Full HTML file example below
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="result"></div>
<script type="text/javascript">
var data = {
"images": {
"0": {
"filename": "image1.jpg"
},
"1": {
"filename": "image2.jpg"
},
"2": {
"filename": "image3.jpg"
}
}};
var html = '';
for (objectName in data["images"]) {
html += data["images"][objectName]["filename"] + "<br />"
}
document.getElementById("result").innerHTML = html;
</script>
</body>
</html>
I ended up figuring it out - although may not be best practice it worked in this case
var imageHoldingList = new List<VehicleImagesModel>();
var connectionResponse = JsonConvert.DeserializeObject<dynamic>(results);
var jImage = connectionResponse["response"]["vehicles"]["images"].Children();
foreach (var image in jImage)
{
var h = new VehicleImagesModel
{
Filename = image.First.filename.ToString(),
Caption = image.First.caption.ToString()
};
imageHoldingList.Add(h);
}
I have written the script dynamically using string builder as follows
public static void ShowMessage1(ENUM_MessageType pMessageType, string pMessage, Button c)
{
StringBuilder strScript = new StringBuilder();
strScript.Append("<script type=\"text/javascript\" src=\"").Append("/Scripts/jquery-1.4.1.js").Append("\"></script>");
strScript.Append("<script type=\"text/javascript\" src=\"").Append("/Scripts/jquery.msgBox.js").Append("\"></script>");
strScript.Append("<link rel=\"stylesheet\" type=\"text/css\" href=\"").Append("/Styles/msgBoxLight.css").Append("\" />");
strScript.Append("<script type=\"text/javascript\">");
strScript.Append("(function example()");
strScript.Append("{");
strScript.Append("$.msgBox({");
strScript.Append("title:'" + lMessageType + "'");
strScript.Append(",");
strScript.Append("content:'" + pMessage + "'");
strScript.Append(",");
strScript.Append("type:'" + lOptionType + "'");
strScript.Append(",");
strScript.Append("buttons: [{ value: 'Yes' }, { value: 'No'}],");
strScript.Append("success: function (result) {");
strScript.Append("if(result == 'Yes'){");
strScript.Append("javascript:_doPostBack('" + c.ClientID + "','');");
strScript.Append("}");
strScript.Append("}");
strScript.Append("});");
strScript.Append("})();");
strScript.Append("</script>");
if (page != null && !page.ClientScript.IsClientScriptBlockRegistered("alert"))
{
page.ClientScript.RegisterClientScriptBlock(typeof(enumClass), "info", strScript.ToString());
}
}
I am getting the exception as ReferenceError: _doPostBack is not defined can some one help me
Its should javascript currently you have
strScript.Append("avascript:_doPostBack('" + c.ClientID + "','');");
It should be:
strScript.Append("javascript:__doPostBack('" + c.ClientID + "','');");
Missing j in front. Also make sure that its __ not a single underscore.
Looks like you're missing an underscore on your __doPostBack() call.
Also, take a look at the success in your rendered JS:
(function example() {
$.msgBox({
title : 'INFORMATION',
content : 'I am from client side',
type : 'confirm',
buttons : [{
value : 'Yes'
}, {
value : 'No'
}
],
success : function (result) {
if (result == 'Yes') {
javascript : __doPostBack('Button1', ''); // <--- this line
}
}
});
})();
If you are just trying to call a postback there, get rid of the javascript : so that it reads like this:
strScript.Append("__doPostBack('" + c.ClientID + "','');");
Also, according to the answer on this SO question, make sure there is an ASP.NET WebControl rendered to the page. __doPostBack() is automatically included on the page when a WebControl is rendered. So, if you on't have one on the page, there's a chance that the __doPostBack() method could be missing.
If you don’t have any asp.net server side postback controls on the page the “_doPostBack not defined” error will be thrown on the client. To avoid the described error you can try adding following lines of code into the page load event:
protected override void OnPreLoad(EventArgs e)
{
this.Page.ClientScript.GetPostBackEventReference(this, string.Empty);
base.OnPreLoad(e);
}
The GetPostBackEventReference returns a string that can be used in a client event to cause postback to the server
The other approach is to add hidden asp:Button which will register the same scripts as GetPostBackEventReference method.
I designed an application which works in all browser except in IE,
Actually where i got struck means i added 2 tabs for example,
public string GetTabs()
{
strResult = strResult + "<div class='amc-container'>";
strResult = strResult + "<div id='links-div' class='simple-round-div-right'>";
strResult = strResult + "<div id='tab-link1' class='tab-button-enabled'>Products</div>";
strResult = strResult + "<div id='tab-link2' class='tab-button-disabled'>Spares</div> </div></div>";
return strResult;
}
//Javascript function
function showTab(div, dom, obj, tcd, tid,status) {
$("div.tab-button-enabled").removeClass('tab-button-enabled').addClass('tab-button-disabled');
$(obj).parent().removeClass('tab-button-disabled').addClass('tab-button-enabled');
$("#" + div).html('Loading...');
$.get("/common/get_amcb.aspx", { dm: dom, acd: tcd, aid: tid, domain: obj.firstChild.nodeValue,status:status },
function (data) {
$("#" + div).html(data);
});
}
$.get() function loads page get_amcb.aspx page & get the data from .aspx page through response.Write() method & bind into the div.
while page loading I'm calling this function (GetTabs()) & assigning to label.
All this works in chrome,Firefox but not in IE if I'll use IE(9.0 version) then added data is not reflect into the tab if we want to show data means we need close browser & reopen the browser that time added data is showed, WHY its happening & I'm not getting whats going on behind please help me.
Thanks
IE loves caching. Clear cache and see. If that is the case, send a timestamp along with the url. So it will be considered a s anew request.
var tstmp = new Date();
var uniqueTimeStamp = tstmp.getTime()
$.get("/common/get_amcb.aspx?timestam="+uniqueTimeStamp , { dm: dom, acd: tcd, aid: tid, domain: obj.firstChild.nodeValue,status:status },
function (data) {
$("#" + div).html(data);
});
Sorry I'm very new to JQuery... I can't for the life of me figure out where my bug is. When I run this I don't get any results. When I check the error in Firefox and Chrome it points to the source line. I just can't see anything wrong.
Here's my script
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.11.js")" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#CustName').autocomplete({
//Firefox points to a syntax error here
source: #SqlHelper.getJSONArray("CustName", "dba.BillingInfo")
});
});
</script>
<p>Customer Name #Html.TextBox("CustName")</p>
SqlHelper.getJsonArray is a method I'm using to return a JSON string. I've checked and double checked that it is in fact returning valid JSON.
public static string getJSONArray(string column,string table)
{
string qry = "SELECT DISTINCT " + column
+ " FROM " + table
+ " WHERE " + column + " is not null"
+ " AND " + column + " <> ''"
+ " ORDER BY 1";
List<string> result = new List<string>();
SqlDataReader reader = execQry(qry);
while (reader.Read())
{
result.Add(reader[0].ToString());
}
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(result);
}
[UPDATE]
Here is the syntax error firefox is spitting back:
source: $.parseJSON(["Customer1","Customer2...
---------------------^
So I'm beginning to think the issue is the quotes are getting rendered as quot; instead of ". If I try putting my source as ["Test1","Test2","Test3"] it works fine. Is there a way to get razor to not HTML encode the string?
[UPDATE]
That was the issue. The solution was using Html.Raw()
The issue was razor automatically HTML encoding the JSON. The fix is using HTML.Raw
$('#CustName').autocomplete({
source: #Html.Raw(SqlHelper.getJSONArray("CustName", "dba.BillingInfo"))
});
Try using $.parseJSON.
$(document).ready(function () {
$('#CustName').autocomplete({
//Firefox points to a syntax error here
source: $.parseJSON(#SqlHelper.getJSONArray("CustName", "dba.BillingInfo"))
});
});