Show/Hide within jQuery File Upload Plugin - show-hide

I am using PHP with the "jQuery File Upload Plugin" by Sebastian Tschan (https://blueimp.net) and within the upload and download templates I want to do some simple show/hide stuff but can't figure out how to do it.
When you first view the page I only want to be able to see the "Add files..." button.
Then when files are added (by whichever method) the "Start upload" should then appear along with the "Cancel" button.
Once uploaded I then want a block of text to say something like "You have successfully uploaded [X] photographs. These will now be reviewed by our assessors. Your reference for these uploaded images is [XXXXXXXXX].". This block of text will appear once directly below the last uploaded image in the Download template.
Obviously the upload is using JQuery/JavaScript and not PHP and I am trying to look for some sort of trigger to detect how many images are being uploaded and when that upload is complete.
I also want to disable the "Start upload" button once it has been triggered so as to prevent uploading files twice.
Regards, Neil
<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-upload fade">
<td>
<span class="preview"></span>
</td>
<td>
<p class="name">{%=file.name%}</p>
{% if (file.error) { %}
<div><span class="label label-important">Error</span> {%=file.error%}</div>
{% } %}
</td>
<td>
<p class="size">{%=o.formatFileSize(file.size)%}</p>
{% if (!o.files.error) { %}
<div class="progress progress-success progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="bar" style="width:0%;"></div></div>
{% } %}
</td>
<td>
{% if (!o.files.error && !i && !o.options.autoUpload) { %}
<button class="btn btn-primary start" style="display:none;">
<!--<i class="icon-upload icon-white"></i>-->`enter code here`
<!--<span>Start</span>-->
</button>
{% } %}
{% if (!i) { %}
<button class="btn btn-warning cancel">
<i class="icon-ban-circle icon-white"></i>
<span>Cancel</span>
</button>
{% } %}
</td>
</tr>
{% } %}
</script>

Related

Laravel 7.x with Nova Can't use menu from optimistdigital/nova-menu-builder

I am new to Laravel Nova ... I just installed optimistdigital/nova-menu-builder in order to generate menus in a more efficient way then whats generated by nova. My menu structure is very complex and needs more control. Anyway, I installed the package and created a menu. I am at the point where I would like to load it in the sidebar but can't figure out how that works ...
in the navigation.blade.php file I added:
#menu("admin")
Where admin is supposed to be the menu slug
After a refresh, nothing happened. So I tried something more basic. I removed the #menu and added "hello world" instead. It did not appear ... So I ran the following commands:
php artisan config:clear
php artisan cache:clear
php artisan nova:publish
All 3 were executed without any errors. But the sidebar still did not show my hello world.
So my question is the following. How can I reflect my changes in the blade views? And is #menu("") the right way to use the optimistdigital/nova-menu-builder package? The documentation seems to be missing the part on how to use the menus you create... Thx in advance!
Here's my layout page
<router-link exact tag="h3"
:to="{
name: 'dashboard.custom',
params: {
name: 'main'
}
}"
class="cursor-pointer flex items-center font-normal dim text-white mb-8 text-base no-underline">
<svg>[Long SVG string]</svg>
<span class="text-white sidebar-label">{{ __('Dashboard') }}</span>
</router-link>
hello world
#menu("admin")
#if (\Laravel\Nova\Nova::availableDashboards(request()))
<ul class="list-reset mb-8">
#foreach (\Laravel\Nova\Nova::availableDashboards(request()) as $dashboard)
<li class="leading-wide mb-4 ml-8 text-sm">
<router-link :to='{
name: "dashboard.custom",
params: {
name: "{{ $dashboard::uriKey() }}",
},
query: #json($dashboard->meta()),
}'
exact
class="text-white no-underline dim">
{{ $dashboard::label() }}
</router-link>
</li>
#endforeach
</ul>
#endif
Thx to leek, I was able to find how to retrieve the menus and build on that.
So my first problem was that I was editing the wrong file. You need to do the following first:
copy the file in nova/resources/views/layout.blade.php and put it in
/resources/views/vendor/nova.
After doing this your changes will reflect correctly. I moved all the files in the nova view folder while I was at it.
In side the newly created /resources/views/vendor/nova/layout.blade.php file replace this code:
#foreach (\Laravel\Nova\Nova::availableTools(request()) as $tool)
{!! $tool->renderNavigation() !!}
#endforeach
with this code:
#php
$menus = [
nova_get_menu('admin'),
];
#endphp
<section style="width: 100%; position: absolute; top: 60px;">
<ul class="sidebar-menu">
<li class="sidebar-header">MAIN NAVIGATION</li>
<li>
<a href="/nova">
<i class="fa fa-dashboard"></i> <span>Dashboard</span></i>
</a>
</li>
#foreach ($menus as $menu)
#continue(is_null($menu))
<li>
<a href="">
<i class="fa fa-dashboard"></i> <span>{{ $menu['name'] }}</span> #if ($menu['menuItems'])<i class="fa fa-angle-left pull-right"></i> #endif
</a>
#if ($menu['menuItems'])
<ul class="sidebar-submenu">
#foreach (($menu['menuItems'] ?? []) as $item)
<li>
#if ($item['type'] === 'text')
{{ $item['name'] }}
#else
<a href="{{ $item['value'] }}"
target="{{ $item['target'] }}"
#if ($item['target'] === '_blank') rel="noopener" #endif><i class="fa fa-circle-o"></i> {{ $item['name'] }}</a>
#endif
</li>
#endforeach
</ul>
#endif
</li>
#endforeach
<li>
<a href="/nova/logout">
<i class="fa fa-sign-out"></i> <span>Logout</span></i>
</a>
</li>
</ul>
</section>
Replace "admin" with the slug of your menu
You can change the HTML to what ever you want.
I used https://www.jqueryscript.net/menu/Stylish-Multi-level-Sidebar-Menu-Plugin-With-jQuery-sidebar-menu-js.html
And the result is:
You can add more then one menu like this if you need to
#php
$menus = [
nova_get_menu('admin'),
nova_get_menu('user'),
nova_get_menu('pages'),
nova_get_menu('configuration'),
nova_get_menu('store'),
];
#endphp
The foreach loop will add them all to your page in the order you put them in the $menus array.
Good luck!
Quote from this issue on GitHub:
[nova_get_menu()] only returns a PHP array. You have to handle creating the HTML yourself.
As of version 2.3.7, you will need to use this function yourself to generate your own menu HTML:
$menuJson = nova_get_menu('admin')
// Returns:
// [
// 'id',
// 'name',
// 'slug',
// 'locale',
// 'menuItems' => []
// ]

