Файловый менеджер - Редактировать - /home/infrafs/www/wp-content/plugins/wp-store-locator/admin/js/wpsl-admin.js
Назад
jQuery( document ).ready( function( $ ) { var map, geocoder, startLatLng, markersArray = [], wpslAdmin = wpslAdmin || {}; /** * Verify the provided API keys * * @since 2.2.22 */ wpslAdmin.verifyKeys = { init: function() { var self = this, $btn = $( "#wpsl-verify-keys" ), preloader = wpslSettings.url + "img/ajax-loader.gif", mapService = ( typeof wpslSettings.mapService !== "undefined" ) ? wpslSettings.mapService : "gmaps"; $btn.on( "click", function() { $( "#wpsl-wrap .notice" ).remove(); self[mapService].check(); $btn.after( '<img src="' + preloader + '" class="wpsl-api-key-preloader" />' ); return false; }); }, /** * Show the status of the API keys. * * @since 2.2.22 * @param {string} response The API response * @param {string} keyType The type of API key we need to show the notice for * @param {string} noticeType Show either an error or success notice. * @returns {void} */ showStatus: function( response, keyType, noticeType = "error" ) { this.createNotice( response, keyType, noticeType ); // After the browser check has finished we remove the preloader. if ( keyType == "browser" ) { $( ".wpsl-api-key-preloader" ).remove(); } }, /** * Create the error notice. * * @since 2.2.10 * @param {string} response The API response to show * @param {string} keyType The type of API key we need to show the notice for * @param {string} noticeType Show either an error or success notice. * @returns void */ createNotice: function( response, keyType, noticeType ) { var notice, noticeLocation, cssClass; cssClass = ( noticeType == "error" ) ? "error" : "updated"; notice = '<div class="' + cssClass + ' notice is-dismissible">'; notice += '<p><strong>' + response + '</strong></p>'; notice += '<button type="button" class="notice-dismiss"><span class="screen-reader-text">' + wpslL10n.dismissNotice + '</span></button>'; notice += '</div>'; noticeLocation = ( $( "#wpsl-tabs" ).length ) ? "wpsl-tabs" : "wpsl-settings-form"; $( "#" + noticeLocation + "" ).before( notice ); if ( noticeType == "error" ) { $( "#wpsl-api-" + keyType + "-key" ).addClass( "wpsl-error" ); } else { $( "#wpsl-api-" + keyType + "-key" ).removeClass( "wpsl-error" ); } }, gmaps: { /** * Check for any issues with the used API keys. * * @since 2.2.22 * @returns {void} */ check: function() { this.server(function() { wpslAdmin.verifyKeys.gmaps.browser(); }); }, /** * Make a request to the Google Geocode API to * check if the server key is valid or not. * * @since 2.2.22 * @returns {void} */ server: function( callback ) { var status, ajaxData = { action: "validate_server_key", server_key: $( "#wpsl-api-server-key" ).val() }; if ( ajaxData.server_key ) { $.get( wpslSettings.ajaxurl, ajaxData, function( response ) { status = ( response.valid ) ? "updated" : "error"; wpslAdmin.verifyKeys.showStatus( response.msg, "server", status ); callback(); }); } else { wpslAdmin.verifyKeys.showStatus( wpslL10n.serverKeyMissing, "server" ); callback(); } }, /** * Make a request to the Google JavaScript API to * check if the browser key is valid or not. * * @since 2.2.22 * @returns {void} */ browser: function() { var browserAPICheck, browserKey = $( "#wpsl-api-browser-key" ).val(); if ( browserKey ) { /** * Wait 3 seconds before checking if the * Geocode API returned data. * * If this hasn't happened, then there has to * be a problem with the API keys. */ browserAPICheck = setInterval(function() { wpslAdmin.verifyKeys.showStatus( wpslL10n.browserKeyError, "browser" ); clearInterval( browserAPICheck ); }, 3000 ); /** * This will only complete if there are no issues * with the API key, otherwise it won't even make a request. * * To check this we use the setInterval in the above section. */ geocoder.geocode( { 'address': 'Manhattan, NY 10036, USA' }, function( response, status ) { if ( status == google.maps.GeocoderStatus.OK ) { wpslAdmin.verifyKeys.showStatus( wpslL10n.browserKeySuccess, "browser", "success" ); } else { wpslAdmin.verifyKeys.showStatus( wpslL10n.browserKeyError, "browser" ); } clearInterval( browserAPICheck ); }); } else { wpslAdmin.verifyKeys.showStatus( wpslL10n.browserKeyMissing, "browser" ); } } } }; /** * Handle the Geocode requests made from * the Tools section on the settings page. * * This can be used to check the API response * for any input the user provides, and see if * it's in the expected location. * * Will show error messages if there are any * issues with the used browser API keys. * * @since 2.2.22 */ wpslAdmin.showApiResponse = { init: function() { var $geocodeInput = $( "#wpsl-geocode-input" ), self = this, mapLoaded = false; $( "#wpsl-show-geocode-response" ).on( "click", function( e ) { self.createDialog(); initializeGmap("wpsl-geocode-preview" ); // Make sure we don't add the same message twice. if ( !$( ".wpsl-geocode-warning span" ).length ) { self.createRestrictionsMsg(); } // Check for map errors after it finished loading. google.maps.event.addListenerOnce( map, "tilesloaded", function() { mapLoaded = true; self.checkQuotaError(); }); // Check if the map was load succesfully, if not show an error message explaining it. setTimeout(function() { if ( !mapLoaded ) { $(".wpsl-geocode-warning, #wpsl-geocode-test input, #wpsl-geocode-tabs").remove(); $(".wpsl-geocode-api-notice").show().html( wpslL10n.loadingFailed ); } }, 1000 ); return false; }); // Submit the geocode request. $( "#wpsl-geocode-submit" ).on( "click", function( e ) { $geocodeInput.removeClass( "wpsl-error" ); if ( !$geocodeInput.val() ) { $geocodeInput.addClass( "wpsl-error" ); $( ".wpsl-geocode-api-notice" ).hide(); } else { self.geocoding.makeRequest(); } }); // Handle users using the enter key in the dialog box. $( "#wpsl-geocode-test" ).keydown( function( event ) { var keyCode = ( event.keyCode ? event.keyCode : event.which ); if ( keyCode == 13 ) { $( "#wpsl-geocode-submit" ).trigger( "click" ); } }); }, /** * Create the dialog box * * @since 2.2.22 * @returns {void} */ createDialog: function() { $( "#wpsl-geocode-test" ).dialog({ resizable: false, height: "auto", width: 550, modal: true, open: function() { // Move it closer to the top then it normally would $( this ).parent().css({ "top": window.pageYOffset + 50 }); $( "#wpsl-geocode-tabs" ).tabs(); $( "#wpsl-geocode-input" ).focus(); $( ".wpsl-geocode-api-notice" ).hide(); // Make sure the first tab is always selected after the dialog is opened a second time $( "#wpsl-geocode-tabs" ).tabs( "option", "active", $( "li" ).index( $( "li:visible:eq(0)" ) ) ); // Make sure to remove any previous input $( "#wpsl-geocode-input, #wpsl-geocode-response textarea" ).val( "" ); $( ".ui-widget-overlay" ).bind( "click", function() { $( "#wpsl-geocode-test" ).dialog( "close" ); }); }, buttons: { Cancel: function() { $( this ).dialog( "close" ); } } }); }, /** * If there's a problem with the billing account, * then a 'dismissButton' class will exist in the map itself. * * If this is the case, then we remove everything and * show an error explaining the problem. * * @since 2.2.22 * @returns {void} */ checkQuotaError: function() { setTimeout(function() { if ( $( "#wpsl-geocode-preview .dismissButton" ).length > 0 ) { $( ".wpsl-geocode-warning, #wpsl-geocode-test input" ).remove(); $( ".wpsl-geocode-api-notice" ).show(); $( ".wpsl-geocode-api-notice span" ).html( wpslL10n.loadingError ); } }, 1000 ); }, /** * Create a message explaning the user that the * results are restricted to the selected map region, * and possibly only work for zip codes. * * @since 2.2.22 * @returns {void} */ createRestrictionsMsg: function() { var countryName, zipcodeOnly, $warningElem = $( ".wpsl-geocode-warning" ).show().find( "strong" ); if ( $( "#wpsl-api-region" ).val() ) { countryName = $( "#wpsl-api-region option:selected" ).text(); zipcodeOnly = ( $( "#wpsl-force-postalcode" ).is( ":checked" ) ) ? wpslL10n.restrictedZipCode : ''; $warningElem.after( "<span>" + wpslL10n.resultsWarning + ' ' + countryName + ' ' + zipcodeOnly + "</span>" ); } else { $warningElem.after( "<span>" + wpslL10n.noRestriction + "</span>" ); $( ".wpsl-region-href" ).on( "click", function() { $( ".ui-widget-overlay" ).trigger( "click" ); }); } }, geocoding: { /** * Geocode the provided user input * * @since 2.2.22 * @returns {void} */ makeRequest: function() { var request = this.createParams(); geocoder.geocode( request, function( response, status ) { // Show an error message if there is a problem with the browser API key. if ( status == "OK" || status == "ZERO_RESULTS" ) { // Make sure to remove the marker from the map if one exists. if ( typeof markersArray[0] !== "undefined" ) { markersArray[0].setMap( null ); markersArray.length = 0; } if ( status == "OK" ) { addMarker( response[0].geometry.location, false ); map.setZoom( 12 ); map.setCenter( response[0].geometry.location ); } else { map.setZoom( parseInt( wpslSettings.defaultZoom ) ); map.setCenter( startLatLng ); } } else { status = wpslL10n.browserKeyError; $( "#wpsl-geocode-preview, #wpsl-geocode-response textarea" ).remove(); } $( ".wpsl-geocode-api-notice" ).show(); $( ".wpsl-geocode-api-notice span" ).html( status ); $( "#wpsl-geocode-response textarea" ).val( JSON.stringify( response, null, 4 ) ); }); }, /** * Create the params used in the geocode request * made through the test tool in the tools section. * * @since 2.2.22 * @return {object} request The parameters included in the geocode API request */ createParams: function() { var request = {}; // Check if we need to set the geocode component restrictions. if ( typeof wpslSettings.geocodeComponents !== "undefined" && !$.isEmptyObject( wpslSettings.geocodeComponents ) ) { request.componentRestrictions = wpslSettings.geocodeComponents; if ( typeof request.componentRestrictions.postalCode !== "undefined" ) { request.componentRestrictions.postalCode = $( "#wpsl-geocode-input" ).val(); } else { request.address = $( "#wpsl-geocode-input" ).val(); } } else { request.address = $( "#wpsl-geocode-input" ).val(); } return request; }, }, }; if ( $( "#wpsl-gmap-wrap" ).length ) { initializeGmap(); } /** * If we are on the settings page, then init the API tools. */ if ( $( "#wpsl-map-settings").length ) { wpslAdmin.verifyKeys.init(); wpslAdmin.showApiResponse.init(); } /** * Initialize the map with the correct settings. * * @since 1.0.0 * @param string mapId The ID of the element to render the map in * @returns {void} */ function initializeGmap( mapId = "wpsl-gmap-wrap" ) { var defaultLatLng = wpslSettings.defaultLatLng.split( "," ), mapOptions; startLatLng = new google.maps.LatLng( defaultLatLng[0], defaultLatLng[1] ); mapOptions = { zoom: parseInt( wpslSettings.defaultZoom ), center: startLatLng, mapTypeId: google.maps.MapTypeId[ wpslSettings.mapType.toUpperCase() ], mapTypeControl: false, streetViewControl: false, zoomControlOptions: { position: google.maps.ControlPosition.RIGHT_TOP } }; geocoder = new google.maps.Geocoder(); map = new google.maps.Map( document.getElementById( mapId ), mapOptions ); checkEditStoreMarker(); } /** * Check if we have an existing latlng value. * * If there is an latlng value, then we add a marker to the map. * This can only happen on the edit store page. * * @since 1.0.0 * @returns {void} */ function checkEditStoreMarker() { var location, lat = $( "#wpsl-lat" ).val(), lng = $( "#wpsl-lng" ).val(); if ( ( lat ) && ( lng ) ) { location = new google.maps.LatLng( lat, lng ); map.setCenter( location ); map.setZoom( 16 ); addMarker( location ); } } // If we have a city/country input field enable the autocomplete. if ( $( "#wpsl-start-name" ).length ) { activateAutoComplete(); } /** * Activate the autocomplete function for the city/country field. * * @since 1.0.0 * @returns {void} */ function activateAutoComplete() { var latlng, input = document.getElementById( "wpsl-start-name" ), options = { types: ['geocode'] }, autocomplete = new google.maps.places.Autocomplete( input, options ); google.maps.event.addListener( autocomplete, "place_changed", function() { latlng = autocomplete.getPlace().geometry.location; setLatlng( latlng, "zoom" ); }); } /** * Add a new marker to the map based on the provided location (latlng). * * @since 1.0.0 * @param {object} location The latlng value * @param {boolean} draggable Whether the marker should be draggable or not * @returns {void} */ function addMarker( location, draggable = true ) { var marker = new google.maps.Marker({ position: location, map: map, draggable: draggable }); markersArray.push( marker ); // If the marker is dragged on the map, make sure the latlng values are updated. google.maps.event.addListener( marker, "dragend", function() { setLatlng( marker.getPosition(), "store" ); }); } // Lookup the provided location with the Google Maps API. $( "#wpsl-lookup-location" ).on( "click", function( e ) { e.preventDefault(); codeAddress(); }); /** * Update the hidden input field with the current latlng values. * * @since 1.0.0 * @param {object} latLng The latLng values * @param {string} target The location where we need to set the latLng * @returns {void} */ function setLatlng( latLng, target ) { var coordinates = stripCoordinates( latLng ), lat = roundCoordinate( coordinates[0] ), lng = roundCoordinate( coordinates[1] ); if ( target == "store" ) { $( "#wpsl-lat" ).val( lat ); $( "#wpsl-lng" ).val( lng ); } else if ( target == "zoom" ) { $( "#wpsl-latlng" ).val( lat + ',' + lng ); } } /** * Geocode the user input. * * @since 1.0.0 * @returns {void} */ function codeAddress() { var filteredResponse, geocodeAddress; // Check if we have all the required data before attempting to geocode the address. if ( !validatePreviewFields() ) { geocodeAddress = createGeocodeAddress(); geocoder.geocode( { 'address': geocodeAddress }, function( response, status ) { if ( status === google.maps.GeocoderStatus.OK ) { // If we have a previous marker on the map we remove it. if ( typeof( markersArray[0] ) !== "undefined" ) { if ( markersArray[0].draggable ) { markersArray[0].setMap( null ); markersArray.splice(0, 1); } } // Center and zoom to the searched location. map.setCenter( response[0].geometry.location ); map.setZoom( 16 ); addMarker( response[0].geometry.location ); setLatlng( response[0].geometry.location, "store" ); filteredResponse = filterApiResponse( response ); $( "#wpsl-country" ).val( filteredResponse.country.long_name ); $( "#wpsl-country_iso" ).val( filteredResponse.country.short_name ); } else { alert( wpslL10n.geocodeFail + ": " + status ); } }); return false; } else { activateStoreTab( "first" ); alert( wpslL10n.missingGeoData ); return true; } } /** * Check that all required fields for the map preview are there. * * @since 1.0.0 * @returns {boolean} error Whether all the required fields contained data. */ function validatePreviewFields() { var i, fieldData, requiredFields, error = false; $( ".wpsl-store-meta input" ).removeClass( "wpsl-error" ); // Check which fields are required. if ( typeof wpslSettings.requiredFields !== "undefined" && _.isArray( wpslSettings.requiredFields ) ) { requiredFields = wpslSettings.requiredFields; // Check if all the required fields contain data. for ( i = 0; i < requiredFields.length; i++ ) { fieldData = $.trim( $( "#wpsl-" + requiredFields[i] ).val() ); if ( !fieldData ) { $( "#wpsl-" + requiredFields[i] ).addClass( "wpsl-error" ); error = true; } fieldData = ''; } } return error; } /** * Build the address that's send to the Geocode API. * * @since 2.1.0 * @returns {string} geocodeAddress The address separated by , that's send to the Geocoder. */ function createGeocodeAddress() { var i, part, address = [], addressParts = [ "address", "city", "state", "zip", "country" ]; for ( i = 0; i < addressParts.length; i++ ) { part = $.trim( $( "#wpsl-" + addressParts[i] ).val() ); /* * At this point we already know the address, city and country fields contain data. * But no need to include the zip and state if they are empty. */ if ( part ) { address.push( part ); } part = ""; } return address.join(); } /** * Filter out the country name from the API response. * * @since 1.0.0 * @param {object} response The response of the geocode API * @returns {object} collectedData The short and long country name */ function filterApiResponse( response ) { var i, responseType, collectedData, country = {}, addressLength = response[0].address_components.length; // Loop over the API response. for ( i = 0; i < addressLength; i++ ) { responseType = response[0].address_components[i].types; // Filter out the country name. if ( /^country,political$/.test( responseType ) ) { country = { long_name: response[0].address_components[i].long_name, short_name: response[0].address_components[i].short_name }; } } collectedData = { country: country }; return collectedData; } /** * Round the coordinate to 6 digits after the comma. * * @since 1.0.0 * @param {string} coordinate The coordinate * @returns {number} roundedCoord The rounded coordinate */ function roundCoordinate( coordinate ) { var roundedCoord, decimals = 6; roundedCoord = Math.round( coordinate * Math.pow( 10, decimals ) ) / Math.pow( 10, decimals ); return roundedCoord; } /** * Strip the '(' and ')' from the captured coordinates and split them. * * @since 1.0.0 * @param {string} coordinates The coordinates * @returns {object} latLng The latlng coordinates */ function stripCoordinates( coordinates ) { var latLng = [], selected = coordinates.toString(), latLngStr = selected.split( ",", 2 ); latLng[0] = latLngStr[0].replace( "(", "" ); latLng[1] = latLngStr[1].replace( ")", "" ); return latLng; } $( ".wpsl-marker-list input[type=radio]" ).click( function() { $( this ).parents( ".wpsl-marker-list" ).find( "li" ).removeClass(); $( this ).parent( "li" ).addClass( "wpsl-active-marker" ); }); $( ".wpsl-marker-list li" ).click( function() { $( this ).parents( ".wpsl-marker-list" ).find( "input" ).prop( "checked", false ); $( this ).find( "input" ).prop( "checked", true ); $( this ).siblings().removeClass(); $( this ).addClass( "wpsl-active-marker" ); }); // Detect changes in checkboxes that have a conditional option. $( ".wpsl-has-conditional-option" ).on( "change", function() { $( this ).parent().next( ".wpsl-conditional-option" ).toggle(); }); /* * Detect changes to the store template dropdown. If the template is selected to * show the store list under the map then we show the option to hide the scrollbar. */ $( "#wpsl-store-template" ).on( "change", function() { var $scrollOption = $( "#wpsl-listing-below-no-scroll" ); if ( $( this ).val() == "below_map" ) { $scrollOption.show(); } else { $scrollOption.hide(); } }); $( "#wpsl-api-region" ).on( "change", function() { var $geocodeComponent = $( "#wpsl-geocode-component" ); if ( $( this ).val() ) { $geocodeComponent.show(); } else { $geocodeComponent.hide(); } }); // Make sure the correct hour input format is visible. $( "#wpsl-editor-hour-input" ).on( "change", function() { $( ".wpsl-" + $( this ).val() + "-hours" ).show().siblings( "div" ).hide(); $( ".wpsl-hour-notice" ).toggle(); }); // Set the correct tab to active and show the correct content block. $( "#wpsl-meta-nav li" ).on( "click", function( e ) { var activeClass = $( this ).attr( "class" ); activeClass = activeClass.split( "-tab" ); e.stopPropagation(); // Set the correct tab and metabox to active. $( this ).addClass( "wpsl-active" ).siblings().removeClass( "wpsl-active" ); $( ".wpsl-store-meta ." + activeClass[0] + "" ).show().addClass( "wpsl-active" ).siblings( "div" ).hide().removeClass( "wpsl-active" ); }); // Make sure the required store fields contain data. if ( $( "#wpsl-store-details" ).length ) { $( "#publish" ).click( function() { var firstErrorElem, currentTabClass, elemClass, errorMsg = '<div id="message" class="error"><p>' + wpslL10n.requiredFields + '</p></div>', missingData = false; // Remove error messages and css classes from previous submissions. $( "#wpbody-content .wrap #message" ).remove(); $( ".wpsl-required" ).removeClass( "wpsl-error" ); // Loop over the required fields and check for a value. $( ".wpsl-required" ).each( function() { if ( $( this ).val() == "" ) { $( this ).addClass( "wpsl-error" ); if ( typeof firstErrorElem === "undefined" ) { firstErrorElem = getFirstErrorElemAttr( $( this ) ); } missingData = true; } }); // If one of the required fields are empty, then show the error msg and make sure the correct tab is visible. if ( missingData ) { $( "#wpbody-content .wrap > h2" ).after( errorMsg ); if ( typeof firstErrorElem.val !== "undefined" ) { if ( firstErrorElem.type == "id" ) { currentTabClass = $( "#" + firstErrorElem.val + "" ).parents( ".wpsl-tab" ).attr( "class" ); $( "html, body" ).scrollTop( Math.round( $( "#" + firstErrorElem.val + "" ).offset().top - 100 ) ); } else if ( firstErrorElem.type == "class" ) { elemClass = firstErrorElem.val.replace( /wpsl-required|wpsl-error/g, "" ); currentTabClass = $( "." + elemClass + "" ).parents( ".wpsl-tab" ).attr( "class" ); $( "html, body" ).scrollTop( Math.round( $( "." + elemClass + "" ).offset().top - 100 ) ); } currentTabClass = $.trim( currentTabClass.replace( /wpsl-tab|wpsl-active/g, "" ) ); } // If we don't have a class of the tab that should be set to visible, we just show the first one. if ( !currentTabClass ) { activateStoreTab( 'first' ); } else { activateStoreTab( currentTabClass ); } /* * If not all required fields contains data, and the user has * clicked the submit button. Then an extra css class is added to the * button that will disabled it. This only happens in WP 3.8 or earlier. * * We need to make sure this css class doesn't exist otherwise * the user can never resubmit the page. */ $( "#publish" ).removeClass( "button-primary-disabled" ); $( ".spinner" ).hide(); return false; } else { return true; } }); } /** * Set the correct tab to visible, and hide all other metaboxes * * @since 2.0.0 * @param {string} $target The name of the tab to show * @returns {void} */ function activateStoreTab( $target ) { if ( $target == 'first' ) { $target = ':first-child'; } else { $target = '.' + $target; } if ( !$( "#wpsl-meta-nav li" + $target + "-tab" ).hasClass( "wpsl-active" ) ) { $( "#wpsl-meta-nav li" + $target + "-tab" ).addClass( "wpsl-active" ).siblings().removeClass( "wpsl-active" ); $( ".wpsl-store-meta > div" + $target + "" ).show().addClass( "wpsl-active" ).siblings( "div" ).hide().removeClass( "wpsl-active" ); } } /** * Get the id or class of the first element that's an required field, but is empty. * * We need this to determine which tab we need to set active, * which will be the tab were the first error occured. * * @since 2.0.0 * @param {object} elem The element the error occured on * @returns {object} firstErrorElem The id/class set on the first elem that an error occured on and the attr value */ function getFirstErrorElemAttr( elem ) { var firstErrorElem = { "type": "id", "val" : elem.attr( "id" ) }; // If no ID value exists, then check if we can get the class name. if ( typeof firstErrorElem.val === "undefined" ) { firstErrorElem = { "type": "class", "val" : elem.attr( "class" ) }; } return firstErrorElem; } // If we have a store hours dropdown, init the event handler. if ( $( "#wpsl-store-hours" ).length ) { initHourEvents(); } /** * Assign an event handler to the button that enables * users to remove an opening hour period. * * @since 2.0.0 * @returns {void} */ function initHourEvents() { $( "#wpsl-store-hours .wpsl-icon-cancel-circled" ).off(); $( "#wpsl-store-hours .wpsl-icon-cancel-circled" ).on( "click", function() { removePeriod( $( this ) ); }); } // Add new openings period to the openings hours table. $( ".wpsl-add-period" ).on( "click", function( e ) { var newPeriod, hours = {}, returnList = true, $tr = $( this ).parents( "tr" ), periodCount = currentPeriodCount( $( this ) ), periodCss = ( periodCount >= 1 ) ? "wpsl-current-period wpsl-multiple-periods" : "wpsl-current-period", day = $tr.find( ".wpsl-opening-hours" ).attr( "data-day" ), selectName = ( $( "#wpsl-settings-form" ).length ) ? "wpsl_editor[dropdown]" : "wpsl[hours]"; newPeriod = '<div class="' + periodCss +'">'; newPeriod += '<select autocomplete="off" name="' + selectName + '[' + day + '_open][]" class="wpsl-open-hour">' + createHourOptionList( returnList ) + '</select>'; newPeriod += '<span> - </span>'; newPeriod += '<select autocomplete="off" name="' + selectName + '[' + day + '_close][]" class="wpsl-close-hour">' + createHourOptionList( returnList ) + '</select>'; newPeriod += '<div class="wpsl-icon-cancel-circled"></div>'; newPeriod += '</div>'; $tr.find( ".wpsl-store-closed" ).remove(); $( "#wpsl-hours-" + day + "" ).append( newPeriod ).end(); initHourEvents(); if ( $( "#wpsl-editor-hour-format" ).val() == 24 ) { hours = { "open": "09:00", "close": "17:00" }; } else { hours = { "open": "9:00 AM", "close": "5:00 PM" }; } $tr.find( ".wpsl-open-hour:last option[value='" + hours.open + "']" ).attr( "selected", "selected" ); $tr.find( ".wpsl-close-hour:last option[value='" + hours.close + "']" ).attr( "selected", "selected" ); e.preventDefault(); }); /** * Remove an openings period * * @since 2.0.0 * @param {object} elem The clicked element * @return {void} */ function removePeriod( elem ) { var periodsLeft = currentPeriodCount( elem ), $tr = elem.parents( "tr" ), day = $tr.find( ".wpsl-opening-hours" ).attr( "data-day" ); // If there was 1 opening hour left then we add the 'Closed' text. if ( periodsLeft == 1 ) { $tr.find( ".wpsl-opening-hours" ).html( "<p class='wpsl-store-closed'>" + wpslL10n.closedDate + "<input type='hidden' name='wpsl[hours][" + day + "_open]' value='' /></p>" ); } // Remove the selected openings period. elem.parent().closest( ".wpsl-current-period" ).remove(); // If the first element has the multiple class, then we need to remove it. if ( $tr.find( ".wpsl-opening-hours div:first-child" ).hasClass( "wpsl-multiple-periods" ) ) { $tr.find( ".wpsl-opening-hours div:first-child" ).removeClass( "wpsl-multiple-periods" ); } } /** * Count the current opening periods in a day block * * @since 2.0.0 * @param {object} elem The clicked element * @return {string} currentPeriods The ammount of period divs found */ function currentPeriodCount( elem ) { var currentPeriods = elem.parents( "tr" ).find( ".wpsl-current-period" ).length; return currentPeriods; } /** * Create an option list with the correct opening hour format and interval * * @since 2.0.0 * @param {string} returnList Whether to return the option list or call the setSelectedOpeningHours function * @return {mixed} optionList The html for the option list of or void */ function createHourOptionList( returnList ) { var openingHours, openingHourInterval, hour, hrFormat, pm = false, twelveHrsAfternoon = false, pmOrAm = "", optionList = "", openingTimes = [], openingHourOptions = { "hours": { "hr12": [ 12, 1, 2, 3 ,4 ,5 ,6, 7, 8, 9, 10, 11, 12, 1, 2, 3 , 4, 5, 6, 7, 8, 9, 10, 11 ], "hr24": [ 0, 1, 2, 3 ,4 ,5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ,16, 17, 18, 19, 20, 21, 22, 23 ] }, "interval": [ '00', '15', '30', '45' ] }; if ( $( "#wpsl-editor-hour-format" ).length ) { hrFormat = $( "#wpsl-editor-hour-format" ).val(); } else { hrFormat = wpslSettings.hourFormat; } $( "#wpsl-store-hours td" ).removeAttr( "style" ); if ( hrFormat == 12 ) { $( "#wpsl-store-hours" ).removeClass().addClass( "wpsl-twelve-format" ); openingHours = openingHourOptions.hours.hr12; } else { $( "#wpsl-store-hours" ).removeClass().addClass( "wpsl-twentyfour-format" ); openingHours = openingHourOptions.hours.hr24; } openingHourInterval = openingHourOptions.interval; for ( var i = 0; i < openingHours.length; i++ ) { hour = openingHours[i]; /* * If the 12hr format is selected, then check if we need to show AM or PM. * * If the 24hr format is selected and the hour is a single digit * then we add a 0 to the start so 5:00 becomes 05:00. */ if ( hrFormat == 12 ) { if ( hour >= 12 ) { pm = ( twelveHrsAfternoon ) ? true : false; twelveHrsAfternoon = true; } pmOrAm = ( pm ) ? "PM" : "AM"; } else if ( ( hrFormat == 24 ) && ( hour.toString().length == 1 ) ) { hour = "0" + hour; } // Collect the new opening hour format and interval. for ( var j = 0; j < openingHourInterval.length; j++ ) { openingTimes.push( hour + ":" + openingHourInterval[j] + " " + pmOrAm ); } } // Create the <option> list. for ( var i = 0; i < openingTimes.length; i++ ) { optionList = optionList + '<option value="' + $.trim( openingTimes[i] ) + '">' + $.trim( openingTimes[i] ) + '</option>'; } if ( returnList ) { return optionList; } else { setSelectedOpeningHours( optionList, hrFormat ); } } /** * Set the correct selected opening hour in the dropdown * * @since 2.0.0 * @param {string} optionList The html for the option list * @param {string} hrFormat The html for the option list * @return {void} */ function setSelectedOpeningHours( optionList, hrFormat ) { var splitHour, hourType, periodBlock, hours = {}; /* * Loop over each open/close block and make sure the selected * value is still set as selected after changing the hr format. */ $( ".wpsl-current-period" ).each( function() { periodBlock = $( this ), hours = { "open": $( this ).find( ".wpsl-open-hour" ).val(), "close": $( this ).find( ".wpsl-close-hour" ).val() }; // Set the new hour format for both dropdowns. $( this ).find( "select" ).html( optionList ).promise().done( function() { // Select the correct start/end hours as selected. for ( var key in hours ) { if ( hours.hasOwnProperty( key ) ) { // Breakup the hour, so we can check the part before and after the : separately. splitHour = hours[key].split( ":" ); if ( hrFormat == 12 ) { hourType = ""; // Change the hours to a 12hr format and add the correct AM or PM. if ( hours[key].charAt( 0 ) == 0 ) { hours[key] = hours[key].substr( 1 ); hourType = " AM"; } else if ( ( splitHour[0].length == 2 ) && ( splitHour[0] > 12 ) ) { hours[key] = ( splitHour[0] - 12 ) + ":" + splitHour[1]; hourType = " PM"; } else if ( splitHour[0] < 12 ) { hours[key] = splitHour[0] + ":" + splitHour[1]; hourType = " AM"; } else if ( splitHour[0] == 12 ) { hours[key] = splitHour[0] + ":" + splitHour[1]; hourType = " PM"; } // Add either AM or PM behind the time. if ( ( splitHour[1].indexOf( "PM" ) == -1 ) && ( splitHour[1].indexOf( "AM" ) == -1 ) ) { hours[key] = hours[key] + hourType; } } else if ( hrFormat == 24 ) { // Change the hours to a 24hr format and remove the AM or PM. if ( splitHour[1].indexOf( "PM" ) != -1 ) { if ( splitHour[0] == 12 ) { hours[key] = "12:" + splitHour[1].replace( " PM", "" ); } else { hours[key] = ( + splitHour[0] + 12 ) + ":" + splitHour[1].replace( " PM", "" ); } } else if ( splitHour[1].indexOf( "AM" ) != -1 ) { if ( splitHour[0].toString().length == 1 ) { hours[key] = "0" + splitHour[0] + ":" + splitHour[1].replace( " AM", "" ); } else { hours[key] = splitHour[0] + ":" + splitHour[1].replace( " AM", "" ); } } else { hours[key] = splitHour[0] + ":" + splitHour[1]; // When the interval is changed } } // Set the correct value as the selected one. periodBlock.find( ".wpsl-" + key + "-hour option[value='" + $.trim( hours[key] ) + "']" ).attr( "selected", "selected" ); } } }); }); } // Update the opening hours format if one of the dropdown values change. $( "#wpsl-editor-hour-format, #wpsl-editor-hour-interval" ).on( "change", function() { createHourOptionList(); }); // Show the tooltips. $( ".wpsl-info" ).on( "mouseover", function() { $( this ).find( ".wpsl-info-text" ).show(); }); $( ".wpsl-info" ).on( "mouseout", function() { $( this ).find( ".wpsl-info-text" ).hide(); }); // If the start location is empty, then we color the info icon red instead of black. if ( $( "#wpsl-latlng" ).length && !$( "#wpsl-latlng" ).val() ) { $( "#wpsl-latlng" ).siblings( "label" ).find( ".wpsl-info" ).addClass( "wpsl-required-setting" ); } /** * Try to apply the custom style data to the map. * * If the style data is invalid json we show an error. * * @since 2.0.0 * @return {void} */ function tryCustomMapStyle() { var validStyle = "", mapStyle = $.trim( $( "#wpsl-map-style" ).val() ); $( ".wpsl-style-preview-error" ).remove(); if ( mapStyle ) { // Make sure the data is valid json. validStyle = tryParseJSON( mapStyle ); if ( !validStyle ) { $( "#wpsl-style-preview" ).after( "<div class='wpsl-style-preview-error'>" + wpslL10n.styleError + "</div>" ); } } map.setOptions({ styles: validStyle }); } // Handle the map style changes on the settings page. if ( $( "#wpsl-map-style" ).val() ) { tryCustomMapStyle(); } // Handle clicks on the map style preview button. $( "#wpsl-style-preview" ).on( "click", function() { tryCustomMapStyle(); return false; }); /** * Make sure the JSON is valid. * * @link http://stackoverflow.com/a/20392392/1065294 * @since 2.0.0 * @param {string} jsonString The JSON data * @return {object|boolean} The JSON string or false if it's invalid json. */ function tryParseJSON( jsonString ) { try { var o = JSON.parse( jsonString ); /* * Handle non-exception-throwing cases: * Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking, * but... JSON.parse(null) returns 'null', and typeof null === "object", * so we must check for that, too. */ if ( o && typeof o === "object" && o !== null ) { return o; } } catch ( e ) { } return false; } // Make sure the custom error notices can be removed $( "#wpsl-wrap" ).on( "click", "button.notice-dismiss", function() { $( this ).closest( 'div.notice' ).remove(); }); /** * Handle the red warning that's shown next to the * force zipcode search option if the autocomplete * value is changed. * * The autocomplete option itself doesn't support * zip only searches, so having both of them enabled * gives the user the wrong expectation. */ $( "#wpsl-search-autocomplete, #wpsl-force-postalcode" ).change( function() { var $info = $( "#wpsl-force-postalcode" ).parent( "p" ).find( ".wpsl-info-zip-only" ); if ( $( "#wpsl-search-autocomplete" ).is( ":checked" ) && $( "#wpsl-force-postalcode" ).is( ":checked" ) ) { $info.show(); } else { $info.hide(); } }); $( "#wpsl-delay-loading" ).change( function() { if ( $( this ).is( ":checked" ) ) { $( this ).parent( "p" ).find( ".wpsl-info" ).trigger( "mouseover" ); } else { $( this ).parent( "p" ).find( ".wpsl-info" ).trigger( "mouseout" ); } }); $( "#wpsl-wrap" ).on( "click", function( e ) { $( ".wpsl-info-text" ).hide(); }); });
| ver. 1.4 |
Github
|
.
| PHP 8.2.29 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка