How to avoid image flicker in IE using timer - image

I have the following code which causes smooth playback in Chrome. but in IE10 it causes a flicker. Are there workarounds at all?
Thanks
HTML
<a href="#" title="Play Motion Clip from Beginning">
<img alt="Play Motion" src="../Images/play_green_controls.png" style="border-style: none; width: 32px; height: 32px; background-color: #000000; cursor: pointer;"
id="btnPlay" />
</a>
<div id="divImage" >
hello andy
</div>
Javascript
<script type="text/javascript">
var cache = [];
var cacheImage = document.createElement('img');
var interval = 100;
var _total = 0;
$("#btnPlay").click(function () {
$.ajax({
type: "POST",
url: "Default3.aspx/GetClips",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
cache = [];
_total = 0;
$.each(msg.d, function () {
var cacheImage = document.createElement('img');
cacheImage.src = this['Text'];
cache[_total] = cacheImage;
_total++;
}
);
setInterval('swapImages()', interval);
},
error: function (msg) {
alert(msg.d);
}
});
});
var div = document.getElementById('divImage');
var _index = 0;
function swapImages() {
if (_index < _total) {
if (_index > 0) {
div.removeChild(cache[_index - 1]);
}
div.appendChild(cache[_index]);
}
else {
interval = 0;
}
_index++;
if (_index == _total)
{
div.removeChild(cache[_index - 1]);
_index = 0;
div.appendChild(cache[_index]);
}
}
Code Behind:
[WebMethod]
public static ArrayList GetClips()
{
ArrayList _arr = new ArrayList();
int _max = 250; //seems to be safe
string[] _files = Directory.GetFiles(#"C:\Cloud\Catalogues\000EC902F17F\2\2013\10\6\10\f1fe61da-4684-48ed-a503-4a5586ece9c8","*.jpg"); //731
for (int _index = 0; _index < _files.Length; _index++)
{
string _file = _files[_index];
string[] _bits = _file.Split('\\');
string _url = "Portal/Catalogues/000EC902F17F/2/2013/10/6/10/f1fe61da-4684-48ed-a503-4a5586ece9c8/" + _bits[10];
ListItem _item = new ListItem();
_item.Text = _url;
_arr.Add(_item);
if (_index == _max - 1)
{
break;
}
}
return _arr;
}

Related

Google Maps: add listener to dynamically created marker outside initialize function

I have been trying for days to add an event listener for an infoWindow to markers that are created on Ajax success.
The mouseover event is never fired, so there must be something I'm doing wrong in adding the listener.
The listener that does NOT work is for the marker restMarker. The dragend listener for addressMarker in the initialize() function works fine.
I have tried adding the listener in multiple ways: google.maps.event.addListener(markerObject,'mouseover',function(){}) and markerObject.addListener('mouseover',function(){}).
I have tried giving the restMarker global scope.
I have read the following:
Dynamically Adding Listeners To Google Maps Markers
create event listener to dynamically created google-map marker
...and more.
I have infoWindows working fine with dynamically created markers in other projects. The only difference I'm aware of in the working projects is that the markers are created in the map initialize() function instead of in an ajax success function.
Am I doing anything obviously wrong?
<script type='text/javascript'>
var zoneMap;
var currentRestMarkers = [];
var markerInfoWindow;
var distances = [{"fee":2,"distance":5,"available":1},{"fee":3,"distance":7,"available":1},{"available":1,"distance":9,"fee":7},{"fee":9,"available":0,"distance":10}];
var ajaxResponse = {"success":[{"duration":"11.5","name":"Backyard Bistro","lng":-78.7253,"lat":35.7989,"distance":6.64,"restId":"179"},{"lat":35.7796,"lng":-78.6758,"restId":"180","distance":7.5,"name":"Baja Burrito","duration":"13.3"},{"name":"Mi Rancho","duration":"15.6","lng":-78.6482,"lat":35.7491,"restId":"183","distance":6.32},{"lat":35.7757,"lng":-78.6363,"distance":4.67,"restId":"188","name":"El Rodeo Downtown","duration":"13.7"},{"duration":"9.2","name":"El Rodeo North","lng":-78.6262,"lat":35.8137,"distance":3.35,"restId":"189"},{"name":"Fallon's Flowers","duration":"9.1","restId":"192","distance":2.92,"lat":35.789,"lng":-78.6507},{"lng":-78.6397,"lat":35.7742,"restId":"193","distance":4.62,"name":"Fire Wok","duration":"14.1"},{"lng":-78.6131,"lat":35.8051,"restId":"194","distance":6.21,"name":"Gateway","duration":"9.8"},{"restId":"195","distance":27.99,"lng":-79.0564,"lat":35.9152,"name":"Gift Cards ","duration":"35.6"},{"name":"Jumbo China","duration":"8.5","lng":-78.6262,"lat":35.819,"distance":2.87,"restId":"197"},{"lng":-78.6456,"lat":35.8817,"restId":"198","distance":4.93,"name":"La Rancherita","duration":"12.0"},{"duration":"8.9","name":"Mami Nora's","restId":"205","distance":3.35,"lat":35.8137,"lng":-78.6271},{"distance":2.94,"restId":"209","lat":35.7883,"lng":-78.6474,"duration":"8.0","name":"Mellow Mushroom"},{"distance":7.88,"restId":"212","lng":-78.7387,"lat":35.7878,"duration":"12.3","name":"Ole Time BBQ"},{"lng":-78.6388,"lat":35.8374,"restId":"214","distance":2.23,"duration":"7.0","name":"Piola"},{"name":"The Remedy Diner 2.0 - Brunch","duration":"11.9","lng":-78.656,"lat":35.7824,"distance":4.24,"restId":"216"},{"lng":-78.656,"lat":35.7824,"restId":"217","distance":4.24,"duration":"11.9","name":"The Remedy Diner 2.0"},{"distance":7.66,"restId":"218","lng":-78.6773,"lat":35.7777,"name":"Sammy's Tap & Grill","duration":"13.4"},{"lng":-78.621,"lat":35.8238,"distance":4.39,"restId":"219","duration":"8.4","name":"Shaba Shabu"},{"name":"Spring Rolls","duration":"5.9","distance":1.88,"restId":"220","lng":-78.6409,"lat":35.8399},{"duration":"9.6","name":"Thaiphoon","restId":"222","distance":3.2,"lat":35.7845,"lng":-78.6477},{"lat":35.7776,"lng":-78.6398,"restId":"223","distance":4.3,"duration":"11.6","name":"The Big Easy"},{"lng":-78.6433,"lat":35.8364,"restId":"225","distance":1.68,"duration":"5.5","name":"The Q Shack"},{"duration":"14.4","name":"Vic's Italian","lng":-78.6356,"lat":35.7759,"restId":"226","distance":4.72},{"restId":"227","distance":1.68,"lng":-78.6433,"lat":35.8364,"name":"Which Wich North Hills","duration":"5.5"},{"lat":35.7912,"lng":-78.6799,"restId":"245","distance":5.89,"duration":"10.5","name":"The Wild Cook's Indian Grill"},{"lng":-78.6237,"lat":35.873,"restId":"301","distance":4.68,"name":"Taj Mahal North","duration":"12.9"},{"restId":"820","distance":6.29,"lng":-78.6825,"lat":35.8986,"duration":"14.5","name":"El Dorado "},{"name":"Taza Grill","duration":"12.8","restId":"821","distance":4.84,"lat":35.8693,"lng":-78.6211},{"duration":"14.9","name":"Sassool","restId":"824","distance":6.83,"lat":35.9043,"lng":-78.6567},{"lng":-78.5797,"lat":35.8477,"distance":8.45,"restId":"830","name":"Alpaca Peruvian Charcoal Chicken","duration":"13.9"},{"distance":6.21,"restId":"831","lat":35.899,"lng":-78.653,"name":"Shish Kabob Six Forks","duration":"14.1"},{"distance":2.87,"restId":"923","lng":-78.6262,"lat":35.819,"name":"Tropical Picken Chicken","duration":"8.5"},{"duration":"10.3","name":"Wicked Taco","lat":35.7852,"lng":-78.6923,"restId":"931","distance":6.48},{"duration":"14.8","name":"Despina's Cafe","restId":"1142","distance":6.31,"lng":-78.6824,"lat":35.9015},{"duration":"4.7","name":"WhichWich Crabtree","lat":35.8391,"lng":-78.6752,"distance":1.7,"restId":"1242"},{"duration":"6.3","name":"Pharaoh's Grill at North Hills","distance":1.86,"restId":"1296","lng":-78.6434,"lat":35.8403},{"name":"Pharaoh's at the Museum","duration":"12.2","restId":"1297","distance":4.43,"lat":35.7818,"lng":-78.6386},{"restId":"1298","distance":2.54,"lng":-78.6298,"lat":35.8215,"name":"Gorilla Grill","duration":"6.5"},{"name":"My Way Tavern","duration":"9.8","lng":-78.6506,"lat":35.7872,"restId":"1307","distance":3.04}]};
function initialize() {
var myLatlng = new google.maps.LatLng(35.8013,-78.6409);
var geocoder = new google.maps.Geocoder();
var mapOptions = {
zoom: 13,
center: myLatlng,
panControl: false,
zoomControl: true,
mapTypeControl: false,
scaleControl: true,
streetViewControl: false,
overviewMapControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
zoneMap = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
var addressMarker = new google.maps.Marker({
position: zoneMap.center,
map: zoneMap,
clickable: true,
draggable: true,
flat: true,
icon: 'https://maps.google.com/mapfiles/ms/icons/blue-dot.png'
});
google.maps.event.addListener(addressMarker, 'dragend', function(event) {
var markerNewLatLng=event.latLng;
geocoder.geocode({'latLng': markerNewLatLng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
showAvailableRests(markerNewLatLng.lat(),markerNewLatLng.lng());
}
else {
console.log('Geocoder failed due to: ' + status);
}
});
});
}
function loadScript() {
var acScript = document.createElement('script');
acScript.type = 'text/javascript';
acScript.src = 'https://maps.googleapis.com/maps/api/js?libraries=places&callback=initialize';
document.body.appendChild(acScript);
}
function showAvailableRests(whichLat,whichLng) {
var rest_list = jQuery('#rest_list');
jQuery(rest_list).empty();
jQuery('#restCount').html('');
if (currentRestMarkers.length > 0) {
for (var i in currentRestMarkers) {
currentRestMarkers[i].setMap(null);
}
currentRestMarkers = [];
}
var restCount = 0;
for (var i=0; i < ajaxResponse.success.length; i++ ) {
var iconColor = 'green.png';
var available = 1;
var tierClass = 'tier1';
for (var j=0; j < distances.length; j++ ) {
if (ajaxResponse.success[i].distance >= distances[j].distance) {
if (distances[j].available == 0) {
available = 0;
}
if (j === 0) {
iconColor = 'yellow.png';
tierClass = 'tier2';
}
else if (j === 1) {
iconColor = 'orange.png';
tierClass = 'tier3';
}
else if (j > 1) {
iconColor = 'purple.png';
tierClass = 'tier4';
}
}
else {
break; // if it is not greater than the shorter distance, it is not greater than longer ones either
}
}
if (available === 0) { // if this restaurant is not available at this distance
//continue; // skip the rest for unavailable
iconColor = 'red.png';
tierClass = 'unavailable';
}
else {
restCount++;
}
var restDiv = jQuery(document.createElement('div'));
var distanceTier = jQuery(document.createElement('span')).html(' ').addClass('distance-tier ' + tierClass).appendTo(restDiv);
var restDist = jQuery(document.createElement('span')).html(ajaxResponse.success[i].distance + ' mi.').addClass('rest-distance').appendTo(restDiv);
var restName = jQuery(document.createElement('span')).html(ajaxResponse.success[i].name).addClass('rest-name').appendTo(restDiv);
jQuery(restDiv).appendTo(rest_list);
var restMarkerPosition = new google.maps.LatLng(ajaxResponse.success[i].lat,ajaxResponse.success[i].lng);
var restMarker = new google.maps.Marker({
position: restMarkerPosition,
map: zoneMap,
clickable: false,
draggable: false,
flat: true,
icon: 'https://maps.google.com/mapfiles/ms/icons/' + iconColor
});
currentRestMarkers.push(restMarker);
google.maps.event.addListener(restMarker, 'mouseover', function(e) {
console.log('mouseover event fired'); // the mouseover event is never fired!!!
showRestWindow(e, ajaxResponse.success[i].name, ajaxResponse.success[i].distance);
});
/*restMarker.addListener('mouseover', function() {
new google.maps.InfoWindow({
content: "<div><strong>" + ajaxResponse.success[i].name + "<\/strong><br>" + ajaxResponse.success[i].distance + " miles<\/div>",
disableAutoPan: true,
});
markerInfoWindow.open(zoneMap, this);
});*/
jQuery('#restCount').html(restCount);
}
}
function showRestWindow(event, name, distance) {
markerInfoWindow = new google.maps.InfoWindow({
content: "<div><strong>" + name + "<\/strong><br>" + distance + " miles<\/div>",
disableAutoPan: true,
position: event.latLng,
});
markerInfoWindow.open(zoneMap);
};
jQuery(document).ready(function () {
loadScript();
return false;
});
</script>
<div id='map_container'>
<div id='map_canvas'></div>
</div>
<div id='column_right'>
<p><b>Available Restaurants: <span id='restCount'></span></b></p>
<div id='rest_list'></div>
</div>

Call Ajax.ActionLink using Razor syntax on value changed event

I have a View in which i have criteria a Supplier TextBox a LastMonth dropdown and a Months Textbox.
#using JouleBrokerDB.ViewModels;
#model AssignPayReportToDepositViewModel
#{
ViewBag.Title = "View";
}
<link href="#Url.Content("~/Content/kendo/kendo.common-bootstrap.min.css")" rel="stylesheet" />
<link href="#Url.Content("~/Content/kendo/kendo.bootstrap.min.css")" rel="stylesheet" />
<link href="#Url.Content("~/Content/kendo/kendo.dataviz.min.css")" rel="stylesheet" />
<link href="#Url.Content("~/Content/kendo/kendo.dataviz.bootstrap.min.css")" rel="stylesheet" />
<style>
.treediv {
display: inline-block;
vertical-align: top;
width: 440px;
/*height:400px;*/
min-height: 400px;
text-align: left;
margin: 0 2em;
border-radius: 25px;
border: 2px solid #8AC007;
padding: 15px;
overflow: auto;
}
</style>
<div class="row">
<div class="col-md-9 col-md-offset-1">
#using (Html.BeginForm("Show", "AssignPayReportToDeposit", FormMethod.Post, new { id = "AssignToPayReportForm", #class = "form-horizontal" }))
{
<fieldset>
<!-- Form Name -->
<legend>Assign Pay Report to Deposit</legend>
<div class="form-group">
<!-- Supplier -->
<div class="col-sm-4">
#Html.Label("", "Supplier:", new { #class = "control-label", #for = "textinput" })
<div id="suppliers">
#Html.DropDownListFor(x => x.SuppliersList, new SelectList(Model.SuppliersList, "SupplierID", "Name"), new { id = "ddSupplier", #class = "form-control" })
</div>
</div>
<!-- Last Month -->
<div class="col-sm-4">
#Html.Label("", "Last Month:", new { #class = "control-label", #for = "textinput" })
#Html.DropDownListFor(x => x.LastMonthsList, new SelectList(Model.LastMonthsList), new { #id = "ddLastMonth", #class = "form-control" })
</div>
<!-- Months-->
<div class="col-sm-4">
#Html.Label("", "Months:", new { #class = "control-label", #for = "textinput" })
#Html.TextBox("txtMonths", null, new { type = "number", step = 1, min = 1, max = 12, #class = "form-control", required = "required" })
</div>
</div>
</fieldset>
<div class="treediv">
#Html.Label("", "UnAssigned PayReport:", new { #class = "control-label", #for = "textinput" })
<div id="TreeView_UPR" style="padding:5px"></div>
</div>
<div class="treediv">
#Html.Label("", "Deposits:", new { #class = "control-label", #for = "textinput" })
<h4></h4>
<div id="TreeView_AD" style="padding:5px"></div>
</div>
}
</div>
</div>
<script src="#Url.Content("~/Scripts/kendo/kendo.all.min.js")"></script>
<script src="#Url.Content("~/Scripts/Views/AssignPayReportToDeposit/Show.js")"></script>
Here on this text box i have attached changed event though jQuery. The requirement is that whenever the criteria changes the treeview div will be filled with data will be refreshed.
AssignPayReportsToDeposit.AttachEvents = function () {
$("#ddSupplier").change(AssignPayReportsToDeposit.OnSupplierChange);
$("#ddLastMonth").change(AssignPayReportsToDeposit.OnLastMonthChange);
$("#txtMonths").change(AssignPayReportsToDeposit.OnMonthsChange);
}
these changed event handler will handle the refreshing the treeview. The whole thing is handled through ajax calls.
Now i know that using Ajax.ActionLink and UpdateTargetId parameter with Replace option i can return the treeview in partial view so the manual handling can be removed. but that will require me put the anchor button which user have to click. Requirement is that the refresh of treeview should be done on any criteria change.
Is there any way i am able to achieve this using Ajax.ActionLink (or any another razor syntax that will take load off from the manual handling ) ? On change event of the controls i would like to call a controller using ajax.actionlink which will return a partialview and update the div.
Edit: I am handling this through jQuery right now. so i will post the complete code for more understanding.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using JouleBrokerDB;
using JouleBrokerDB.ViewModels;
using JouleBroker.Filters;
namespace JouleBroker.Controllers
{
[RoutePrefix("AssignPayReportToDeposit")]
[Route("{action=Show}")]
public class AssignPayReportToDepositController : Controller
{
// GET: AssignPayReportToDeposit
//[Route("Show",Name = "APTDShow")]
//[ValidateLogin]
public ActionResult Show()
{
List<SupplierViewModel> suppliers = DBCommon.GetAllSuppliers(false);
SuppliersList_LastMonthsList_ViewModel model = new SuppliersList_LastMonthsList_ViewModel()
{
SuppliersList = suppliers,
LastMonthsList = new List<string>()
};
return View(model);
}
[HttpPost]
[Route("GetUnAssignedPayReports")]
public JsonResult GetUnAssignedPayReports(int SupplierID,
string MonthPaid,
int Months)
{
var payreports = AssignPayReportsToDepositData.GetUnAssignedPayReports(SupplierID,
MonthPaid,
Months);
return Json(payreports);
}
[HttpPost]
[Route("GetAssignedPayReports")]
public JsonResult GetAssignedPayReports(int SupplierID,
string MonthPaid,
int Months)
{
var payreports = AssignPayReportsToDepositData.GetAssignedPayReports(SupplierID,
MonthPaid,
Months);
return Json(payreports);
}
[HttpPost]
[Route("AssignDepositIdToPayReport")]
public bool AssignDepositIdToPayReport(int PayReportID, int DepositID)
{
return AssignPayReportsToDepositData.AssignDepositIdToPayReport(PayReportID, DepositID);
}
}
}
JavaScript File (the code is a bit lengthy so you don't need to look at all of them you can see the methods which are calling the action methods. GetUnAssignedPayReports and GetAssignedPayReports which returns the data which is used to fill the tree view.) I just want this portion to moved to partial view and passing model to partial view generate treeview there and replace the div each time on change event with rendering partial view again. Hope i am clear enough. so change the above methods to return partial instead of json result that what i am trying to achive
function AssignPayReportsToDeposit() { }
AssignPayReportsToDeposit.SelectedSupplierID = 0;
AssignPayReportsToDeposit.SelectedLastMonth = null;
AssignPayReportsToDeposit.SelectedMonths = 0;
AssignPayReportsToDeposit.LastMonthsList = null;
AssignPayReportsToDeposit.UnAssignedPayReportsList = null;
AssignPayReportsToDeposit.AssignedPayReportsList = null;
AssignPayReportsToDeposit.LastTextChangedNode = null;
//--------- Document Ready Function -------- //
$(document).ready(function () {
//AttachEvents
AssignPayReportsToDeposit.AttachEvents();
});
AssignPayReportsToDeposit.AttachEvents = function () {
$("#ddSupplier").change(AssignPayReportsToDeposit.OnSupplierChange);
$("#ddLastMonth").change(AssignPayReportsToDeposit.OnLastMonthChange);
$("#txtMonths").change(AssignPayReportsToDeposit.OnMonthsChange);
}
//Handles Supplier ChangeEvents
AssignPayReportsToDeposit.OnSupplierChange = function () {
//Get Changed Supplier ID
AssignPayReportsToDeposit.SelectedSupplierID = $('#ddSupplier').val();
//Get Last Month List
AssignPayReportsToDeposit.LastMonthsList = CommonAction.GetLastPayReportMonthsBySupplierID(AssignPayReportsToDeposit.SelectedSupplierID);
//Fill Last Month List
AssignPayReportsToDeposit.FillLastMonths();
//Refresh TreeView_UPR
AssignPayReportsToDeposit.RefreshTreeViewUPR();
//Refresh TreeView_AD
AssignPayReportsToDeposit.RefreshTreeViewAD();
}
//Handles Last Month Change Event
AssignPayReportsToDeposit.OnLastMonthChange = function () {
AssignPayReportsToDeposit.SelectedLastMonth = $('#ddLastMonth').val();
//Refresh TreeView_UPR
AssignPayReportsToDeposit.RefreshTreeViewUPR();
//Refresh TreeView_AD
AssignPayReportsToDeposit.RefreshTreeViewAD();
}
//Handles Month Change Event
AssignPayReportsToDeposit.OnMonthsChange = function () {
AssignPayReportsToDeposit.SelectedMonths = $('#txtMonths').val();
//Refresh TreeView_UPR
AssignPayReportsToDeposit.RefreshTreeViewUPR();
//Refresh TreeView_AD
AssignPayReportsToDeposit.RefreshTreeViewAD();
}
//Fills Last Month Dropdown with options
AssignPayReportsToDeposit.FillLastMonths = function () {
var ddLastMonth = $("#ddLastMonth");
if (ddLastMonth != undefined) {
ddLastMonth.empty();
if (AssignPayReportsToDeposit.LastMonthsList != undefined) {
$.each(AssignPayReportsToDeposit.LastMonthsList, function () {
Common.AddOptionToSelect(ddLastMonth, this.Text, this.Text);
});
ddLastMonth.val(AssignPayReportsToDeposit.LastMonthsList[0].Text);
AssignPayReportsToDeposit.SelectedLastMonth = ddLastMonth.val();
}
}
}
AssignPayReportsToDeposit.ValidateControls = function () {
var success = true;
if (AssignPayReportsToDeposit.SelectedSupplierID == undefined ||
AssignPayReportsToDeposit.SelectedSupplierID == 0) {
// bootbox.alert('Please select a Supplier');
success = false;
}
else if (AssignPayReportsToDeposit.SelectedLastMonth == undefined ||
AssignPayReportsToDeposit.SelectedLastMonth == '') {
// bootbox.alert('Please select Last Month');
success = false;
}
else if (AssignPayReportsToDeposit.SelectedMonths == undefined ||
AssignPayReportsToDeposit.SelectedMonths == 0) {
// bootbox.alert('Please Enter Months');
success = false;
}
return success;
}
//Assigns DepositIdToPayReport
AssignPayReportsToDeposit.AssignDepositIdToPayReport = function (PayReportID, DepositID) {
var success = false;
if (PayReportID != undefined && DepositID != undefined) {
var jsonData = JSON.stringify({ PayReportID: PayReportID, DepositID: DepositID });
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: 'AssignPayReportToDeposit/AssignDepositIdToPayReport',
data: jsonData,
async: false,
success: function (result) {
success = result;
},
error: Common.AjaxErrorHandler
});
}
return success;
}
//--------- Tree View UPR Functions -------- //
//Gets UnAssigned Pay Reports
AssignPayReportsToDeposit.GetUnAssignedPayReports = function () {
var payReports;
if (AssignPayReportsToDeposit.ValidateControls()) {
var jsonData = JSON.stringify(
{
SupplierID: AssignPayReportsToDeposit.SelectedSupplierID,
MonthPaid: AssignPayReportsToDeposit.SelectedLastMonth,
Months: AssignPayReportsToDeposit.SelectedMonths
});
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "AssignPayReportToDeposit/GetUnAssignedPayReports",
data: jsonData,
async: false,
success: function (data) {
if (data != undefined && data != "")
payReports = data;
},
error: Common.AjaxErrorHandler
});
}
return payReports;
}
AssignPayReportsToDeposit.BindTreeViewUPR = function () {
var treeview = $("#TreeView_UPR");
var inline = new kendo.data.HierarchicalDataSource({
data: AssignPayReportsToDeposit.UnAssignedPayReportsList,
schema: {
model: {
id: "PayReportID"
}
}
});
treeview.kendoTreeView({
dragAndDrop: true,
dataSource: inline,
dataBound: function (e) {
if (!this.dataSource.data().length) {
this.element.append("<p class='no-items'>No items yet.</p>");
} else {
this.element.find(".no-items").remove();
}
},
dataTextField: ["DisplayValue"],
drop: AssignPayReportsToDeposit.OnTreeViewUPRDrop
});
}
AssignPayReportsToDeposit.OnTreeViewUPRDrop = function (e) {
var isTargetTreeViewAD = false;
var sourceDataItem = this.dataItem(e.sourceNode);
var targetDataItem = this.dataItem(e.destinationNode);
if (targetDataItem == undefined) {
targetDataItem = $("#TreeView_AD").data("kendoTreeView").dataItem(e.destinationNode);
isTargetTreeViewAD = true;
}
if (sourceDataItem == undefined ||
targetDataItem == undefined) {
//Source and target both must exists
e.preventDefault();
return;
}
if (sourceDataItem.IsDeposit == true) {
//Deposits cannot be drag and Drop
e.preventDefault();
return;
}
if (isTargetTreeViewAD) {
if (e.dropPosition == "over" &&
sourceDataItem.IsPayReport == true &&
sourceDataItem.IsAssignedPayReport == false &&
targetDataItem.IsDeposit == true) {
//Source must UnAssigned Payreport Target Must be Deposit and Drop position must over
//Implement logic to assign deposit id to the Pay Report
var PayReportID = sourceDataItem.PayReportID;
var DepositID = targetDataItem.DepositID;
if (AssignPayReportsToDeposit.AssignDepositIdToPayReport(PayReportID, DepositID)) {
sourceDataItem.set("DepositID", DepositID);
sourceDataItem.set("IsAssignedPayReport", true);
}
else {
//Didnt update the record don't do the drop
e.preventDefault();
return;
}
}
else {
e.preventDefault();
return;
}
}
else {
if ((e.dropPosition == "before" || e.dropPosition == "after") &&
sourceDataItem.IsPayReport == true &&
targetDataItem.IsPayReport == true &&
targetDataItem.IsAssignedPayReport == false) {
//Only allow sorting in this condition otherwise cancel drop event
//Means only allow sorting of unassigned payreports within the tree
}
else {
e.preventDefault();
return;
}
}
}
AssignPayReportsToDeposit.RefreshTreeViewUPR = function () {
//Destroy and empty tree
var treeview = $("#TreeView_UPR").data("kendoTreeView");
if (treeview != undefined) { treeview.destroy(); }
treeview = $("#TreeView_UPR");
treeview.empty();
AssignPayReportsToDeposit.UnAssignedPayReportsList = AssignPayReportsToDeposit.GetUnAssignedPayReports();
AssignPayReportsToDeposit.BindTreeViewUPR();
}
//--------- TreeView_AD Functions -------- //
//Gets Assigned Pay Reports
AssignPayReportsToDeposit.GetAssignedPayReports = function () {
var payReports;
if (AssignPayReportsToDeposit.ValidateControls()) {
var jsonData = JSON.stringify(
{
SupplierID: AssignPayReportsToDeposit.SelectedSupplierID,
MonthPaid: AssignPayReportsToDeposit.SelectedLastMonth,
Months: AssignPayReportsToDeposit.SelectedMonths
});
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "AssignPayReportToDeposit/GetAssignedPayReports",
data: jsonData,
async: false,
success: function (data) {
if (data != undefined && data != "")
payReports = data;
},
error: Common.AjaxErrorHandler
});
}
return payReports;
}
AssignPayReportsToDeposit.BindTreeViewAD = function () {
var treeview = $("#TreeView_AD");
var inline = new kendo.data.HierarchicalDataSource({
data: AssignPayReportsToDeposit.AssignedPayReportsList,
schema: {
model: {
id: "DepositID",
hasChildren: "HasAnyAssignedPayReports",
children: "AssignedPayReports"
}
}
});
treeview.kendoTreeView({
dragAndDrop: true,
dataSource: inline,
dataBound: function (e) {
if (!this.dataSource.data().length) {
this.element.append("<p class='no-items'>No items yet.</p>");
} else {
this.element.find(".no-items").remove();
}
},
dataTextField: ["DisplayValue", "DisplayValue"],
drop: AssignPayReportsToDeposit.OnTreeViewADDrop,
select: AssignPayReportsToDeposit.OnTreeViewADSelect
});
}
AssignPayReportsToDeposit.OnTreeViewADSelect = function (e) {
var dataItem = this.dataItem(e.node);
var treeview = this;
if (AssignPayReportsToDeposit.LastTextChangedNode != undefined) {
//Restore last node's Text
var previousDataItem = this.dataItem(AssignPayReportsToDeposit.LastTextChangedNode);
if (previousDataItem != undefined) {
var date = AssignPayReportsToDeposit.FormatDepositMonthToDisplay(previousDataItem.DepositDate);
var displaytext = "[" + date + "]" + "-[" + previousDataItem.BankName + "]-" + "[" + previousDataItem.Amount + "]";
this.text(AssignPayReportsToDeposit.LastTextChangedNode, displaytext);
}
AssignPayReportsToDeposit.LastTextChangedNode = undefined;
}
if (dataItem.IsDeposit) {
if (dataItem.hasChildren > 0) {
dataItem.set("expanded", true);
//Append sum to selected node's diplay value
var childs = dataItem.children.data();
var sum = 0;
$.each(childs, function () { sum += this.Amount });
var date = AssignPayReportsToDeposit.FormatDepositMonthToDisplay(dataItem.DepositDate);
var displaytext = "[" + date + "]" + "-[" + dataItem.BankName + "]-" + "[" + dataItem.Amount + "(" + sum + ")" + "]";
this.text(e.node, displaytext)
AssignPayReportsToDeposit.LastTextChangedNode = e.node;
}
}
}
AssignPayReportsToDeposit.FormatDepositMonthToDisplay = function (jsondate) {
var depositedate = "";
if (jsondate != undefined && jsondate != "") {
var date = Common.ParseDate(jsondate);
var month = ("0" + (date.getMonth() + 1)).slice(-2);
depositedate = date.getFullYear() + "-" + (month);
}
return depositedate;
}
AssignPayReportsToDeposit.OnTreeViewADDrop = function (e) {
var isTargetTreeViewURP = false;
var DroptoNoItemZone = false;
var sourceDataItem = this.dataItem(e.sourceNode);
var targetDataItem = this.dataItem(e.destinationNode);
var treeview_UPR = $("#TreeView_UPR").data("kendoTreeView");
if (targetDataItem == undefined) {
targetDataItem = treeview_UPR.dataItem(e.destinationNode);
if (treeview_UPR.element.find(".no-items").length > 0) DroptoNoItemZone = true;
isTargetTreeViewURP = true;
}
if ((sourceDataItem == undefined ||
targetDataItem == undefined) && DroptoNoItemZone == false) {
e.preventDefault();
return;
}
if (sourceDataItem.IsDeposit == true) {
//Deposits can not be moved within the tree view
e.preventDefault();
return;
}
if (isTargetTreeViewURP) {
if (((e.dropPosition == "before" || e.dropPosition == "after") &&
sourceDataItem.IsPayReport == true &&
sourceDataItem.IsAssignedPayReport == true &&
targetDataItem.IsPayReport == true) || (e.dropPosition == "over" && DroptoNoItemZone)) {
//Implement logic to unassing deposit id to PayReport
var PayReportID = sourceDataItem.PayReportID;
var DepositID = 0;
if (AssignPayReportsToDeposit.AssignDepositIdToPayReport(PayReportID, DepositID)) {
sourceDataItem.set("DepositID", DepositID);
sourceDataItem.set("IsAssignedPayReport", false);
}
else {
//Didnt update the record don't do the drop
e.preventDefault();
return;
}
}
else {
e.preventDefault();
return;
}
}
else {
if (e.dropPosition == "over" &&
sourceDataItem.IsPayReport == true &&
targetDataItem.IsDeposit == true) {
//Implement Logic to change deposit ID for assigned payreport
var PayReportID = sourceDataItem.PayReportID;
var DepositID = targetDataItem.DepositID;
if (AssignPayReportsToDeposit.AssignDepositIdToPayReport(PayReportID, DepositID)) {
sourceDataItem.set("DepositID", DepositID);
sourceDataItem.set("IsAssignedPayReport", true);
}
else {
//Didnt update the record don't do the drop
e.preventDefault();
return;
}
}
else {
e.preventDefault();
return;
}
}
}
AssignPayReportsToDeposit.RefreshTreeViewAD = function () {
//Destroy and empty tree
var treeview = $("#TreeView_AD").data("kendoTreeView");
if (treeview != undefined) { treeview.destroy(); }
treeview = $("#TreeView_AD");
treeview.empty();
AssignPayReportsToDeposit.LastTextChangedNode = undefined;
AssignPayReportsToDeposit.AssignedPayReportsList = AssignPayReportsToDeposit.GetAssignedPayReports();
AssignPayReportsToDeposit.BindTreeViewAD();
}
Unfortunately not out the box.
The Ajax extension methods are really just HTML helpers that work with other jQuery libraries. The helpers create the relavant HTML markup (such as adding custom addtributes data-*="") and the client scripts use this to determine their behaviour.
You could create your own MVC HTML helper and script library to handle change events for you however I would recommend looking at a front end framework such as Angular instead. This library would handle all the events declaratively so you don't need to waste time writing event handlers.