Why Symfony Controller return template snipped with <html> and <body> tags?

I have a controller-action:
/**
* Get the template for the notifications in the user-navbar
*
* #Route("/notification/get-template", name="get_notifications_template")
* #param Request $request
* #return Response
*/
public function getNotificationsTemplateAction(Request $request)
{
if (!$request->isXmlHttpRequest()) {
return $this->redirect($this->generateUrl('homepage'));
}
return $this->render('Menu/_notifications_block.html.twig');
}
I want to do an AJAX call with to get this template:
refreshNotifications() {
$.ajax({
url: this.$wrapper.data('refresh-action-path'),
method: 'POST',
}).then(function (data) {
// remove old notifications
this.$wrapper.remove();
// append data to the container
$('#user-notifications-container').append(data);
console.log(data);
}.bind(this))
}
The problem is now - that the Symfony container sends a whole html page:
the template is that:
{% if app.user is not null and is_granted('ROLE_USER') %}
{% if app.user|notifications|length != 0 %}
{% set notifications = app.user|notifications %}
{% set all_notification_count = notifications|length %}
<li class="nav-item mx-2 dropdown js-notification-wrapper data-refresh-action-path="{{ path('get_notifications_template') }}"">
<a href="#" class="icon-wrapper nav-link btn-lg" data-toggle="dropdown">
<span class="icon icon-mail" aria-hidden="true"></span>
<span class="badge badge-notification">{{ all_notification_count }}</span>
</a>
<ul class="dropdown-menu dropdown-menu-right notification-list">
{% if app.user is not null and is_granted('ROLE_USER') and all_notification_count != 0 %}
{% for notification in notifications %}
<div class="notification-text">
<div class="d-flex">
<div class="col-10 px-0">
Kurszugang: {{ notification.courseAction.course }} ({{ notification.courseAction.course.school }})
- {{ notification.courseAction.schoolUser }}
</div>
<div class="col-2">
<button class="btn btn-sm btn-success" id="js-accept-course-action" data-course-action-path="{{ path('course_action_accept_join_request', {'courseAction' : notification.courseAction.id}) }}">
<i class="icon icon-thumbs-up"></i>
</button>
<button class="btn btn-sm btn-secondary" id="js-decline-course-action" data-course-action-path="{{ path('course_action_decline_join_request', {'courseAction' : notification.courseAction.id}) }}">
<i class="icon icon-thumbs-down"></i>
</button>
</div>
</div>
</div>
</li>
{% endfor %}
{% endif %}
</ul>
</li>
{% endif %}
{% endif %}
Can somebody tell me - why I can't only the snipped but a whole html page?
I can not append this whole page to the container ...
The way I understand it render returns a complete response(with headers), while renderView will just return the html.
Try changing this line:
return $this->render('Menu/_notifications_block.html.twig');
to this:
return new JsonResponse([
'html'=> $this->renderView('Menu/_notifications_block.html.twig')
]);
then in the ajax function change:
$('#user-notifications-container').append(data);
to this:
$(data.html).appendTo('#user-notifications-container');

