jQuery UI portlets - toggle portlets to save to a cookie (half way there!) - jquery-ui

I'm a bit of a jQuery n00b so please excuse me if this seems like a stupid question. I am creating a site using the jQuery UI more specifically the sortable portlets. I have been able store whether or not a portlet is has been open or closed to a cookie. This is done using the following code. The slider ID is currently where the controls are stored to turn each portlet on and off.
var cookie = $.cookie("hidden");
var hidden = cookie ? cookie.split("|").getUnique() : [];
var cookieExpires = 7; // cookie expires in 7 days, or set this as a date object to specify a date
// Remember content that was hidden
$.each( hidden, function(){
var pid = this; //parseInt(this,10);
$('#' + pid).hide();
$("#slider div[name='" + pid + "']").addClass('add');
})
// Add Click functionality
$("#slider div").click(function(){
$(this).toggleClass('add');
var el = $("div#" + $(this).attr('name'));
el.toggle();
updateCookie(el);
});
$('a.toggle').click(function(){
$(this).parents(".portlet").hide();
// *** Below line just needs to select the correct 'id' and insert as selector i.e ('#slider div#block-1') and then update cookie! ***
$('#slider div').addClass('add');
});
// Update the Cookie
function updateCookie(el){
var indx = el.attr('id');
var tmp = hidden.getUnique();
if (el.is(':hidden')) {
// add index of widget to hidden list
tmp.push(indx);
} else {
// remove element id from the list
tmp.splice( tmp.indexOf(indx) , 1);
}
hidden = tmp.getUnique();
$.cookie("hidden", hidden.join('|'), { expires: cookieExpires } );
}
})
// Return a unique array.
Array.prototype.getUnique = function() {
var o = new Object();
var i, e;
for (i = 0; e = this[i]; i++) {o[e] = 1};
var a = new Array();
for (e in o) {a.push (e)};
return a;
}
What I would like to do is also add a [x] into the corner of each portlet to give the user another way of hiding it but I'm unable to currently get this to store within the Cookie using the code above.
Can anyone give me a pointer of how I would do this?
Thanks in advance!
Gareth

Have you tried adding another selector to the click function?
$("#slider div, #slider div > span.ui-icon-x").click(function(){
$(this).toggleClass('add');
var el = $("div#" + $(this).attr('name'));
el.toggle();
updateCookie(el);
});

Related

Uncaught TypeError: Cannot read property 'Input' of undefined

I changed from OpenLayers v3.0.0 to 3.19.1 and now following line doesn't work:
var visible = new ol.dom.Input(document.getElementById('visible'));
Switching back to the older version, everything is ok. What's going wrong?
ol.dom.Input was removed in 3.5.0
The experimental ol.dom.Input component has been removed. If you need to synchronize the state of a dom Input element with an ol.Object, this can be accomplished using listeners for change events. For example, you might bind the state of a checkbox type input with a layer's visibility like this:
var layer = new ol.layer.Tile();
var checkbox = document.querySelector('#checkbox');
checkbox.addEventListener('change', function() {
var checked = this.checked;
if (checked !== layer.getVisible()) {
layer.setVisible(checked);
}
});
layer.on('change:visible', function() {
var visible = this.getVisible();
if (visible !== checkbox.checked) {
checkbox.checked = visible;
}
});

ValidationSummary hyperlink doesn't change tab

Im using devexpress Html.DevExpress().ValidationSummary in my mvc project. My form contains a devexpress page control with 3 tabs. When there are client-side validation errors validation summary shows them, and every error is hyperlink. If you click it, the field with error is focused, but if the field is on other tab nothing happens. So the field is focused if it is on active tab. I'd like it to change the active tab and focus appropriate field. Is there a way to make it work right?
My colleague solved this problem using javascript and jQuery:
var nameControlTab = "myPageControl"; //name of your pagecontrol here
$(document).ready(function () {
$("tbody").on('click', 'a[href*="javascript:_aspxVSOnErrorClick("]', function () {
var url = $(this).attr("href");
url = url.substring(url.indexOf("'") + 1);
url = url.substring(0, url.indexOf("'"));
var idTab = $("#" + url + "_ET").parents('div[id*="' + nameControlTab + '_C"]').not(nameControlTab + '_CC')[0].id;
var indexTab = idTab.substring((nameControlTab + '_C').length);
SetTab(indexTab);
return true;
});
});
function indexOf(array, value) {
if ([].indexOf)
return array.indexOf(value);
else {
for (var i = 0; i < array.length; i++)
if (array[i] == value)
return i;
return -1;
}
}
function SetTab(indexTab) {
this[nameControlTab].SetActiveTabIndex(indexTab);
}

