How to use Model data in String.Format? - asp.net

I'm trying to display every images in specific folders based on the folder name which equivalent to Model.Id.
#foreach (var imgPath in Directory.GetFiles(Server.MapPath("~/menu/" + Model.Id), "*.jpg"))
{
var img = new FileInfo(imgPath);
<img src="#Url.Content(String.Format("~/menu/449/{0}", img.Name))" />
}
In the last line, 449 is the folder name. How can I use Model.Id to replace 449? I'm not sure how to do that using String.Format

#foreach (var imgPath in Directory.GetFiles(Server.MapPath("~/menu/" + Model.Id), "*.jpg"))
{
var img = new FileInfo(imgPath);
<img src="#Url.Content(String.Format("~/menu/{0}/{1}", Model.Id, img.Name))" />
}
With string.Format you use numeric placeholders that match the position of the parameter included after the string. {0} is the 1st parameter, {1} the second and so on.

Related

Repetitive sublayout - How can I make it unique - to meet ADA requirements

I have a search box that is loaded twice - once for desktop and once for mobile.
Device determines which is displayed. However, due to ADA, the labeling needs to be unique.
Is there a way to call the sublayout and generate unique tag for each of the html elements to use?
Or, is there a way to generate a tag within the sublayout to ensure the tags are unique.
<div id="desktop">
<sc:Sublayout Path="~/site/sublayouts/Shared/QuickSearch.ascx" runat="server" />
</div>
<div id="mobile-search" class="hidden">
<sc:Sublayout Path="~/site/sublayouts/Shared/QuickSearch.ascx" runat="server" />
</div>
----------- within the layout
<div class="searchtool">
<img src="/includes/images/search.png" alt="Search" style="float:left"/>
<div style="float:left">
<fieldset class="search" aria-labelledby="Name">
The alt and aria-labelledby tags need to be unique.
Thanks
Just an idea, pass the device as a parameter and make the label e.g. "search-desktop" or "search-mobile".
See here for details - http://imjo.hn/2012/02/23/passing-properties-into-sitecore-sublayouts/
<sc:Sublayout Path="~/site/sublayouts/Shared/QuickSearch.ascx" runat="server"
Parameters="device=mobile" />
<img src="/includes/images/search.png" alt="Search-<%=GetParameter("device") %>" style="float:left"/>
Here's the helper functions mentioned in that article.
private NameValueCollection _ParameterCollection;
public NameValueCollection ParameterCollection
{
get
{
if (_ParameterCollection == null)
{
_ParameterCollection = new NameValueCollection();
string[] parameters = (Parent as Sublayout).Parameters.Split('&');
string[] pair;
foreach (string paramPair in parameters)
{
pair = paramPair.Split('=');
_ParameterCollection.Add(pair[0], pair[1]);
}
}
return _ParameterCollection;
}
}
public string GetParameter(string key)
{
string value = String.Empty;
string parameterValue = ParameterCollection.Get(key);
if (parameterValue != null)
{
value = parameterValue;
}
return value;
}
I ended up duplicating the sub-layout section - with a new name and changing all the tag elements to reflect different names.

Uploading file AND text to server using Ajax in asp.net mvc

Greeting.
I want to upload an image together with a description to the server by using ajax.
The fileupload works fine, although I can't figure out how to also extract the text entered.
Basically the form looks like this:
<form id="uploader">
<input id="fileInput" type="file" multiple>
<input type="text" id="fileText" name="fileText" value=" " />
<input type="submit" value="Upload file" />
</form>
The script for the upload to the server looks like this:
document.getElementById('uploader').onsubmit = function () {
var formdata = new FormData(); //FormData object
var fileInput = document.getElementById('fileInput');
//Iterating through each files selected in fileInput
for (i = 0; i < fileInput.files.length; i++) {
//Appending each file to FormData object
formdata.append(fileInput.files[i].name, fileInput.files[i]);
}
//Creating an XMLHttpRequest and sending
var xhr = new XMLHttpRequest();
xhr.open('POST', '/Controller/Action');
xhr.send(formdata);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
}
return false;
}
And on the serverside, in the controller for the related action:
public JsonResult Upload(){
for (int i = 0; i < 9; i++){
HttpPostedFileBase file = Request.Files[i]; //Uploaded files
//Do stuff with uploaded files
}
}
What I've tried:
Changed the Upload method to take in a string parameter named fileText.
Changed the script to also appent the text to the formdata with these two lines inside the for-loop:
var fileText = document.getElementById('fileText');
formdata.append(fileText.value, fileText.value)
I'm probably missing something in both of my trials but I can't seem to figure out what. Please help!
Regards,
Chris
Changed the Upload method to take in a string parameter named fileText.
Correct.
Changed the script to also appent the text to the formdata with these two lines inside the for-loop:
Incorrect. You shouldn't be doing this inside the loop because you have only one input field for the text, so you can send only 1 value. So move this code outside of the loop. Also you should specify the correct name when appending to the FormData which must match your controller action parameter name:
var fileText = document.getElementById('fileText');
formdata.append('fileText', fileText.value);

