Create a link within Textarea of CSHTML page in MVC - asp.net-mvc

In CSHTML page, I am displaying text using #Html.TextArea. Now I need to create one link within that text. Is that possible to create a link within TextArea?
If it is not possible, what kind of control I can use to display text with link? Any suggestion please.
Ex:
#Html.TextArea("MsgTxtBox","Messagewithlinkhere",new { readOnly = true, id = "MsgTxtBox" })

Yes it is possible but you would have to use some javascript and provided there is only one link in the text. Add a javascript onclick event function to the textbox:
#Html.TextArea("MsgTxtBox","Messagewithlinkhere",new { readOnly = true, id = "MsgTxtBox", onclick="redirectToUrl()" })
Now make sure the links in the text are surrounded by a character like [link], so you can separate them from the text. Lets say the value of the text is "Hello [https://www.google.com] World"
Now add the following javascript on top: We would take the index of the first [ character and then the second one ], and use a substring method to get the string in between. See link, then use window.location to redirect to that link.
<script type="text/javascript">
function redirectToUrl() {
var text = document.getElementById("MsgTxtBox").value;
var start = text.indexOf('[') + 1;
var end = text.indexOf(']', start);
var link = text.substring(start, end)
window.location = link;
}
</script>

Related

localization of items and groups in vis.js timeline

We used vis.js to create a timeline , We need to localize the name of groups and the content of items with different languages . we tried to use the $translate = $filter('translate') to translate the name of group in angularjs but it works only when we reloading the screen . We also tried for the translation of items to use the template handlebars engine to translate the items but The problem is that Angular seems not to proceed the templates used by Handlebars when we put "{{ 'timeline.content' | translate }} it gives an error . so is there any idea or a way to localize name of groups and items in vis.js .
You can use the configuration functions groupTemplate or template
var config = {
...
groupTemplate: function (group) {
var groupTemplate = document.createElement('div');
// assuming that you have stored the label key in the content, instead of text.
groupTemplate.innerText = translate.get(group.content);
// or whatever function call you need to make to get the translated label;
return groupTemplate;
}
...
}
You can do the same with the actual items in the timeline.
var config = {
...
template: function (item) {
var itemTemplate = document.createElement('div');
// assuming that you have stored the labels in the content, instead of text.
itemTemplate.innerText = translate.get(item.content)
// or whatever function call you need to make to get the translated label;
return itemTemplate;
}
...
}
You can also attach event listeners, or do whatever with templates as they render to a usual DOM elements.
Hope this helps.

Updating list in view Asp.net mvc razor

I have 2 lists in a view. What I want to do is that pick elements from list1 and update list2 with selected elements everytime I pick one. I tried to use PartialView (I don't know if it's correct approach or not) but I failed. I have a function in controller that fills a list by selected items. What needs to be done is updating the view dynamically. Can you suggest me a roadmap for this?
Update
I forgot to say that I have done this with javascript. But I feel like it's the long way when it comes to some validations (checking duplications etc.)
$(document).ready(function (){
$("#allPlayersList a").on("click", function () {
var options = $(this).clone();
$("#thisWeekList").append(options);
});
});
Just create an html list. See if this link helps. https://codepen.io/alexander-holman/pen/QNQrvz. You can also populate the values from database
Then you can get the selected element by javascript like this
var input = document.getElementById('Something').value;
Update after edited question
You can try something like
var listSelection = document.getElementById('Something').value;
Now you can create an api in the backend which accepts this value and returns a list based on it. Call that Api like this
&.ajax({
url: //url of api
data: {exactNameOfApiParameter : listSelection },
success: function(data){
for (i = 0; i < data.length; i++) {
$('<li>', { text: data[i] }).appendTo($('#list2'));
}
}
})
Make sure that id of second list is list2.

jQuery disable submit button if text box contains these variables

How I can strip out the variables listed below from within a textbox (input) that if a user tries to type a URL i.e these variables:
"http://"
"www."
".com"
".co.uk"
If any of the variables above exist in the textbox on keyup the submit button gets disabled or/and it removes/strips out the variables above.
Is this possible? I've tried doing it using Charcodes, but I face the problem that I would like the user to still use '.; (full-stops) etc
Can somebody help?
Thanks,
Here you go!
Demo
$("#myinput").keyup(function()
{
var a = ["http://", "www.", ".com", ".co.uk"]; //Add the substrings
a.forEach(function(k)
{
if($("#myinput").attr("value").indexOf(k) > -1)
{
alert('Found!'); //Do something
return true;
}
else
{
return false;
}
});
});
Every time the user types a char, it checks for the string in array a. If the substring is found, it popups an alert message.
Using blur it will check for the string only when the user go outs of the input box (its more efficient using blur, but you can use this way if you want to check few strings and the input value is not too long).
Try this,
$("#textboxId").blur(function (event) {
var text = event.target.val();
if(text.contains("www")) {
$("submitBtnId").prop('disabled', true);
}
});

How to retain data (form) on custom pagination using MVC?