Getting Property Values of Dropped Object in JQuery UI

I am (working with one of my students) using jqueryui getting the properties of a dropped object. The object that is being dropped is an image. All images are set to draggable through a single jquery call to draggable.
The challenge here is really getting any of the properties of the object being dropped on the drop target. the drop event handler works fine (I can easily alert on it) - but have not been able to get any of the properties of the objects being dropped.
This code is also available at http://jsfiddle.net/reaglin/FUvT8/4/
Note - the real action occurs when
(1) draggable() is called to make objects droppable
(2) The image is created and added to the document body
(3) The handleDropEvent is called.
This is a good example for working with playing cards - but this example uses Dr. Who characters.
$ (init);
function image(id, image1) {
this.id = id;
this.image1 = image1;
}
$('#deal').click(function () {dealAll(
dealCard(randomCard()));
});
$(function() {
$( "#draggable" ).draggable({ containment: "#left"});
});
function init() {
$('.drop').droppable( {
drop: handleDropEvent
} );
$("img").draggable();
}
// global variables
var cardsInDeck = new Array();
var numberOfCardsInDeck = 15;
cardsInDeck[0] = "Ace";
cardsInDeck[1] = "Grace";
cardsInDeck[2] = "Susan";
cardsInDeck[3] = "Ian";
cardsInDeck[4] = "Barbara";
cardsInDeck[5] = "Brigadier";
cardsInDeck[6] = "Romana I";
cardsInDeck[7] = "K9";
cardsInDeck[8] = "Tegan";
cardsInDeck[9] = "Jamie";
cardsInDeck[10] = "Sarah Jane";
cardsInDeck[11] = "Jo";
cardsInDeck[12] = "Romana II";
cardsInDeck[13] = "Yates";
cardsInDeck[14] = "Leela";
var cardsDealt = new Array();
// deal 5 cards at once - works
function dealAll(){
var z=0;
for (z=0;z<5;z++) {
cardsDealt[z] = new Image(z,dealCard(randomCard()));
}
}
//deal cards - works
function dealCard(i) {
if (numberOfCardsInDeck == 0) return false;
var $img = new Image();
$img.src = "http://debsiepalmer.com/images/companions/" + cardsInDeck[i] + ".jpg";
// Here I set the ID of the object
$img.id=cardsInDeck[i];
$img.class='drag';
$("img").draggable();
document.body.appendChild($img);
removeCard(i);
return $img;
}
// deal randomly - works
function randomCard() {
return Math.floor(Math.random() * numberOfCardsInDeck);
}
// remove spent cards from pool -works
function removeCard(c)
{
for (j=c; j <= numberOfCardsInDeck - 2; j++)
{
cardsInDeck[j] = cardsInDeck[j+1];
}
numberOfCardsInDeck--;
numberOfCardsInDeck--;
numberOfCardsInDeck--;
}
// this is what to do when card drops in tardis
function handleDropEvent( event, ui ) {
// Here I want the id of the dropped object
}
Researching a bit more on the documentation for jqueryui - provides these answers;
First when the image is declared draggable - this needs to be done after it is added to the document.body - this is because jquery selector uses the DOM to create the list of objects - so the lines
$("img").draggable();
document.body.appendChild($img);
would be changed to
document.body.appendChild($img);
$("img").draggable();
also in this example all images are declared to be draggable, we can be more specific however and just make the appended image to the document draggable.
document.body.appendChild($img);
$('#'+$img.id).draggable();
Once the image is made draggable - the properties of the object passed to the handleDropEvent are event and ui - the draggable property of the ui object is a jquery object which does have access to the attributes of the object it contains;
function handleDropEvent( event, ui ) {
alert(ui.draggable.attr("id"));
}

Google Script - Can't combine on the same script multiple selection from listBox and SubmitButton

