WinForms CefSharp Browser LocalStorage not working - c#

I'm trying to use CefSharp browser control at WinForms application along with the LocalStorage mechanism.
The problem is that the browser control in the application changes to LocalStorage don't affect other browser windows and it doesn't get changes from other chrome browser windows. The HTML works inside native chrome browser and changes localstorage and get changes notifications. What do I miss?
C# Code:
public Form1()
{
InitializeComponent();
CefSharp.Cef.Initialize();
_browser = new ChromiumWebBrowser(URL_TO_LOAD);
_browser.BrowserSettings = new CefSharp.BrowserSettings()
{
ApplicationCacheDisabled = false,
FileAccessFromFileUrlsAllowed = true,
JavascriptDisabled = false,
LocalStorageDisabled = false,
WebSecurityDisabled = true,
JavaScriptOpenWindowsDisabled = false,
JavascriptDomPasteDisabled = false
};
_browser.Load(URL_TO_LOAD);
splitContainer1.Panel1.Controls.Add(_browser);
}
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=620"/>
<title>HTML5 Demo: Storage Events</title>
</head>
<body>
<div>
<p>
<label for="data">Your test data:</label> <input type="text"
name="data" value="" placeholder="change me" id="data" />
</p>
<p id="fromEvent">Waiting for data via<code>storage</code>event...
</p>
</div>
<SCRIPT type="text/javascript">
var addEvent = (function () {
if (document.addEventListener) {
return function (el, type, fn) {
if (el && el.nodeName || el === window) {
el.addEventListener(type, fn, false);
} else if (el && el.length) {
for (var i = 0; i < el.length; i++) {
addEvent(el[i], type, fn);
}
}
};
} else {
return function (el, type, fn) {
if (el && el.nodeName || el === window) {
el.attachEvent('on' + type, function () { return fn.call(el, window.event); });
} else if (el && el.length) {
for (var i = 0; i < el.length; i++) {
addEvent(el[i], type, fn);
}
}
};
}
})();
</SCRIPT>
<script>
alert("localStorage: " + localStorage);
var dataInput = document.getElementById('data'), output = document
.getElementById('fromEvent');
addEvent(window, 'storage', function(event) {
alert('change notification');
if (event.key == 'storage-event-test') {
output.innerHTML = event.newValue;
}
});
addEvent(dataInput, 'keyup', function() {
localStorage.setItem('storage-event-test', this.value);
});
var curStorageVal = localStorage.getItem('storage-event-test');
if(curStorageVal != null && curStorageVal != '')
{
output.innerHTML = curStorageVal;
}
</script>
</body>
</html>

Unless you set a path for the cache location in a CefSharp.CefSettings object and pass it to the Cef.Initialize() method, every time your app is started, the browser(s) will create a new cache instance, which will be discarded when your app exits.
The cache instance also holds your localStorage data, as well as any cookies (you might want to keep a user signed in?) and other things as well.
I had the same problem, but found a solution here: https://github.com/cefsharp/CefSharp/blob/v39.0.2/CefSharp.Example/CefExample.cs#L30-L32
One minimal solution is to add this to your application's startup procedure, like in your Program.Main or in your case, your Form1 class's constructor:
var settings = new CefSharp.CefSettings
{
CachePath = "cache"
};
CefSharp.Cef.Initialize(settings);

1.Get these from NuGet package manager :
using CefSharp;
using CefSharp.WinForms;
2.Create instance for you CefSetting :
CefSettings settings = new CefSettings();
settings.CachePath = #"C:\localstorage";

Related

Web Scraping Java Sites with HtmlAgilityPack

