yii2 How to remove unused query parameters from url - javascript

I have Kartik gridView and custom filter. After gridfilter in my browser i got URL like
localhost:20024/consignment?fid=&post_code=&pud2_mrn=&pud2_status=PUDP&pud_status=&pud2_remaining_date=&mrn=&mrn_status=&ioss_number=&declaration_type=&status=&entry_at=&exit_at=&created_at=
Is there a way to remove unfilled parameters from url inside YII instead javascript?
Or can anybody provide full example of javascript to achieve the goal.

Copy vendor/yiisoft/yii2/yii.gridView.js somewhere under web directory (e.g. web/js and add this line:
$.each(data, function (name, value) { if (value[0].length === 0) data[name] = null; });
prior this line in applyFilter method:
var pos = settings.filterUrl.indexOf('?');
Then add this to web.conf (update paths if you used different place for this js file):
'assetManager' => [
'bundles' => [
'yii\grid\GridViewAsset' => [
'sourcePath' => '#webroot/js',
'basePath' => '#webroot/js',
'baseUrl' => 'vendor/js',
],
],
],
This was you are not modifying anything in the vendor folder.

Related

How to create a single Gatsby Page to show and filter all blog posts by tag/category

Hello i'm building a blog using Gatsby and Netlify CMS. I started off from the gatsby-starter-netlify-cms template.
I have the /blog page where i currently display all posts and also a list of all the tags.
When user clicks on a tag, it is currently redirected to the tags/name-of-tag page, where a list of all posts tagged like that is displayed.
What i want instead is to directly filter the list on the /blog page.
This way i'll have only one page to display and filter blog posts by tag (and possibly by term search).
So the tag links should redirect to /blog?tag-name or something like that.
I'm not sure how to tell Gatsby to create a single page with possibility to inject a filter value in order to pass it to the page query..
This is how /tags/ pages are created currently:
// Tag pages:
let tags = []
// Iterate through each post, putting all found tags into `tags`
posts.forEach((edge) => {
if (_.get(edge, `node.frontmatter.tags`)) {
tags = tags.concat(edge.node.frontmatter.tags)
}
})
// Eliminate duplicate tags
tags = _.uniq(tags)
// Make tag pages
tags.forEach((tag) => {
const tagPath = `/tags/${_.kebabCase(tag)}/`
createPage({
path: tagPath,
component: path.resolve(`src/templates/tags.js`),
context: {
tag,
},
})
})
This is my blog page query (the one i want to be able to filter by tag):
export const blogPageQuery = graphql`
query BlogPageTemplate {
markdownRemark(frontmatter: { templateKey: { eq: "blog-page" } }) {
frontmatter {
image {
childImageSharp {
fluid(maxWidth: 2048, quality: 80) {
...GatsbyImageSharpFluid
}
}
}
heading
subheading
}
}
allMarkdownRemark(
sort: { order: DESC, fields: [frontmatter___date] }
filter: { frontmatter: { templateKey: { eq: "blog-post" } } }
) {
edges {
node {
id
fields {
slug
}
excerpt(pruneLength: 180)
frontmatter {
date(formatString: "MMMM DD, YYYY")
title
description
featuredpost
featuredimage {
childImageSharp {
fluid(quality: 50, maxWidth: 512) {
...GatsbyImageSharpFluid
}
}
}
}
}
}
}
}
`
I'm not sure how to tell Gatsby to create a single page with
possibility to inject a filter value in order to pass it to the page
query.
You can't. The only way to filter data in a page query is by passing data using the context. Like you are doing in with the tags page:
createPage({
path: tagPath,
component: path.resolve(`src/templates/tags.js`),
context: {
tag,
},
})
The easiest and native approach is to use the /tag/tag-name page, which is intended to filter by tag name, otherwise, you will need to get the URL parameter and using it in a JavaScript filter function to filter all the data from the page query. Since you are missing the rendering part of your blog page... Something like this approach should work:
const BlogTemplate=({ data }){
if(typeof window !== "undefined"){
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const urlTag= urlParams.get('tag');
const filteredPosts= data.allMarkdownRemark.edges.node.filter(node=> node.frontmatter.tag.includes(urlTag))
const loopData= urlParams.has('tag') ? filteredPosts : data
}
return loopData.allMarkdownRemark.edges.node.map(node=> <h1 key={node.title}>{node.title}</h1>)
}
Note: of course, adapt it to your needs but get the idea.
Note also that you will need to wrap all your window logic in the typeof window !== "undefined" condition, since in the SSR window (and other global objects) are not available.
The key part is to use wether use data or your filteredPosts depending on the existance of the URL parameter, so if it exists, you will need to filter the data otherwise, you need to use the "default" data (unfiltered).
It's difficult to guess how the code will behave but the idea relies on changing your iterable data depending on the URL, use some hooks if needed.
According to your query, it seems that your blogs don't contain any tag field in the blog template query so you will need to add it to allow the filter loop to work.
Once the code is working, you will need to add the proper controls to avoid the code-breaking when some field is missing, but the idea and the path to follow is this.

Shopify script_tag API - how to pass the variable?

I have some javascript code in my ShopifyApp which I'm adding to the ShopifyShop using script_tag API:
$response = $client->request(
'POST',
"https://{$store}/admin/script_tags.json",
[
'headers' => [
'X-Shopify-Access-Token' => $access_token
],
'form_params' => [
'script_tag' => [
"event" => "onload",
"src" => $scriptUrl
]
]
]);
Script:
var _smid = 'someValue';
(function(a,b,c,d,e) {...})
My problem is that I need to pass var _smid there which is different per App instalation (generated server side) - is there any way to do it or maybe some other way to actually pass script as variable from php and not as url to .js file?
Modify your script tag to do a callback to an App Proxy. That way, your App gets the store name, and any other data you need to pass to it.

yii2: How to integrate AdminBSB Theme

I'm using yii2 advanced framework. And I am using AdminBSB theme for my layout. But this error appears. I tried on searching for same issues. But I can't figure it out. Here is the error when I inspect:
Uncaught TypeError: jQuery(...).yiiActiveForm is not a function
at HTMLDocument.
Some say I declare JS twice. But I didn't declare it twice or I didn't notice It call twice because of my template.
Below is how I am loading the javascript in my Asset Manager file.
public $js = [
"plugins/jquery/jquery.min.js",
"plugins/bootstrap/js/bootstrap.js",
"plugins/bootstrap-select/js/bootstrap-select.js",
"plugins/jquery-slimscroll/jquery.slimscroll.js",
"plugins/node-waves/waves.js",
"plugins/flot-charts/jquery.flot.js",
"plugins/jquery-sparkline/jquery.sparkline.js",
"js/admin.js"
];
i had the same theme and i also faced this error and that is because the yiiActiveForm is loaded before the jquery file does, even if you will fix that it will get in conflict with bootstrap js file that functions for the dropdown in the dashboard under user image. I advise you to change the loading of jquery and bootstrap to the following, you need to make some changes to you AppAsset.php file.
1.Remove the bootstrap and jquery links from the $js and $css arrays in the AppAsset.php.
2.Update your $depends array to the following.
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
'yii\bootstrap\BootstrapPluginAsset',
];
3.Then update your frontend/config/main.php to the following.
'assetManager' => [
'bundles' => [
'yii\web\JqueryAsset' => [
'sourcePath' => null, 'js' => ['//code.jquery.com/jquery-2.2.4.min.js'],
],
'yii\bootstrap\BootstrapAsset' => [
'sourcePath' => null, 'css' => ['//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'],
],
'yii\bootstrap\BootstrapPluginAsset' => [
'sourcePath' => null, 'js' => ['//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'],
],
],
],

