another way to write this - asp.net-mvc

Is there another way to write this:
//javascript and jquery area
'<% if (Model.Fruit == MyEnum.Apple) { %>'
$("#PaymentType option").each(function(){
//blah
});
'<% } %>'
i'm not sure i like the quotes around the whole if statement

In your view:
var isApple = <% Model.Fruit == MyEnum.Apple %>;
In an included javascript file:
if(isApple) {
$("#PaymentType option").each(function(){
//blah
});
}

If the goal is to have VS continue to correctly check/auto-reformat javascript then you must use your trick or one similar to avoid the issue.
In one of the answers to the following related question there is text from Microsoft indicating that this is a known issue for which they do not yet have a good solution.
Visual Studio confused by server code inside javascript

Related

How do insert a separator bar between many groups on a Kendo UI Menu

I am using the pure Razor style definition for a Kendo Menu:
#using Kendo.Mvc.UI
#(Html.Kendo().Menu()
.Name("main-menu")
.Items(items1 =>
{
items1.Add().Text("Home").Url(#Url.Action("Index", "Home"));
items1.Add().Text("Movements").Items(subs =>
{
subs.Add().Text("Import Data").Action("Import", "VehicleMovementBatch");
subs.Add().Text("View Movements");
});
items1.Add().Text("Presences");
items1.Add().Text("Billing");
items1.Add().Text("Config").Items(items2 =>
{
items2.Add().Text("Pricing").Action("Index", "PriceRule");
items2.Add().Text("Users");
});
items1.Add().Text("Control");
})
)
I can find absolutely bloody nothing anywhere on all the internets, that even hints how to do do this properly. The closest I have is defining the DataSource in JavaScript object notation, with separators, and assigning it to the grid oj the client side at run time. This is definitely a good example of a case where can only pray to all the gods that the API isn't as superlatively inadequate as the documentation.
This is all you need to do. Figured it out on my own because I couldn't find an answer anywhere on the web.
items1.Add().Text("<hr/>").Encoded(false).Enabled(false);
The < hr / > thing didn't work for me in kendo 2014.1.528
This does:
children.Add().Text("<div class='k-separator'></div>").Encoded(false).Enabled(false);
So an example would be:
items.Add().Text("Menu X").ImageUrl(Url.Content("~/Content/img/menux_16E.png"))
.Items(children =>
{
children.Add().Text("Item 1").ImageUrl(Url.Content("~/Content/img/item1_16E.png"));
children.Add().Text("<div class='k-separator'></div>").Encoded(false).Enabled(false);
children.Add().Text("Item 3").ImageUrl(Url.Content("~/Content/img/item3_16E.png"));
});
To help anyone coming across this issue in the future, you can add a separator directly with the following:
items.Add().Separator(true);
This works since at least v2013.2.918, since that is what I am using.
Justin
I have v2016.3.914 and items.Add().Separator(true); creates an unwanted horizontal scrollbar on an RTL page.
I solved it using this:
inner.Add().Separator(true).HtmlAttributes(new { style = "width: 99%;" });

What is the best practice for opening a jquery dialog from angular?

Heres the html:
<div ng-controller="MyCtrl">
<a ng-click="open()">Open Dialog</a>
<div id="modal-to-open" title="My Title" ui-jq="dialog" ui-options="{width: 350, autoOpen: false, modal: true}">
Dialog Text
</div>
</div>
And here's the js:
function MyCtrl($scope)
{
$scope.open = function () {
$('#modal-to-open').dialog('open');
}
}
Is this the best way to go about doing this? It seems like there could be a better way of opening it without accessing the DOM but I am not sure how I would go about that. The above code works, I am just wondering if this is the way I should go about doing this. Any input is welcome.
"Best practice" is fuzzy ground here. If it's readable and it works, then you're 90% there, IMO, and it's probably fine.
That said, the "angular way" is to keep DOM manipulation out of the controller, and to use dependency injection to make sure everything is testable. Obviously the way you illustrated above would be hard to test, and puts some DOM manipulation in the controller.
I guess what I would do to get the DOM manipulation out of the controller is use a directive:
A simple directive to tie your dialog open call to a click on an element:
app.directive('openDialog', function(){
return {
restrict: 'A',
link: function(scope, elem, attr, ctrl) {
var dialogId = '#' + attr.openDialog;
elem.bind('click', function(e) {
$(dialogId).dialog('open');
});
}
};
});
And in mark up it would be used like so:
<button open-dialog="modal-to-open">Open Dialog</button>
Now, this is obviously very basic. You could get pretty advanced with this if you wanted to, adding additional attributes for different options in the dialog.
You could go even further and add a Service that opened the dialog for you, so you could inject it into your controller or even your directive, and get the call out of there that way. For example:
app.factory('dialogService', [function() {
return {
open: function(elementId) {
$(elementId).dialog('open');
}
};
}]);
And here it is in use. It seems silly because it's essentially the same thing. But that's mostly because it's a very simplistic example. But it at least leverages DI and is testable.
app.controller('MyCtrl', function($scope, dialogService) {
$scope.open = function () {
dialogService.open('#modal-to-open');
};
});
Anyhow. I hope all of that helps you decide what path you want to take. There are a thousand ways to do this. The "right" way is whatever works, allows you to do whatever you need to do (testing or anything else), and is easy to maintain.

DevExpress DateEdit using MVC

