Note: I have a workaround to this problem, but I'd prefer to comma-separate the values as I describe below rather than separating them with spaces (which is what my workaround does).
I have an ASP.NET website that allows instructors to choose from a DropDownList of preset comments and apply these comments to students in their classes. I display the students and comments inside a GridView, and use a Label to display any comments that already exist in the database (removing them from the DropDownList in the process). When an instructor selects one of these comments and clicks a button, my jQuery function:
Pulls the selected value and text out of the option (provided it isn't the default option).
Checks Label.children().length, and appends a ", " to the text if it's greater than zero.
Creates a <span> tag with a hidden field containing the value and text.
Appends the text inside the span.
Closes the span.
Attaches an onclick event to the span.
Removes the original option from the DropDownList.
The span tag's onclick event does the reverse of what I describe above -- it pulls the value and text out and re-creates the option inside the drop-down menu. Additionally, it replaces strings like ", , " with ", " in the parent Label. I've found that when I replace these strings (which lie outside the spans I've attached the onclick events to) that the onclick events go away.
I'm familiar with .live(), but because each row in this GridView contains a unique reference to the particular student and class currently in use, I can't know the values that each row needs to pass into the funciton ahead of time. Is there any solution to this problem other than my described workaround or re-attaching the onclick event?
Here's an idea: Wrap the commas in <span>s with some class like 'separator'. Then, when you remove an item, you can check to see if it's the first thing in the list, and if so, remove the subsequent seperator, and if not, remove the previous one. So we'll say you have an html structure like so:
<span id="myLabel">
<span class="comment">You're great!</span><span class="separator">, </span><span class="comment">You're mediocre!</span><span class="separator">, </span><span class="comment">You suck!</span>
</span>
Here's a click function that should remove the commas properly, while maintaining the onclick events:
$('.comment').click(function() {
//decide which comma to remove
if ($(this).prevAll('.comment').size() == 0) {
//this is the first comment, remove the next comma and this comment
$(this).next('.separator').remove().end().remove();
} else {
//this is not the first comment, remove the previous comma and this comment
$(this).prev('.separator').remove().end().remove();
}
});
Here's a live demo showing that this works: http://jsfiddle.net/yWet5/
Sorry if I've misunderstood any part of your problem.
Related
On my page, I have a contenteditable div element. When a specific key is pressed, a function executes:
function bla(element) {
if (getSelectionHtml() != "") {
replaceSelectedText("text");
}
}
getSelectionHtml() checks if something is selected by the user. replaceSelectedText(text) replaces the selected text with a given string. Both functions are working properly.
After the selected text has been replaced, I want to 'cancel' the user's selection, as the selection is now equal to the 'new' string, so just deleting the text is not an option.
I tried this:
element.style.userSelect = "none";
element.style.userSelect = "text;
But it didn't work because userSelect: none doesn't seem to change anything in a div element with contenteditable. Also, this solution looks pretty ugly for such a simple problem.
So, how can I cancel the user's selection?
I think you want to remove selection completely. You can do so once you have replaced the string with
window.getSelection().removeAllRanges()
So basically, once you select the range of content, you can get the range with window.getSelection() method which returns set of details about selected content. It has many functions to alter the range and remove the range completely. To know more, you can read in brief of all supported methods Selection API
I want to make a text editor. It should work the way all text editors work (including this one i am using right now), so the user makes a selection of the text, presses a button or whatever, and then some function is executed.
I want my editor to work in the following way:
1. User selects
2. Function selected() is triggered that makes a span around the selected text.
3. When user clicks a button such as "B" or "I", they invoke functions that change .style of the span element.
For now I figured out how to get string from user selection, nothing more than that.
<body>
<textarea onselect="selected()">Some text here, more text here.</textarea>
</body>
<script>
function selected() {
var preselection = window.getSelection();
selection = preselection.toString();
console.log(selection);
}
</script>
textareas can't contain spans, so you will need to use something like this if you decide to use spans:
<p contenteditable="true" ...
You probably don't want to fire your function every time a user makes a selection. Instead, just run the function if a user presses a button (like the bold button) and then pick up the selected text, if any, using something like:
document.getSelection().toString()
Now adding a <span> object to an HTML element is pretty easy, but the big challenge here is that you don't know if your selection will cross other span objects (like if the user already added some formatting). Notice that stackoverflow inserts characters like ** in the edit area and then does one pass to add in tags like <strong>. This is possible in a text area as well, so you wouldn't need contenteditable="true".
It is possible to analyze what is in your selection and then collect all elements involved, and rewrite them as needed. You would have to get all parent objects involved in the selection and then add <span> elements around the text inside each of the parent objects.
To simplify this, you might make a rule that only one level of tags is allowed in your editable region, and then always re-write for that so that the results would only have one level of span:
<span class="bold">This whole sentence is italic and </span><span class="italic_bold">this half is also bold.</span> with no nesting of these span tags.
Investigating these properties might help with dealing with nesting: https://developer.mozilla.org/en-US/docs/Web/API/Selection
These string commands might also help:
https://www.w3schools.com/jsref/jsref_obj_string.asp
I want to create a Form Input in a Web Page and have Custom Text Formatting Options like Bold, Italic and Adding HyperLink.
Pretty much similar to how asking a question in StackOverflow.
The primary purpose is to get the html output of what user enters in the form. For example, if user selects Bold Button and types something, i should get that part as
<b>Bold Content</b>
Need suggestions on how to achieve this.
Thanks
There are various ways to approach this, I'm going to tackle 2 fairly simple ones
The first thing to note is that you want to wrap your editor in a container element with the contenteditable attribute, then have an array variable, containing text strings and "events" of styling strings, encoded in whichever way you prefer (maybe strings starting with :, like ":bold").
What you don't want to do is directly store the html, but rather the states that can then be translated into html code.
Whenever the user writes, you'd capture the keystrokes (and prevent them from default behaviour) to add to the last text string (or add a new one in case the last was an event), and if the keystroke is, say, a backspace, then if the last item is an event, you remove all events on the tail of the array ( so [ "this ", ":bold", "is ", ":no-bold", ":italic", "text", ":no-italic", ":bold" ], which you'd later turn to "this is text ", would turn into [ "this", ":bold", "is", ":no-bold", ":italic", "tex" ])
Now you can do 2 major things.
Firstly, you can add a span for each text character, and assign the various classes based on the event styles so that each character has its own element:
<span class="">t</span><span class="">h</span>...<span class="bold">i</span><span class="bold">s</span><span class="bold"> </span><span class="italic">t</span>...
This is very slow for the browser to render, but will work quite well.
The other thing you can do, is evolving the previous example by working on each text string rather than each character, so you'd start a span for every transition from text to event in the array, assuming you're iterating over it, and add classes corresponding to the various types until you get a transition from event to text, in which case you insert the text, and close it before another event occurs, and simply repeat:
<span class="">this </span><span class="bold">is </span><span class="italic">text</span>
Much more concise and quite easy to get to. Alternatively you can add a <b> tag for every :bold event, a </b> for every :no-bold and similar. This is however highly discouraged. If you're missing it: in css you can have font-weight to describe boldness and other properties for italic and other styles
TinyMCE gives you all these features (and more) straight out of the box.
I am using some JQuery Combobox that you can check out here: https://simpletutorials.com/uploads/1860/demo/index.html
As you can see, you can start typing and get the results filtered.
However, once you have selected a value, when clicking on the arrow to open the list, no other values are shown anymore. So, if I want to change college/state, I need to manually clear the input value. I don't like this, so I want to modify it.
I changed that code and added this JS on the click event of the list:
onclick="document.getElementById('statesCombo-ddi').value='';"
This line basically finds the input by id and sets its value to an empty string.
You can try out by looking for the td element having class "stc-button" (with Chrome, just focus on the arrow of the second combo box) and add my code to the tag.
===EDIT===
You can obtain the same results by adding this code directly to the input:
onclick="this.value=''"
===END EDIT===
This has a weird behavior:
If I SELECT an element from the list, it clears the value and everything works correctly.
If I TYPE some letters and then select a value from the list, no item is shown in the list after clicking.
What's wrong with it?
You can override one of the combo box methods to accomplish this:
STComboBox.prototype.filterAndResetSelected = function() {
this.$('ddi').val('');
this.filterList('');
this.selectRow(0);
this.$('ddl').scrollTop(0);
};
Does this help?
The unminified code is provided, is relatively small (12kb) and is fairly well commented, so you could make this modification directly to the source if you'd like.
Edit: Fixed to clear the input value (as indicated in the comment below)
By reading the source and doing a little debugging with Chrome's inspector (Control+Shift+i), you can find the particular ID of the element you need to clear (#collegesCombo-ddi) in order to clear the input box. Once you've found the element's ID you need to clear (and being very careful with plugins that assign multiple elements with the same ID, which is not allowed in the standard, and an indicator of poorly-written code):
$('#collegesCombo-ddi').val('');
i need to remove class attribute from the selected text(selected text means user will select some range of text by mouse). if the selected text has the class='ansspans', then we need to remove that class for that particular selected text. ( i am using this in gridview, so many rows will be there, so i need to remove class for that particular selected text)
<span id="sss_ctl00_ctl06_lblAnswerText" class="Label">
<span>ssss</span><span class="ansspans">assignment</span>submission
</span>
if User Selects assignment from the page, which already has class='anspans', then if he click button(to reset highlighted marking), then for that particular selected text, we should remove the class attribute. after clicking the button.
Output
<span id="sss_ctl00_ctl06_lblAnswerText" class="Label">
<span>ssss</span><span>assignment</span>submission
</span>
here why i am doing this,
Basically user will select some word and mark some word. (marking and highlighting is all done, n working fine ) ( imagine he selects 3 words)
Now user wants to remove the one of the highlighted word, then he selects the word, then click reset button. then for that selected text, class attribute will be removed. which i am facing problem.
Update : Even i tried one of my friends solution like this. JSfiddle - still not working for my page.
A Rangy-specific version of this is solved on the Rangy forum. Code is quite lengthy so not reproduced here. http://groups.google.com/group/rangy/browse_thread/thread/5738cf7bc32c607a
Demo: http://jsfiddle.net/URms2/
You can add are remove class by using jQuery methods. Please refer for removeClass
and for addClass.