Im trying to pass some table data to its child vuestrap Modal component. The modal will be reused by all the Td's where the checkbox is calling the modal.
<div id="ordertbl" class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
...
</tr>
</thead>
<tbody>
<tr v-repeat="slides">
<td>#{ {NAME}}</td>
<td>#{ {MESSAGE}}</td>
<td> <input type="checkbox" v-on="click:showMod = true" v-model="published" > </td>
</tr>
</tbody>
</table>
<modal title="Modal" show="#{{#showMod}}" effect="fade" width="400">
<div class="modal-body">You will publish NAME, MESSAGE</div>
</modal>
</div>
when the checkbox is clicked. As you can see every row in the table has one checkbox so the data to be passed to the Modal will be unique to its row.
As Im new to Vue, besides Im trying to use Vuestrap to not reinvent things,
I dont know how to give that Data to the Modal when it pops.
new Vue({
el:'#ordertbl',
components: {
'modal':VueStrap.modal
},
data: {
showMod: false,
sortKey: '',
reverse:false,
slides: {
id: '',
name: '',
message: '',
published: ''
}
},
Basically I want to do the following
$('#exampleModal').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget) // Button that triggered the modal
var recipient = button.data('whatever') // Extract info from data-* attributes
// If necessary, you could initiate an AJAX request here (and then do the updating in a callback).
// Update the modal's content. We'll use jQuery here, but you could use a data binding library or other methods instead.
var modal = $(this)
modal.find('.modal-title').text('New message to ' + recipient)
modal.find('.modal-body input').val(recipient)
})
Pass the related data to the Modal, but with Vuestrap
You can use v-for="slide in slides". So every tr can get one of the slide object. Then you can pass it as a props to modal.
Extra ajax request is not required.
I manage to solve it with an ajax request depending on the Id clicked.
Related
EDIT:
Here is the exact problem that I have demonstrate, please have a look and as soon as I click the submit button it post back and lost its state and as you can see in the sample code I have three pages I'm posting the form
1) EmployeeForm, 2) EmployerForm, 3) ContractorForm
https://dotnetfiddle.net/wVtwgW
How do I persist the checkbox?
Once I post the page and it reloads the same page if I have my data-model invalid and it display the error message on the screen but the problem is that, it hides the fieldset and the user has to click the checkbox again to show the fieldset.
my question is: how can I still show the fieldset and show the error message in it?
//my scripts that shows the fieldset
<script>
$(document).ready(function() {
$('#Employee').change(function() {
if (this.checked) {
$('#emp').show();
}
});
});
</script>
//it shows the fieldset with checkbox:
<fieldset class="fieldset-auto-width">
<legend>
Select Employee
</legend>
<table width="auto">
<tr>
<th>
Employee
</th>
<td>
#Html.CheckBox("Employee")
</td>
</tr>
</table>
</fieldset>
//my form where I have all the input text and button etc...
<fieldset id="emp" style="display: none" class="fieldset-auto-width">
<legend>
Employee Display
</legend>
#using (Html.BeginForm("EmployeeServer", "EmployeeForm", FormMethod.Post))
{
#Html.ValidationSummary(true)
<div>..... </div>
}
</fieldset>
Instead of using #Html.CheckBox() use #Html.CheckBoxFor()
<td>
#Html.CheckBoxFor(m => m.Employee)
</td>
this will retain the state of the checkbox when you return the model state errors..
in your javascript, just call the $("#Employee") change event after the page loads..
$(document).ready(function() {
$('#Employee').change(function() {
if (this.checked) {
$('#emp').show();
}
});
$('#Employee').trigger("change");
});
Set the Fieldset display value when view is rendered
<fieldset id="emp" style="#(Model.Employee ? "": "display: none")" class="fieldset-auto-width">
<legend>
Employee Display
</legend>
#using (Html.BeginForm("EmployeeServer", "EmployeeForm", FormMethod.Post))
{
#Html.ValidationSummary(true)
<div>..... </div>
}
</fieldset>
this will hide the fieldset if Model.Employee = false or display it if Model.Employee = true.
Just do it with JavaScript. Look for the rendered element from the validation summary helper, and if it exists then you can show your employee form. You can add it to your already executing script like this:
$(document).ready(function() {
$('#Employee').change(function() {
if (this.checked) {
$('#emp').show();
}
});
//check for validation summary elements
if($('.validation-summary-errors').length > 0){
//and show previous entry if present
$('#emp').show();
}
});
I am new to knockoutJS. I am working on an MVC application where I want to implement knockoutJS but the scenario is bit different.
I have a page where I am showing a list. I have 3 links on the page and on click of them I am adding partial views to page accordingly. What I want to do is that whenever I add values/data to partial views, the list which is on page should be updated with knockout. In other words I want to add value to observable array when I save data from partial view.
Please let me know if this is possible or I should keep it in jquery only.
Here is the code:
Main view:
<input type="button" value="Add Partial View" onclick="LoadPartial();" />
<div id="dvContent"></div>
<h4>People</h4>
<ul data-bind="foreach: people">
<li>
Name at position <span data-bind="text: $index"> </span>:
<span data-bind="text: name"> </span>
Remove
</li>
</ul>
<button data-bind="click: addPerson">Add</button>
<script src="~/Scripts/jquery-1.7.1.js"></script>
<script src="~/Scripts/knockout-2.1.0.js"></script>
<script>
function LoadPartial() {
$.ajax({
url: "/home/index",
dataType:"html",
type: "GET",
success: function (data) {
$("#dvContent").html(data);
}
});
}
</script>
<script>
function AppViewModel() {
var self = this;
self.people = ko.observableArray([
{ name: 'Bert' },
{ name: 'Charles' },
{ name: 'Denise' }
]);
self.addPerson = function () {
self.people.push({ name: "New at " + new Date() });
};
self.removePerson = function () {
self.people.remove(this);
}
}
ko.applyBindings(new AppViewModel());
</script>
Partial View:
<table>
<tr>
<td>Add new Row</td>
<td><input type="button" value="Add" data-bind="click: addPerson"/></td>
</tr>
</table>
Thanks,
JsHunjan
It is easy to accomplish with Knockout. You need to show some code that you have tried though if you want to get some help. I will post a general answer but it isn't going to fix your use case exactly, just basically -
Create an object to hold your new item, you can do this either in the parent or the child view model, but if you do it in the child you need to pass it back to the parent.
Once you hit a save button or add or whatever in the child view model just do a .push() into the observableArray that you created ex... - myObservableArray.push(newItem());
Knockout will recognize all of the changes taking place and perform the actions you want automatically.
Hope this helps.
I'm going to use a grid view. it contains a check box per row.
its for deleting row. for example when user checked some checkbooks and click on delete button checked rows have to delete.
Now How can I give checked rows ID's in my action ?
Do you have any ideas ?
Thanks.
OK. We assume that you want to retrieve a list of products and show them in a raw html grid.
First of all, arrange your view like this:
#model IEnumerable<MyPrj.Product>
// ... Other codes ...
<table id="tblGrid">
<tr>
<th>Delete</th>
<th>ProductName</th>
// ... Other Properties ...
</tr>
#foreach(var item in Model)
{
<tr id="tr#(item.ProductID)">
<td>
#Html.Raw("<input type='checkbox' id='chk#(item.ProductID)' onclick='chkChange(#chkID)' />");
</td>
<td>#item.ProductName</td>
// ... Other Properties ...
</tr>
}
</table>
<input type="button" id="btnDelete" value="Delete Selected Rows" onclick="performDelete()"/>
Now, you have your view and it will render the grid for you with the supplied model. Then, you need to add some javascript and jquery codes to perform the row deletion for you.
A function to handle checkbox clicks:
<script>
function chkChange(id) {
if ($(id).val() != 'false')
$(id).val('false');
else
$(id).val('true');
}
// ...
</script>
And finally, a function to handle delete button clicks:
function performDelete() {
var rows = $("input:checked");
rows.each(function () {
$(this).parent().parent().remove();
});
}
That's it! - you're done. The complete <script> blog is like the following:
<script>
function chkChange(id) {
if ($(id).val() != 'false')
$(id).val('false');
else
$(id).val('true');
}
function performDelete() {
var rows = $("input:checked");
rows.each(function () {
$(this).parent().parent().remove();
});
}
</script>
You could place the grid along with its checkboxes inside an HTML form and make the Delete button as submit button for this form. Then when the button is clicked, the form will be submitted and the values of the selected checkboxes will be sent to the controller action so that you could delete the corresponding records.
UPDATE: The third bullet below ("so I tried the following" section) is the closest I have come to a fix. I think I basically need to 1) disable the button, 2) add ui-disable, 3) jqm refresh, all within the data-bind or model.
I am trying to get one of the knockout demos to run with jqm in order to build something similar in my project. It mostly works except that the submit button does not disable goes disabled but does not appear grayed out if items = 0.
If you remove jqm, the example works fine and the button turns gray. I realize that jqm can conflict with knockout due to dom manipulation so I tried the following:
Triggering style refresh in the model methods: $('button').button(); or $('.ui-page-active' ).page( 'destroy' ).page();
Starting the binding after pageinit. This broke the entire thing.
As a test, I tried a data-bind to set ui-disable instead of disabling the button. It applies the class but jqm needs a refresh somehow. Can I put code into the data-bind to do the refresh?
<button data-bind="css: {'ui-disable': gifts().length > 0}" type='submit'>Submit</button>
Here is the fiddle I have been using to troubleshoot this: http://jsfiddle.net/wtjones/wkEgn/
What am I missing?
<form action='/someServerSideHandler'>
<p>You have asked for <span data-bind='text: gifts().length'> </span> gift(s)</p>
<table data-bind='visible: gifts().length > 0'>
<thead>
<tr>
<th>Gift name</th>
<th>Price</th>
<th />
</tr>
</thead>
<tbody data-bind='foreach: gifts'>
<tr>
<td><input class='required' data-bind='value: name, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: price, uniqueName: true' /></td>
<td><a href='#' data-bind='click: $root.removeGift'>Delete</a></td>
</tr>
</tbody>
</table>
<button data-bind='click: addGift'>Add Gift</button>
<button data-bind='enable: gifts().length > 0' type='submit'>Submit</button>
</form>
The model code:
var GiftModel = function(gifts) {
var self = this;
self.gifts = ko.observableArray(gifts);
self.addGift = function() {
self.gifts.push({
name: "",
price: ""
});
};
self.removeGift = function(gift) {
self.gifts.remove(gift);
};
self.save = function(form) {
alert("Could now transmit to server: " + ko.utils.stringifyJson(self.gifts));
// To actually transmit to server as a regular form post, write this: ko.utils.postJson($("form")[0], self.gifts);
};
};
var viewModel = new GiftModel([
{ name: "Tall Hat", price: "39.95"},
{ name: "Long Cloak", price: "120.00"}
]);
ko.applyBindings(viewModel);
// Activate jQuery Validation
//$("form").validate({ submitHandler: viewModel.save });
Yep. If you change button properties via JS (or using KO to change these props), then you must call the refresh method to update visual styling.
$('button').button('refresh');
So I suggest to create custom binding instead of default enable that updates mobile button styling (if applied):
ko.bindingHandlers.mobileEnable = {
update: function(el) {
ko.bindingHandlers.enable.update.apply(el, arguments);
$.fn.button && $(el).button('refresh');
}
}
and...
<button data-bind='mobileEnable: gifts().length > 0' type='submit'>Submit</button>
Corrected fiddle: http://jsfiddle.net/wkEgn/2/
I have 3 user controls in an aspx page in my MVC application.
i bind data from DB from one controller.
on the selection of "Filter / Status" i want to bind data (refresh) to "List" user control with out refreshing "Filter & Status" user controls.
below are my user controls in aspx page.
please help me how to refresh part of the page/user control.
i have tried by returning only "ListView" View data. but its searching for the other 2 views & throwing exception.
<td>
<%Html.RenderPartial("Filter", ViewData["FilterView"]); %>
</td>
<td valign="top" width="15%">
<%Html.RenderPartial("Status", this.ViewData["StatusView"]); %>
</td>
<td valign="top" width="85%">
<%Html.RenderPartial("List", this.ViewData["ListingView"]); %>
</td>
do sth like this
html (aspx page):
<div id="ListingView">
<%Html.RenderPartial("List", this.ViewData["ListingView"]); %>
</div>
...
<input type="button" id="refreshListingView" />
javascript to handle it:
$('#refreshListingView').click(function () {
var selectedStatusId = 'get here proper status id';
$.ajax({
url: '/YourController/GetListingView',
type: "GET",
data: { "statusId": selectedStatusId },
success: function (response) {
$('#ListingView').html(response);
}
});
});
YourController:
[HttpGet]
public ActionResult GetListingView(int statusId)
{
ViewData["ListingView"] = your data filtered by statusId or what you want;
return PartialView("List",ViewData["ListingView"]);
}
Instead of ViewData["ListingView"] I would use dedicated model, but it's just an example. It should work.