Is it possible to loop through list of models and update displayed data in view without refreshing the page or making ajax call to server?
Scenario:
Model:
public SomeModel
{
public int Id { get; set; }
public string LinkName { get; set; }
public string ItemDecsiption { get; set; }
public string Text { get; set; }
}
List of SomeModel objects is inicialized, filled with data and passed to View in controller ActionResult. I can see all data in view (i am able to loop through individual models and create list from SomeModel.LinkName property.
<ul>
<% foreach (SomeNamespace.SomeModel m in Model)
{ %>
<li class="green"><%= m.LinkName %></li>
<% } %>
</ul>
What I want to do is to divide page content section into two parts-one with menu (consisting of links created from every LinkName in Model) and second containing block with description and text (for id currently clicked in menu). Now comes the trick part. I want to be able to change displayed data in second block after clicking Link in menu without refreshing the page or making ajax call to server (since all the data I need is already available to client side). Only solution I could think of is to generate hidden blocks for every SomeModel object and then write jquery to manipulate visibility after link click. What I want to know is if there is some more elegant way to accomplish this.
Project is written in C#.NET 3.5 ASP.NET MVC 2.0
The only way to do this would be to use JavaScript to manipulate the DOM.
Depending on the markup which you'll produce, hidden html blocks may be the most elegant solution of all. Like, for intance, if you switch visibility by simply changing a class of block which should be visible without changing the DOM.
The other option will be to prepare json object from Model and use it as data source for visible markup. But this may lead to raise of complexity which is not necessary in most of the cases.
there is another way.
1.var data=#Model.ToJson() in js; there is not a ToJson function ,that just what you need to do
2.only one content block
3.when click menu,find element in data,and set block content use js
Related
Is there some way in Sitecore 7 when using MVC to create a controller which can return a PartialView result using the rendering defined on the item (or its template standard values), without having to set up Layout and Renderings for that item?
I can see how to do this using custom template fields, but this seems like a hacky way of doing things. Is there a better way to achieve the following:
public PartialViewResult MyAction(string someParameter)
{
Item selectedItem;
//some code here to retrieve sitecore item based on the value of someParameter
var cshtmlFilePath = selectedItem["MyCustomField"];
return PartialView(cshtmlFilePath, selectedItem);
}
FYI my cshtml could be something really simple like:
#model Sitecore.Data.Items.Item
<div>
<h3>
#Html.Sitecore().Field("Title", Model)
</h3>
<div>
#Html.Sitecore().Field("Content", Model)
</div>
</div>
While the approach above will work, I don't like it because there is not a proper interface for assigning the rendering to the item's template's standard values. I could easily define my own presentation template which has a single 'Path' field, then create items somewhere under `sitecore/layout/Renderings' then reference that item in a link field of my content item, but it just seems like that should be doable out of the box.
I'm not sure I fully understand the intent here, so this may only be a partial answer, but seeing as you want to render an item based on layout information contained within the item itself, would Item Renderings be able to help?
Here's the info: http://www.sitecore.net/Community/Technical-Blogs/John-West-Sitecore-Blog/Posts/2012/06/MVC-Item-Renderings-in-the-Sitecore-ASPNET-CMS.aspx
I realize returning a partial view would be a little more flexible than the Item Rendering route, but in the normal scenario (i.e. adding a callout to a page) it seems like this method might work.
One solution is to simply assign a layout (which references a cshtml file) to the item, then use item.Visualization to get the file path to the layout assigned to the item and use that layout's cshtml file in the call to PartialView.
public PartialViewResult MyAction(string contentItem)
{
Item selectedItem;
//retrieve sitecore item
string layoutPath = selectedItem.Visualization.Layout.FilePath;
return PartialView(layoutPath, modalContentItem);
}
I have two DropDownList elements in my model.
[DisplayName("Site")]
public List<KeyValuePair<int, string>> Site { get; set; }
public int SelectedSiteID { get; set; }
<%= Html.DropDownListFor(model => model.SelectedSiteID, new SelectList(Model.Site, "Key", "Value"))%>
[DisplayName("Data Center")]
public List<KeyValuePair<int, string>> DataCenter { get; set; }
public int SelectedDataCenterID { get; set; }
<%= Html.DropDownListFor(model => model.SelectedDataCenterID, new SelectList(Model.DataCenter, "Key", "Value"))%>
I am attempting to modify the collection of ListItem's in my second DropDownList when the user makes a change to the first's selection.
I think that this is possible in the following manner, but I wanted to confirm that this was good practice:
Using jQuery, bind to the first DropDownList's change event.
When responding to the change event -- send an AJAX request to the server with the newly selected value.
The server will respond with JSON representing a collection of ListItem objects for the second DropDownList.
Using jQuery, I modify the second DropDownList's selection such that it contains the returned JSON elements.
This all seems a bit... non-MVC3y, if you will. Is this the standard way of achieving what I am asking, or is there a more clear way?
I think it would be best to use Jquery in this scenario.
The best thing for you to do is bind the firstDropdown box to a OnChange event inside Jquery then using $.ajax load the data from JSONresult in your Controller. Once that data has been loaded load the data inside the secondDropdown.
Let me know if you need some code help with this.
I use the jQuery Cascade Select plugin to do this for me. It's easy to plug in and doesn't require you to re-invent the wheel. http://code.google.com/p/jquery-cascade/
I have a grid with the following object:
public PagedList<GridList> PagedList { get; set; }
public class GridList
{
public Employee EmployeeItem { get; set; }
public bool isChecked { get; set; }
}
My aspx implemented the table inside a loop and then I put a checkbox for each Employee:
<%foreach (var item in Model.PagedList )
{%>
<tr>
<td align="center">
<%: Html.CheckBox(item.EmployeeItem.ID.ToString(), item.isChecked)%>
</td>
</tr>
<% }%>
I need to keep all the checkboxes selected when the user change the page. So, if he selects 2 or 3 options of a page an then change the page number, when he come back to this page, the same checks should be marked.
I tried many solutions but I wont comment them here just to expect a better one. All the orders I tryed I had problems that I cannot solve.
When the user click to got to another page, the code goes to the [HttpGet] method.
Thanks for the help.
You will have to somehow send the checked values to the server when performing pagination or you will loose them. You have a couple of possibilities:
Put the checkboxes inside an HTML form alongside with the pager and make the pager links submit buttons of this form.
Use AJAX to perform the pagination and refresh only the grid portion of the DOM and do not touch at the checkboxes. This way they will preserve their values.
Subscribe to the onclick event of the pager links and inside cancel the default action (evt.preventDefault()), harvest the values of the checkboxes and append them to the query string of the url that will perform the pagination. Then redirect to this new url.
What's the best way to approach the following situation in asp.net mvc2 (c#):
I have a form where a user can add more fields ... for example I ask user the details of personal computing devices that they have. For simplicity sake let's say I ask for the brand and type (dropdown list of Desktop/Laptop/Tablet/Other) and they can provide unlimited devices. I will start with a pair of text boxes:
<label>Type</label>
<select><option>Desktop</option><option>Laptop</option><option>Tablet</option><option>Other</option></select>
<label>Brand</label>
<input type="text" />
<input type="button" value="Add more device" />
And then as user click the "Add more device" button I will display another pair of Brand and Type text boxes ... and so on.
My question is how should I use HTML helper for this, how I construct the viewModel, etc.
I am from PHP background and I used to use the following in PHP:
<input type="text" name="brand[]" />
which on the back end will give me an array of brands ... not sure if that's doable in asp.net environment. I would appreciate any input. Thank you.
[I added the following lines to make my question clearer]
I think I have not been very clear with my question.
Suppose I have the following viewmodel:
public class UserRegisterViewModel
{
public string DeviceBrand { get; set; }
public string DeviceType { get; set; }
}
That works well when I have two text boxes:
<%: Html.TextBoxFor(m => m.DeviceBrand) %>
<%: Html.TextBoxFor(m => m.DeviceType) %>
but the situation that I am facing is I need to allow user to add more pair of device brand and type text boxes ... user should be able to add as many as he needs to.
How should I write my viewmodel and view?
I hope this makes my question a bit clearer. I don't have problem in hiding and showing the text boxes (and yes I use JQuery for that).
Thank you.
In C#, like C++ arrays are fixed sizes. You can however use a List<> to do something similar. It allows you to dynamically add data with an add function. Like so:
List<object> name = new List<object>();
name.Add(an_object);
So say a list of strings:
List<string> myStrings == new List<string>();
myStrings.Add("Blah");
They're accessed just like arrays - Console.WriteLine(myStrings[0]) outputs Blah
Depending on scenarion there are following solutions:
If you already know which Textboxes will be shown add them in your page and set their visiblity to false (like in CSS "display:none") And show them later.
If you dont know in advance which textboxes will be shown you can still append them in HTML DOm (Add it to your page's controls collection)
To show them there are two apporaches:
In first case Either use jQuery or Javascript to show them back.
In first case Use can also do it from server side that will result in whole page post back.
In second Apporach Also you can use jQuery or Javascript to add new textboxes in the form
In second case you can add new boxes from your C# code on server but again it will result in whole page post back.
Use any approach that best suits you
What you can do is having UserRegister as Model and have UserRegisterViewModel
whith List property
Then in your view you can have loop to render your viewmodel list property
in a foreach for example in C#
Lets say you have your ViewModel defined as:
public class BrandListViewModel
{
public List<UserRegisterViewModel> Brands {get;set;}
}
Your View would need to output HTML as:
<select name="Brands[0].DeviceType">...</select>
<input type="text" name="Brands[0].DeviceBrand"/>
and
<select name="Brands[1].DeviceType">...</select>
<input type="text" name="Brands[1].DeviceBrand"/>
You need to keep the index going so that the model binder can construct your list in the correct order. Now, you could use jQuery to do this and as you append items to the page just get a count and increment by one. If you want to remove a single one, you need to rename all of the fields.
You could also use a pure jQuery method, parse the elements, push items to an array and send the array to the server.
I have written a user control that contains a text box and a button. Functionality is such that you input a QuoteID into the textbox and click the button then the app goes and fetches a bunch of information about the specified quote and plops it onto the screen.
My employer wants this to be modified to be only a button which will reside on the page that displays the order normally. So, obviously on this page we have access to the QuoteID. However, since the text-box is no longer part of the control I'm not sure how to get to the ID.
Is there any way to pass information into a custom control? Perhaps a way to set up the HTML so that the control knows what ID it will be searching for if clicked?
We are not using MVC.
You can add a public property to the user control for the QuoteID and set it whenever you know what it is.
Example:
//code behind of your user control
class SpecialUserControl: UserControl
{
//this property is now accessible outside this user control
public int QuoteID { get; set; }
}
You could always save the ID as a query string in the url, then retrieve it in the code behind file. It should then be accessible from the HTML. This would depend on how sensitive the ID was though, as it would be viewable in the address bar.
string ID = Request.QueryString[1];
That would help with the extraction process, and from there simply pass the ID to wherever its needed in the code behind file.
A public property in the user control is the way to go.
public string QuoteID { get; set; }
You can assign it from the page, or from the code behind.
<uc1:QuoteControl id="QuoteControl1" runat="server" QuoteID="myquoteid" />
or
QuoteControl1.QuoteID = "myquoteid";
Just add a propert in the user control:
public string MyQuote
{
get
{
return txtQuote.Text;
}
set
{
txtQuote.Text = value;
}
}
Then you can access it from your page as:
<uc1:Quote id="QuoteUserControl" runat="server" />
string quote = QuoteUserControl.MyQuote;
asp:HiddenField controls might work out for you here.
In your page load method, you can pass the property to the user control - something like this example (where we set a hidden label to be the quote id for use when you press the button...)
Control c = LoadControl("QuoteSearch.ascx");
Label hiddenLabel = (Label)c.FindControl("HiddenQuoteIdLabelOrWhatever");
hiddenLabel .Text = "32415";
Although, you have to ask yourself whether a user control is really any use at this stage as it doesn't sound like the nice re-usable, stand-alone quote search box that you originally designed.