Shopify show how close to free shipping

I am trying to show how close someone is to free shipping using the standard timber draw cart system. The code should be checking if the customer has $30 or less and then display how much more they need to spend to achieve free shipping, and if they are over $30 state that they have achieve the free shipping threshold.
Here is my current cart code
<!-- /snippets/ajax-cart-template.liquid -->
{% comment %}
This snippet provides the default handlebars.js templates for
the ajax cart plugin. Use the raw liquid tags to keep the
handlebar.js template tags as available hooks.
{% endcomment %}
<script id="CartTemplate" type="text/template">
{% raw %}
<form action="/cart" method="post" novalidate class="cart ajaxcart">
<div class="ajaxcart__inner">
{{#items}}
<div class="ajaxcart__product">
<div class="ajaxcart row" data-line="{{line}}">
<div class="grid__item desktop-4 tablet-2 mobile-1">
<img src="{{img}}" alt="">
</div>
<div class="desktop-8 tablet-4 mobile-2">
<p>
{{name}}
{{#if variation}}
<span class="ajaxcart__product-meta">{{variation}}</span>
{{/if}}
{{#properties}}
{{#each this}}
{{#if this}}
<span class="ajaxcart__product-meta">{{#key}}: {{this}}</span>
{{/if}}
{{/each}}
{{/properties}}
{% endraw %}{% if settings.cart_vendor_enable %}{% raw %}
<span class="ajaxcart__product-meta">{{ vendor }}</span>
{% endraw %}{% endif %}{% raw %}
</p>
<p><strong>{{{price}}}</strong></p>
<div class="display-table">
<div class="display-table-cell">
<div class="ajaxcart__qty">
<button type="button" class="ajaxcart__qty-adjust ajaxcart__qty--minus quantity-increment" data-id="{{id}}" data-qty="{{itemMinus}}" data-line="{{line}}">
<span>−</span>
</button>
<input type="text" name="updates[]" class="ajaxcart__qty-num" value="{{itemQty}}" min="0" data-id="{{id}}" data-line="{{line}}" aria-label="quantity" pattern="[0-9]*">
<button type="button" class="ajaxcart__qty-adjust ajaxcart__qty--plus quantity-increment" data-id="{{id}}" data-line="{{line}}" data-qty="{{itemAdd}}">
<span>+</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
{{/items}}
{% endraw %}{% if settings.cart_notes_enable %}{% raw %}
<div>
<label for="CartSpecialInstructions">{% endraw %}{{ 'cart.general.note' | t }}{% raw %}</label>
<textarea name="note" class="input-full" id="CartSpecialInstructions">{{ note }}</textarea>
</div>
{% endraw %}{% endif %}{% raw %}
</div>
<div class="ajaxcart__footer row">
<div class="desktop-half tablet-half mobile-half">
<p><strong>{% endraw %}{{ 'cart.general.subtotal' | t }}{% raw %}</strong></p>
</div>
<div class="desktop-half tablet-half mobile-half">
<p class="text-right"><strong>{{{totalPrice}}}</strong></p>
</div>
<p class="text-center">{% endraw %}{{ 'cart.general.currency_disclaimer' | t }}{% raw %}</p>
<p class="text-center">{% endraw %}{{ section.settings.hello }}{% raw %}</p>
<p class="text-center">{% endraw %}{{ 'cart.general.shipping_at_checkout' | t }}{% raw %}</p>
<p class="text-center">
{% endraw %}
{% if totalPrice <= 30 %}
You’re just {{{30 | minus: totalPrice}}} away from FREE shipping.
{% else %}
You've qualified for Free Shipping.
{% endif %}
{% raw %}
</p>
<button type="submit" class="cart__checkout" name="checkout">
{% endraw %}{{ 'cart.general.checkout' | t }}{% raw %} →
</button>
{% endraw %}{% if additional_checkout_buttons %}
<div class="additional_checkout_buttons">{{ content_for_additional_checkout_buttons }}</div>
{% endif %}{% raw %}
</div>
</form>
{% endraw %}
</script>
<script id="AjaxQty" type="text/template">
{% raw %}
<div class="ajaxcart__qty">
<button type="button" class="ajaxcart__qty-adjust ajaxcart__qty--minus icon-fallback-text" data-id="{{id}}" data-qty="{{itemMinus}}">
<span class="icon icon-minus" aria-hidden="true"></span>
<span class="fallback-text">−</span>
</button>
<input type="text" class="ajaxcart__qty-num" value="{{itemQty}}" min="0" data-id="{{id}}" aria-label="quantity" pattern="[0-9]*">
<button type="button" class="ajaxcart__qty-adjust ajaxcart__qty--plus icon-fallback-text" data-id="{{id}}" data-qty="{{itemAdd}}">
<span class="icon icon-plus" aria-hidden="true"></span>
<span class="fallback-text">+</span>
</button>
</div>
{% endraw %}
</script>
<script id="JsQty" type="text/template">
{% raw %}
<div class="js-qty">
<button type="button" class="js-qty__adjust js-qty__adjust--minus quantity-increment" data-id="{{id}}" data-qty="{{itemMinus}}">
<span>−</span>
</button>
<input type="text" class="js-qty__num" value="{{itemQty}}" min="1" data-id="{{id}}" aria-label="quantity" pattern="[0-9]*" name="{{inputName}}" id="{{inputId}}">
<button type="button" class="js-qty__adjust js-qty__adjust--plus quantity-increment" data-id="{{id}}" data-qty="{{itemAdd}}">
<span>+</span>
</button>
</div>
{% endraw %}
</script>
You wrote:
{% endraw %}
{% if totalPrice <= 30 %}
You’re just {{{30 | minus: totalPrice}}} away from FREE shipping.
{% else %}
You've qualified for Free Shipping.
{% endif %}
{% raw %}
Which is correct... if you were offering free shipping at $0.30
Shopify stores prices as integers, not floating-point-numbers - so the values in the price variables represent cents, not dollars. If you want to compare to $30.00, you'll need to compare to 3000, not 30
Also, you've put your Liquid code into a Handlebars template - Liquid is rendered server-side, so the evaluation of the cart total happens before the page is served to your client. If the shopper changes their cart total, the template does not get re-evaluated at the server level, so the message won't be dynamic.
What you should do instead is add a new variable to your template, like {{{ shippingMessageHTML }}}, then edit the script file that populates the template to have a variable with the same name.
Example:
(Note: It looks like you're using Brooklyn or one of its related themes. This theme family names the function that populates that template buildCart, which is usually found in an asset file named ajax-cart, app or theme. The extension will either be .js or .js.liquid)
Find the section of code near the bottom of the function, which should look something like this:
// Gather all cart data and add to DOM
data = {
items: items,
note: cart.note,
totalPrice: Shopify.formatMoney(cart.total_price, settings.moneyFormat),
totalCartDiscount: cart.total_discount === 0 ? 0 : {{ 'cart.general.savings_html' | t: savings: '[savings]' | json }}.replace('[savings]', Shopify.formatMoney(cart.total_discount, settings.moneyFormat))
};
At the end of that data object, add your message HTML. Example:
// Gather all cart data and add to DOM
data = {
items: items,
note: cart.note,
totalPrice: Shopify.formatMoney(cart.total_price, settings.moneyFormat),
totalCartDiscount: cart.total_discount === 0 ? 0 : {{ 'cart.general.savings_html' | t: savings: '[savings]' | json }}.replace('[savings]', Shopify.formatMoney(cart.total_discount, settings.moneyFormat)),
//Note: we added a comma after the previous line before adding this new one
shippingMessageHTML: cart.total_price < 3000 ? 'Want free shipping? It\'s only ' + Shopify.formatMoney(3000 - cart.total_price, settings.moneyFormat) + ' away!' : 'Yahoo! No pay-for-shipping for you!'
};
With that, when the data gets merged with your cart template, the most current cart total will be used in the calculation. As long as the variable you use inside the data object matches the name of the variable you set in the CartTemplate, you'll be good to go!
(If you're wondering what the difference between {{ variable }} and {{{ variable }}} is, the Handlebars template language interprets double-curly-braces as text and triple-curly-braces as HTML. So if you want to put a span or anything into your message, use triple braces. If your message will only ever be flat text, you can use either double or triple)

Liquid nesting For-Loop Syntax issue in Jekyll

First time posting, so thanks in advance for your time c:
I'm using Jekyll to serve a portfolio. I'm using a portfolio plugin as well as a JS library called Lightbox. I have the portfolio plugin working. The ideal action is that every time the user clicks a portfolio item, it executes the lightbox (that's working). In order to for more images to be stored in the lightbox, I must give them the same data-title name.
My understanding is that I need to nest a for-loop within my current loop, to check for all items within the array to return any additional lightbox items.
My .yml file reads like so:
title: Portfolio Title
description: A crazy portfolio item
bg-image: Test-01.png
lb-images:
- Test-01.png
- Test-02.png
- Test-03.png`
My .md file reads like so:
<div class="flex-container">
<!-- portfolio-item -->
{% assign projects = site.data.projects | get_projects_from_files | sort:'date' %}
{% for project in projects reversed %}
<div class="flex-item" style="background-image: url(/img/projects/{{ project.bg-image }}); background-repeat: no-repeat">
<a href="../images/projects/{{ project.lb-images[0] }}" data-lightbox="{{ project.title }}" data-title="{{ project.bg-image }}">
<div id="overlay">
<span id="reveal-text">
<h3>{{ project.title }}</h3>
<p>{{ project.description }}</p>
<p>{{ project.category }}</p>
</span>
</div>
</a>
</div>
{% for project in projects %}
{% endfor %}
{% endfor %}
</div>
I assumed that the forloop.index would begin at [1] and then continue through that array until there are no more lb-images. But something's up. My guess is syntax or how I'm calling the data from the .yml file, or both.
Again thanks for your time.
Daniel
(edit: took out space in nested endfor loop, runs now but returns: href="../images/projects/] }}" and data-title and data-lightbox returns are for each data.project file instead of for each item in data.project.lb-images)
Correct loop to expose images for a project is:
{% assign projects = site.data.projects | get_projects_from_files | sort:'date' %}
<div class="flex-container">
{% for project in projects reversed %}
<!-- portfolio-item -->
<div class="flex-item" style="background-image: url(/img/projects/{{ project.bg-image }}); background-repeat: no-repeat">
<a href="../images/projects/{{ project.lb-images[0] }}" data-lightbox="{{ project.title }}" data-title="{{ project.bg-image }}">
<div id="overlay">
<span id="reveal-text">
<h3>{{ project.title }}</h3>
<p>{{ project.description }}</p>
<p>{{ project.category }}</p>
</span>
</div>
</a>
</div>
{% for img in project.lb-images %}
{% if forloop.first != true %}
{% endif %}
{% endfor %}
{% endfor %}
</div>
Liquid forloop documentation

AJAX handler not called

Trying to create a component under October CMS which create a ToDo list (Look at this video). Adding an item works fine but now I'm trying to set up and Ajax handler to delete one element when a button is clicked.
Thi is the html code:
<form>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Tasks assigned to: {{ __SELF__.name }}</h3>
</div>
<div class="panel-body">
<div class="input-group">
<input name="task" type="text" id="inputItem" class="form-control" value="" \>
<span class="input-group-btn">
<button type="submit" class="btn btn-primary"
data-request="{{ __SELF__ }}::onAddItem"
data-request-success="$('#inputItem').val('')"
data-request-update="'{{ __SELF__ }}::tasks': '#result'"
>Add</button>
</span>
</div>
<ul class="list-group" id="result">
{% partial __SELF__ ~ '::tasks' tasks=__SELF__.tasks removeId=__SELF__.removeId %}
</ul>
</div>
</div>
<form>
and the code of the component (named tasks) that render the list of tasks:
{% if tasks|length > 0 %}
{% for i in 0..tasks|length-1 %}
<li class="list-group-item">
{{ tasks[i] }}
<button class="close pull-right"
data request="{{ __SELF__ }}::onRemoveItem"
data-request-success="console.log(data)"
>
×
</button>
</li>
{% endfor %}
{% endif %}
Lastly the code of the handler (don't do so much):
public function onRemoveItem()
{
return [
'Name' => 'Federico';
];
}
Now, I set up the handler onRemoveItem putting its data-request in a button and, as explained on this page, clicking the button should start the handler's execution but this don't happen, while all works correctly in the Add button that insert the tasks in the database.
Can someone explain me what I'm doing wrong?
(In case someone want to see the page the link is http://afterlife.ddns.net/
EDIT:
Solved, I had to link the framework js in the layout file

Resources