Let me start out by saying that I am no pro at web scraping. I can do the basics on most platforms, but that's about it.
I am trying to create the foundation for a web application that can helps users reinforce their language learning by generating additional data, metrics, as well as create new tools for self-testing. The Duolingo website is not offering up any sort of API so my next thought for now is just to scrape https://www.duome.eu/. I wrote a quick little scraper but didn't realize that the site was java. In the following example, it is my wish to collect all of the words from the Words tab that contain anchors:
using System;
using HtmlAgilityPack;
using System.Net.Http;
using System.Text.RegularExpressions;
namespace DuolingoUpdate
{
class Program
{
static void Main(string[] args)
{
string userName = "Podus";
UpdateDuolingoUser(userName);
Console.ReadLine();
}
private static async void UpdateDuolingoUser(string userName)
{
string url = "https://www.duome.eu/" + userName + "/progress/";
// Create the http client connection
HttpClient httpClient = new HttpClient();
var html = await httpClient.GetStringAsync(url);
// Store the html client data in an object
HtmlDocument htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(html);
//var words = htmlDocument.DocumentNode.Descendants("div")
// .Where(node => node.GetAttributeValue("id", "")
// .Equals("words")).ToList();
//var wordList = words[0].Descendants("a")
// .Where(node => node.GetAttributeValue("class", "")
// .Contains("wA")).ToList();
Console.WriteLine(html);
}
}
}
The html object of the above code contains:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="google" value="notranslate">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Duolingo ยท Podus # duome.eu</title>
<link rel="stylesheet" href="/style.css?1548418871" />
<link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<script src="//code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
if("".length==0){
var visitortime = new Date();
var visitortimezone = "GMT " + -visitortime.getTimezoneOffset()/60;
//localStorage.tz = visitortimezone;
//timezone = Date.parse(localStorage.tz);
//timezone = localStorage.tz;
//console.log(timezone);
$.ajax({
type: "GET",
url: "/tz.php",
data: 'time='+ visitortimezone,
success: function(){
location.reload();
}
});
}
});
</script>
</head>
<body>
<noscript>Click here to adjsut XP charts to your local timezone. </noscript>
<!-- Yandex.Metrika counter --> <script type="text/javascript" > (function (d, w, c) { (w[c] = w[c] || []).push(function() { try { w.yaCounter47765476 = new Ya.Metrika({ id:47765476, clickmap:true, trackLinks:true, accurateTrackBounce:true }); } catch(e) { } }); var n = d.getElementsByTagName("script")[0], s = d.createElement("script"), f = function () { n.parentNode.insertBefore(s, n); }; s.type = "text/javascript"; s.async = true; s.src = "https://mc.yandex.ru/metrika/watch.js"; if (w.opera == "[object Opera]") { d.addEventListener("DOMContentLoaded", f, false); } else { f(); } })(document, window, "yandex_metrika_callbacks"); </script> <noscript><div><img src="https://mc.yandex.ru/watch/47765476" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <!-- /Yandex.Metrika counter -->
</body>
</html>
But if you go to the actual url https://www.duome.eu/Podus/progress/, the site contains a ton of script. So upon inspection the first problem is that I am not getting the html that I see in the browser. The second problem is that if you view source, its nothing like what is in inspect and I don't see anything in source that would lead me to isolate the data from div id="words".
Given my lackluster knowledge of java built web pages, how do I do this, or is it even possible?
You can access dualingo profile data in JSON format via https://www.duolingo.com/users/<username>
eg. https://www.duolingo.com/users/Podus
This should be much easier than trying to scrape the duome profile page manually.

Google map not properly load in web browser control

