Break when style has changed in Chrome Dev Tools - debugging

I just wonder if anyone know if it's possible to add a break point on a specific css property on a specific element in Chrome Dev Tools, i.e when #mydiv's height property has changed, break.

You can only break on all inline style (<div style="height: 20px; width: 100%">) changes using the Elements panel context menu's Break on... | Attributes modifications.

You can do it this way:
function observe(el, property) {
var MutationObserver = window.WebKitMutationObserver;
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log('old', mutation.oldValue, 'new', mutation.target.style.cssText, 'mutation', mutation);
if (mutation.attributeName == property) debugger;
});
}
);
var config = {
attributes: true,
attributeOldValue: true
}
observer.observe(el, config);
}
Then you can set breakpoint on style change like this: observe(element, "style")
It will break when it changes and also print in console old and new value.

Related

Kendo Grid validation message position issue

The Kendo grid I developed has a validation message, but the arrow points to the column to the right. I cannot change anything in /kendo.default.min.css as this is located in a shared folder which should not be changed. Any help on this?
dataSource: {
data: data.ReportData,
schema: {
model: {
fields: {
ProposedDiscount: {
validation: {
required: true,
proposeddiscountcvalidation: function (input) {
if (input.val() != "" && input.is("\[name='ProposedDiscount'\]")) {
input.attr("data-proposeddiscountcvalidation-msg", "Should be whole number between 0 & 100");
// $('.k-widget k-tooltip k-tooltip-validation k-invalid-msg .k-icon k-warning .k-tooltip-validation .k-callout-n').removeClass('.k-callout-n');
return input.val() >= 0 && input.val() < 101 && input.val() % 1 == 0;
} else {
return true;
}
}
}
}
You could try simply overriding some of the styles on the validation tool-tip. This works for me, though I've scoped it pretty tight to try to avoid any unexpected effects elsewhere. You might need to modify it slightly, depending on what version of kendo you're using:
<style>
.k-grid .k-grid-content tr.k-grid-edit-row>td[role='gridcell'] .k-tooltip-validation>.k-callout-n {
left: auto;
margin-left: auto;
}
</style>
Edit: I've just noticed you said you "cannot change anything in /kendo.default.min.css" - you shouldn't need to. This should override the default styles provided by kendo in that file. If you've got your own site-wide CSS file you could add it to that, or even just add it directly to the page hosting your grid (though that's not really recommended). Hope this helps.
The Kendo style default displays the tooltip and places the callout (arrow) in the center of the tooltip. If the message is wide enough, like in your example, because the arrow is in the center it ends up pointing to the wrong cell. If you constrain the tooltip to the width of the cell it will wrap the message and keep it constrained to the cell width, which means the centered arrow will line up.
.k-validator-tooltip { width: min-content; }

CKEditor: multiple widget templates

I'm currently creating a 'smartobject' widget. In the widgets dialog, the user can choose a 'smartobject', which simply put, generates some html, which should be added to the editor. Here comes the tricky part: the html sometimes div elements and sometimes simply span elements. In the case of the div variant, the widget should be wrapped in a div 'template'. In the case of a span variant, the widget should be wrapped in a span and the html should be added 'inline'.
In the widgets API I see the following way to define a template:
editor.widgets.add('smartobject', {
dialog: 'smartobject',
pathName: lang.pathName,
template: '<div class="cke_smartobject"></div>', // <------
upcast: function(element) {
return element.hasClass('smartObject');
},
init: function() {
this.setData('editorHtml', this.element.getOuterHtml());
},
data: function() {
var editorHtml = this.data.editorHtml;
var newElement = new CKEDITOR.dom.element.createFromHtml(editorHtml);
newElement.copyAttributes(this.element);
this.element.setText(newElement.getText());
}
});
But in my case, the template is more dynamic: sometimes a div and sometimes the span will do the correct thing..
How can I fix this without needing to create two widgets which will do the exact same thing, with only the wrapping element as difference?
I've already tried to replace the entire element in the 'data' method, like:
newElement.replace(this.element);
this.element = newElement;
But this seemed not supported: resulted in undefined errors after calling editor.getData().
I'm using ckeditor v4.5.9
Thanks for your help!
It seems I got it working (with a workaround).
The code:
CKEDITOR.dialog.add('smartobject', this.path + 'dialogs/smartobject.js');
editor.widgets.add('smartobject', {
pathName: lang.pathName,
// This template is needed, to activate the widget logic, but does nothing.
// The entire widgets html is defined and created in the dialog.
template: '<div class="cke_smartobject"></div>',
init: function() {
var widget = this;
widget.on('doubleclick', function(evt) {
editor.execCommand('smartobject');
}, null, null, 5);
},
upcast: function(element) {
return element.hasClass('smartObject');
}
});
// Add a custom command, instead of using the default widget command,
// otherwise multiple smartobject variants (div / span / img) are not supported.
editor.addCommand('smartobject', new CKEDITOR.dialogCommand('smartobject'));
editor.ui.addButton && editor.ui.addButton('CreateSmartobject', {
label: lang.toolbar,
command: 'smartobject',
toolbar: 'insert,5',
icon: 'smartobject'
});
And in the dialog, to insert code looks like:
return {
title: lang.title,
minWidth: 300,
minHeight: 80,
onOk: function() {
var element = CKEDITOR.dom.element.createFromHtml(smartobjectEditorHtml);
editor.insertElement(element);
// Trigge the setData method, so the widget html is transformed,
// to an actual widget!
editor.setData(editor.getData());
},
...etc.
UPDATE
I made the 'onOk' method a little bit better: the smartobject element is now selected after the insertion.
onOk: function() {
var element = CKEDITOR.dom.element.createFromHtml(smartobjectEditorHtml);
var elementId = "ckeditor-element-" + element.getUniqueId();
element.setAttribute("id", elementId);
editor.insertElement(element);
// Trigger the setData method, so the widget html is transformed,
// to an actual widget!
editor.setData(editor.getData());
// Get the element 'fresh' by it's ID, because the setData method,
// makes the element change into a widget, and thats the element which should be selected,
// after adding.
var refreshedElement = CKEDITOR.document.getById(elementId);
var widgetWrapperElement = CKEDITOR.document.getById(elementId).getParent();
// Better safe then sorry: if the fresh element doesn't have a parent, simply select the element itself.
var elementToSelect = widgetWrapperElement != null ? widgetWrapperElement : refreshedElement;
// Normally the 'insertElement' makes sure the inserted element is selected,
// but because we call the setData method (to ensure the element is transformed to a widget)
// the selection is cleared and the cursor points to the start of the editor.
editor.getSelection().selectElement(elementToSelect);
},
So in short, I partially used the widget API for the parts I wanted:
- Make the html of the widget not editable
- Make it moveable
But I created a custom dialog command, which simply bypasses the default widget insertion, so I can entirely decide my own html structure for the widget.
All seems to work like this.
Any suggestions, to make it better are appreciated:)!
As suggested in this ckeditor forum thread, the best approach would be to set the template to include all possible content elements. Then, in the data function, remove the unnecessary parts according to your specific logic.

Kendo Grid: Removing dirty cell indicators

I have been looking at a way to save off my client side edited grid data automatically when the user changes to another row (just like in access, sql management studio etc). It really seems to be a bit of a challenge to do.
One scheme was to use the data source sync, but this ha the problem of loosing our cell position (it always jumped to cell 0, 0).
I have been shown some clever work arounds (go back to the cell after the case, which by the way is hugely appreciated thanks),
but it after some lengthy testing (by myself and others) seemed to be a little "glitchy" (perhaps I just need to work on this more)
At any rate, I wanted to explore perhaps not using this datasource sync and perhaps just do the server side calls "manually" (which is a bit is a pity, but if that's what we need to do, so be it). If I do this, I would want to reset the cell little red cell "dirty" indicators.
I thought I could use something similar to this scheme (except rather than resetting the flag, I want to unset).
So, as in the above link, I have the following..
var pendingChanges = [];
function gridEdit(e) {
var cellHeader = $("#gridID").find("th[data-field='" + e.field + "']");
if (cellHeader[0] != undefined) {
var pendingChange = new Object();
pendingChange.PropertyName = e.field;
pendingChange.ColumnIndex = cellHeader[0].cellIndex;
pendingChange.uid = e.items[0].uid;
pendingChanges.push(pendingChange);
}
}
where we call gridEdit from the datasource change..
var dataSrc = new kendo.data.DataSource({
change: function (e) {
gridEdit(e);
},
Now assuming we have a callback that detects the row change, I thought I could do the following...
// clear cell property (red indicator)
for (var i = 0; i < pendingChanges.length; i++) {
var row = grid.tbody.find("tr[data-uid='" + pendingChanges[i].uid + "']");
var cell = row.find("td:eq(" + pendingChanges[i].ColumnIndex + ")");
if (cell.hasClass("k-dirty-cell")) {
cell.removeClass("k-dirty-cell");
console.log("removed dirty class");
}
}
pendingChanges.length = 0;
// No good, we loose current cell again! (sigh..)
//grid.refresh();
When this didn't work, I also tried resetting the data source dirty flag..
// clear dirty flag from the database
var dirtyRows = $.grep(vm.gridData.view(),
function (item) {
return item.dirty == true;
})
if (dirtyRows && dirtyRows.length > 0) {
dirtyRows[0].dirty = false;
}
demo here
After none of the above worked, I tried the grid.refresh(), but this has the same problem as the datasource sync (we loose our current cell)
Would anyone have any idea how I can clear this cell indicator, without refreshing the whole grid that seems to totally loose our editing context?
Thanks in advance for any help!
Css :
.k-dirty-clear {
border-width:0;
}
Grid edit event :
edit: function(e) {
$("#grid .k-dirty").addClass("k-dirty-clear"); //Clear indicators
$("#grid .k-dirty").removeClass("k-dirty-clear"); //Show indicators
}
http://jsbin.com/celajewuwe/2/edit
Simple solution for resolve that problem is to override the color of the "flag" to transparent.
just override the ".k-dirty" class (border-color)
just adding the above lines to your css
CSS:
//k-dirty is the class that kendo grid use for mark edited cells that not saved yet.
//we override that class cause we do not want the red flag
.k-dirty {
border-color:transparent transparent transparent transparent;
}
This can also be done by applying the below style,
<style>
.k-dirty{
display: none;
}
</style>

Optimizing AngularJS directive that updates ng-model and ng-style on focus

I'm new to AngularJS and I'm making made a couple of custom Angular directives to do what I used to do with Jquery, however there is one case where I'm not sure if I'm doing it the "the angular way". It works but I think there might be a better way.
I want to do is this for a search box:
When focus is on the search box the app must change the color of the text in the box from grey to black. The app must also then check the current text in the box, if it is the default text then the app must clear the text.
When the box loses focus (blur) the app must change the box's text back to grey. It must then put back the default text only if the text box is empty upon losing focus.
Here is a jsfiddle that has a directive set up to do all of this perfectly.
http://jsfiddle.net/Rick_KLN/5N73M/2/
However I suspect there is an even better way to do it.
It seems like all three those variables in the controller should be unnecessary.
I also seems like having 4 if, else statements is too much and that binding to all the events is overkill seeing as only focus and blur are used and they are specified in the if statements.
Any ideas on optimizing this directive?
The "default text" behavior you are looking for is automatically handled by the HTML5 placeholder attribute. It is supported in just about any modern browser, and can be styled using CSS, as follows:
Markup:
<input id="searchBar" type="text" placeholder="Search" />
CSS:
#searchBar { color: #858585; }
#searchBar:focus { color: #2c2c2c; }
#searchBar:focus::-webkit-input-placeholder { color: transparent; }
#searchBar:focus::-moz-placeholder { color: transparent; }
#searchBar:focus:-moz-placeholder { color: transparent; }
#searchBar:focus:-ms-input-placeholder { color: transparent; }
It's that simple.
Notes:
The pseudo-elements & pseudo-classes (-webkit-input-placeholder, etc) are what hide the placeholder text on focus. Normally it stays until you start typing.
I forked your original jsFiddle. It's not really an AngularJS app anymore:
http://jsfiddle.net/Smudge/RR9me/
For older browsers: You can still use the same code as above, but you could use Modernizr (or something similar) to fall-back to a javascript-only approach if the attribute is not supported.
You can create a custom directive that requires the ng-model directive and then within your directive's link function supply a fourth parameter that is a reference to the model. This will allow you to watch the model for changes and react accordingly. Here is the fiddle:
http://jsfiddle.net/brettlaforge/6t39j/3/
var app = angular.module('app', []);
app.directive('searchbar', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, model) {
var options = scope.$eval(attrs.searchbar);
scope.$watch(attrs.ngModel, function(value) {
// If the input element is currently focused.
if (!elm.is(":focus")) {
// If the input is empty.
if (value === undefined || value === "") {
// Set the input to the default. This will not update the controller's model.
elm.val(options.default);
}
}
});
elm.on('focus', function(event) {
// If the input is equal to the default, replace it with an empty string.
if (elm.val() === options.default) {
elm.val('');
}
});
elm.on('focusout', function(event) {
// If the input is empty, replace it with the default.
if (elm.val() === '') {
elm.val(options.default);
}
});
}
};
});
function FormCtrl($scope) {
$scope.search = "";
}​

jQuery plugin for filtering the options in multi-select box as you type

I have a multi-select box populated with some pre-defined list. I want to filter those options as user types in the input box above it.
Can anybody suggest any available jQuery plugin?
Thanks,
Saurabh
var input = $('input'),
select = $('select');
input.keyup(function() {
var inputVal = $(this).val(),
inputLength = inputVal.length;
select.find('option').each(function() {
if ($(this).val().substr(0, inputLength) != inputVal) {
$(this).attr({ disabled: 'disabled' });
} else {
$(this).removeAttr('disabled');
}
select.focus();
input.focus();
});
});
jsFiddle.
The focus to select and then back is to make the browser redraw the changes, which it wasn't doing in mine (Chrome 9).
If you want them to actually be removed, you will need to remove them and re-add them as required because display: none didn't work for me.

Resources