JQuery Steps: how to disable a step? - jquery-steps

I am using JQuery Steps, which has been excellent. But some things are proving tricky.
Suppose I am on step 2. Depending on what is selected in my form, I might want to skip directly to step 4 when "next" is clicked, and further, disable the step 3 anchor altogether. The step 3 anchor should still appear in the steps list, it should just be grayed out and disabled.
I cannot seem to get this to work. Any advice from the JQuery Steps gurus?
I have tried several variants of the following in onStepChanged:
if ($('#option').val() == 'foo') {
$('#wizard-t-3').attr('disabled', true);
$('#wizard-t-3').addClass('disabled');
} else {
$('#wizard-t-3').attr('disabled', false);
$('#wizard-t-3').removeClass('disabled');
}
if (currentIndex == 2) {
$(this).steps('next');
}
And applied what I thought was appropriate CSS:
.wizard>.steps a .disabled,.wizard>.steps a:hover .disabled,.wizard>.steps a:active .disabled,.wizard>.steps a:visited .disabled {
color: #777;
cursor: default
}
But it doesn't seem to do the trick. And it's not just the CSS that doesn't seem to work, the step still seems to be enabled. Everything looks right in the Chrome debugger, but it's not working right. I am obviously confused.

I realize this is sort of an old question, but here's what I did to remedy this.
Add the following to jquery.steps.js:
$.fn.steps.incomplete = function (i) {
var wizard = this,
options = getOptions(this),
state = getState(this);
if (i < state.stepCount) {
var stepAnchor = getStepAnchor(wizard, i);
stepAnchor.parent().addClass("disabled");
stepAnchor.parent().removeClass("done")._enableAria(false);
refreshSteps(wizard, options, state, i);
}
};
...and then call it by using this:
$("#yourWizard").steps('incomplete', stepNumber);
Hope this helps.

Related

How to get className to work with dynamic input from map()