How to parse a javascript file that contains json data stored in a variable?

I was wondering how can I extract the JSON data from a javascript file. The javascript is intended to be used as a config file and contains one variable with JSON data in it. This is similar to the require-config.js file used in Magento 2, just for reference. It looks something like this:
var config = {
fieldsets : [
{
title : 'Quote Essentials',
description : 'Some',
fields : [
{
label : 'What type of project is this for?',
required : true,
class : '',
type : 'input',
inputType : 'text',
hint : 'For example: company uniforms, clothing line, school events, etc.',
id : ''
},
{
label : 'How many total items do you need?',
required : true,
class : '',
type : 'input',
inputType : 'text',
hint : 'Please note: the minimum order size is 24 pieces.',
id : ''
},
...
If you're accessing this server-side you can export the config
module.exports = {
fieldset: [ ... ]
}
and require it
const config = require('./config.js');
If you're trying to access it on the client-side, just place the config script before the scripts that access it and you'll be able to access it like you would any other object:
config.fieldset...
One problem with this is that you're adding the config variable directly to window and by doing this you might be over-writing an existing config variable. Probably unlikely, but a way to mitigate this is to provide a namespace for your code so you don't pollute the global namespace and the code becomes more modularised. WRT to your config file, your namespace technique might work like this:
// Semi-colon to prevent minify issues
// Pass `window` into the immediately-invoked function expression
// as an argument
;(function (window) {
// config is local to this function and can't leak
var config = { ... };
// If the `app` variable isn't available, create it
window.app = window.app || {};
// Add config to the app namespace
window.app.config = config;
})();
And you can do something similar to the rest of your code.
You would access the config with app.config.fieldset....
Hope that helps.

Is it possible to update js file using php command?

I have script.js file. and it has following array
script.js
'COntent': function() {
var contentFacts = {
blocks: {
'block1': {
name: 'yleow',
title: 'H2',
type: 'content'
}
}
};
}
},
I tried like this in my php , but it did not work :(
$lines = file($path.'/script.js');
$lines[64] = "'block2': {name: 'yleow',title: 'H2',type: 'content'}"
file_put_contents($path.'/script.js', implode($lines));
I want to add another element call block2 for this array. How can i update my script.js file function using php?
Is it possible using file_put_contents? please advice
JavaScript is a very poor substitute for a database or any other structured data format. In this case even more because you are trying to inject content into source code.
What you probably want is some form of structured data outside of your code for example a JSON file or an SQLite database.
PHP does support parsing from and serializing to JSON:
json_decode
json_encode
Possible solution
Put the contentFacts into a seperate JSON file
{
"blocks": {
"block1": {
name: 'yleow',
title: 'H2',
type: 'content'
}
}
}
Manipulate JSON with PHP
$json = file($path.'/blocks.json');
$blocks = json_decode($json, true);
$blocks['block2'] = array(
'name' => 'blue',
'title' => 'h3',
'type' => 'content'
);
Write back to JSON file
$adapted_json = json_encode($blocks);
file_put_contents($path.'/blocks.json');
Now you need to get this into your JavaScript part, I assume on the client. You can do this by requesting it from the server:
const contentPromise = fetch('/path/to/blocks.json');
contentPromise.then((blocks) => {
// Do something with those blocks. (render them to the page?)
});

Categories

Resources