I have just started using the
<% Html.DevExpress().DateEdit()
control and i got it to work fine in my ASP.Net MVC application. The code is as shown below:
aspx page:
<% Html.DevExpress().DateEdit(settings =>
{
settings.Name = "EndDate";
settings.Properties.NullText = "dd/MM/yyyy";
settings.Properties.EditFormat = EditFormat.Custom;
settings.Properties.EditFormatString = "dd/MM/yyyy";
settings.Properties.DisplayFormatString = "dd/MM/yyyy";
settings.Date = Model.EndDate;
settings.Width = 100;
}
).Render();
%>
Above this code i have a reference to my javascript file (DateChanges.js) in this file i want to be able to do something like:
$(document).ready(function(){
$("#EndDate").change(function(){
//do whatever i want
});
})
I cant do this now cause using firefox i can see that the actual textbox that this datepicker assigns a value to has be named "EndDate_I". So my question is how can i easily do this since i want to be able to catch the change event of this control and play around with it in jQuery??
The DevExpress MVC Extensions offer their own infrastructure for the client-side processing needs (see the http://help.devexpress.com/#AspNet/CustomDocument6908 help topic to getting started).
It is necessary to handle the client-side ASPxClientDateEdit.DateChanged event, and retrieve the newly selected Date via the client-side ASPxClientDateEdit.GetDate() method. Use the retrieved js Date object for your additional needs:
<script type="text/javascript">
function OnDateChanged(s, e) {
var newDate = s.GetDate();
alert(newDate);
}
</script>
settings.Properties.ClientSideEvents.DateChanged = "OnDateChanged";
There is a rather long Blog post at http://kennytordeur.blogspot.com/2011/05/aspnet-mvc-where-is-clientid_10.html discussing your problem
( I think it is to long to have it pasted here, and the author deserves the credits )
following on from your comment on Mikhails's answer, there will be a property in the global namespace with the name of your control, so it's just like this:
CalculateDayDifference(s.GetDate(), EndDate.GetDate());
All the mvc controls do this, for some you might have to set the EnableClientSideApi property to start using them.

Conditional link in Razor

I have some tabs, and I want to say "if they are currently on the page that this tab refers to, make this a span. Otherwise, make this a link." In pseudo-razor, that would look like this:
#if(CurrentlyOnThisPage) {
<span>
} else {
<a>
}
Tab Content
#if(CurrentlyOnThisPage){
</span>
} else {
</a>
}
Razor (correctly) notes that I'm not closing my beginning tags, and so has trouble parsing this syntax. If the tab content was small, I could use Html.ActionLink, but I've got a few lines of stuff and I'd like to keep the benefits of the HTML editor rather than putting it all into a string. Is there any way to do this?
You can write the tags as literal text to prevent Razor from parsing them:
#:<span>
How about something like this?
#{
var linkOrSpan= CurrentlyOnThisPage ? "span" : "a";
}
<#linkOrSpan><text>Tab Content</text></#linkOrSpan>
No errors about closing tags with this.
Looks a bit cleaner too ihmo.
HTH
Or just write it out explicitly:
#if(CurrentlyOnThisPage)
{
<span>tabcontent</span>
} else {
<a>tabcontent</a>
}

AJAX failure after using jQuery sortable in CakePHP

I used to use scriptaculous in all my CakePHP projects because of its easy helpers. In time, I got more and more into jQuery, and now I want to replace my current scriptaculous scripts with jQuery scripts. Until now, everything has been good... except jQuery sortable.
JQuery sortable runs, but the AJAX call afterwards isn't working right. Now my programmer is on holiday so I've gotta ask you guys:
Old CakePHP code (inside pages_controller.php):
function order($parent_id = 0){
$this->autoRender=false;
//Users with rights may view this
$user = $this->checkRights('pages',true);
//loop through the data sent via the ajax call
foreach ($this->params['form']['page'] as $order => $id){
$this->Page->id = $id;
if(!$this->Page->saveField('order',$order)) {
$this->flash('Really freaky errors are occuring','/');
exit();
}
}
}
My jQuery looks like:
$(".sortable-list").sortable({
update: function() {
$.post('/pages/order/0', {
data: $('.sortable-list').sortable("serialize")
});
}
});
$(".sortable-list").disableSelection();
With Firebug, I see that the AJAX post call produces something like this:
page[]=14&page[]=23&page[]=18&page[]=11&page[]=26&page[]=28
However, it doesn't seem to work. I guess the page[]=id is different that the old scriptaculous format:
pages_0[] 1
pages_0[] 3
pages_0[] 2
Does anyone know how I can adjust the CakePHP file to read the string correctly?
I don't have working php environment to test, but should work basically.
$pages = $_GET['page'];
foreach( $pages as $order => $id)
{
$this->Page->id = $id;
if(!$this->Page->saveField('order',$order)) {
$this->flash('Really freaky errors are occuring','/');
exit();
}
}
PS. Probably you have kind of problem updating "$this->params".
before foreach line, insert
debug($this->params['form']['page']);
and see how page array looks like. then iterate properly.
Ah, finally.. It turned out that jquery's output was: data: '&page_0[]=1etc'. I had to make it page_0 instead of data and its fixed!
So:
$(".sortable-list").sortable({
update: function() {
$.post('/pages/order/0/, $('#pages_0').sortable("serialize", {key: 'pages_0[]'}))
}
});
$(".sortable-list").disableSelection();
I removed the {} from the second argument of $.post and it turned out to be the winner! thx for the help guys!

Resources