I'm new to HTML/CSS and having an issue I just cannot google my way out of.
I've setup a search box which takes you to google.
<form action="https://www.google.co.uk/search"target="_blank">
<input type="text" name="q">
<button>Search Google</button>
</form>
This works for Google, you can type in a search, click the button and it takes you to Google with the search.
But when I try the same for Instagram it takes me to an error page.
<form action="https://www.instagram.com/explore/tags/"target="_blank">
<input type="text" name="q">
<button>Search instagram</button>
</form>
Example if you type in #Coding it takes you to this page: https://www.instagram.com/explore/tags/?q=#coding
Instead of this page: https://www.instagram.com/explore/tags/coding/
Not sure what I'm doing wrong, any suggestions to help me out please :)
CodePudding user response:
Google accepts GET param q
as a string to search. So Your first form works as needed.
While instagram adds search query to URL.
You need a little help of JS to make Your second form work as needed:
const form = document.querySelector("form");
const q = document.querySelector("input[name='q']");
form.addEventListener("submit", (event) => {
event.preventDefault();
const url = form.action '/' q.value;
window.open(url);
});
Working example: https://jsfiddle.net/asertfy5/1/
CodePudding user response:
One approach is below, and seems to satisfy your request as written; explanations are in the code as comments:
// defining a named handler for the <form> element's submission, using
// Arrow syntax, and passing the Event Object automagically from the
// (later) use of EventTarget.addEventListener():
const formHandler = (event) => {
// here we make use of the event.preventDefault() method to
// prevent the <form> from being submitted:
event.preventDefault();
// we get a reference to the current <form> element to which the
// event-handler is bound:
let form = event.currentTarget,
// an Object of functions to handle the submission process,
// based on the supplied attribute-value of the custom
// data-* attribute in the <form> tag:
format = {
getParameters: function() {
// if GET parameters are used then we can simply
// submit the <form> programatically, taking
// advantage of the fact that programmatic events
// don't call event-handlers by default, so this
// submission bypasses the <form> element's
// submit-handler:
form.submit();
},
rest: function() {
// if we're accessing a REST API, then we simply
// use Window.open(), and pass the relevant URL string;
// this function has access to the variables declared
// outside of itself, so here we create the URL by
// retrieving the path from the <form> element's
// action attribute and concatenating that with the
// trimmed value of the <input> element with the
// name of 'q' (this is not designed to handle multiple
// words, however; if that's a requirement please leave
// a comment but that's not ordinarily how a REST API
// would work):
window.open(`${form.action}${form.q.value.trim()}`);
}
};
// here we call the function held within the format Object,
// after determining the appropriate search-method from the
// <form> element's custom data-searchmethod attribute and
// using bracket-notation, in place of dot-notation, to access
// that function:
format[form.dataset.searchmethod]();
};
// we iterate over all <form> elements using document.querySelectorAll() to
// retrieve those elements, and then chaining with NodeList.prototype.forEach()
// to handle iteration:
document.querySelectorAll('form').forEach(
// here we pass the current <form> element into the function,
// and bind the formHandler() function as the event-handler for
// the 'submit' event on that <form>:
(form) => form.addEventListener('submit', formHandler)
);
/* all CSS is irrelevant, it's just to make the demo
a little prettier */
*,
::before,
::after {
box-sizing: border-box;
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
margin: 0;
padding: 0;
}
form {
display: flex;
gap: 0.25em;
justify-content: start;
margin-block: 1em;
margin-inline: auto;
width: 80vw;
}
button {
padding-inline: 0.3em;
}
<!-- within the <form> element's opening tag I added a custom data-*
attribute to provide information about how the search functionality
is intended to work, in the case of Google we're using, and therefore
passing, GET parameters: -->
<form action="https://www.google.co.uk/search"
target="_blank"
data-searchmethod="getParameters">
<input type="text" name="q">
<button>Search Google</button>
</form>
<!-- in the Instagram search, we're using a REST endpoint: -->
<form action="https://www.instagram.com/explore/tags/" target="_blank" data-searchmethod="rest">
<input type="text" name="q">
<button>Search instagram</button>
</form>
Please note that, while the code above is identical between JS Fiddle and the Stack Snippet the Snippet won't work here on Stack Overflow due to the security restrictions of the sandbox, so please test in the linked JS Fiddle.
I feel that it's worth adding that during my testing the URL for Instagram was created as you desired, but the Instagram site blocked the page from loading. This may, or may not, be the result of something on my end but while I can verify the URL of the opened page matches your request, I can't verify that it loads the content you desire.
References: