The desired effect when submitting a form using React router 4 is to append the search query to the end of the URL.
My current setup will send an API request on form submission, and then render the results in the render method.
Without using Links or Redirects, is there a way to add the query onto the URL, maybe from within the form submission method?
You can dynamically push the queries to the url like
this.props.router.push({
pathname: '/yourRoute',
query: { someQuery: 'value' }
})
Connect your Component with witRouter to be able to use the router prop
import { withRouter } from 'react-router'
....
export default withRouter(App);
Related
I am wondering, what would be the best setup of data flow from PHP (database) to fronted Javascript rendering, lets say VueJS.
My first idea is, that will provide data attribute with JSON data to HTML element - div, which Vue instance will be mounted on.
I dont want to create REST API and load data via AJAX HTTP requests from Vue.
# PHP part
echo '<div id="myId" data-my-data="{h1:\"My heading\"}"></div>';
// Javascript part
import Vue from 'vue/dist/vue.js';
import App from './MyApp.vue';
const el = document.querySelector('#myId');
new Vue({
el,
render: h => h(App, {
props: {
myData: JSON.parse(el.dataset.myData),
},
}),
});
What do you think, is it ok or is there any other option except REST?
Update:
Main purpose is that my App will handle complex - multi-step Forms with some complex fields, which I would like to create as reusable components.
App will validate forms via AJAX (to prevent re-rendering page), on success redirect to success page.
My infrastructure would be, that PHP will prepare data, render main layout with assets (JS + CSS) and DIV with data atributes for Vue App.
Is it possible to restrict user from putting url of page by hand?
Let's say I have two pages - somepage.com/home and someplace.com/other and somewhere in home page is button that redirects user to /other site. I want to make sure that user won't be able to access /other by writing its url by hand. Instead it should redirect back to home page.
Is there maybe some decorator like login_required that I can use? Or maybe I should use some js function?
Thanks in advance for any tips, cheers.
Try using the referrer property of the html, if the user goes to other page by clicking the link in your home page, then referrer with point to your homepage. But if the user have manually typed the other page link then the referrer will not point to your homepage.
Return Value: A String, representing the URL of the document that loaded the current document. Returns the entire URL, including the protocol (like http://). If the current document was not opened through a link (for example, through a bookmark), an empty string is returned.
Reference : https://www.w3schools.com/jsref/prop_doc_referrer.asp
Other, not so efficient solutions :
You don't need login functionality ? If you need then simply go ahead and implement one and mark other view as login_required.
If you don't need that then read point #2.
You can POST some random unique value from homepage button to go to other page. And in other view check for that value. If that value is not found then redirect to homepage. If found, display other view.
If the user is accessing page by entering the url, that value will be missing those redirection to homepage to occur. One thing to make note of, this solution is not secure. Users can trick the server, if you don't implement is secure enough.
You can build a middelware and use it.
First, you need to give each user a group or access to the user.i did this with user_type.
Now you create file acl and make a pack of urls name.
acl.py
acl_view_segment_divided = {
"pack_1": [
"url_name_1",
"url_name_2",
.
.
.
],
"pack_2": [
"url_name_3",
"url_name_4",
.
.
.
],
}
acl_view_segment = dict(
user_type_1=list(
acl_view_segment_divided["pack_1"] +
acl_view_segment_divided["pack_2"]
),
user_type_2=list(
acl_view_segment_divided["pack_1"]
),
)
Now you need to create middelware file:
middleware.py
from django.conf import settings
from django.utils.deprecation import MiddlewareMixin
from django.core.urlresolvers import resolve
from acl import acl_view_segment
from django.shortcuts import render
from django.contrib import auth
from apps.main.views import page_permission_denied_view
class ACLMiddleware(MiddlewareMixin):
#staticmethod
def process_view(request, view_func, view_args, view_kwargs):
if not request.user.is_authenticated():
return
current_url = resolve(request.path_info).url_name
if current_url in getattr(settings, 'ACL_EXEMPT_VIEWS', set()):
return
user_type = request.user.user_type
acl = acl_view_segment[user_type]
if current_url not in acl:
return page_permission_denied_view(request)
or
return redirect(home_page)
added middelware to setting.py
settings.py
MIDDLEWARE = [
...
'yourproject.middleware.ACLMiddleware',
]
If you have questions, ask questions in comment.I hope your problem is resolved.
I am new in vuejs . I want to load component from ajax response.
<div id="app"></div>
export default(){
created: function(){
const url = "xyz.json";
this.$http.get(url).then(response => {
this.resp = response.body;
var comp = this.resp.components;
}
}
}
Here is my JSON response
{
components: "Hello.vue",
}
I want to draw dynamically components by using json data
Update:
My Purpose is to draw a vuejs component in response of server side data. In server side data, I will tell which component will be loaded for this particular action. For example, I want to render particular view in response of drop-down value. If value is 1 , then server will tell load A component, if value is 2, then server will tell load B component.
I have index.html. In that I have form which accepts some data.After clicking on submit button, I want to send the all data to the process.php file in ajax format using react js. Thanks in Advance.
Correct way :
There is no AJAX functionality in the Reactjs. Basically react is just a view layer. For use of Network layer and Data layer you have to use some other configuration with React . Best will be Reactjs + Flux like facebook.
I like fluxxor for fluxx + react combination. fluxxor provides actions . By using those action you can call some external API.
Or Hack :
var Form = React.createClass({
submit:function(e){
e.preventDefault();
// make ajax call .
},
render: function() {
return (
<form onsubmit = {this.submit} > </form>
);
}
});
Is it possible to have a Router implementation similar to the following?
var Router = Backbone.Router.extend({
routes: {
'' : 'search',
'*querystring' : 'results'
},
search: function() {
// load search view
},
results: function(querystring) {
// load search view
// make ajax request using querystring
}
});
The search view has a form that when submitted should go to the results view which will parse the url for the query, submit an ajax request and then display the response.
Obviously something like this would make more sense
'results?*querystring' : 'results'
But I can't get my form to submit the URL in that format.
When put my form action as <form action="index.html/results"> I get http://localhost:8000/index.html/results?c=foo&a=bar as my URL.
This is close, but I really need http://localhost:8000/index.html#/results?c=foo&a=bar and when I try to do this with <form action="index.html#/results"> it gives me http://localhost:8000/index.html?c=foo&a=bar#/results which is not what I want :(
This is why I would rather just have no form action and instead have a route that can will parse the query if one exists.
Ok thanks for reading. Hopefully someone understands some of that and can help me out.
don't put pushstate to true, set it to false
Backbone.js PushStates: Fallback for Internet Explorer not working
Remove form or prevent the submission
Simply get the params and trigger a route
Handle the params appropriately in the triggered route.
Router
routes:{
'search':'search' //queryString is automatically passed as last param in backbone 1.1
},
search: function(queryString){
//Write your logic to do the search
}
View:
events:{
'submit form':'preventAndNavigate'
},
preventAndNavigate: function(e){
e.preventDefault();
var query = $(e.currentTarget).serialize();
Backbone.history.navigate('search?'+query,{trigger:true});
}
Docs :
Backbone Routers now handle query params in route fragments, passing them into the handler as the last argument. Routes specified as strings should no longer include the query string ('foo?:query' should be 'foo').
References :
http://backbonejs.org/#changelog