I have a grid (list generated using scaffolding option) with search criteria. And I created paging concept. I entered search criteria data and search, after post back, I retained the form data using TempData. But, if I click page numbers in grid, the form data not retained and also the grid also getting refreshed.
Is there any way to retain data on pagination?
Thanks!
I added a hidden field dynamically within the form using JavaScript. The page number stored in hidden field, when the user click page number, then submit the form. It is working well without any issue.
Paging:
<button onclick="navigateTo(this, '#Url.RouteUrl("Defined_Route", new { currentPage = j })');">#j</button>
Javascript:
$(function () { //Page Load - Create hidden field, if search button found
if ($("#search")) // Button id
{
var element = document.createElement("input");
element.type = "hidden";
element.id = "currentPage";
element.name = "currentPage";
element.value = '#TempData["Page"]';
if (isNaN(element.value)) element.value = "1";
$(to).parent().append(element);
}
});
function navigateTo(field, url)
{
$("#currentPage").val(field.innerText);
if (isNaN($("#currentPage").val()))
{
location.href = url;//This is for direct url, ie. no search form
}
else
{
$("form").action = url;
$("form").submit();
}
}

Sanitizing Input with JsonConvert.SerializeObject in MVC4?

Long story short, I'm trying to get the output from JsonConvert.SerializeObject to be sanitized without having to modify the contents of the saved data.
I'm working on an app that has the following markup in the view:
<textarea data-bind="value: aboutMe"></textarea>
If I save the following text, I run into problems:
<script type="text/javascript">alert("hey")</script>
The error I get in FF:
The relevant part of the offending rendered text:
$(document).ready(ko.applyBindings(new
MyProfileVm({"profileUsername":"admin","username":"Admin","aboutMe":"alert(\"hey\")","title":"Here's a
short self-bio!
:)","thumbnail":"https://i.imgur.com/H1HYxU9.jpg","locationZip":"22182","locationName":"Vienna,
VA"
And finally - at the bottom of my view:
<script type="text/javascript">
$(document).ready(ko.applyBindings(new MyProfileVm(#Html.Raw(JsonConvert.SerializeObject(Model, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() })))));
</script>
Here, I'm passing the model that I get from the MVC controller into the js ViewModel for knockout to map into observable data. The Raw encoding seems to be the problem, but I'm not sure how to go about handling it.
To be clear, I'm getting data from the server, and outputting it to the client, which is mucking up the JSON/KO combo.
The problems is that you cannot have a closing </script> tag inside a JavaScript string literal because the browser interprets it as then end of the script block. See also: Script tag in JavaScript string
There is no builtin function in Asp.Net what could handle it on the server side you before outputting your generated script you need to replace the </script> to something else:
<script type="text/javascript">
$(document).ready(ko.applyBindings(new MyProfileVm(#Html.Raw(
JsonConvert.SerializeObject(Model,
new JsonSerializerSettings() {
ContractResolver = new CamelCasePropertyNamesContractResolver()
}).Replace("</script>", "</scripttag>")
))));
</script>
Of course if you will need this in multiple place you can move this logic into a helper/extension method, like:
public static class JavaScriptExtensions
{
public static string SerializeAndEscapeScriptTags(this object model)
{
return JsonConvert.SerializeObject(model,
new JsonSerializerSettings()
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
}).Replace("</script>", "</scripttag>");
}
}
And use it with:
#using YourExtensionMethodsNamespace
<script type="text/javascript">
$(document).ready(ko.applyBindings(new MyProfileVm(#Html.Raw(
Model.SerializeAndEscapeScriptTags()))));
</script>
And on the JavaScript side in your Knockout viewmodel you need to replace back the </script> tag before the usage:
var MyProfileVm = function(data) {
//...
this.aboutMe = ko.observable(
// you need `"</scr"+ "ipt>"` because of the above mentioned problem.
data.aboutMe.replace(/<\/scripttag>/g, "</scr"+ "ipt>"));
}
Of course you can also create a helper function for this, like:
function fixScriptTags(data) {
for(var prop in data) {
if (typeof(data[prop]) == "string") {
data[prop] = data[prop].replace(/<\/scripttag>/g, "</scr"+ "ipt>");
}
//todo check for complex property values and call fixScriptTags recursively
}
return data;
}
And use it with:
ko.applyBindings(new ViewModel(fixScriptTags(data)));
Demo JSFiddle.
I've had a similar problem, it came from using knockout.js to get input from a <textarea> just like you did. Everything was fine on the "create" part, but once I put the data back into an action via #Html.Raw(...), it turned out to contain linefeed and carriage-return characters that broke the json string.
So I added something like this:
// Regex to replace all unescaped (single) backslashes in a string
private static Regex _regex = new Regex(#"(?<!\\)\\(?!\\)", RegexOptions.Compiled);
(I know it doesn't handle "\\\", but that doesn't appear from knockout)
Then I build my anonymous classes and do this:
var coJson = JsonHelper.Serialize(co);
var coJsonEsc = _regex.Replace(coJson, #"\\")
Maybe this can help you. I found it by breaking in the razor view and looking at the strings.
This problem also appears with unesacped tabs (\t) and possibly other escape sequences.

Resources