I using the following function to delete a row in a table
//delete individual row
jQuery('.stdtable img.delete').click(function(){
var c = confirm('Continue delete?');
if(c) jQuery(this).parents('tr').fadeOut(function(){
jQuery(this).remove();
});
return false;
});
This code is in a separate js file and is common to all pages.
Now I would like to add an Ajax action that deletes the row from the database. But depending on which page I'm on, it must call different controller.
Example:
Product page must call delete in ProductController
ProductGroup page must call delete in ProductGroupController
How to handle this?
If you need some method of defining which controller to call, you could put a data attribute on the table. Something like this:
<table class="stdtable" data-remove-url="#Url.Action("DeleteRow", "MyController")">
<tr data-id="1">
AAA
<img class="delete" src="foo.jpg" />
</tr>
<tr data-id="2">
BBB
<img class="delete" src="foo.jpg" />
</tr>
</table>
Then in your jQuery you can get this value as the url parameter of your request, along with the id to delete.
jQuery('.stdtable img.delete').click(function(e) {
e.preventDefault();
if (confirm('Continue delete?')) {
var $el = $(this);
var $tr = $el.closest('tr');
var url = $el.closest('table').data('remove-url');
var id = $tr.data('id');
$tr.fadeOut(function() {
$el.remove();
$.post(url, { rowId = id }); // do the delete on the server
});
}
});
You could add a custom attribute to your table or row with contains the url off the controller you need to call. In your method you can read this custom attribute to get the url of your controller.Look here for the JQuery attr methode.
If I understand your question right, you want to click the image with class delete to make a call to delete that row in the database. The simplest solution would be
<img data-rowid="1" src="something.jpg"/>
jQuery('.stdtable img.delete').click(function(e){
e.preventDefault();
var c = confirm('Continue delete?');
var that = this;
if(c) {
var id = this.data("rowid");
jQuery.ajax({ url : "/resource/"+id, method : "DELETE"
statusCode: {
200: function() {
jQuery(that).parents('tr').fadeOut(function(){
jQuery(that).remove();
});
}
}});
}
return false;
});
Related
Within my view I have a select box. If a certain value is selected I want more form options to appear below using #if.
#model App.ViewModels.JobVM
<div class="row">
<div class="form-group">
#Html.Label("Job Type", new { #class = "control-label" })
#Html.DropDownListFor(model => model.JobId,
new SelectList(App.ViewModels.JobVM.GetJobs(),
"Value", "Text"),
"--Choose Job Type--",
new { #class = "form-control"})
</div>
</div>
...
#if (Model.JobId == 1)
{
.... more form options
}
However when running if the select option that give Job ID 1; the form options don't render.
Is there a reason why the form options do not appear when the Select option changes? Or will I have to use javascript to accomplish this goal?
It's expected behavior as view is rendered on server once before sending data to browser. However, for displaying additional inputs you can use both methods - js or partial views (even with ajax if you need) you have to use only JavaScript to show/hide other elements of form for required cases.
The #if statement and Model.JobId executed server-side, hence Model.JobId value doesn't change when the dropdown selected value has changed because change event occurred in client-side. By handling change event with JS, you can use AJAX call to set the value and display additional form options which contained inside partial view:
jQuery AJAX call
$('#JobId').change(function () {
var jobId = $(this).val();
if (jobId == 1) {
$.ajax({
type: 'GET', // or 'POST'
url: '#Url.Action("ActionName", "ControllerName")',
data: { JobId : jobId },
success: function (result) {
$('#formoptions').html(result);
},
// other stuff
});
}
else {
$('#formoptions').empty();
}
});
Controller Action
public ActionResult ActionName(int JobId)
{
// do something
return PartialView("_FormOptions", viewmodel);
}
If the form options are already rendered together inside view, instead of using server-side #if block, simply use a <div> placeholder and toggle its visibility like this:
$('#JobId').change(function () {
var jobId = $(this).val();
if (jobId == 1) {
$('#formoptions').show(); // show form options
} else {
$('#formoptions').hide(); // hide form options
}
});
HTML
<div id="formoptions">
<!-- more form options -->
</div>
I am able to get the aggreate values from server to client, but could not display it on the template. Am i missing something here.Appreciate your help.Iam a newbie in meteor.
//client side javascript
Template.DashboardCategoriesChart.helpers({
'CategoryAggregateItem':function(){
var res;
Meteor.call("getAggregateCategoriesSum",function(errors,results){
console.log("results value: "+ JSON.stringify(results))
return results ;
};
};
});
//stringfy value returned
results value: [
{"_id":"Household","totalAmount":420},
{"_id":"Insurance","totalAmount":235},
{"_id":"Family","totalAmount":1358},
{"_id":"Utilities","totalAmount":5371.5},
{"_id":"Automobile","totalAmount":500},
{"_id":"Home Office","totalAmount":290},
{"_id":"Travel","totalAmount":14},
{"_id":"Food","totalAmount":303}
]
//Template
{{#each CategoryAggregateItem}}
<tr>
<td>{{_id}}</td><td>{{totalAmount}}</td>
</tr>
{{/each}}
The following code worked, thanks a ton JeremyK for leading to right direction.
Template.DashboardCategoriesChart.helpers({
'CategoryAggregateItem':function(){
return Template.instance().CategoryAggregateItem.get(); //this.CategoryAggregateItem;
}
});
Template.DashboardCategoriesChart.onCreated(function () {
var instance = this;
this.CategoryAggregateItem = new ReactiveVar(null);
Meteor.call("getAggregateCategoriesSum",function(errors,results){
console.log("results value: "+ JSON.stringify(results))
instance.CategoryAggregateItem.set(results);
})
})
Try changing your client side javascript to this:
Template.DashboardCategoriesChart.onCreated(function () {
_this = this;
_this.CategoryAggregateItem = new ReactiveVar(null);
Meteor.call("getAggregateCategoriesSum",function(errors,results){
console.log("results value: "+ JSON.stringify(results))
_this.CategoryAggregateItem.set(results);
}
});
Template.DashboardCategoriesChart.helpers({
'CategoryAggregateItem':function(){
return Template.instance().CategoryAggregateItem.get();
});
When the Callback from Meteor.Call is triggered, it will update the ReactiveVar. This causes the template to rerender and display the retrieved data.
You may also want to provide alternative markup in your template for when the helper returns null, before the data is received by the client.
When I try to use this.findAll on a template where the selector is in a sub-template, findAll returns nothing.
Here's the HTML:
<template name="products">
{{#each productList}}
{{> product }}
{{/each}}
</template>
<template name="product">
<div class="box">{{name}}</div>
</template>
Here's the JS:
Template.products.helpers({
productList: function() {
var all = Products.find({}).fetch();
return all;
}
});
Template.products.rendered = function(){
var boxes = this.findAll('.box');
console.log(boxes.length);
}
Output of boxes.length is 0. Any ideas how I could get the "box" elements?
According to the docs for findAll:
Only elements inside the template and its sub-templates can match parts of the selector.
So it should work for sub-templates. I tried this with a fixed array of products and it worked, which implies that you are just seeing a delay between the call to rendered and the products being fetched. For example if you do:
Template.products.events({
'click .box': function (e, t) {
var boxes = t.findAll('.box');
console.log(boxes.length);
}
});
Then if you click on one of the boxes, you should see the correct number logged to the console. In short, I think the test may just be invalid. If you are using iron-router, you could try adding a waitOn for the products - that may ensure they arrive before the rendered call.
Here's what I did to run a script after all products have been loaded.
I've added last_product property in all the products.
Template.products.helpers({
productList: function() {
var all = Products.find({}).fetch();
var total = all.length;
var ctr = 0;
all.forEach(function(doc){
doc.last_product = false;
ctr++;
if(ctr == total)
{
doc.last_product = true;
}
return doc;
});
return all;
}
});
Then instead of "Template.products", I used "Template.product" to detect if the last product is rendered. When the last product is rendered, run the script.
Template.product.rendered = function(){
if(this.data.last_product){
var boxes = $('.pbox');
console.log(boxes.length);
}
}
boxes.length now has the correct length.
Thanks to David for the idea!
Here's the correct answer. I've added this to my iron-router route:
action : function () {
if (this.ready()) {
this.render();
}
}
Found the answer from https://stackoverflow.com/a/23576039/130237 while I was trying to solve a different problem.
In my ASP.NET MVC 4 Project, At my index page, I have a dropdownlist where I want to 'redirect' the selected value back to the same index page.
I wrote a basic function but I have no clue how I can send that selected value with jQuery.
So the situation right now: Every time a user makes the dropdownlist change, the ID of the selected value is*captured in var selectedFB.
Then I want a url, link... that passes selectedFB back to the index page. But how to generate that URL?
<script>
$(function () {
$('#FBType').change(function () {
var selectedFB = $(this).find('option:selected').val();
var result = '#Html.ActionLink("Index", "Index", new { id = selectedFB })';
$("#dynamicLink").attr("href", );
return true;
});
});
</script>
looks like you are mixing client and server site. 2 options for you...
on the client site you need to have your restful route as you use to in MVC like this http://server/action/parameter
Or you should build up your client site script dynamic and let the view engine insert the resolved links.
This will not be resolved in the browser
'#Html.ActionLink("Index", "Index", new { id = selectedFB })';
Please let me know if this helps...
You cannot generate url by #Html.ActionLink on client side.You need something like this.
<script>
$(function () {
var action = '#Url.Action("Index", "Index")';
$('#FBType').change(function () {
var selectedFB = $(this).find('option:selected').val();
var result = action + '/' + selectedFB;
$("#dynamicLink").attr("href", result );
return true;
});
});
i am converting over from websforms to asp.net mvc and i have a question.
i have a loop that generates links dynamicallly where picNumberLink is a variable in a loop and image is a variable image link.
i want to avoid putting javascript actions inline so in my webforms project is did the following:
hyperLink.Attributes.Add("onclick", "javascript:void(viewer.show(" + picNumberlink + "))");
what is the equivalent using jquery in asp.net mvc?
I have seen examples of using the $(document).ready event to attach on clicks but i can't figure out the syntax to pass in the picNumberLink variable into the javascript function.
suggestions?
EDIT: If you generate your links with the ID of this form:
<a id="piclink_1" class="picLinks">...</a>
<a id="picLink_2" class="picLinks">...</a>
<script type="text/javascript">
$('a.picLinks').click(function () {
//split at the '_' and take the second offset
var picNumber = $(this).attr('id').split('_')[1];
viewer.show(picNumber);
});
</script>
var functionIWantToCall = function(){
var wrappedLink = $(this);
//some serious action
}
//this should be called on document ready
$("#myLinkId").click(functionIWantToCall);
If you need to get URL of picture, keep it in anchor`s href:
var functionIWantToCall = function(event){
event.preventDefault(); //this one is important
var link = $(this).attr('href');
//some serious action
}
$(document).ready(function()
{
$('#LinkID').click(function() {
viewer.show($(this).attr('picNumber'));
});
});
You can add an attribute called picNumber to your hyperlink tag and set this is your mvc view
The link in your view might look something like this:
<%= Html.ActionLink("Index", new { id = "LINKID", picNumber = 1 }) %>
Assuming you're able to change the HTML you output, can't you put the picNumberLink in the id or class attribute?
HTML:
<img src="..."/>
jQuery:
$(function() {
// using the id attribute:
$('.view').click(function() {
viewer.show(+/-(\d+)/.exec(this.id)[1]);
});
// or using the class attribute:
$('.view').click(function() {
viewer.show(+/(^|\s)foo-(\d+)(\s|$)/.exec(this.className)[2]);
});
}}