First, sorry for my bad english. I'll try to explain the best i can.
So, i have problem with mobile's keyboards. When i try to search something on my search-bar, the virtual keyboard appears and destroy my design. Here you can see my problem :
Normal
Bug
On the first screen, you can see " Barre de recherche " means " SearchBar" and " Contenu du site " means " Website content "
On the second screen, as you can see, the content hide my searchbar, only when keyboard is open...
I don't really know how to solve this.
<div class="row bgBlanc clrNoir hidden-lg hidden-md search-container hidden-search-container">
<div class="col-24 flex flexRow flexAlignCenter-sm flexJustifySpace-sm">
<form class="row search-bar searchFormMob fullW" name="quickFind" action='advanced_search_result.php' method="get" autocomplete="off">
<input class="tup col-offset-1 col-18 col-sm-20 keywords fs40" type="search" name="keywords" placeholder="<?php echo TEXT_SEARCH_PEF_KEYWORDS; ?>" style="min-height:10rem; width:100%;border-style:none;opacity: 0.4;">
<!-- <button class="submitBtn-search col-2 ffwi pt15 fs60" type="submit"></button> -->
<button class="submitBtn-search col-2 col-sm-2 ffwi pt15 fs60" type="submit">
<svg width="44px" height="44px" viewBox="0 0 22 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Icones-nav-2" transform="translate(-805.000000, -25.000000)" fill-rule="nonzero" fill="#000000">
<g id="ic_search_black_24px-copy" transform="translate(805.000000, 25.000000)">
<path d="XXXXXXXXXXXXX" id="Shape"></path>
</g>
</g>
</g>
</svg>
</button>
</form>
</div>
</div>
Related
Trying to wrap my head around SVGs and displaying images. I asked a related question just a few hours ago but I seems to have managed to figure that part out, now I'm stuck with trying to figure out the relation between viewport, viewbox and the image tag inside it.
My first understanding of viewbox was that it was basically defining the coordination system. having it set to "0 0 100 100" meant "upper left corner is called 0,0 and 100,100 is the bottom right coordinate" then if you draw something like a rect you use 0-100 to reach the corners. Then you use css around it set the size you want on the container and all inside the SVG tag is scaled accordingly.
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<div class="container-fluid">
<div class="row" style="height: 100vh;">
<div class="col-2" style="background: pink">
1 of 3
</div>
<div class="col-8 bg-dark">
<p>
A bit of text
</p>
<svg viewBox="0 0 100 100" style="outline: 1px solid red" preserveAspectRatio="xMidYMid meet">
<defs>
<mask id="image-mask" x="0" y="0" width="100" height="100">
<rect x="0" y="0" width="100" height="100" fill="#F000FF" />
<rect x="33" y="0" width="33" height="100" fill="white" />
</mask>
</defs>
<image width="100" height="100" xlink:href="https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Panorama_Gendarmenmarkt-Berlin-Huntke-2008.jpg/640px-Panorama_Gendarmenmarkt-Berlin-Huntke-2008.jpg" mask="url(#image-mask)" />
</svg>
<p>
Some more text
</p>
</div>
<div class="col-2" style="background: orange">
3 of 3
</div>
</div>
</div>
That seems very wrong.
After tweaking and testing and poking around my current understanding is "if I want to display a non-vector image inside the SVG will I have to set the viewport and the image height/width to match the aspect ratio of the image, the numbers don't matter as long as the ratio is correct". So the image I have here is 640x170px. Normalising to width 100 the height is 26.56. So I set viewport to 0 0 100 26.56 and image width/height to 100 and 26.56 respectively:
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<div class="container-fluid">
<div class="row" style="height: 100vh;">
<div class="col-2" style="background: pink">
1 of 3
</div>
<div class="col-8 bg-dark">
<p>
A bit of text
</p>
<svg viewBox="0 0 100 26.56" style="outline: 1px solid red" preserveAspectRatio="xMidYMid meet">
<defs>
<mask id="image-mask" x="0" y="0" width="100" height="100">
<rect x="0" y="0" width="100" height="100" fill="#F000FF" />
<rect x="33" y="0" width="33" height="100" fill="white" />
</mask>
</defs>
<image width="100" height="26.56" xlink:href="https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Panorama_Gendarmenmarkt-Berlin-Huntke-2008.jpg/640px-Panorama_Gendarmenmarkt-Berlin-Huntke-2008.jpg" mask="url(#image-mask)" />
</svg>
<p>
Some more text
</p>
</div>
<div class="col-2" style="background: orange">
3 of 3
</div>
</div>
</div>
That seems to work, and it works for the commented out image as well when I adjust the numbers to fit it's aspect ratio of 100x66.56. I haven't really been able to find much info when it comes to the viewBox and images so my worry is that I'm just lucky and guessed something which works for two examples.
So the answers I'm looking for are:
Are my assumptions correct?
Does this mean that when I want to be able to show different aspect ratios of images do I have to adjust the viewport and the image width/height with javascript for each image?
Is there any more efficient way of solving this? Like "width: 100%; Height: auto;" and make it wrap all aspect rations of images?
PART 1 -
So I have a bunch of <circle>'s inside a SVG, and I want those circles to be checkboxes. And after that I want to:
PART 2 -
When circle 1 (which is now a checkbox) is clicked, then it is checked. But all the other circles now get unchecked.
This is what I've already tried:
PART 1 - Turning the SVG into a checkbox:
<circle opacity="0.5" cx="842" cy="451.814" r="25.582" class="svg_spot" id="1" fill="#FFB60C" >
<animate attributeName="r" values="25.582; 33; 25.582" keyTimes="0; 0.5; 1" begin="0s" dur="1s" repeatCount="indefinite" calcMode="linear" />
<input type="checkbox" id="spot1" name="spot" class="common_selector spot_id" value="spot1">
</circle>
PART 2 -
$('input[name=spot]').click (function (){
$(this).attr('checked', true);
$('input[name=spot]').not(this).attr('checked', false);
});
Thanks for your time guys. Would appreciate any help!
It is possible to get this working without any Javascript.
How this works:
Put the SVG in the label of the input. Clicking on the SVG (ie the label) will thus activate the field.
Make the actual <input> field invisible, so that all you see is the label.
Style the SVG based on whether the field is selected, by using the :checked pseudo-selector.
// just here to prove that the form value is changing
// prints value of spot field when inputs change
document.querySelectorAll("#spot1, #spot2, #spot3")
.forEach((elem) => elem.addEventListener("change", (evt) => console.log(document.myform.spot.value)));
.common_selector {
position: absolute;
opacity: 0;
}
.common_selector + label svg {
width: 50px;
height: 50px;
fill: red;
}
.common_selector:checked + label svg {
fill: green;
}
<form name="myform">
<input type="radio" id="spot1" name="spot" class="common_selector spot_id" value="spot1">
<label for="spot1">
<svg viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50"/>
</svg>
</label>
<input type="radio" id="spot2" name="spot" class="common_selector spot_id" value="spot2">
<label for="spot2">
<svg viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50"/>
</svg>
</label>
<input type="radio" id="spot3" name="spot" class="common_selector spot_id" value="spot3">
<label for="spot3">
<svg viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50"/>
</svg>
</label>
</form>
<input> is not a valid SVG element - it is a HTML element, so this won't work. You can either:
wrap an input element inside a <foreignObject> element and do it that way, or
you could use positioning to place the input element over the circle. But fair warning - form elements haven't always played well when they're positioned over other types of elements. Or
You can manually draw SVG that looks like an input element and use JavaScript to make it behave like one. or
Since you just need a circle, why not wrap the input element in a Div with an appropriate border radius and make a circle that way.
PART 1:
Use <foreignObect> to display any HTML element inside an SVG:
<foreignObject x="20" y="20" width="100" height="100">
<input type="checkbox" id="spot1" name="spot" class="common_selector spot_id"
value="spot1">
</foreignObject>
Then you can use css to hide default styling of this input field and position your circle over it. You can read about it here: https://www.w3schools.com/howto/howto_css_custom_checkbox.asp
PART 2:
Use Radio Buttons instead of Checkboxes. Checkboxes allow more than one selection. Radio buttons are what you need here. Read about it here: https://www.w3schools.com/tags/att_input_type_radio.asp
I hope I understand your question. You can not change an svg element into an input however you can try to mimic one.
// selects all the circles with a class of radio
let inputs = document.querySelectorAll(".radio")
// for every circle
inputs.forEach(i =>{
//when the circle is clicked
i.addEventListener("click", ()=>{
// remove the class checked from all the circles but the clicked one
inputs.forEach(j =>{if(i!==j)j.classList.remove("checked") })
// toggle the class checked on the clicked one
i.classList.toggle("checked")
})
})
svg{border:1px solid}
.checked{fill:red}
<svg id="theSVG" viewBox="800 410 300 85" width="300">
<circle class="radio" opacity="0.5" cx="842" cy="451.814" r="25.582" fill="#FFB60C" stroke="#FFB60C" stroke-width="10" />
<circle class="radio" opacity="0.5" cx="950" cy="451.814" r="25.582" fill="#FFB60C" stroke="#FFB60C" stroke-width="10" />
<circle class="radio" opacity="0.5" cx="1050" cy="451.814" r="25.582" fill="#FFB60C" stroke="#FFB60C" stroke-width="10" />
</svg>
It sounds like you want to use an SVG as a type of "selector" like a color selector or, in my case a planet selector. Here I have a SVG representing the solar system where the user clicks on a planet to select it. Since it sounds like you only want to select a single item then a radio button is the better option, however the method below should work with either.
As others have suggested the foreignObject element can be used. I had issues getting it work without specifically declaring a prefixed namespaces for the svg and saving the file with a .xhtml extension.
Of course there are plenty of ways to do something similar with javaScript, however a big advantage of using an underlying radio button is that it takes care of all the logic and makes validation easier.
I used an empty div over the circle that is acting as a label for the radio button. Since clicking on the label activates the radio button the circle now functions as a radio button!
The SVG does not show up in the snippet, so the div's are shaded for visibility. The actual radio buttons can be hidden if desired.
div{
border: red solid 1px;
background-color: black;
opacity: 20%;
}
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg">
<p>Select a planet</p>
<form name="planetData">
<input id="venus" name="planet" type="radio" value="venus" />
<label for="venus">Venus</label>
<input id="earth" name="planet" type="radio" value="earth" />
<label for="venus">Earth</label>
<input id="mars" name="planet" type="radio" value="mars" />
<label for="venus">Mars</label>
</form>
<svg:svg height="100" width="100" viewbox="0 0 100 100">
<svg:circle cx="0" cy="50" r="10" fill="yellow"/>
<svg:circle cx="30" cy="75" r="10" fill="green"/>
<svg:circle cx="60" cy="30" r="10" fill="blue"/>
<svg:circle cx="90" cy="60" r="10" fill="red"/>
<svg:foreignObject x="20px" y="65px" height="20px" width="20px">
<label for="venus">
<div style="height: 30px; width: 30px;">
</div>
</label>
</svg:foreignObject>
<svg:foreignObject x="50" y="20" height="20" width="20">
<label for="earth">
<div style="height:20px; width: 20px;"></div>
</label>
</svg:foreignObject>
<svg:foreignObject x="80" y="50" height="20" width="20">
<label for="mars">
<div style="height:40px; width: 40px;"></div>
</label>
</svg:foreignObject>
</svg:svg>
</html>
I am trying to provide edit option for label inside svg element using text box with in foreign object.
If text written in the text box is larger than width of the text box,text given overflows outer the text box field.
<svg>
<foreignObject x="30" y="15" width="200" height="40" class="editable" style="cursor: default;">
<div xmlns="http://www.w3.org/1999/xhtml">
<input type="text" class="editable-div" style="width:120px;">
</div>
</foreignObject>
</svg>
sample
It's quite easy to create a text with different font sizes for different words in HTML. But what about <text> in a svg?
I think this explains quite well about my question: https://jsfiddle.net/4atoctra/1/
Everything's here below:
<div>
This is a text, and you can have <span style="font-size:25px">big</span> and <span style="font-size:11px">small</span> sizes easily inline.
</div>
<div style="margin-top:50px">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="none" x="0px" y="0px" width="360px" height="126px" viewBox="0 0 360 126">
<text><tspan x="150" text-anchor="middle" y="10" font-family="Tahoma" font-weight="bold" font-size="11" fill="#003863" xml:space="preserve">What about this in a <svg>?</tspan></text></svg>
</div>
You can just change the font-size on each tspan element?
<svg viewBox="0 0 500 100" width="500px">
<text x="0" y="50" font-size="20">It's not <tspan font-size="30">that hard</tspan><tspan font-size="40"> to change size?</tspan></text>
</svg>
You can use a <foreignObject> to insert HTML markup into an SVG document:
<svg width="220" height="120" viewBox="0 0 220 120">
<rect x="10" y="10" width="200" height="100" fill="#ff9" stroke="none" />
<foreignObject x="15" y="15" width="190" height="90">
<div xmlns="http://www.w3.org/1999/xhtml" style="width:190px; height:90px; overflow-y:auto">This is a text, and you can have <span style="font-size:25px">big</span> and <span style="font-size:11px">small</span> sizes easily inline.
</div>
</foreignObject>
</svg>
I'm looking to bind a form input string to an svg text element in an Angular 2 template. I'm not sure how to do this and would appreciate any help.
<svg class="box">
<rect class="largeFrame" x="40" y="10" rx="10" ry="10"/>
<text class="name" x ="400" y="40">Name</text>
<text class="personName" x="400" y="55" [textContent]="personName.value"></text>
</svg>
<form #f="ngForm">
<div class="input">
<label for="name">Enter Your Name</label>
<input type="text" [(ngModel)]="personName.value" id="name">
</div>
[textContent] is not working... can anyone clue me in on the best syntax? Or suggest a method for binding SVG and inputs in Angular 2.
Thanks!
Looks like I needed to use [()] to bind the data.
I also needed to give personName.value an initial value.
<text class="personName" x="400" y="55" [(textContent)]="personName.value"></text>
use interpolation binding, which will bind to the textContent property for you
use the safe navigation operator to guard against null and undefined, then you won't need to specify an initial value
<text class="personName" x="400" y="55">{{personName?.value}}</text>