I am working on a Blazor textarea input. What I want to achieve is whenever user types "#" character, I am going to popup a small window and they can select something from it. Whatever they select, I will insert that text into the textarea, right after where they typed the "#".
I got this HTML:
<textarea rows="10" class="form-control" id="CSTemplate" #bind="original" #oninput="(e => InputHandler(e.Value))" #onkeypress="#(e => KeyWasPressed(e))"></textarea>
And the codes are:
protected void InputHandler(object value)
{
original = value.ToString();
}
private void KeyWasPressed(KeyboardEventArgs args)
{
if (args.Key == "#")
{
showVariables = true;
}
}
protected void AddVariable(string v)
{
original += v + " ";
showVariables = false;
}
This worked very well. The showVariables boolean is how I control the pop-up window and AddVariable function is how I add the selected text back to the textarea.
However, there is one small problem. If I've already typed certain text and then I go back to any previous position and typed "#", menu will still pop-up no problem, but when user selects the text and the insert is of course only appended to the end of the text. I am having trouble trying to get the exact caret position of when the "#" was so I only append the text right after the "#", not to the end of the input.
Thanks a lot!
I did fast demo app, check it https://github.com/Lupusa87/BlazorDisplayMenuAtCaret
I got it - I was able to use JSInterop to obtain the cursor position $('#CSTemplate').prop("selectionStart") and save the value in a variable. Then use this value later in the AddVariable function.
you can set your condition in InputHandler and when you are checking for the # to see if it's inputed you can also get the length to see that if it's just an # or it has some characters before or after it obviously when the length is 1 and value is # it means there is just an # and if length is more than one then ...
I am using Geb to write a script that will test a survey many times with random input to make sure nothing breaks. I would like to iterate through every input on a form and do different things depending on the input type.
For example:
while ($("form").find("input", j)) {
if($("form").find("input", j) == "checkbox"){
//check it sometimes
}
else if($("form").find("input", j) == "select"){
//select a random option
}
j++
}
I'm not exactly sure how the survey is going to work yet, so I would rather go down the page as a human would instead of doing all checkboxes first and then all selects etc. It is possible to check the type of input like my example?
Additionally, I notice I am repeating the $("form").find("input", j). Can I make that into a variable like in jQuery?
Simply collect all your inputs and selects in a navigator and iterate over all of them. Use is(String tagName) to detect select elements and #type attribute accessor to detect other element types:
def form = $("form")
def formElements = form.find("input") + form.find("select")
formElements.each { Navigator element ->
if (element.is("select") {
//select a random option
}
if (element.#type == "checkbox") {
//check it sometimes
}
}
I have a little snippet of code here:
View:
#foreach (var lines in Model.KVpairs)
{
#Html.TextBoxFor( m => lines, new { placeholder = lines })
}
In my application, I load the view containing this code twice, the first time, it works as intended, the second time, the values for all of the textboxes are the same value, but the placeholders are all different. Or in other words, the placeholders are working as intended, but the value(the actual text inside the box) is not.
Am I missing something very obvious?
EDIT:
wanted to add some pics:
before I sumbit the form, ive entered these values
Here you can see the values of the KVpairs
And this is the result I get after form submission
And these are the placeholders after the submission
Instead of foreach loop try using for loop like this:
#for (var i = 0; i < Model.KVpairs.Count(); i++)
{
#Html.TextBoxFor( m => Model.KVpairs[i], new { placeholder = lines })
}
I am not able to put any value in my application using WebDriver. My application is using frames.
I am able to clear the value of my textbox with driver.findElement(By.name("name")).clear();, but I'm unable to put any value using driver.findElement(By.name("name")).sendKeys("manish");. The click command works for another button on the same page.
I also had that problem, but then I made it work by:
myInputElm.click();
myInputElm.clear();
myInputElm.sendKeys('myString');
Before sendkeys(), use the click() method (i.e., in your case: clear(), click(), and sendKeys()):
driver.findElement(By.name("name")).clear();
driver.findElement(By.name("name")).click(); // Keep this click statement even if you are using click before clear.
driver.findElement(By.name("name")).sendKeys("manish");
Try clicking on the textbox before you send keys.
It may be that you need to trigger an event on the field before input and hopefully the click will do it.
I experienced the same issue and was able to collect the following solution for this:
Make sure element is in focus → try to click it first and enter a string.
If there is some animation for this input box, apply some wait, not static. you may wait for an element which comes after the animation. (My case)
You can try it out using Actions class.
Clicking the element works for me too, however, another solution I found was to enter the value using JavaScript, which doesn't require the element to have focus:
var _element= driver.FindElement(By.Id("e123"));
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("arguments[0].setAttribute('value', 'textBoxValue')", _element);
Use JavaScript to click in the field and then use sendkeys() to enter values.
I had a similar problem in the past with frames. JavaScript is the best way.
First pass the driver control to the frame using:
driver.switchTo().frame("pass id/name/index/webelement");
After that, perform the operation which you want to do on the webelement present inside the frame:
driver.findElement(By.name("name")).sendKeys("manish");
I have gone with the same problem where copy-paste is also not working for that text box.
The below code is working fine for me:
WebDriver driver = new FirefoxDriver();
String mobNo = "99xxxxxxxx";
WebElement mobileElementIrs =
driver.findElement(By.id("mobileNoPrimary"));
mobileElementIrs.click();
mobileElementIrs.clear();
mobileElementIrs.sendKeys(mobNo);
I had a similar problem too, when I used
getDriver().findElement(By.id(idValue)).clear();
getDriver().findElement(By.id(idValue)).sendKeys(text);
The value in "text" was not completely written into the input. Imagine that "Patrick" sometimes write "P" another "Pat",...so the test failed
The fix is a workaround and uses JavaScript:
((JavascriptExecutor)getDriver()).executeScript("$('#" + idValue + "').val('" + value + "');");
Now it is fine.
Instead of
driver.findElement(By.id("idValue")).sendKeys("text");
use,
((JavascriptExecutor)getDriver()).executeScript("$('#" + "idValue" + "').val('" + "text" + "');");
This worked for me.
I had a similar problem recently and tried some of the suggestions above, but nothing worked. In the end it fell back on a brute-force retry which retries if the input box wasn't set to what was expected.
I wanted to avoid thread.sleep for obvious reasons and saw different examples of it failing that looked like some kind of race or timing condition.
public void TypeText(string id, string text)
{
const int numberOfRetries = 5;
for (var i = 1; i < numberOfRetries; i++)
{
try
{
if (TryTypeText())
return;
}
catch (Exception)
{
if (i == numberOfRetries)
throw;
}
}
bool TryTypeText()
{
var element = _webDriver.FindElement(By.Id(id));
element.Click();
element.Clear();
element.SendKeys(text);
if (element.TagName.ToLower() == "input"
&& !DoesElementContainValue(element, text, TimeSpan.FromMilliseconds(1000)))
{
throw new ApplicationException($"Unable to set the type the text '{text}' into element with id {id}. Value is now '{element.GetAttribute("value")}'");
}
return true;
}
}
private bool DoesElementContainValue(IWebElement webElement, string expected, TimeSpan timeout)
{
var wait = new WebDriverWait(_webDriver, timeout);
return wait.Until(driver =>
{
try
{
var attribute = webElement.GetAttribute("value");
return attribute != null && attribute.Contains(expected);
}
catch (StaleElementReferenceException)
{
return false;
}
});
}
In my case, I had some actions.keyDowns(Keys.CONTOL).XXXX;
But I forgot to add the keyUp for that button and that prevented from sending keys and resulted in weird behaviors
Adding X.keyUp() after the x.keyDown() fixed the issue
Try using JavaScript to sendkeys().
WebElement element = driver.findElement(By.name("name"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
More information on JavaScript Executor can be found at
JavascriptExecutor - Selenium.
Generally I keep a temporary variable. This should work.
var name = element(by.id('name'));
name.clear();
name.sendKeys('anything');
I'm trying to use two devExpress checkedComboBoxes (boxes) to maintain a list and its antilist (i.e, same items in both comboboxes, and they must be checked in only one of the lists).
I'm using C++/CLI, so for each box I handle
EditValueChanged += gcnew System::EventHandler(this, &SelectionControl::exclBox_EditValueChanged);
which calls through to
void
box_ToggleAntibox(
DevExpress::XtraEditors::CheckedComboBoxEdit^ box,
DevExpress::XtraEditors::CheckedComboBoxEdit^ antibox )
{
using namespace DevExpress::XtraEditors::Controls ;
cli::array<String ^> ^ sAnti = gcnew cli::array<String ^>(2*box->Properties->Items->Count) ;
int ii = 0;
String ^ delim = ", ";
for each (CheckedListBoxItem^ i in box->Properties->GetItems()) {
if (i->CheckState==Windows::Forms::CheckState::Unchecked)
{
sAnti[ii] = i->Value->ToString();
++ii;
sAnti[ii] = delim;
++ii;
}
}
String ^ result = String::Concat(sAnti);
antibox->EditValue = result;
}
As the devExpress documentation seems to say to set the edit value, rather than simply iterating through the box list and setting the anti-list to !Checked.
However, it doesn't seem to be working (the correct items are added to the text window, but nothing is checked). Moreover, if I look at my box after the event has finished, I find that the string value in the text window is correct (reflects what I'd selected), but if I open it up, then all items are selected.
Does anyone have any suggestions I might try?
Is it better to set each item's CheckState::Checked instead?
Thanks!
I spent some time talking to DevExpress support. The short answer is that this should work - but doesn't for us. Your mileage may vary, but our solution was to put the two comboboxes on to separate controls on the form.