Error in displaying image in HTML file

In my MVC2 application I use CKEditor where I allow the user to create a PDF document.
First the CKEditor content will get converted into HTML file and later as PDF document.
I have provided a button called Arrow on click of it image of an arrow should get inserted. In editor image gets displayed successfully but in HTML and PDF file image is not getting displayed inplace of it alt content gets displayed.
Code for an arrow button:
<input type="button" class="green_button" id="arrow" name="Arrow" value="Arrow" style="width: 110px; height: 30px; background-color: #FFFFFF;" onclick="return arrow_onclick()" />
function arrow_onclick() {
var editor = CKEDITOR.instances.message;
editor.insertHtml(' <input type="image" alt="arrow" src="../../PDFimages/arrow-left-up.jpg" style="height:100px; width:100px" />');
}
Controller code:
public ActionResult CreateFile(FormCollection data)
{
var filename = data["filename"];
var htmlContent = data["content"];
string sFilePath = Server.MapPath(_createdPDF + filename + ".html");
htmlContent = htmlContent.Trim();
if (!System.IO.File.Exists(sFilePath))
{
using (FileStream fs = new FileStream(sFilePath, FileMode.Create))
{
using (StreamWriter w = new StreamWriter(fs, Encoding.UTF8))
{
w.Write(htmlContent);
}
}
string filename1 = Path.GetFileNameWithoutExtension(sFilePath);
string name = Server.MapPath(_createdPDF + filename1 + ".pdf");
HTML2PDF.SetModulePath(#"C:\Documents and Settings\shubham\My Documents\visdatemplatemanger\visdatemplatemanger\bin");
using (PDFDoc doc = new PDFDoc())
{
if (HTML2PDF.Convert(doc, sFilePath))
doc.Save(name, pdftron.SDF.SDFDoc.SaveOptions.e_linearized);
}
System.IO.File.Delete(sFilePath);
UploadURL(name);
}
return View();
}
Before submit your form, you should set textarea value from CkEditor and make your action that accepts the post has this annotation applied [HttpPost, ValidateInput(false)]
$("#content").val(CKEDITOR.instances.message.getData());
And check your src value. Maybe should using:
src="#(Url.Content( "~/PDFimages/arrow-left-up.jpg" ))"
if PDFimages folder included in Project/Content

Right way to retrieve model value in editortemplate

Consider this editor template (even though it doesn't make sense - I have simplified it for clarity):
#Html.TextBox("", null)
This editor template should retrieve the name and the value for the element which it was called for. The name does get set correctly. The value, however, does not.
The data type differs - sometimes it is a double, sometimes it is a string. So I cannot declare a specific data type as the model.
The only way I can make it behave correctly is if I specify the type as dynamic:
#model dynamic
#Html.TextBox("", (string)Convert.ToString(Model))
This seems like a very clumsy syntax, although it works. Have I got it right?
EDIT:
The full code for my editortemplate is a textfield, that can dynamically be calculated by js ajax calls. It works perfectly, and is meant as a general template for any value that can be calculated from the value of other fields. It is not necessarily a string type. However, I need to provide an object for the argument of the Html.TextBox value.
#model dynamic
#{
var CalcClasses = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcClasses")) ? " " + #ViewData.ModelMetadata.AdditionalValues["CalcClasses"] : "";
var CalcUrl = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcUrl")) ? #ViewData.ModelMetadata.AdditionalValues["CalcUrl"] : "";
var CalcDependsOn = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcDependsOn")) ? #ViewData.ModelMetadata.AdditionalValues["CalcDependsOn"] : "";
var CalcTooltip = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcTooltip")) ? #ViewData.ModelMetadata.AdditionalValues["CalcTooltip"] : "";
}
<div class="calculated-field-container input-append">
#Html.TextBox("", (string)Convert.ToString(Model), new
{ #class="calculated-field" + CalcClasses,
data_calc_url = CalcUrl,
data_calc_dependencies = CalcDependsOn
})
<button class="btn button-calculate" data-toggle="tooltip" title="#CalcTooltip">=</button>
</div>
EDIT 2:
Seems this works as well:
#{
var CalcClasses = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcClasses")) ? " " + #ViewData.ModelMetadata.AdditionalValues["CalcClasses"] : "";
var CalcUrl = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcUrl")) ? #ViewData.ModelMetadata.AdditionalValues["CalcUrl"] : "";
var CalcDependsOn = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcDependsOn")) ? #ViewData.ModelMetadata.AdditionalValues["CalcDependsOn"] : "";
var CalcTooltip = (#ViewData.ModelMetadata.AdditionalValues.ContainsKey("CalcTooltip")) ? #ViewData.ModelMetadata.AdditionalValues["CalcTooltip"] : "";
}
<div class="calculated-field-container input-append">
#Html.TextBox("", Model, new
{ #class="calculated-field" + CalcClasses,
data_calc_url = CalcUrl,
data_calc_dependencies = CalcDependsOn
})
<button class="btn button-calculate" data-toggle="tooltip" title="#CalcTooltip">=</button>
</div>

