Here my problem:
I have an input text and behind a date picker ui: and I would like to get the datepicker's value in razor:
Index.cshtml
<input id="datePickerCalendar" type= "text"/>
<script type="text/javascript">
$(document).ready(function () {
$('#datePickerCalendar').datepicker({
altFormat: "dd-mm-yy",
dayNamesMin: ["Di", "Lu", "Ma", "Me", "Je", "Ve", "Sa"],
monthNames: ["Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"],
changeMonth: true,
onSelect: function () {
/*('#datePickerCalendar').change(loadCalendar());*/
}
});
});
</script>
<table border="1" class="tableCalendar" id="calendar">
<caption> Veuillez sélectionner l'horaire souhaité </caption>
<th id="court"></th>
#foreach(var item in Model) {
foreach(var court in item.TennisCourts){
if (court.Outside == true)
{
<td id="court" class="court">Court n°#court.Number (Extérieur)</td>
}
else
{
<td id="court" class="court">Court n°#court.Number (Intérieur)</td>
}
}
}
#foreach (var item in Model)
{
var chooseDate = $('#datePickerCalendar').value; // here ! This instruction is not correct...
}
I'm Building a dynamic calendar that allow the user to make a reservation for a tennis court...
So, my questions are:
1)How to get the value from the datepicker in razor ?
2)How can I get the value every time when the user change the date ?
Thanks in advance
You need to post your value to a action method on the controller, surround the field with a form
#using (Html.BeginForm("Controller", "Action", FormMethod.Post))
{
}
Then change your field into a server side rendered one (So the model binder can capture the new value)
#Html.TextBoxFor(m => m.MyDate)
The action method needs to take the model as argument and it needs to have the DateTime property named MyDate
edit:
If you will be sending values from the server you need to be sure the client datepicker and the serer uses the same date format. This is a bit tricky, but I did this with the globalize jquery plugin, you have to choose if you want to hardcode the ui culture, or if the sever will use the client culture. This is done in web.config
Hardcoded
<globalization culture="se-SE" uiCulture="se-SE" enableClientBasedCulture="false" />
Client chooses
<globalization enableClientBasedCulture="true" />
edit2
Sorry for all my edits :D
A good way for sending server settings like datetime and such is to create a settings razor view and change its mime type to javascript, also be sure to have caching otherwise the client will load it every time
#{
Layout = null;
Response.Expires = 120;
Response.CacheControl = "public";
Response.ContentType = "text/javascript";
}
MyAppName = {};
MyAppName.settings = {
culture: "#Thread.CurrentThread.CurrentCulture.Name",
timeFormat: "#Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortTimePattern.ToLower()",
dateFormat: "#Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern.ToLower().Replace("yyyy", "yy")",
}
Related
**I have created a custom edit form for a SharePoint online custom list. Where I have created a custom button via which I will start a Workflow.
the issue is I am not able to call that function on button click. I have used a single comma also for the function call
I have created a custom edit form for a SharePoint online custom list. Where I have created a custom button via which I will start a Workflow.
The issue is I am not able to call that function on button click. I have used a single comma also for function call**
HTML Button Code:
<td class="ms-toolbar" nowrap="nowrap" align="right">
<input type="button" runat="server" value="Assign To Next Step" name="AssignToNextStep" onClick="startWorkflow()"/>
</td>
JavaScript Function Code is:
<script type="text/javascript">
function startWorkflow()
{
alert("Inside");
try
{
showInProgressDialog();
var ctx = SP.ClientContext.get_current();
var wfManager = SP.WorkflowServices.WorkflowServicesManager.newObject(ctx, ctx.get_web());
var subscription = wfManager.getWorkflowSubscriptionService().getSubscription("My Workflow ID");
ctx.load(subscription, 'PropertyDefinitions');
ctx.executeQueryAsync(
function(sender, args)
{
wfManager.getWorkflowInstanceService().startWorkflow(subscription, "");
ctx.executeQueryAsync(
function(sender, args)
{
closeInProgressDialog();
},
function (sender, args)
{
closeInProgressDialog();
alert(errorMessage);
});
});
}
catch(ex)
{
alert(ex);
dlg.close();
}
}
</script>
That Function was out of Scope. I mean I just changed the place of that function.
How do you insert the code? Have you checked the developer tools in your browser if it shows any errors?
Try to add
onClick="startWorkflow();return false;"
In your code.
I want to send the value of textbox to the Action Method for searching the technology for that i want to get the value of textbox in Action.
I have the following code :-
#Html.TextBox("technologyNameBox", "", new { id = "technologyName", #class = "form-control", #placeholder = "Search For Technology" })
<span class="input-group-btn" style="text-align:left">
<a class="btn btn-default" id="searchTechnology"
href="#Url.Action("SearchTechnology", "Technology",
new {technologyName="technologyName",projectId=ProjectId })">
<span class="glyphicon glyphicon-search "></span>
</a>
</span>
Question :- How to get the value of textbox "technologyNameBox" in Action ?
Please help me out. Thanks in Advance!
You'd have to append the value to the URL via JavaScript before directing the user. Using jQuery (since that generally comes packaged with ASP.NET), it might look something like this (with a good bit of manual conditional checks for blank values or query string parameters):
$('#searchTechnology').click(function (e) {
e.preventDefault();
var url = '#Url.Action("SearchTechnology", "Technology", new { projectId=ProjectId })';
var technologyName = $('#technologyName').val();
if (technologyName.length < 1) {
// no value was entered, don't modify the url
window.location.href = url;
} else {
// a value was entered, add it to the url
if (url.indexOf('?') >= 0) {
// this is not the first query string parameter
window.location.href = url + '&technologyName=' + technologyName;
} else {
// this is the first query string parameter
window.location.href = url + '?technologyName=' + technologyName;
}
}
return false;
});
The idea is that when the user clicks that link, you would fetch the value entered in the input and append it to the URL as a query string parameter. Then redirect the user to the new modified URL.
I'd like to extend the users content definition to include a short bio and picture that can be viewed on every blog post of an existing blog. I'm unsure of what the best method to do this is.
I have tried extending the User content type with those fields, but I can't seem to see them in the Model using the shape tracing tool on the front end.
Is there a way to pass through fields on the User shape in a blog post? If so, what is the best way to do it?
I also have done this a lot, and always include some custom functionality to achieve this.
There is a way to do this OOTB, but it's not the best IMO. You always have the 'Owner' property on the CommonPart of any content item, so in your blogpost view you can do this:
#{
var owner = Model.ContentItem.CommonPart.Owner;
}
<!-- This automatically builds anything that is attached to the user, except for what's in the UserPart (email, username, ..) -->
<h4>#owner.UserName</h4>
#Display(BuildDisplay((IUser) owner))
<!-- Or, with specific properties: -->
<h1>#T("Author:")</h1>
<h4>#owner.UserName</h4>
<label>#T("Biography")</label>
<p>
#Html.Raw(owner.BodyPart.Text)
</p>
<!-- <owner content item>.<Part with the image field>.<Name of the image field>.FirstMediaUrl (assuming you use MediaLibraryPickerField) -->
<img src="#owner.User.Image.FirstMediaUrl" />
What I often do though is creating a custom driver for this, so you can make use of placement.info and follow the orchard's best practices:
CommonPartDriver:
public class CommonPartDriver : ContentPartDriver<CommonPart> {
protected override DriverResult Display(CommonPart part, string displayType, dynamic shapeHelper) {
return ContentShape("Parts_Common_Owner", () => {
if (part.Owner == null)
return null;
var ownerShape = _contentManager.BuildDisplay(part.Owner);
return shapeHelper.Parts_Common_Owner(Owner: part.Owner, OwnerShape: ownerShape);
});
}
}
Views/Parts.Common.Owner.cshtml:
<h1>#T("Author")</h1>
<h3>#Model.Owner.UserName</h3>
#Display(Model.OwnerShape)
Placement.info:
<Placement>
<!-- Place in aside second zone -->
<Place Parts_Common_Owner="/AsideSecond:before" />
</Placement>
IMHO the best way to have a simple extension on an Orchard user, is to create a ContentPart, e.g. "UserExtensions", and attach it to the Orchard user.
This UserExtensions part can then hold your fields, etc.
This way, your extensions are clearly separated from the core user.
To access this part and its fields in the front-end, just add an alternate for the particular view you want to override.
Is there a way to pass through fields on the User shape in a blog post?
Do you want to display a nice picture / vita / whatever of the blog posts author? If so:
This could be your Content-BlogPost.Detail.cshtml - Alternate
#using Orchard.Blogs.Models
#using Orchard.MediaLibrary.Fields
#using Orchard.Users.Models
#using Orchard.Utility.Extensions
#{
// Standard Orchard stuff here...
if ( Model.Title != null )
{
Layout.Title = Model.Title;
}
Model.Classes.Add("content-item");
var contentTypeClassName = ( (string)Model.ContentItem.ContentType ).HtmlClassify();
Model.Classes.Add(contentTypeClassName);
var tag = Tag(Model, "article");
// And here we go:
// Get the blogPost
var blogPostPart = (BlogPostPart)Model.ContentItem.BlogPostPart;
// Either access the creator directly
var blogPostAuthor = blogPostPart.Creator;
// Or go this way
var blogPostAuthorAsUserPart = ( (dynamic)blogPostPart.ContentItem ).UserPart as UserPart;
// Access your UserExtensions part
var userExtensions = ( (dynamic)blogPostAuthor.ContentItem ).UserExtensions;
// profit
var profilePicture = (MediaLibraryPickerField)userExtensions.ProfilePicture;
}
#tag.StartElement
<header>
#Display(Model.Header)
#if ( Model.Meta != null )
{
<div class="metadata">
#Display(Model.Meta)
</div>
}
<div class="author">
<img src="#profilePicture.FirstMediaUrl"/>
</div>
</header>
#Display(Model.Content)
#if ( Model.Footer != null )
{
<footer>
#Display(Model.Footer)
</footer>
}
#tag.EndElement
Hope this helps, here's the proof:
I have hierarchical JSON structure that differs after every new JSON from the server side. Given my template, this does not adequately show model update.
After troubleshooting, I noticed the mapping plugin does not correctly map child elements(or perhaps I am doing it incorrectly)
I can also track the memory keeps growing for every update in the datamodel.
Any help will be greatly appreciated.
This simple test is up on JSFiddle http://jsfiddle.net/Bru5a/1/
Here is my view
<div id="view">
The behavior is different depending on the order you load the model.
First
Second
Third
<span data-bind="text: name"></span>
<div data-bind="if: $data.child">
<b data-bind="text: child.name"></b>
<div data-bind="if: child.sub">
<b data-bind="text: child.sub.name"></b>
</div>
</div>
</div>
Here is my Javascript:
var BaseModel = function(om) {
ko.mapping.fromJS(om, {}, this);
};
var resourceModel = null;
function applyJson(json) {
try {
if(resourceModel){
ko.mapping.fromJS(json, {} ,resourceModel);
} else {
resourceModel = new BaseModel(json);
ko.applyBindings(resourceModel, $("#view")[0]);
}
} catch(e) {
alert(e);
}
}
function loadFirst() {
var json = { "name" : "1",
"child" : {
"name": "Child One"
}
};
applyJson(json);
}
function loadSecond() {
var json = { "name" : "2" };
applyJson(json);
}
function loadThird() {
var json = { "name" : "3",
"child" : {
"name": "Child Three",
"sub" : {
"name" : "Third Sub Child"
}
}
};
applyJson(json);
}
$(document).ready(function () {
$("#second").click(function(){
loadSecond();
});
$("#third").click(function(){
loadThird();
});
$("#first").click(function(){
loadFirst();
});
});
What is happening in your case, is that knockout is behaving as designed.
To see what is happening, add the following line inside your outer div
<div data-bind="text: ko.toJSON($root)"></div>
You can see what is being bound in your view model.
To understand what is being displayed, Watch what is happening the to the viewmodel as you select the different links. As you update your model, you will see that once a property has been created, it remains there. This is by design of how the mapper works.
Next, you have to remember that ko.applyBindings is only being called ONE time. Therefore, the binding are only being applied one time to the properties that are in existence at the time the applyBindings is called. When you add properties to your viewmodel later, they will not automatically be bound to the data-bindings.
To make this example work, you will need to re-think your view model so that all the properties are present at the time you call apply bindings.
EDIT
I've edited your fiddle to show what I was talking about at http://jsfiddle.net/photo_tom/Bru5a/5/
When should destroy be called? Does it ever get called automatically by YUI lifecycle? Does the page unload cause the YUI lifecycle to call destroy on all objects created during the page processing? I have been working under the assumption that I need to make all my own calls to destroy but that gets hairy when ajax calls replace sections of code that I had progressively enhanced. For example:
<div id="replaceMe">
<table>
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
</table>
<script>
YUI().use('my-lib', function(Y) {
Y.mypackage.enhanceTable("replaceMe");
});
<script>
</div>
The my-lib module basically adds a click handler and mouseover for each row:
YUI.add('my-lib', function(Y) {
function EnhancedTable(config) {
EnhancedTable.superclass.constructor.apply(this, arguments);
}
EnhancedTable.NAME = "enhanced-table";
EnhancedTable.ATTRS = {
containerId : {},
onClickHandler : {},
onMouseoverHandler : {},
onMouseoutHandler : {}
};
Y.extend(EnhancedTable, Y.Base, {
_click : function(e) {
//... submit action
},
destructor : function() {
var onClickHandler = this.get("onClickHandler"),
onMouseoverHandler = this.get("onMouseoverHandler"),
onMouseoutHandler = this.get("onMouseoutHandler");
onClickHandler && onClickHandler.detach();
onMouseoverHandler && onMouseoverHandler.detach();
onMouseoutHandler && onMouseoutHandler.detach();
},
initializer : function(config) {
var container = Y.one("[id=" + this.get("containerId") + "]");
this.set("container", container);
this.set("onMouseoverHandler", container.delegate("mouseover",
this._mouseover, "tr", this ));
this.set("onMouseoutHandler", container.delegate("mouseout",
this._mouseout, "tr", this ));
this.set("onClickHandler", container.delegate("click",
this._click, "tr", this ));
},
_mouseout : function(e) {
e.currentTarget.removeClass("indicated");
},
_mouseover : function(e) {
e.currentTarget.addClass("indicated");
}
});
Y.namespace("mypackage");
Y.mypackage.enhanceTable = function(containerId) {
var enhancedTable new EnhancedTable({containerId:containerId});
};
}, '0.0.1', {
requires : [ 'base', 'node' ]
});
The click handler would submit a request back to my application that would change the page. Do I need to remember all the enhancedTable objects and have an onunload handler call the destroy method of each? Or does the YUI framework take care of this?
The last part of this quesiton is, I also have code outside of this that replaces the whole table by replacing the content of the <div id="replaceMe">. In doing so, the script would get re-run and augment the new <table> with a new EnhancedTable. Do I need to remember the old table, and destroy it before the new table clobbers it?
Instead of setting handlers as attributes I'd store them all in an array like this:
this._handlers = [
container.delegate("mouseover", this._mouseover, "tr", this ),
container.delegate("mouseout", this._mouseout, "tr", this ),
container.delegate("click", this._click, "tr", this )
];
Then add a destructor method that does the following
destructor : function() {
new Y.EventTarget(this._handlers).detach();
}
It accomplishes the same thing but with way less work on your part!
Ideally instead of running this against each table you'd attach all your delegates to #replaceMe so that it wouldn't need to be recreated each time you changed the content, no matter where that happened from.
YUI won't automatically call .destroy() for you on unload, it will clean up DOM subs though. The above is extra credit that's really only necessary if you are going to be destroying the object yourself.