Json result returned as a file in Internet Explorer?

net MVC application, in which I have multiple charts. On these charts, I have applied filters and by clicking each filter, I do an ajax call which returns the result in Json and then applies to the charts.
Now its working perfectly in Firefox and Chrome, but in Internet Explorer - Ajax call is always unsuccessful. I tried hitting the web api url directly through my browser and the issue it seems is, the result json was being returned as a file to be downloaded.
This is my ajax code :
function getIssueResolvedGraphdata(control, departCode, departName) {
$.ajax(
{
type: "GET",
url: WebApiURL + "/api/home/GetQueryIssueResolvedData?deptCode=" + departCode,
dataType: "json",
crossDomain: true,
async: true,
cache: false,
success: function (myData) {
var resolvedStartDate = myData.data.IssueResolvedStartDate;
var issueData = myData.data.IssueData;
var resolveData = myData.data.ResolvedData;
//converting issueData into integer array...
var issue = issueData.replace("[", "");
var issue1 = issue.replace("]", "");
var issue2 = issue1.split(",");
for (var i = 0; i < issue2.length; i++) { issue2[i] = parseInt(issue2[i]); }
//converting resolvedData into integer array
var resolve = resolveData.replace("[", "");
var resolve1 = resolve.replace("]", "");
var resolve2 = resolve1.split(",");
for (var j = 0; j < resolve2.length; j++) { resolve2[j] = parseInt(resolve2[j]); }
//getting max value from array...
var issueMaxVal = Math.max.apply(null, issue2);
var resolveMaxVal = Math.max.apply(null, resolve2);
//Eliminating leading zeros in issue array
var removeIndex = 0;
var myDate;
var newDate;
var arrayLength;
if (issueMaxVal != 0) {
arrayLength = issue2.length;
for (var i = 0; i < arrayLength; i++) {
if (issue2[0] == 0) {
issue2.splice(0, 1);
removeIndex = i;
} else {
break;
}
}
//Getting days count of current month
var monthStart = new Date(new Date().getFullYear(), new Date().getMonth(), 1);
var monthEnd = new Date(new Date().getFullYear(), new Date().getMonth() + 1, 1);
var monthLength = (monthEnd - monthStart) / (1000 * 60 * 60 * 24);
var monthDays = 0;
if (monthLength == 28) {
monthDays = removeIndex;
}
else if (monthLength == 30) {
monthDays = removeIndex + 1;
}
else if (monthLength == 31 || monthLength == 29) {
monthDays = removeIndex + 2;
}
//matching the resultant issue array with resolve array & setting start date
var iDate = resolvedStartDate;
var tDate = '';
for (var i = 0; i < iDate.length; i++) {
if (iDate[i] == ',') {
tDate += '/';
}
else {
tDate += iDate[i];
}
}
if (removeIndex != 0) {
resolve2.splice(0, (removeIndex + 1));
var myDate = new Date(tDate);
myDate.setDate(myDate.getDate() + monthDays);
newDate = Date.UTC(myDate.getFullYear(), (myDate.getMonth() + 1), myDate.getDate());
} else {
var myDate = new Date(tDate);
newDate = Date.UTC(myDate.getFullYear(), (myDate.getMonth() + 1), myDate.getDate());
}
} else {
alert("Empty");
}
//updating chart here...
var chart = $('#performance-cart').highcharts();
chart.series[0].update({
pointStart: newDate,
data: issue2
});
chart.series[1].update({
pointStart: newDate,
data: resolve2
});
if (issueMaxVal > resolveMaxVal) {
chart.yAxis[0].setExtremes(0, issueMaxVal);
} else {
chart.yAxis[0].setExtremes(0, resolveMaxVal);
}
},
error: function (x, e) {
alert('There seems to be some problem while fetching records!');
} });}
Code from web api controller :
[HttpGet]
[CrossDomainActionFilter]
public Response<GraphIssueResolvedWrapper> GetQueryIssueResolvedData(string deptCode)
{
Response<GraphIssueResolvedWrapper> objResponse = new Response<GraphIssueResolvedWrapper>();
GraphIssueResolvedWrapper objGraphIssueResolvedWrapper = new GraphIssueResolvedWrapper();
try
{
....code.....
objResponse.isSuccess = true;
objResponse.errorDetail = string.Empty;
objResponse.data = objGraphIssueResolvedWrapper;
}
catch (Exception ex)
{
objResponse.isSuccess = false;
objResponse.errorDetail = ex.Message.ToString();
objResponse.data = null;
}
return objResponse;
}
Reponse Class :
public class Response<T>
{
public bool isSuccess { get; set; }
public string errorDetail { get; set; }
public T data { get; set; }
}
I am stuck at this for hours now. Any help will be appreciated.
I have solved my problem by using the following code : ( I guess it needed CORS support)
function isIE() {
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE");
if (msie > 0)
return true;
return false;
}
Then in document.ready function of my binding script :
$(document).ready(function () {
if (isIE())
$.support.cors = true;
});
Note : it still download Json stream as a file but now my AJAX call is successful upon each hit.
You've missed contentType: 'text/html' which is pretty important for IE7-8:
$.ajax(
{
type: "GET",
url: WebApiURL + "/api/home/GetQueryIssueResolvedData?deptCode=" + departCode,
dataType: "json",
contentType: 'text/html'
crossDomain: true,
async: true,
cache: false,
success: function (myData) {
var result = JSON.parse(myData);
///...code...
},
error: function (x, e) {
alert('There seems to be some problem while fetching records!');
}
}
);
To make it works in IE7-8 you also need to be sure that you've writing Conrent-Type Header into your response on server side. Add this line right before return statement;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html; charset=iso-8859-1");
And in code probably you will need to parse result in success method by using JSON.parse(myData);

