I'm trying to make a form ADA compliant which requires tabbing over several dropzone fields that need to use the onKeyDown event handler in addition to being clickable.
I tried adding onkeydown to the dropzoneJsConfig like so:
this.dropzoneJsConfig = {
addRemoveLinks: true,
clickable: true,
onkeydown: true,
..., }
But that doesn't seem to work.
I added the tabIndex to a the div encompassing the Dropzone element:
return (
<div tabIndex={0} className={className}
ref={(div) => this.afterRender(div)}
data-help-text={help_text}
data-valid={this.state.valid}
data-processing={this.state.processing}
>
<Dropzone config={this.dropzoneConfig} eventHandlers={this.dropzoneEventHandlers} djsConfig={this.dropzoneJsConfig}>
</Dropzone>
</div>
);
Please help!
Related
Here's some example HTML I'm trying to produce:
<div>
<input type="checkbox" id="checkbox_1" name="checkbox_1" />
<label for="checkbox_1"></label>
</div>
This is my downcast converter:
conversion.for( 'downcast' ).elementToElement( {
model: 'checkbox',
view: ( modelElement, viewWriter ) => {
const div = viewWriter.createContainerElement( 'div', {} );
const input = viewWriter.createEmptyElement( 'input', {'type': 'checkbox'} );
const label = viewWriter.createEditableElement( 'label', {} );
viewWriter.insert( viewWriter.createPositionAt( div, 0 ), input );
viewWriter.insert( viewWriter.createPositionAt( div, 1 ), label );
return toWidgetEditable( div, viewWriter );
}
} );
In the CKEditor 5 inspector, I can see that the view is rendered like this:
<div contenteditable="true" class="ck-editor__editable ck-editor__nested-editable">
<input type="checkbox" />
<label>
</label>
</div>
In the editor, I can't add text to the label or the surrounding div.
If I change the div declaration from createContainerElement to createEditableElement, I can insert text in the div, but I still can't edit the label.
How do I set up the converters so that I can have an editable label attached to my <input>? I've tried looking at the todolist code from ckeditor5-list, but it doesn't use conversion.for or elementToElement at all, so I'm a bit lost.
The code that you posted is incorrect because you cannot create view elements like that, out of the blue. They need to be mapped to something in the model if they are supposed to be editable. Unless this was supposed to be a non-editable region. In which case you should use toWidget() not to toWidgetEditable().
The second problem is that using focusable fields inside the editor has to be done very carefully. Such elements must be inside a non-editable part of the widget, plus, you need to stop the editor from handling events on them. This, currently, can only be achieved with a hack:
// Hack needed to make the input fields accessible and responsive when used in a widget.
function preventCKEditorHandling( domElement, editor ) {
// Prevent the editor from listening on below events in order to stop rendering selection.
domElement.addEventListener( 'click', stopEventPropagationAndHackRendererFocus, { capture: true } );
domElement.addEventListener( 'mousedown', stopEventPropagationAndHackRendererFocus, { capture: true } );
domElement.addEventListener( 'focus', stopEventPropagationAndHackRendererFocus, { capture: true } );
// Prevents TAB handling or other editor keys listeners which might be executed on editors selection.
domElement.addEventListener( 'keydown', stopEventPropagationAndHackRendererFocus, { capture: true } );
function stopEventPropagationAndHackRendererFocus( evt ) {
evt.stopPropagation();
// This prevents rendering changed view selection thus preventing to changing DOM selection while inside a widget.
editor.editing.view._renderer.isFocused = false;
}
See: https://github.com/ckeditor/ckeditor5-core/compare/proto/input-widget#diff-44ca1561ce575490eac0d660407d5144R239
Essentially, I want to trigger the input button in the page using TypeScript
//its no different than doing it in vanilla JS
let elem = document.getElementById('submitBtn');
let evt = new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window
});
elem.dispatchEvent(evt);
Use #ViewChild as follows in .ts
#ViewChild('fileInput') fileInput: ElementRef;
let inputElement: HTMLElement = this.fileInput.nativeElement as HTMLElement;
inputElement.click();
In your .html,
<input #fileInput type="file" ng2FileSelect (onFileSelected)="fileUpload($event)"/>
JS code:
document.getElementById('mat-checkbox-1-input').click();
Happy Coding!!!
Google charts range filter works perfectly fine outside of accordion. The default range sliders are set at left most and right most. For example: http://jsfiddle.net/samsumi007/1v5xyqL9/
But the sliders get messed up when i put this google chart inside of accordion. For example: http://jsfiddle.net/samsumi007/k1cvd05m/ (Check Section 2)
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
// Load the Visualization API and the controls package.
google.load('visualization', '1.0', {
'packages': ['controls']
});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawDashboard);
// Callback that creates and populates a data table,
// instantiates a dashboard, a range slider and a pie chart,
// passes in the data and draws it.
function drawDashboard() {
// Create our data table.
var data = google.visualization.arrayToDataTable([
['Name', 'Donuts eaten'],
['Michael', 5],
['Elisa', 7],
['Robert', 3],
['John', 2],
['Jessica', 6],
['Aaron', 1],
['Margareth', 8]
]);
// Create a dashboard.
var dashboard = new google.visualization.Dashboard(
document.getElementById('dashboard_div'));
// Create a range slider, passing some options
var donutRangeSlider = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'filter_div',
'options': {
'filterColumnLabel': 'Donuts eaten'
}
});
// Create a pie chart, passing some options
var pieChart = new google.visualization.ChartWrapper({
'chartType': 'PieChart',
'containerId': 'chart_div',
'options': {
'width': 600,
'height': 600,
'pieSliceText': 'value',
'legend': 'right'
}
});
// Establish dependencies, declaring that 'filter' drives 'pieChart',
// so that the pie chart will only display entries that are let through
// given the chosen slider range.
dashboard.bind(donutRangeSlider, pieChart);
// Draw the dashboard.
dashboard.draw(data);
}
</script>
<script>
$(function() {
$("#accordion").accordion({
autoHeight: false,
active: false,
alwaysOpen: false,
fillspace: false,
collapsible: true,
navigation: true,
heightStyle: "content" //auto, fill, conten
});
});
</script>
</head>
<body>
<div id="accordion">
<h3>Section 1</h3>
<div></div>
<h3>Section 2</h3>
<div id="dashboard_div" style='height:900px;'>
<!--Divs that will hold each control and chart-->
<div id="filter_div"></div>
<div id="chart_div"></div>
</div>
</div>
</body>
I am not sure why it's behaving like this. Even though its displaying the correct data, the left and right sliders are set at '0' which doesn't make sense to user reading the graph.
Well, problem is your accordion is making the display hidden so when it tries to set the state of the control, it thinks the width available is 0 (you see your data correctly because the state is acually in 8). Can only think of 2 ways of fixing it:
1) After the first click on the chart section, set the correct width and left style properties for the state >> a bit hard (or just draw the chart after the section 2 has been clicked)
2) Make the accordion only after the chart has finished rendering:
<script>
var firstTimeLoaded=true;
//your code...
if (firstTime) { // if its the first time it draws, add the accordion
google.visualization.events.addListener(dashboard, 'ready', function() {
$("#accordion").accordion({
autoHeight: false,
active: false,
alwaysOpen: false,
fillspace: false,
collapsible: true,
navigation: true,
heightStyle: "content" //auto, fill, conten
});
google.visualization.events.removeAllListeners(dashboard) // remove listener
})
}
dashboard.draw(data);
Working fiddle: http://jsfiddle.net/k1cvd05m/1/
This issue is driving me mad.
So I've got a modal dialog.
<div class="modal">
<img src="...."/>
</div>
Instanciated thus:
$(".modal").dialog({
resizable: false,
draggable: false,
modal: true,
autoOpen: false,
width: 530,
height: 460,
closeOnEscape: false,
dialogClass: 'popup noTitle'
});
Then I have a form:
<form>
<input type="submit"/>
</form>
and Js to open the modal:
$('form input').click(function() {
$(".modal").dialog('open');
});
In most browsers this works great:
In IE 9 and IE 10. The modal is opened but the image is missing:
I believe it is something to do with the form submit, stopping the image from loading. If I run $(".modal").dialog('open'); from the console it works fine. I've tried preloading the images:
$("#divSearching img").each(function() {
var imgObj = new Image();
imgObj.src = $(this).attr('src');
});
Doesn't help. Anyone else having issues with this or have a good solution? Everything I've tried has failed.
Tried to create a fiddle but because it is related to a form submit I couldn't do it.
Try canceling the form submission:
$('form input').click(function() {
$(".modal").dialog('open');
return false;
});
Right now you have a form with a submit button and when someone clicks on the submit button this form gets sent to the server and the browser redirects away from its current location. You cannot expect any more javascript to continue executing at that stage. By returning false from the submit handler you are canceling the default action.
Figured out a solution. So I changed:
$('form input').click(function() {
$(".modal").dialog('open');
});
To:
$('form input').click(function(e) {
var $form = $(this).parents('form');
$(".modal").on('dialogopen', function() {$form.submit();});
$(".modal").dialog('open');
e.preventDefault();
});
This puts off the form submit until the js to open the dialog has completed. Like I said. Seems to be an IE9 and IE10 issue only. FireFox, Chrome, etc. work fine with this.
I've a column of XTemplate cells in a Grid Panel. How do I add a click event/listener that applies to all cells on this particular column? What I've tried so far works but applies to ALL clicks on ANY cell in the grid. I can't seem to manipulate the delegate option to filter for a particular class of element.
My code so far:
columns:[
...
{
xtype: 'templatecolumn',
text: 'Approve2',
flex: 1,
dataIndex: 'Approved',
align: 'center',
sortable: false,
tpl: '<input type="checkbox" class="approveCheckbox" />'
},
...
],
initComponent: function () {
this.on('itemclick', this.storeCheckboxVal, this, { delegate: '.approveCheckbox' });
},
...
,
storeCheckboxVal: function (view, record, item, index, event) {
alert(record.data['ID']);
}
AFAIK, delegate works only if you assign handler to DOM Element (not Component). Try this code instead:
initComponent: function () {
this.mon(this.el, 'click', this.storeCheckboxVal, this, { delegate: '.approveCheckbox' });
},
You'll probably need to change your grid's selType to cellmodel. After that, you should be able to listen to the grid view's cellclick. This appears to be undocumented, but I found it using Ext.util.Obersvable.capture(Ext.getCmp('my-grid-id'), console.log) Which is an extremely useful trick to know.
Thanks for the replies all, however I've managed to solve my problem via this solution: Ext JS on click event