I'm trying to code on google app and I've encountered one issue. For example, let's consider this example code on google website ( link's here https://developers.google.com/apps-script/class_formpanel )
function doGet() {
var app = UiApp.createApplication();
var form = app.createFormPanel();
var flow = app.createFlowPanel();
flow.add(app.createTextBox().setName("textBox"));
flow.add(app.createListBox().setName("listBox").addItem("option 1").addItem("option 2"));
flow.add(app.createSubmitButton("Submit"));
form.add(flow);
app.add(form);
return app;
}
function doPost(eventInfo) {
var app = UiApp.getActiveApplication();
app.add(app.createLabel("Form submitted. The text box's value was '" +
eventInfo.parameter.textBox +
"' and the list box's value was '" +
eventInfo.parameter.listBox + "'"));
return app;
}
My issue is that I want to select multiple values on the listbox. I change then line 6 in
flow.add(app.createListBox(true).setName("listBox").addItem("option 1").addItem("option 2"));
to allow multiple selection. But the result is that only the last selected value is taken, preventing multiple selections. Apparently, it is due to the submitButton. I need to keep the formPanel because on a further code I'll like to combine uploading files and listBox multiple selection. How may I fix that? Thank you a lot
As a complement to Mogsdad's answer, note that this bug / issue is only concerning the doPost structured handler... if you don't need the file upload feature you could use a simple doGet + handler with callbackElement and in this case the multiselect list is available and works as expected.
test function :
function doGet() {
var app = UiApp.createApplication().setTitle('test listBox');
var panel = app.createHorizontalPanel().setStyleAttribute('padding','40px');
var sHdlr = app.createServerHandler('validateList').addCallbackElement(panel);
var items = ['category 1','category 2','category 3'];
var list1 = app.createListBox(true).setName('list1');
for(var i =0;i<items.length;++i){list1.addItem(items[i],i)}
panel.add(list1).add(app.createButton('validate',sHdlr));
app.add(panel);
return app;
}
function validateList(e){
var app = UiApp.getActiveApplication();
app.add(app.createLabel("Value(s) in list : "+e.parameter.list1).setStyleAttribute('margin-left','40'));
return app;
}
and below is a working example of the workaround described in the issue tracker.
I used a textBox to show the process, set it to visible(false) or use a hidden widget in a 'real' app. ( Test available here )
function doGet() {
var app = UiApp.createApplication().setTitle('test listBox');
var panel = app.createHorizontalPanel().setStyleAttribute('padding','40px');
var listHandler = app.createServerHandler('updlistVal').addCallbackElement(panel);
var items = ['category 1','category 2','category 3'];
var list1 = app.createListBox(true).setName('list1').addChangeHandler(listHandler);
for(var i =0;i<items.length;++i){list1.addItem(items[i])}
panel.add(list1).add(app.createTextBox().setText(items[0]).setId('listboxVal').setName('listboxVal').setWidth('200'));// set a default value in case the user is happy with that and doesn't touch the listBox
var submitBtn = app.createSubmitButton('test').setStyleAttribute('margin-left','40');
app.add(app.createFormPanel().add(panel.add(submitBtn)));
return app;
}
function doPost(e){
var app = UiApp.getActiveApplication();
app.add(app.createLabel().setStyleAttribute('padding','40').setText("Submitted value(s) from list : "+e.parameter.listboxVal));
return app;
}
function updlistVal(e){
var app = UiApp.getActiveApplication();
app.getElementById('listboxVal').setValue(e.parameter.list1);
return app;
}
EDIT 2 :
As Mentioned in the comments on this post we must find a way to prevent going through the submission before the value of the hidden/text widget has been updated with a valid value. The "default value" I used above is a possible solution, another one is to use a client handler to validate the submit button only if the listValue (or its value in the hidden widget) is right. Here is a code that does it (only the doGet is reproduced, all other functions being identical.
function doGet() {
var app = UiApp.createApplication().setTitle('test listBox');
var panel = app.createHorizontalPanel().setStyleAttribute('padding','40px');
var submitBtn = app.createSubmitButton('test').setStyleAttribute('margin-left','40').setEnabled(false);
var listHandler = app.createServerHandler('updlistVal').addCallbackElement(panel);
var items = ['category 1','category 2','category 3'];
var listVal = app.createTextBox().setText('not defined yet').setId('listboxVal').setName('listboxVal').setWidth('200');
var list1 = app.createListBox(true).setName('list1').addChangeHandler(listHandler).addItem('choose one or more item(s)');
for(var i =0;i<items.length;++i){list1.addItem(items[i])}
var clientH = app.createClientHandler().forTargets(submitBtn).setEnabled(true).validateMatches(list1, 'category');
list1.addClickHandler(clientH);
panel.add(list1).add(listVal);// set a default value in case the user is happy with that and doesn't touch the listBox
app.add(app.createFormPanel().add(panel.add(submitBtn)));
return app;
}
Using the hidden widget as validation source causes a small issue as we need to click twice on the listBox to make it work... in case there are other questions on the form this will be solved by triggering the client handler with every other widgets so that the double click won't be necessary anymore but this is becoming a bit "out of subject" I'm afraid.
EDIT 3 :
just for the fun of it, a last version that works apparently without issue...
test here
function doGet() {
var app = UiApp.createApplication().setTitle('test listBox');
var panel = app.createHorizontalPanel().setStyleAttribute('padding','40px');
var submitBtn = app.createSubmitButton('test').setStyleAttribute('margin-left','40').setEnabled(false).setId('sbmt');
var wait = app.createImage('https://dl.dropboxusercontent.com/u/211279/loading3T.gif').setId('wait').setVisible(false);
var listHandler = app.createServerHandler('updlistVal').addCallbackElement(panel);
var items = ['category 1','category 2','category 3'];
var listVal = app.createTextBox().setText('not defined yet').setId('listboxVal').setName('listboxVal').setWidth('200');
var list1 = app.createListBox(true).setName('list1').addChangeHandler(listHandler).addItem('choose one or more item(s)');
for(var i =0;i<items.length;++i){list1.addItem(items[i])}
var clientH = app.createClientHandler().forTargets(wait).setVisible(true).forTargets(submitBtn).setEnabled(false);
list1.addChangeHandler(clientH);
panel.add(list1).add(listVal);// set a default value in case the user is happy with that and doesn't touch the listBox
app.add(app.createFormPanel().add(panel.add(submitBtn).add(wait)));
return app;
}
function doPost(e){
var app = UiApp.getActiveApplication();
app.add(app.createLabel().setStyleAttribute('padding','40').setText("Submitted value(s) from list : "+e.parameter.listboxVal));
return app;
}
function updlistVal(e){
var app = UiApp.getActiveApplication();
app.getElementById('listboxVal').setValue(e.parameter.list1);
app.getElementById('sbmt').setEnabled(true);
app.getElementById('wait').setVisible(false);
return app;
}
This is a known bug in the issue tracker, Issue 959. Visit and star it for updates.
It's been known and "worked on" since Dec 2011, if you believe the notes added by the support team. Other users have provided a work-around, and a modified version of it appears below.
The idea is to attach a handler function to the ListBox, which will receive all the selected items from the ListBox. The handler will then write those values to a hidden element in the form. When the form is submitted, the list of selections will be available to the doPost(), via the hidden element.
...
var listbox = app.createListBox(true).setName("listBox").addItem("option 1").addItem("option 2");
flow.add(listbox);
// Issue 959 ListBox Workaround: http://code.google.com/p/google-apps-script-issues/issues/detail?id=959
var listboxHidden= app.createHidden("listboxHidden", "").setId("listboxHidden");
flow.add(listboxHidden);
var fixListBoxHandler = app.createServerHandler('fixListBoxHandler');
fixListBoxHandler.addCallbackElement(listbox);
listbox.addChangeHandler(fixListBoxHandler);
...
}
function fixListBoxHandler(e) {
var app = UiApp.getActiveApplication();
app.getElementById('listboxHidden').setValue(e.parameter.listbox);
return app;
}
NOTE: Unfortunately, this work-around is time-sensitive; it can take several seconds for the handler to update the hidden value. If the submit button is hit before the handler completes its job, then post() receives what was in the hidden element before the call to the handler.

