/*
# Copyright (c) 2012+ Damjan Rems
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*******************************************************************
* Find and extract parameters value from url
*******************************************************************/
$.getUrlParam = function(name) {
var results = new RegExp('[\\?&]' + name + '=([^]*)').exec(window.location.href);
return results[1] || 0;
};
/*******************************************************************
* Dump all attributes to console
*******************************************************************/
dumpAttributes = function(obj) {
console.log('Dumping attributes:');
$.each(obj.attributes, function() {
console.log(this.name,this.value);
});
};
/*******************************************************************
* Trying to remove background from iframe element. It is not yet working.
*******************************************************************/
remove_background_from_iframe = function(obj) {
var head = obj.head;
var css = '';
$(head).append(css);
};
/*******************************************************************
* Activate jquery UI tooltip. This needs jquery.ui >= 1.9
*******************************************************************/
/*
$(function() {
$( document ).tooltip();
});
*/
/*******************************************************************
* Process json result from ajax call and update parts of document.
* I invented my own protocol which is arguably good or wrong.
*
* Protocol consists of operation and value which are returned as json by
* called controller. Controller will return an ajax call usually like this:
* render json: {operation: value}.to_json
*
* Operation is further divided into source and determinator which are divided by underline char.
* render json: {#div_status: 'OK!'}.to_json
* will replace html in div="status" with value 'OK!'. Source is '#div' determinator is 'status'.
*
* Possible operators are:
* record_name: will replace value of record[name] field on a form with supplied value
*
* msg_error: will display error message.
* msg_warn: will display warning message.
* msg_info: will display informational message.
*
* #div_divname : will replace divname with value
* #div+_divname : will append value to divname
* #+div_divname : will prepend value to divname
* .div_classname : will replace all accurencess of classname with value
* .+div_classname : will prepend value to all accurencess of classname
* .div+_classname : will append value to all accurencess of classname
*
* url_: Will force loading of url supplied in value into same window
* window_: Will force loading of url supplied in value into new window
* reload_: Will reload current window
*
* Operations can be chained and are executed sequentialy.
* render json: {'window_' => "/dokument.pdf", 'reload_' => 1}.to_json
* will open /dokument.pdf in new window and reload current window.
*
* render json: {'record_name' => "Damjan", 'record_surname' => 'Rems'}.to_json
* will replace values of two fields on the form.
*******************************************************************/
process_json_result = function(json) {
var c = '';
$.each(json, function(key, val) {
i = key.search('_');
if (i > 1) {
oper = key.substring(0,i);
what = key.substring(i+1,100);
switch (oper) {
/* update field */
case 'record':
$('#'+key).val(val);
break;
/* display message */
case 'msg':
selector = 'dc-form-' + what;
if ($('.'+selector).length == 0) {
val = '
' + val + '
';
$('.dc-title').after(val);
} else
$('.'+selector).html(val);
break;
/* update div */
case '#div+':
$('#'+what).append(val);
break;
case '#+div':
$('#'+what).prepend(val);
break;
case '#div':
$('#'+what).html(val);
break;
case '.div+':
$('.'+what).append(val);
break;
case '.+div':
$('.'+what).prepend(val);
break;
case '.div':
$('.'+what).html(val);
break;
/* goto url */
case 'url':
window.location.href = val;
break;
case 'window':
w = window.open(val, what);
w.focus();
break;
case 'reload':
location.reload();
break;
}
}
});
};
/*******************************************************************
* Will reload window
*******************************************************************/
function dc_reload_window() {
location.reload();
}
/*******************************************************************
* Will scroll to position on the screen. This is replacement for
* location.hash, which doesn't work in Chrome.
*
* Thanks goes to: http://web-design-weekly.com/snippets/scroll-to-position-with-jquery/
*******************************************************************/
$.fn.dc_scroll_view = function () {
return this.each(function () {
$('html, body').animate({
scrollTop: $(this).offset().top - 50
}, 500);
});
};
/*******************************************************************
*
*******************************************************************/
$(document).ready( function() {
/*******************************************************************
* Register ad clicks
*******************************************************************/
$('a.link_to_track').click(function() {
$.post('/dc_common/ad_click', { id: this.id });
return true;
});
/*******************************************************************
* Popup or close CMS edit menu on icon click
*******************************************************************/
$('.drgcms_popmenu').bind('click',function(e) {
$(e.target).parents('dl:first').find('ul').toggleClass('div-hidden');
});
/*******************************************************************
* Popup CMS edit menu option clicked
*******************************************************************/
$('.drgcms_popmenu_item').bind('click',function(e) {
url = e.target.getAttribute("data-url");
$('#iframe_cms').attr('src', url);
// $('#iframe_cms').width(1000).height(1000);
// scroll to top of page and hide menu
window.scrollTo(0,0);
$(e.target).parents('dl:first').find('ul').toggleClass('div-hidden');
});
/*******************************************************************
* Sort action clicked on cmsedit
*******************************************************************/
$('.drgcms_sort').change( function(e) {
table = e.target.getAttribute("data-table");
sort = e.target.value;
e.target.value = null;
window.location.href = "/cmsedit?sort=" + sort + "&table=" + table;
});
/*******************************************************************
* Tab clicked on form. Hide old and show selected div.
*******************************************************************/
$('.dc-form-li').bind('click', function(e) {
/* find li with dc-form-li-selected class and remove it. This will deselect tab */
var old_id = null;
$(e.target).parents('ul').find('li').each( function() {
/* console.debug( $(this) ); */
if ($(this).hasClass('dc-form-li-selected')) {
/* ignore if tab is already selected */
if ($(this) !== $(e.target)) {
$(this).toggleClass('dc-form-li-selected');
$(e.target).toggleClass('dc-form-li-selected');
old_id = this.getAttribute("data-div");
}
return false;
}
}); /* show selected data div */
if (old_id !== null) {
$('#data_' + old_id).toggleClass('div-hidden');
$('#data_' + e.target.getAttribute("data-div")).toggleClass('div-hidden');
}
});
/*******************************************************************
* Resize iframe_cms to the size of its contents. Make at least 500 px hight
* unless on initial display.
*******************************************************************/
$('#iframe_cms').load( function() {
// alert('bla 1');
new_height = this.contentWindow.document.body.offsetHeight + 50;
if (new_height < 500 & new_height > 60) new_height = 500;
this.style.height = new_height + 'px';
remove_background_from_iframe(this.contentWindow.document);
$('#iframe_cms').dc_scroll_view();
});
/*******************************************************************
* Same goes for editiframe. Resize it + 30px
* unless on initial display with no data
*******************************************************************/
$('#iframe_edit').load( function() {
// console.log(this.contentWindow.document.body.offsetHeight);
if (this.contentWindow.document.body.offsetHeight > 10) {
this.style.height = (this.contentWindow.document.body.offsetHeight + 30) + 'px';
// scroll to it
$('#iframe_edit').dc_scroll_view();
}
// remove_background_from_iframe(this.contentWindow.document);
});
/*******************************************************************
* Process Ajax call on cmsedit form actions
*******************************************************************/
$('.dc-link-ajax').bind('click', function(e) {
var target = e.target;
// if (e.target.src !== undefined) {
// target = e.target.parent(); // picture
// };
// dumpAttributes(target);
req = target.getAttribute("data-request");
/* Get some values from elements on the page: */
if (req == "script") {
eval (target.getAttribute("data-script"));
return false;
}
else if (req == "post") {
data = $('form').serialize();
// alert(data);
}
else {
data = {};
req = 'get'; // by default
}
$('#dc-spinner').toggleClass('div-hidden');
$.ajax({
url: target.getAttribute("data-url"),
type: req,
dataType: "json",
data: data,
success: function(data) {
process_json_result(data);
$('#dc-spinner').toggleClass('div-hidden');
}
});
});
/*******************************************************************
* Animate button on click
******************************************************************
$('.xdc-action-menu li').mousedown( function() {
$(this).toggleClass('dc-animate-button');
});
******************************************************************
* Animate button on click
******************************************************************
$('.xdc-action-menu li').mouseup( function() {
$(this).toggleClass('dc-animate-button');
});
*/
/*******************************************************************
* Animate button on click
*******************************************************************/
$('.dc-animate').mousedown( function() {
$(this).toggleClass('dc-animate-button');
});
/*******************************************************************
* Animate button on click
*******************************************************************/
$('.dc-animate').mouseup( function() {
$(this).toggleClass('dc-animate-button');
});
/*******************************************************************
* App menu option clicked
*******************************************************************/
$('.app-menu-item a').bind('click', function(e) {
/* parent of a is li */
$(e.target).parents('li').each( function() {
/* for all li's in ul, deselect */
$(this).parents('ul').find('li').each( function() {
if ($(this).hasClass('app-menu-item-selected')) {
$(this).toggleClass('app-menu-item-selected');
}
});
/* select clicked li */
$(this).toggleClass('app-menu-item-selected');
});
});
/*******************************************************************
* Display spinner on link with spinner, submit link
*******************************************************************/
$('.dc-link-spinner').bind('click', function(e) {
$('#dc-spinner').toggleClass('div-hidden');
});
$('.dc-link-submit').bind('click', function(e) {
$('#dc-spinner').toggleClass('div-hidden');
});
/*******************************************************************
* Add button clicked while in edit. Create window dialog for adding new record
* into required table. This is helper scenario, when user is selecting
* data from with text_autocomplete and data doesn't exist in belongs_to table.
*******************************************************************/
$('.in-edit-add').bind('click', function(e) {
url = '/cmsedit/new?table=' + this.getAttribute("data-table");
/* I know. It doesn't work as expected. But it will do for now. */
w = window.open(url, '', 'chrome=yes,width=800,height=600,resizable,scrollbars=yes,status=1,centerscreen=yes,modal=yes');
w.focus();
});
/**********************************************************************
* When filter_field (field name) is selected on filter subform this routine finds
* and displays apropriate span with input field.
**********************************************************************/
$('#_filter_field').bind('change', function() {
if (this.value.length > 0) {
name = 'filter_' + this.value;
$(this).parents('form').find('span').each( function() {
/*
element = $(this).find(':first').attr('id');
sometimes it is the second element
if (element == nil) { element = $(this).find(':first').next().attr('id');}
*/
if ($(this).attr('id') === name) {
if ( $(this).hasClass('div-hidden') ) { $(this).toggleClass('div-hidden'); }
} else {
if ( !$(this).hasClass('div-hidden') ) { $(this).toggleClass('div-hidden'); }
}
});
}
});
/*******************************************************************
* It is not possible to attach any data to submit button except the text
* that is written on a button and it is therefore very hard to distinguish
* which button was pressed when more than one button is present on a form.
*
* The purpose of this trigger is to append data hidden in html5 data attributes
* to the form. We can now attach any kind of data to submit button and data
* will be passed as data[] parameters to controller.
*******************************************************************/
$('.dc-submit').bind('click', function() {
$.each(this.attributes, function() {
if (this.name.substring(0,5) === 'data-') {
$('').attr({
type: 'hidden',
name: 'data[' + this.name.substring(5) + ']',
value: this.value
}).appendTo('form');
}
});
});
/* DOCUMENT INFO */
/*******************************************************************
* Popup or hide document information
*******************************************************************/
$('#dc-document-info').bind('click',function(e) {
popup = $(e.target).next();
popup.toggleClass('div-hidden');
if (!popup.hasClass('div-hidden')) {
var o = {
left: e.pageX - popup.width() - 10,
top: e.pageY - popup.height() - 20
};
popup.offset(o);
};
});
/*******************************************************************
* Just hide document information on click.
*******************************************************************/
$('#dc-document-info-popup').bind('click',function(e) {
// click on container (id)
if (e.target.id == 'dc-document-info-popup') {
$(e.target).toggleClass('div-hidden');
// click on text or picture. Hence hide parent
} else {
$(e.target).parent().toggleClass('div-hidden');
}
});
/*******************************************************************
* Force reload of parent page if this div appears
*******************************************************************/
$('#div-reload-parent').load( function() {
// alert('div-reload-parent 1');
parent.location.href=parent.location.href
});
/*******************************************************************
* Force reload of parent page if this div appears
*******************************************************************/
$('#div-reload').load( function() {
// alert('div-reload 1');
location.href=location.href
});
$('#div-reload-parent').bind('DOMNodeInserted DOMNodeRemoved', function() {
alert('div-reload-parent 2');
});
$('#div-reload').bind('DOMNodeInserted DOMNodeRemoved', function() {
alert('div-reload 2');
});
});
/*******************************************************************
* Catch ctrl+s key pressed and fire save form event. I press ctrl+s
* almost every minute. That was a lesson learned years ago when I lost
* few hours of work on computer lockup ;-(
*******************************************************************/
$(document).keydown( function(e) {
if ((e.which == '115' || e.which == '83' ) && (e.ctrlKey || e.metaKey))
{
e.preventDefault();
document.forms[0].submit();
return false;
}
return true;
});