I have one html file like Map.Html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title></title>
<script type="text/javascript" src="http://maps.google.com.mx/maps/api/js?sensor=true"></script>
<script type="text/javascript">
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var myOptions = {
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var address = "Ahmedabad, India" //change the address in order to search the google maps
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
var infoWindow = new google.maps.InfoWindow({
content: 'Hello'
});
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.open(map, marker);
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:100%; height:100%"></div>
</body>
</html>
then i load this html file in webbrowser control DocumentText using below code:
using (StreamReader reader = new StreamReader(System.Windows.Forms.Application.StartupPath + "\\Map.html"))
{
_mapHTML = reader.ReadToEnd();
}
webBrowser1.DocumentText = _mapHTML;
but map not load properly.
zoom in/out, Map/Satellite option, Marker are showing but one white layer on map display.
SOLVED -- for me at least.
For some reason, the Webbrowser control is defaulting to a bad version (experimental?). I changed my initialization script to specify the current 3.3 version and everything is back to normal.
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.3"></script>

Save button does not fire code behind event

This is a simple MVC4 application with single drop down list. When I click the Save button an event for SaveWorkRequestDetails should fire, seen below as the [HttpPost], but it doesn't for some reason. I am seeing a 500 error stating that myMachine:12345/WorkRequest/SaveWorkRequestDetails cannot be found when I hit the Save button. See bottom of post for picture of Console window in Chrome.
Controller
public ActionResult Index()
{
_model = new WorkRequestViewModel()
{
WorkSections = GetWorkSections()
};
return View(_model);
}
[HttpPost]
public JsonResult SaveWorkRequestDetails(WorkRequestViewModel viewModel)
{
// TODO: Save logic goes here
return Json(new {});
}
This is the WorkRequest.js file which should fire the Save event. This does trigger said event IF I DON'T include _model in the return of the View from the ActionResult Index() above, however, the alert seen in the WorkRequest.js file in beforeSend has 'null' when I do that. Clearly, this isn't the intended behavior because I do want those values and the Save button to trigger the [HttpPost].
var WorkRequest = {
PrepareKo: function () {
ko.bindingHandlers.date = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
element.onchange = function () {
var observable = valueAccessor();
observable(new Date(element.value));
}
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var observable = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(observable);
if ((typeof valueUnwrapped == 'string' || valueUnwrapped instanceof String) &&
valueUnwrapped.indexOf('/Date') === 0) {
var parsedDate = WorkRequest.ParseJsonDate(valueUnwrapped);
element.value = parsedDate.getMonth() + 1 + "/" +
parsedDate.getDate() + "/" + parsedDate.getFullYear();
observable(parsedDate);
}
}
};
},
ParseJsonDate: function (jsonDate) {
return new Date(parseInt(jsonDate.substr(6)));
},
BindUIwithViewModel: function (viewModel) {
ko.applyBindings(viewModel);
},
EvaluateJqueryUI: function () {
$('.dateInput').datepicker();
},
RegisterUIEventHandlers: function () {
$('#Save').click(function (e) {
// Check whether the form is valid. Note: Remove this check, if you are not using HTML5
if (document.forms[0].checkValidity()) {
e.preventDefault();
$.ajax({
type: "POST",
url: WorkRequest.SaveUrl,
data: ko.toJSON(WorkRequest.ViewModel),
contentType: 'application/json',
async: true,
beforeSend: function () {
// Display loading image
alert(ko.toJSON(WorkRequest.ViewModel));
},
success: function (result) {
// Handle the response here.
},
complete: function () {
// Hide loading image.
},
error: function (jqXHR, textStatus, errorThrown) {
// Handle error.
}
});
}
});
},
};
$(document).ready(function () {
WorkRequest.PrepareKo();
WorkRequest.BindUIwithViewModel(WorkRequest.ViewModel);
WorkRequest.EvaluateJqueryUI();
WorkRequest.RegisterUIEventHandlers();
});
This is my Index.cshtml
#using Microsoft.Ajax.Utilities
#model WorkRequest.ViewModel.WorkRequestViewModel
#using WorkRequest.Helper
#section styles{
#Styles.Render("~/Content/themes/base/css")
<link href="~/Content/WorkRequest.css" rel="stylesheet" />
}
#section scripts{
#Scripts.Render("~/bundles/jqueryui")
<script src="~/Scripts/knockout-2.2.0.js"></script>
<script src="~/Scripts/knockout.mapping-latest.js"></script>
<script src="~/Scripts/Application/WorkRequest.js"></script>
<script type="text/javascript">
WorkRequest.SaveUrl = '#Url.Action("SaveWorkRequestDetails", "WorkRequest")';
WorkRequest.ViewModel = ko.mapping.fromJS(#Html.Raw(Json.Encode(Model)));
</script>
}
<form>
<div class="mainWrapper">
<table>
<tr>
<td>Work Sections:
</td>
<td>
#Html.DropDownList("WorkSections", Model.WorkSections, new {data_bind="value: WorkRequest.ViewModel.WorkSections"})
</td>
</tr>
</table>
</div>
<br />
<input id="Save" type="submit" value="Save" />
</form>
Now this entire sample is based on a demo I found here: http://www.codeproject.com/Articles/657981/ASP-NET-MVC-4-with-Knockout-Js and I was able to get it working just fine until I tried to populate my own drop down list. I am able to get the data for my drop down list and populate my SelectList without issues and see it on my form.
My View Model
public class WorkRequestViewModel
{
public SelectList WorkSections { get; set; }
}
I have confirmed this SelectList is populated and I see the items in my drop down list but the demo application uses two custom classes to make the controls in the Index.cshtml page observable so that knockout can do its thing...
HtmlExtensions.cs
public static class HtmlExtensions
{
/// <summary>
/// To create an observable HTML Control.
/// </summary>
/// <typeparam name="TModel">The model object</typeparam>
/// <typeparam name="TProperty">The property name</typeparam>
/// <param name="htmlHelper">The <see cref="HtmlHelper<T>"/></param>
/// <param name="expression">The property expression</param>
/// <param name="controlType">The <see cref="ControlTypeConstants"/></param>
/// <param name="htmlAttributes">The html attributes</param>
/// <returns>Returns computed HTML string.</returns>
public static IHtmlString ObservableControlFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel,
TProperty>> expression, string controlType =
ControlTypeConstants.TextBox, object htmlAttributes = null)
{
var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
string jsObjectName = null;
string generalWidth = null;
// This will be useful, if the same extension has
// to share with multiple pages (i.e. each with different view models).
switch (metaData.ContainerType.Name)
{
case "WorkRequestViewModel":
// Where WorkRequest is the Javascript object name (namespace in theory).
jsObjectName = "WorkRequest.ViewModel.";
generalWidth = "width: 380px";
break;
default:
throw new Exception(string.Format("The container type {0} is not supported yet.",
metaData.ContainerType.Name));
}
var propertyObject = jsObjectName + metaData.PropertyName;
TagBuilder controlBuilder = null;
// Various control type creation.
switch (controlType)
{
case ControlTypeConstants.TextBox:
controlBuilder = new TagBuilder("input");
controlBuilder.Attributes.Add("type", "text");
controlBuilder.Attributes.Add("style", generalWidth);
break;
case ControlTypeConstants.Html5NumberInput:
controlBuilder = new TagBuilder("input");
controlBuilder.Attributes.Add("type", "number");
controlBuilder.Attributes.Add("style", generalWidth);
break;
case ControlTypeConstants.Html5UrlInput:
controlBuilder = new TagBuilder("input");
controlBuilder.Attributes.Add("type", "url");
controlBuilder.Attributes.Add("style", generalWidth);
break;
case ControlTypeConstants.TextArea:
controlBuilder = new TagBuilder("textarea");
controlBuilder.Attributes.Add("rows", "5");
break;
case ControlTypeConstants.DropDownList:
controlBuilder = new TagBuilder("div");
controlBuilder.Attributes.Add("class", "dropDownList");
break;
case ControlTypeConstants.JqueryUIDateInput:
controlBuilder = new TagBuilder("input");
controlBuilder.Attributes.Add("type", "text");
controlBuilder.Attributes.Add("style", generalWidth);
controlBuilder.Attributes.Add("class", "dateInput");
controlBuilder.Attributes.Add("data-bind", "date: " + propertyObject);
// date is the customized knockout binding handler. Check PrepareKo method of Person.
break;
default:
throw new Exception(string.Format("The control type {0} is not supported yet.", controlType));
}
controlBuilder.Attributes.Add("id", metaData.PropertyName);
controlBuilder.Attributes.Add("name", metaData.PropertyName);
// Check data-bind already exists, add if not.
if (!controlBuilder.Attributes.ContainsKey("data-bind"))
{
controlBuilder.Attributes.Add("data-bind", "value: " + propertyObject);
}
// Merge provided custom html attributes. This overrides the previously defined attributes, if any.
if (htmlAttributes != null)
{
controlBuilder.MergeAttributes(
HtmlExtensions.AnonymousObjectToHtmlAttributes(htmlAttributes), true);
}
return MvcHtmlString.Create(controlBuilder.ToString());
}
/// <summary>
/// To convert '_' into '-'.
/// </summary>
/// <param name="htmlAttributes">The html attributes.</param>
/// <returns>Returns converted <see cref="RouteValueDictionary"/>.</returns>
private static RouteValueDictionary AnonymousObjectToHtmlAttributes(object htmlAttributes)
{
RouteValueDictionary result = new RouteValueDictionary();
if (htmlAttributes != null)
{
foreach (System.ComponentModel.PropertyDescriptor property in
System.ComponentModel.TypeDescriptor.GetProperties(htmlAttributes))
{
result.Add(property.Name.Replace('_', '-'), property.GetValue(htmlAttributes));
}
}
return result;
}
}
ViewModelConstants.cs
public static class ControlTypeConstants
{
public const string TextBox = "TextBox";
public const string TextArea = "TextArea";
public const string CheckBox = "CheckBox";
public const string DropDownList = "DropDownList";
public const string Html5NumberInput = "Html5NumberInput";
public const string Html5UrlInput = "Html5UrlInput";
public const string Html5DateInput = "Html5DateInput";
public const string JqueryUIDateInput = "JqueryUIDateInput";
}
So the root of my issue is that once the UI is successfully populated with a drop down list containing values, I select one and hit the save button and I see the alert display what is in the model but the Save button is never triggered.
In the example provided from CodeProject a control has this custom ObservableControlFor after #Html, see above class HtmlExtensions. This is what it looks like: #Html.ObservableControlFor(model => model.Name, ControlTypeConstants.TextBox) so I tried to do the same in my example but I don't know how to turn #Html.DropDownList("myList") into #Html.ObservableControlFor... I tried the following #Html.ObservableControlFor(model => model.WorkSections, ControlTypeConstants.DropDownList) but the control is never rendered to the UI and I get the same 500 error as before.
I have tried ViewData in my #Html control but the function is expecting something like model => model.WorkSections
HTML Markup from View Source
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title></title>
<link href="/Content/site.css" rel="stylesheet"/>
<script src="/Scripts/modernizr-2.6.2.js"></script>
<link href="/Content/themes/base/jquery.ui.core.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.resizable.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.selectable.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.accordion.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.autocomplete.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.button.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.dialog.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.slider.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.tabs.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.datepicker.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.progressbar.css" rel="stylesheet"/>
<link href="/Content/themes/base/jquery.ui.theme.css" rel="stylesheet"/>
<link href="/Content/WorkRequest.css" rel="stylesheet" />
</head>
<body>
<form>
<div class="mainWrapper">
<table>
<tr>
<td>Work Sections:
</td>
<td>
<div class="dropDownList" data-bind="value: WorkRequest.ViewModel.WorkSections" id="WorkSections" name="WorkSections"></div>
</td>
</tr>
</table>
</div>
<br />
<input id="Save" type="submit" value="Save" />
</form>
<script src="/Scripts/jquery-1.8.2.js"></script>
<script src="/Scripts/jquery-ui-1.8.24.js"></script>
<script src="/Scripts/knockout-2.2.0.js"></script>
<script src="/Scripts/knockout.mapping-latest.js"></script>
<script src="/Scripts/Application/WorkRequest.js"></script>
<script type="text/javascript">
WorkRequest.SaveUrl = '/WorkRequest/SaveWorkRequestDetails';
WorkRequest.ViewModel = ko.mapping.fromJS({"WorkSectionId":0,"WorkSections":[{"Selected":false,"Text":"308:IPACS","Value":"308"},{"Selected":false,"Text":"312:IPACS","Value":"312"},{"Selected":false,"Text":"301:IPACS","Value":"301"},{"Selected":false,"Text":"316:IPACS","Value":"316"},{"Selected":false,"Text":"307:IPACS","Value":"307"},{"Selected":false,"Text":"318:IPACS","Value":"318"},{"Selected":false,"Text":"313:IPACS","Value":"313"},{"Selected":false,"Text":"319:IPACS","Value":"319"},{"Selected":false,"Text":"315:IPACS","Value":"315"},{"Selected":false,"Text":"310:IPACS","Value":"310"},{"Selected":false,"Text":"300:IPACS","Value":"300"},{"Selected":false,"Text":"302:IPACS","Value":"302"},{"Selected":false,"Text":"304:IPACS","Value":"304"},{"Selected":false,"Text":"306:IPACS","Value":"306"},{"Selected":false,"Text":"309:IPACS","Value":"309"},{"Selected":false,"Text":"305:STORM","Value":"305"},{"Selected":false,"Text":"311:IPACS","Value":"311"},{"Selected":false,"Text":"317:IPACS","Value":"317"},{"Selected":false,"Text":"303:IPACS","Value":"303"},{"Selected":false,"Text":"314:IPACS","Value":"314"}]});
</script>
</body>
</html>
I think your issue may lie in these two lines of code:
data: ko.toJSON(WorkRequest.ViewModel),
contentType: 'application/json',
You should remove the contentType line and change:
data: $.param(WorkRequest.ViewModel)
The issue issue is you are trying to pass the server JSON and it by default accepts application/x-www-form-urlencoded. contentType dictates the format passed back from the server. dataType is what you are looking for however by default .Net MVC wants the default.
If this doesnt work it would be helpful to see the stack trace from the exception that is causing your 500 error, although I would expect the issue is that your model is not binding since your data is in the wrong format.

