Ответы пользователя по тегу JavaScript
  • Как получить значение photo_100 в функцию?

    Попробуйте объявление share_photo вынести за пределы функции (из VK.api):
    var verapi = '5.78';
    var share_photo;
    VK.api("groups.getById", {
     "group_ids": params['group_id'], "v": verapi
      }, function (data) {
    document.getElementById('group_name').innerHTML = data.response[0].name;
    var img = document.getElementById("group_photo"); img.src = data.response[0].photo_100;
    // убираем var
    share_photo = data.response[0].photo_100;
    });

    Либо в share_app добавьте параметр и передавайте в него значения. Это будет более правильный вариант, но логику придется подправить.
    Ответ написан
  • Как дебажить ajax ошибку?

    Отключите обработку ошибок (в web.config и фильтры) и уведите в чем проблема.

    Метод научного тыка говорит, что проблема в кодированных данных (выделено жирным):

    +%26%23171%3B%D0%94%D0%A0%D0%A3%D0%93%D0%90+%D0%91%D0%9E%D0%A0%D0%9E%D0%94%D0%90%26%23187%3B

    %26%23171%3B => «
    %26%23187%3B => »
    Ответ написан
    2 комментария
  • Как добавить строку в таблицу в ReactJS?

    Если вы хотите что-то изменить в текущем компоненте, то используйте состояние (setState).

    Если вы хотите изменить дочерний компонент, меняйте состояние текущего (setState) и передавайте измененные данные из состояния (state) дочернему компоненту через props.

    В вашем примере, корневой компонент - Table, в который вы передаете свойства (props): head_names и rows. Если вы хотите сделать возможность добавлять новую строку в Table, то вам следует сделать контейнер, в который поместить Table и кнопку (или другой элемент) для добавления новых строк. В состояние (state) контейнера нужно добавит head_names и rows, на основе которых и будет создаваться таблица.

    class TableManagement extends React.Component {
    
      constructor(props) {
        super(props);
        
        this.state = {
          head_names: ['qwe0', 'qwe1'],
          rows: [
            [1, 2],
            [3, 4]
          ]
        };
      }  
    
      AddRow() {
        let newRows = this.state.rows;
        newRows.push([0, 0]);
        this.setState({rows: newRows});
      }
    
      render() {
        return (
          <div>
            <Table head={this.state.head_names} rows={this.state.rows} />
            <hr />
            <button onClick={ this.AddRow.bind(this) }>Add row</button>
          </div>
        );
      }
    }
    
    class Table extends React.Component {
      render() {
        return (
          <table>
            <thead>
              {this.genHead()}
            </thead>
            <tbody>
              {this.genRow()}
            </tbody>
          </table>
        );
      }
    
      genHead() {
        var head = this.props.head;
    
        return head.map(function(v, i) {
          return (
            <th key={'th' + i}>
              {v}
            </th>
          );
        });
      }
    
      genRow() {
        var rows = this.props.rows;
    
        return rows.map(function(v, i) {
          var tmp = v.map(function(v2, j) {
            return (
              <td key={'td' + i + '_' + j}>
                {v2}
              </td>
            );
          });
    
          return (
            <tr key={'tr' + i}>
              {tmp}
            </tr>
          )
        });
      }
    }
    
    ReactDOM.render(
      <TableManagement />,
      document.getElementById('root')
    );

    https://jsfiddle.net/m11x34fp/

    В процессе разработки, важно определиться, кто будет тупым, а кто умным :-)

    Тупые (простые) компоненты - это компоненты, которые ничего не делают, просто принимают свойства и рисуются.

    Умные компоненты способны управлять состоянием, как своим, так и передавать его своим тупым отпрыскам потомкам :-)

    Если компонентов много, и особенно, если много вложенных компонентов, то следует хорошо продумать роль каждого компонента. Один умный компонент с множеством тупых вложенных компонентов - это самый простой вариант. Если дети тоже будут умными и должны будут общаться с компонентами своего уровня (братьями и сестрами) или верхнего уровня (дедушками, бабушками и выше), то организовать взаимодействие между компонентами будет сложно, будут конфликты, лишние обновления, в худшем случае зацикливание. Для решения проблем таких масштабов можно использования библиотеки управления состоянием, такие как Redux, Flux и т.п.
    Ответ написан
    2 комментария
  • Почему switch не работает?

    У вас двоеточие там, где должна быть точка с запятой:

    case valMetr == 0:
      valMetr = 0: // <<===== ошибка, должна быть точка с запятой
      break;
    case valMetr>1 && valMetr<=49:
      valMetr = 30: // <<===== ошибка, должна быть точка с запятой
      break;

    Вместо подобной конструкции switch лучше использовать if ... else.
    Быстрее будет работать, как минимум :-)
    Ответ написан
    1 комментарий
  • Как вывести данные из бд изменив снова сохранить?

    По указанной вами ссылке ведь есть готовый код:
    var grid, dialog;
    grid = $('#grid').grid({
        // ваш url, который будет передавать данные из вашей бд
        dataSource: '/Grid/GetPlayers',
        uiLibrary: 'bootstrap',
        // имена полей, которые следует выводить в таблице
        columns: [
            { field: 'ID', width: 32 },
            { field: 'Name', sortable: true },
            { field: 'PlaceOfBirth', title: 'Place Of Birth', sortable: true }
        ],
        pager: { limit: 5, sizes: [2, 5, 10, 20] }
    });

    Со стороны сервера можно сделать Action в обычном контроллере, который будет делать запрос к базе и возвращать данные в формате JSON. Но лучше использовать WebAPI, это будет проще.

    Для удаления и сохранения отдельные методы.

    Набросал простой пример: https://github.com/alekseynemiro/examples/tree/mas...
    Возможно для проверки работы примера потребуется переустановить пакеты. Для этого откройте меню Сервис => Диспетчер пакетов Nuget => Консоль диспетчера пакетов и введите следующую команду:

    Update-Package –reinstall

    В контроллере есть метод GetAccounts, который возвращает записи из базы:

    [HttpPost]
    public JsonResult GetAccounts(int page, int limit)
    {
      using (var context = new Database1Entities())
      {
        // получаем записи для указанной страницы
        var result = context.Account.OrderBy(
           row => row.AccountID
        ).Skip((page - 1) * limit).Take(limit).ToArray();
        int total = context.Account.Count();
    
        // возвращаем json
        return Json(new { records = result, total = total });
      }
    }

    В представлении, в коде инициализации jQuery Grid Bootstrap, указывается ссылка на этот метод:

    grid = $('#grid').grid({
      // ссылка на действие GetAccounts в контроллере Home
      // запрос выполняется методом POST
      dataSource: { url: '/Home/GetAccounts', method: 'POST' },
      uiLibrary: 'bootstrap',
      columns: [
        { field: 'AccountID', sortable: true },
        { field: 'FirstName', sortable: true },
        { field: 'LastName', sortable: true },
        { field: 'Company', sortable: true },
        { field: 'Position', sortable: true }
      ],
      pager: { limit: 2, sizes: [2, 5, 10, 20] }
    });
    Ответ написан
    Комментировать
  • Datapicker криво отображает дату?

    Используйте русскую локализацию:

    <script src="i18n/datepicker-ru.js"></script>
    $('#datepicker').datepicker($.datepicker.regional[ 'ru' ]);

    Скачать нужные ресурсы можно отсюда:
    https://github.com/jquery/jquery-ui/tree/master/ui/i18n

    Если вам нужен календарь на английском (или другом) языке, то задать первый день недели можно следующим образом:

    $('#datepicker').datepicker({ firstDay: 1 });
    // или
    $('#datepicker').datepicker('option', 'firstDay', 1);

    Посмотреть рабочий пример

    0 - воскресенье (Su - Sunday)
    1 - понедельник (Mo - Monday)
    и т.д.
    Ответ написан
    Комментировать
  • Как получить ответ с fancybox?

    Я обычно делаю собственные alert и confirm, которые выводят сообщения в модальных окнах.

    Для обработки закрытия можно использовать либо функции обратного вызова, либо Promise.

    Использование с Promise выглядит так:

    Confirm("Да или Нет?").then((result) => {
      if (result) {
        console.log("Пользователь согласен на всё.");
      }
      else
      {
        console.log("Пользователь что-то подозревает.");
      }
    });

    Внутри все равно без обработчиков не обойтись, но если функция вызова окна будет одна, то это не критично:

    function Confirm(message) {
      let p = new Promise((resolve, reject) => {
        // тут код создания окна
        // $.fancybox({ 
        //   modal: true,
        //   content: '<div>' + message + '</div>'
        // });
        // в обработчики кнопок нужно добавить вызов resolve
        // true - если пользователь нажал Ok
        // resolve(true);
        // false - если пользователь нажал Отмена
        // resolve(false);
      });
    
      return p;
    }

    При желании, можно сделать свой аналог Promise, хотя смысла нет, готовый вполне пригоден для решения подобной задачи.

    Вот более полный рабочий пример:

    function Confirm(message) {
      return new Promise(function(resolve, reject) {
        var buttons = $('<div class="buttons" />');
        var btnOk = $('<button class="btn btn-default">Ok</button>');
        var btnCancel = $('<button class="btn btn-default">Отмена</button>');
        var content = $('<div />');
    
        btnOk.click(function() { 
          resolve(true);
          $.fancybox.close(); 
        });
        
        btnCancel.click(function() { 
          resolve(false); 
          $.fancybox.close();
        });
    
        content.append('<div class="message" />');
        content.append('<hr />');
        content.append(buttons);
        
        $('.message', content).html(message);
        
        buttons.append(btnOk);
        buttons.append(' ');
        buttons.append(btnCancel);
        
        $.fancybox({ 
           modal: true,
           content: content
        });
      });
    }
    
    Confirm('Вы согласны с этим решением?').then(function(result) {
      if (result) {
        $('body').append("<h1>Отлично!</h1>");
      }
      else  {
        $('body').append("<h1>Очень жаль...</h1>");
      }
    });
    Ответ написан
    Комментировать
  • Как найти динамический DOM элемент?

    var element = document.createElement('div');
    element.id = 'test'; // уникальный идентификатор элемента
    element.innerHTML = 'создан новый элемент';
    
    document.body.appendChild(element);
    
    // получаем по идентификатору добавленный элемент
    document.getElementById('test').innerHTML = 'изменено содержимое созданного элемента';

    https://jsfiddle.net/alekseynemiro/x76s8zsy/1/

    В просмотре кода страницы динамически созданных элементов не будет, т.к. содержимое страницы - это то, что было получено от сервера, а JavaScript работает на стороне клиента.

    ---

    Дополню ответ в соответствии с обновлением текста вопроса.

    Получить path можно:

    1. По ссылке, в переменной path:

    console.log('path', path);

    2. Найти с помощью document.querySelector, например по имени класса:

    var path = document.createElement('path');
    path.className = 'anyClass';
    
    console.log('path', document.querySelector('.anyClass'));

    3. По идентификатору, как показано в самом первом примере:

    var path = document.createElement('path');
    path.id= 'path';
    
    console.log('path', document.getElementById('path'));

    4. По имени тега, но придется еще что-то проверять, поскольку на выходе будут все элементы path:

    console.log('path', document.getElementsByTagName('path'));


    PS: У меня ваш код работает без ошибок:
    https://jsfiddle.net/alekseynemiro/voyj5rt1/
    Используется Snap.svg v0.4.1

    649c48abe93b40a8b7efe17f39e7a0b5.gifOpera 39, Chrome 54, IE 11

    ---

    Обновление по результатам обсуждения проблемы в комментариях:

    Проблема в том, что создавать SVG-элементы нужно с указанием пространства имен, с помощью метода document.createElementNS:

    var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');

    https://jsfiddle.net/alekseynemiro/voyj5rt1/4/
    Ответ написан
  • Как быстро отсортировать таблицу?

    Узкое место тут в первую очередь jQuery. Нужно уменьшить число запросов к элементам через jQuery. А то получается, что у вас при сортировки для каждой итерации происходит маленький ад :-)

    Возможно, если вы сделаете сортировку, сформируете новый набор данных и затем замените им старые данные, работать будет быстрее.

    Вот небольшой пример: https://jsfiddle.net/alekseynemiro/q3tsw3bt/1/

    var data = [];
    
    // получаем данные из таблицы в массив
    $('tr', 'table>tbody').each(function(index, row) {
      var cells = $('td', row);
      var sum = 0;
      var items = [];
    
      for (var i = 0; i < cells.length; i++)
      {
        if (i == cells.length - 1)
        {
          cells[i].innerHTML = sum / 5;
          items.push(sum / 5);
        }
        else
        {
          sum += parseInt(cells[i].innerHTML, 10);
          items.push(parseInt(cells[i].innerHTML, 10));
        }
      }
    
      data.push(items);
    });
    
    // сортируем массив
    data.sort(function (a, b) {
      return a[5] - b[5];
    });
    
    // создаем новую таблицу на основе массива
    var html = '<table><thead><tr>';
    html += '<th>price</th><th>price</th><th>price</th>';
    html += '<th>price</th><th>price</th><th>avrg</th></tr></thead>';
    html += '<tbody>';
    
    for (var i = 0; i < data.length; i++)
    {
      html += '<tr>';
    
      for (var j = 0; j < data[i].length; j++)
      {
        html += '<td>' + data[i][j] + '</td>';
      }
    
      html += '</tr>';
    }
    
    html += '</tbody></table>';
    
    // выводим таблицу (перезаписываем старую)
    $('#content').html(html);

    Набросал еще вариант со счетчиком и с 50 000 строками, но счетчик показывает неправильное время, видимо на отрисовку данных в браузере уходит больше времени.
    Ответ написан
    Комментировать
  • Как сделать связанные select?

    Каскадные списки (cascade dropdown) это называется:
    https://github.com/dnasir/jquery-cascading-dropdown
    www.dnasir.com/github/jquery-cascading-dropdown/de...
    Ответ написан
    Комментировать
  • Как составить регулярное выражение исходя из следующих условий?

    В ситуациях, когда нужно изолировать фрагменты текста от обработки, проще всего перед обработкой их маскировать. Заменить на что-нибудь, что точно не попадет под обработку. А после обработки вернуть назад.

    this.replaceStandardHtmlEntities = (text) => {
      // маскируем ссылки
      text = text.replace(/\<a([^\>]*)\>/g, String.fromCharCode(1) + 'a$1' + String.fromCharCode(1));
      text = text.replace(/\<\/a\>/g, String.fromCharCode(1) + '/a' + String.fromCharCode(1));
    
      // остальной код без изменений
      let regular = /( {2}|&|'|<|>|\\n)/g, translate = {
        '  ': '&nbsp',
        '&': '&amp',
        '\'': '&quot',
        '<': '&lt',
        '>': '&gt',
        '\\n': '<br>'
      };
    
      // результат замены передаем в переменную
      let result = (text.replace(regular, (match, entity) => {
        return translate[entity];
      }));
      
      // возвращаем ссылки обратно
      result = result.replace(/\x01a([^\x01]*)\x01/g, '<a$1>');
      result = result.replace(/\x01\/a\x01/g, '</a>');
      
      return result;
    };

    Смотреть в JSFiddle
    Ответ написан
    5 комментариев
  • Как правильно удалить часть строки?

    Раз подстроки разделены запятыми, то проще всего получить массив с помощью функции split, перебрать элементы циклом, собрать новый массив без ненужных данных и потом склеить с помощью join:

    // входящие данные
    var str = 'odborka_vecher_01.jpg,%,podborka_vecher_37.jpg';
    // разбиваем на массив по запятой
    var arr = str.split(',');
    // фильтруем
    var resultArr = [];
    for (var i = 0; i < arr.length; i++)
    {
      if (arr[i] != '%')
      {
        // добавляем в результат
        resultArr.push(arr[i]);
      }
    }
    // склеиваем новый массив в строку
    var result = resultArr.join(',');
    // выводим полученный результат в консоль
    console.log(result);

    Более короткий вариант и без join:

    str.split(',').forEach(function(item) {
      if (item != '%') { 
        if (result != '') { result += ','; }
        result += item; 
      }
    });
    
    console.log(result);

    Еще короче, с использованием filter:

    var arr = str.split(',').filter(function(item) {
      return item != '%';
    });
    
    var result = arr.join(',');

    В качестве альтернативного решения, обычный поиск и замена:

    var result = str.replace(/,\%,/g, '');
    // с учетом того, что % может быть первым или последним
    // str.replace(/(\,*)\%(\,*)/g, '')
    Ответ написан
  • Как взять токен из адресной строки (oauth)?

    Вы должны сохранить полученный маркер доступа (access token). В случае с JavaScript это можно сделать в sessionStorage (в рамках текущей сессии) или localStorage (сохранить на длительный срок), либо передать на сервер (более надежный вариант).

    Код сохранения маркера доступа в хранилище браузера может быть примерно таким:
    if (window.location.hash != '') {
      var hash = window.location.hash.substring(1);
      var accessToken = hash.substr(hash.indexOf('access_token=')).split('&')[0].split('=')[1];
      sessionStorage.setItem('access_token', accessToken);
      // для безопасности, из url лучше удалить access_token
      window.location.hash = '';
      // window.location.href = window.location.href.substr(0, window.location.href.indexOf('#'))
    }
    
    // и далее использовать сохраненный маркер доступа
    var currentAccessToken = sessionStorage.getItem('key');
    Ответ написан
    Комментировать
  • Как убрать экранирование с помощью angular?

    Поиск и замена?
    return $sce.trustAsHtml(text.replace(/\\/g, ''));
    Можно отдельный фильтр для этого сделать :-)

    Набросал пример, у меня слеш и так не выводится:

    <div ng-app="app">
      <div ng-controller="ExampleController">
        <p ng-bind-html="text | trusted"></p>
      </div>
    </div>

    angular.module('app', []).controller('ExampleController', function($scope) {
      $scope.text = "A GREAT LOT, THIS IS THE ONE YOU\'VE BEEN LOOKING FOR";
    }).filter('trusted', ['$sce', function ($sce) {
      return function (text) {
        return $sce.trustAsHtml(text); // $sce.trustAsHtml(text.replace(/\\/g, ''));
      };
    }]);
    Ответ написан
    Комментировать
  • Как по клику заменить слово на другое и при повторном клике обратно?

    <div class="clickme">
    Нажми на меня!
    </div>

    $('.clickme').click(function(){
      if (!$(this).data('status')) {
        $(this).html('Молодец! А еще раз слабо?');
        $(this).data('status', true);
      }
      else {
        $(this).html('Ну ты гигант! А может еще раз?');
        $(this).data('status', false);
      }
    });

    https://jsfiddle.net/alekseynemiro/bu0zfgz4/
    Ответ написан
    1 комментарий
  • Как задать динамическое значение props?

    Использовать state вместо props:
    var Hello = React.createClass({
      getInitialState: function() {
        return { test: 0 };
      },
      componentWillMount: function() {
        setInterval(() => {
          var dynamicData = (Math.random() * 100).toFixed(0);
          this.setState({ test: dynamicData });
        }, 3000);  
      },
      render: function() {
        return <h2>{this.state.test}</h2>;
      }
    });
    
    ReactDOM.render(
      <Hello />,
      document.getElementById('container')
    );

    Если нужны именно props, то родительский компонент может менять состояние и передавать его в нужное свойство дочернего компонента, а дочерний компонент может обрабатывать изменения в componentWillReceiveProps(nextProps).

    Еще можно вызывать forceUpdate(), но лучше так не делать.

    От идеи внешнего управления компонентами лучше сразу отказаться. Будет меньше проблем. Все должно быть внутри компонентов, либо вообще не относиться к компонентам.
    Ответ написан
    2 комментария
  • Как интерпретировать this в данном примере?

    function CoffeeMachine(power) {
      //...
    
      var self = this; // запоминаем ссылку на текущий объект
    
      //...
    
      function getBoilTime() {
        // здесь this будет ссылкой на window, 
        // т.к. вызов метода getBoilTime() происходит из другого контекста
        // доступ к исходному объекту возможен через ссылку, 
        // которая была передана в переменную self
        console.log('this', this);
        console.log('self', self);
        return self.waterAmount * WATER_HEAT_CAPACITY * 80 / power;
      }
    
      // ...
    
      this.run = function() {
        setTimeout(onReady, getBoilTime());
      };
    }


    Привязка контекста и карринг: "bind"

    С передачей контекста код будет примерно таким:

    function CoffeeMachine(power) {
      this.waterAmount = 0;
    
      var WATER_HEAT_CAPACITY = 4200;
    
      function getBoilTime() {
          console.log('getBoilTime', this);
          return this.waterAmount * WATER_HEAT_CAPACITY * 80 / power;
        }
    
      function onReady() {
        alert( 'Кофе готово!' );
      }
    
      this.run = function() {
        console.log('run', this);
        var interval = getBoilTime.apply(this, null);
        setTimeout(onReady, interval);
      };
    
    }
    
    var coffeeMachine = new CoffeeMachine(100000);
    coffeeMachine.waterAmount = 200;
    
    coffeeMachine.run.apply(coffeeMachine, null);
    Ответ написан
    3 комментария
  • Reactjs плагины и requirejs, как?

    Не переписывать же плагины, верно? Кто как с этим борется?


    Использую TypeScript и Visual Studio. Итоговый JavaScript сам собирается в нужном виде, достаточно выбрать систему модулей в свойствах проекта.

    Но с некоторыми библиотеками React в AMD возникали проблемы. И да, единственным решением было внесение изменений в код этих компонентов, что не очень хорошо и не факт, что можно будет отделаться парой простых изменений.

    В итоге пришлось использовать Webpack. Опыт работы с RequireJS сильно усложнил миграцию и в какие-то моменты я даже пытался прикрутить RequireJS в Webpack :-) Так что про RequireJS лучше полностью забыть.

    Реализация с Webpack мне нравится больше, но настроек придется написать много и иногда все это дело глючит. С использованием загрузчиков, на выходе можно получить все что угодно из чего угодно.
    Ответ написан
    Комментировать