Swiper init script for mobile issue - javascript

I'm using Swiper 6.4.10 for a project. It's the first time I use Swiper.
This website has multiple sliders on 1 page. So I decided to create some initializing script. I'm using data-attributes to create the slider settings. Every slider has different setups. One of those settings is to run the slider only on a mobile device and destroy it on desktop or tablet.
I've read a whole lot of posts here and in Google but I just can't get it to work.
It is about this part:
if(container){
var initID = '#' + container;
if(mobile){
if(mobile_breakpoint.matches){
var init = new Swiper(this, settings)
} else if (!mobile_breakpoint.matches){
var init = this.swiper.destroy();
}
}
//var init = new Swiper(initID, settings)
}
When I use this code here above then all carousels are destroyed OR I get an error saying this.swiper.destroy is undefined.
When I run my code like this:
if(container){
var initID = '#' + container;
var init = new Swiper(initID, settings)
}
Then all carousels just work. When I check for data attribute mobile and try to destroy the carousels then all stop working. I clearly miss something out.
Anybody have any idea what I do wrong? Any help greatly appreciated!

"Your mistake" under else if you forgot first to Initialize swiper instance .
This is why when you uncomment this block of code - the page is broken (error: this.swiper.destroy is undefined).
To destroy an instance you first should create this instance (destroy() is a Method of swiper instance).
const swiper = new Swiper('.swiper-container', {});
swiper.destroy();
Otherwise, your code is like writing:
bla_bla.destroy(); /* Uncaught ReferenceError: bla_bla is not defined */
Create an instance (Missing in your code)
Destroy
else if (!mobile_breakpoint.matches){
var init = new Swiper(this, settings) /* missing in your code */
init = this.swiper.destroy();
}
In general - your code is very long ==> next time create a Minimal, Reproducible Example (A lot of code not related to your issue/error).

Related

Javascript swiper.js Object not loading/initializing correctly (only sometimes)

I'm trying to fix the issue on a mobile website where I'm using swiper.js, but it doesn't always load correctly, which I find odd, because I have to refresh the website a couple of times and then it loads and works as expected.
Here is the whole script I'm trying to work with
let $;
const swiperSelector = '#dog-swiper-carousel .swiper-container';
let swiperRef;
let swiperId;
let slide1, slide2, slide3;
let slides;
let carousel;
window.addEventListener('load', function() {
$ = jQuery;
swiperRef = $(swiperSelector).data('swiper');
swiperRef.params.allowTouchMove = false;
swiperRef.params.noSwiping = true;
swiperRef.params.noSwipingClass = 'swiper-slide';
swiperRef.params.grabCursor = false;
swiperRef.params.navigation.nextEl = '.js-next1';
swiperRef.params.navigation.prevEl = '.js-prev1';
swiperId = document.getElementById('swiper-slide-index').children[0].children[0];
slide1 = document.getElementById('js-slide1').children[0].children[0].children[0];
slide2 = document.getElementById('js-slide2').children[0].children[0].children[0];
slide3 = document.getElementById('js-slide3').children[0].children[0].children[0];
slides = document.querySelectorAll('.mobile-card');
//Then here are a bunch of functions that take care of the navigation and perform actions on these variables
swiperRef.update();
});
I've tried to rewrite code to be more focused on vanilla js, since jQuery isn't something I'm very experienced in. I've already changed the event on window/document load from DOMContentLoaded to load, so all css styles, html elements and content can load first, before I start executing my code. However I couldn't find any issues in the code itself. I'm even creating variables and then waiting for the whole page to load before I assign values to them.
However the error I'm getting everytime I'm on the page is
Uncaught TypeError: Cannot read properties of undefined (reading 'params') at HTMLDocument.<anonymous>
And then it points to the line
swiperRef.params.allowTouchMove = false;
The problem is present only on mobile device (iPhone 12 and google chrome browser as well as safari browser). I haven't tired any other mobile devices, because I have none.

Adding slider to demo application

I am trying to add a slider to one of the demo applications. I added a slider to the home-fragment.xml by adding
<Slider value="{{ slider }}" horizontalAlignment="center" width="80%"/>
Now I want to be able to edit and read data from this slider from my viewmodel. According to the slider documentation I need to import the slider and then create it. My code now looks like this:
import { Slider } from "tns-core-modules/ui/slider";
const observableModule = require("data/observable");
const slider = new Slider();
function HomeViewModel() {
const viewModel = observableModule.fromObject({
});
slider.value = 0;
return viewModel;
}
module.exports = HomeViewModel;
Visual Studio Code does not show any errors but once I launch the app I get the following error:
An uncaught Exception occurred on "main" thread.
java.lang.RuntimeException: Unable to start activity ComponentInfo{org.nativescript.app/com.tns.NativeScriptActivity}: com.tns.NativeScriptException:
Calling js method onCreate failed
Error: Building UI from XML. #file:///app/tabs/tabs-page.xml:30:13
> Unexpected token import
File: "file:///data/data/org.nativescript.app/files/app/tns_modules/tns-core-modules/ui/builder/builder.js, line: 208, column: 20
I am new to Nativescript and probably made a mistake in the architecture or setup. Can somebody help me out by showing me what goes wrong and how to fix it?
it could be a couple of things, but one thing is certain: you don't need to import that Slider component to set its value. You can simply bind to a property (slider = 20;).
The easiest way to start with NativeScript, and to learn how those UI widgets work, is by using the Playground. I've created a little project with a Slider for you to show how it works in "plain" NativeScript with TypeScript: https://play.nativescript.org/?template=play-tsc&id=I7SGei