limit characters in dynamic text box in data list asp.net 3.5

In the JavaScript below I have a problem in that the JavaScript applies only to one text box not to all the text area's because the ID generated in the html is different for all text area's. Any help regarding to this
<font>Maximum Number of characters for this text box is 255.<br>
<textarea runat="server" id="txtAnswerMain" onkeypress="return taLimit(this)" onkeyup="return taCount(this,'myCounter')"
name="Description" rows="7" wrap="physical" cols="40">
</textarea>
this is the java script i am using it works for single text area but when i apply to dynamically created text area it does not work
<script language="Javascript">
maxL = 100;
var bName = navigator.appName;
function taLimit(taObj) {
if (taObj.value.length == maxL) return false;
return true;
}
function taCount(taObj, Cnt) {
objCnt = createObject(Cnt);
objVal = taObj.value;
if (objVal.length > maxL) objVal = objVal.substring(0, maxL);
if (objCnt) {
if (bName == "Netscape") {
objCnt.textContent = maxL - objVal.length;
}
else { objCnt.innerText = maxL - objVal.length; }
}
return true;
}
function createObject(objId) {
if (document.getElementById) return document.getElementById(objId);
else if (document.layers) return eval("document." + objId);
else if (document.all) return eval("document.all." + objId);
else return eval("document." + objId);
}
</script>
If I dynamically add a textarea using JQuery it works fine.
<script type="text/JavaScript">
$(document).ready(function(){
$('#divToAddTo').append('<textarea id="txtAnswerMain2" onkeypress="return taLimit(this)" onkeyup="return taCount(this,'myCounter')" name="Description" rows="7" wrap="physical" cols="40">');
$('#divToAddTo').append('</textarea>');
});
</script>

