i have a little issue with my variables disappearing from a certain scope. My code is below
$(document).ready(function(){
var t = $("textarea:not(#testimony)"), a = ['.paragraph', '.underline', '.italics', '.bold'], b = ["<p>", "<u>", "<i>", "<b>"];
t.on("focus", function() {
var d = $(this), f = $(this).val(), g = f.substr(f.selectionStart, f.selectionEnd);
for (var i = 0; i < a.length; i++) {
$(a[i]).bind("click", function(){ alert(f);
d.val(f.substr(0, f.indexOf(g)) + /*function() {
return b[i] + $(this).text() + b[i].substr(0, 1) + "/" + b[i].substr(1);
} +*/ f.substr(f.indexOf(g)));
});
}
});
});
The f variable disappears once I throw it into that bind method but the alertcall does run when it is called say at the loop entry or in the outer function. I would probably use use or global in PHP but I have no idea how to reference those variables here. Someone please help!
I think there are a couple of issues here. First of all, youâre binding an additional click handler to those a elements each time you focus the textarea, each time with its current value as f. I canât imagine this is the desired behaviourâŚ? Furthermore, f[0] is the first character of the textareaâs value, so f[0].substr() doesnât really make sense. And if the textarea has no value, it even yields a type error as f[0] is undefined.
SORRRRRY! Error on my part. Please see modified initial post. I should be using jQueryâs native wrap function to wrap the selected text with the corresponding elements but it doesnât work for a reason I suspect is the same variable scoping so I have decided to do the wrapping my gaddemn self! Thank you
I have more than one textarea on the live site so the event needs to be bound each time to know whoâs buttons were clicked and whoâs text area value to alter.
No need to apologise! Anyway the bin gives you the following warning:
Line 10: Donât make functions within a loop.
Which is exactly what I was telling you above. Iâm still not sure what youâre actually trying to achieve, but if you want to access the textarea value within those click handlers, fetch it from there anew each time the handler is called. Like (maybe?)
$('.paragraph, .underline, .italics, .bold').click(function() {
var val = $("textarea:not(#testimony)").val();
// etc.
});
Edit after x-post:
Then youâd have to query the context differently, e.g. by a common parent element. The way youâre doing it results in a new event handler each time any textarea gets focused, so if you focus a textarea say 3 times, every single a element will have no less but 3 event handlers attached to it.
With this, how do I know what corresponding value for the b array to return? Iâm working with both remember? If a[1] is clicked for instance, return the textarea value wrapped in b[1] as an html tag.
I donât see where youâre even accessing that b array. Do you mean that line which is commented out? And no, I do not remember as you didnât mention it anywhere in this thread (maybe elsewhere?). Please clarify what youâre trying to do, otherwise I can hardly help you.
Yes. That line was commented out because when I click on the âbuttonsâ that have the click event attached to them, it returns the contents of that function as a string. You can uncomment the line and see for yourself. But feel free the uncomment it and see for yourself. I just didnât mention it because I felt the code logic was self explanatory.
What the logic I have there intends to achieve is:
When a textarea is focused, pick its text content.
On click of on any div with any of the classes in the first array (a):
(a) Wrap the selected text with the corresponding value from array b
(b) Let the new value of this active textarea be the previous text plus the wrapped string from (a) above and any other text after it.
$('.paragraph, .underline, .italics, .bold').click(function() {
var textarea = $(this).nextAll('textarea');
var start = textarea.get(0).selectionStart;
var end = textarea.get(0).selectionEnd;
var value = textarea.val();
var tag = $(this).attr('data-tag');
textarea.val(
value.substr(0, start) +
`<${tag}>` +
value.substr(start, end - start) +
`</${tag}>` +
value.substr(end)
);
});
Hereâs a fiddle. BTW if you want to make your code self-explanatory, Iâd suggest to use meaningful variable names and make your code more readable overall with line breaks and proper indentation.
Thatâs a new ES6 feature called (a bit misleadingly) template literals⌠basically just saves you a few quotes and pluses.
Yes, that would work too â note though that .siblings() returns all siblings; the only difference to .nextAll() is that the latter goes only in one direction.
Returns just the direct sibling when you provide the required element as argument to the siblings() method. I donât know why jQuery has two methods doing the exact same function but Iâm more conversant with the siblings() method. All the same, thank you for telling me about the template literals. Iâll look into it soon.