Adding a 'target' attribute to the URL of a tabstrip item in Telerik MVC extensions

I am replacing this 'hand-rolled' tabstrip with the Telerik Extensions Tabstrip below it, but I can't fathom how to get the Tabstrip to include the target attribute in the URL for each item. How can I achieve this?
Before:
<ol>
#foreach (var sheet in Model.Sheets)
{
<li>
#sheet.Name</li>
}
</ol>
After:
#Html.Telerik().TabStrip().Name("Card").BindTo(Model.Sheets, (item, tabInfo) =>
{
item.Text = tabInfo.Name;
item.Url = Url.Content(Server.MapUrl(tabInfo.FilePath));
})
You could use the LinkHtmlAttributes property to set additional html attributes:
item.LinkHtmlAttributes = new Dictionary<string, object>
{
{ "target", "selected-worksheet" }
};
Actually I've never used Telerik, so I am not quite sure if you have to instantiate a new dictionary or simply add a key (in case the property is automatically instantiated):
item.LinkHtmlAttributes["target"] = "selected-worksheet";
I think I had a similar problem with the Telerik TreeView and solved it via a detour with jQuery.
My problem was, that it didn't work to pass any (Link)HtmlAttributes, to the TreeViewItems in the View. I tried to add several HtmlAttributes to the TreeViewItem in the Controller: (e.g. one attribute I wanted to add to the < a > element):
newNodes[i].HtmlAttributes.Add("data-ajax-update","#main");
, but after return as JsonResult of the Ajax-Request, all except .Text, .Value, .Enabled, .LoadOnDemand, .Url were then empty in the View.
I found a sensible answer that these elements are not getting serialized in the Telerik forum:
http://www.telerik.com/community/forums/aspnet-mvc/treeview/target-blank-on-treeviewitem-url.aspx#1548458
I solved it then, with adding a special
<span class="treeViewItemAddAjaxLocation"></span>
element to the .Text of the TreeViewItem. Locating these elements then via jQuery in the View and adding the desired html-attributes to the < a > element.
Telerik TreeView Binding method of the 2nd and 3rd stage elements via Ajax:
.DataBinding(databinding => databinding.Ajax().Select("_AjaxLoading", "Menu"))
Controller snippet in Action "_AjaxLoading":
IList<TreeViewItem> newNodes = new List<TreeViewItem>();
foreach (RevisionEntity revision in revisions)
{
newNodes.Add(new TreeViewItem()
{
Text = "Node Name" + "<span class='treeViewItemAddAjaxLocation'></span>", // name + locator element
Value = revision.ID.ToString() + ";RevisionEntity",
Encoded = false,
Enabled = true,
LoadOnDemand = false,
Url("/Menu/NavigateToRevisionDetails"), // creates an < a > element
});
}
return new JsonResult { Data = newNodes };
View:
<div class="t-bot">
<a class="t-link t-in" href="/Menu/NavigateToRevisionDetails" data-ajax-update="#main" data-ajax-mode="replace" data-ajax-method="GET" data-ajax="true">Node Name
<span class="treeViewItemAddAjaxLocation"></span>
</a>
<input class="t-input" type="hidden" value="774336a5-c6eb-42cc-905a-4d215c957fa2;RevisionEntity" name="itemValue">
</div>
function TreeView_onLoad(e) {
var treeView = $(this).data("tTreeView");
$(".treeViewItemAddAjaxLocation", treeView.element)
.each(function () {
var $this = $(this); // put it in jQuery constr
item = $this.closest(".t-link"); // take the a
item.attr('data-ajax-update', '#main');
item.attr('data-ajax-mode', 'replace');
item.attr('data-ajax-method', 'GET');
item.attr('data-ajax', 'true');
$this.remove(); // removes the span element
});
}
Result TreeView element:
<div class="t-bot">
<a class="t-link t-in" href="/Menu/NavigateToRevisionDetails" data-ajax-update="#main" data-ajax-mode="replace" data-ajax-method="GET" data-ajax="true">Node Name</a>
<input class="t-input" type="hidden" value="774336a5-c6eb-42cc-905a-4d215c957fa2;RevisionEntity" name="itemValue">
</div>
Loads the PartialView invoked through "NavigateToRevisionDetails" Action via Ajax in the #main html-element and the rest of the page doesn't get refreshed!

Resources