I have a vue component that has different methods, f.ex. mouseMove:
mouseMove: function(event) {
console.log("Event is: " + event);
element5 = event.target
this.elementMove = element5
if (element5.getAttribute('data') == 'day') {
hourPreStart = parseInt(element5.getAttribute('value'))
dayPreStart = parseInt(element5.parentElement.firstChild.getAttribute('day-value'));
this.hourPreEnd = hourPreStart
this.dayPreEnd = dayPreStart
}
console.log(this.hourPreStart, this.dayPreStart, this.hourPreEnd, this.dayPreEnd)
},
When I hover over a field with my mouse I get this error:
I don't know what the problem is because event is defined.
Here's the full component.
Can someone help me?
You are using this code:
<tbody #mousedown='mouseDown' #mouseup='mouseUp' #mousemove='mouseMove'>
But you should add $event to handlers like this:
<tbody #mousemove='mouseMove($event)'>
event5 is not defined (as the error stares). You have to first define event5 to use it.
Use this
mouseMove: function(event) {
console.log("Event is: " + event);
let element5 = event.target
this.elementMove = element5
if (element5.getAttribute('data') == 'day') {
let hourPreStart = parseInt(element5.getAttribute('value'))
let dayPreStart = parseInt(element5.parentElement.firstChild.getAttribute('day-value'));
this.hourPreEnd = hourPreStart
this.dayPreEnd = dayPreStart
}
console.log(this.hourPreStart, this.dayPreStart, this.hourPreEnd, this.dayPreEnd)
}
Related
I need help,
Requirement
when the user types in an input box I want to highlight the link with blue color if any
My Research
when I dig into it, I realize that without using a contenteditable div it's not possible to do, also there is no v-model associated with contenteditable div I am manually updating the state.
so far I have this, courtesy- contenteditable div append a html element and v-model it in Vuejs
<div id="app"><div class="flex">
<div class="message" #input="updateHtml" v-html="html" contenteditable="true"></div>
<br>
<div class="message">{{ html }}</div>
</div>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
html: 'some text',
},
methods: {
updateHtml: function(e) {
this.html = e.target.innerHTML;
},
renderHtml: function(){
this.html += '<img src="https://cdn-images-1.medium.com/max/853/1*FH12a2fX61aHOn39pff9vA.jpeg" alt="" width=200px>';
}
}
});</script>
Issue
every time user types something, the focus is misbehaving which is strange to me, I want v-html to update along with user types #keyup,#keydown also have the same behavior.it works ok on #blur #focusout events, but that's not what I want
Appreciate Help.Thanks
I figured it out myself. Posting the answer so that may help other developers. v-HTML doesn't do all the trick. You’ll need to store the cursor position so it can be restored properly each time the content updates as well as parse the content so that it renders as expected. Here is the example
HTML
<p>
An example of live syntax highlighting in a content-editable element. The hard part is storing and restoring selection after changing the DOM to account for highlighting.
<p>
<div contentEditable='true' id='editor'>
Edit text here. Try some words like bold and red
</div>
<p>
Just a demo trivial syntax highlighter, should work with any syntax highlighting you want to implement.
</p>
JS
const editor = document.getElementById('editor');
const selectionOutput = document.getElementById('selection');
function getTextSegments(element) {
const textSegments = [];
Array.from(element.childNodes).forEach((node) => {
switch(node.nodeType) {
case Node.TEXT_NODE:
textSegments.push({text: node.nodeValue, node});
break;
case Node.ELEMENT_NODE:
textSegments.splice(textSegments.length, 0, ...(getTextSegments(node)));
break;
default:
throw new Error(`Unexpected node type: ${node.nodeType}`);
}
});
return textSegments;
}
editor.addEventListener('input', updateEditor);
function updateEditor() {
const sel = window.getSelection();
const textSegments = getTextSegments(editor);
const textContent = textSegments.map(({text}) => text).join('');
let anchorIndex = null;
let focusIndex = null;
let currentIndex = 0;
textSegments.forEach(({text, node}) => {
if (node === sel.anchorNode) {
anchorIndex = currentIndex + sel.anchorOffset;
}
if (node === sel.focusNode) {
focusIndex = currentIndex + sel.focusOffset;
}
currentIndex += text.length;
});
editor.innerHTML = renderText(textContent);
restoreSelection(anchorIndex, focusIndex);
}
function restoreSelection(absoluteAnchorIndex, absoluteFocusIndex) {
const sel = window.getSelection();
const textSegments = getTextSegments(editor);
let anchorNode = editor;
let anchorIndex = 0;
let focusNode = editor;
let focusIndex = 0;
let currentIndex = 0;
textSegments.forEach(({text, node}) => {
const startIndexOfNode = currentIndex;
const endIndexOfNode = startIndexOfNode + text.length;
if (startIndexOfNode <= absoluteAnchorIndex && absoluteAnchorIndex <= endIndexOfNode) {
anchorNode = node;
anchorIndex = absoluteAnchorIndex - startIndexOfNode;
}
if (startIndexOfNode <= absoluteFocusIndex && absoluteFocusIndex <= endIndexOfNode) {
focusNode = node;
focusIndex = absoluteFocusIndex - startIndexOfNode;
}
currentIndex += text.length;
});
sel.setBaseAndExtent(anchorNode,anchorIndex,focusNode,focusIndex);
}
function renderText(text) {
const words = text.split(/(\s+)/);
const output = words.map((word) => {
if (word === 'bold') {
return `<strong>${word}</strong>`;
}
else if (word === 'red') {
return `<span style='color:red'>${word}</span>`;
}
else {
return word;
}
})
return output.join('');
}
updateEditor();
Hope this helps...
I want to create a Bar chart on Excel Add-in, but I want to get the target position of the chart from the user in a textfield, how can I use that value and assign it to the chart.setPosition ? Is it possible to add the parameter for the setPosition function as a variable that contains the value taken as input from the textfield?
Here is my code:
function createBarChart() {
Excel.run(function (context) {
const sheet = context.workbook.worksheets.getItem("Sheet1");
const salesTable = sheet.tables.getItem("Table1");
const dataRange = salesTable.getDataBodyRange();
let chart = sheet.charts.add("ColumnClustered", dataRange, "Auto");
chart.setPosition("A9", "F20");
chart.title.text = "Farm Sales Bar chart";
chart.legend.position = "Right";
chart.legend.format.fill.setSolidColor("white");
chart.dataLabels.format.font.size = 15;
chart.dataLabels.format.font.color = "black";
let points = chart.series.getItemAt(0).points;
points.getItemAt(0).format.fill.setSolidColor("pink");
points.getItemAt(1).format.fill.setSolidColor("indigo");
return context.sync();
})
.catch(function (error) {
console.log("Error: " + error);
if (error instanceof OfficeExtension.Error) {
console.log("Debug info: " + JSON.stringify(error.debugInfo));
}
});
}
You could use
<input type="text" id="leftTop"/>
<input type="text" id="bottomRight"/>
in the HTML for user to enter the param, and use
let value = $("#leftTop").val();
let lt = String(value);
value = $("#bottomRight").val();
let br = String(value);
chart.setPosition(lt, br);
to parse the textfield into chart.setPosition.
Here's a sample code, you could run it by import into ScriptLab.
I am creating a simple app using Sencha Touch where I'm dynamically creating container with textfields, textareafields etc. when the user needs to add new container with components. The problem now is when the clear icon on the textareafield is tapped it clears the text, but I would like to know which textareafield has been cleared. Can anyone help me in this please?
This is how I created container .
var childObj2 = {};
childObj2.xtype = 'container';
var type = 'vbox';
var layout = {}
layout.type = type;
childObj1.layout = layout;
var txtarea= {};
txtarea.xtype = 'textareafield';
txtarea.id = "txt51";
txtarea.flex = 3;
txtarea.maxRows = 7;
txtarea.placeHolder = 'Type here';
txtarea.value = value['notes'];
txtarea.inputCls = 'txtareaStyle'
txtarea.clearicontap = "clearText";
How to add clearicontap listener to this?
When you you create a textfield simply add a listener to it for the clearicontap event and that callback will get executed for each of the fields.
For example:
var container = Ext.create('Ext.Container', {});
for (var i=1; i<=3; i++) {
var field = Ext.create('Ext.field.Text', {
id: 'textfieldnumber' + i,
listeners: {
clearicontap: function() {
alert("Tapped clear icon on text field number: " + i + "!");
}
}
});
container.add(field);
}
[EDIT]
I answer the question you make after your edit:
I am using the standard way of creating Sencha components through Ext.create(), and I would suggest you to switch to the same way. It is not clear by the code you posted how those Javascript objects are actually transformed into Ext components. Anyway, they are very likely components configurations, so I guess you could try:
txtarea.listeners = {
clearicontap: function() {
alert("Tapped clear icon on text field");
}
}
I have a little problem / question. I work on a little WYSIWYG editor. I use a div with the option contentEditable="true" and I would like to know when there is a click on a button which element in my div is modifying by the user.
For example if there is 3 paragraphs on the the div, and that user modifies the second, I would like to know when he clicks on a button that he is currently to modify the second paragraph to show the text content ! In this example "P2" :
<div contenteditable="true"><p>P1</p><p>P2</p><p>P3</p></div>
Thanks in advance for your help.
Nicolas
You could examine the selection in the mousedown event of the button. The following will work in all major browsers:
function getSelectionBoundaryContainerElement(start) {
var container = null;
if (typeof window.getSelection != "undefined") {
var sel = window.getSelection();
if (sel.rangeCount) {
var range = sel.getRangeAt(0);
range.collapse(start);
container = range.startContainer;
if (container.nodeType != 1) {
container = container.parentNode;
}
}
} else if (typeof document.selection != "undefined" && document.selection.type != "Control") {
var textRange = document.selection.createRange();
textRange.collapse(start);
container = textRange.parentElement();
}
return container;
}
document.getElementById("yourButtonId").onmousedown = function() {
alert(getSelectionBoundaryContainerElement().innerHTML);
}
I have a programmer class that populates a ul with project names and checkboxes - when a checkbox is clicked a popup dialog is supposed to show with the programmers id and the project name. dojo.connect is supposed to setup onclick for each li but the project (i) defaults to the last value (windows). Any ideas why this is happening?
...
projects: {"redial", "cms", "android", "windows"},
name: "Chris",
id: "2",
constructor: function(programmer) {
this.name = programmer.name;
this.id = programmer.id;
this.projects = programmer.projects;
},
update: function(theid, project) {
alert(theid + ", " + project);
},
postCreate: function() {
this.render();
// add in the name of the programmer
this.programmerName.innerHTML = this.name;
for(var i in this.projects) {
node = document.createElement("li");
this.programmerProjects.appendChild(node);
innerNode = document.createElement("label");
innerNode.setAttribute("for", this.id + "_" + i);
innerNode.innerHTML = i;
node.appendChild(innerNode);
tickNode = document.createElement("input");
tickNode.setAttribute("type", "checkbox");
tickNode.setAttribute("id", this.id + "_" + i);
if(this.projects[i] == 1) {
tickNode.setAttribute("checked", "checked");
}
dojo.connect(tickNode, 'onclick', dojo.hitch(this, function() {
this.update(this.id, i)
}));
node.appendChild(tickNode);
}
},
Just found out that extra parameters can be attached to the hitch:
dojo.connect(tickNode, 'onclick', dojo.hitch(this, function() {
this.update(this.id, i)
}));
should be:
dojo.connect(tickNode, 'onclick', dojo.hitch(this, "update", this.id, i));
Why are you calling this.render()? Is that your function or the widget base (i.e. already in the lifecycle)? For good measure make sure to call this.inherited(arguments); in postCreate.
My guess would be that tickNode is not in the DOM yet for the connect to work. Try appending the checkbox before you setup the connect. The last one is being fired because it is being held on by reference. You can try something like this instead:
for(var i = 0; i < this.projects.length; i++) {
var p = this.projects[i];
node = document.createElement("li");
this.programmerProjects.appendChild(node);
innerNode = document.createElement("label");
innerNode.setAttribute("for", this.id + "_" + p);
innerNode.innerHTML = p;
node.appendChild(innerNode);
tickNode = document.createElement("input");
tickNode.setAttribute("type", "checkbox");
tickNode.setAttribute("id", this.id + "_" + p);
if(i == 0) { //first item checked?
tickNode.setAttribute("checked", "checked");
}
node.appendChild(tickNode);
dojo.connect(tickNode, 'onclick', function(e) {
dojo.stopEvent(e);
this.update(this.id, p);
});
}
I would consider looking into dojo.create as well instead of createElement as well. Good luck!
Alternatively, and I think it's cleaner, you can pass the context into dojo.connect as the third parameter:
dojo.connect(tickNode, 'onclick', this, function() {
this.update(this.id, i);
});