I am attempting to use the javascript datepicker to help in showing a calendar and being able to select a date to add/view/edit an event on that date.
I currently have a view that shows the datepicker calender in a div
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Event Calendar</title>
<link rel="stylesheet" href="/Content/themes/base/jquery-ui.css">
<script src="/Scripts/jquery-1.10.2.js"></script>
<script src="/Scripts/jquery-ui-1.10.4.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<script>
$(function () {
$("#datepicker").datepicker();
});
</script>
</head>
<body>
Date: <div id="datepicker"></div>
</body>
</html>
I have a model Todays events that will show the events for the day
namespace TryEvents2.Models
{
public class TodaysEventsViewModel
{
public List<Event> events;
}
}
a model for the specific events
namespace TryEvents2.Models
{
[Bind(Exclude = "Id")]
public class Event
{
[ScaffoldColumn(false)]
public int Id { get; set; }
[DisplayName("Start Date")]
public DateTime Start { get; set; }
[DisplayName("End Date")]
public DateTime End { get; set; }
[DisplayName("Event Details")]
public string Message { get; set; }
[DisplayName("User")]
public string UserName { get; set; }
public void setEvent()
{
}
}
}
a model for the database calendar entities
namespace TryEvents2.Models
{
public class CalendarEntities : DbContext
{
public DbSet<Event> Events { get; set; }
}
}
I have a home controller of the following
namespace TryEvents2.Controllers
{
public class HomeController : Controller
{
CalendarEntities db = new CalendarEntities();
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
public PartialViewResult GetWEntitiesByDate(DateTime date)
{
var entities = db.Events.Where(x => x.Start == date.Date);
var todaysEvents = new TodaysEventsViewModel {events = entities.ToList() };
return PartialView("_TodaysEvents", todaysEvents);
}
}
}
I am having difficulties going from here on creating the methods necessary to CRUD the calendar events and the view that would be displaying them. I am wanting to make the standard datepicker element bigger and have a popup window for the event detail display.
Can anyone help with this?
In my few experience doing something like that is quite difficult with jquery UI datepicker. If you want a calendar to works as a datepicker and able to edit events and shows depending on the day I think the best solution for you is Arshaw Fullcalendar
FullCalendar
This is a calendar (not a datepicker) but you can create custom events to make it works as a datepicker-calendar for your purposes. You can choose a date an render your events from a specific date. You are using MVC so for bringing the date you need JSON like this
public ActionResult GetEvents()
{
//code to return the events from DB
return Json(evevtsObject,JsonRequestBehavior.AllowGet);
}
And for the events to load on the calendar you need to call the "events" function from the calendar.
events: function (startdate, enddate, callback) {
var url = "Controller/GetEvents";
$.getJSON(url,
function (result) {
if (result != null) {
for (i in result) {
var calEvent = result[i];
calEvent.startdate = new Date(parseInt(calEvent.startdate.replace("/Date(", "").replace(")/", ""), 10));
calEvent.end = new Date(parseInt(calEvent.enddate.replace("/Date(", "").replace(")/", ""), 10));
}
}
var calevents = result;
callback(calevents);
});
}
Hope this helps.
Related
I'm unable to capture a custom Javascript event in a C# WPF mshtml WebBrowser control. I've created the example code below. A button click raises a custom event. I realise that there are easy ways to capture a button click event. I need to use a custom event. I've used a button just for this example and testing. What am I doing wrong?
XAML file:
<Window x:Class="WebEvent2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<WebBrowser Name="webBrowser1" Loaded="webBrowser1_Loaded" LoadCompleted="webBrowser1_LoadCompleted"></WebBrowser>
</Grid>
</Window>
C# file:
namespace WebEvent2{
public partial class MainWindow : Window{
public MainWindow(){
InitializeComponent();
}
private void webBrowser1_Loaded(object sender, RoutedEventArgs e{
webBrowser1.Navigate(#"file:///D:/test.html");
}
private void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e){
try{
var evtListener = new EventListener();
var window = ((IHTMLDocument2)webBrowser1.Document).parentWindow as IHTMLWindow3;
window.attachEvent("MyCustomEvent", evtListener);
// Also not working:
// ((HTMLDocument)webBrowser1.Document).attachEvent("MyCustomEvent", evtListener);
}catch (UnauthorizedAccessException err){
Console.WriteLine("OOPS: " + err);
}
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
public class EventListener{
[DispId(0)]
public void handler(IHTMLEventObj evt){
MessageBox.Show("message received");
}
}
}
}
HTML file:
<html>
<head>
<title>Test page</title>
<script>
function sendCustomEvent() {
var event;
if (typeof(Event) === 'function') {
event = new Event('MyCustomEvent');
} else {
event = document.createEvent('HTMLEvents');
event.initEvent('MyCustomEvent', true, false);
}
document.dispatchEvent(event);
}
</script>
</head>
<body>
<button onclick="sendCustomEvent()">Send custom event</button>
</body>
</html>
I was able to achieve the required functionality by using the WebBrowser controls 'ObjectForScripting' property. Nice and simple.
XAML remains the same as above.
WebInterface.cs:
namespace WebEvent2
{
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class WebInterface
{
public void callMe()
{
MessageBox.Show("hello");
}
}
}
MainWindow.xaml.cs:
namespace WebEvent2
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
WebInterface wi = new WebInterface();
private void webBrowser1_Loaded(object sender, RoutedEventArgs e)
{
webBrowser1.ObjectForScripting = wi;
webBrowser1.Navigate(#"file:///D:/test.html");
}
}
}
test.html:
<html>
<head>
<title>Test page</title>
</head>
<body>
<button onclick="window.external.callMe()">Send custom event</button>
</body>
</html>
I am brand new on Apache Wicket and I need to set value on a Java attribute. This value comes from a var on JS filled by a specific function from a specific GIS lib (https://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html). This setting must be triggered by some component behavior.
Here is a simplified example code:
Wicket web page:
public class MapPage extends WebPage {
private static final long serialVersionUID = 1L;
private Integer coordinates;
// getters and setters
}
Wicket html:
<html xmlns:wicket="http://wicket.apache.org">
<head>
<!-- metas, scripts, and css imports -->
</head>
<body>
<script>
// component declarations
var coordinates = ''
map.on('draw:edited', function (e) {
e.layers.eachLayer(function(layer) {
coordinates = toWKT(layer);
// send coordinates to coordinates java attribute ??? how??
});
});
</script>
</body>
Thanks a lot!
This is a piece of code from one of my projects, where I want to handle a click on a (HighCharts) chart. It passes data to Wicket and Wicket then updates another panel to display details related to the click.
The relevant javascript part, where interactionurl is actually the callbackScript that is generated by the behavior later on:
interactionurl(JSON.stringify(myDataToPass));
The behaviour:
this.add( this.interactionbehavior = new AbstractDefaultAjaxBehavior()
{
#Override
protected void respond( final AjaxRequestTarget target )
{
RequestCycle cycle = RequestCycle.get();
WebRequest webRequest = (WebRequest) cycle.getRequest();
String param1 = webRequest.getQueryParameters().getParameterValue( "mydict" ).toString( "" );
//param1 contains the JSON map passed from javascript.
//you can also do stuff now, like replacing components using ajax
}
#Override
protected void updateAjaxAttributes( AjaxRequestAttributes attributes )
{
super.updateAjaxAttributes( attributes );
attributes.getExtraParameters().put( "mydict", "__PLACEHOLDER__" );
}
#Override
public CharSequence getCallbackScript()
{
String script = super.getCallbackScript().toString().replace( "\"__PLACEHOLDER__\"", "data" );
return script;
}
} );
You only need to pass the interaction url to the page on some moment. For this you can use renderHead in the component that has the behaviour:
#Override
public void renderHead( final IHeaderResponse response )
{
...
//use the `setupCallback` to store the callback script somewhere.., I store it in 'interactionurl'
String script = String.format( " setupCallback(this.interactionbehavior.getCallbackScript()); ");
response.render( OnDomReadyHeaderItem.forScript( script )
}
I'm constructing a MVC5 Web App and want to make a dynamic page view by using Knockout.js. However, I have found that Knockout.Mapping doesn't seem to work correctly in my project.
As you see Intellisense does not the suggestion for the mapping plugin (I have included the reference of the plugin in the _reference.js). And it fails to show the second alert written when I complete this line forcibly.
Do I have to do something more to make it work correctly?
#if (false)
{
<script src = "~/Scripts/knockout-3.4.0.js" ></script >
<script src = "~/Scripts/knockout.mapping-latest.js"></script >
}
<script type="text/javascript" src="#Url.Content("~/Scripts/knockout-3.4.0.js")"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/knockout.mapping-latest.js")"></script>
//~~body~~//
<script type="text/javascript">
alert("1");
var json = '#Html.Raw(Json.Encode(Model))';
b = ko.mapping.fromJson(json); //"mapping" is not suggested when "ko." is put.
//b = ko.mapping.fromJson(Model); //mistake at the original post
ko.applyBindings(b);
alert("2"); // not showed when the previous two lines is active.
</script>
Take a look at the help available here.
I think the example you will need to create your mapping is this:
ko.mapping.fromJS(#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model)))
Try this.
var ViewModel = function() {
var self = this;
self.formData2 = ko.mapping.fromJS(#Html.Raw(Json.Encode(Model)));
}
and in your controller:
public ActionResult Index()
{
return View(new ExecutivoViewModel());
}
My ViewModel Class:
public class ExecutivoViewModel
{
public ExecutivoViewModel() { }
public ExecutivoViewModel(Executivo entidade)
{
this.ExecutivoId = entidade.ExecutivoId;
this.Nome = entidade.Nome;
this.Cargo = entidade.Cargo;
this.Inativo = entidade.Inativo;
}
[DisplayName("Executivo ID")]
[Required]
public int ExecutivoId { get; set; }
[DisplayName("Nome")]
[MaxLength(50)]
[Required]
public string Nome { get; set; }
[DisplayName("Cargo")]
[MaxLength(50)]
[Required]
public string Cargo { get; set; }
[DisplayName("Inativo")]
public bool Inativo { get; set; }
Sorry for delaying follow-up. Finally I make it working by using
<script src="~/Scripts/knockout-3.4.0.js"></script>
<script src="~/Scripts/knockout.mapping-latest.js"></script>
//~~body~~//
#section scripts{
<script src="~/Scripts/knockout-3.4.0.js"></script>
<script src="~/Scripts/knockout.mapping-latest.js"></script>
}
and show the suggest by putting
/// <reference path="knockout.mapping-latest.js" />
after the reference of the core library of knockout.js in _reference.js.
tl/dr
The managed C# COM visible object that I created has an event. In the "OnCardRead" method (which fires the actual event) I check to see if the event is subscribed to and it is. The event callback code in javascript appears to never be called.
The story
The project is simple. Create a webpage that "opens" a rfid device and returns the serial number of the card. That portion of has its own set of unit tests and works just fine. To help my self debug if the Serial Ports address is set to 0 then it uses my MockRfidSDK. But for the sake of being thorough here is the code surrounding that (minus the actual RFID code).
IRfidDevice
[Guid("E86A9038-368D-4e8f-B389-FDEF38935B2F"), InterfaceType(ComInterfaceType.InterfaceIsDual), ComVisible(true)]
public interface IRfidDevice
{
[DispId(1)]
int Open();
[DispId(2)]
int Close();
[DispId(3)]
void SetComPort(int comport);
[DispId(4)]
void FlashLed(int led);
}
IRfidEvent
[ComVisible(true), GuidAttribute("0422D916-C11A-474e-947D-45A107038D12"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface IRfidEvent
{
[DispIdAttribute(0x60020000)]
void CardUidReceived(byte sak, ushort atq, string uid);
}
RfidSdk/EmptyRfidSdk
internal interface RfidSdk
{
void Open();
int GetCard();
byte[] SelectCard();
int Close();
void FlashLed(int led);
}
class EmptyRfidSdk : RfidSdk
{
public void Open()
{
}
public int GetCard()
{
System.Threading.Thread.Sleep(10);
return 0x0344;
}
public byte[] SelectCard()
{
System.Threading.Thread.Sleep(2000);
return new byte[] { 0x20, 0x44, 0x03, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37 };
}
public int Close()
{
return 0;
}
public void FlashLed(int led)
{
}
}
RfidDevice
[Guid("873355E1-2D0D-476f-9BEF-C7E645024C32"), ProgId("MasterRDActiveX.RfidDevice"), ClassInterface(ClassInterfaceType.None), ComDefaultInterface(typeof(IRfidDevice)), ComVisible(true), ComSourceInterfaces(typeof(IRfidEvent))]
public class RfidDevice : InternetSafeObject, IRfidDevice
{
private RfidSdk sdk;
private bool _searchForCard = false;
[ComVisible(false)]
public delegate void RfidEventHandler(byte sak, ushort atq, string uid);
public event RfidEventHandler CardUidReceived;
public int Open()
{
try
{
sdk.Open();
_searchForCard = true;
Task.Factory.StartNew(SearchForCard);
return 0;
}
catch (Exception ex)
{
Trace.TraceError(ex.Message);
return -1;
}
}
public int Close()
{
try
{
_searchForCard = false;
sdk.Close();
sdk = null;
return 0;
}
catch (Exception ex)
{
Trace.TraceError(ex.Message);
return -1;
}
}
public void SetComPort(int comport)
{
if (sdk != null) Close();
if (comport < 1)
{
sdk = new EmptyRfidSdk();
}
else
{
sdk = new MasterRDWrapper.MasterRD(comport);
}
}
public void FlashLed(int led)
{
sdk.FlashLed(led);
}
private void SearchForCard()
{
while (_searchForCard)
{
int temp = 0;
while ((temp = sdk.GetCard()) == 0)
{
}
if (temp == sdk.GetCard())
{
var card = sdk.SelectCard();
FireCardUidReceived(card[0], BitConverter.ToUInt16(card, 1), card.Skip(3).ToArray());
}
}
}
private void FireCardUidReceived(byte sak, ushort atq, byte[] uid)
{
if (CardUidReceived != null)
{
Console.Beep(1000,100);
CardUidReceived(sak, atq, BitConverter.ToString(uid));
}
else
{
Console.Beep(2000, 2000);
}
}
So that code is working just fine. Remember the beeps. Short beep means the Event is subscribed to, long beep means it's not being subscribed too.
Now the webpage is where things get a little murky for me. I've looked at a lot of ActiveX tutorials here are some rules about the HTML code. It can't use deprecated HTML tags (IE... OBJECT). Here is my solution thus far
rfidScript.js
function onRfidCard(a, b, c) {
console.log('I am in your event');
document.getElementById('result').innerHTML = c;
console.log('all done in your event');
}
function tryRfid(rfidDevice) {
var uidTag = document.getElementById('result');
var comPort = parseInt(document.getElementById('comPortBox').value);
if (rfidDevice != null) {
rfidDevice.SetComPort(comPort);
if (rfidDevice.Open() === 0) {
uidTag.innerHTML = "Please Tap Card";
}
else {
document.getElementById('error').innerHTML = "Failed to Open";
}
}
}
function closeRfid(rfidDevice) {
rfidDevice.Close();
}
and last bit the html code
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>RFID ActiveX Test</title>
<!--//C:\Users\snyder\Source\Repos\xPD\MasterRDActiveX\MasterRDActiveX\bin\Debug\testRfid.html-->
<script type="text/javascript">
var ctrl = new ActiveXObject('MasterRDActiveX.RfidDevice');
eval('function ctrl::CardUidReceived(a,b,c){ onRfidCard(a,b,c); }');
</script>
<script src="rfidScript.js"></script>
</head>
<body>
<h1>This is our Active X Test Page for RFID</h1>
<input type="text" id="comPortBox" /> <br />
<button type="button" onclick="tryRfid(ctrl);">Open</button>
<button type="button" onclick="closeRfid(ctrl);">Close</button>
<h2>
<output id="error" style="color: red;"></output>
<output id="result"></output>
</h2>
</body>
</html>
I fire up IE, put 0 in the textbox, click open and I hear 1 short beep(and only one.. not sure why on that one as I would expect a beep every 2 seconds see note1), but I don't see any text show up in the result output tag (and I've tried using alert to no avail.) So why?????? what am I missing?
Note 1 - Earlier when I was getting long beeps it would long beep over and over again as I would expect.
This is the entire Java code I've used. I will explain in more detail below...
public class Test7 extends Activity {
//debug
private final static String TAG = "JSInterface";
private WebView wv;
private class JSInterface {
private WebView wv;
// Variables to manage interfacing with JS
private String returnValue;
private boolean canReadReturnValue;
private Lock lockOnJS;
private Condition condVarOnJS;
public JSInterface (WebView wv) {
this.wv = wv;
this.canReadReturnValue = false;
this.lockOnJS = new ReentrantLock();
this.condVarOnJS = lockOnJS.newCondition();
}
public void setReturnValue(String ret) {
lockOnJS.lock();
returnValue = ret;
canReadReturnValue = true;
condVarOnJS.signal();
lockOnJS.unlock();
Log.d(TAG, "returnValue = " + returnValue);
}
public String getReturnValue() {
Log.d(TAG, "enter in getReturnValue");
lockOnJS.lock();
while (!canReadReturnValue) {
try {
Log.d(TAG, "get wait...");
condVarOnJS.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lockOnJS.unlock();
Log.d(TAG, "returnValue: " + returnValue);
return returnValue;
}
public String getNewString() {
wv.loadUrl("javascript:JSInterface.setReturnValue(createNewString())");
return getReturnValue();
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
wv = (WebView) findViewById(R.id.webView1);
wv.getSettings().setJavaScriptEnabled(true);
wv.addJavascriptInterface(new JSInterface(wv), "JSInterface");
wv.loadUrl("file:///android_asset/prova7.html");
}
public void button1(View v) {
wv.loadUrl("javascript:func('1')");
}
}
And it seems work fine.
You can see that I've got a button (that we can call button1), and clicking on it, it tries to execute a JS method, called func().
public void button1(View v) {
wv.loadUrl("javascript:func('1')");
}
Inside this JS method, I have to call another Java method. This is the code:
function func(id) {
document.getElementById(id).innerHTML = JSInterface.getNewString();
}
I need to return the result of JSInterface.getNewString() to the innerHTML variable.
The code of JSInterface.getNewString() is this:
public String getNewString() {
wv.loadUrl("javascript:JSInterface.setReturnValue(createNewString())");
return getReturnValue();
}
You can see that I use the method setReturnValue and getReturnValue to return the value returned by another JS method. This is the code:
function createNewString() {
return "my New String";
}
The problem is that when I try to set the returnValue, the function createNewString is never executed! If I add a console.log() line, my logCat display nothing!
I cannot understand why this happens.
All the javascript and your JSInterface methods called from javascript are running on the single thread in Android WebView. So while you are waiting in condVarOnJS.await() no javascript can be executed, just because it is executed on the same thread.
Moreover, all the webview instances in your application share the same javascript thread.
In Internet Explorer I found the same problem. You can use setTimeout like this:
function func(id) {
setTimeout(
function(){
document.getElementById(id).innerHTML = JSInterface.getNewString();
},
500);
}
I did the functionality what you intend in that code,for me createNewString() is called,
I will show up the code i used,
In java
,
public String videoPlay(){
System.out.println("videoPlay");
mWebView.loadUrl("javascript:window.demo.setReturnValue(createNewString())");
return getReturnValue();}
public void setReturnValue(String test){
rotValue=test;
System.out.println(test);
}
public String getReturnValue(){
System.out.println("get"+rotValue);
return rotValue;
}
in HTML,
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script>
function inform(){
alert('et');
document.getElementById('myText').value=window.demo.videoPlay();
alert('et');
}
function createNewString() {
return "my New String";
}
</script>
</head>
<body onload="init()">
<form>
<input type='text' id='myText' />
<input type="button" name="test" value="Click me" onclick="inform()">
</form>
</body>
</html>
The function getter and setter called and values also set, but i have the output log as..
11-08 19:18:17.155: INFO/System.out(847): videoPlay
11-08 19:18:17.165: INFO/System.out(847): getnull
11-08 19:18:17.875: INFO/System.out(847): my New String
videoPlay called from JS and createnewString() also called from java to JS , but it returns the value before it set , because i don`t what is the purpose to use lock , even i tried using lock as you did for that it will print
11-08 19:18:17.155: INFO/System.out(847): videoPlay
11-08 19:18:17.165: INFO/System.out(847): getnull
using lock also the function callback works in wrong manner, you need work on locks.