/*
* Version 1.1.4
*/
jQuery( document ).ready( function( $ ) {
// Initial rulelist sortable
initialize_sort();
// Rebuild array on page load (if not updating settings)
if( ! $( 'div.preventRebuildArray' ).length ) {
rebuildArray();
}
// Edit title button
$( document ).on( 'click', 'div.edit_title_div', function() {
// Get original value
var orig_value = $( this ).parent().siblings( 'span.group_name' ).text();
var check_nodes = $( this ).parent().siblings( 'span.group_name' ).children( 'input.edit_title_input' );
// If we are already editing, don't edit again
if( $( check_nodes ).length > 0 ) { return false; }
// Create submit/cancel buttons and replace html
var edit_input = '';
$( this ).parent().siblings( 'span.group_name' ).html( edit_input );
var edit_actions = 'Submit';
edit_actions += 'Cancel';
edit_actions += '';
edit_actions += 'format_bold';
$( this ).parent().siblings( 'span.group_name_edit' ).html( edit_actions );
// Check for current title color
var title_color = $( this ).parent().parent().siblings( 'input.title_color' ).val();
var set_color = title_color === '' ? '#000' : title_color;
// Check for current title opacity
var title_opacity = $( this ).parent().parent().siblings( 'input.title_opacity' ).val();
var set_opacity = title_opacity === '' ? '1' : title_opacity;
// Check for current title bold
var title_bold = $( this ).parent().parent().siblings( 'input.title_bold' ).val();
if( title_bold == 'true' ) {
$( this ).parent().siblings( 'span.group_name_edit' ).children( 'span.title_bold' ).addClass( 'active' );
}
// Build rgba from color and opacity
var rgba = hexToRGB( set_color, set_opacity );
// Set color picker
$(".color_picker").spectrum({
color: rgba,
showInitial: true,
showPaletteOnly: true,
togglePaletteOnly: true,
togglePaletteMoreText: 'Show More',
togglePaletteLessText: 'Show Less',
chooseText: 'Choose',
cancelText: 'Cancel',
hideAfterPaletteSelect: true,
showAlpha: true,
palette: [
["#000","#444","#666","#999","#ccc","#eee","#f3f3f3","#fff"],
["#f00","#f90","#ff0","#0f0","#0ff","#00f","#90f","#f0f"],
["#f4cccc","#fce5cd","#fff2cc","#d9ead3","#d0e0e3","#cfe2f3","#d9d2e9","#ead1dc"],
["#ea9999","#f9cb9c","#ffe599","#b6d7a8","#a2c4c9","#9fc5e8","#b4a7d6","#d5a6bd"],
["#e06666","#f6b26b","#ffd966","#93c47d","#76a5af","#6fa8dc","#8e7cc3","#c27ba0"],
["#c00","#e69138","#f1c232","#6aa84f","#45818e","#3d85c6","#674ea7","#a64d79"],
["#900","#b45f06","#bf9000","#38761d","#134f5c","#0b5394","#351c75","#741b47"],
["#600","#783f04","#7f6000","#274e13","#0c343d","#073763","#20124d","#4c1130"]
],
change: function( color ) {
// Populate hidden input field for later consumption
$( this ).parent().parent().siblings( 'input.title_color' ).val( color.toHexString() );
$( this ).parent().parent().siblings( 'input.title_opacity' ).val( color.getAlpha() );
}
});
});
// Edit container button
$( document ).on( 'click', 'div.edit_container_div', function() {
// If we are already editing, don't edit again
var check_nodes = $( this ).parent().parent().siblings( 'div.container_options' ).children( 'input.cont_bg_color_picker' );
if( $( check_nodes ).length > 0 ) { return false; }
// Define container html
var html = '';
html += 'Container Background Color: ';
html += 'Submit';
html += 'Cancel';
// Build new container options panel
var new_div = $( '
' );
$( new_div ).html( html );
$( new_div ).prependTo( $( this ).parent().parent().parent( 'div.rule_container' ) ).fadeIn();
// Get container color option
var container_color = $( this ).parent().parent().siblings( 'input.container_color' ).val();
var container_opacity = $( this ).parent().parent().siblings( 'input.container_opacity' ).val();
// Build rgba from color and opacity
var rgba = hexToRGB( container_color, container_opacity );
// Set color picker
$(".cont_bg_color_picker").spectrum({
color: rgba,
showInitial: true,
showPaletteOnly: true,
togglePaletteOnly: true,
togglePaletteMoreText: 'Show More',
togglePaletteLessText: 'Show Less',
chooseText: 'Choose',
cancelText: 'Cancel',
hideAfterPaletteSelect: true,
showAlpha: true,
palette: [
["#000","#444","#666","#999","#ccc","#eee","#f3f3f3","#fff"],
["#f00","#f90","#ff0","#0f0","#0ff","#00f","#90f","#f0f"],
["#f4cccc","#fce5cd","#fff2cc","#d9ead3","#d0e0e3","#cfe2f3","#d9d2e9","#ead1dc"],
["#ea9999","#f9cb9c","#ffe599","#b6d7a8","#a2c4c9","#9fc5e8","#b4a7d6","#d5a6bd"],
["#e06666","#f6b26b","#ffd966","#93c47d","#76a5af","#6fa8dc","#8e7cc3","#c27ba0"],
["#c00","#e69138","#f1c232","#6aa84f","#45818e","#3d85c6","#674ea7","#a64d79"],
["#900","#b45f06","#bf9000","#38761d","#134f5c","#0b5394","#351c75","#741b47"],
["#600","#783f04","#7f6000","#274e13","#0c343d","#073763","#20124d","#4c1130"]
],
change: function( color ) {
// Populate hidden input field for later consumption
$( this ).parent().siblings( 'input.container_color' ).val( color.toHexString() );
$( this ).parent().siblings( 'input.container_opacity' ).val( color.getAlpha() );
}
});
});
// Title bold button click
$( document ).on( 'click', 'span.title_bold', function() {
// Toggle active class
$( this ).toggleClass( 'active' );
// Get and set hidden input field
var title_bold = $( this ).hasClass( 'active' ) ? 'true' : 'false';
$( this ).parent().parent().siblings( 'input.title_bold' ).val( title_bold );
});
// Cancel edit title button
$( document ).on( 'click', 'span.cancel_edit', function() {
// Get original value
var orig_value = $( this ).parent().siblings( 'span.group_name' ).children( 'input.edit_title_input' ).val();
// Replace title with original value
$( this ).parent().siblings( 'span.group_name' ).html( orig_value );
// Clear edit area
$( this ).parent().html( '' );
// Rebuild user array
rebuildArray();
});
// Cancel edit container button
$( document ).on( 'click', 'span.cancel_edit_container', function() {
// Remove edit container div
$( this ).parent().fadeOut( "normal", function() { $( this ).remove(); });
// Rebuild user array
rebuildArray();
});
// Submit edit title button
$( document ).on( 'click', 'span.submit_edit', function() {
// Get new title value
var new_value = $( this ).parent().siblings( 'span.group_name' ).children( 'input.edit_title_input' ).val();
// Get title color
var title_color = $( this ).parent().parent().siblings( 'input.title_color' ).val();
// Get title opacity
var title_opacity = $( this ).parent().parent().siblings( 'input.title_opacity' ).val();
// Get title bold
var title_bold = $( this ).parent().parent().siblings( 'input.title_bold' ).val();
var font_weight = title_bold == 'true' ? 'bold' : 'normal';
// Replace title with new values
$( this ).parent().siblings( 'span.group_name' ).html( new_value ).css({ 'color': title_color, 'font-weight': font_weight, 'opacity': title_opacity });
// Clear edit area
$( this ).parent().html( '' );
// Rebuild array
rebuildArray();
});
// Submit edit container
$( document ).on( 'click', 'span.submit_edit_container', function() {
// Get container color
var container_color = $( this ).parent().siblings( 'input.container_color' ).val();
// Get container opacity
var container_opacity = $( this ).parent().siblings( 'input.container_opacity' ).val();
// Combine rgba
var rgba = hexToRGB( container_color, container_opacity );
// Replace container with new values
$( this ).parent().parent().css({ 'background-color': rgba });
// Remove edit container div
$( this ).parent().fadeOut( "normal", function() { $( this ).remove(); });
// Rebuild array
rebuildArray();
});
// Create container button
$( "span#create_group_button" ).click( function() {
// Get name from input
var name = $( 'input#new_group_name' ).val();
// If no name, alert and bail
if( name == '' ) {
alert( "Please enter a valid Group Name.");
return false;
}
// Create html for new container
var html = '';
html += '
';
// Check hide counts option
var check_counts = $( 'input#hide_counts' ).is( ':checked' ) ? 'display: none;' : '';
// Hidden divs
html += '';
html += '';
html += '';
html += '';
html += '';
html += '
';
html += '' + name + '';
html += '';
html += '(0 items)';
html += 'more_vert';
// Three dot menu
html += '
';
html += '
open_with Move
';
html += '
file_upload Collapse
';
html += '
edit Edit Container
';
html += '
edit Edit Title
';
html += '
arrow_downward Sort Asc
';
html += '
arrow_upward Sort Desc
';
html += '
delete Delete Container
';
html += '
';
html += '
';
// Rule list
html += '
';
html += '
';
// Append container to page
$( 'div#rules_container' ).prepend( html );
// Clear input field
$( 'input#new_group_name' ).val( '' );
// Rebuild array
rebuildArray();
// Initialize sort
initialize_sort();
});
// Delete section button
$( document ).on( 'click', 'div.delete_container', function() {
var this_delete = $( this );
// Confirm deletion
if( confirm( "Permenantly delete the group?\nAny remaining rules in this group will be moved to the Original Rules group." ) == true ) {
// Check if any rules exist in container
var check_rules = $( this_delete ).parent().parent().siblings( 'ul' ).children();
// If rules are found
if( check_rules.length !== 0 ) {
// Copy rules and append to original rules container
var copy_html = $( this_delete ).parent().parent().siblings( 'ul' ).html();
$( 'div#original-rules' ).find( 'ul.rulelist' ).append( copy_html );
}
// Remove container
$( this_delete ).parent().parent().parent().remove();
// Rebuild array
rebuildArray();
}
});
// Toggle open/close
$( document ).on( 'click', 'div.toggle_container', function() {
// Switch material icon from open/close
if( $( this ).children( 'i' ).text() == 'file_upload' ) {
$( this ).html( 'file_download Expand' );
}
else if( $( this ).children( 'i' ).text() == 'file_download' ) {
$( this ).html( 'file_upload Collapse' );
}
// Toggle list
$( this ).parent().parent().siblings( 'ul' ).toggle();
// Rebuild array
rebuildArray();
});
// Copy rule
$( document ).on( 'click', 'div.copy_rule', function() {
var new_item = $( this ).parent().parent().clone();
new_item.find( 'div.copy_rule' ).remove();
new_item.children( 'div.dropdown-content' ).prepend( '
delete Delete Rule
' );
$( this ).parent().parent().after( new_item );
// Rebuild array
rebuildArray();
});
// View rule
$( document ).on( 'click', 'div.view_rule', function() {
window.open( $( this ).attr( 'url' ) );
$( this ).parent().hide();
return false;
});
// Delete duplicate rule
$( document ).on( 'click', 'div.delete_duplicate', function() {
$( this ).parent().parent().remove();
// Rebuild array
rebuildArray();
});
// Three dot submenu click function
$( document ).on( 'click', 'i.submenu', function() {
$( 'div.dropdown-content' ).not( $( this ).siblings( 'div.dropdown-content' ) ).hide();
$( this ).siblings( 'div.dropdown-content' ).toggle();
$( this ).toggleClass( 'active' );
var css = ! $( this ).siblings( 'div.dropdown-content' ).is( ':visible' ) ? '0deg' : '90deg';
$( this ).css( 'rotate', css );
});
// Three dot close if clicking anywhere outside of container
window.onclick = function(event) {
if( ! event.target.matches( '.submenu' ) ) {
$( 'div.dropdown-content' ).hide();
$( 'i.submenu' ).css( 'rotate', '0deg' );
$( 'i.submenu' ).removeClass( 'active' );
}
}
// Sort ascending
$( document ).on( 'click', 'div.sortasc_container', function() {
// Get list items
var list = $( this ).parent().parent().siblings( 'ul.rulelist' );
var items = list.children( 'li' ).get();
// Sort
items.sort( function( a, b ) {
var a_sort = $( a ).children( 'span.rule_name' ).text().toUpperCase();
var b_sort = $( b ).children( 'span.rule_name' ).text().toUpperCase();
// Remove special characters
a_sort = a_sort.replace( /[^\w\s]/gi, '' );
b_sort = b_sort.replace( /[^\w\s]/gi, '' );
return a_sort.localeCompare( b_sort );
});
// Append back to list
$.each( items, function( idx, itm ) { list.append( itm ); });
// Rebuild array
rebuildArray();
});
// Sort descending
$( document ).on( 'click', 'div.sortdesc_container', function() {
// Get list items
var list = $( this ).parent().parent().siblings( 'ul.rulelist' );
var items = list.children( 'li' ).get();
// Sort
items.sort( function( a, b ) {
var b_sort = $( b ).children( 'span.rule_name' ).text().toUpperCase();
var a_sort = $( a ).children( 'span.rule_name' ).text().toUpperCase();
// Remove special characters
b_sort = b_sort.replace( /[^\w\s]/gi, '' );
a_sort = a_sort.replace( /[^\w\s]/gi, '' );
return b_sort.localeCompare( a_sort );
});
// Append back to list
$.each( items, function( idx, itm ) { list.append( itm ); });
// Rebuild array
rebuildArray();
});
// Toggle options panel
$( document ).on( 'click', 'span#options_panel', function() {
$( this ).toggleClass( 'active' );
$( 'div#options_section' ).fadeToggle();
});
// Export options
$( 'span#generate_export').click( function() {
// Get options from hidden input
var options = $( 'input#userArray' ).val();
// Place into textarea
$( 'textarea#export_textarea' ).val( options );
});
// Import options
$( 'span#generate_import' ).click( function() {
// Get import value
var import_opts = $( 'textarea#import_textarea' ).val();
if( import_opts == '' ) {
alert( 'Please paste the contents of an export into the import textarea.' );
return false;
}
// Check if the import is parsable by json
var json_check = true;
try { var json = $.parseJSON( import_opts ); }
catch( err ) { json_check = false; }
// If hte data is good
if( json_check ) {
// Copy and paste into hidden input field
$( 'input#userArray' ).val( import_opts );
// Click "Done" button
$( 'button#btnDone' ).click();
}
// Else the data is no good
else {
alert( 'There is a problem with the import data. Please ensure the data has been pasted correctly.' );
}
});
// Copy export to clipboard
$( 'span#copy_export' ).click( function() {
// Get export value
var text = $( 'textarea#export_textarea' ).val();
// Hubitat does not always run over https. In order for copy to clipboard on http, need js helper
const textArea = document.createElement( 'textarea' );
textArea.value = text;
document.body.appendChild( textArea );
textArea.focus();
textArea.select();
// Try to copy to clipboard; alert if unsuccessful
try {
document.execCommand( 'copy' );
// Change tooltip text
$( 'span#exportTooltip' ).text( 'Copied Successfully!' );
}
catch (err) {
alert( 'Unable to copy to clipboard' );
}
// Remove temp textarea
document.body.removeChild( textArea );
});
// Copy export change text
$( 'span#copy_export' ).mouseout( function() {
// Get tooltip element and alter text
var tooltip = document.getElementById( 'exportTooltip' );
tooltip.innerHTML = 'Copy to clipboard';
});
// Global option hide container counts
$( 'input#hide_counts' ).change( function() {
if( $( this ).is( ':checked' ) ) {
$( 'span.group_rule_count' ).hide();
}
else {
$( 'span.group_rule_count' ).show();
}
// Rebuild array
rebuildArray();
});
// If resetting rules; click the "Done" button
$( 'span#reset_opts' ).click( function() {
if( confirm( "Permanently reset all options? This will restore all default app setting, and save the app.\nThe window will return to the main Apps page." ) == true ) {
// Get default setting
var get_defaults = $( 'input#load_default_opts' ).val();
// Set defualt setting
$( 'input#userArray' ).val( get_defaults );
// Click "Done" button
$( 'button#btnDone' ).click();
}
});
// Done function
$( document ).on( 'click', 'span#done_submit', function() {
// Click "Done" button
$( 'button#btnDone' ).click();
});
// Build new user array
function rebuildArray() {
// Define base array
var rb_array = {};
// Push global options
rb_array.hide_counts = $( 'input#hide_counts' ).is( ':checked' ) ? 'true' : 'false';
rb_array.containers = [];
// Loop each container
$( 'div.rule_container' ).each( function() {
// Create container array and populate
var title = $( this ).children( 'h4' ).children( 'span.group_name' ).text();
var this_array = {};
this_array.name = title;
this_array.slug = string_to_slug( title );
this_array.title_color = $( this ).children( 'input.title_color' ).val();
this_array.title_opacity = $( this ).children( 'input.title_opacity' ).val();
this_array.title_bold = $( this ).children( 'input.title_bold' ).val();
this_array.container_color = $( this ).children( 'input.container_color' ).val();
this_array.container_opacity = $( this ).children( 'input.container_opacity' ).val();
this_array.visible = $( this ).children( 'ul' ).is( ':visible' );
// Populate all rules
this_array.rules = [];
$( this ).children( 'ul' ).children( 'li' ).each( function(i, v) { this_array.rules.push( v.id ); });
// Count rules in this container and display on page
var count = this_array.rules.length;
var items = count == 1 ? 'item' : 'items';
$( this ).children( 'h4' ).children( 'span.group_rule_count' ).html( '(' + count + ' ' + items + ')' );
// Push this container to base array
rb_array.containers.push( this_array );
});
// Populate hidden input with new user array
$( 'input#userArray' ).val( JSON.stringify( rb_array ) );
// Adjust list classes on duplicate items
$( 'div.delete_duplicate' ).each( function() {
$( this ).parent().parent().addClass( 'duplicate' );
});
}
// Build slugs from friendly names
function string_to_slug( str ) {
// Trim string and cast to lowercase
str = str.replace(/^\s+|\s+$/g, '');
str = str.toLowerCase();
// Remove accents, swap ñ for n, etc
var from = "àáäâèéëêìíïîòóöôùúüûñç·/_,:;";
var to = "aaaaeeeeiiiioooouuuunc------";
for (var i=0, l=from.length ; i","