For example
Case 1 : <p></br></br></br></br></br>Sample Content</br>This is next line</br></br></br></br></br></br></p>
Result : <p>Sample Content</br>This is next line</p>
Case 2 : <p></br></br>Sample Content</p>
Result : <p>Sample Content</p>
Case 3 : <p></br></br></br>Sample Content</br></br></br>This is next line</br></br></br></br></br></br></p>
Result : <p>Sample Content</br></br></br>This is next line</p>
If you mean the following with 'unnecessary': a br tag that is right after or before an other tag you can use the following code. This code will result in the desired output you have in your question (Edit: except for Case 3, which was added after I answered this question).
function trimSource(inputElemId="input", outputElemId="output") {
let input = document.getElementById(inputElemId).innerHTML;
let output = input;
do {
input = output;
output = input.replaceAll("><br>", ">").replaceAll("<br><", "<");
} while (input!=output);
document.getElementById(outputElemId).innerHTML = output;
}
.input, .output {
display: block;
border: 1px solid black;
}
<button onclick="trimSource()">Click here to 'Trim' input to output</button><br>
output:<br>
<span id="output" class="output"></span>
input:<br>
<span id="input" class="input">
<p></br></br></br></br></br>Sample Content</br>This is next line</br></br></br></br></br></br></p></span>
Related
For example:
one
two
three
four
five
six
seven
eight
nine
ten
eleven
twelve
to
one two three
four five six
seven eight nine
ten eleven twelve
I couldn't figure out how to do this and was only able to do vice versa on vscode.
Not a shortcut, but you can easily do such job with find ans replace.
Ctrl+H
Find what: (\w+)\R(\w+)\R(\w+)
Replace with: $1 $2 $3
CHECK Wrap around
CHECK Regular expression
Replace all
Explanation:
(\w+) # group 1, 1 or more word characters
\R # any kind of linebreak
(\w+) # group 2, 1 or more word characters
\R
\R # any kind of linebreak
Screenshot (before):
Screenshot (after):
Not VS Code, but you can do that using this snippet:
Just bookmark this answer if you need it again (or copy and paste the snippet info into an HTML file on your device). Also, I think the "Copy to clipboard" button doesn't work because the snippet runs in a cross-origin iframe, but it should work in a same-origin context.
function splitWordsPerLine (text, wpl = 1) {
let result = '';
wpl = wpl < 1 ? 1 : wpl;
let count = wpl;
for (const word of text.split(/\s+/)) {
count -= 1;
let line = word;
if (count === 0) {
line += '\n';
count = wpl;
}
else line += ' ';
result += line;
}
return result.trim();
}
function getWPL (numberInput) {
if (!numberInput) return 1;
const wpl = parseInt(numberInput.value, 10);
return Number.isNaN(wpl) ? 1 : wpl;
}
function handleInput (event) {
const wpl = getWPL(event.target);
const textInput = document.getElementById('text');
if (!textInput) return;
textInput.value = splitWordsPerLine(textInput.value, wpl);
}
async function handleClick (event) {
let message = 'Copying failed 😭';
const textInput = document.getElementById('text');
try {
if (!textInput) throw new Error('No input found');
await navigator.clipboard.writeText(textInput.value);
message = 'Text copied ✅';
}
catch {}
textInput?.select();
const setText = str => event.target.textContent = str;
setText(message);
setTimeout(() => setText('Copy to clipboard'), 1500);
}
function handlePaste (event) {
const text = event.clipboardData?.getData('text');
if (!text) return;
const wpl = getWPL(document.getElementById('wpl'));
event.target.value = splitWordsPerLine(text, wpl);
event.preventDefault();
}
document.getElementById('wpl')?.addEventListener('input', handleInput);
document.getElementById('copy')?.addEventListener('click', handleClick);
document.getElementById('text')?.addEventListener('paste', handlePaste);
html {
box-sizing: border-box;
height: 100%;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
font-family: sans-serif;
height: 100%;
margin: 0;
padding: 1rem;
}
.container {
display: flex;
gap: 0.5rem;
}
.container.vertical {
flex-direction: column;
height: 100%;
}
#copy {
background-color: black;
border: 0;
color: white;
display: inline-flex;
align-items: center;
font-size: 1rem;
padding: 0.5rem;
}
#wpl, #text {
border: 1px solid;
font-family: monospace;
padding: 0.5rem;
}
#wpl {
font-size: 1.5rem;
width: 5rem;
}
#text {
font-size: 1rem;
height: 100%;
width: 100%;
resize: none;
white-space: pre;
}
<div class="container vertical">
<div class="container">
<input id="wpl" type="number" min="1" step="1" value="1" />
<button id="copy">Copy to clipboard</button>
</div>
<textarea id="text" rows="0" cols="0" placeholder="Select number of words per line, then paste your text here"></textarea>
</div>
You can use extension Select By and the command selectby.lineNr
Place the cursor on the first line
execute command: Place cursor based on line number, uses boolean expression
enter expression: c+3k to place a cursor every 3 lines
maybe expression: c+3k && n<50 to limit the end line to use
now use End Space Delete as often as needed
press Esc to exit Multi Cursor Mode
Hi so I have these radio buttons where I want to save their data as json in my Postgres db . It is not being sent I get a message.success back that says I did but when i check my db nothing happens.
I don't exactly know where I am wrong so if u can help please do share.
PS: Im using Ant Design vue that's where the a- come from .
I do click on a button and it opens a modal where I have the radio buttons :
<template #modalite="{ record }">
<span>
<a-button
#click="showModalite(record)"
class="btn btn-sm btn-light mr-2"
>
<i class="fe fe-edit mr-2" />
Modalité
</a-button>
</span>
</template>
and here is my buttons code :
<a-modal
v-model:visible="visible"
:width="500"
#ok="ChangeModalite(modelInfo)"
>
<div class="row">
<a-radio-group name="radioGroup" v-model:value="traitement">
<div class="col-md-6">Négociation directe</div>
<div class="col-md-3">
<a-radio value="Négociation directe" v-model:checked="modalite.negociation" />
</div>
<div class="col-md-6">Appel à concurrence</div>
<div class="col-md-3">
<a-radio value="Appel à concurrence" v-model:checked="modalite.concurrence"/>
</div>
</a-radio-group>
</div>
</a-modal>
The script :
setup() {
const visible = ref(false)
const traitement = ref('Négociation directe');
const modalite = ref({
negociation:false,
concurrence:false,
})
const showModalite = (record) => {
modelInfo.value = record
modalite.value = { ...modalite.value, ...record.modalite }
visible.value = true
}
const ChangeModalite = (record) => {
console.log(record.id+": "+traitement.value)
axios.patch('/prop/' + record.id,{
modalite:modalite.value,
})
.then(()=>{
record.modalite=modalite.value
Object.assign(
dataSource.value.filter((item) => record.id === item.id),
record,
)
message.success(`successfully updated !!`)
visible.value = false
})
.catch((e)=>{
message.warning("smthg wrong ")
})
}
return {
dataSource,
modelInfo,
showModalite,
ChangeModalite,
modalite,
traitement,
}
},
}
So what happens now is i get the 'succefully updated ' msg without being really updated.where did i miss something?
I changed the type from json to string in my db everything works fine when I changed this line :axios.patch('/prop/' + record.id,{ modalite:modalite.value, }) to this axios.patch('/prop/' + record.id,{ modalite:traitement.value, })
so yeah data gets updated, still don't know why with the json type it's not working but at least i found a way if u have an explanation or suggestion it will be appriciated .
How can I format a number inside a itemTpl?
Example:
'<div style="font-size: 9px;">Total: $ {total}</div>' <= This number {total} must be 100.00, but appears just 100
Thanks!
Use a member function of your XTemplate:
itemTpl: new Ext.XTemplate(
'<div style="font-size: 9px;">Total: $ {[this.formatTotal(values.total)]}</div>',
formatTotal: function(total) {
return //formattedTotal
}
)
Learn more here: http://docs.sencha.com/touch/2.2.1/#!/api/Ext.XTemplate
As #kevhender said you can use Ext.XTemplate and toFixed javascript method for formatting.
More specific
itemTpl: new Ext.XTemplate(
'<div style="font-size: 9px;">Total: $ {[this.totalFormat(values.total)]}</div>',{
totalFormat : function(total) {
return total.toFixed(2);
}
})
I have created a webcomponent called "color-item" and instantiated it throug adding its custom element tag in the html. I'we also given the elements id's like this:
<color-item id="colorItem1" color_text="LimeGreen" bg_color="LimeGreen" ></color-item>
<color-item id="colorItem2" color_text="green" bg_color="YellowGreen" ></color-item>
The compoenents show up just fine and behave as expected. However, when I try to access those elements (in the main loop) to do some fun things on them with Dart-code I just end up with errors. Here is how I have tried to access them:
ColorItem color_Item1 = query("#colorItem1").xtag;
ColorItem color_Item2 = query("#colorItem2").xtag;
That produces the following error:
Breaking on exception: type 'DivElement' is not a subtype of type 'ColorItem' of 'color_Item1'.
I'we also tried casting like this:
ColorItem color_Item1 = query("#colorItem1").xtag(ColorItem);
ColorItem color_Item2 = query("#colorItem2").xtag(ColorItem);
That produces a similar error:
Exception: type 'DivElement' is not a subtype of type 'ColorItem' of 'color_Item1'.
Breaking on exception: Class 'DivElement' has no instance method 'call'.
The component itself is defined like this:
<!DOCTYPE html>
<html>
<body>
<element name="color-item" constructor="ColorItem" extends="div">
<template>
<style scoped>
.color-box{
cursor:pointer;
padding:20px;
margin:10px;
margin-left:0px;
display:inline-block;
width:auto;
height:auto;
position: relative;
font-size: 24px;
color:white;
background-color:orange;
border-radius:24px;
box-shadow: 2px 2px 10px rgba(0,0,0,0.2);
user-select: none;
}
</style>
<div class="color-box" style="background-color:{{bg_color}}; color:{{text_color}}" on-click="swapColor()"> Color: <b>{{color_text}}</b> </div>
</template>
<script type="application/dart" src="ColorItem.dart"></script>
</element>
</body>
</html>
and the script for the component looks like this:
import 'package:web_ui/web_ui.dart';
class ColorItem extends WebComponent {
#observable
String color_text ="orange";
#observable
String bg_color ="orange";
#observable
String text_color ="white";
#observable
ColorItem next_color_item =null;
List<String> colors = new List<String>()
..add("LimeGreen")
..add("green")
..add("yellow")
..add("OrangeRed")
..add("red")
..add("purple")
..add("blue");
int i = 0;
String getNextColor(){
i++;
i%=colors.length;
return colors[i];
}
void swapColor(){
String oldColor = bg_color;
String nextColor = getNextColor();
bg_color = nextColor;
color_text = nextColor;
if(next_color_item!=null){
next_color_item.bg_color = oldColor;
next_color_item.color_text = oldColor;
}
}
}
Any suggestions?
The problem is that the custom elements haven't been "ugraded" yet, so the xtag isn't set properly. The specific error you're seeing is odd though, because I would expect xtag to be null, not a DivElement.
Try this and see if it works:
Timer.run(() {
ColorItem color_Item1 = query("#colorItem1").xtag;
ColorItem color_Item2 = query("#colorItem2").xtag;
});
Try replacing;
<color-item id="colorItem1" color_text="LimeGreen" bg_color="LimeGreen" ></color-item>
<color-item id="colorItem2" color_text="green" bg_color="YellowGreen" ></color-item>
with
<div is="x-color-item" id="colorItem1" color_text="LimeGreen" bg_color="LimeGreen" ></div>
<div is"x-color-item" id="colorItem2" color_text="green" bg_color="YellowGreen" ></div>
and replace
<element name="color-item" constructor="ColorItem" extends="div">
with
<element name="x-color-item" constructor="ColorItem" extends="div">
and try to use code like the following in main;
var color_Item1 = query("#colorItem1").xtag;
print(color_Item1.attributes);
color_Item1.attributes.forEach((k,v){
print('$k :: $v');
});
var color_Item2 = query("#colorItem2").xtag;
Not tested, but could you try this?
<color-item
on-load='onLoadHandler($event)'
/>
Then in the main, foresee the handler :
void onLoadHandler(Event event) {
DivElement theDiv = event.currentTarget as DivElement;
// then the xtag
theDiv.xtag.doSomethingVeryFunky();
}
I have a strange behaviour with the code below:
function update(txt, _)
{
#text = <>{txt}</>
#data = <>{txt}</>
}
command = <a onclick={update("test1", _)}> change text1 </a> <+>
<a onclick={update("test2", _)}> change text2 </a>
content = <textarea style="width:30%;" rows=1 id=#text > filename </textarea>
<textarea style="width:100%;" rows=30 id=#data > This is a text area </textarea>
Server.start(
Server.http,
[
{page: function() {command <+> content}, title: "test" }
]
)
When I clik on the links "change text1" or "change text2", the text is updated in the two textareas, but as soon as I edit the value of one of these textareas, the update failed when I clik on the links.
Why ?
i think this is because once you have edited a textarea, the browser considers the "value" attribute of the textarea, and not the HTML content inside the textarea.
So in order to work, you should :
function update(txt, _)
{
Dom.set_value(#text, txt)
Dom.set_value(#data, txt)
}