How do I render a partial site to another div? - asp.net-mvc-3

I want a view with a table on the site and when you click on a table Item, i want to update a partial view with the current object I just clicked on. How do I manage to do this?
<table>
#foreach (var a in annotations)
{
<tr>
<td>
<label onclick="change stuff to new Annotation">#a.Title</label>
</td>
</tr>
}
</table>
<div id="stuff">#Html.RenderPartial("Go", "new annotation")"</div>

You're mixing client-side and server-side code. By the time the click event occurs, you're on the client and server-side code has run and finished.
You could render the partial view in a hidden div and just unhide it on the click event. Something similar to this, perhaps:
<table>
#foreach (var a in annotations)
{
<tr>
<td>
<label>#a.Title</label>
<div style="display:none;">#Html.RenderPartial("Go", a)</div>
</td>
</tr>
}
</table>
<script type="text/javascript">
$(function () {
$('table tr td label').click(function () {
$(this).closest('td').find('div').show();
});
});
</script>
There may be a more elegant way to find the correct div in the jQuery selectors, you can perhaps add classes and ids to DOM elements as needed to make it cleaner. If you have a lot of these table rows then I'd also recommend using the jQuery .on() function for binding the click event as it would perform better. Something like this:
<script type="text/javascript">
$(function () {
$('body').on('click', 'table tr td label', function () {
$(this).closest('td').find('div').show();
});
});
</script>
This would bind a single click event to the DOM instead of many, with the added bonus that dynamically added rows would still handle the event after the binding takes place.

your getting your client side and server side code mixed up here.
#Html.RenderPartial("Go", a)
is a server side method that returns some HTML.
<label onclick=
Is client side code. So by the time your client gets the data it looks like this:
<label onclick="The text returned from html.render partial">
I think you need to read up on MVC a bit more to achieve what you want as your fundamentally going down the wrong route here.

Related

Knockout Viewmodel binding and Datatable Sorting

I'm using Knockout for data binding and using dataTable+YADCF for Sorting and filtering. My scenario is little complex, on clicking the Category nodes (left side) each time need to make an AJAX call and refresh the table data (right side) through Knockout. This Knockout binding functionality works fine without any issue.
HTML Code
<table class="pdm-data-table pdmList" id="ListCatAttrVal" data-link="row">
<thead>
<tr>
<th>Display Name</th>
<th>Display Source</th>
</tr>
</thead>
<tbody id="listAttribute" data-bind="foreach: attributevalue">
<tr>
<td data-bind="text: dispName"></td>
<td data-bind="text: dispSrc"></td>
</tr>
</table>
Knockout Model Code
if (!ko.dataFor(document.getElementById("listAttribute"))) {
var attributeModel = function () {
this.attributevalue = ko.observableArray();
};
attributeBinding = new attributeModel();
ko.applyBindings(attributeBinding, document.getElementById("listAttribute"));
}
Issue is after applying DataTable for the Table
$("#ListCatAttrVal").dataTable().fnClearTable();
for (var x in response.attributes) {
attributeBinding.attributevalue.push(response.attributes[x]);
}
$("#ListCatAttrVal").dataTable();
After this, Datatable Sorting is not working.
I'm trying to remove the existing generated dataTable and re-initiate it every-time when I click on the category node. But it is not working as expected.
I had a similar issue while working with knockout and datatables - my bindings inside the datatable don't seem to work initially. As a workaround I ended up initialising the datatable in the following way:
var table = $("#ListCatAttrVal").dataTable();
table.fnPageChange(0, true);
After calling fnPageChange (or any other function of datatable library, I believe) bindings seem to be working.

display model contents dynamically in View MVC4

