Call previous sibling as function parameter? - javascript

I'm building a wee letter-writing tool that will have a range of paragraphs the user can choose to add to a letter, but I worry that I'm doing it in a really inefficient way.
Currently, it's structured like this:
<p id="deposit-dispute" class="paragraph">This is a paragraph about deposits not being protected</p>
<button onclick="addPara(depositDispute)" class="add">Add paragraph</button>
and then in the Javascript, I create a const that pulls the inner HTML of that id:
const depositDispute = "\n" + document.getElementById("deposit-dispute").innerHTML + "\n";
which the addPara() function then adds to the textarea:
function addPara(text) {
document.getElementById("text-body").value += text;
}
But would there be a way to make the function just call whatever the previous p element had in it, rather than having to give them all unique IDs and creating a unique variable for them all?
Here it is in a codepen so you can see what I'm trying to do - the paragraphs to be added are in the accordion on the right: https://codepen.io/gordonmaloney/pen/GRWyjOP
Thanks a lot - and big apologies if this is a ridiculously amateurish question, I've spent ages trying to google a solution but can't find a thing!
G

Each box contains a paragraph and a button.
We can get all the boxes and each box paragraph and button, and finally add click event to the button to insert the paragraph html of this box to the textarea
// Get textarea and boxes
var textarea = document.getElementById('textarea');
var boxes = document.querySelectorAll('.box');
// get the button and the paragraph of each box
boxes.forEach(box => {
var btn = box.querySelector('.button');
var paragraph = box.querySelector('.paragraph');
// add the html of the selected box paragraph to the textarea
btn.addEventListener('click', () => {
textarea.value += "\n" + paragraph.innerHTML; + "\n";
});
});
<div class="wrapper">
<div class="box">
<p class="paragraph">This is paragraph 1</p>
<button class="button">Add to textarea</button>
</div>
<div class="box">
<p class="paragraph">This is paragraph 2</p>
<button class="button">Add to textarea</button>
</div>
<div class="box">
<p class="paragraph">This is paragraph 3</p>
<button class="button">Add to textarea</button>
</div>
</div>
<textarea name="" id="textarea" cols="30" rows="10"></textarea>

Related

How do do you edit HTML form elements’ in jQuery?