JQuery Autocomplete Problem

I am using JQuery UI Autocomplete in my JSP. Whenever user keys character, i made the request to server and get the data as JSON and load with the pulgin.
It's working fine. But Whenever i typed the same character as previous term. It's not populating any values.
For eg., First i typed p, it lists the p starting elements. I have the button to reset the text content of autocompleter. After reset, if i am typing same character p, it doesn't show anything.
my code as follows,
var cache = {};
$("#Name").autocomplete({
source: function(req, add){
if (req.term in cache) {
add(cache[req.term]);
return;
}
$.getJSON("/store/StockManagement?action=getMedicinesStock",req, function(data) {
var medicines = [];
$.each(data, function(i, val){
medicines.push(val.name + "," + val.code);
});
cache[req.term] = medicines;
add(medicines);
});
},select: function(e, ui) {
var medicine = ui.item.value;
$('#Code').val(medicine.split(",")[1]);
setTimeout(function(){
var med = $('#Name').val();
$('#Name').val(med.split(",")[0]);
},500);
}
});
// Taken from jquery-ui-1.8.4.custom.min.js
if (a.term != a.element.val()) { // *** THE MATCH IS HERE
//console.log("a.term != a.element.val(): "+a.term+", "+a.element.val());
a.selectedItem = null;
a.search(null, c) // *** SEARCH IS TRIGGERED HERE
}
I just commented the condition. now it's works fine.

Resources