Controlling the preventDefault to select which default to prevent - javascript

In a page I'm working on I have this HTML (simplified version; the original is a bit more complex).
<a href="alink.php" >
<b>1</b>
<span name="aName" data-editable="text" ></span>
<span class="type">numeric</span>
</a>
Then I have a system that allows an "edit mode".
That edit to mode changes that HTML to this:
<a href="alink.php" >
<b>1</b>
<span name="aName" data-editable="text" ><input name="aName" type="text"></span><img src="ok.png"><img src="x.png"></span>
<span class="type">numeric</span>
</a>
The issue is as follows:
When the user clicks the input how can I have the carret where the user clicked without anything else happening?
For that I tried this:
If I use the preventDefault(), the user is not sent to the link but the carret is also not positioned where the user clicked.
If I use stopPropagation(), nothing is prevented, the link is clicked.
If I use both, same as preventDefault() happens.
One possible solution I thought is to get rid of the <a> and replace it with a different tag, like a <span> tag. I just would prefer not to have to do that due to how this system works. If you think that there's a nice alternative, then please state it.
No examples or answers with libraries please
Edit: My relevant js code, as requested:
this.editableElement = document.createElement('input');
this.editableElement.type = "text";
this.editableElement.onclick = function (e){
e.preventDefault();
e.stopPropagation();
}.bind(this);
this.editableElement.name = this.parent.getAttribute('name');
this.editableElement.value = this.currentText;
Edit2: jsfiddle as requested.
http://jsfiddle.net/brunoais/gZU8C/
Now try to place the caret where you clicked. You'll check that the input becomes selected, the link is not followed but the caret is not placed where you clicked.

Related

The drop down element is not locating

Requirement : Click on the drop down and the drop down should open.
DOM:
<span class="select2 select2-container select2-container--default select2-container--below select2-container--open" dir="ltr" data-select2-id="3522" style="width: 208.328px;" xpath="1">
<span class="selection">
<span class="select2-selection select2-selection--single" role="combobox" aria-haspopup="true" aria-expanded="true" tabindex="0" aria-disabled="false" aria-labelledby="select2-_ID-container" aria-owns="select2_ID-results" aria-activedescendant="select2_ID-result-pwlg-2">
<span class="select2-selection__rendered" id="select2_ID-container" role="textbox" aria-readonly="true" title="Choose Inco Term">Choose Inco Term</span>
<span class="select2-selection__arrow" role="presentation">
<b role="presentation"></b>
</span>
</span>
</span>
The element is located on the UI:
But when I use the same id on the code as below:
cy.get('#select2_ID-container').click({force:true})
Then I get the following error:
Timed out retrying: Expected to find element: #select2_ID-container, but never found it.
I also tried {force: true}:
cy.get('#select2_ID-container').click({force:true})
There is a different id shown above, perhaps you want
cy.get('[id="select2_ID-container"]').click()
Perhaps you are looking for role="combobox", since this is likely to be the dropdown.
cy.get('span[role="combobox"]').click({force:true})
#select2_ID-container is the selector for the first option in the dropdown list which is Choose Inco Term. You can use this to open the drop down.
cy.get('[aria-owns="select2_ID-results"]').click()
OR
cy.get('[aria-activedescendant="select2_ID-result-pwlg-2"]').click()
Or, You can also use the text to find and click.
cy.contains('Choose Customer').click()
The jQuery select2 has a visible textbox which can be clicked to show the options.
If you're having trouble with the ID, this is how I would approach the test
cy.get('.select2 [title="Choose Inco Term"]')
.as('select2') // alias the textbox
.click() // open the options list
// Options now open
cy.contains('li.select2-results__option', 'TextOfOption').click() // choose an option
// Verify
cy.get('#select2')
.find('li.select2-selection__choice') // choice is listed under textbox
.should('contain', 'TextOfOption') // check the text
// Remove
cy.get('#select2')
.find('.select2-selection__choice__remove') // remove button
.click()
cy.get('#select2')
.should('not.contain', 'TextOfOption') // check text has gone
Sometimes cypress requires a mouse move. Try this too:
cy.get('[id="select2_ID-container"]').trigger('mousemove').click()
Also make sure the element is present / not timedout by checking the command logs : https://docs.cypress.io/api/commands/click#Command-Log
Finally I found a solution to this. I tried all of the above solutions, but neither worked for me. This was due to the version issue. I simple updated the Cypress to the latest version 10.0.1 and ran the test and it worked. Also the dropdown is not located because the page was not loaded properly. The click action was performed on the automation before the page loads completely. So I added cy.wait(10000) before clicking the dropdown. I think the version is not the main problem. The main problem is the page load.
Thank you all for your time. :)

Prevent HTML page from reloading when a button is clicked to send a HTTP request [updated] [duplicate]

