I'm looking for alternatives for the plug In values in legend.
The plug in uses jQuery and I'm running a Angular 5 application.
Has someone created a solution for that before?
labelFormat: '<span style="color:{color}">{name}</span>: <b>{point.y:.2f} USD</b> ({point.change:.2f}%)<br/>'
Here is a sample of Hicharts using jQuery to access the chart container and display the series value on legend.
To get rid of jquery you can replace jquery .bind method with js addEventListener on chart.container. Next, follow highcharts-angular documentation and create your own wrapper for this plugin. Check demo posted below.
Value-in-legend.js plugin:
(function(factory) {
if (typeof module === "object" && module.exports) {
module.exports = factory;
} else {
factory(Highcharts);
}
})(function(Highcharts) {
Highcharts.Series.prototype.point = {}; // The active point
Highcharts.Chart.prototype.callbacks.push(function(chart) {
chart.container.addEventListener("mousemove", function() {
var legendOptions = chart.legend.options,
hoverPoints = chart.hoverPoints;
// Return when legend is disabled (#4)
if (legendOptions.enabled === false) {
return;
}
if (!hoverPoints && chart.hoverPoint) {
hoverPoints = [chart.hoverPoint];
}
if (hoverPoints) {
Highcharts.each(hoverPoints, function(point) {
point.series.point = point;
});
Highcharts.each(chart.legend.allItems, function(item) {
item.legendItem.attr({
text: legendOptions.labelFormat
? Highcharts.format(legendOptions.labelFormat, item)
: legendOptions.labelFormatter.call(item)
});
});
chart.legend.render();
}
});
});
// Hide the tooltip but allow the crosshair
Highcharts.Tooltip.prototype.defaultFormatter = function() {
return false;
};
});
Next, initialize it in your component:
require("./path-to-your-file/value-in-legend")(Highcharts);
Demo:
https://codesandbox.io/s/j2j7wxwv7y
Here I am validating a field in my jquery-mobile form:
$("#contactForm").submit(function (e)
{
e.preventDefault();
if($("#name").val() == '')
{
alert("Fill in name");
}
});
Obviously I don't want to do this using an alert box. How might I convey to the user instead that the field is invalid? I would like to have a solution that works on all typical mobile platforms.
Create a custom class.
.required {
border: 1px solid red;
}
Add / remove it to fields:
Text input
$(document).on('blur', 'textarea, input', function (e) {
if (!$(this).val() && e.target.localName == 'input') {
$(this).closest('div').addClass('required');
}
if (!$(this).val() && e.target.localName == 'textarea') {
$(this).addClass('required');
}
});
Textarea
$(document).on('focus', 'textarea, input', function (e) {
if (e.target.localName == 'input') {
$(this).closest('div').removeClass('required');
}
if (e.target.localName == 'textarea') {
$(this).removeClass('required');
}
});
Demo
This is my first time really delving into jQuery with my ASP MVC3 intranet app. I need the autocomplete to be able to reference a list of items from a database. I followed the tutorial found here and thought "ok, that looks easy"... and now after implementing the code and researching other methods and bashing my head against the keyboard for at least four hours I'm not anywhere closer to making this work that before I wrote the code.
Here is the code from the view, w/the library declarations as well. FYI - I am taking over this project, so all the other javascript/Ajax you see was written by someone else with more experience than me. I put all the code in this section just in case something else is getting in the way.
<link href="../../Content/jquery-ui-1.9.2.custom.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-1.8.3.js" type="text/javascript"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$("#BankName").autocomplete({
source: '#Url.Action("GetBanks", "AgentTransmission")',
minLength: 1
});
$(function () {
$("#drpProducerType").change(function () {
var value = $(this).val();
if (value == "SoleProprietor") {
$("#Role").val(value);
$('#DSSfields').removeClass('noSee');
$('#DSSfields').addClass('seeMe');
//alert("Role must be set to \"Sole Proprietor\" as well. Monet will do this for you!");
}
else {
//TO DO: add role stuff here as well
$('#DSSfields').removeClass('seeMe');
$('#DSSfields').addClass('noSee');
}
});
$("#Role").change(function () {
var value = $(this).val();
if (value == "SoleProprietor") {
$("#drpProducerType").val(value);
alert("Producer Type changed to \"Sole Proprietor\" as well");
}
});
});
function ChangeChannel() {
//this function called if Market Segment changes, to update the channel
var pendistcode = document.getElementById('Pendist');
if (pendistcode == null) alert('Error: Cannot find Market Segment control');
$.ajax({
type: 'POST',
url: '/AgentTransmission/GetChannel/',
data: { pendist: pendistcode.value },
success: function (data) {
// alert("success: " + data);
$('#channelName').html(data);
$('#Channel').val(data);
},
error: function (data) {
alert("failure to obtain Channel name");
}
});
CheckTerritory('channel');
} //end ChangeChannel
function CheckTerritory(category) {
//this function called when changes happen that could change the territory (inddist)
//if the channel changed, or the alignment indicator, update the Territory
if ((category == "channel") | (category == "align")) UpdateTerritory();
//only trigger if the state or zip changed on the aligned address
if ((category == "L") && ($('#AlignmentL').attr('checked'))) UpdateTerritory();
if ((category == "M") && ($('#AlignmentM').attr('checked'))) UpdateTerritory();
} //end CheckTerritory
function UpdateTerritory() {
var i = $('#INDDist').val();
var p = $('#Pendist').val();
// alert(":" + i + ":" + p + ":");
//if ((i == "") || (p == "")) return;
if (p == "") return;
if ($('#INDDist').val() == "864") {
$('#INDDist').val("701");
}
else {
if ($('#INDDist').val() == "") {
$('#INDDist').val("864");
}
}
} //end UpdateTerritory
function MoreCompanies(row) {
//if the user clicks on the plus sign, add more company rows
if (row == '3') {
$('#plus2').html(' ');
$('#row3').removeClass('noSee');
$('#row3').addClass('seeMe');
}
if (row == '4') {
$('#plus3').html(' ');
$('#row4').removeClass('noSee');
$('#row4').addClass('seeMe');
}
if (row == '5') {
$('#plus4').html(' ');
$('#row5').removeClass('noSee');
$('#row5').addClass('seeMe');
}
} //end MoreCompanies
function CompanyFields() {
} //end CompanyFields
function ShowHideTerritory() {
alert('sunshine');
} //end ShowHideTerritory
</script>
The text box the autocomplete is supposed to work on
<div class="M-editor-label">
Bank\Agency Name
</div>
<div class="M-editor-field">
#Html.TextBoxFor(model => model.BankName, new { id = "BankName" })
#Html.ValidationMessageFor(model => model.BankName)
</div>
and here is the GetBanks method from the controller. I've set a breakpoint at the first line of this method and I've never been able to get it to hit.
//GET
public JsonResult GetBanks(string search)
{
var banks = from c in db.BankListMaster.Where(n => n.BankName.Contains(search))
select c.BankName;
banks = banks.Distinct();
return Json(banks, JsonRequestBehavior.AllowGet);
}
EDIT
If I replace the current .autocomplete code with the code suggested by this method instead , I get the following error in Chrome's debugger:
Uncaught Error: cannot call methods on autocomplete prior to initialization; attempted to call method '/AgentTransmission/GetBanks'
Here's the new code, I put it in the exact same spot as what I was previously using:
$(document).ready( function() {
$('#BankName').autocomplete('#Url.Action("GetBanks", "AgentTransmission")', {
dataType: 'json',
parse: function(data) {
var rows = new Array();
for(var i=0; i<data.length; i++){
rows[i] = { data:data[i], value:data[i].BankName };
}
return rows;
},
formatItem: function(row, i, n) {
return row.BankName + ' - ' + row.Description;
},
width: 300,
mustMatch: true,
});
});
I added an extra set of closing brackets to the autocomplete which cleared this up. The widget functions properly now.
$(function () {
$("#BankNameAuto").autocomplete({
source: '#Url.Action("GetBanks", "AgentTransmission")',
minLength: 1
});
});
I'm using SlickGrid (2.0) dataView with slick.editors. In the Grid, a user can edit any number of cells which then modifies the underlying grid data so that the edits are maintained when the grid scrolls. This works great. But I also want to provide visual feedback for all the edits since these are not saved to the database until user hit "Save Edits" button.
Problem is that the editor method resets the cell after it reads back the changed grid data. I need to maintain a background color change to indicate that it's been edited. Has anyone been able to do this?
Here is the relevent code (simple Integer editor):
function IntegerCellEditor(args) {
var $input;
var defaultValue;
var scope = this;
this.init = function() {
$input = $("<input type=text class='edited' type=text style='font:normal 12px arial; width:95px; text-align:right; border:none;' />");
$input.bind("keydown.nav", function(e) {
if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
e.stopImmediatePropagation();
}
});
$('#saveChanges').removeAttr("disabled"); // remove disabled attribute from "Save Changes" btn
$input.appendTo(args.container);
$input.focus().select();
};
this.destroy = function() {
$input.remove();
};
this.focus = function() {
$input.focus();
};
this.loadValue = function(item) {
defaultValue = item[args.column.field];
$input.val(defaultValue);
$input[0].defaultValue = defaultValue;
$input.select();
};
this.serializeValue = function() {
return parseInt($input.val(),10) || 0;
};
this.applyValue = function(item,state) {
item[args.column.field] = state;
};
this.isValueChanged = function() {
return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
document.getElementsByClassName('ui-widget-content slick-row')[row].className += 'edited';
};
this.validate = function() {
if (isNaN($input.val()))
return {
valid: false,
msg: "Please enter a valid integer"
};
return {
valid: true,
msg: null
};
};
this.init();
}
This line does nothing and I can't figure out how to do this:
document.getElementsByClassName('ui-widget-content slick-row')[row].className += 'edited';
Thanks
I am not an expert in SlickGrid but take a look a Example 14, I think it has similar information that would help you.
My idea would be something like:
subscribe to grid.onCellChange event
store changes in object
use grid.setCellCssStyles('highlight',changes) to update CSS or grid.addCellCssStyles
Hope that helps a little at least.
I am currently porting a large application over to a HTML5 based web app - I have started building the app in AngularJS and enjoying the power of the AngularJS framework - I have one issue standing in my way currently:
I have a directive that gives me a jQuery Datepicker however the binding to the model does not seem to be working.
http://jsfiddle.net/9BRNf/
I am probably misunderstanding the way directives work and would like to see if I can patch this part of my understanding of the framework. I have gone through loads of examples (including the angularui project on github but still not making sense of why the binding is not happening)
any assistance will be greatly appreciated.
For those Googling this issue (as I was), a simpler way of tying in the jQuery UI datepicker with Angular is to do this...
$.datepicker.setDefaults({
// When a date is selected from the picker
onSelect: function(newValue) {
if (window.angular && angular.element)
// Update the angular model
angular.element(this).controller("ngModel").$setViewValue(newValue);
}
});
Just place it prior to your .datepicker() initialisation code.
(Taken from another answer I posted here: https://stackoverflow.com/a/17206242/195835)
First off, it's great that you are using angularjs, its a sweet framework. An offshoot project was started awhile back to deal with things like wrapping jquery-ui and creating ui modules.
Below is link to Peter Bacon Darwin's implementation.
https://github.com/angular-ui/angular-ui/tree/master/modules/directives/date
--dan
The angular-ui datepicker wasn't working with Angular 1.0.0, so I rewrote it. My fork gives you the ability to set how the date is formatted inside the input and how it gets saved back to the model.
Code: https://gist.github.com/2967979
jsFiddle: http://jsfiddle.net/m8L8Y/8/ (It's missing jquery-ui styles but works just the same)
// Code inspired by angular-ui https://github.com/angular-ui/angular-ui/blob/master/modules/directives/date/src/date.js
/*
Features:
* via the ui-date attribute:
* Ability to say how model is parsed into a date object
* Ability to say how input's value is parsed into a date object
* Ability to say how a date object is saved to the model
* Ability to say how a date object is displayed in the input
* via the ui-date-picker attribute
* Ability to directly configure the jQuery-ui datepicker
*/
angular.module('ui.directives', [])
.directive('uiDate', function () {
return {
require: '?ngModel',
//scope: {},
link: function ($scope, element, attrs, ngModel) {
// Date Handling Functions
var dateHandler = $.extend({ model: {}, view: {} }, $scope.$eval(attrs.uiDate));
// This will attempt to use preferredParser to parse a date.
function defaultDateParse(date, preferredParser) {
if (!preferredParser)
return new Date(date);
return preferredParser(date);
}
// This will attempt to use preferredFormatter to format a date, otherwise use 'mm/dd/yy'.
function defaultDateFormatter(date, preferredFormatter) {
if (!preferredFormatter)
preferredFormatter = "mm/dd/yy";
if (typeof preferredFormatter == 'string')
return $.datepicker.formatDate(preferredFormatter, date);
else
return preferredFormatter(date);
}
// Functions for Parsing & Formatting on the Model & View
function parseDateFromModel(date) {
return defaultDateParse(date, dateHandler.model.parse)
}
function parseDateFromView(date) {
return defaultDateParse(date, dateHandler.view.parse)
}
function formatDateForModel(date) {
return defaultDateFormatter(date, dateHandler.model.format)
}
function formatDateForView(date) {
return defaultDateFormatter(date, dateHandler.view.format)
}
var defaultDateViewFormat = (
typeof dateHandler.view.format == 'string'
? dateHandler.view.format
: 'mm/dd/yy'
)
// Initialize the jQuery-ui datePicker
var datePickerSettings = $.extend({ dateFormat: defaultDateViewFormat }, $scope.$eval(attrs.uiDatePicker))
var oldOnSelect = datePickerSettings.onSelect;
datePickerSettings.onSelect = function (dateVal) {
$scope.$apply(function () {
element.focus().val(dateVal);
updateModel();
})
if (oldOnSelect)
oldOnSelect.apply(this, arguments)
}
element.datepicker(datePickerSettings);
if (ngModel) {
// Specify how UI should be updated
ngModel.$render = function () {
element.val(ngModel.$viewValue || '');
};
// Listen for change events to enable binding
element.bind('blur keyup change', function () {
$scope.$apply(updateModel);
});
// Write data to the model
function updateModel() {
ngModel.$setViewValue(element.val());
}
// Convert the model into a string value
ngModel.$formatters.push(function (v) {
if (v != "" && v != null)
return formatDateForView(parseDateFromModel(v));
return null;
});
// Convert the string value into the model
ngModel.$parsers.push(function (v) {
if (v != "" && v != null)
return formatDateForModel(parseDateFromView(v))
return null;
});
}
}
};
})
Similar to praveepd (using their's as a base), but this will include deep model selection.
http://jsfiddle.net/c8PMa/
var myApp = angular.module('myApp', ['myApp.directives']);
function MainCtrl($scope) {
$scope.deepValue = {
fromDate: null,
toDate: null
}
}
angular.module('myApp.directives', [])
.directive('myDatepicker', function() {
return function(scope, element, attrs) {
element.datepicker({
changeYear : true,
changeMonth : true,
appendText : '(yyyy-mm-dd)',
dateFormat : 'yy-mm-dd',
onSelect: function(dateText) {
var mdlAttr = $(this).attr('ng-model').split(".");
if (mdlAttr.length > 1) {
var objAttr = mdlAttr[mdlAttr.length-1];
var s = scope[mdlAttr[0]];
for (var i=0; i < mdlAttr.length-2; i++) {
s = s[mdlAttr[i]];
}
s[objAttr] = dateText;
} else {
scope[mdlAttr[0]] = dateText;
}
scope.$apply();
}
});
}
});
http://jsfiddle.net/9BRNf/74/ here is the solution :)
code:
var myApp = angular.module('myApp', ['myApp.directives']);
function MainCtrl() {
}
angular.module('myApp.directives', [])
.directive('myDatepicker', function() {
return {
require: '?ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
element.datepicker({
changeYear : true,
changeMonth : true,
appendText : '(yyyy-mm-dd)',
dateFormat : 'yy-mm-dd',
onSelect: function(date) {
ngModelCtrl.$setViewValue(date);
scope.$apply();
}
});
}
}
});
Old question, but this was the first hit for me in google search for this. Anyways, I used dual datepickers working together using jquery and angular directives, so I thought I'd share to help anyone else trying to do this.
Here's the plunker for it:
http://plnkr.co/edit/veEmtCM3ZnQAhGTn5EGy?p=preview
Basically it initializes the form using json. The datepickers have their own conditions like mindate's, etc. The first select box if true = disables sundays on the calendars, else enables them.
The viewmodel get's updates when 'done' is clicked. Here's a bit of the code for one of the datepickers:
Html:
<input id="StartDate" data-ng-model="viewModel.startdate" date-from />
Directive:
app.directive('dateFrom', function() {
return function (scope, element, attrs) {
var doDate = $('#EndDate');
element.datepicker({
dateFormat: 'dd-M-yy', showOtherMonths: true,
selectOtherMonths: true, minDate: '0',
beforeShowDay: function (date) {
var day = date.getDay();
console.log(scope.nosunday);
if (scope.nosunday === 'true') return [(day !== 0), '']; // disable sundays
else return [true, ''];
},
onSelect: function (selectedDate) {
var toDate = new Date(element.datepicker("getDate"));
toDate.setDate(toDate.getDate() + 1);
doDate.datepicker('option', 'minDate', toDate);
scope.viewModel.startdate = selectedDate;
scope.viewModel.enddate = doDate.val();
}
});
}
})
Feel free to optimize it further. Post a comment with a forked plunk if you do :)
I had just trimmed the code, have a look at this: http://jsfiddle.net/YU5mV/
HTML
<input id="date1" value="1/1/1980" ng-model="fromDate" my-datepicker />
<input id="date2" value="1/1/1980" ng-model="toDate" my-datepicker />
JavaScript
angular.module('myApp.directives', [])
.directive('myDatepicker', function() {
return function(scope, element, attrs) {
element.datepicker({
changeYear : true,
changeMonth : true,
appendText : '(yyyy-mm-dd)',
dateFormat : 'yy-mm-dd',
onSelect: function(dateText) {
var mdlAttr = $(this).attr('ng-model');
scope[mdlAttr] = dateText;
scope.$apply();
}
});
}
});