Stay in same location on submit the form - xhtml

When i submitting the form the page will navigate to starting of page.
i want to stay on same location. is there any method to do that?

Yes, instead of using the form submission, send an asynchronous request in JavaScript using XHR. To give a concrete example, suppose you have a simple form that looks like:
<form method="POST" action="/path/to/submit">
<input id="input_name" name="input_name" type="text" value="value" />
</form>
Using XHR, it might look something like the following (using the Closure library for XHR):
<script>
goog.require('goog.net.XhrIo');
var submitCompleted = function() {
alert('Submitted!');
};
var submitAction = function() {
var value = document.getElementById('input_name').value;
goog.net.XhrIo.send(
'/path/to/submit',
submitCompleted,
'POST',
'input_name=' + encodeURIComponent(value));
};
</script>
I'm assuming that you still keep the same input element as before, but that you define your onsubmit function to invoke submitAction instead of using the default submission behavior of your form.

Related

Drupal 9: Adding a form on a page with AJAX

I've got a controller that is generating some markup. In the markup there is a link that dynamically adds some content to the page using jQuery ajax.
The content that's added to the page comes from another controller. In that content there's a Drupal form. It renders correctly on the page, but it doesn't submit properly (although it works well if I call it directly - it only fails to submit if it's inserted through AJAX).
So, in summary, controller A renders some markup like this:
<a id="ajax-link">Click here to display the form</a>
<div id="form"></div> <!-- form will be displayed here through AJAX -->
In the javascript, I've got:
$("#ajax-link").on("click", function() {
$.ajax({
url: "/controller-B/get-form",
type: "POST",
dataType: "JSON",
success: function(data) {
$("#form").html(data.output);
}
});
Controller B renders the form like this:
public function get_form() {
$form = \Drupal::formBuilder()->getForm('Drupal\my_module\Form\MyForm');
$output = \Drupal::service('renderer')->render($form);
$data = new \StdClass();
$data->output = $output;
return new JsonResponse($data);
}
So I click on the link, it calls the script, which calls controller B, which generates the form, and the script adds the markup for the form on the page.
It works well, but the form doesn't submit properly.
Looking at the markup that's generated after the form is inserted on the page, it looks like it's the action attribute that's incorrect. It generates something like this:
<form action="form_action_p_pvdeGsVG5zNF_XLGPTvYSKCf43t8qZYSwcfZl2uzM" method="post" id="comment-form" accept-charset="UTF-8" class="comment-form" data-drupal-selector="comment-form">
Any tip would be greatly appreciated!

Save the current view in variable to be able to render it later

I am reproducing a simplified version of my problem, to ask a fundamental question.
I have a template called 'form',
<template name="form">
<input id="name" type="text">
<button id="submitform type="submit">Submit</button>
</template>
I am handling the submit event as follows,
Template.form.events({
'click #submitform': function() {
event.preventDefault();
if(Meteor.user())
alert('submitted');
else{
//save the filled form along with view (basically the template or view)
Router.go('login');
}
}
});
My question is, how do i save the filled template with data filled in a variable/any how, so that i can render it after sign in.
This is how I am rendering to form template,
Router.route('/form', function () {
this.render('form');
});
What I want is to be able to render the user filled template/view back for him when he signs in. Please tell if there is a meteor way of doing it, and not easy JavaScript hack. Please ask if you need additional data/code.
Thanks in advance.
You can use a session variable for this if I'm understanding your question.
<template name="form">
<input id="name" type="text" value="{{name}}">
<button id="submitform type="submit">Submit</button>
</template>
Template.form.helpers({
name() {
return Session.get('name');
}
});
Template.form.events({
'click #submitform': function(event, template) {
event.preventDefault();
if(Meteor.user())
alert('submitted');
else{
Session.set('name', template.find('#name').value);
Router.go('login');
}
}
});
Then on your Meteor.loginWithPassword callback redirect back to the form route.
If you want to save the form with the user data in it, you could you make it invisible and then visible again later when you want to show it?
Otherwise you could repopulate the form from a save formData object. See Use jquery to re-populate form with JSON data

Meteor with Typeahead: where to call typeahead() on input element?

I'm using Meteor with Iron Router, and can't seem to get typeahead (this version: https://github.com/bassjobsen/Bootstrap-3-Typeahead) to work.
Here's some code:
HomeController = RouteController.extend({
//....
after: function () {
var tags = this.getData().tags;
console.log(tags);
if(tags.length > 0) {
var tags = ['hello', 'world'];
console.log("Adding typeahead for tags to ", $('.input-search')[0]);
console.log("tags: ", tags);
$('.input-search').typeahead({
source: tags,
updater: function(item) {
Router.go('/projects/tag/' + item);
}
});
}
},
I have a header that's part of the application layout, and has an input like this:
<input type="text" class="form-control input-search" data-provide="typeahead" placeholder="Search">
The jQuery in the after: function gets the input correctly. But calling typeahead on the input doesn't seem to activate typeahead properly: when typing in the input, nothing happens.
However if I wrap the typeahead call in a setTimeout, it does work.
Of course, whenever you start wrapping things in setTimeouts, something isn't right.
Where/when is the correct place to initialise typeahead when using Iron Router?
You can initialize the typeahead in the rendered function of your template. For instance:
Template.mytemplate.rendered = function() {
$('.input-search').typeahead({
source: tags,
updater: function(item) {
Router.go('/projects/tag/' + item);
}
});
};
I figured it out.
You need to make sure any inputs used by plugins are "preserved", i.e. not re-rendered, by Meteor. The simplest way to do this is to make sure the input has an ID attribute. So changing my search input to this fixed it:
<input type="text" id="input-search" class="form-control" data-provide="typeahead" placeholder="Search">
Relevant documentation: http://docs.meteor.com/#template_preserve
As of Meteor 1.0.3.1 and iron:router#1.0.7 working solution is to install sergeyt:typeahead and init typeahead like this:
Template.MyTemplate.rendered = function () {
Meteor.typeahead.inject();
}
Init may be done only once for top-level template.
I wrote an article about this, you can read it here.
In summary, your implementation using javascript to select and alter the element is bad practice in a reactive environment. I've tried it that way and it's a huge pain.
What I found is that you can create a helper that returns a JSON string of your typeahead data and use the data-source attribute, like so
JS
Template.myHelper.helper({
typeahead : function(){
return JSON.stringify(Session.get("typeahead"));
}
});
HTML
<template name="myTemplate">
<input data-source="{{typeahead}}" data-provide="typeahead" id="blah" type="text" />
</template>

How to add Search with Meteor and Bootstrap?

I am trying to implement searching in my Meteor app. I don't exactly understand how it ties together. At this point, I have this following code:
html:
<form class="navbar-search pull-left">
<input type="text" class="search-query" placeholder="Search">
</form>
js:
Template.menubar.events({
'keyup input.search-query': function (evt) {
console.log("Keyup value: " + evt.which);
if (evt.which === 13) {
console.log("Got an Enter keyup");
Session.set("searchQuery", "justATestVar");
}
}
});
I can see the values of keyup as I press different keys into the search box, so I know the event is being hit. Capturing the "enter" keyup also works, but pressing enter causes the enter site to reload and when I do:
Session.get("searchQuery")
it returns undefined.
I don't know if I'm handling this properly. Essentially, I just want to get the value from the search box and then use that value for making a search on my collection. Any help would be appreciated! Thank you.
You should really use a submit button for your search form to avoid ruining accessibility.
Using a submit button will also enable by default the behavior you're looking for : form submission on enter key pressed.
If you really want to get rid of the submit button, keep it in the DOM but use CSS to hide it.
It's very important to call preventDefault on the event you'll receive from "submit form" handler, if you forget to do so, the page will refresh ruining the meteor "Single Page App" experience (and by the way, page refresh will clear your Session variables, which is why you get an undefined value in the first place).
"submit form":function(event,template){
event.preventDefault();
Session.set("searchQuery",template.find(".search-query").value);
}
What is probably happening is your form is being submitted when you hit enter. Try an preventDefault(). Probably something like this would work:
Template.menubar.events({
'keyup input.search-query': function (evt) {
console.log("Keyup value: " + evt.which);
if (evt.which === 13) {
console.log("Got an Enter keyup");
Session.set("searchQuery", "justATestVar");
}
},
'submit form': function (evt) {
evt.preventDefault();
}
...
You could also try adding evt.preventDefault(); in your keyup but I think it's the form submission that's doing it.
In case anyone got here trying to implement the search function as well, I recommend the following:
meteor add matteodem:easy-search
On client and server:
Players = new Meteor.Collection('players');
// name is the field of the documents to search over
Players.initEasySearch('name');
On the client, make a template.html:
<template name="searchBox">
{{> esInput index="players" placeholder="Search..." }}
<ul>
{{#esEach index="players"}}
<li>Name of the player: {{name}}</li>
{{/esEach}}
</ul>
</template>
Reference

jQuery post from ASP.NET web page (WebMatrix)

I'm trying to submit form data with jQuery. I'm using ASP.NET WebMatrix. In a .cshtml file I have
#{
// other code
if(IsPost)
{
var item = new Item();
item.Title = Request.Form["title"];
item.Description = Request.Form["description"];
// aditional code here
}
}
<script type="text/javascript">
$(document).ready(function(){
$("form#itemForm").submit(function(){
$.post("form.cshtml", {
title: $("#title").val(),
description: $("#description").val(),
price: $("#price").val()},
function(data){
},
"json");
})
});
</script>
<form>
<!-- html form here -->
</form>
How can I pass values from form to Request.Form object? And how can I than response with json back to html?
A better way would be to just have jQuery post the form data using $(this).serialize() instead of building an object with all the values in it it to pass. After that, yah, Request["title"], etc will get the values that were posted.
This is what you want.
http://www.mikesdotnetting.com/Article/155/WebMatrix-And-jQuery-Forms
Values are passed through jQuery.post() to Request.Parameters.

Resources