Running function only if a certain element isn't burring - javascript

im making an application that creates a text input where ever you click. I was having a problem where whenever you would click inside the field another text field would appear but i managed to fix that. I have one last major issue that I just can't solve. I know ou can't use blur() and focus() as arguments (though it would be nice) but i need to find a way so that after you enter text into the input field and out click, it just blurs the input box and doesn't create another until the user clicks again.

Just create a variable to keep track or only use a certain ID for the input you create, then check for that variable or input element before creation..
if(!$("#myDynamicInputElement").length){
//TODO: Create your element..
}

Related

Refocus input field after page gets refreshed in wicket

Is it somehow possible to refocus an input field after a refresh which was last focused before the page was requested?
I have a Wicket Form within my WebPage and in this Form there are quite some input fields (like text fields) the user can use to filter my data view. But when the user for example has the focus on the second input field and then clicks on 'go to next page' within the data view he loses the focus, but due to accessibility it is necessary to refocus the second input field.
My idea was to first tag the input field with jQuery with "regain-focus" when focused:
$("input").focus(function() {
$("input").removeAttr("regain-focus");
$(this).attr("regain-focus", "regain-focus");
});
Then on server update search for the element with the "regain-focus" tag - but that's the part, I don't know how to do that... - tag the corresponding component with "autofocus":
input.add(AttributeModifier.append("autofocus", "autofocus"));
and refocus with javascript:
$('[autofocus]').focus();
Since you have JavaScript experience it would be much simpler to do it completely client side: $(document).on('focusin', 'input textarea', function(event) {localStorage.setItem('focus:'+location.pathname, event.target.id)}) and then use jQuery.ready() based logic to read the entry and use it.
When your page DOM/elements change between requests/refresh/ajax calls, it is better to use a CSS selector using optimal-select to store just a unique identifier for the element and use a JQuery selector to find it again for focus setting. I used this in the NoWicket web framework to remember the focused element on ajax calls. Example JS code here.

Sitecore - Field not detected as modified. How to force the save prompt to show?

We are using the Taxonomy module for Sitecore: https://marketplace.sitecore.net/Modules/T/Taxonomy.aspx?sc_lang=en
The module works fine 90% of the time. The only catch is that when in a taxonomy field you select a value from the auto-complete options, the field doesn't seem to be marked as changed. This creates the occasional confusion with editors as when they publish the "Do you want to save?" prompt doesn't show and the content is published without tags.
If instead of selecting from the auto-complete we use the dialog box, everything works fine.
I looked at the markup, JavaScript and C# code and couldn't find a solution.
I even tried to set Sitecore.Context.ClientPage.Modified = true but it doesn't seem to do anything.
How can I force the save prompt to show?
I had a similar issue, I was updating a field using js and the experience editor wasnt detecting the change.
I got this working by doing the following using js:-
There is a save button state object saved in a view state field. You can grab by doing window.parent.document.getElementById("__SAVEBUTTONSTATE"). I then did the following:-
var saveButtonState = window.parent.document.getElementById("__SAVEBUTTONSTATE");
saveButtonState.value = 1;
saveButtonState.onchange();
This will make the save button enabled
In the experience editor, Sitecore wraps your sitecore item fields in an span element, which contain a unique id. (These are the fields you interact with in the experience editor). However, its not these values which Sitecore receives when you hit Save button. Sitecore actually stores values of your item fields in hidden inputs, so when you interact with the span element, in the background, these hidden inputs are being updated. So in order for Sitecore to receive your changes, you must update the corresponding hidden input. If you open Inspect element in the experience editor and search "scFieldValues", you will see these hidden inputs. I updated the field by using jquery:-
$('#scFieldValues').children('input').each(function () {
if (id.indexOf($(this).attr('id')) >= 0) {
$(this).val(value);
}
});
The id object is the id of the span element. The contents of that id is used in the id of the hidden input. This is why I use "id.IndexOf" to find correct input element. So when I update the span element value, I grab that value and update the corresponding input.
Hope this helps

Simple .on('keydown') jQuery event not responding until next key is pressed

I'm making a page for a friend and I have a hidden text field and when the user types the text is transposed into a div so that it looks like they're typing on the screen rather than in an input field.
Here is a link to the page: http://merkd.com/godis.php
Here is the function that I use to respond to the key strokes:
$('#hiddenInput').keydown(function() {
var input = $('#hiddenInput').val();
var html = '<div style="float: left;">'+input+'</div><div id="cursor">|</div>';
$('#typingArea').html(html);
});
The text-field is visible right now so that you can see the problem. When text is entered or deleted, it doesn't respond until the next keypress. So if I type a single letter, nothing shows up until I type the next letter.
I looked at the jQuery .on() documentation but I couldn't find anything on this. Any help is much appreciated.
P.S. I know it should be in a separate question, but is there an easy way to make a text-field always in focus? I want to make it so that no matter where the user clicks or whatever, if they type, the text will still show up.
Use .keyup() event because when you first press (keydown), the letter is never typed so the var html is getting previous value. For second part you can bind keypress event in document to focus your input field.

How to prevent multiple html selection box displayed on screen?

I have been working on the last bit of my php + ajax based datagrid project.Everything works as I designed except one thing : I cannot stop user opening multiple selection boxes...
Go my research page and use username "ChenxiMao" and password "accedo" to login(without double quotes).
Note that perhaps the images used in this datagrid would not be displayed when page is loaded for the first time(weird, I am trying to fix this, browser incompatibilities, perhaps).
If you double click on one cell in the "CONSULTANT" column, a html select box would be displayed, you can select one consultant to assign him to this task or unassign the consultant from this task. No problem for this.
The problem is : when user leaves this selection box OPEN, he/she can still open another selection box... My jquery code cannot stop people from opening multiple selection boxes.
You can ctrl-U to see the source code on this page, and check the content inside the "gridview-helper.js" for what I have been done.
I want to let user only open a single selection box. When he/she leaves the cell, the selection box should be closed, without changing the html inside...
Puzzled, screwed up for this afternoon...
Thanks for any suggestons in advance!
JavaScript is single-threaded, so you can add a mutex variable and check its value before opening a new select box.
At the top of gridview-helper.js:
var is_choice_visible = false;
In your double-click handler:
$(this).dblclick(function()
{
if (is_choice_visible)
return;
is_choice_visible = true;
...
For your select box, add an onblur handler which sets is_choice_visible back to false and deletes itself.
Unrelated tip: Growing a string in a loop is slow on older versions of Internet Explorer. It's more efficient to append to an array and join the array, e.g.:
var html = ["<select>..."];
for (var i in consultantnames)
{
html.push("<option>...</option>");
}
html.push("</select>");
return html.join("");
Have you tried using the onmouseout event on the cell, and removing the child dropdown box element if mouse out is triggered? Seems that should work.

Dynamically growing an array of text inputs (HTML/JavaScript)

I'm creating a data entry app for some in-house stuff.
My team needs to enter info about "items" which can have many "categories" and vice versa.
I need a quick way to let them enter an arbitrary amount of categories.
Here's my idea:
On the item entry page, I'll have it so that initially there's one text input for "categories" and if it's tabbed out of while it's empty, the input field is deleted (unless it's the only one) and focus skips to the next field. If it's not empty when it's tabbed out of and if it's the last input field in the array, then an additional "category" text input will be added and focused.
This way people can enter an arbitrary amount of categories really quickly, without taking their hands off the keyboard, just by typing and hitting tab. Then hitting tab twice to denote the end of the list.
First of all, what do you think of this interface? Is there a better way to do it?
Second of all, is there a jQuery (or something) plugin to do this? I've searched but can't find one. I searched scriptaculous/prototype and mootools too, with no luck.
I would obviously rather use something tried and tested than roll my own.
Any and all advice appreciated
First I'll try to address the problems commented on nickf solution.
To set the focus on the newly created input $copy.find(":text").focus(); will not work. The jQuery focus method only triggers the event, but does not call the underlying focus method.
You can set the focus with setTimeout(function(){$copy.find(":text").get(0).focus()}, 10); but:
setTimeout is needed in firefox or strange things will happen with the blinking cursor.
IE7 needs another input to focus when tabbing. I haven't found the way to set the focus on an input if the focus goes to the address bar. I suppose this will not be a problem because you will need at least a submit button.
To control shift-tab I've been trying to track the focused element, in order to skip the blurHandler when the focused element is a previous input, but the resulting code is really ugly so I'll post this and look for a better solution.
And last, you're asking what we think of this UI, and I think that a comma separated list of categories is easier to code an to fill in. :-)
it's actually not too difficult to implement that, even with vanilla JS (ie: no jQuery, prototype, etc), but everything is easier with jQuery, so I'll have a go at it using that:
Assuming a structure like this:
<form id="myForm">
<div class="inputRow">
<input type="text" name="myInput[]" />
</div>
<div class="inputRow">
<input type="text" name="myInput[]" />
</div>
...
</form>
Here's the JS
$('#myForm :text').blur(onBlurHandler);
function onBlurHandler() {
$row = $(this).parent();
if ($row
.nextAll(":has(:text)") // all following divs with a text element
.length == 0 // but there aren't any, we're on the last one
) {
if ($.trim($row.find(":text").val())) { // the text box isn't empty
$copy = $row.clone(true);
$copy
.find(":text") // get the new text box,
.val('') // remove any text in it
.blur(onBlurHandler) // and add the event handler (is this necessary?)
;
$copy.insertAfter($row);
} else if ($row.prev(':has(:text)').length) { // the text box is empty, and this one isn't the first row
$row.remove(); // get rid of the row.
}
}
}
Response to comments:
thanks for the answer! i've tried it but it doesn't seem to work as intended. i'm on mac firefox. if i tab off the last field, it adds the new one but focuses the address bar. i tried adding: $copy.find(":text").focus(); after the insertAfter line, but it doesn't change anything. any ideas?
also if i shift-tab the blurhandler doesn't know i'm going in the opposite direction. is there any way around that?
Hmm, I hadn't thought about that. What you could try doing is to put an element after all your text fields which can take focus (like a textbox which is rendered off-screen, eg: margin-left: -10000px). Add an onfocus handler onto that to see if the last row is empty, and if it is, then it would have been added just then by the onBlurHandler function, so pass the focus back to the last row. If the last row isn't empty, then pass the focus onto the next element (your submit button, probably). If there are issues with the last row not existing in the DOM yet, then put the above into a timeout.
(If this actually works) this should let your users tab backwards and forwards without hassle.

Categories