I have a homepage that will display a table with some data for each user. The back-end handles that and I have a list in my model. I am trying to view a dynamic table based on this list and be able to delete elements from without having to hit refresh. I do not know where to start to do something like this. Any help?
Here is what I have so far:
Inside HomePage controller I have an action returning Json representation of the model. Have of 'HpModel' gets set in the login controller and the other is in this one:
public JsonResult GetUserInfo(HomePageModel HpModel)
{
DBOps ops = new DBOps();
HpModel.PhoneDisplay = ops.getDisplayInfo(HpModel.ExtNum);
HpModel.NumberOfLines = HpModel.PhoneDisplay.Count;
return Json(HpModel);
}
In my view I have a javascript to grab this model:
function getInfo() {
alert('here');
$.ajax({
url: '#Url.Action("GetUserInfo", "HomePage")',
data: json,
type: 'POST',
success: function (data) {
alert(data);
}
});
}
I am not sure what is going wrong, and not 100% sure its the way to be done anyway.
Help is appreciated :)
One more idea. You may use jQuery to hide and callback function to $Post to your Delete ActionResult.
For examp: (here I created easy example without $post: jsfiddle)
<script>
$('.delete').click(function()
{
$(this).closest('tr').hide(callback);
function callback() {
$post(/Home/Delete/....
});
</script>
<table>
<tr>
<td>Marry</td>
<td>10 points</td>
<td><a class="delete" href="#">Delete</a></td>
</tr>
<tr>
<td>Jane</td>
<td>8 points</td>
<td><a class="delete" href="#">Delete</a></td>
</tr>
<tr>
<td>Lara</td>
<td>5 points</td>
<td><a class="delete" href="#">Delete</a></td>
</tr>
</table>

Validation of dynamic created form (AngularJS)

I try to made nested form with validation. All works fine, but when I remove one of nested form, validation continue to use removed form. I made jsfiddle example http://jsfiddle.net/sokolov_stas/VAyXu/
When example runs, form are valid. If click "+" button, nested form will be added and valid will be false. Then click "-" button, and valid will be false all the same.
The question is: How to remove dynamic created form from validation processing.
Well, for one thing, a <form> inside of a <form> is not valid HTML.
Second, you're not supposed to be doing DOM manipulation from inside the controller. The controller is for "business" logic. See the section on controllers here
For what you're doing, you'd probably be better off using one form, with an ng-repeat inside of it, and adding additional elements to an array:
<form name="myForm" ng-controller="FormCtrl" ng-submit="doSomething()">
<div ng-repeat="item in items">
<input ng-model="item" type="text" required/>
</div>
<a ng-click="addItem()">+</a>
<a ng-click="removeItem()">-</a>
<button type="submit">Submit</button>
<div>Form valid: {{myForm.$valid}}</div>
</form>
and the controller:
function FormCtrl($scope) {
$scope.items = [];
$scope.addItem = function() {
$scope.items.push(null);
};
$scope.removeItem = function() {
$scope.items.pop();
};
$scope.doSomething = function () {
//your submission stuff goes here.
};
}

Bootstrap popover with knockout.js

I've got an application receiving some data through AJAX-call. After that, received data binds to DOM-elements using knockout.js library. I'd like to use boostrap's unobtrusive markup for creating popovers like this:
<table class="table table-condensed" data-bind="foreach: items">
<tr>
<td><b data-bind="text: $data.id"></b></td>
<td data-bind="text: $data.title"></td>
<td>Info</td>
</tr>
</table>
According to the latest bootstrap documentation, implicit call of something like $('.popover').popover() isn't required, however, it's not working.
I suppose, that boostrap.js perform some DOM-analysis on document.ready and perform all needed work for popover to work. And the question: is there some way to tell bootstrap.js to perform similar job for data after receiving AJAX response? Or how this kind of requirements can be achieved?
You can create custom dataBinding to make that element popover. Check this jsfiddle demo
ko.bindingHandlers.bootstrapPopover = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var options = ko.utils.unwrapObservable(valueAccessor());
var defaultOptions = {};
options = $.extend(true, {}, defaultOptions, options);
$(element).popover(options);
}
};
var viewModel = {
items: ko.observableArray([{
"id": 1,
"title": "title-1",
"info": "info-1"},
{
"id": 2,
"title": "title-2",
"info": "info-2"},
{
"id": 3,
"title": "title-3",
"info": "info-3"}])
}
ko.applyBindings(viewModel);​
And html
<div class="container">
<div class="hero-unit">
<table class="table table-condensed" data-bind="foreach: items">
<tr>
<td><b data-bind="text: $data.id"></b></td>
<td data-bind="text: $data.title"></td>
<td>Info</td>
</tr>
</table>
</div>
</div>​
"According to the latest bootstrap documentation, implicit call of something like $('.popover').popover() isn't required, however, it's not working."
I can't find anywhere in the docs that states that. In fact, they state quite the opposite. Namely, Twitter Bootstrap does not automatically initialize popovers or tooltips on a page. From the docs:
For performance reasons, the Tooltip and Popover data-apis are opt in.
If you would like to use them just specify a selector option.
In order to "opt in", as they say, you would attach the Popover object to an element which contains all the popovers which might appear on the page. Here's one way of doing it:
$('body').popover({selector: '[rel="popover"]'});
I believe the performance considerations originally in mind came from the fact that prior to 2.1, the Popover plugin was by default triggered by mouseenter and mouseleave events, which are certainly not something you want to be constantly processing for an entire page.
Since 2.1, the default is now click, which shouldn't pose any performances issues. Nevertheless, if you can determine an element farther down the DOM than body to which to attach the Popover object, that is always preferred. However, depending on where you are displaying the AJAX content, body might be your best bet.
Here is a complete working example with array of objects, I changed the ko.applyBindings() to ko.applyBindingsToDescendants to include the binding context $root and $parent when we would like to associate a button for example to a function in a root viewModel.
$(element).click(function() {
$(this).popover('toggle');
var thePopover = document.getElementById(attribute.id+"-popover");
childBindingContext = bindingContext.createChildContext(viewModel);
ko.applyBindingsToDescendants(childBindingContext, thePopover);
});
Take a look # http://jsfiddle.net/mounir/Mv3nP/6/

Is it possible to load a partial view by selecting a Radio Button in mvc3

Can i use radio button's to select two different partial view, Without using Jquery?
yes and no. a partial can only be loaded (after initial page load) via ajax, so a partial page refresh isn't possible without using ajax. however, you could submit the selected radio button (via javascript) to the controller action and then determine inside the controller which radio button had been selected. It would then just be a case of selecting the appropriate view.
As I said, you can't go down the partial route without ajax in the mix, so the answer is no. also, you'd still have to use javascript in order to use the radio button in the submit, in which case, an ajax solution might be worth thinking about.
[edit] with deference to Splash-X, here's a quick work up of the hidden div scenario:
#*use either #Html.RenderPartial() or #Html.RenderAction() as required*#
<div id="developerDiv" style="display: none">
This is the developer stuff, in reality,
this would be populated as such #*#Html.RenderPartial("DeveloperPartial")*#
</div>
<div id="testerDiv" style="display: none">
And here we have the testers, again,
this would be populated as such #*#Html.RenderPartial("TestersPartial")*#
</div>
<div>
Developer :#Html.RadioButton("team", "developer", new { onclick = "showResult(this)"})
Tester :#Html.RadioButton("team", "tester", new { onclick = "showResult(this)"})
</div>
<div id="partialContainer"></div>
<script type="text/javascript">
function showResult(radio) {
var selected = radio.value;
if (selected == "developer")
document.getElementById("partialContainer").innerHTML
= document.getElementById("developerDiv").innerHTML;
else if (selected == "tester")
document.getElementById("partialContainer").innerHTML
= document.getElementById("testerDiv").innerHTML;
}
</script>
enjoy..

Resources