I am doing the following:
<a href="www.stackoverflow.com">
<button disabled="disabled" >ABC</button>
</a>
This works good but I get a HTML5 validation error that says "Element 'button' must not be nested within element 'a button'.
Can anyone give me advice on what I should do?
No, it isn't valid HTML5 according to the HTML5 Spec Document from W3C:
Content model: Transparent, but there must be no interactive content descendant.
The a element may be wrapped around entire paragraphs, lists, tables, and so forth, even entire sections, so long as there is no interactive content within (e.g. buttons or other links).
In other words, you can nest any elements inside an <a> except the following:
<a>
<audio> (if the controls attribute is present)
<button>
<details>
<embed>
<iframe>
<img> (if the usemap attribute is present)
<input> (if the type attribute is not in the hidden state)
<keygen>
<label>
<menu> (if the type attribute is in the toolbar state)
<object> (if the usemap attribute is present)
<select>
<textarea>
<video> (if the controls attribute is present)
If you are trying to have a button that links to somewhere, wrap that button inside a <form> tag as such:
<form style="display: inline" action="http://example.com/" method="get">
<button>Visit Website</button>
</form>
However, if your <button> tag is styled using CSS and doesn't look like the system's widget... Do yourself a favor, create a new class for your <a> tag and style it the same way.
If you're using Bootstrap 3, this works quite well
Primary link
Link
I've just jumped into the same issue and I solved it substituting 'button' tag to 'span' tag. In my case I'm using bootstrap. This is how it looks like:
<a href="#register">
<span class="btn btn-default btn-lg">
Subscribe
</span>
</a>
No.
The following solution relies on JavaScript.
<button type="button" onclick="location.href='http://www.stackoverflow.com'">ABC</button>
If the button is to be placed inside an existing <form> with method="post", then ensure the button has the attribute type="button" otherwise the button will submit the POST operation. In this way you can have a <form> that contains a mixture of GET and POST operation buttons.
It would be really weird if that was valid, and I would expect it to be invalid. What should it mean to have one clickable element inside of another clickable element? Which is it -- a button, or a link?
These days even if the spec doesn't allow it, it "seems" to still work to embed the button within a <a href...><button ...></a> tag, FWIW...
Another option is to use the onclick attribute of the button:
<button disabled="disabled" onClick="location.href='www.stackoverflow.com'" >ABC</button>
This works, however, the user won't see the link displayed on hover as they would if it were inside the element.
You can add a class to the button and put some script redirecting it.
I do it this way:
<button class='buttonClass'>button name</button>
<script>
$(".buttonClass').click(function(){
window.location.href = "http://stackoverflow.com";
});
</script>
why not..you can also embeded picture on button as well
<FORM method = "POST" action = "https://stackoverflow.com">
<button type="submit" name="Submit">
<img src="img/Att_hack.png" alt="Text">
</button>
</FORM>
Explanation and working solution here:
Howto: div with onclick inside another div with onclick javascript
by executing this script in your inner click handler:
if (!e) var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
It is illegal in HTML5 to embed a button element inside a link.
Better to use CSS on the default and :active (pressed) states:
body{background-color:#F0F0F0} /* JUST TO MAKE THE BORDER STAND OUT */
a.Button{padding:.1em .4em;color:#0000D0;background-color:#E0E0E0;font:normal 80% sans-serif;font-weight:700;border:2px #606060 solid;text-decoration:none}
a.Button:not(:active){border-left-color:#FFFFFF;border-top-color:#FFFFFF}
a.Button:active{border-right-color:#FFFFFF;border-bottom-color:#FFFFFF}
<p><a class="Button" href="www.stackoverflow.com">Click me<a>
Use formaction attribute inside the button
PS! It only works if your button type="submit"
<button type="submit" formaction="www.youraddress.com">Submit</button>

Add popup based on class (most likely)

I'm trying to use Tampermonkey to add a popup on pages in the Canvas LMS. It's a forum, and after each post there is a "Reply" option, which is what I want to add the popup to. But when I click the "Reply" link, no popup appears. It opens the Reply box, as normal, but my popup is nowhere to be seen.
The code looks roughly like this:
<div class="entry-controls hide-if-collapsed hide-if-replying">
<div class="notification" data-bind="notification"></div>
<a role="button" class="discussion-reply-action entry-control" data-event="addReply" href="#">
<i class="icon-replied"></i>
<span aria-hidden="true">Reply</span>
<span class="screenreader-only">Reply to Comment</span>
</a>
</div>
The JS code I'm trying to add is:
document.querySelectorAll('.discussion-reply-action').forEach(item => {
item.addEventListener('click', event => {
alert("Popup text here");
})
})
In addition to .discussion-reply-action, I've tried using .entry-controls, .notification, .entry-control, even stuff like span[aria-hidden="true"]. Nothing seems to work.
I know the Tampermonkey script itself is applying correctly, because it has other functionality that is showing up as usual.
Any idea why this bit isn't working for me? I'm a complete JS noob, for what that's worth.
This got answered in the replies, but just wanted to formally note that it came down to delaying my code injection. I was trying to attach to elements that loaded after the doc. Once I got behind them, it worked fine.

Skip hidden tab indexes

I have the following html:
<span tabindex="19">
</span>
<span tabindex="20">
</span>
<span tabindex="21">
</span>
<span id="hidden" tabindex="22">
</span>
<span tabindex="23">
</span>
<span tabindex="24">
</span>
As you can see one of the span is hidden, the code to hide it is
#hidden
{
display: none;
}
I want a behavior where tab skips the hidden indexes. So i want something like this when i click tab:-
go to 19,20,21,23,24
I have no way of controlling the tab indexes as they are coming hard coded in the html i process.
Thank you guys!!
I tried a lot of things, so i was wrong in hiding it using
#hidden
{
display : none.
}
I tried
#hidden
{visibility : hidden }
and tab skips the links which are marked as hidden.
You could give it a negative tabindex which is supposed to be ignored by the browser. There are jQuery plugins that do this as well, such as SkipOnTab https://github.com/joelpurra/skipontab.
var $hidden = $('#hidden');
$hidden.attr('tabindex', '-' + $hidden.attr('tabindex'));
It would help if you posted your code, but you could try something like this:
$("#hidden").attr("disabled","disabled");
Normally the tab-event automatic skips a non visible HTML-element. However, the hard coded HTML part can override with JavaScript after the page has been loaded:
<script>
window.addEventListener("load", function()
{
document.getElementById("hidden").setAttribute("tabindex", "-1");
});
</script>
JQuery is also a solution, but 90kByte is a little bit heavy for this simply task.

JS-Linking to an anchor inside the document in the onclick() event

I have a problem on the following code, imagine the rest is okay (html, head, body etc)
What I want to do is, when you click on one of the buttons the hidden text/images in the section show or hide, the code does that just fine. The problem is I also want it to take you to an anchor in that newly appeared section when you click on the button, and I cant seem to do that.
Here's the code on the HTML
<h2 class="especial">TITLE</h2>
<p class="normal"><input type=image src="images/img_beta/buttonimage1.png" onclick="show_section1();">Section1</p>
<p class="normal"><input type=image src="images/img_beta/buttonimage2.png" onclick="show_section2();">Section2</p>
<hr>
<div id="Section1" style="display:none">
<a id="Section1_anchor"><h2 class="especial">Sect1TittleHere</h2></a>
<p class="interior">Blablah this is the content of section1</p>
</div>
<div id="Section2" style="display:none">
<a id="Section2_anchor"><h2 class="especial">Sect2TittleHere</h2></a>
<p class="interior">Blablah content of section2</p>
</div>
And here's the JS function that controls the onclick event, I have one for each section, but they are all the same.
<script language='javascript'>
//Variables
var sect1_guardian=0, sect2_guardian=0, sect3_guardian=0;
function show_sect1(){
if (sect1_guardian == 0) { document.getElementById("Section1").style.display="block";
sect1_guardian=1;
//Close the other sections if opened
document.getElementById("Section2").style.display="none";
document.getElementById("Section3").style.display="none";
//Reset guardians
sect2_guardian=0;
sect3_guardian=0;
}
else {
document.getElementById("Section1").style.display="none";
sect1_guardian=0;
}
}
Where and how should I add the link to the anchor? If i tried adding it to the button tag and the onclick event. I do something like this
<p class="normal"><input type=image src="images/img_beta/buttonimage1.png" onclick="show_section1();">Section1</p>
Because the onclick event is in the image and I don't want the text to be hiperlinked. Clearly I'm loosing something/doing something wrong, probably an humiliating mistake, but I ask for suggestions and corrections.
If it's exactly a copy paste of your code, the onclick handler is called 'show_section1()' and the function is called 'show_sect1()'. Notice sect != section :) .
Should we look further?
You can have the html you proposed and do something like this:
window.location = document.getElementById("Section1").parentNode.href;
Replace 'Section1' with your particular section.
Allright, I found a solution, it was far easier and probably nobody said it because I was presenting the problem in the wrong way, but perhaps this will help somebody.
I wanted to make the button take you to an anchor in the document, right?
The code above worked well, you clicked on the button and it showed hidden text, or hide it.
Now, adding the following to the button code, it does the anchor thingy also.
<p class="normal"><input type=image src="images/img_beta/buttonimage1.png" onclick="show_section1();">Section1</p>
I just added a tag to link the button, and used the HTML id (which I already used for the JS) to function as an anchor. I hope to have explained it clearly, and that it helps somebody!
Key was, use the html id as an anchor

Categories