ASP.NET MVC - Disable button depending on value in database (WebGrid) - asp.net

I want to create a submit button in webgrid, which is sending a row to another table, but I don`t know how to disable this button, when user have done this already.
First table:
CREATE TABLE [dbo].[Applications] (
[ApplicationId] INT IDENTITY (1, 1) NOT NULL,
[ApplicantName] NVARCHAR (50) NOT NULL,
[DepartmentName] NVARCHAR (100) NOT NULL,
[StartDate] DATETIME NOT NULL,
[EndDate] DATETIME NOT NULL,
[AssistantName] NVARCHAR (50) NOT NULL,
[Description] NVARCHAR (MAX) NULL,
[Approved] BIT NULL,
PRIMARY KEY CLUSTERED ([ApplicationId] ASC)
);
I created here an "Approved" value, which is changing to "True", when user clicks a button. Then, when Approved==True button should be disabled.
Second table:
CREATE TABLE [dbo].[Events] (
[EventID] INT IDENTITY (1, 1) NOT NULL,
[Subject] NVARCHAR (100) NOT NULL,
[DepartmentName] NVARCHAR (100) NULL,
[AssistantName] NVARCHAR (50) NULL,
[Description] NVARCHAR (300) NULL,
[Start] DATETIME NOT NULL,
[End] DATETIME NOT NULL,
[ThemeColor] NCHAR (10) NULL,
[IsFullDay] BIT NOT NULL,
PRIMARY KEY CLUSTERED ([EventID] ASC)
);
My controller to this action:
[HttpPost, ValidateInput(false)]
public ActionResult Accept(string applicationJSONaccept, Event model)
{
Application apl = (new JavaScriptSerializer()).Deserialize<Application>(applicationJSONaccept);
MyDatabaseEntities dc = new MyDatabaseEntities();
Application app = dc.Applications.FirstOrDefault(x => x.ApplicationId == apl.ApplicationId);
app.Approved = true;
dc.Events.Add(new Event
{
Subject = apl.ApplicantName,
DepartmentName = apl.DepartmentName,
Description = apl.Description,
Start = apl.StartDate,
End = apl.EndDate,
IsFullDay = false,
AssistantName = apl.AssistantName
});
dc.SaveChanges();
return Redirect("ApplicationView");
}
Webgrid:
#grid.Table(
htmlAttributes: new { #id = "grid", #class = "Grid" },
tableStyle: "table table-responsive table-bordered",
columns: grid.Columns(
grid.Column(columnName: "ApplicationId", header: "Nr"),
grid.Column(columnName: "ApplicantName", header: "Imię i nazwisko"),
grid.Column(columnName: "DepartmentName", header: "Oddział"),
grid.Column(columnName: "StartDate", header: "Od"),
grid.Column(columnName: "EndDate", header: "Do"),
grid.Column(columnName: "AssistantName", header: "Zastępca"),
grid.Column(columnName: "Description", header: "Opis"),
//Here is this button:
grid.Column(null, header: "", format: #<text>#Html.ActionLink("Zatwierdź", null, null, new { #class = "accept btn btn-success", #role="button" })</text>)
))
#using (Html.BeginForm("Accept", "Home", FormMethod.Post, new { #id = "IndexForm2" }))
{
<input type="hidden" name="applicationJSONaccept" />
}
JS:
<script type="text/javascript">
$("body").on("click", ".accept", function () {
var row = $(this).closest("tr");
var application = {};
application.ApplicationId = row.find("td").eq(0).html();
application.ApplicantName = row.find("td").eq(1).html();
application.DepartmentName = row.find("td").eq(2).html();
application.StartDate = new Date(row.find("td").eq(3).html().substr(6, 4), row.find("td").eq(3).html().substr(4, 2) - 1, row.find("td").eq(3).html().substr(0, 2));
application.EndDate = new Date(row.find("td").eq(4).html().substr(6, 4), row.find("td").eq(4).html().substr(4, 2) - 1, row.find("td").eq(4).html().substr(0, 2));
application.AssistantName = row.find("td").eq(5).html();
application.Description = row.find("td").eq(6).html();
$("[name=applicationJSONaccept]").val(JSON.stringify(application));
$("#IndexForm2")[0].submit();
return false;
});
</script>
Everything is working fine, row goes to another table, value of Approved is changing, but I`ve problem how to disable this button when Approved==false. Do you know how can I do this?
Thanks in advance!
Edit:
Tried this, but still doesn`t work.
grid.Column(null, header: "", format:
#<text>
#if (ViewBag.Approved == false || ViewBag.Approved == null) {
#Html.ActionLink("Zatwierdź", null, null, new { #class = "accept btn btn-success", #role = "button" })
}
else
{
#Html.ActionLink("Zatwierdź", null, null, new { #class = "accept btn btn-success disabled", #role = "button" });
}
</text>)
Controller update:
[HttpPost, ValidateInput(false)]
public ActionResult Accept(string applicationJSONaccept, Event model)
{
Application apl = (new JavaScriptSerializer()).Deserialize<Application>(applicationJSONaccept);
MyDatabaseEntities dc = new MyDatabaseEntities();
Application app = dc.Applications.FirstOrDefault(x => x.ApplicationId == apl.ApplicationId);
ViewBag.Approved = app.Approved;
if (app.Approved == false || app.Approved == null)
{
app.Approved = true;
dc.Events.Add(new Event
{
Subject = apl.ApplicantName,
DepartmentName = apl.DepartmentName,
Description = apl.Description,
Start = apl.StartDate,
End = apl.EndDate,
IsFullDay = false,
AssistantName = apl.AssistantName
});
dc.SaveChanges();
}
else
{
}
return Redirect("ApplicationView");
}

you can change the css class ([disabled] selector) based on the value from the database while you are binding your view.

You need to add CSS class and remove class whatever your condition, If you need button enable click event then remove class and if you need disable click event then add the class
Style
.btnDisable{
pointer-events: none;
}
In your "IndexForm2" button.
Just add and remove this CSS class your problem solve.
Try below new code
grid.Column("YourColumnName", format:(item) =>
{
if (item.Approved == false || item.Approved == null)
{
#Html.ActionLink("Zatwierdź", null, null, new { #class = "accept btn btn-success", #role="button" })
}
else
{
#Html.ActionLink("Zatwierdź", null, null, new { #class = "accept btn btn-success btnDisable", #role="button" })
}
}

I found a solution, here`s the code:
grid.Column(null, header: "Akceptuj", format:
#<text>#Html.ActionLink("✓", null, null, new { #class = "accept btn " +
(#Html.Raw((item.Approved == true) ? "btn-secondary disabled" : "btn-info")),
#role = "button" })</text>)
That`s all, no css added here, just bootstrap ;)
Thanks for every reply!

Related

Apply color to ActionLink

I am trying to change the font of a ActionLink, however I cannot get it to change when I have , null at the end of it.
What I have tried:
#Html.ActionLink(" Verification |", "VerIndex", "MFC_Form", new { deviceID = item.DeviceID, type = "Verification", id = "Color" }, null)
window.onload = function () {
var x = "fontColor";
alert("color " + x);
if (x == "fontColor") {
$("#Color").css('color', "red");
}
else {
$("#Color").css('color', "green");
}
}
and
#Html.ActionLink(" Verification |", "VerIndex", "MFC_Form", new { deviceID = item.DeviceID, type = "Verification", style = "color:red" }, null)
and
#Html.ActionLink(" Verification |", "VerIndex", "MFC_Form", new { deviceID = item.DeviceID, type = "Verification", #class = "fontColor" }, null)
You cannot mix the routeValues and htmlAttributes parameters. These two must be distinct objects.
View
#Html.ActionLink(" Verification |", "VerIndex", "MFC_Form", new {deviceID = item.DeviceID, type = "Verification"}, new { #class = "text-red" })
CSS
.text-red {
color: red;
}
The generated link looks like this:
<a class="text-red" href="/MFC_Form/VerIndex?deviceID=1&type=Verification"> Verification |</a>

DynamoDB Query confusion

I have the following table creation code for DynamoDB (C#):
client.CreateTable(new CreateTableRequest
{
TableName = tableName,
ProvisionedThroughput = new ProvisionedThroughput { ReadCapacityUnits = 20, WriteCapacityUnits = 10 },
KeySchema = new List<KeySchemaElement>
{
new KeySchemaElement
{
AttributeName = "RID",
KeyType = KeyType.HASH
}
}
,
AttributeDefinitions = new List<AttributeDefinition>
{
new AttributeDefinition {
AttributeName = "RID",
AttributeType = ScalarAttributeType.N
}
}
});
the data that gets populated into this table comes from this JSON:
[
{"RID": 208649, "CLI_RID": 935476, "PRT_DT": "VAL_AA", "DISTR": "INTERNAL"},
{"RID": 217427, "CLI_RID": 1009561, "PRT_DT": "VAL_BB", "DISTR": "INTERNAL", "STATE": "VAL_BD"},
{"RID": 223331, "CLI_RID": 1325477, "PRT_DT": "VAL_CB", "DISTR": "", "STATE": "VAL_CD", "FNAME": "VAL_CE", "START": "VAL_CF"},
{"RID": 227717, "CLI_RID": 1023478, "PRT_DT": "VAL_DB", "DISTR": "", "STATE": "VAL_DD"}
{"RID": 217462, "CLI_RID": 1009561, "PRT_DT": "VAL_BB", "DISTR": "", "STATE": "VAL_BD"},
{"RID": 218679, "CLI_RID": 1009561, "PRT_DT": "VAL_AA", "DISTR": "INTERNAL"},
{"RID": 222376, "CLI_RID": 1263978, "PRT_DT": "VAL_DB", "DISTR": "", "STATE": "VAL_DD"}
]
How would I Query or Filter for all records containing 1009561 in column "CLI_RID" and column "DISTR" <> "INTERNAL"?
There will be about 15 mil records in this DynamoDB table.
Is my table defined correctly for this query/filter?
Updated table creation:
// CLI_RIDIndex
var cli_ridIndex = new GlobalSecondaryIndex
{
IndexName = "cli_ridIndex",
ProvisionedThroughput = new ProvisionedThroughput
{
ReadCapacityUnits = 20,
WriteCapacityUnits = 10
},
KeySchema = {
new KeySchemaElement
{
AttributeName = "CLI_RID", KeyType = "HASH"
}
},
Projection = new Projection { ProjectionType = "ALL" }
};
client.CreateTable(new CreateTableRequest
{
TableName = tableName,
ProvisionedThroughput = new ProvisionedThroughput { ReadCapacityUnits = 20, WriteCapacityUnits = 10 },
KeySchema = new List<KeySchemaElement>
{
new KeySchemaElement
{
AttributeName = "RID",
KeyType = KeyType.HASH // Partiton Key (Unique)
},
new KeySchemaElement
{
AttributeName = "CLI_RID",
KeyType = KeyType.RANGE // Sort Key
}
}
,
AttributeDefinitions = new List<AttributeDefinition>
{
new AttributeDefinition {
AttributeName = "RID",
AttributeType = ScalarAttributeType.N
},
new AttributeDefinition {
AttributeName = "CLI_RID",
AttributeType = ScalarAttributeType.N
}
},
GlobalSecondaryIndexes = { cli_ridIndex }
});
But when attempting to query it,
var request = new QueryRequest
{
TableName = "TNAArchive",
KeyConditionExpression = "CLI_RID = :v_cli_rid",
ExpressionAttributeValues = new Dictionary<string, AttributeValue> {
{":v_cli_rid", new AttributeValue { S = "905466" }}}
};
var response = client.Query(request);
I get this error:
Query condition missed key schema element: RID
I guess I'm not really understanding how to do this.
According to your table structure, you won't be able to perform Query on the table but you have to Scan it which we need to avoid.
To perform Query you need to modify certain things
1) Add a Global Secondary Index(GSI) with the field CLI_RID as Hash
2) Now You Query GSI by passing CLI_RID and add query filter with condition <> your value
Here is the reference link.
Edit: Your Main table structure will be same no need to change, but you need to add one more GSI with Hash key as CLI_RID and project required table attribute.
Now you need to query your GSI instead of the table with a hash key as CLI_RID, you don't need to pass RID here.
here is the link on how to add GSI on table.
If CLI_RID is not present in a master table then that record will not be reflected in the GSI so no need to worry.
Edit 2: Just add (IndexName = NameOFYourIndex) attribute while querying and everything should work.
var request = new QueryRequest
{
TableName = "TNAArchive",
IndexName = "NameOfYourIndex",
KeyConditionExpression = "CLI_RID = :v_cli_rid",
ExpressionAttributeValues = new Dictionary<string, AttributeValue> {
{":v_cli_rid", new AttributeValue { S = "905466" }}}
};
Hope that helps

How to display enum description or name in a grid row?

I am using the Kendo grid in my ASP.Net MVC application. If I have the following grid definition,
#(Html.Kendo().Grid(Model) //Bind the grid to ViewBag.Products
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.FullName);
columns.Bound(p => p.MyEnum)
})
.Groupable()
.Pageable()
.Sortable()
.Scrollable(scr => scr.Height(600))
.Filterable()
)
where one of the column is an Enum. My enum definition is:
public enum MyEnum
{
[Display(AutoGenerateField = false, Name = "My enum 1", Description = "My Enum 1")]
EnumOne,
[Display(Name = "My Enum 2")]
EnumTwo
}
How do I make it display "My Enum 1" or "My Enum 2" for each row?
Thanks in advance!
I recently ran into this problem and solved it by using
var someArrayOfValueAndText = new[] {new {
Id = 0, Description = "Foo"
}, new {
Id = 1, Description = "Bar"
}
.Columns(c.ForeignKey(m=> m.MyEnum, someArrayOfValueAndText, "Id","Description"))
instead of the .Bound method
I created an helper class containing some extension methods a while back:
public static class EnumExtensions
{
public static string GetDisplayName(this Enum enu)
{
var attr = GetDisplayAttribute(enu);
return attr != null ? attr.Name : enu.ToString();
}
public static string GetDescription(this Enum enu)
{
var attr = GetDisplayAttribute(enu);
return attr != null ? attr.Description : enu.ToString();
}
private static DisplayAttribute GetDisplayAttribute(object value)
{
Type type = value.GetType();
if (!type.IsEnum)
{
throw new ArgumentException(string.Format("Type {0} is not an enum", type));
}
// Get the enum field.
var field = type.GetField(value.ToString());
return field == null ? null : field.GetCustomAttribute<DisplayAttribute>();
}
}
It contains two methods for extracting the Name and Description of a Display attribute. The display name:
columns.Bound(p => p.MyEnum.GetDisplayName())
And for a description:
columns.Bound(p => p.MyEnum.GetDescription())
You have to add a using statement in your Web.config or in your view.
Update
What if you create a property for it in your model:
public string MyEnumName
{
get { return MyEnum.GetDisplayName(); }
}
Now you should be able to use:
columns.Bound(p => p.MyEnumName);
Henk's solution is good. But you can use filtering capability if you use ClientTemplate:
col.Bound(m => m.MyEnum) // this provides you filtering
.ClientTemplate("#: MyEnumName #") // this shows a name of enum
For more information about kendo ui templates see: http://docs.telerik.com/kendo-ui/framework/templates/overview
I use #user1967246 method and would like to explain more how to i do.
i created array in top of my kendo grid
var statusLikeEntityStatus = new[]
{
new {Id = 0, Status = EntityStatus.Passive},
new {Id = 1, Status = EntityStatus.Active},
new {Id = 2, Status = EntityStatus.Draft},
new {Id = 3, Status = EntityStatus.ReadyToLive},
new {Id = -1, Status = EntityStatus.Freezed},
new {Id = -2, Status = EntityStatus.Blocked}
};
Then i use ForeignKey property instead of Bound.
columns.ForeignKey(m => m.Status, statusLikeEntityStatus, "Id", "Status").Title(Resources.General.Status);
Here is my columns attribute
.Columns(columns =>
{
columns.Bound(m => m.InventoryID).Title("Id");
columns.Bound(m => m.ERPCode).Title(Resources.Products.ProductCode);
columns.Bound(m => m.Price).Title(Resources.Products.ListPrice);
columns.Bound(m => m.Discount).Title(Resources.Products.
columns.Bound(m => m.Stock).Title(Resources.Products.TotalStock); // todo: Resources
columns.ForeignKey(m => m.Status, statusLikeEntityStatus, "Id", "Status").Title(Resources.General.Status);
columns.Command(commandConf =>
{
commandConf.Edit();
commandConf.Destroy();
});
})
Hope it will help to you.

How to refresh the data without reloading the page using data-bind

I am using knockout.js in my django project and having problem in post method in javascript. I tried to rebind or re-initialized the list but it didn't work.
Eg: I am showing table data with 10 rows..I want on button click I get another data with 5 rows and want to reload that data on table without reloading the page.
Does any one knows the solution .. Below is my code for knockout.js, html and view.py page:
javascript:
function makeShowObjectList(model, d_url, no_num, detail_per_page, b, fruit) {
var showobjectList = ko.observableArray([]);
$.post(d_url, data, function (response_data) {
// here we have applied code to set new data in showobjectList
if (!showobjectList.is_ready)
{
//Here we are trying to relaod the list on the page but did'nt work
FViewModel.showobjectList=showobjectList;
showobjectList.is_ready = true;
showobjectList.onready();
ko.mapping.fromJSshowobjectList, {}, self); }
}
}, 'json');
}
function fruitFilterItem( n, i ) {
this.n = n;
this.i = i;
}
var FViewModel=function(c_data)
{
var self = this;
self.abc= ko.observable(null);
this.optionsText = ko.observable();
this.fruitFilter = ko.observableArray([
new fruitFilterItem( "Mango", 2 ),
new fruitFilterItem( "Banana", 1 ),
new fruitFilterItem( "Grapes", 3 )
]);
this.selectedfruit = ko.observable();
this.VegeFilter = ko.observableArray([
new fruitFilterItem( "Tomato", "Tomato" ),
new fruitFilterItem( "Patato", "Patato" ),
new fruitFilterItem( "Onion", "Onion" ),
]);
this.selectedVege = ko.observable();
self.showtList = makeShowObjectList(BucketViewModel, urls.get_fruit_info, self.fruit_page, self.num_fruit, self.bbq,
self.selectedfruit());
self.setShowType = function(d, ele) {
this.get_updates = function () {
ko.mapping.fromJS(searchList(), self);};
self.showtList = makeShowObjectList(BucketViewModel, urls.get_fruit_info, self.fruit_page, self.num_fruit, self.b, self.selectedfruit());
self.showtList();
}
self.ShowmessageList = function () {
return self.showtList;
}
}
HTML:
<script>
VarModel = new FViewModel(c_data);
$(function() {
function get_updates () {
$.getJSON('/new-lines.json', function(c_data) {
var VarModel = ko.mapping.fromJS(choices_data);
ko.applyBindings(VarModel );
});
}
ko.applyBindings(VarModel);
</script>
<body>
<select id="fruit" name="fruit" style="width:200px;" data-bind = "
value: selectedfruit,
options: fruitFilter,
optionsText: 'n',
optionsValue: 'i',
optionsCaption: 'Select a fruit'
">
</select>
<select style="width:180px;" data-bind = "
value: selectedVege,
options: VegeFilter,
optionsText: 'n',
optionsValue: 'i',
optionsCaption: 'Select a Vege'
">
//here we are showing our columns
</body>
Views.py:
def urls.get_fruit_info(request):
//we are calculating the page_object here
response_object = {
'page': page_object,
'no_not': FruitRecipient.objects.filter(user=request.member, add_at=None).count()
}
return HttpResponse(simplejson.dumps(response_object, indent=3))
I would be thankful if any one could help me out in sorting my issue.
Thanks in advance.
Use ko.mapping its a plugin that you can download, it only updates the observables that have changed between two states, thus only the members that have changed will be re re-rendered in the view

MVC Telerik Grid Conditional column Value?

How can i get this work in MVC Telerik Grid Control
columns.Template(e =>
{
if (e.EndDate>DateTime.Now )
{
#Html.ActionLink("Stop", "StopMedication", "Medication",
new { id = e.PrescriptionID }, new { #class = "standard button" })
}
else {
#Html.ActionLink("Renew", "RenewMedication", "Medication",
new { id = e.PrescriptionID }, new { #class = "standard button" })
}
});
The following snippet should work perfectly fine in the Telerik Grid template column using Razor syntax:
columns.Template(
#<text>
#if (#item.EndDate > DateTime.Now)
{
#Html.ActionLink("Stop", "StopMedication", "Medication",
new { id = #item.PrescriptionID }, new { #class = "standard button" })
}
else
{
#Html.ActionLink("Renew", "RenewMedication", "Medication",
new { id = #item.PrescriptionID }, new { #class = "standard button" })
}
</text>
);
Taking use of the #<text></text> inside of the template, as well as using the #item object, which represents the current item (entity tied to the row) and it's properties, will allow you to have this template up and running.

Resources