Trying to render some buttons dynamically, cant get the styling to work.
I have my btnList -
const btnList= [
"FirsBtn",
"SecondBtn",
"ThirdBtn",
"ForthBtn",
"FifthBtn",
"SixthBtn",
];
I have my map function -
const RenderBtns = (btnList) => {
return btnList.map((btn) => {
return (
<button className={`classes.${btn}`} name={btn} onClick={onClickHandler}>{btn}</button>
);
});
};
And, I have my btn.module.css, with
.FirstBtn {background-color: #662626;}
.SecondBtn {background-color: #b0bf76;}
.ThirdBtn {background-color: #6b8327;}
.ForthBtn {background-color: #6a5938;}
.FifthBtn {background-color: #b0bf76;}
.SixthBtn {background-color: #1fa593;}
The styling, doesn't work.
This - className={classes.FirstBtn} works.
This - className={`${classes.SecondBtn}`} works.
This - className={`${classes}.${btn}`} Doesn't.
The buttons themselves, the clicks, everything else - works.
I went through all of the combinations, and I can't seem to get it to work.
Even though I get the main idea behind literal, and object,
at this point I'm just beat-up.
I want to get the className to accept the dynamic "btn"
any way to make it happen?
Help, Please, and thank you.
Almost gave up on google, and than I stumbled upon this
Answer
It was actually the second one that worked for me,
but n one the less - it worked.
className={classes[`${item}Btn`]}

Ask to confirm when changing tabs in angular bootstrap

I have tabs with forms and I want ask the user to confirm or discard their changes when changing tabs. My current code works
<uib-tab heading="..." index="3" deselect="main.onDeselect($event)" ... >
this.onDeselect = function($event) {
if(...isDirty...) {
if($window.confirm("Do you want to discard?")) {
... discard (and go to new tab) ...
} else {
$event.preventDefault(); //stays on current tab
}
}
}
The problem is I want to change confirm to javascript dialog and I will get result in callback.
I planed to preventDefault() all and then switch manually, but I cannot figure out where to get new tab id.
Any solution is appreciated. Even if it is easier in other tab implementations.
I use AngularJS v1.4.7, ui-bootstrap-tpls-1.3.3.min.js
You can make use of $selectedIndex and the active property for that purpose. See this Plunk
One thing to be noted here is that when we manually change the active property, it again fires the deselect event which needed to be handled. Otherwise it seems to do what you wanted.
Edit
Indeed as noted in the comments, the deselect carries the HTML index rather than what is passed in in the tab index property. A workaround could be in this: Another Plunk. Here I'm pulling the actual index from the HTML index.
And a little research indicates that this issue might as well be fixed already with 3.0 bootstrap tpl See this.
I spent some time with different approaches and this one is stable for some time. What I do is to prevent deselect at the beginning and set the new tab in callback if confirmed to loose changes...
this.onDeselect = function($event, $selectedIndex) {
var me = this;
if(this.tabs.eventDirty || this.tabs.locationDirty || this.tabs.contractDirty) {
$event.preventDefault();
var alert = $mdDialog.confirm({
title: 'Upozornění',
textContent: 'Na záložce jsou neuložené změny. Přejete si tyto změny zrušit a přejít na novou záložku?',
ok: 'Přijít o změny',
cancel: 'Zůstat na záložce'
});
$mdDialog
.show( alert )
.then(function() {
$rootScope.$emit("discardChanges");
me.tabs.activeTab = $selectedIndex;
})
}
};

How to use gridfilters Plugin AND programmatically clear/set the filters?

In my app (ExtJS 5.0.1) I'm trying to use a grid with the gridfilters Plugin AND shortcut buttons (and also from a tree) with custom/hardcoded fiters.
I was able to partially mimic the set and clear of the filters, but I'm having the following problems:
1- When I set a filter via grid.filters.store.addFilter(..) the style of the column title doesn't change to bold, and the grid filter checkbox stays unchecked.
2- Same as 1 but reversed... first I set the filter on the column, when I clear the filter the column stays bold, but in this case the checkbox is cleared (as it should).
3- When I'm using summary feature 'sometimes' the total is not updated
So, my question is:
Is there a proper way to programmatically set/clear filters mimicking the gridfilter Plugin ?
I've put a minimal Fiddle to simulate this.
https://fiddle.sencha.com/#fiddle/akh
Best Regards,
Ricardo Seixas
Just use filter instance on column:
var column = grid.columnManager.getColumns()[0];
column.filter.setValue('J');
column.filter.enable();
Working sample: http://jsfiddle.net/3be0s3d8/7/
For List Filters use the following override to enable the setValue method:
//Enable setting filter values in list filters
Ext.define('Ext.ux.fixed.ListFilter', {
override: 'Ext.grid.filters.filter.List',
setValue: function(values) {
var me = this, len = values.length;
if(!values) {
me.callParent();
return;
}
if(!me.menu){
me.createMenu();
}
me.filter.setValue(values);
if (len && me.active) {
me.updateStoreFilter(me.filter);
} else {
me.setActive(!!len);
}
}
});
You can directly change the styles in the GridFilter.css file :
<link rel="stylesheet" type="text/css" href="js/lib/ext-4.2.1.883/ux/grid/css/GridFilters.css" />
By changing this element :
.ux-filtered-column {
font-style: italic;
font-weight: bold;
background: #56b8ff;
}
Hope this helps.
In the latest release (5.1) Ext's ChainedStore worked well for me.

Filtering spcific with checkboxes

My question is that I want a filtering system that will filter by checked checkboxes.
The tool is to my comparison website where I compare TV packages.
my visitors should filter the packages by the tv-channels they want to se.
example;
Checkbox 1: Discovery
Checkbox 2: Animal PLanet
Checkbox 3: Disney Channel
Output should be the matching TV-package
Package 1: (contains Discovery and Disney channel)
Package 2: (contains Animal Planet, Disney channel)
Package 3: (contains Animal Planet)
So if checkbox 1 is checked it should only show package 1.
if checkbox 1 + checkbox 2 is checked it should say "No match found, but this package was was closest to your choice"
if checkbox 2 + checkbox 3 is checked it should only show package 2 which match the visitors choice exactly.
I hope your can help me out. I have been searching a lot after this specific solution without any success.
I think it should be in Jquery. i have seen some simular filtering examples, but no one there are like my wish above.
This is an old question, but... I'll take a shot. Working jsfiddle: http://jsfiddle.net/a0nnrfua/
I think a lot really depends on how you intend to define "closest", but presuming a jQuery solution and hopefully your browser requirements aren't TOO far in the past, you could use the data- attributes and jQuery to come up with some relatively simple functions. Or even use the value portions of the checkboxes really.
Psuedocode, it would look like:
Define a click or change handler to detect whenever a checkbox has been touched/changed.
Define a function that will scan all checked items and pass the values into your "closest package" function.
Based on the results of that function, filter your package selection so that your choices are highlighted or marked in some way.
So let's presume the following HTML markup:
<h3>TV Channels</h3>
<div id="TVChannelSelections">
<input type="checkbox" class="tvchannel" name="tvchannel" id="tvchannel_Discovery" value="Discovery" />
<label for="tvchannel_Discovery">Discovery Channel</label>
<br/>
<input type="checkbox" class="tvchannel" name="tvchannel" id="tvchannel_AnimalPlanet" value="Animal Planet" />
<label for="tvchannel_AnimalPlanet">Animal Planet</label>
<br/>
<input type="checkbox" class="tvchannel" name="tvchannel" id="tvchannel_DisneyChannel" value="Disney Channel" />
<label for="tvchannel_Disney">Disney Channel</label>
<br/>
</div>
<div id="message"></div>
<h3>Packages</h3>
<div id="FilteredPackages">
<div class="package deselected" id="Package1" data-channels="Discovery,Disney Channel">Package #1</div>
<div class="package deselected" id="Package2" data-channels="Animal Planet,Disney Channel">Package #2</div>
<div class="package deselected" id="Package3" data-channels="Animal Planet">Package #3</div>
</div>
So in jQuery, your generic change or click handler would be defined in code: Note that I'm saying, any element on your page that has the class "tvchannel" defined, if there's ever a change that occurs, run my filter function.
<script type="text/javascript" src="../path/to/jQuery/library"></script>
<script type="text/javascript">
$(document).ready(function() {
$(".tvchannel").on("change", function() {
FilterMySelectedChannels();
});
});
</script>
Now we can define your Filter function. We're going to assume two things. #1, that we want to find all the selected checkboxes and their values. Then we're going to iterate through the data-channels property of all of our packages (defined as elements with class = "package"). We'll use some form of string comparison and boolean logic to define what a complete match is vs. a close but no cigar match vs. a complete fail.
In order to keep track of things I'm using 3 classes, selected, deselected, and close.
In css, you can decide whether you want notselected to mean "hide the package completely" (i.e. display: none;) or maybe you want it to be visible but greyed out and "struck out" (i.e. text-decoration: strikethrough; color: grey;}
I'm going to use kind of a brute force way of doing the comparison. There are better array functions and comparison functions in javascript, but this should be relatively clear for most people and I trust the good folks at stackoverflow to chime in with better solutions. But this should get you started. :)
<script type="text/javascript">
function FilterMySelectedChannels() {
$checkedboxes = $(".tvchannel:checked");
$packages = $(".package");
var bAnyFound = false;
$packages.each(function () {
var bCloseButNoCigar = false;
var bCompleteMatch = true;
var packagearray = $(this).data("channels").split(",");
var $currentPackage = $(this);
$checkedboxes.each(function () {
if ($.inArray($(this).val(), packagearray) != -1) {
bCloseButNoCigar = true;
} else {
bCompleteMatch = false;
}
});
if (bCompleteMatch) {
$currentPackage.removeClass("selected").removeClass("deselected").removeClass("close").addClass("selected");
bAnyFound = true;
} else if (bCloseButNoCigar) {
$currentPackage.removeClass("selected").removeClass("deselected").removeClass("close").addClass("close");
} else {
$currentPackage.removeClass("selected").removeClass("deselected").removeClass("close").addClass("deselected");
}
});
if (bAnyFound) {
$("#message").html("The following matches were found");
} else {
$("#message").html("No actual matches were found, but here are some close matches based on your selections");
$(".package.close").removeClass("deselected").removeClass("close").removeClass("selected").addClass("selected");
}
}
</script>
<style type="text/css">
.selected {
color: red;
background-color: yellow !important;
}
.deselected {
color: grey;
text-decoration: strike-through !important;
background-color: white !important;
}
</style>
There are obvious optimizations that could probably work here, but it's a start for those trying to do something similar. Note that it assumes that your markup is dynamically generated or properly coded. If you need to guard against human typos, converting your text using .toLowerCase/UpperCase and using the .Trim functions to eliminate extra space will assist. But you still have to choose your data values wisely so there's no overlap. And if you choose them well enough you can use better techniques such as regular expressions and wildcard searches to make the code a bit shorter.
Hope this helps someone!

How to go to first page after(before) sorting in extJs grid

I have extJs 4.1 grid with paging. For this grid applied remoteSort(maybe remoting style of sorting doesn't matter) behaviour. After sort click(click on header) I wanna go to first page. How can I achive this? Maybe exists presort callback in what I can cancel loading data and forward loading to first page with store.loadPage(1)?
P.S. Sorry for english.
This code is part of the FiltersFeature.js file.
Take a look at how when to specify (local: false) it goes to first page automagically ;)
reload : function () {
var me = this,
store = me.view.getStore();
if (me.local) {
store.clearFilter(true);
store.filterBy(me.getRecordFilter());
store.sort();
} else {
me.deferredUpdate.cancel();
if (store.buffered) {
store.pageMap.clear();
}
store.loadPage(1);
}
}
What you have to do is configure the feature with local: false.

Resources