I can not get result after calling JavaScript function

I am working with Javascript StopWatch in C# web Aplication. But I don't get output from javascript. Below is my code.
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<script type="text/javascript" language="JavaScript">
var state = 0;
function startstop() {
if (state == 0) {
state = 1;
then = new Date();
then.setTime(then.getTime() - ms);
} else {
state = 0;
now = new Date();
ms = now.getTime() - then.getTime();
document.stpw.time.value = ms;
}
}
function swreset() {
state = 0;
ms = 0;
document.stpw.time.value = ms;
}
function display() {
setTimeout("display();", 50);
if (state == 1) {now = new Date();
ms = now.getTime() - then.getTime();
document.stpw.time.value = ms;
}
}
</script>
</head>
<body onload="display()">
<form id="form1" runat="server">
<div>
Time:
<input type="text" name="time"/>
<input type="button" name="ssbutton" value="Start/Stop" onclick="javascript:startstop()"/>
<input type="button" name="reset" value="Reset" onclick="javascript:swreset()"/>
</div>
</form>
</body>
</html>
I am new with javascript ,Where I am doing mistake?? Thank You...
Udate:Finally I get the errors and solved it. Here is updates solution for someone who want to implement JavaScript Stopwatch in C# Application.
<html>
<head>
<script type="text/javascript">
var ms = 0;
var state = 0;
var then;
var now;
ms = new Date();
function startstop()
{
if (state == 0)
{
state = 1;
then = new Date();
then.setTime(then.getTime() - ms);
}
else
{
state = 0;
now = new Date();
ms = now.getTime() - then.getTime();
document.getElementById('timeInput').value = ms;
}
}
function swreset() {
state = 0;
ms = 0;
document.getElementById('timeInput').value = ms;
}
function display() {
ms = new Date();
setTimeout("display();", 50);
if (state == 1) {
now = new Date();
ms = now.getTime()-then.getTime();
document.getElementById('timeInput').value = ms;
}
}
</script>
</head>
<body onload="display()">
<form>
Time:
<input type="text" name="time" id="timeInput"/>
<input type="button" name="ssbutton" value="Start/Stop" onclick="javascript:startstop()"/>
<input type="button" name="reset" value="Reset" onclick="javascript:swreset()"/>
</form>
</body>
</html>
Thanks For All your help.
Here are some first steps: (This doesn't mean that everything will work, but it will sure help.)
As JohnFx pointed out, make sure the HTML is in good shape.
Give your "text" input called "time" an ID.
<input type="text" name="time" id="timeInput"/>
Reference the element using getElementById()
document.getElementById("timeInput").value = ...
If things don't behave properly, put alert(...) statements in the javascript to see where its going and what values it's coming up with.
Well, one problem is this line:
<inputtype="button"name="ssbutton"value="Start/Stop" onclick="javascript:startstop()"/>
I think you need a few extra spaces in there.
Also you refernce document.stpw.time several times, but I don't see stpw in your html.
onclick=..., onload=... is bad.
javascript: is useless.
language=JavaScript is useless
runat=server is useless.
you don't have a title and therefore don't have valid HTML.
your state and functions are global
you don't use var ms = ...
document.stpw doesn't exist.
You probably meant to name your form document.stpw and document.<formName> is bad. Use document.forms.stpw instead.
setTimeout(string) is bad.
you don't end your if (...) {now = new Date(); with an }

Categories

Resources