Kendo TabStrip for MVC not hiding tab content properly - javascript

I have Telerik Kendo TabStrip on my page with the following markup:
#(Html.Kendo().TabStrip().Name("FilterTabs")
.Animation(a =>
{
a.Enable(true);
a.Open(c =>
{
c.Expand(ExpandDirection.Vertical);
c.Fade(FadeDirection.In);
c.Duration(400);
});
a.Close(c =>
{
c.Reverse(true);
});
})
.Items(t => t.Add().Text("Simple Filter").Selected(true)
.ContentHtmlAttributes(new { #class = "edit-pool-tab", #style = "min-height: 100px;" })
.Content(#<partial name="_FilterSimple" for="#Model" />))
.Items(t => t.Add().Text("Extended Filter")
.ContentHtmlAttributes(new { #class = "edit-pool-tab", #style = "min-height: 100px;" })
.Content(#<partial name="_FilterExtended" for="#Model" />))
)
It behaves incorrectly in the following ways:
When the page is loaded, the content of tab 1 (simple filter) are shown (which is correct) but both tab headers have the unselected look.
If I click on tab 2, the tab 2 header will get the selected look, but both contents of tab 1 and tab 2 are shown.
Only after I click back on tab 1, and then back on tab 2, will I get the correct behavior - contents of tab 2 disappear, and then if I click on tab 2 again contents of tab 1 disappear. If I click on tab 1 first after the page loads, I get the correct behavior.
Any idea what's causing this and how to fix it?
EDIT: I was suspecting this might be caused by the animation setings, so I removed the whole Animation section. It didn't help.

Apparently the .Selected(true) part is wonky, but the following workaround did the trick:
jQuery(document).ready(function () {
var tabstrip = $("#FilterTabs").kendoTabStrip().data("kendoTabStrip");
tabstrip.select(0);
}
);

Related

page back button not resetting css

I have a button that "navigates" to a new page.
To do this the button makes the current section's/page's display settings = none and the new section/page's display = block.
<div class="listLeft"><p class="listItems" onclick="navButtons('work')">work</p><p class="listItems" onclick="navButtons('about')">about</p></div>
<div class="listRight"><p class="listItems" onclick="navButtons('playground')">playground</p><p class="listItems" onclick="navButtons('contact')">contact</p></div>
js below
function navButtons(page) {
let section = document.getElementById(page);
section.setAttribute("class", "visible");
window.location.href = `#${page}page`;
window.scrollTo(0, document.body.scrollHeight);
let pagesArrayCopy = [...pagesArray]
const unselected = pagesArrayCopy.filter(item => item.id !== page);
setTimeout(() => {
unselected.forEach((el, index) => unselected[index].setAttribute("class", "invisible"));
pagesArray = Array.from(pagesNodeList);
}, 500);
};
when I press the back button the url is obviously changing back to the old #section, but the css doesn't reset, so the new page is still visible and the previous page is still display = none.
How do i get around this, so when the back button is pressed the css values reset to default?
Try to use an anchor tag so your URL actually change (ie: update the adress to mypage.html#page2).
Then you could bind a function to onhashchange and check of your page is well displayed.
you haven't supplied all the html. there's no id work so section is null
function navButtons(page) {
let section = document.getElementById(page);
console.log(section)
section.setAttribute("class", "visible");
window.location.href = `#${page}page`;
window.scrollTo(0, document.body.scrollHeight);
let pagesArrayCopy = [...pagesArray]
const unselected = pagesArrayCopy.filter(item => item.id !== page);
setTimeout(() => {
unselected.forEach((el, index) => unselected[index].setAttribute("class", "invisible"));
pagesArray = Array.from(pagesNodeList);
}, 500);
};
<div class="listLeft">
<p class="listItems" onclick="navButtons('work')">work</p>
<p class="listItems" onclick="navButtons('about')">about</p></div>
<div class="listRight">
<p class="listItems" onclick="navButtons('playground')">playground</p>
<p class="listItems" onclick="navButtons('contact')">contact</p></div>
Another way to do this is to bind your changing state to the history of the browser. Since there is no real way of overriding the 'back' button on the browser, you will have to write it into your history. See the History API for HTML5 here:
https://css-tricks.com/using-the-html5-history-api/
The same thing specified above can also be done with this plugin:
https://code.google.com/archive/p/reallysimplehistory/

How to select all tabs to the right of current tab?

If you right click on any tab at the top of Chrome browser, you will see an option called Close tabs to the right. This closes all tabs to the right of the current active tab. I'm trying to do something similar with a Chrome extension. Can the tabs to the right be selected using a loop like "for index of current active tab until index of last tab?"
Following is the source code of an open source Chrome extension. The function selects all tabs in the current window except for the active tab and "suspends" them. I am trying to write a similar function but instead of all tabs, it needs to select only the tabs to the right of the active tab.
function suspendAllTabs(force) {
const forceLevel = force ? 1 : 2;
getCurrentlyActiveTab(activeTab => {
if (!activeTab) {
gsUtils.warning(
'background',
'Could not determine currently active window.'
);
return;
}
chrome.windows.get(activeTab.windowId, { populate: true }, curWindow => {
for (const tab of curWindow.tabs) {
if (!tab.active) {
gsTabSuspendManager.queueTabForSuspension(tab, forceLevel);
}
}
});
});
Each tab has an index which shows its position. For example, the 3rd tab will have an index of 2 (starts from 0).
Therefore, tab to the right of the any tab means tab.index +1 to tabs.length
For example ...
Getting the tabs to the right of the active tab
// get all the tabs in current window
chrome.tabs.query({currentWindow: true}, tabs => {
let activeIndex;
for (const tab of tabs) {
// set the activeIndex so we wont have to run a loop on the tabs twice
if (tab.active) { activeIndex = tab.index; }
// tabs to the right of the active tab will have higher index
if(typeof activeIndex !== 'undefined' && tab.index > activeIndex) {
// tabs is on the right of the active tab ... do whatever needed
}
}
});
Getting the tabs to the left of the active tab
// get all the tabs in current window
chrome.tabs.query({currentWindow: true}, tabs => {
for (const tab of tabs) {
// stop when reached the active tab
if (tab.active) { break; }
// tabs to the left of the active tab ... do whatever needed
}
});
Another option which can be useful in many situations and is very intuitive is to use filtering to get your new tabs.
Adding to #erosman’s answer. When you get the tabs you can:
// All to right of current
tabs = tabs.filter((x)=> x.index > activeTab.index);
// All to left of current
tabs = tabs.filter((x)=> x.index < activeTab.index);
// Do whatever with the new tabs.
Similar approach can be taken to get any tab as long as the condition in the filter is met!

MVC DropDownListFor gets disabled after the first selection and post request

We have an old ASPNET MVC application designed using Kendo(v4.0.30319). In the view I am using DropDownListFor to populate a list of items. The way the webpage works is after selecting an item from dropdown, there will be an ajax call to load data into grid.
My problem is when the page gets loaded for first time, dropdown is populated and I am able to select the item and load the grid. But, once it's loaded the dropdown is inactive/disabled and I am not able to select any other item.
Here is the snap of webpage
Here is the code block from my view:
<div class="col-sm-9 col-md-8 col-lg-9">
#Html.DropDownListFor(model => model.company_id, new System.Web.Mvc.SelectList(Model.CompanyList, "company_id", "company_name"), new { #class = "form-control", #id = "ddlCompany" })
</div>
The script block is:
$(document).ready(function () {
$('#ddlCompany').change(function () {
$("#CompanyConnectorPropertyGrid").data("kendoGrid").dataSource.read({ "companyConnectorID": 0 });
$('#dvGrid').hide();
$('#dvMessage').html('');
if ($('#ddlCompany').val()) {
BindConnectorDropdown();
}
else {
$('#dvGrid').hide();
}
});
$('#ddlConnector').change(function () {
$('#dvMessage').html('');
if ($('#ddlConnector').val() && $('#ddlConnector').val() > 0) {
$("#CompanyConnectorPropertyGrid").data("kendoGrid").dataSource.read({ "companyConnectorID": $('#ddlConnector').val() });
$('#dvGrid').show();
}
else {
$('#dvGrid').hide();
}
});
var connectorID = getParameterByName('cid');
if (connectorID) {
$("#ddlConnector").val(connectorID);
$('#ddlConnector').trigger('change');
}
});
There is nowhere it's mentioned to disable the dropdown.
I want the dropdown to be active so that I can select a diffrent item , bind it and get data. Any help to solve the problem would be appreciated. Thanks in advance.

Bookmarklet to simulate button click in a Google service iframe

The goal is to add keyboard shortcuts to Google's Google Translator Toolkit. Most functions there have keyboard shortcuts, but these two don't.
The first function is called Merge Down. It fires correctly when this bookmarklet is executed:
javascript:document.evaluate("//div[(#id='gtc-merge-arent')]/div[(#class='modal-dialog
gtc-merge')]/div[(#class='modal-dialog-buttons')]/button[(text()='OK')]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE,
null).singleNodeValue.click();
The Apply to All function is trickier. Normally you have to click three times to execute this function:
#1 to click the button that makes visible the Repetitions dialog and sets the parameters: what to replace what with.
#2 to click 'Apply to all' and trigger the actual replacement throughout
#3 to hide the dialog element.
I don't want to mess with Google's internal code, so a normal click as if by mouse would be best.
#2 and #3 fire easily enough: same bookmarklet, with a pause:
javascript:(function(pause) {
document.evaluate("//div[(#id='fnrDialogParent')]/div[(#class='modal-dialog gtc-rep-modal-dialog')]/div[(#class='modal-dialog-buttons')]/button[(text()='Apply to all')]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click();
setTimeout(() => document.evaluate("//div[(#id='fnrDialogParent')]/div[(#class='modal-dialog gtc-rep-modal-dialog')]/div[(#class='modal-dialog-buttons')]/button[(text()='Exit')]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click(), pause)
})(400);
I can't simulate a click on the Repetitions button, which is supposed to pop up with the two buttons I need to click to finish the job. The button itself is a div with an img inside an iframe. I tried most of the methods I found here for click simulation, the latest being this one, but it doesn't work all the same (the references are taken correctly)
var ifrm = document.querySelectorAll('iframe')[2];<br>
$(ifrm).contents().find('img.jfk-button-img.gtc-img-rep').click();
(The button itself is a div with an img inside. Depending on whether a segment repeats elsewhere or not, the button is either -enabled or -disabled. Here's the HTML code for an enabled button:
<div role="button" class="goog-inline-block jfk-button jfk-button-standard jfk-button-narrow jfk-button-collapse-left jfk-button-collapse-right jfk-button-clear-outline" tabindex="0" id="goog-gtc-repbutton" aria-label="Repeated: 3" data-tooltip="Repeated: 3" style="user-select: none;"><img src="./images/cleardot.gif" class="jfk-button-img gtc-img-rep" style="width: 21px; height: 21px;"></div>
javascript: (function() {
const a = f => new MouseEvent(f, { bubbles: !0 }),
b = f => () => document.querySelector(f).click(),
c = f => `#fnrDialogParent .gtc-rep-modal-dialog .modal-dialog-buttons button[name=${f}]`,
d = { imgSel: (f => () => {
const g = a('mousedown'),
h = a('mouseup'),
i = document.querySelector(f);
i.dispatchEvent(g), i.dispatchEvent(h) })('img.jfk-button-img.gtc-img-rep'), applyToAll: b(c('repDialogReplaceAll')), exit: b(c('repDialogExit')) };
d.imgSel(), d.applyToAll(), d.exit() })();
This is the bookmarklet that answers my question and does the 3 clicks. This answer tipped me off.

Extjs 5.1 Dynamic addition of container to panel

What i am trying to do is dynamically add container to panel on click of button.
1st instance of container gets added and can be seen in the panel.items.length
2nd instance onwards the panel.items.length doesn't change. but the panel can be seen in dom and on screen.
Just wanted to know why the panel.items.length is not increasing. Is it a bug?
Fiddler link https://fiddle.sencha.com/#fiddle/p3u
Check for the line :
console.log(qitems);
below debugger; it is set to questionsblock.items.length that i am talking about.
Remove the itemId from QuestionTemplate and remove renderTo from the new instance.
Your click handler should look like this:
listeners: {
'click': function(button) {
var questionPanel = button.up('form').down('#questionsblock'),
qitems = questionPanel.items.length,
questiontemplate = Ext.create('QuestionTemplate', {
qid: qitems,
questiontype: 'text'
});
console.log(qitems);
questionPanel.add(questiontemplate);
questionPanel.doLayout();
}
}
Check this fiddle: https://fiddle.sencha.com/#fiddle/p47

Categories