I’m trying to make a simple font generator for a challenge. The form element I’m trying to edit is the tag.
The way this webpage is supposed to work is a user types in the “input textbox”, presses one of the 3 buttons and the new text will appear in the “output textbox” in the font that the user chooses.
This is what my HTML looks like:
<div id=“inputContainer”>
<p id=“inputText style=“text-decoration:underline;position:relative;”>Input</p>
<textarea id=“input” rows=“10” columns=“10”></textarea>
</div>
<div id=“outputContainer”>
<p id=“outputText” style=“text-decoration:underline;position:relative;”>Output</p>
<textarea id=“output” rows=“10” columns=10”></textarea>
</div>
And here is my jQuery/JS:
var inputText = $("#input").html();
$("#monospaceButton").click(function() {
$("#output").html(inputText);
});
The function only works if I manually add text between the tags (innerHTML). When the user types in the textarea in the code’s output (The website.), there will be no output in the “output” textarea.
I appreciate any help. Please let me know if I need to explain anything more clearly. Thanks!
$("#button1").click(function() {
var value = $("#input").val();
$("#output").css('font-family', 'serif');
$("#output").val(value);
});
$("#button2").click(function() {
var value = $("#input").val();
$("#output").css('font-family', 'monospace');
$("#output").val(value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<p id="inputText" style="text-decoration:underline;position:relative;">Input</p>
<textarea id="input" rows="3" columns="10"></textarea>
</div>
<button id="button1">Style 1</button>
<button id="button2">Style 2</button>
<div>
<p id="outputText" style="text-decoration:underline;position:relative;">Output</p>
<textarea id="output" rows="3" columns="10"></textarea>
</div>

programmatically select part of content on another contenteditable div

<div id="leftdiv" style="float:left;display:inline-block;height:100px;font-family:Helvetica;font-size:14px;width:300px;border:1px solid red;" contenteditable>
<div>
first text
</div>
<div>
second text
</div>
...
<div>
other texts
</div>
</div>
<div id="rightdiv" style="margin-left:1em;display:inline-block;float:left;width:300px;height:100px;font-family:Helvetica;font-size:14px;border:1px solid red;" contenteditable>
<div>
first text
</div>
<div>
second text
</div>
...
<div>
other texts
</div>
</div>
I have two contenteditable divs and these divs have exactly the same content. When I highlight part of content in leftdiv like "ond" in "second" text using mouse, i want exactly the same part in rightdiv highlighted at the same time. Eventually 2 highlighting in seperate divs will occur simultaneously.
I have tried this but nothing happens.
$('#leftdiv').on('mousedown', function() {
$('#leftdiv').on('selectstart', function() {
document.getElementById('rightdiv').tabIndex = -1 ;
document.getElementById('rightdiv').focus();
var range = document.createRange();
range.selectNodeContents(this);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
});
});
This is far from a complete solution, and it makes use of css to fake the second selection, but perhaps it will give you an idea.
Try selecting "ond" in the leftdiv, as you suggested in your description, and "ond" is highlighted in the rightdiv (after the selection is complete - it won't live update as you drag the mouse to change the selection).
If you select content across multiple divs within leftdiv, this will break, and if you select text that appears multiple times, it will highlight the first match, not the exact match. Like I said, just trying to give you a potential path to explore further.
$('#leftdiv').on('mouseup', function() {
$("*").removeClass("highlight");
$('#rightdiv').html($('#leftdiv').html());
var selection = window.getSelection()+"";
var matchStart = $('#rightdiv').html().indexOf(selection);
var matchEnd = matchStart + selection.length - 1;
var beforeMatch = $('#rightdiv').html().slice(0, matchStart);
var matchText = $('#rightdiv').html().slice(matchStart, matchEnd + 1);
var afterMatch = $('#rightdiv').html().slice(matchEnd + 1);
$('#rightdiv').html(beforeMatch + "<font class='highlight'>" + matchText + "</font>" + afterMatch);
});
.highlight {background-color:#b4daf7;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="leftdiv" style="float:left;display:inline-block;height:100px;font-family:Helvetica;font-size:14px;width:300px;border:1px solid red;" contenteditable>
<div>
first text
</div>
<div>
second text
</div>
...
<div>
other texts
</div>
</div>
<div id="rightdiv" style="margin-left:1em;display:inline-block;float:left;width:300px;height:100px;font-family:Helvetica;font-size:14px;border:1px solid red;" contenteditable>
<div>
first text
</div>
<div>
second text
</div>
...
<div>
other texts
</div>
</div>

Click button show different text, repeat first text

HTML:
<button id="slider1next" >Clickme</button>
<p class="text" id="first_one">This is the first text</p>
<p class="text" id="second_one" style="display:none">This is the second text</p>
<p class="text" id="third_one" style="display:none">This is the third text</p>
<p class="text" id="fourth_one" style="display:none">This is the four text</p>
JavaScript:
$("#slider1next").click(function() {
var $next = $(".text:visible").hide().next();
$next.length ? $next.show() : $(".text:first").show();
});
$("#slider2next").click(function() {
var $next = $(".text:visible").hide().prev();
$next.length ? $next.show() : $(".text:last").show();
});
I want to make it where the text is shown, but after the last text, it repeats the first text.
Trying to make something like this
If there's a better way to do this, other than using JavaScript and HTML, please let me know.. But JavaScript and HTML is the only way I can think of, an alternative to JS functions would be jQUERY. Help? ;-;
Looking for suggestions with the use of PHP, too, maybe to mock the code's intended for what I am trying to re-create using a different set of languages.
var count = 0;
$("#sliderNext").click(function() {
count++;
if (count < $('.text').length) {
$(".text:nth(" + count + ")").show().prev().hide();
} else {
$(".text:first").show();
$(".text:last").hide();
count = 0;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<button id="sliderNext">Next</button>
<p class="text" id="first_one">This is the first text</p>
<p class="text" id="second_one" style="display:none">This is the second text</p>
<p class="text" id="third_one" style="display:none">This is the third text</p>
<p class="text" id="fourth_one" style="display:none">This is the four text</p>
Use the modulo function to loop through a set of numbers: (count % 4) + 1. This will cycle through the numbers 1,2,3, and 4 if count starts at 0 and increases with each click of the next button.

Javascript split by spaces, but not within html-tags

My first goal is to split a string by spaces, but not the ones within html-tags.
I've tried to rewrite the following, unsuccessfully: Javascript split by spaces but not those in quotes
What would the regex look like in:
arr = fullHtmlString.split(?);
?
My main goal is to shift an IMG-tag by one space at a time.
After that I'll iterate over the array, search for the img-tag, remove it, and add it the next item, and finally join the array.
The code I use at the moment is quite comprehensive and use jQuery extensively to achive the goal.
Input:
<div>
<p><img class=something>Some text.</p>
<p>Some more text.</p>
</div>
Deisred output first time:
<div>
<p>Some<img class=something> text.</p>
<p>Some more text.</p>
</div>
...second time:
<div>
<p>Some text.<img class=something></p>
<p>Some more text.</p>
</div>
...third time:
<div>
<p>Some text.</p>
<p><img class=something>Some more text.</p>
</div>
You should not try to do this with a regular expression, why explained here.
You can use DOM properties and methods though
function run(){
var img = document.querySelector(".something"),
sibling = img,
parent = img.parentNode,
next = parent.nextElementSibling;
//Search for the next textNode
while((sibling = sibling.nextSibling) && sibling.nodeType !=3);
if(sibling) {
//split the text only once,
//so "some more text" becomes ["some","more text"]
var textParts = sibling.textContent.split(/ (.*)?/,2);
//put the first split item before the sibling
parent.insertBefore(document.createTextNode(textParts[0]+" "),sibling);
//replace the sibling with the img element
parent.replaceChild(img,sibling);
//finally if there was more text insert it after the img
textParts[1] && parent.insertBefore(document.createTextNode(textParts[1]),img.nextSibling);
} else if(!sibling && next) {
//no sibling in the current parent,
//so prepend it to the next available element in parent
next.insertBefore(img,next.firstChild);
} else {
clearInterval(timer);
}
}
var timer = setInterval(run,2000);
<div>
<p><img class="something" src="http://placehold.it/10x10">Some text.</p>
<p>Some <span>skip me</span> more text.</p>
</div>

Diff two containers with JS or jQuery

I want to update a container with a new version without replacing it. For example:
Container1:
<div id="container-one">
<p>
<webview src="http://i.stack.imgur.com/Ed1aw.jpg"></webview>
</p>
<p>
Text
</p>
</div>
Container2:
<div id="container-two">
<p>
Cool intro
<webview src="http://i.stack.imgur.com/Ed1aw.jpg"></webview>
</p>
<p>
Long text
</p>
<p>
New Paragraph with text in it.
</p>
</div>
Container1 updated:
<div id="container-one">
<p>
Cool intro
<webview src="http://i.stack.imgur.com/Ed1aw.jpg"></webview>
</p>
<p>
Long text
</p>
<p>
New Paragraph with text in it.
</p>
</div>
A Container1.innerHTML = Container2.innerHTMLwould be simple but I don't want to reload my webview so the code should detect new divs or updated content in existing divs and apply the modifications in Container1.
UPDATE :
Container2 is a new version of container1 edited by a user, so Container2 can have anything in it: images, links, new paragraphs.
How can I do this?
I might have not understood your question correctly, but by adding an id to the text that you want to replace, and using simple javascript, you can achieve this.
HTML
<div id="container-one">
<p>
<span id="inner-one-1"></span>
<webview src="http://i.stack.imgur.com/Ed1aw.jpg"></webview>
</p>
<p>
<span id="inner-one-2">Text</span>
</p>
</div>
<div id="container-two">
<p>
<span id="inner-two-1">Cool intro</span>
<webview src="http://i.stack.imgur.com/Ed1aw.jpg"></webview>
</p>
<p>
<span id="inner-two-2">Long text</span>
</p>
</div>
<button id="click">Click Me!</button>
JS
document.getElementById("click").onclick = function() {
document.getElementById("inner-one-2").innerHTML = document.getElementById("inner-two-2").innerHTML;
document.getElementById("inner-one-1").innerHTML = document.getElementById("inner-two-1").innerHTML;
}
DEMO HERE
please try it.
var container_one = $("#container-one").children();
var container_two = $("#container-two").children();
$.each(container_one, function(index, element){
var cont_one_html = $(this).html();
var cont_two_html = $(container_two[index]).html();
if(cont_one_html != cont_two_html){
$(this).html(cont_two_html);
}
});
please have a look on image for more understanding.
you need to get the text node and replace the content, like
$('button').on('click', function () {
// this block is for not to update the webview
// get the first text node
var txt = $('#container-one > p:first').contents().first().get(0);
if (txt.nodeType === 3) { // Node.TEXT_NODE
txt.nodeValue = $('#container-two > p:first').text();
}
// update rest of the elements
$('#container-two').children().each(function (i) {
if (i !== 0 && $('#container-one').children()[i]) {
$($('#container-one').children()[i]).html($(this).html());
}
if (!$('#container-one').children()[i]) {
$('#container-one').append($(this).clone());
}
});
});
DEMO
Have a try and see if this works for you.
var first = $('container-one p:first');
first.html($('container-two p:first').html() + first.html());
$('container-one p:last').html($('container-two p:last').html());
Use this:
function update(s){
document.getElementById("container-one").innerHTML=s.innerHTML;
}
setInterval(function(){
update(document.getElementById("container-two"));
},1000);
What this does is it updates the content once every second.
To show that it can handle dynamic content, I have made the second div editable.
Demo:http://jsfiddle.net/5RLV2/2

Categories

Resources