HandsOnTable - destroy and re-create not working after upgrading from 0.11.0 to 0.15.0-beta 2

I have code like below:
HTML
<div id="rangePricesGrid" class="handsontable" style="width: auto; overflow: auto"></div>
Javascript:
var rangePriceGrid = $('#rangePricesGrid').handsontable('getInstance');
if (rangePriceGrid != undefined) {
rangePriceGrid.destroy();
if (setRangeGridOptions != undefined)
rangePriceGrid = $('#rangePricesGrid').handsontable(setRangeGridOptions);
} else {
if (setRangeGridOptions != undefined)
rangePriceGrid = $('#rangePricesGrid').handsontable(setRangeGridOptions);
}
On page load, it works fine and paints the HOT. But then when I update one of the properties (say Data, and number of columns also) of HOT and then calls above method, it fails at the below
rangePriceGrid = $('#rangePricesGrid').handsontable(setRangeGridOptions);
with error
Uncaught Error: This method cannot be called because this Handsontable instance has been destroyed
What am I doing wrong here ? I know the HOT table is destoryed, but I am trying to re-created it with updated options.
Please suggest
I think you understand that you're destroying the instance but you don't understand how to recreate the instance. To start it would be useful to see setRangeGridOptions and maybe also a jsfiddle. If you're instantiating handsontable using the jQuerySelector.handsontable(options) method, it may be the cause of your problems.
Have you considered manually erasing the reference to the previous HOT instance so you don't have this problem? Try instantiating HOT this way:
var hot = new Handsontable($('#rangePricesGrid')[0], setRangeGridOptions)
This way, you should be able to destroy the hot instance and your code should start working. To destroy the hot instance you would simply do:
hot.destroy()
And to recreate it, you reuse the line above.
You can do like this.
// incorrect
var rangePriceGrid = $('#rangePricesGrid').handsontable('getInstance');
rangePriceGrid.destroy();
// correct
$('#rangePricesGrid').destroy();

CKEditor New Instance always unloaded

I'm using CKEditor in my Angular app and have a view that reloads my CKEditor instance every time users access a new model.
I'm using the following JS to initialize the editor:
var initEditor = function() {
$('.js-editor-wrap').html("<textarea id='editor'></textarea>");
var editor = CKEDITOR.replace('editor', {});
editor.on('loaded', function() {
console.log('editor loaded');
});
editor.on('instanceReady', function() {
console.log('instance ready')
});
}
And the following to destroy the editor:
var destroyEditor = function() {
if (CKEDITOR.instances['editor']) {
CKEDITOR.instances['editor'].destroy(true);
$('#editor').off().remove();
}
}
The first editor initialization works just as expected, but subsequent initializations create an editor instance with a status of "unloaded" that never triggers the "loaded" or "instanceReady" events. I'm not seeing any errors in the console.
Any ideas what might be causing this?
This is definitely a similar issue to the following, but different enough that I think it warrants its own question: CKEditor instance already exists
After a LOT more digging and thanks to the jsfiddle from Jey Dwork, I figured out where the issue is here. My CKEditor config file adds a couple of plugins that referenced lang files that were improperly named. For some reason, when these plugins were included together they caused the editor to not fully load during a second initialization.
Removing the lang files and reference to them in the plugin definitions resolved the issue. It's too bad that there wasn't some error that was triggered around this. All's well that ends well though.

Trying to access toolbar button is nil

I have been working on writing some automation scripts for an app I am writing, and have been trying to get the following function to work. I was able to finally get it to complete correctly, but with some different code. The following two code snippets are the same, in my mind, but only the FIRST one seems to work. I would love some insight as to why. Is it my JavaScript skills (which are weak, at best), or something specific to UIAutomation?
// Define some global variables -- THIS WORKS
var target = UIATarget.localTarget();
var app = target.frontMostApp().mainWindow();
var toolbarButtons = app.toolbar().buttons();
toolbarButtons["Back"].tap();
This fails...
var target = UIATarget.localTarget();
var app = target.frontMostApp().mainWindow();
var backButton = app.toolbar().buttons()["Back"];
backButton.tap();
The second (failing) code snippet says that I'm getting a nil value for the button. If someone could help point out why this second approach isn't correct, I'd greatly appreciate it. I have to tap the back button a number of times, and backButton.tap() just seems cleaner.
UPDATE: Below is the exact code that is failing
// Define some global variables
var target = UIATarget.localTarget();
var app = target.frontMostApp().mainWindow();
// List everything we see
UIALogger.logStart("Logging app...");
app.logElementTree();
UIALogger.logPass();
// Function for moving into and out of every home screen option
var homeToViewAndBack = function() {
var backButton = app.toolbar().buttons()["Back"];
// Let's go down the list of buttons
app.buttons()["VideoHomeButton"].tap();
backButton.tap();
UIALogger.logPass("Basic navigation works.");
}
// Call our functions
homeToViewAndBack();
This give an error " Script threw an uncaught JavaScript error: Cannot perform action on invalid element: UIAElementNil from target.frontMostApp().mainWindow().toolbar().buttons()["Back"]". However, the code in the first snippet above works like a charm.
To confirm again, I changed the text on the back button to "Home" and tried the following code...the first call to the back button works, but the second fails:
var homeToViewAndBack = function() {
var toolbarButtons = app.toolbar().buttons();
var backButton = app.toolbar().buttons()["Home"];
// Let's go down the list of buttons
app.buttons()[0].tap();
toolbarButtons["Home"].tap();
app.buttons()[1].tap();
backButton.tap();
UIALogger.logPass("Basic navigation works.");
}

Categories

Resources