How can I use input in grid view? - asp.net-mvc

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.

Related

how to disabled asp-action link after one click

i would like to disabled asp=action link after one click
i have a foreach loop to display my book in table in my view
my asp-action for add book in the cart is in the loop but i want to disabled just the book who already in the cart not all books
<a asp-action="AcheterLivre" asp-Controller="Achat" asp-route-id="#item.Isbn" id="disabled" onclick="return myFunction(this);"> Ajouter
i try something with jquery but its dont work well
i tried this
<script>
function myFunction() {
$("#disabled").one("click", function () {
alert("this book is already in the cart");
});
}
i have this function in my class
its verify if the books is in the cart maybe i should use it ?
public bool IsPresent(string isbn)
{
//rechercher si l'isbn correspond a un livre de la liste
AchatLivreViewModel livre = ListeElements.Find(element => element.Isbn == isbn);
if (livre != null)
{
return true;
}
else
{
return false;
}
}
Why not trying this simple approach:
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#item.Isbn
</td>
<td>
#item.Titre
</td>
<td>
<label class="btn btn-primary" style="padding:0">Add to Cart</label>
</td>
<td>
<label class="btn btn-danger" style="padding:0">Remove From Cart</label>
</td>
</tr>
}
</tbody>
And in your javascript, if you don't want to use Ajax, you can manage your cart items all on client side using an array of objects, Let's name it CartItems:
var CartItems = [];
$('.ADD2CART').click(function () {
if ($(this).closest('tr').hasClass("ExistingInCart")) {
alert('Already in Cart !!');
}
else {
// add this item to the Cart through Ajax or
// local javascript object: e.g.:
CartItems.push({
ISBN: $(this).closest('tr').find('td:eq(0)').text().trim(),
Title: $(this).closest('tr').find('td:eq(1)').text().trim(),
});
$(this).closest('tr').addClass("ExistingInCart");
}
return false; //to prevent <a> from navigating to another address
});
$('.RemoveFromCART').click(function () {
$(this).closest('tr').removeClass("ExistingInCart");
var isbn = $(this).closest('tr').find('td:eq(0)').text().trim();
CartItems = CartItems.filter(x => x.ISBN !== isbn);
return false;
});
Once you need to submit or post the page, you have all the already selected books in CartItems array.
To add this javascript code to your view, choose one of the options:
Put this block at the bottom of your view and copy the above script inside the <script></script> tag:
#section scripts{
<script>
.... copy it here ...
</script>
}
copy the script code inside a newFile.js and add it to your view
<script src="~/Scripts/jquery-3.3.1.min.js"></script>
<script src="~/Scripts/newFile.js"></script>
You may decide to bundle this newFile.js
try this:
Ajouter
And your Javascript:
function foo(input) {
if ($(input).attr('yetClickable') === '1') {
$(input).attr('yetClickable', '0');
return true;
}
else {
// this false returning will counteract the effect of click event on the anchor tag
return false;
}
}
Once an Item is removed from the cart, again you need javascript to select that Item by its Id and change the yetClickable attribute back to 1 (in order to be clickable).
Note: This idea above (upon your scenario) works until the page is not reloaded. Otherwise, you need to handle ADD/Remove operations on the Cart through Ajax.
Hope this helps.

How to Pass Data to a vuestrap Modal component

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.

<fieldset hides when page re-loads - MVC 5

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();
}
});

Pre loader for index action MVC

Im trying to do a preloader for a page
the index action controller:
myapp/FR/Index
public ActionResult Index(){
return View(db.SP_GetRegistrosFRByID(0).ToList());}
the view, there isnt a begin form because is a get request:
#foreach (var item in Model)
{
...etc...<tr>
<td>
#Html.DisplayFor(modelItem => item.CodIden)
</td>
<td>
#Html.DisplayFor(modelItem => item.Nombres)
</td> ...etc
As David says it's a broad and open-ended question and you can apply lot of approaches. You have not given details about how index gets called (form submit, button click ..)
First you need a div with the loader image in the view where you need the preloader to display.
<div id="loader" class="loader">
Working.. <img src="~/Images/loading_small.gif" />
</div>
and now the JS function that shows/hides the div with the loader image based on your data loading status.
function pageLoading(status) {
if (status == 'true') {
$("#loader").css('display', 'block');
}
else {
$("#loader").css('display', 'none');
}
}
Before making the AJAX request you can call pageLoading("true"); to start displaying the image and finally when the table data gets populated call pageLoading("false"); to hide the loading image. Something like
$.ajax({
url: 'your index method url',
success: function (partial) {
$('#results').html(partial);
pageLoading("false");
}
error: function () {
pageLoading("false");
}
});

Building a form from json

I'm fetching an array of viewmodels from my controller using jquery+json. I then build a form where each row in a table represents one viewmodel.
My question is: How should I name each form element so that I can get it to my controller action like this:
public ActionResult Update(MyViewModel[] models)
{
}
Edit: I'm using jquery-tmpl to generate the form, and I'm also trying to figure out how to get an index variable in it (if that's needed for the form generation).
I managed to get it working.
My jquery template:
<script id="wagonTemplate" type="text/x-jquery-tmpl">
<tr>
<td>
<input type="checkbox" value="true" class="wagoncheck" name="wagons[${$item.getIndex()}].IsSelected" />
</td>
<td>
<input type="text" name="wagons[${$item.getIndex()}].WagonId" value="${WagonId}" style="width:120px" />
</td>
<td>
<input type="text" name="wagons[${$item.getIndex()}].WagonNumber" value="${WagonNumber}" style="width:20px" />
</td>
</script>
Method that loads the template:
function loadWagons(trainId, partId) {
$.getJSON('/train/wagons/' + escape(trainId) + '?partNo=' + partId, function (data) {
$wagons = $('#wagons tbody');
$wagons.empty();
// the function used in the template to get an index.
var tmplOptions = {
getIndex: function getIndex() {
return $.inArray(this.data, data);
}
};
$("#wagonTemplate").tmpl(data, tmplOptions).appendTo($wagons);
});
}
In other words:
To get a YourModel[] items argument in your controller action you need to name the items as items[0].MyProperty' where0` should correspond to the index in the array.
To get an index in a jquery template, just use pass a method in the options to the template function. I'm using a slightly modified version of the answer found here. Passing the item as done in that answer is not necessary as this points on the current item.

Resources