SlickGrid filter not working

I am fairly new to SlickGrid. I am trying to make SlickGrid filter work but no luck. I am following the example (http://mleibman.github.io/SlickGrid/examples/example4-model.html).
Below is my source code.
$(document).ready(function() {
var tName;
$('#submit').click(function(e) {
tName = $('#source option:selected').text();// name1
tName = tName.trim();
$.ajax({
url : 'someUrl',
type : 'GET',
cache : false,
success : function(d) {
var grid;
var searchString = "";
var data = [];
var columns = new Array();
var cols = d[0].columns;
var pkColNames = d[0].pkColNames;
for (var j=0; j< cols.length; j++) {
var key = {id: cols[j].colName, name: cols[j].colName, field: cols[j].colName, width: 200, sortable:true, editor: Slick.Editors.LongText};
columns[j] = key;
}
var options = {
editable: true,
enableAddRow: false,
enableCellNavigation: true,
asyncEditorLoading: false,
enableColumnReorder:true,
multiColumnSort: false,
autoEdit: false,
autoHeight: false
};
function myFilter(item, args) {
return true;// Let us return true all time ?
}
for (var i = 0; i < d.length; i++) {
var tempData = (data[i] = {});
var title = null;
var val = null;
for (var q = 0; q < d[i].columns.length; q++) {
title = d[i].columns[q].colName;
val = d[i].columns[q].colValue;
tempData[title] = val;
}
}
var dataView = new Slick.Data.DataView({ inlineFilters: true });
grid = new Slick.Grid("#myGrid", dataView, columns, options);
dataView.setPagingOptions({
pageSize: 25
});
var pager = new Slick.Controls.Pager(dataView, grid, $("#myPager"));
var columnpicker = new Slick.Controls.ColumnPicker(columns, grid, options);
grid.setSelectionModel(new Slick.CellSelectionModel());
grid.onAddNewRow.subscribe(function(e, args) {
// Adding a new record is not yet decided.
});
grid.onCellChange.subscribe(function (e) {
var editedCellNo = arguments[1].cell;
var editedColName = grid.getColumns()[editedCellNo].field;
var newUpdatedValue= arguments[1].item[grid.getColumns()[editedCellNo].field];
var editedColType = "";
for (var cnt = 0; cnt < cols.length; cnt++) {
if (editedColName == cols[cnt].colName) {
editedColType = cols[cnt].colType;
break;
}
}
var pkKeyValue="";
for (var v=0; v <pkColNames.length;v++) {
for (var p=0; p<grid.getColumns().length; p++) {
if (pkColNames[v] == grid.getColumns()[p].field) {
var value = arguments[1].item[grid.getColumns()[p].field];
pkKeyValue += "{"+pkColNames[v] + '~' +getColDbType(grid.getColumns()[p].field) + ":"+value+"},";
break;
}
}
}
function getColDbType(colName) {
for (var c = 0; c < cols.length; c++) {
if (colName == cols[c].colName) {
return cols[c].colType;
}
}
}
pkKeyValue = pkKeyValue.substring(0, pkKeyValue.length-1);
$.ajax({
url: 'anotherUrl',
type:'GET',
dataType:'text',
success: function(f) {
bootbox.alert("Data updated successfully");
},
error: function() {
bootbox.alert("Error - updating data. Please ensure you are adding the data in right format.");
grid.invalidateAllRows();
grid.render();
}
});
});
grid.onClick.subscribe(function (e) {
//do-nothing
});
dataView.onRowsChanged.subscribe(function(e, args) {
grid.updateRowCount();
grid.invalidateRows(args.rows);
grid.render();
});
grid.onSort.subscribe(function(e, args) {
// args.multiColumnSort indicates whether or not this is a multi-column sort.
// If it is, args.sortCols will have an array of {sortCol:..., sortAsc:...} objects.
// If not, the sort column and direction will be in args.sortCol & args.sortAsc.
// We'll use a simple comparer function here.
var comparer = function(a, b) {
return a[args.sortCol.field] > b[args.sortCol.field];
}
// Delegate the sorting to DataView.
// This will fire the change events and update the grid.
dataView.sort(comparer, args.sortAsc);
});
// wire up the search textbox to apply the filter to the model
$("#txtSearch").keyup(function (e) {
console.log('Called...txtSearch');
Slick.GlobalEditorLock.cancelCurrentEdit();
// clear on Esc
if (e.which == 27) {
this.value = "";
}
searchString = this.value;
updateFilter();
});
function updateFilter() {
console.log("updateFilter");
dataView.setFilterArgs({
searchString: searchString
});
dataView.refresh();
}
dataView.beginUpdate();
dataView.setItems(data, pkColNames);
dataView.setFilterArgs({
searchString: searchString
});
dataView.setFilter(myFilter);
dataView.endUpdate();
},
error : function() {
bootbox.alert("Invalid user");
}
});
});
});
Your function myFilter() is always returning true so of course it will never work. The example that you looked at, was to filter something specific. I would recommend that you look at the following example to have a generic filter. From the example, simply type the text you are looking on a chosen column and look at the result... see example below (from SlickGrid examples).Using fixed header row for quick filters
In case you want a more in depth conditional filters ( > 10, <> 10, etc...), please take a look at my previous answer on how to make this kind of filtering possible, see my previous answer below:SlickGrid column type
Hope that helps you out

object parameters in Javascript

I'm having a bit of an issue with my javascript object. What I want to do is pass in an id and have it set a variable that is accessible to all of my functions.
Here's a small sample of what I have:
var myObject = function() {
var pageSize = 6;
var currentPage = 1;
var pagerPagesVisible = 5;
var pagerId = '#my-pager';
var entityId = '';
var doStuff = function() {
var endIndex = pageSize * currentPage;
var startIndex = endIndex - pageSize;
$.ajax({ type: "GET", url: "/items/" + this.entityId + "/entities/" + startIndex + "/" + pageSize + "/", dataType: "json", success: loadData, cache: false,
error: function(response, status, error) {
alert(response.responseText);
}
});
};
var loadData = function(data) {
var itemCount = data.length;
//build the html and write to the page
buildPager(itemCount);
};
var buildPager = function(itemCount) {
pager.build(pagerId, pageSize, itemCount, currentPage);
};
var attachEvents = function() {
//attach events to the pager
};
return {
init: function(entityId) {
this.entityId = entityId;
doStuff();
}
}
} ();
the issue is, in init, it sets the entityId instance that you see at the top. But when it hits doStuff() entityId is set back to ''.
You're mixing closure and object styles - you need to be consistent:
<script>
var myObject = function() {
var pageSize = 6;
var currentPage = 1;
var pagerPagesVisible = 5;
var pagerId = '#my-pager';
var entityId = '';
var doStuff = function() {
alert(entityId);
};
return {
init: function(myEntityId) {
entityId = myEntityId;
doStuff();
}
}
} ();
myObject.init(123);
</script>
Others have answered your question here, but I wanted to point out that you may want to use the prototype if you are going to be creating many of these objects.
When you enclose your methods you waste memory on every instantiation.
ClassName.prototype.methodname = function(){ ... }
That's because the entityId variable is local to the function and has nothing to do with the object you create at the end. Instead, put everything in that object at the end and not as locals in the function.
eg.
var myObject = function() {
var pageSize = 6;
var currentPage = 1;
var pagerPagesVisible = 5;
var pagerId = '#my-pager';
return {
doStuff: function() {
var endIndex = pageSize * currentPage;
var startIndex = endIndex - pageSize;
var self = this;
$.ajax( {
type: "GET",
url: "/items/" + this.entityId + "/entities/" + startIndex + "/" + pageSize,
dataType: "json",
success: function() { self.loadData(); },
cache: false,
error: function(response, status, error) {
alert(response.responseText);
}
} );
},
loadData: function(data) {
var itemCount = data.length;
this.buildPager(itemCount);
},
buildPager = function(itemCount) {
pager.build(pagerId, pageSize, itemCount, currentPage);
},
attachEvents: function() {
//attach events to the pager
},
entityId: '',
init: function(entityId) {
this.entityId = entityId;
this.doStuff();
}
};
}();

Resources